From 53d98d8eabc05b374676d4017c9a01986a8629d2 Mon Sep 17 00:00:00 2001 From: Matias Pierobon Date: Sat, 29 May 2021 16:03:21 -0300 Subject: [PATCH 01/46] add chunk and loadedChunks commands --- carpetmodSrc/carpet/CarpetSettings.java | 12 +- .../carpet/commands/CarpetCommands.java | 3 +- .../carpet/commands/CommandCarpetBase.java | 3 + .../carpet/commands/CommandChunk.java | 125 ++++++++ .../carpet/commands/CommandLoadedChunks.java | 276 ++++++++++++++++++ 5 files changed, 415 insertions(+), 4 deletions(-) create mode 100644 carpetmodSrc/carpet/commands/CommandChunk.java create mode 100644 carpetmodSrc/carpet/commands/CommandLoadedChunks.java diff --git a/carpetmodSrc/carpet/CarpetSettings.java b/carpetmodSrc/carpet/CarpetSettings.java index 216adfac..494ca5ca 100644 --- a/carpetmodSrc/carpet/CarpetSettings.java +++ b/carpetmodSrc/carpet/CarpetSettings.java @@ -25,6 +25,7 @@ import carpet.utils.TickingArea; import carpet.worldedit.WorldEditBridge; import net.minecraft.block.BlockFalling; +import net.minecraft.command.NumberInvalidException; import net.minecraft.init.Blocks; import net.minecraft.server.dedicated.DedicatedServer; import net.minecraft.util.math.AxisAlignedBB; @@ -87,10 +88,15 @@ public class CarpetSettings }) public static boolean commandBlockInfo = true; - @Rule(desc = "Enables /loadchunk command", category = COMMANDS, extra = { - "Loads a chunk remotely" + @Rule(desc = "Enables /chunk command", category = COMMANDS, extra = { + "chunk info command" }) - public static boolean commandLoadChunk = true; + public static boolean commandChunk = true; + + @Rule(desc = "Enables /loadedChunks command", category = COMMANDS, extra = { + "Get information of the loaded chunks hashmap" + }) + public static boolean commandLoadedChunks = true; @Rule(desc = "Enables /entityinfo command", category = COMMANDS, extra = { "Also enables yellow carpet placement action if 'carpets' rule is turned on as well" diff --git a/carpetmodSrc/carpet/commands/CarpetCommands.java b/carpetmodSrc/carpet/commands/CarpetCommands.java index edc73117..9ab6351c 100644 --- a/carpetmodSrc/carpet/commands/CarpetCommands.java +++ b/carpetmodSrc/carpet/commands/CarpetCommands.java @@ -10,6 +10,7 @@ public static void register(CommandHandler handler) { handler.registerCommand(new CommandAutosave()); handler.registerCommand(new CommandBlockInfo()); handler.registerCommand(new CommandCarpet()); + handler.registerCommand(new CommandChunk()); handler.registerCommand(new CommandCounter()); handler.registerCommand(new CommandDebugCarpet()); handler.registerCommand(new CommandDebuglogger()); @@ -22,7 +23,7 @@ public static void register(CommandHandler handler) { handler.registerCommand(new CommandLagSpike()); handler.registerCommand(new CommandLazyChunkBehavior()); handler.registerCommand(new CommandLight()); - handler.registerCommand(new CommandLoadChunk()); + handler.registerCommand(new CommandLoadedChunks()); handler.registerCommand(new CommandLog()); handler.registerCommand(new CommandPerimeter()); handler.registerCommand(new CommandPing()); diff --git a/carpetmodSrc/carpet/commands/CommandCarpetBase.java b/carpetmodSrc/carpet/commands/CommandCarpetBase.java index 1feceef7..26c4c7bf 100644 --- a/carpetmodSrc/carpet/commands/CommandCarpetBase.java +++ b/carpetmodSrc/carpet/commands/CommandCarpetBase.java @@ -56,5 +56,8 @@ public boolean command_enabled(String command_name, ICommandSender sender) return true; } + protected int parseChunkPosition(String arg, int base) throws NumberInvalidException { + return arg.equals("~") ? base >> 4 : parseInt(arg); + } } diff --git a/carpetmodSrc/carpet/commands/CommandChunk.java b/carpetmodSrc/carpet/commands/CommandChunk.java new file mode 100644 index 00000000..48927470 --- /dev/null +++ b/carpetmodSrc/carpet/commands/CommandChunk.java @@ -0,0 +1,125 @@ +package carpet.commands; + +import it.unimi.dsi.fastutil.HashCommon; +import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; +import net.minecraft.command.CommandException; +import net.minecraft.command.ICommandSender; +import net.minecraft.command.WrongUsageException; +import net.minecraft.server.MinecraftServer; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.ChunkPos; +import net.minecraft.util.text.TextComponentString; +import net.minecraft.world.World; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.gen.ChunkProviderServer; +import test.Test; + +import javax.annotation.Nullable; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class CommandChunk extends CommandCarpetBase +{ + /** + * Gets the name of the command + */ + + public String getUsage(ICommandSender sender) + { + return "Usage: chunk "; + } + + public String getName() + { + return "chunk"; + } + + protected World world; + /** + * Callback for when the command is executed + */ + public void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException + { + if (!command_enabled("commandChunk", sender)) return; + + if (args.length == 1 && args[0].equals("test")) { + List> chunks = Test.profileResults.entrySet().stream().sorted(Map.Entry.comparingByValue()).collect(Collectors.toList()); + for (int i = 0; i < chunks.size(); i++) { + Map.Entry entry = chunks.get(i); + long time = i == 0 ? 0 : entry.getValue() - chunks.get(i - 1).getValue(); + long absTime = entry.getValue() - chunks.get(0).getValue(); + sender.sendMessage(new TextComponentString("- " + entry.getKey() + ": " + absTime + " / " + time)); + } + } + + if (args.length != 3) + { + throw new WrongUsageException(getUsage(sender)); + } + + int chunkX = parseChunkPosition(args[0], sender.getPosition().getX()); + int chunkZ = parseChunkPosition(args[1], sender.getPosition().getZ()); + + world = sender.getEntityWorld(); + try { + switch (args[2]){ + case "load": + world.getChunk(chunkX, chunkZ); + sender.sendMessage(new TextComponentString("Chunk " + chunkX + ", " + chunkZ + " loaded")); + return; + case "unload": + unload(sender, chunkX, chunkZ); + return; + case "info": + info(sender, chunkX, chunkZ); + + } + }catch (Exception e){ + throw new WrongUsageException(getUsage(sender)); + } + } + + protected void info(ICommandSender sender, int x, int z) throws NoSuchFieldException, IllegalAccessException { + if(!world.isChunkLoaded(x, z, false)) { + sender.sendMessage(new TextComponentString(("Chunk is not loaded"))); + } + + long i = ChunkPos.asLong(x, z); + ChunkProviderServer provider = (ChunkProviderServer) world.getChunkProvider(); + int mask = CommandLoadedChunks.getMask((Long2ObjectOpenHashMap) provider.loadedChunks); + long key = HashCommon.mix(i) & mask; + sender.sendMessage(new TextComponentString(("Chunk ideal key is " + key))); + if (world.isSpawnChunk(x, z)) + sender.sendMessage(new TextComponentString(("Spawn Chunk"))); + } + + protected void unload(ICommandSender sender, int x, int z){ + if(!world.isChunkLoaded(x, z, false)) { + sender.sendMessage(new TextComponentString(("Chunk is not loaded"))); + return; + } + Chunk chunk = world.getChunk(x, z); + ChunkProviderServer provider = (ChunkProviderServer) world.getChunkProvider(); + provider.queueUnload(chunk); + sender.sendMessage(new TextComponentString(("Chunk is queue to unload"))); + } + + public List getTabCompletions(MinecraftServer server, ICommandSender sender, String[] args, @Nullable BlockPos targetPos) { + int chunkX = sender.getPosition().getX() >> 4; + int chunkZ = sender.getPosition().getZ() >> 4; + + if (args.length == 1) { + return getListOfStringsMatchingLastWord(args, Integer.toString(chunkX), "~"); + } else if (args.length == 2) { + return getListOfStringsMatchingLastWord(args, Integer.toString(chunkZ), "~"); + } else if (args.length == 3) { + return getListOfStringsMatchingLastWord(args, "info", "load", "unload"); + } else { + return Collections.emptyList(); + } + } +} diff --git a/carpetmodSrc/carpet/commands/CommandLoadedChunks.java b/carpetmodSrc/carpet/commands/CommandLoadedChunks.java new file mode 100644 index 00000000..97b879d2 --- /dev/null +++ b/carpetmodSrc/carpet/commands/CommandLoadedChunks.java @@ -0,0 +1,276 @@ +package carpet.commands; + +import carpet.CarpetSettings; +import it.unimi.dsi.fastutil.HashCommon; +import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; +import net.minecraft.command.CommandException; +import net.minecraft.command.ICommandSender; +import net.minecraft.command.WrongUsageException; +import net.minecraft.server.MinecraftServer; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.ChunkPos; +import net.minecraft.util.text.TextComponentString; +import net.minecraft.world.World; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.gen.ChunkProviderServer; + +import javax.annotation.Nullable; +import java.lang.reflect.Field; +import java.util.*; +import java.util.stream.Collectors; + +public class CommandLoadedChunks extends CommandCarpetBase +{ + /** + * Gets the name of the command + */ + protected World world; + public String getUsage(ICommandSender sender) + { + return "Usage: loadedChunks "; + } + + public String getName() + { + return "loadedChunks"; + } + + /** + * Callback for when the command is executed + */ + public void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException + { + if (!command_enabled("commandLoadedChunks", sender)) return; + + world = sender.getEntityWorld(); + ChunkProviderServer provider = (ChunkProviderServer) world.getChunkProvider(); + Long2ObjectOpenHashMap loadedChunks = (Long2ObjectOpenHashMap) provider.loadedChunks; + + try { + switch (args[0]){ + case "size": + sender.sendMessage(new TextComponentString(String.format("Hashmap size is %d, %.2f", loadedChunks.size(), getFillLevel(loadedChunks) ))); + break; + case "search": + search(sender, parseChunkPosition(args[1], sender.getPosition().getX()), parseChunkPosition(args[2], sender.getPosition().getZ())); + break; + case "remove": + remove(sender, parseChunkPosition(args[1], sender.getPosition().getX()), parseChunkPosition(args[2], sender.getPosition().getZ())); + break; + case "add": + add(sender, parseChunkPosition(args[1], sender.getPosition().getX()), parseChunkPosition(args[2], sender.getPosition().getZ())); + break; + case "inspect": + Object[] chunks = getValues(loadedChunks); + int mask = getMask(loadedChunks); + Integer start = 0, end = chunks.length; + Optional keyClass = Optional.empty(); + for (int i = 1; i < args.length; i++){ + switch (args[i]){ + case "from": + start = Integer.valueOf(args[++i]); + break; + case "to": + end = Integer.valueOf(args[++i]);; + break; + case "class": + keyClass = Optional.of(Long.valueOf(args[++i])); + break; + default: + throw new WrongUsageException(getUsage(sender)); + } + } + ArrayList inspections = new ArrayList<>(); + String last = ""; + int lastN = 0; + for (int i = start; (i & mask) != (end & mask); i++) { + Chunk chunk = (Chunk) chunks[i & mask]; + if(keyClass.isPresent()){ + if(chunk == null){ + if(!last.equals("null")){ + if(lastN > 0) + inspections.add(String.format("... %d %s", lastN, last)); + last = "null"; + lastN = 0; + } + lastN++; + continue; + } + if(getKeyClass(chunk, mask) != keyClass.get()){ + if(last != "chunks"){ + if(lastN > 0) + inspections.add(String.format("... %d %s", lastN, last)); + last = "chunks"; + lastN = 0; + } + lastN++; + continue; + } + } + if(last != ""){ + if(lastN > 0) + inspections.add(String.format("... %d %s", lastN, last)); + last = ""; + lastN = 0; + } + String formatted = formatChunk(chunk, i & mask, mask); + inspections.add(formatted); + + } + String result = inspections.stream().collect(Collectors.joining(", ", "[", "]")); + sender.sendMessage(new TextComponentString(result)); + break; + default: + throw new WrongUsageException(getUsage(sender)); + } + }catch (Exception exception){ + exception.printStackTrace(); + throw new CommandException(exception.getMessage()); + } + + } + + protected void search(ICommandSender sender, int chunkX, int chunkZ) throws NoSuchFieldException, IllegalAccessException { + Long2ObjectOpenHashMap loadedChunks = (Long2ObjectOpenHashMap) ((ChunkProviderServer) world.getChunkProvider()).loadedChunks; + Object[] chunks = getValues(loadedChunks); + int mask = getMask(loadedChunks); + for (int i = 0; i < chunks.length; i++) { + Chunk chunk = (Chunk) chunks[i]; + if(chunk == null) + continue; + if (chunk.x != chunkX || chunk.z != chunkZ) + continue; + sender.sendMessage(new TextComponentString(formatChunk(chunk,i, mask))); + break; + } + } + + protected static HashMap tempChunks = new HashMap<>(); + + protected void add(ICommandSender sender, int x, int z) { + long hash = ChunkPos.asLong(x, z); + if(!tempChunks.containsKey(hash)){ + sender.sendMessage(new TextComponentString(String.format("Chunk (%d, %d) couldn't been found", x, z))); + return; + } + Chunk chunk = tempChunks.get(hash); + Long2ObjectOpenHashMap loadedChunks = getLoadedChunks(); + loadedChunks.put(hash, chunk); + sender.sendMessage(new TextComponentString(String.format("Chunk (%d, %d) has been added back", x, z))); + } + + protected void remove(ICommandSender sender, int x, int z) { + long hash = ChunkPos.asLong(x, z); + + Long2ObjectOpenHashMap loadedChunks = getLoadedChunks(); + if(!loadedChunks.containsKey(hash)){ + sender.sendMessage(new TextComponentString(String.format("Chunk (%d, %d) is not in loaded list", x, z))); + } + Chunk chunk = loadedChunks.remove(hash); + tempChunks.put(hash, chunk); + sender.sendMessage(new TextComponentString(String.format("Chunk (%d, %d) has been removed", x, z))); + } + + protected Long2ObjectOpenHashMap getLoadedChunks(){ + ChunkProviderServer provider = (ChunkProviderServer) world.getChunkProvider(); + return (Long2ObjectOpenHashMap) provider.loadedChunks; + } + + public String formatChunk(Chunk chunk, int pos, int mask){ + if (chunk == null) { + return String.format("%d: null", pos); + + } + + return String.format("%d: %s(%d, %d) %d", + pos, getChunkDescriber(chunk), chunk.x, chunk.z, + getKeyClass(chunk, mask)); + } + + public String getChunkDescriber(Chunk chunk){ + int x = chunk.x, z = chunk.z; + long hash = ChunkPos.asLong(x, z); + String describer = ""; + if(world.isSpawnChunk(x, z)){ + describer +="S "; + } + if(((hash ^ (hash >>> 16)) & 0xFFFF) == 0){ + describer +="0 "; + } + return describer; + } + + public static long getKeyClass(Chunk chunk, int mask){ + return HashCommon.mix(ChunkPos.asLong(chunk.x, chunk.z)) & mask; + } + + public static int getMaxField(Long2ObjectOpenHashMap hashMap) throws NoSuchFieldException, IllegalAccessException { + Field maxFill = Long2ObjectOpenHashMap.class.getDeclaredField("maxFill"); + maxFill.setAccessible(true); + return (int) maxFill.get(hashMap); + } + + public static int getMask(Long2ObjectOpenHashMap hashMap) throws NoSuchFieldException, IllegalAccessException { + Field mask = Long2ObjectOpenHashMap.class.getDeclaredField("mask"); + mask.setAccessible(true); + return (int) mask.get(hashMap); + } + + public static float getFillLevel(Long2ObjectOpenHashMap hashMap) throws NoSuchFieldException, IllegalAccessException { + return (float) hashMap.size() / getMaxField(hashMap); + } + + public static Object[] getValues(Long2ObjectOpenHashMap hashMap) throws NoSuchFieldException, IllegalAccessException { + Field value = Long2ObjectOpenHashMap.class.getDeclaredField("value"); + value.setAccessible(true); + return (Object[]) value.get(hashMap); + } + + public List getTabCompletions(MinecraftServer server, ICommandSender sender, String[] args, @Nullable BlockPos targetPos) { + + if (!CarpetSettings.commandLoadedChunks) + { + return Collections.emptyList(); + } + + if (args.length == 1) + { + return getListOfStringsMatchingLastWord(args, + "size", "inspect", "search", "remove", "add"); + } + + switch (args[0]){ + case "inspect": + switch (args[args.length - 1]){ + case "class": + case "from": + case "to": + return Collections.emptyList(); + } + return getListOfStringsMatchingLastWord(args, + "class", "from", "to"); + case "search": + case "remove": + case "add": + if (args.length > 3) + return Collections.emptyList(); + return getChunkCompletitions(sender, args, 2); + } + + return Collections.emptyList(); + } + + + public List getChunkCompletitions(ICommandSender sender, String[] args, int index) { + int chunkX = sender.getPosition().getX() >> 4; + int chunkZ = sender.getPosition().getZ() >> 4; + + if (args.length == index) { + return getListOfStringsMatchingLastWord(args, Integer.toString(chunkX), "~"); + } else if (args.length == index + 1) { + return getListOfStringsMatchingLastWord(args, Integer.toString(chunkZ), "~"); + } else { + return Collections.emptyList(); + } + } +} From 2d5d8e578e7bfb6b74ab0e0825b9d40c060fa92d Mon Sep 17 00:00:00 2001 From: Matias Pierobon Date: Sat, 29 May 2021 16:19:31 -0300 Subject: [PATCH 02/46] deprecate load chunk for chunk load --- .../carpet/commands/CommandLoadChunk.java | 65 ------------------- 1 file changed, 65 deletions(-) delete mode 100644 carpetmodSrc/carpet/commands/CommandLoadChunk.java diff --git a/carpetmodSrc/carpet/commands/CommandLoadChunk.java b/carpetmodSrc/carpet/commands/CommandLoadChunk.java deleted file mode 100644 index 89a2f563..00000000 --- a/carpetmodSrc/carpet/commands/CommandLoadChunk.java +++ /dev/null @@ -1,65 +0,0 @@ -package carpet.commands; - -import carpet.CarpetSettings; -import carpet.utils.BlockInfo; -import carpet.utils.Messenger; -import com.google.common.collect.Lists; -import net.minecraft.command.CommandException; -import net.minecraft.command.ICommandSender; -import net.minecraft.command.WrongUsageException; -import net.minecraft.server.MinecraftServer; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.text.TextComponentString; -import net.minecraft.world.World; - -import javax.annotation.Nullable; -import java.util.Collections; -import java.util.List; - -public class CommandLoadChunk extends CommandCarpetBase -{ - /** - * Gets the name of the command - */ - - public String getUsage(ICommandSender sender) - { - return "Usage: loadchunk "; - } - - public String getName() - { - return "loadchunk"; - } - - /** - * Callback for when the command is executed - */ - public void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException - { - if (!command_enabled("commandLoadChunk", sender)) return; - - if (args.length != 2) - { - throw new WrongUsageException(getUsage(sender), new Object[0]); - } - int chunkX = parseInt(args[0]); - int chunkZ = parseInt(args[1]); - World world = sender.getEntityWorld(); - world.getChunk(chunkX, chunkZ); - sender.sendMessage(new TextComponentString("Chunk" + chunkX + ", " + chunkZ + " loaded")); - } - - public List getTabCompletions(MinecraftServer server, ICommandSender sender, String[] args, @Nullable BlockPos targetPos) { - int chunkX = sender.getPosition().getX() >> 4; - int chunkZ = sender.getPosition().getZ() >> 4; - - if (args.length == 1) { - return getListOfStringsMatchingLastWord(args, Integer.toString(chunkX)); - } else if (args.length == 2) { - return getListOfStringsMatchingLastWord(args, Integer.toString(chunkZ)); - } else { - return Collections.emptyList(); - } - } -} From 859109de6ad803cd269e75f74c69dc1f11453dfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=ADas=20Pierobon?= Date: Sat, 29 May 2021 17:03:07 -0300 Subject: [PATCH 03/46] clean up --- .../carpet/commands/CommandCarpetBase.java | 1 + .../carpet/commands/CommandChunk.java | 19 +-- .../carpet/commands/CommandLoadedChunks.java | 143 ++++++++++-------- 3 files changed, 83 insertions(+), 80 deletions(-) diff --git a/carpetmodSrc/carpet/commands/CommandCarpetBase.java b/carpetmodSrc/carpet/commands/CommandCarpetBase.java index 26c4c7bf..f024c888 100644 --- a/carpetmodSrc/carpet/commands/CommandCarpetBase.java +++ b/carpetmodSrc/carpet/commands/CommandCarpetBase.java @@ -4,6 +4,7 @@ import carpet.utils.Messenger; import net.minecraft.command.CommandBase; import net.minecraft.command.ICommandSender; +import net.minecraft.command.NumberInvalidException; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.server.MinecraftServer; import net.minecraft.util.text.ITextComponent; diff --git a/carpetmodSrc/carpet/commands/CommandChunk.java b/carpetmodSrc/carpet/commands/CommandChunk.java index 48927470..59813139 100644 --- a/carpetmodSrc/carpet/commands/CommandChunk.java +++ b/carpetmodSrc/carpet/commands/CommandChunk.java @@ -12,15 +12,10 @@ import net.minecraft.world.World; import net.minecraft.world.chunk.Chunk; import net.minecraft.world.gen.ChunkProviderServer; -import test.Test; import javax.annotation.Nullable; import java.util.Collections; -import java.util.Comparator; import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; -import java.util.stream.Stream; public class CommandChunk extends CommandCarpetBase { @@ -46,18 +41,7 @@ public void execute(MinecraftServer server, ICommandSender sender, String[] args { if (!command_enabled("commandChunk", sender)) return; - if (args.length == 1 && args[0].equals("test")) { - List> chunks = Test.profileResults.entrySet().stream().sorted(Map.Entry.comparingByValue()).collect(Collectors.toList()); - for (int i = 0; i < chunks.size(); i++) { - Map.Entry entry = chunks.get(i); - long time = i == 0 ? 0 : entry.getValue() - chunks.get(i - 1).getValue(); - long absTime = entry.getValue() - chunks.get(0).getValue(); - sender.sendMessage(new TextComponentString("- " + entry.getKey() + ": " + absTime + " / " + time)); - } - } - - if (args.length != 3) - { + if (args.length != 3) { throw new WrongUsageException(getUsage(sender)); } @@ -75,6 +59,7 @@ public void execute(MinecraftServer server, ICommandSender sender, String[] args unload(sender, chunkX, chunkZ); return; case "info": + default: info(sender, chunkX, chunkZ); } diff --git a/carpetmodSrc/carpet/commands/CommandLoadedChunks.java b/carpetmodSrc/carpet/commands/CommandLoadedChunks.java index 97b879d2..4c115b91 100644 --- a/carpetmodSrc/carpet/commands/CommandLoadedChunks.java +++ b/carpetmodSrc/carpet/commands/CommandLoadedChunks.java @@ -41,84 +41,27 @@ public String getName() public void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException { if (!command_enabled("commandLoadedChunks", sender)) return; - - world = sender.getEntityWorld(); - ChunkProviderServer provider = (ChunkProviderServer) world.getChunkProvider(); - Long2ObjectOpenHashMap loadedChunks = (Long2ObjectOpenHashMap) provider.loadedChunks; + if (args.length == 0) throw new WrongUsageException(getUsage(sender)); try { switch (args[0]){ case "size": - sender.sendMessage(new TextComponentString(String.format("Hashmap size is %d, %.2f", loadedChunks.size(), getFillLevel(loadedChunks) ))); + size(server, sender, args); break; case "search": + if (args.length != 3) throw new WrongUsageException(getUsage(sender)); search(sender, parseChunkPosition(args[1], sender.getPosition().getX()), parseChunkPosition(args[2], sender.getPosition().getZ())); break; case "remove": + if (args.length != 3) throw new WrongUsageException(getUsage(sender)); remove(sender, parseChunkPosition(args[1], sender.getPosition().getX()), parseChunkPosition(args[2], sender.getPosition().getZ())); break; case "add": + if (args.length != 3) throw new WrongUsageException(getUsage(sender)); add(sender, parseChunkPosition(args[1], sender.getPosition().getX()), parseChunkPosition(args[2], sender.getPosition().getZ())); break; case "inspect": - Object[] chunks = getValues(loadedChunks); - int mask = getMask(loadedChunks); - Integer start = 0, end = chunks.length; - Optional keyClass = Optional.empty(); - for (int i = 1; i < args.length; i++){ - switch (args[i]){ - case "from": - start = Integer.valueOf(args[++i]); - break; - case "to": - end = Integer.valueOf(args[++i]);; - break; - case "class": - keyClass = Optional.of(Long.valueOf(args[++i])); - break; - default: - throw new WrongUsageException(getUsage(sender)); - } - } - ArrayList inspections = new ArrayList<>(); - String last = ""; - int lastN = 0; - for (int i = start; (i & mask) != (end & mask); i++) { - Chunk chunk = (Chunk) chunks[i & mask]; - if(keyClass.isPresent()){ - if(chunk == null){ - if(!last.equals("null")){ - if(lastN > 0) - inspections.add(String.format("... %d %s", lastN, last)); - last = "null"; - lastN = 0; - } - lastN++; - continue; - } - if(getKeyClass(chunk, mask) != keyClass.get()){ - if(last != "chunks"){ - if(lastN > 0) - inspections.add(String.format("... %d %s", lastN, last)); - last = "chunks"; - lastN = 0; - } - lastN++; - continue; - } - } - if(last != ""){ - if(lastN > 0) - inspections.add(String.format("... %d %s", lastN, last)); - last = ""; - lastN = 0; - } - String formatted = formatChunk(chunk, i & mask, mask); - inspections.add(formatted); - - } - String result = inspections.stream().collect(Collectors.joining(", ", "[", "]")); - sender.sendMessage(new TextComponentString(result)); + inspect(server, sender, args); break; default: throw new WrongUsageException(getUsage(sender)); @@ -130,6 +73,80 @@ public void execute(MinecraftServer server, ICommandSender sender, String[] args } + protected Long2ObjectOpenHashMap getLoadedChunks (ICommandSender sender){ + world = sender.getEntityWorld(); + ChunkProviderServer provider = (ChunkProviderServer) world.getChunkProvider(); + return (Long2ObjectOpenHashMap) provider.loadedChunks; + } + + protected void size(MinecraftServer server, ICommandSender sender, String[] args) + throws CommandException, NoSuchFieldException, IllegalAccessException { + Long2ObjectOpenHashMap loadedChunks = this.getLoadedChunks(sender); + sender.sendMessage(new TextComponentString(String.format("Hashmap size is %d, %.2f", loadedChunks.size(), getFillLevel(loadedChunks)))); + } + + protected void inspect(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException, NoSuchFieldException, IllegalAccessException { + Long2ObjectOpenHashMap loadedChunks = this.getLoadedChunks(sender); + Object[] chunks = getValues(loadedChunks); + int mask = getMask(loadedChunks); + Integer start = 0, end = chunks.length; + Optional keyClass = Optional.empty(); + for (int i = 1; i < args.length; i++){ + switch (args[i]){ + case "from": + start = Integer.valueOf(args[++i]); + break; + case "to": + end = Integer.valueOf(args[++i]);; + break; + case "class": + keyClass = Optional.of(Long.valueOf(args[++i])); + break; + default: + throw new WrongUsageException(getUsage(sender)); + } + } + ArrayList inspections = new ArrayList<>(); + String last = ""; + int lastN = 0; + for (int i = start; (i & mask) != (end & mask); i++) { + Chunk chunk = (Chunk) chunks[i & mask]; + if(keyClass.isPresent()){ + if(chunk == null){ + if(!last.equals("null")){ + if(lastN > 0) + inspections.add(String.format("... %d %s", lastN, last)); + last = "null"; + lastN = 0; + } + lastN++; + continue; + } + if(getKeyClass(chunk, mask) != keyClass.get()){ + if(last != "chunks"){ + if(lastN > 0) + inspections.add(String.format("... %d %s", lastN, last)); + last = "chunks"; + lastN = 0; + } + lastN++; + continue; + } + } + if(last != ""){ + if(lastN > 0) + inspections.add(String.format("... %d %s", lastN, last)); + last = ""; + lastN = 0; + } + String formatted = formatChunk(chunk, i & mask, mask); + inspections.add(formatted); + + } + String result = inspections.stream().collect(Collectors.joining(", ", "[", "]")); + sender.sendMessage(new TextComponentString(result)); + } + protected void search(ICommandSender sender, int chunkX, int chunkZ) throws NoSuchFieldException, IllegalAccessException { Long2ObjectOpenHashMap loadedChunks = (Long2ObjectOpenHashMap) ((ChunkProviderServer) world.getChunkProvider()).loadedChunks; Object[] chunks = getValues(loadedChunks); From 61200eafdbcf762889fcd81228b1b10eeb0180bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=ADas=20Pierobon?= Date: Sun, 25 Jul 2021 19:10:18 -0300 Subject: [PATCH 04/46] feat(commands): Change dimensions on /tp --- carpetmodSrc/carpet/CarpetSettings.java | 3 ++ .../carpet/helpers/TeleportHelper.java | 41 +++++++++++++++++++ .../minecraft/command/CommandTP.java.patch | 28 ++++++++++++- 3 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 carpetmodSrc/carpet/helpers/TeleportHelper.java diff --git a/carpetmodSrc/carpet/CarpetSettings.java b/carpetmodSrc/carpet/CarpetSettings.java index 8850252c..eb0d31b6 100644 --- a/carpetmodSrc/carpet/CarpetSettings.java +++ b/carpetmodSrc/carpet/CarpetSettings.java @@ -225,6 +225,9 @@ private static boolean validateInstantScheduling(boolean value) { @Rule(desc = "Enables controlable TNT jump angle RNG for debuging.", category = TNT) public static boolean TNTAdjustableRandomAngle; + @Rule(desc = "/tp will teleport the players across dimensions", category = CREATIVE) + public static boolean tpAcrossDimensions = true; + @Rule(desc = "Allows to place blocks in different orientations. Requires Carpet Client", category = CREATIVE, extra = { "Also prevents rotations upon placement of dispensers and furnaces", "when placed into a world by commands" diff --git a/carpetmodSrc/carpet/helpers/TeleportHelper.java b/carpetmodSrc/carpet/helpers/TeleportHelper.java new file mode 100644 index 00000000..f1ac2775 --- /dev/null +++ b/carpetmodSrc/carpet/helpers/TeleportHelper.java @@ -0,0 +1,41 @@ +package carpet.helpers; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.network.play.server.SPacketRespawn; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.WorldServer; + +public class TeleportHelper { + + public static void changeDimensions(EntityPlayerMP player, EntityPlayerMP target){ + // Adapted from spectator teleport code (NetHandlerPlayServer::handleSpectate) + double x = target.posX; + double y = target.posY; + double z = target.posZ; + MinecraftServer server = player.getServer(); + assert server != null; + + WorldServer worldFrom = (WorldServer) player.world; + WorldServer worldTo = (WorldServer) target.world; + int dimension = worldTo.provider.getDimensionType().getId(); + player.dimension = dimension; + + player.connection.sendPacket(new SPacketRespawn(dimension, worldFrom.getDifficulty(), worldFrom.getWorldInfo().getTerrainType(), player.interactionManager.getGameType())); + server.getPlayerList().updatePermissionLevel(player); + worldFrom.removeEntityDangerously(player); + player.isDead = false; + player.setLocationAndAngles(x, y, z, (float) target.rotationYaw, (float) target.rotationPitch); + + worldFrom.updateEntityWithOptionalForce(player, false); + worldTo.spawnEntity(player); + worldTo.updateEntityWithOptionalForce(player, false); + + player.setWorld(worldTo); + server.getPlayerList().preparePlayer(player, worldFrom); + + player.setPositionAndUpdate(x, y, z); + player.interactionManager.setWorld(worldTo); + server.getPlayerList().updateTimeAndWeatherForPlayer(player, worldTo); + server.getPlayerList().syncPlayerInventory(player); + } +} diff --git a/patches/net/minecraft/command/CommandTP.java.patch b/patches/net/minecraft/command/CommandTP.java.patch index bd3825ad..e88950da 100644 --- a/patches/net/minecraft/command/CommandTP.java.patch +++ b/patches/net/minecraft/command/CommandTP.java.patch @@ -1,6 +1,15 @@ --- ../src-base/minecraft/net/minecraft/command/CommandTP.java +++ ../src-work/minecraft/net/minecraft/command/CommandTP.java -@@ -13,6 +13,10 @@ +@@ -5,6 +5,8 @@ + import java.util.List; + import java.util.Set; + import javax.annotation.Nullable; ++ ++import carpet.helpers.TeleportHelper; + import net.minecraft.entity.Entity; + import net.minecraft.entity.EntityLivingBase; + import net.minecraft.entity.player.EntityPlayerMP; +@@ -13,6 +15,10 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; @@ -11,7 +20,7 @@ public class CommandTP extends CommandBase { public String func_71517_b() -@@ -38,6 +42,17 @@ +@@ -38,6 +44,17 @@ } else { @@ -29,3 +38,18 @@ int i = 0; Entity entity; +@@ -73,7 +90,13 @@ + else + { + Entity entity1 = func_184885_b(p_184881_1_, p_184881_2_, p_184881_3_[p_184881_3_.length - 1]); +- ++ // CM ++ if(CarpetSettings.tpAcrossDimensions && (entity1.field_70170_p != entity.field_70170_p)){ ++ if(entity1 instanceof EntityPlayerMP && entity instanceof EntityPlayerMP){ ++ TeleportHelper.changeDimensions((EntityPlayerMP) entity, (EntityPlayerMP) entity1); ++ } ++ } ++ // CM END + if (entity1.field_70170_p != entity.field_70170_p) + { + throw new CommandException("commands.tp.notSameDimension", new Object[0]); From a6641a77e022017d84de5c67e7c7fdf6a715acc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=ADas=20Pierobon?= Date: Sun, 25 Jul 2021 20:25:52 -0300 Subject: [PATCH 05/46] Bump version to v21_07_25 --- carpetmodSrc/carpet/CarpetSettings.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/carpetmodSrc/carpet/CarpetSettings.java b/carpetmodSrc/carpet/CarpetSettings.java index eb0d31b6..2cf960fe 100644 --- a/carpetmodSrc/carpet/CarpetSettings.java +++ b/carpetmodSrc/carpet/CarpetSettings.java @@ -44,7 +44,7 @@ public class CarpetSettings public static boolean locked = false; // TODO: replace these constants at build time - public static final String carpetVersion = "v21_07_16"; + public static final String carpetVersion = "v21_07_25"; public static final String minecraftVersion = "1.12.2"; public static final String mcpMappings = "39-1.12"; From 847e7ec4629b62457e90bd77b82a07e56c3631db Mon Sep 17 00:00:00 2001 From: Jake K <68135816+Sylk0s@users.noreply.github.com> Date: Sat, 30 Oct 2021 13:41:53 -0400 Subject: [PATCH 06/46] added explosion logger (#163) * added explosion logger * Apply suggestions from code review Co-authored-by: Joseph Burton * Fixed explosion logger crash Co-authored-by: Joseph Burton --- carpetmodSrc/carpet/helpers/OptimizedTNT.java | 4 + .../carpet/logging/LoggerRegistry.java | 2 + .../logHelpers/ExplosionLogHelper.java | 104 ++++++++++++++++++ .../net/minecraft/world/Explosion.java.patch | 39 ++++++- .../minecraft/world/WorldServer.java.patch | 62 ++++++----- 5 files changed, 179 insertions(+), 32 deletions(-) create mode 100644 carpetmodSrc/carpet/logging/logHelpers/ExplosionLogHelper.java diff --git a/carpetmodSrc/carpet/helpers/OptimizedTNT.java b/carpetmodSrc/carpet/helpers/OptimizedTNT.java index 22064f18..8cbcf00c 100644 --- a/carpetmodSrc/carpet/helpers/OptimizedTNT.java +++ b/carpetmodSrc/carpet/helpers/OptimizedTNT.java @@ -249,6 +249,10 @@ public static void doExplosionB(Explosion e, boolean spawnParticles) } } } + + if(LoggerRegistry.__explosions) { + e.logHelper.onExplosionDone(e.world.getWorldTime()); + } } private static void removeFast(List lst, int index) { diff --git a/carpetmodSrc/carpet/logging/LoggerRegistry.java b/carpetmodSrc/carpet/logging/LoggerRegistry.java index 4aee0dd1..3d4b3237 100644 --- a/carpetmodSrc/carpet/logging/LoggerRegistry.java +++ b/carpetmodSrc/carpet/logging/LoggerRegistry.java @@ -47,6 +47,7 @@ public class LoggerRegistry public static boolean __instantComparators; public static boolean __items; public static boolean __rng; + public static boolean __explosions; public static boolean __recipes; public static boolean __damageDebug; public static boolean __invisDebug; @@ -66,6 +67,7 @@ public static void initLoggers(MinecraftServer server) registerLogger("instantComparators", new Logger(server, "instantComparators", "all", new String[]{"all", "tileTick", "buggy"}, LogHandler.CHAT)); registerLogger("items",new Logger(server, "items", "brief", new String[]{"brief", "full"}, LogHandler.CHAT)); registerLogger("rng", new Logger(server, "rng", null, null, LogHandler.CHAT)); + registerLogger("explosions", new Logger(server, "explosions", "compact", new String[]{"brief", "full", "compact"}, LogHandler.CHAT)); registerLogger("autosave", new Logger(server, "autosave", null, null, LogHandler.HUD)); registerLogger("tps", new Logger(server, "tps", null, null, LogHandler.HUD)); diff --git a/carpetmodSrc/carpet/logging/logHelpers/ExplosionLogHelper.java b/carpetmodSrc/carpet/logging/logHelpers/ExplosionLogHelper.java new file mode 100644 index 00000000..204d6702 --- /dev/null +++ b/carpetmodSrc/carpet/logging/logHelpers/ExplosionLogHelper.java @@ -0,0 +1,104 @@ +package carpet.logging.logHelpers; + +import carpet.logging.LoggerRegistry; +import carpet.utils.Messenger; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.Vec3d; +import net.minecraft.util.text.ITextComponent; + +public class ExplosionLogHelper { + + // CARPET-SYLKOS + // Some code yeeted from lntricarpet and gnembon 1.16+ fabric carpet + + public final Vec3d pos; + public final Entity entity; + private static boolean affectBlocks = false; // will be used later when I add in the full explosion logger + private static long lastGametime = 0; + private static long explosionCountInCurrentGT = 0; + private static long explosionCountInCurrentPos = 0; + public static Vec3d previousPosition = null; + public static long startTime = 0; + + public static boolean tickHasCompact = false; + + public ExplosionLogHelper(Entity entity, double x, double y, double z, float power, boolean createFire) { // blocks removed + this.entity = entity; + this.pos = new Vec3d(x, y, z); + } + + public void onExplosionDone(long gametime) { + if(lastGametime != gametime) { + explosionCountInCurrentGT = 1; + explosionCountInCurrentPos = 0; + previousPosition = pos; + lastGametime = gametime; + startTime = System.currentTimeMillis(); + LoggerRegistry.getLogger("explosions").log((option) -> { + return new ITextComponent[]{Messenger.m(null, "wb tick : ", "d " + gametime)}; + }); + } + + LoggerRegistry.getLogger("explosions").log((option) -> { + ITextComponent[] msg = null; + switch (option) { + case "brief": + msg = new ITextComponent[]{Messenger.m(null, + "d #" + explosionCountInCurrentGT, + "gb ->", + Messenger.dblt("l", pos.x, pos.y, pos.z), + (affectBlocks)?"m (affects blocks)":"m (doesn't affect blocks)" + )}; + explosionCountInCurrentGT++; + break; + + // temporarily removed "full" because its not really needed for my use case. may implement later - Sylkos + + case "compact": + tickHasCompact = true; + if(previousPosition != null && !pos.equals(previousPosition)) { + msg = new ITextComponent[]{Messenger.m(null, + "d #" + explosionCountInCurrentGT, + "gb ->", + "d " + explosionCountInCurrentPos + "x ", + Messenger.dblt("l", previousPosition.x, previousPosition.y, previousPosition.z), + (affectBlocks)?"m (affects blocks)":"m (doesn't affect blocks)", + "g (", "d " + (System.currentTimeMillis()-startTime), "g ms)" + )}; + explosionCountInCurrentGT += explosionCountInCurrentPos; + explosionCountInCurrentPos = 0; + previousPosition = pos; + startTime = System.currentTimeMillis(); + } + explosionCountInCurrentPos++; + break; + } + return msg; + }); + } + + public static void logLastExplosion() { + if(LoggerRegistry.__explosions) { + if (tickHasCompact) { + tickHasCompact = false; + LoggerRegistry.getLogger("explosions").log((option) -> { + ITextComponent[] msg = null; + if ("compact".equals(option)) { + if (previousPosition != null) { + msg = new ITextComponent[]{Messenger.m(null, + "d #" + (explosionCountInCurrentGT), + "gb ->", + "d " + explosionCountInCurrentPos + "x ", + Messenger.dblt("l", previousPosition.x, previousPosition.y, previousPosition.z), + (affectBlocks) ? "m (affects blocks)" : "m (doesn't affect blocks)", + "g (", "d " + (System.currentTimeMillis()-startTime), "g ms)" + )}; + } + startTime = 0; + } + return msg; + }); + } + } + } +} diff --git a/patches/net/minecraft/world/Explosion.java.patch b/patches/net/minecraft/world/Explosion.java.patch index 1747b682..636ab4c2 100644 --- a/patches/net/minecraft/world/Explosion.java.patch +++ b/patches/net/minecraft/world/Explosion.java.patch @@ -1,6 +1,14 @@ --- ../src-base/minecraft/net/minecraft/world/Explosion.java +++ ../src-work/minecraft/net/minecraft/world/Explosion.java -@@ -26,20 +26,26 @@ +@@ -1,5 +1,7 @@ + package net.minecraft.world; + ++import carpet.logging.LoggerRegistry; ++import carpet.logging.logHelpers.ExplosionLogHelper; + import com.google.common.collect.Lists; + import com.google.common.collect.Maps; + import com.google.common.collect.Sets; +@@ -26,20 +28,29 @@ import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; @@ -34,11 +42,22 @@ + // For disabling the explosion particles and sound CARPET-XCOM + public static int explosionSound = 0; ++ ++ // For explosion logger CARPET-SYLKOS ++ public ExplosionLogHelper logHelper = null; + public Explosion(World p_i45754_1_, Entity p_i45754_2_, double p_i45754_3_, double p_i45754_5_, double p_i45754_7_, float p_i45754_9_, boolean p_i45754_10_, boolean p_i45754_11_) { this.field_77287_j = p_i45754_1_; -@@ -54,6 +60,16 @@ +@@ -50,10 +61,24 @@ + this.field_77282_d = p_i45754_7_; + this.field_77286_a = p_i45754_10_; + this.field_82755_b = p_i45754_11_; ++ ++ if (LoggerRegistry.__explosions) { ++ this.logHelper = new ExplosionLogHelper(p_i45754_2_, p_i45754_3_, p_i45754_5_, p_i45754_7_, p_i45754_9_, p_i45754_10_); ++ } + } public void func_77278_a() { @@ -55,7 +74,7 @@ Set set = Sets.newHashSet(); int i = 16; -@@ -102,7 +118,7 @@ +@@ -102,7 +127,7 @@ } } @@ -64,7 +83,7 @@ float f3 = this.field_77280_f * 2.0F; int k1 = MathHelper.func_76128_c(this.field_77284_b - (double)f3 - 1.0D); int l1 = MathHelper.func_76128_c(this.field_77284_b + (double)f3 + 1.0D); -@@ -164,6 +180,14 @@ +@@ -164,6 +189,14 @@ public void func_77279_a(boolean p_77279_1_) { @@ -79,3 +98,15 @@ this.field_77287_j.func_184148_a((EntityPlayer)null, this.field_77284_b, this.field_77285_c, this.field_77282_d, SoundEvents.field_187539_bB, SoundCategory.BLOCKS, 4.0F, (1.0F + (this.field_77287_j.field_73012_v.nextFloat() - this.field_77287_j.field_73012_v.nextFloat()) * 0.2F) * 0.7F); if (this.field_77280_f >= 2.0F && this.field_82755_b) +@@ -226,6 +259,11 @@ + } + } + } ++ ++ // Logs explosion CARPET-SYLKOS ++ if(LoggerRegistry.__explosions) { ++ this.logHelper.onExplosionDone(this.field_77287_j.func_72820_D()); ++ } + } + + public Map func_77277_b() diff --git a/patches/net/minecraft/world/WorldServer.java.patch b/patches/net/minecraft/world/WorldServer.java.patch index f784eba2..dd81e0ca 100644 --- a/patches/net/minecraft/world/WorldServer.java.patch +++ b/patches/net/minecraft/world/WorldServer.java.patch @@ -1,14 +1,15 @@ --- ../src-base/minecraft/net/minecraft/world/WorldServer.java +++ ../src-work/minecraft/net/minecraft/world/WorldServer.java -@@ -1,5 +1,7 @@ +@@ -1,5 +1,8 @@ package net.minecraft.world; +import carpet.helpers.NextTickListEntryFix; +import carpet.helpers.ScheduledBlockEventSerializer; ++import carpet.logging.logHelpers.ExplosionLogHelper; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; -@@ -14,7 +16,6 @@ +@@ -14,7 +17,6 @@ import java.util.Set; import java.util.TreeSet; import java.util.UUID; @@ -16,7 +17,7 @@ import java.util.stream.Collectors; import javax.annotation.Nullable; import net.minecraft.advancements.AdvancementManager; -@@ -60,6 +61,7 @@ +@@ -60,6 +62,7 @@ import net.minecraft.util.math.ChunkPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; @@ -24,7 +25,7 @@ import net.minecraft.village.VillageCollection; import net.minecraft.village.VillageSiege; import net.minecraft.world.biome.Biome; -@@ -80,14 +82,23 @@ +@@ -80,14 +83,23 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -51,7 +52,7 @@ private final Map field_175741_N = Maps.newHashMap(); public boolean field_73058_d; private boolean field_73068_P; -@@ -99,6 +110,13 @@ +@@ -99,6 +111,13 @@ private int field_147489_T; private final List field_94579_S = Lists.newArrayList(); @@ -65,7 +66,7 @@ public WorldServer(MinecraftServer p_i45921_1_, ISaveHandler p_i45921_2_, WorldInfo p_i45921_3_, int p_i45921_4_, Profiler p_i45921_5_) { super(p_i45921_2_, p_i45921_3_, DimensionType.func_186069_a(p_i45921_4_).func_186070_d(), p_i45921_5_, false); -@@ -159,11 +177,24 @@ +@@ -159,11 +178,24 @@ this.func_175723_af().func_177750_a(this.field_72986_A.func_176137_E()); } @@ -90,7 +91,7 @@ super.func_72835_b(); if (this.func_72912_H().func_76093_s() && this.func_175659_aa() != EnumDifficulty.HARD) -@@ -184,15 +215,26 @@ +@@ -184,15 +216,26 @@ this.func_73053_d(); } @@ -117,7 +118,7 @@ int j = this.func_72967_a(1.0F); if (j != this.func_175657_ab()) -@@ -200,26 +242,76 @@ +@@ -200,26 +243,81 @@ this.func_175692_b(j); } @@ -192,11 +193,16 @@ + } + if(CarpetSettings.setSeed != 0){ + this.field_73012_v.setSeed(CarpetSettings.setSeed ^ 0x5DEECE66DL); ++ } ++ ++ // Solution for final explosion check -- not a great solution - CARPET-SYLKOS ++ if(LoggerRegistry.__explosions) { ++ ExplosionLogHelper.logLastExplosion(); + } } @Nullable -@@ -255,8 +347,15 @@ +@@ -255,8 +353,15 @@ ++j; } } @@ -214,7 +220,7 @@ } } -@@ -287,6 +386,28 @@ +@@ -287,6 +392,28 @@ { if (this.field_73068_P && !this.field_72995_K) { @@ -243,7 +249,7 @@ for (EntityPlayer entityplayer : this.field_73010_i) { if (!entityplayer.func_175149_v() && !entityplayer.func_71026_bH()) -@@ -303,7 +424,7 @@ +@@ -303,7 +430,7 @@ } } @@ -252,7 +258,7 @@ { return this.func_72863_F().func_73149_a(p_175680_1_, p_175680_2_); } -@@ -344,6 +465,7 @@ +@@ -344,6 +471,7 @@ boolean flag = this.func_72896_J(); boolean flag1 = this.func_72911_I(); this.field_72984_F.func_76320_a("pollingChunks"); @@ -260,7 +266,7 @@ for (Iterator iterator = this.field_73063_M.func_187300_b(); iterator.hasNext(); this.field_72984_F.func_76319_b()) { -@@ -355,9 +477,14 @@ +@@ -355,9 +483,14 @@ chunk.func_76594_o(); this.field_72984_F.func_76318_c("tickChunk"); chunk.func_150804_b(false); @@ -276,7 +282,7 @@ { this.field_73005_l = this.field_73005_l * 3 + 1013904223; int l = this.field_73005_l >> 2; -@@ -385,7 +512,7 @@ +@@ -385,7 +518,7 @@ this.field_72984_F.func_76318_c("iceandsnow"); @@ -285,7 +291,7 @@ { this.field_73005_l = this.field_73005_l * 3 + 1013904223; int j2 = this.field_73005_l >> 2; -@@ -443,7 +570,7 @@ +@@ -443,7 +576,7 @@ } } @@ -294,7 +300,7 @@ { BlockPos blockpos = this.func_175725_q(p_175736_1_); AxisAlignedBB axisalignedbb = (new AxisAlignedBB(blockpos, new BlockPos(blockpos.func_177958_n(), this.func_72800_K(), blockpos.func_177952_p()))).func_186662_g(3.0D); -@@ -472,13 +599,25 @@ +@@ -472,13 +605,25 @@ public boolean func_175691_a(BlockPos p_175691_1_, Block p_175691_2_) { @@ -322,7 +328,7 @@ return this.field_73064_N.contains(nextticklistentry); } -@@ -503,15 +642,22 @@ +@@ -503,15 +648,22 @@ { iblockstate.func_177230_c().func_180650_b(this, p_175654_1_, iblockstate, this.field_73012_v); } @@ -347,7 +353,7 @@ if (this.func_175667_e(p_175654_1_)) { -@@ -531,7 +677,13 @@ +@@ -531,7 +683,13 @@ public void func_180497_b(BlockPos p_180497_1_, Block p_180497_2_, int p_180497_3_, int p_180497_4_) { @@ -362,7 +368,7 @@ nextticklistentry.func_82753_a(p_180497_4_); Material material = p_180497_2_.func_176223_P().func_185904_a(); -@@ -549,7 +701,8 @@ +@@ -549,7 +707,8 @@ public void func_72939_s() { @@ -372,7 +378,7 @@ { if (this.field_80004_Q++ >= 300) { -@@ -644,9 +797,18 @@ +@@ -644,9 +803,18 @@ } else { @@ -393,7 +399,7 @@ } this.field_72984_F.func_76320_a("cleaning"); -@@ -677,6 +839,8 @@ +@@ -677,6 +845,8 @@ if (this.func_175707_a(nextticklistentry1.field_180282_a.func_177982_a(0, 0, 0), nextticklistentry1.field_180282_a.func_177982_a(0, 0, 0))) { @@ -402,7 +408,7 @@ IBlockState iblockstate = this.func_180495_p(nextticklistentry1.field_180282_a); if (iblockstate.func_185904_a() != Material.field_151579_a && Block.func_149680_a(iblockstate.func_177230_c(), nextticklistentry1.func_151351_a())) -@@ -699,6 +863,7 @@ +@@ -699,6 +869,7 @@ this.func_175684_a(nextticklistentry1.field_180282_a, nextticklistentry1.func_151351_a(), 0); } } @@ -410,7 +416,7 @@ this.field_72984_F.func_76319_b(); this.field_94579_S.clear(); -@@ -950,11 +1115,18 @@ +@@ -950,11 +1121,18 @@ chunkproviderserver.func_186027_a(p_73044_1_); @@ -430,7 +436,7 @@ } } } -@@ -1033,9 +1205,15 @@ +@@ -1033,9 +1211,15 @@ } else { @@ -446,7 +452,7 @@ return false; } -@@ -1055,6 +1233,7 @@ +@@ -1055,6 +1239,7 @@ this.field_175729_l.func_76038_a(p_72923_1_.func_145782_y(), p_72923_1_); this.field_175741_N.put(p_72923_1_.func_110124_au(), p_72923_1_); Entity[] aentity = p_72923_1_.func_70021_al(); @@ -454,7 +460,7 @@ if (aentity != null) { -@@ -1139,6 +1318,7 @@ +@@ -1139,6 +1324,7 @@ } this.field_147490_S[this.field_147489_T].add(blockeventdata); @@ -462,7 +468,7 @@ } private void func_147488_Z() -@@ -1150,14 +1330,19 @@ +@@ -1150,14 +1336,19 @@ for (BlockEventData blockeventdata : this.field_147490_S[i]) { @@ -482,7 +488,7 @@ } private boolean func_147485_a(BlockEventData p_147485_1_) -@@ -1299,4 +1484,19 @@ +@@ -1299,4 +1490,19 @@ { } } From eff0b254c242350472167309f637ad852865e6bc Mon Sep 17 00:00:00 2001 From: Jake K <68135816+Sylk0s@users.noreply.github.com> Date: Sun, 7 Nov 2021 18:33:04 -0500 Subject: [PATCH 07/46] added removeTNTVelocity rule (#164) --- carpetmodSrc/carpet/CarpetSettings.java | 4 ++++ carpetmodSrc/carpet/helpers/OptimizedTNT.java | 5 +++++ patches/net/minecraft/world/Explosion.java.patch | 12 +++++++++--- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/carpetmodSrc/carpet/CarpetSettings.java b/carpetmodSrc/carpet/CarpetSettings.java index 2cf960fe..e2b4c006 100644 --- a/carpetmodSrc/carpet/CarpetSettings.java +++ b/carpetmodSrc/carpet/CarpetSettings.java @@ -978,6 +978,10 @@ private static boolean validateTileTickLimit(int value) { @Rule(desc = "Changes default tnt fuse.", category = CREATIVE, validator = "validatePositive", options = {"70", "80", "100"}) public static int tntFuseLength = 80; + + @Rule(desc = "Removes tnt applying velocity to other entities.", category = CREATIVE) + public static boolean removeTNTVelocity = false; + // ===== API ===== // /** diff --git a/carpetmodSrc/carpet/helpers/OptimizedTNT.java b/carpetmodSrc/carpet/helpers/OptimizedTNT.java index 8cbcf00c..68b1fa46 100644 --- a/carpetmodSrc/carpet/helpers/OptimizedTNT.java +++ b/carpetmodSrc/carpet/helpers/OptimizedTNT.java @@ -96,6 +96,11 @@ public static void doExplosionA(Explosion e) { explosionSound++; + // CARPET-SYLKOS + // TNT shouldn't apply velocity to entities + // This also yeets all the calculations tnt does for applying velocity and damage to entities + if(CarpetSettings.removeTNTVelocity) return; + for (int k2 = 0; k2 < entitylist.size(); ++k2) { Entity entity = entitylist.get(k2); diff --git a/patches/net/minecraft/world/Explosion.java.patch b/patches/net/minecraft/world/Explosion.java.patch index 636ab4c2..0fcbfe8c 100644 --- a/patches/net/minecraft/world/Explosion.java.patch +++ b/patches/net/minecraft/world/Explosion.java.patch @@ -74,16 +74,22 @@ Set set = Sets.newHashSet(); int i = 16; -@@ -102,7 +127,7 @@ +@@ -102,7 +127,13 @@ } } - this.field_77281_g.addAll(set); + if(!CarpetSettings.explosionNoBlockDamage) this.field_77281_g.addAll(set); ++ ++ // CARPET-SYLKOS ++ // TNT shouldn't apply velocity to entities ++ // This also yeets all the calculations tnt does for applying velocity and damage to entities ++ if(CarpetSettings.removeTNTVelocity) return; ++ float f3 = this.field_77280_f * 2.0F; int k1 = MathHelper.func_76128_c(this.field_77284_b - (double)f3 - 1.0D); int l1 = MathHelper.func_76128_c(this.field_77284_b + (double)f3 + 1.0D); -@@ -164,6 +189,14 @@ +@@ -164,6 +195,14 @@ public void func_77279_a(boolean p_77279_1_) { @@ -98,7 +104,7 @@ this.field_77287_j.func_184148_a((EntityPlayer)null, this.field_77284_b, this.field_77285_c, this.field_77282_d, SoundEvents.field_187539_bB, SoundCategory.BLOCKS, 4.0F, (1.0F + (this.field_77287_j.field_73012_v.nextFloat() - this.field_77287_j.field_73012_v.nextFloat()) * 0.2F) * 0.7F); if (this.field_77280_f >= 2.0F && this.field_82755_b) -@@ -226,6 +259,11 @@ +@@ -226,6 +265,11 @@ } } } From a06917c6af2a967f25f9e84ae2cf8605d9ca615a Mon Sep 17 00:00:00 2001 From: Matias Pierobon Date: Wed, 10 Nov 2021 21:14:21 -0300 Subject: [PATCH 08/46] Add workflows for releasing Carpet zip (#166) * basic github actions * set temurin distribution for java workers * run gradle with stacktrace * skip prompt on env var --- .github/workflows/deploy.yaml | 71 ++++++++++++++++++++++++++++ .github/workflows/pull-requests.yaml | 34 +++++++++++++ build.gradle | 2 + 3 files changed, 107 insertions(+) create mode 100644 .github/workflows/deploy.yaml create mode 100644 .github/workflows/pull-requests.yaml diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml new file mode 100644 index 00000000..bfc67643 --- /dev/null +++ b/.github/workflows/deploy.yaml @@ -0,0 +1,71 @@ +name: deploy + +on: + push: + tags: + - 'v*' + +jobs: + release: + name: Create Release + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v2 + - name: Create Release + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.ref }} + release_name: Release ${{ github.ref }} + draft: false + prerelease: false + outputs: + release_url: ${{ steps.create_release.outputs.upload_url }} + + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - uses: actions/setup-java@v2 + with: + java-version: 8 + distribution: temurin + + - name: Set output + id: vars + run: echo ::set-output name=tag::${GITHUB_REF#refs/*/v} + + - name: Cache Gradle Packages + uses: actions/cache@v2 + with: + path: ~/.gradle/caches + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} + restore-keys: ${{ runner.os }}-gradle + + - name: Grant execute permissions to gradlew + run: chmod +x gradlew + + - name: Build gradle + env: + VERSION: ${{ steps.vars.outputs.tag }} + SKIP_PROMPT: true + run: | + ./gradlew --info --stacktrace setupCarpetmod + ./gradlew --info --stacktrace createRelease + mv build/distributions/Carpetmod_dev.zip build/distributions/Carpet_$VERSION.zip + + - name: Upload Release Asset + id: upload-release-asset + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ needs.release.outputs.release_url }} + asset_path: ./build/distributions + asset_name: Carpet_${{ steps.vars.outputs.tag }}.zip + asset_content_type: application/zip \ No newline at end of file diff --git a/.github/workflows/pull-requests.yaml b/.github/workflows/pull-requests.yaml new file mode 100644 index 00000000..57330768 --- /dev/null +++ b/.github/workflows/pull-requests.yaml @@ -0,0 +1,34 @@ +name: Build on Pull Request + +on: + - pull_request + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-java@v2 + with: + java-version: 8 + distribution: temurin + - name: Cache Gradle Packages + uses: actions/cache@v2 + with: + path: ~/.gradle/caches + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} + restore-keys: ${{ runner.os }}-gradle + - name: Grant execute permissions to gradlew + run: chmod +x gradlew + - name: Build gradle + env: + SKIP_PROMPT: true + run: | + ./gradlew --info --stacktrace setupCarpetmod + ./gradlew --info --stacktrace createRelease + + - uses: actions/upload-artifact@v2 + with: + name: carpet-dev-${{ github.event.number }} + path: build/distributions/Carpetmod_dev.zip diff --git a/build.gradle b/build.gradle index 77f56bbc..8f1858c0 100644 --- a/build.gradle +++ b/build.gradle @@ -143,6 +143,8 @@ gradle.taskGraph.whenReady void warnOverwrite() { + if (System.getenv("SKIP_PROMPT") != null) + return ant.input(message: 'WARNING: this will overwrite your working changes. Continue? (y/n)', addproperty: 'answer', defaultValue: 'y') def answer = ant.properties.answer.toLowerCase() if (answer != 'y' && answer != 'yes') From ccb8326a0d97d8b031c5438108213dcfc44c8e36 Mon Sep 17 00:00:00 2001 From: Matias Pierobon Date: Wed, 10 Nov 2021 21:15:39 -0300 Subject: [PATCH 09/46] remove info and stacktrace options from workflow --- .github/workflows/deploy.yaml | 4 ++-- .github/workflows/pull-requests.yaml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml index bfc67643..c190bd46 100644 --- a/.github/workflows/deploy.yaml +++ b/.github/workflows/deploy.yaml @@ -55,8 +55,8 @@ jobs: VERSION: ${{ steps.vars.outputs.tag }} SKIP_PROMPT: true run: | - ./gradlew --info --stacktrace setupCarpetmod - ./gradlew --info --stacktrace createRelease + ./gradlew setupCarpetmod + ./gradlew createRelease mv build/distributions/Carpetmod_dev.zip build/distributions/Carpet_$VERSION.zip - name: Upload Release Asset diff --git a/.github/workflows/pull-requests.yaml b/.github/workflows/pull-requests.yaml index 57330768..97403755 100644 --- a/.github/workflows/pull-requests.yaml +++ b/.github/workflows/pull-requests.yaml @@ -25,8 +25,8 @@ jobs: env: SKIP_PROMPT: true run: | - ./gradlew --info --stacktrace setupCarpetmod - ./gradlew --info --stacktrace createRelease + ./gradlew setupCarpetmod + ./gradlew createRelease - uses: actions/upload-artifact@v2 with: From db0b692ce3cce611efb74812917e94f20097f34b Mon Sep 17 00:00:00 2001 From: Matias Pierobon Date: Wed, 10 Nov 2021 21:16:38 -0300 Subject: [PATCH 10/46] bump version to v21_11_10 --- carpetmodSrc/carpet/CarpetSettings.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/carpetmodSrc/carpet/CarpetSettings.java b/carpetmodSrc/carpet/CarpetSettings.java index e2b4c006..98c4df49 100644 --- a/carpetmodSrc/carpet/CarpetSettings.java +++ b/carpetmodSrc/carpet/CarpetSettings.java @@ -44,7 +44,7 @@ public class CarpetSettings public static boolean locked = false; // TODO: replace these constants at build time - public static final String carpetVersion = "v21_07_25"; + public static final String carpetVersion = "v21_11_10"; public static final String minecraftVersion = "1.12.2"; public static final String mcpMappings = "39-1.12"; From d252551925fdf1062a314432d2bce50ab8732fb2 Mon Sep 17 00:00:00 2001 From: Matias Pierobon Date: Wed, 10 Nov 2021 21:20:06 -0300 Subject: [PATCH 11/46] fix typo in workflow --- .github/workflows/deploy.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml index c190bd46..0f9689b2 100644 --- a/.github/workflows/deploy.yaml +++ b/.github/workflows/deploy.yaml @@ -25,7 +25,7 @@ jobs: outputs: release_url: ${{ steps.create_release.outputs.upload_url }} - build: + build: runs-on: ubuntu-latest steps: From d35bed8cff2318f4131d5bbb83e968e2b2c685ce Mon Sep 17 00:00:00 2001 From: Jake K <68135816+Sylk0s@users.noreply.github.com> Date: Wed, 10 Nov 2021 19:23:04 -0500 Subject: [PATCH 12/46] Made TNT logger work with summoned TNT (#165) --- .../entity/item/EntityTNTPrimed.java.patch | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/patches/net/minecraft/entity/item/EntityTNTPrimed.java.patch b/patches/net/minecraft/entity/item/EntityTNTPrimed.java.patch index 998a627a..58ced6aa 100644 --- a/patches/net/minecraft/entity/item/EntityTNTPrimed.java.patch +++ b/patches/net/minecraft/entity/item/EntityTNTPrimed.java.patch @@ -1,6 +1,6 @@ --- ../src-base/minecraft/net/minecraft/entity/item/EntityTNTPrimed.java +++ ../src-work/minecraft/net/minecraft/entity/item/EntityTNTPrimed.java -@@ -11,17 +11,36 @@ +@@ -11,17 +11,43 @@ import net.minecraft.util.EnumParticleTypes; import net.minecraft.world.World; @@ -32,13 +32,20 @@ { super(p_i1729_1_); - this.field_70516_a = 80; ++ ++ if (LoggerRegistry.__tnt && logHelper == null) ++ { ++ logHelper = new TNTLogHelper(); ++ logHelper.onPrimed(this.field_70165_t,this.field_70163_u,this.field_70161_v,0); ++ } ++ + this.field_70516_a = CarpetSettings.tntFuseLength; //CM Vanilla default is 80gt + mergedTNT = 1; + mergeBool = false; this.field_70156_m = true; this.field_70178_ae = true; this.func_70105_a(0.98F, 0.98F); -@@ -31,11 +50,27 @@ +@@ -31,11 +57,27 @@ { this(p_i1730_1_); this.func_70107_b(p_i1730_2_, p_i1730_4_, p_i1730_6_); @@ -71,7 +78,7 @@ this.field_70169_q = p_i1730_2_; this.field_70167_r = p_i1730_4_; this.field_70166_s = p_i1730_6_; -@@ -68,18 +103,73 @@ +@@ -68,18 +110,73 @@ this.field_70181_x -= 0.03999999910593033D; } @@ -146,7 +153,7 @@ --this.field_70516_a; if (this.field_70516_a <= 0) -@@ -100,8 +190,14 @@ +@@ -100,8 +197,14 @@ private void func_70515_d() { @@ -162,7 +169,7 @@ } protected void func_70014_b(NBTTagCompound p_70014_1_) -@@ -148,4 +244,12 @@ +@@ -148,4 +251,12 @@ { return this.field_70516_a; } From 9527fd7a8c251f19fdc9b4bea362f13574fe33f9 Mon Sep 17 00:00:00 2001 From: Matias Pierobon Date: Wed, 10 Nov 2021 21:28:12 -0300 Subject: [PATCH 13/46] add release as dependency of build --- .github/workflows/deploy.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml index 0f9689b2..16c8bfc5 100644 --- a/.github/workflows/deploy.yaml +++ b/.github/workflows/deploy.yaml @@ -26,8 +26,9 @@ jobs: release_url: ${{ steps.create_release.outputs.upload_url }} build: + name: Build Carpetmod runs-on: ubuntu-latest - + needs: release steps: - uses: actions/checkout@v2 From 7fd04fe789d15b09f260ff9f8188a4aa6181a691 Mon Sep 17 00:00:00 2001 From: Matias Pierobon Date: Wed, 10 Nov 2021 21:28:21 -0300 Subject: [PATCH 14/46] Bump version to v21_11_10b --- carpetmodSrc/carpet/CarpetSettings.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/carpetmodSrc/carpet/CarpetSettings.java b/carpetmodSrc/carpet/CarpetSettings.java index 98c4df49..bd088303 100644 --- a/carpetmodSrc/carpet/CarpetSettings.java +++ b/carpetmodSrc/carpet/CarpetSettings.java @@ -44,7 +44,7 @@ public class CarpetSettings public static boolean locked = false; // TODO: replace these constants at build time - public static final String carpetVersion = "v21_11_10"; + public static final String carpetVersion = "v21_11_10b"; public static final String minecraftVersion = "1.12.2"; public static final String mcpMappings = "39-1.12"; From bf63a1ef79196b61aeadb1d09a7eed7747397aef Mon Sep 17 00:00:00 2001 From: Matias Pierobon Date: Wed, 10 Nov 2021 21:36:37 -0300 Subject: [PATCH 15/46] fix: use full name for uploading release --- .github/workflows/deploy.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml index 16c8bfc5..31245d31 100644 --- a/.github/workflows/deploy.yaml +++ b/.github/workflows/deploy.yaml @@ -67,6 +67,6 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: upload_url: ${{ needs.release.outputs.release_url }} - asset_path: ./build/distributions + asset_path: ./build/distributions/Carpet_${{ steps.vars.outputs.tag }}.zip asset_name: Carpet_${{ steps.vars.outputs.tag }}.zip asset_content_type: application/zip \ No newline at end of file From adf65aa539e5b31b7d1fca7f1f08de337a9b5d74 Mon Sep 17 00:00:00 2001 From: Matias Pierobon Date: Wed, 10 Nov 2021 21:37:44 -0300 Subject: [PATCH 16/46] Bump version to v21_11_10 --- carpetmodSrc/carpet/CarpetSettings.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/carpetmodSrc/carpet/CarpetSettings.java b/carpetmodSrc/carpet/CarpetSettings.java index bd088303..98c4df49 100644 --- a/carpetmodSrc/carpet/CarpetSettings.java +++ b/carpetmodSrc/carpet/CarpetSettings.java @@ -44,7 +44,7 @@ public class CarpetSettings public static boolean locked = false; // TODO: replace these constants at build time - public static final String carpetVersion = "v21_11_10b"; + public static final String carpetVersion = "v21_11_10"; public static final String minecraftVersion = "1.12.2"; public static final String mcpMappings = "39-1.12"; From 020b5e1121310f3d2d2ec525174efb943dc7f2d5 Mon Sep 17 00:00:00 2001 From: Joe Date: Mon, 6 Dec 2021 21:06:11 +0000 Subject: [PATCH 17/46] Fix worldedit --- jsons/1.12.2-dev.json | 6 +++--- jsons/1.12.2-rel.json | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/jsons/1.12.2-dev.json b/jsons/1.12.2-dev.json index d0cea265..c0c15a38 100644 --- a/jsons/1.12.2-dev.json +++ b/jsons/1.12.2-dev.json @@ -3,18 +3,18 @@ "libraries": [ { "name": "com.sk89q.worldedit:worldedit-core:6.1", - "url": "https://maven.sk89q.com/repo" + "url": "https://maven.enginehub.org/repo" }, { "name": "com.sk89q:jchronic:0.2.4a", - "url": "https://maven.sk89q.com/repo" + "url": "https://maven.enginehub.org/repo" }, { "name": "com.thoughtworks.paranamer:paranamer:2.6" }, { "name": "com.sk89q.lib:jlibnoise:1.0.0", - "url": "https://maven.sk89q.com/repo" + "url": "https://maven.enginehub.org/repo" } ] } diff --git a/jsons/1.12.2-rel.json b/jsons/1.12.2-rel.json index d0cea265..c0c15a38 100644 --- a/jsons/1.12.2-rel.json +++ b/jsons/1.12.2-rel.json @@ -3,18 +3,18 @@ "libraries": [ { "name": "com.sk89q.worldedit:worldedit-core:6.1", - "url": "https://maven.sk89q.com/repo" + "url": "https://maven.enginehub.org/repo" }, { "name": "com.sk89q:jchronic:0.2.4a", - "url": "https://maven.sk89q.com/repo" + "url": "https://maven.enginehub.org/repo" }, { "name": "com.thoughtworks.paranamer:paranamer:2.6" }, { "name": "com.sk89q.lib:jlibnoise:1.0.0", - "url": "https://maven.sk89q.com/repo" + "url": "https://maven.enginehub.org/repo" } ] } From 9c581205bf9888f5b6e5f4f937950b0b1119b081 Mon Sep 17 00:00:00 2001 From: Unknown Date: Thu, 20 Jan 2022 15:27:59 +0100 Subject: [PATCH 18/46] Added async block update fix when using async observers --- carpetmodSrc/carpet/CarpetSettings.java | 3 ++ .../management/PlayerChunkMap.java.patch | 34 +++++++++++++------ .../management/PlayerChunkMapEntry.java.patch | 3 +- .../world/gen/ChunkProviderServer.java.patch | 23 +++++++++---- 4 files changed, 45 insertions(+), 18 deletions(-) diff --git a/carpetmodSrc/carpet/CarpetSettings.java b/carpetmodSrc/carpet/CarpetSettings.java index 98c4df49..6103bad1 100644 --- a/carpetmodSrc/carpet/CarpetSettings.java +++ b/carpetmodSrc/carpet/CarpetSettings.java @@ -481,6 +481,9 @@ public static enum WhereToChunkSavestate { * Rules in this category should end with the "Fix" suffix */ + @Rule(desc = "Fixes the async packet bugs related to asynch observer updates.", category = FIX) + public static boolean asyncPacketUpdatesFix; + @Rule(desc = "Fixes the pearl bugs removing them when players relog, similar fix to mc1.15.", category = FIX) public static boolean fixedPearlBugs; diff --git a/patches/net/minecraft/server/management/PlayerChunkMap.java.patch b/patches/net/minecraft/server/management/PlayerChunkMap.java.patch index 18894b78..73f12699 100644 --- a/patches/net/minecraft/server/management/PlayerChunkMap.java.patch +++ b/patches/net/minecraft/server/management/PlayerChunkMap.java.patch @@ -11,7 +11,21 @@ import com.google.common.collect.Lists; import com.google.common.collect.Sets; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; -@@ -215,9 +217,17 @@ +@@ -129,6 +131,13 @@ + this.field_72697_d.clear(); + } + ++ // Fix for chunks not updating after async updates CARPET-PUNCHSTER ++ if(CarpetSettings.asyncPacketUpdatesFix) { ++ for(PlayerChunkMapEntry entry : field_111193_e){ ++ entry.field_187287_g = 0; ++ } ++ } ++ + if (this.field_187312_l && i % 4L == 0L) + { + this.field_187312_l = false; +@@ -215,9 +224,17 @@ if (!worldprovider.func_76567_e()) { @@ -29,7 +43,7 @@ } public boolean func_152621_a(int p_152621_1_, int p_152621_2_) -@@ -232,20 +242,22 @@ +@@ -232,20 +249,22 @@ return (PlayerChunkMapEntry)this.field_72700_c.get(func_187307_d(p_187301_1_, p_187301_2_)); } @@ -57,7 +71,7 @@ } if (!playerchunkmapentry.func_187272_b()) -@@ -271,8 +283,16 @@ +@@ -271,8 +290,16 @@ public void func_72683_a(EntityPlayerMP p_72683_1_) { @@ -76,7 +90,7 @@ p_72683_1_.field_71131_d = p_72683_1_.field_70165_t; p_72683_1_.field_71132_e = p_72683_1_.field_70161_v; -@@ -280,7 +300,7 @@ +@@ -280,7 +307,7 @@ { for (int l = j - this.field_72698_e; l <= j + this.field_72698_e; ++l) { @@ -85,7 +99,7 @@ } } -@@ -290,8 +310,16 @@ +@@ -290,8 +317,16 @@ public void func_72695_c(EntityPlayerMP p_72695_1_) { @@ -104,7 +118,7 @@ for (int k = i - this.field_72698_e; k <= i + this.field_72698_e; ++k) { -@@ -327,16 +355,32 @@ +@@ -327,16 +362,32 @@ public void func_72685_d(EntityPlayerMP p_72685_1_) { @@ -141,7 +155,7 @@ int i1 = this.field_72698_e; int j1 = i - k; int k1 = j - l; -@@ -349,7 +393,7 @@ +@@ -349,7 +400,7 @@ { if (!this.func_72684_a(l1, i2, k, l, i1)) { @@ -150,7 +164,7 @@ } if (!this.func_72684_a(l1 - j1, i2 - k1, i, j, i1)) -@@ -396,7 +440,7 @@ +@@ -396,7 +447,7 @@ { for (int k1 = k - p_152622_1_; k1 <= k + p_152622_1_; ++k1) { @@ -159,7 +173,7 @@ if (!playerchunkmapentry.func_187275_d(entityplayermp)) { -@@ -413,7 +457,7 @@ +@@ -413,7 +464,7 @@ { if (!this.func_72684_a(l, i1, j, k, p_152622_1_)) { @@ -168,7 +182,7 @@ } } } -@@ -460,7 +504,28 @@ +@@ -460,7 +511,28 @@ if (chunk != null) { diff --git a/patches/net/minecraft/server/management/PlayerChunkMapEntry.java.patch b/patches/net/minecraft/server/management/PlayerChunkMapEntry.java.patch index 68359010..b341f0eb 100644 --- a/patches/net/minecraft/server/management/PlayerChunkMapEntry.java.patch +++ b/patches/net/minecraft/server/management/PlayerChunkMapEntry.java.patch @@ -18,8 +18,9 @@ private final short[] field_187285_e = new short[64]; @Nullable - private Chunk field_187286_f; +- private int field_187287_g; + public Chunk field_187286_f; // CM: changed to public - private int field_187287_g; ++ public int field_187287_g; private int field_187288_h; private long field_187289_i; - private boolean field_187290_j; diff --git a/patches/net/minecraft/world/gen/ChunkProviderServer.java.patch b/patches/net/minecraft/world/gen/ChunkProviderServer.java.patch index b8e5c73e..9115bcc8 100644 --- a/patches/net/minecraft/world/gen/ChunkProviderServer.java.patch +++ b/patches/net/minecraft/world/gen/ChunkProviderServer.java.patch @@ -71,7 +71,7 @@ chunk.field_189550_d = false; } -@@ -93,9 +120,17 @@ +@@ -93,9 +120,26 @@ if (chunk != null) { @@ -79,6 +79,15 @@ + if(CarpetClientChunkLogger.logger.enabled) { + CarpetClientChunkLogger.logger.log(this.field_73251_h,p_186028_1_,p_186028_2_,CarpetClientChunkLogger.Event.LOADING); + } ++ ++ // Fix for chunks not updating after async updates CARPET-PUNCHSTER ++ if(CarpetSettings.asyncPacketUpdatesFix) { ++ PlayerChunkMapEntry entry = field_73251_h.field_73063_M.func_187301_b(p_186028_1_, p_186028_2_); ++ if (entry != null && entry.field_187286_f != null) { ++ entry.field_187286_f = chunk; ++ entry.func_187272_b(); ++ } ++ } + this.field_73244_f.put(ChunkPos.func_77272_a(p_186028_1_, p_186028_2_), chunk); chunk.func_76631_c(); @@ -89,7 +98,7 @@ } } -@@ -113,6 +148,11 @@ +@@ -113,6 +157,11 @@ try { chunk = this.field_186029_c.func_185932_a(p_186025_1_, p_186025_2_); @@ -101,7 +110,7 @@ } catch (Throwable throwable) { -@@ -123,7 +163,7 @@ +@@ -123,7 +172,7 @@ crashreportcategory.func_71507_a("Generator", this.field_186029_c); throw new ReportedException(crashreport); } @@ -110,7 +119,7 @@ this.field_73244_f.put(i, chunk); chunk.func_76631_c(); chunk.func_186030_a(this, this.field_186029_c); -@@ -185,6 +225,8 @@ +@@ -185,6 +234,8 @@ public boolean func_186027_a(boolean p_186027_1_) { @@ -119,7 +128,7 @@ int i = 0; List list = Lists.newArrayList(this.field_73244_f.values()); -@@ -222,8 +264,12 @@ +@@ -222,8 +273,12 @@ { if (!this.field_73251_h.field_73058_d) { @@ -133,7 +142,7 @@ Iterator iterator = this.field_73248_b.iterator(); for (int i = 0; i < 100 && iterator.hasNext(); iterator.remove()) -@@ -231,16 +277,47 @@ +@@ -231,16 +286,47 @@ Long olong = iterator.next(); Chunk chunk = (Chunk)this.field_73244_f.get(olong); @@ -182,7 +191,7 @@ this.field_73247_e.func_75817_a(); } -@@ -283,9 +360,17 @@ +@@ -283,9 +369,17 @@ { return this.field_73244_f.containsKey(ChunkPos.func_77272_a(p_73149_1_, p_73149_2_)); } From b2ee42904d7f97523efcafebc11d506eb2a6bcb1 Mon Sep 17 00:00:00 2001 From: Unknown Date: Thu, 20 Jan 2022 15:29:03 +0100 Subject: [PATCH 19/46] Added try catch in asynch beacon code --- .../minecraft/block/BlockBeacon.java.patch | 70 ++++++++++++++++++- 1 file changed, 68 insertions(+), 2 deletions(-) diff --git a/patches/net/minecraft/block/BlockBeacon.java.patch b/patches/net/minecraft/block/BlockBeacon.java.patch index e48b7c8c..8db61330 100644 --- a/patches/net/minecraft/block/BlockBeacon.java.patch +++ b/patches/net/minecraft/block/BlockBeacon.java.patch @@ -9,15 +9,81 @@ public class BlockBeacon extends BlockContainer { public BlockBeacon() -@@ -93,6 +95,11 @@ +@@ -93,6 +95,20 @@ ((TileEntityBeacon)tileentity).func_174908_m(); p_189540_2_.func_175641_c(p_189540_3_, this, 1, 0); } + + if (CarpetSettings.asyncBeaconUpdates && p_189540_2_.func_175640_z(p_189540_3_)) + { -+ HttpUtil.field_180193_a.submit(() -> p_189540_2_.func_175722_b(p_189540_3_, this, true)); ++ HttpUtil.field_180193_a.submit(() -> { ++ try { ++ p_189540_2_.func_175722_b(p_189540_3_, this, true); ++ } catch(Throwable e) { ++ e.printStackTrace(); ++ } finally { ++ System.out.println("Beacon thread exiting."); ++ } ++ }); + } } public static void func_176450_d(final World p_176450_0_, final BlockPos p_176450_1_) +@@ -101,35 +117,36 @@ + { + public void run() + { +- Chunk chunk = p_176450_0_.func_175726_f(p_176450_1_); ++ try { ++ Chunk chunk = p_176450_0_.func_175726_f(p_176450_1_); + +- for (int i = p_176450_1_.func_177956_o() - 1; i >= 0; --i) +- { +- final BlockPos blockpos = new BlockPos(p_176450_1_.func_177958_n(), i, p_176450_1_.func_177952_p()); ++ for (int i = p_176450_1_.func_177956_o() - 1; i >= 0; --i) { ++ final BlockPos blockpos = new BlockPos(p_176450_1_.func_177958_n(), i, p_176450_1_.func_177952_p()); + +- if (!chunk.func_177444_d(blockpos)) +- { +- break; +- } ++ if (!chunk.func_177444_d(blockpos)) { ++ break; ++ } + +- IBlockState iblockstate = p_176450_0_.func_180495_p(blockpos); ++ IBlockState iblockstate = p_176450_0_.func_180495_p(blockpos); + +- if (iblockstate.func_177230_c() == Blocks.field_150461_bJ) +- { +- ((WorldServer)p_176450_0_).func_152344_a(new Runnable() +- { +- public void run() +- { +- TileEntity tileentity = p_176450_0_.func_175625_s(blockpos); ++ if (iblockstate.func_177230_c() == Blocks.field_150461_bJ) { ++ ((WorldServer) p_176450_0_).func_152344_a(new Runnable() { ++ public void run() { ++ TileEntity tileentity = p_176450_0_.func_175625_s(blockpos); + +- if (tileentity instanceof TileEntityBeacon) +- { +- ((TileEntityBeacon)tileentity).func_174908_m(); +- p_176450_0_.func_175641_c(blockpos, Blocks.field_150461_bJ, 1, 0); ++ if (tileentity instanceof TileEntityBeacon) { ++ ((TileEntityBeacon) tileentity).func_174908_m(); ++ p_176450_0_.func_175641_c(blockpos, Blocks.field_150461_bJ, 1, 0); ++ } + } +- } +- }); ++ }); ++ } + } ++ } catch(Throwable e) { ++ e.printStackTrace(); ++ } finally { ++ System.out.println("Beacon thread exiting."); + } + } + }); From 312f9b326b014d27fd08703eb077b343f4d9aa12 Mon Sep 17 00:00:00 2001 From: Unknown Date: Thu, 20 Jan 2022 15:30:23 +0100 Subject: [PATCH 20/46] Added zetblock, copy of setblock can't be affected by fill updates --- .../carpet/commands/CarpetCommands.java | 1 + .../carpet/commands/CommandZetBlock.java | 183 ++++++++++++++++++ 2 files changed, 184 insertions(+) create mode 100644 carpetmodSrc/carpet/commands/CommandZetBlock.java diff --git a/carpetmodSrc/carpet/commands/CarpetCommands.java b/carpetmodSrc/carpet/commands/CarpetCommands.java index edc73117..15252176 100644 --- a/carpetmodSrc/carpet/commands/CarpetCommands.java +++ b/carpetmodSrc/carpet/commands/CarpetCommands.java @@ -42,6 +42,7 @@ public static void register(CommandHandler handler) { handler.registerCommand(new CommandUnload13()); handler.registerCommand(new CommandUpdateCarpet()); handler.registerCommand(new CommandWaypoint()); + handler.registerCommand(new CommandZetBlock()); // ----- RSMM Start ----- // handler.registerCommand(new MeterCommand(CarpetServer.rsmmServer)); diff --git a/carpetmodSrc/carpet/commands/CommandZetBlock.java b/carpetmodSrc/carpet/commands/CommandZetBlock.java new file mode 100644 index 00000000..11932326 --- /dev/null +++ b/carpetmodSrc/carpet/commands/CommandZetBlock.java @@ -0,0 +1,183 @@ +package carpet.commands; + +import carpet.CarpetSettings; +import carpet.helpers.CapturedDrops; +import carpet.worldedit.WorldEditBridge; +import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; +import net.minecraft.command.*; +import net.minecraft.command.server.CommandSetBlock; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.init.Blocks; +import net.minecraft.inventory.IInventory; +import net.minecraft.nbt.JsonToNBT; +import net.minecraft.nbt.NBTException; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.server.MinecraftServer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import javax.annotation.Nullable; +import java.util.Collections; +import java.util.List; + +public class CommandZetBlock extends CommandSetBlock { + /** + * Gets the name of the command + */ + public String getName() + { + return "zetblock"; + } + + /** + * Return the required permission level for this command. + */ + public int getRequiredPermissionLevel() + { + return 2; + } + + /** + * Gets the usage string for the command. + */ + public String getUsage(ICommandSender sender) + { + return "commands.setblock.usage"; + } + + /** + * Callback for when the command is executed + */ + public void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException + { + if (args.length < 4) + { + throw new WrongUsageException("commands.setblock.usage", new Object[0]); + } + else + { + sender.setCommandStat(CommandResultStats.Type.AFFECTED_BLOCKS, 0); + BlockPos blockpos = parseBlockPos(sender, args, 0, false); + Block block = CommandBase.getBlockByText(sender, args[3]); + IBlockState iblockstate; + + if (args.length >= 5) + { + iblockstate = convertArgToBlockState(block, args[4]); + } + else + { + iblockstate = block.getDefaultState(); + } + + World world = sender.getEntityWorld(); + + if (!world.isBlockLoaded(blockpos)) + { + throw new CommandException("commands.setblock.outOfWorld", new Object[0]); + } + else + { + NBTTagCompound nbttagcompound = new NBTTagCompound(); + boolean flag = false; + + if (args.length >= 7 && block.hasTileEntity()) + { + String s = buildString(args, 6); + + try + { + nbttagcompound = JsonToNBT.getTagFromJson(s); + flag = true; + } + catch (NBTException nbtexception) + { + throw new CommandException("commands.setblock.tagError", new Object[] {nbtexception.getMessage()}); + } + } + + EntityPlayerMP worldEditPlayer = sender instanceof EntityPlayerMP ? (EntityPlayerMP) sender : null; + NBTTagCompound worldEditTag = flag ? nbttagcompound : null; + + if (args.length >= 6) + { + if ("destroy".equals(args[5])) + { + WorldEditBridge.recordBlockEdit(worldEditPlayer, world, blockpos, Blocks.AIR.getDefaultState(), worldEditTag); + CapturedDrops.setCapturingDrops(true); + world.destroyBlock(blockpos, true); + CapturedDrops.setCapturingDrops(false); + for (EntityItem drop : CapturedDrops.getCapturedDrops()) + WorldEditBridge.recordEntityCreation(worldEditPlayer, world, drop); + CapturedDrops.clearCapturedDrops(); + + if (block == Blocks.AIR) + { + notifyCommandListener(sender, this, "commands.setblock.success", new Object[0]); + return; + } + } + else if ("keep".equals(args[5]) && !world.isAirBlock(blockpos)) + { + throw new CommandException("commands.setblock.noChange", new Object[0]); + } + } + + WorldEditBridge.recordBlockEdit(worldEditPlayer, world, blockpos, iblockstate, worldEditTag); + + TileEntity tileentity1 = world.getTileEntity(blockpos); + + if (tileentity1 != null && tileentity1 instanceof IInventory) + { + ((IInventory)tileentity1).clear(); + } + + if (!world.setBlockState(blockpos, iblockstate, 2)) + { + throw new CommandException("commands.setblock.noChange", new Object[0]); + } + else + { + if (flag) + { + TileEntity tileentity = world.getTileEntity(blockpos); + + if (tileentity != null) + { + nbttagcompound.setInteger("x", blockpos.getX()); + nbttagcompound.setInteger("y", blockpos.getY()); + nbttagcompound.setInteger("z", blockpos.getZ()); + tileentity.readFromNBT(nbttagcompound); + } + } + + world.notifyNeighborsRespectDebug(blockpos, iblockstate.getBlock(), false); + sender.setCommandStat(CommandResultStats.Type.AFFECTED_BLOCKS, 1); + notifyCommandListener(sender, this, "commands.setblock.success", new Object[0]); + } + } + } + } + + /** + * Get a list of options for when the user presses the TAB key + */ + public List getTabCompletions(MinecraftServer server, ICommandSender sender, String[] args, @Nullable BlockPos targetPos) + { + if (args.length > 0 && args.length <= 3) + { + return getTabCompletionCoordinate(args, 0, targetPos); + } + else if (args.length == 4) + { + return getListOfStringsMatchingLastWord(args, Block.REGISTRY.getKeys()); + } + else + { + return args.length == 6 ? getListOfStringsMatchingLastWord(args, new String[] {"replace", "destroy", "keep"}) : Collections.emptyList(); + } + } +} From d301a84d513a53838464facf8ed07779af612b48 Mon Sep 17 00:00:00 2001 From: Unknown Date: Thu, 20 Jan 2022 15:29:03 +0100 Subject: [PATCH 21/46] Revert "Added try catch in asynch beacon code" This reverts commit b2ee42904d7f97523efcafebc11d506eb2a6bcb1. --- .../minecraft/block/BlockBeacon.java.patch | 70 +------------------ 1 file changed, 2 insertions(+), 68 deletions(-) diff --git a/patches/net/minecraft/block/BlockBeacon.java.patch b/patches/net/minecraft/block/BlockBeacon.java.patch index 8db61330..e48b7c8c 100644 --- a/patches/net/minecraft/block/BlockBeacon.java.patch +++ b/patches/net/minecraft/block/BlockBeacon.java.patch @@ -9,81 +9,15 @@ public class BlockBeacon extends BlockContainer { public BlockBeacon() -@@ -93,6 +95,20 @@ +@@ -93,6 +95,11 @@ ((TileEntityBeacon)tileentity).func_174908_m(); p_189540_2_.func_175641_c(p_189540_3_, this, 1, 0); } + + if (CarpetSettings.asyncBeaconUpdates && p_189540_2_.func_175640_z(p_189540_3_)) + { -+ HttpUtil.field_180193_a.submit(() -> { -+ try { -+ p_189540_2_.func_175722_b(p_189540_3_, this, true); -+ } catch(Throwable e) { -+ e.printStackTrace(); -+ } finally { -+ System.out.println("Beacon thread exiting."); -+ } -+ }); ++ HttpUtil.field_180193_a.submit(() -> p_189540_2_.func_175722_b(p_189540_3_, this, true)); + } } public static void func_176450_d(final World p_176450_0_, final BlockPos p_176450_1_) -@@ -101,35 +117,36 @@ - { - public void run() - { -- Chunk chunk = p_176450_0_.func_175726_f(p_176450_1_); -+ try { -+ Chunk chunk = p_176450_0_.func_175726_f(p_176450_1_); - -- for (int i = p_176450_1_.func_177956_o() - 1; i >= 0; --i) -- { -- final BlockPos blockpos = new BlockPos(p_176450_1_.func_177958_n(), i, p_176450_1_.func_177952_p()); -+ for (int i = p_176450_1_.func_177956_o() - 1; i >= 0; --i) { -+ final BlockPos blockpos = new BlockPos(p_176450_1_.func_177958_n(), i, p_176450_1_.func_177952_p()); - -- if (!chunk.func_177444_d(blockpos)) -- { -- break; -- } -+ if (!chunk.func_177444_d(blockpos)) { -+ break; -+ } - -- IBlockState iblockstate = p_176450_0_.func_180495_p(blockpos); -+ IBlockState iblockstate = p_176450_0_.func_180495_p(blockpos); - -- if (iblockstate.func_177230_c() == Blocks.field_150461_bJ) -- { -- ((WorldServer)p_176450_0_).func_152344_a(new Runnable() -- { -- public void run() -- { -- TileEntity tileentity = p_176450_0_.func_175625_s(blockpos); -+ if (iblockstate.func_177230_c() == Blocks.field_150461_bJ) { -+ ((WorldServer) p_176450_0_).func_152344_a(new Runnable() { -+ public void run() { -+ TileEntity tileentity = p_176450_0_.func_175625_s(blockpos); - -- if (tileentity instanceof TileEntityBeacon) -- { -- ((TileEntityBeacon)tileentity).func_174908_m(); -- p_176450_0_.func_175641_c(blockpos, Blocks.field_150461_bJ, 1, 0); -+ if (tileentity instanceof TileEntityBeacon) { -+ ((TileEntityBeacon) tileentity).func_174908_m(); -+ p_176450_0_.func_175641_c(blockpos, Blocks.field_150461_bJ, 1, 0); -+ } - } -- } -- }); -+ }); -+ } - } -+ } catch(Throwable e) { -+ e.printStackTrace(); -+ } finally { -+ System.out.println("Beacon thread exiting."); - } - } - }); From 914a62d7b4f1a42c54d2cfbf05c5ed4d3ce77e86 Mon Sep 17 00:00:00 2001 From: Unknown Date: Thu, 20 Jan 2022 15:44:23 +0100 Subject: [PATCH 22/46] Re-added proper beacon try catch --- patches/net/minecraft/block/BlockBeacon.java.patch | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/patches/net/minecraft/block/BlockBeacon.java.patch b/patches/net/minecraft/block/BlockBeacon.java.patch index e48b7c8c..77b68ee6 100644 --- a/patches/net/minecraft/block/BlockBeacon.java.patch +++ b/patches/net/minecraft/block/BlockBeacon.java.patch @@ -9,14 +9,22 @@ public class BlockBeacon extends BlockContainer { public BlockBeacon() -@@ -93,6 +95,11 @@ +@@ -93,6 +95,20 @@ ((TileEntityBeacon)tileentity).func_174908_m(); p_189540_2_.func_175641_c(p_189540_3_, this, 1, 0); } + + if (CarpetSettings.asyncBeaconUpdates && p_189540_2_.func_175640_z(p_189540_3_)) + { -+ HttpUtil.field_180193_a.submit(() -> p_189540_2_.func_175722_b(p_189540_3_, this, true)); ++ HttpUtil.field_180193_a.submit(() -> { ++ try { ++ p_189540_2_.func_175722_b(p_189540_3_, this, true); ++ } catch(Throwable e) { ++ e.printStackTrace(); ++ } finally { ++ System.out.println("Beacon thread exiting."); ++ } ++ }); + } } From b3abf17bbd2783d99431c7a0db8d8cc7b98fb6f6 Mon Sep 17 00:00:00 2001 From: Unknown Date: Thu, 20 Jan 2022 16:37:06 +0100 Subject: [PATCH 23/46] Small fix for beacon patch --- patches/net/minecraft/block/BlockBeacon.java.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/patches/net/minecraft/block/BlockBeacon.java.patch b/patches/net/minecraft/block/BlockBeacon.java.patch index 77b68ee6..dbefa816 100644 --- a/patches/net/minecraft/block/BlockBeacon.java.patch +++ b/patches/net/minecraft/block/BlockBeacon.java.patch @@ -9,7 +9,7 @@ public class BlockBeacon extends BlockContainer { public BlockBeacon() -@@ -93,6 +95,20 @@ +@@ -93,6 +95,19 @@ ((TileEntityBeacon)tileentity).func_174908_m(); p_189540_2_.func_175641_c(p_189540_3_, this, 1, 0); } From 83788c7cef896728eff76e8f8afbaa9bee58d4d9 Mon Sep 17 00:00:00 2001 From: Unknown Date: Thu, 20 Jan 2022 16:37:40 +0100 Subject: [PATCH 24/46] Loaded chunk dump added --- .../carpet/commands/CarpetCommands.java | 1 + .../carpet/commands/CommandLoadedChunks.java | 31 ++++++++++++++++++- .../carpet/helpers/CustomHashMap.java | 21 +++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 carpetmodSrc/carpet/helpers/CustomHashMap.java diff --git a/carpetmodSrc/carpet/commands/CarpetCommands.java b/carpetmodSrc/carpet/commands/CarpetCommands.java index feaf886a..9198e725 100644 --- a/carpetmodSrc/carpet/commands/CarpetCommands.java +++ b/carpetmodSrc/carpet/commands/CarpetCommands.java @@ -43,6 +43,7 @@ public static void register(CommandHandler handler) { handler.registerCommand(new CommandUnload13()); handler.registerCommand(new CommandUpdateCarpet()); handler.registerCommand(new CommandWaypoint()); + handler.registerCommand(new CommandLoadedChunks()); handler.registerCommand(new CommandZetBlock()); // ----- RSMM Start ----- // diff --git a/carpetmodSrc/carpet/commands/CommandLoadedChunks.java b/carpetmodSrc/carpet/commands/CommandLoadedChunks.java index 4c115b91..235752c5 100644 --- a/carpetmodSrc/carpet/commands/CommandLoadedChunks.java +++ b/carpetmodSrc/carpet/commands/CommandLoadedChunks.java @@ -1,6 +1,8 @@ package carpet.commands; + import carpet.CarpetSettings; +import carpet.helpers.CustomHashMap; import it.unimi.dsi.fastutil.HashCommon; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import net.minecraft.command.CommandException; @@ -15,7 +17,11 @@ import net.minecraft.world.gen.ChunkProviderServer; import javax.annotation.Nullable; +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.PrintWriter; import java.lang.reflect.Field; +import java.text.SimpleDateFormat; import java.util.*; import java.util.stream.Collectors; @@ -43,6 +49,10 @@ public void execute(MinecraftServer server, ICommandSender sender, String[] args if (!command_enabled("commandLoadedChunks", sender)) return; if (args.length == 0) throw new WrongUsageException(getUsage(sender)); + world = sender.getEntityWorld(); + ChunkProviderServer provider = (ChunkProviderServer) world.getChunkProvider(); + CustomHashMap loadedChunks = (CustomHashMap) provider.loadedChunks; + try { switch (args[0]){ case "size": @@ -63,6 +73,25 @@ public void execute(MinecraftServer server, ICommandSender sender, String[] args case "inspect": inspect(server, sender, args); break; + case "dump": + String fileName = "loadedchunks-" + new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSSS").format(new Date()) + ".csv"; + try (PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(fileName)))) { + pw.println("index,key,x,z,hash"); + long[] keys = loadedChunks.getKey(); + Object[] values = loadedChunks.getValues(); + for (int i = 0, n = loadedChunks.getHashSize(); i <= n; i++) { + long key = keys[i]; + Chunk val = (Chunk) values[i]; + if (val == null) { + pw.println(i + ",,,,"); + } else { + pw.printf("%d,%d,%d,%d,%d\n", i, key, val.x, val.z, HashCommon.mix(key) & (n - 1)); + } + } + pw.flush(); + } + notifyCommandListener(sender, this, "Written to %s", fileName); + break; default: throw new WrongUsageException(getUsage(sender)); } @@ -253,7 +282,7 @@ public List getTabCompletions(MinecraftServer server, ICommandSender sen if (args.length == 1) { return getListOfStringsMatchingLastWord(args, - "size", "inspect", "search", "remove", "add"); + "size", "inspect", "search", "remove", "add", "dump"); } switch (args[0]){ diff --git a/carpetmodSrc/carpet/helpers/CustomHashMap.java b/carpetmodSrc/carpet/helpers/CustomHashMap.java new file mode 100644 index 00000000..eeff0368 --- /dev/null +++ b/carpetmodSrc/carpet/helpers/CustomHashMap.java @@ -0,0 +1,21 @@ +package carpet.helpers; + +import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; + +public class CustomHashMap extends Long2ObjectOpenHashMap { + public CustomHashMap(int expected) { + super(expected); + } + + public long[] getKey() { + return key; + } + + public V[] getValues() { + return value; + } + + public int getHashSize() { + return n; + } +} \ No newline at end of file From a887af4c668b77ec38382ba1f9826d035d0c734c Mon Sep 17 00:00:00 2001 From: Unknown Date: Thu, 20 Jan 2022 16:38:17 +0100 Subject: [PATCH 25/46] ITT update crash limiter added --- carpetmodSrc/carpet/CarpetServer.java | 1 + carpetmodSrc/carpet/CarpetSettings.java | 3 + .../minecraft/world/WorldServer.java.patch | 64 +++++++++++-------- 3 files changed, 42 insertions(+), 26 deletions(-) diff --git a/carpetmodSrc/carpet/CarpetServer.java b/carpetmodSrc/carpet/CarpetServer.java index 11b665aa..dd2e87ee 100644 --- a/carpetmodSrc/carpet/CarpetServer.java +++ b/carpetmodSrc/carpet/CarpetServer.java @@ -36,6 +36,7 @@ public class CarpetServer // static for now - easier to handle all around the co public static ToggleableChannelHandler rsmmChannel; public static ToggleableChannelHandler wecuiChannel; public static boolean playerInventoryStacking = false; + public static int limitITTCounter; private static CarpetClientServer CCServer; diff --git a/carpetmodSrc/carpet/CarpetSettings.java b/carpetmodSrc/carpet/CarpetSettings.java index c2e27459..94303b0b 100644 --- a/carpetmodSrc/carpet/CarpetSettings.java +++ b/carpetmodSrc/carpet/CarpetSettings.java @@ -487,6 +487,9 @@ public static enum WhereToChunkSavestate { * Rules in this category should end with the "Fix" suffix */ + @Rule(desc = "A limiter for updates happening on the main thread to prevent crashes on instant tile tick.", category = FIX, options = {"0", "1000000", "10000000"}) + public static int limitITTupdates = 0; + @Rule(desc = "Fixes the async packet bugs related to asynch observer updates.", category = FIX) public static boolean asyncPacketUpdatesFix; diff --git a/patches/net/minecraft/world/WorldServer.java.patch b/patches/net/minecraft/world/WorldServer.java.patch index dd81e0ca..9c2f5b5c 100644 --- a/patches/net/minecraft/world/WorldServer.java.patch +++ b/patches/net/minecraft/world/WorldServer.java.patch @@ -25,11 +25,12 @@ import net.minecraft.village.VillageCollection; import net.minecraft.village.VillageSiege; import net.minecraft.world.biome.Biome; -@@ -80,14 +83,23 @@ +@@ -80,14 +83,24 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import carpet.CarpetSettings; ++import carpet.CarpetServer; +import carpet.helpers.LagSpikeHelper; +import carpet.helpers.RandomTickOptimization; +import carpet.helpers.TickSpeed; @@ -52,7 +53,7 @@ private final Map field_175741_N = Maps.newHashMap(); public boolean field_73058_d; private boolean field_73068_P; -@@ -99,6 +111,13 @@ +@@ -99,6 +112,13 @@ private int field_147489_T; private final List field_94579_S = Lists.newArrayList(); @@ -66,7 +67,7 @@ public WorldServer(MinecraftServer p_i45921_1_, ISaveHandler p_i45921_2_, WorldInfo p_i45921_3_, int p_i45921_4_, Profiler p_i45921_5_) { super(p_i45921_2_, p_i45921_3_, DimensionType.func_186069_a(p_i45921_4_).func_186070_d(), p_i45921_5_, false); -@@ -159,11 +178,24 @@ +@@ -159,11 +179,28 @@ this.func_175723_af().func_177750_a(this.field_72986_A.func_176137_E()); } @@ -87,11 +88,15 @@ { + // [CM] Piston ghost blocks fix + this.blockActionsProcessed = false; -+ ++ // [CM] ITT crash fix reset ++ if(CarpetSettings.limitITTupdates > 0 && field_73061_a.func_152345_ab()) { ++ CarpetServer.limitITTCounter = 0; ++ } ++ super.func_72835_b(); if (this.func_72912_H().func_76093_s() && this.func_175659_aa() != EnumDifficulty.HARD) -@@ -184,15 +216,26 @@ +@@ -184,15 +221,26 @@ this.func_73053_d(); } @@ -118,7 +123,7 @@ int j = this.func_72967_a(1.0F); if (j != this.func_175657_ab()) -@@ -200,26 +243,81 @@ +@@ -200,26 +248,81 @@ this.func_175692_b(j); } @@ -202,7 +207,7 @@ } @Nullable -@@ -255,8 +353,15 @@ +@@ -255,8 +358,15 @@ ++j; } } @@ -220,7 +225,7 @@ } } -@@ -287,6 +392,28 @@ +@@ -287,6 +397,28 @@ { if (this.field_73068_P && !this.field_72995_K) { @@ -249,7 +254,7 @@ for (EntityPlayer entityplayer : this.field_73010_i) { if (!entityplayer.func_175149_v() && !entityplayer.func_71026_bH()) -@@ -303,7 +430,7 @@ +@@ -303,7 +435,7 @@ } } @@ -258,7 +263,7 @@ { return this.func_72863_F().func_73149_a(p_175680_1_, p_175680_2_); } -@@ -344,6 +471,7 @@ +@@ -344,6 +476,7 @@ boolean flag = this.func_72896_J(); boolean flag1 = this.func_72911_I(); this.field_72984_F.func_76320_a("pollingChunks"); @@ -266,7 +271,7 @@ for (Iterator iterator = this.field_73063_M.func_187300_b(); iterator.hasNext(); this.field_72984_F.func_76319_b()) { -@@ -355,9 +483,14 @@ +@@ -355,9 +488,14 @@ chunk.func_76594_o(); this.field_72984_F.func_76318_c("tickChunk"); chunk.func_150804_b(false); @@ -282,7 +287,7 @@ { this.field_73005_l = this.field_73005_l * 3 + 1013904223; int l = this.field_73005_l >> 2; -@@ -385,7 +518,7 @@ +@@ -385,7 +523,7 @@ this.field_72984_F.func_76318_c("iceandsnow"); @@ -291,7 +296,7 @@ { this.field_73005_l = this.field_73005_l * 3 + 1013904223; int j2 = this.field_73005_l >> 2; -@@ -443,7 +576,7 @@ +@@ -443,7 +581,7 @@ } } @@ -300,7 +305,7 @@ { BlockPos blockpos = this.func_175725_q(p_175736_1_); AxisAlignedBB axisalignedbb = (new AxisAlignedBB(blockpos, new BlockPos(blockpos.func_177958_n(), this.func_72800_K(), blockpos.func_177952_p()))).func_186662_g(3.0D); -@@ -472,13 +605,25 @@ +@@ -472,13 +610,25 @@ public boolean func_175691_a(BlockPos p_175691_1_, Block p_175691_2_) { @@ -328,8 +333,15 @@ return this.field_73064_N.contains(nextticklistentry); } -@@ -503,15 +648,22 @@ +@@ -501,17 +651,29 @@ + + if (iblockstate.func_185904_a() != Material.field_151579_a && iblockstate.func_177230_c() == p_175654_2_) { ++ // Limiter for instant tile ticks to prevent crashes CARPET-XCOM ++ if(CarpetSettings.limitITTupdates > 0 && field_73061_a.func_152345_ab()){ ++ CarpetServer.limitITTCounter++; ++ if(CarpetServer.limitITTCounter > CarpetSettings.limitITTupdates) return; ++ } iblockstate.func_177230_c().func_180650_b(this, p_175654_1_, iblockstate, this.field_73012_v); } + if(RandomTickOptimization.needsWorldGenFix) return; @@ -353,7 +365,7 @@ if (this.func_175667_e(p_175654_1_)) { -@@ -531,7 +683,13 @@ +@@ -531,7 +693,13 @@ public void func_180497_b(BlockPos p_180497_1_, Block p_180497_2_, int p_180497_3_, int p_180497_4_) { @@ -368,7 +380,7 @@ nextticklistentry.func_82753_a(p_180497_4_); Material material = p_180497_2_.func_176223_P().func_185904_a(); -@@ -549,7 +707,8 @@ +@@ -549,7 +717,8 @@ public void func_72939_s() { @@ -378,7 +390,7 @@ { if (this.field_80004_Q++ >= 300) { -@@ -644,9 +803,18 @@ +@@ -644,9 +813,18 @@ } else { @@ -399,7 +411,7 @@ } this.field_72984_F.func_76320_a("cleaning"); -@@ -677,6 +845,8 @@ +@@ -677,6 +855,8 @@ if (this.func_175707_a(nextticklistentry1.field_180282_a.func_177982_a(0, 0, 0), nextticklistentry1.field_180282_a.func_177982_a(0, 0, 0))) { @@ -408,7 +420,7 @@ IBlockState iblockstate = this.func_180495_p(nextticklistentry1.field_180282_a); if (iblockstate.func_185904_a() != Material.field_151579_a && Block.func_149680_a(iblockstate.func_177230_c(), nextticklistentry1.func_151351_a())) -@@ -699,6 +869,7 @@ +@@ -699,6 +879,7 @@ this.func_175684_a(nextticklistentry1.field_180282_a, nextticklistentry1.func_151351_a(), 0); } } @@ -416,7 +428,7 @@ this.field_72984_F.func_76319_b(); this.field_94579_S.clear(); -@@ -950,11 +1121,18 @@ +@@ -950,11 +1131,18 @@ chunkproviderserver.func_186027_a(p_73044_1_); @@ -436,7 +448,7 @@ } } } -@@ -1033,9 +1211,15 @@ +@@ -1033,9 +1221,15 @@ } else { @@ -452,7 +464,7 @@ return false; } -@@ -1055,6 +1239,7 @@ +@@ -1055,6 +1249,7 @@ this.field_175729_l.func_76038_a(p_72923_1_.func_145782_y(), p_72923_1_); this.field_175741_N.put(p_72923_1_.func_110124_au(), p_72923_1_); Entity[] aentity = p_72923_1_.func_70021_al(); @@ -460,7 +472,7 @@ if (aentity != null) { -@@ -1139,6 +1324,7 @@ +@@ -1139,6 +1334,7 @@ } this.field_147490_S[this.field_147489_T].add(blockeventdata); @@ -468,7 +480,7 @@ } private void func_147488_Z() -@@ -1150,14 +1336,19 @@ +@@ -1150,14 +1346,19 @@ for (BlockEventData blockeventdata : this.field_147490_S[i]) { @@ -488,7 +500,7 @@ } private boolean func_147485_a(BlockEventData p_147485_1_) -@@ -1299,4 +1490,19 @@ +@@ -1299,4 +1500,19 @@ { } } From 9cc89270fc5db692d10c913ac9d6ec36fa2b6990 Mon Sep 17 00:00:00 2001 From: Unknown Date: Thu, 20 Jan 2022 17:47:34 +0100 Subject: [PATCH 26/46] Fixed loadChunk and renamed --- .../carpet/commands/CarpetCommands.java | 1 + .../carpet/commands/CommandChunk.java | 16 ++++++------- .../carpet/commands/CommandLoadedChunks.java | 24 ++++++++++++++----- .../carpet/helpers/CustomHashMap.java | 21 ---------------- 4 files changed, 27 insertions(+), 35 deletions(-) delete mode 100644 carpetmodSrc/carpet/helpers/CustomHashMap.java diff --git a/carpetmodSrc/carpet/commands/CarpetCommands.java b/carpetmodSrc/carpet/commands/CarpetCommands.java index 9198e725..e879d628 100644 --- a/carpetmodSrc/carpet/commands/CarpetCommands.java +++ b/carpetmodSrc/carpet/commands/CarpetCommands.java @@ -43,6 +43,7 @@ public static void register(CommandHandler handler) { handler.registerCommand(new CommandUnload13()); handler.registerCommand(new CommandUpdateCarpet()); handler.registerCommand(new CommandWaypoint()); + handler.registerCommand(new CommandChunk()); handler.registerCommand(new CommandLoadedChunks()); handler.registerCommand(new CommandZetBlock()); diff --git a/carpetmodSrc/carpet/commands/CommandChunk.java b/carpetmodSrc/carpet/commands/CommandChunk.java index 59813139..c2b5565f 100644 --- a/carpetmodSrc/carpet/commands/CommandChunk.java +++ b/carpetmodSrc/carpet/commands/CommandChunk.java @@ -25,7 +25,7 @@ public class CommandChunk extends CommandCarpetBase public String getUsage(ICommandSender sender) { - return "Usage: chunk "; + return "Usage: chunk "; } public String getName() @@ -45,12 +45,12 @@ public void execute(MinecraftServer server, ICommandSender sender, String[] args throw new WrongUsageException(getUsage(sender)); } - int chunkX = parseChunkPosition(args[0], sender.getPosition().getX()); - int chunkZ = parseChunkPosition(args[1], sender.getPosition().getZ()); - world = sender.getEntityWorld(); try { - switch (args[2]){ + int chunkX = parseChunkPosition(args[1], sender.getPosition().getX()); + int chunkZ = parseChunkPosition(args[2], sender.getPosition().getZ()); + + switch (args[0]){ case "load": world.getChunk(chunkX, chunkZ); sender.sendMessage(new TextComponentString("Chunk " + chunkX + ", " + chunkZ + " loaded")); @@ -98,11 +98,11 @@ public List getTabCompletions(MinecraftServer server, ICommandSender sen int chunkZ = sender.getPosition().getZ() >> 4; if (args.length == 1) { - return getListOfStringsMatchingLastWord(args, Integer.toString(chunkX), "~"); + return getListOfStringsMatchingLastWord(args, "info", "load", "unload"); } else if (args.length == 2) { - return getListOfStringsMatchingLastWord(args, Integer.toString(chunkZ), "~"); + return getListOfStringsMatchingLastWord(args, Integer.toString(chunkX), "~"); } else if (args.length == 3) { - return getListOfStringsMatchingLastWord(args, "info", "load", "unload"); + return getListOfStringsMatchingLastWord(args, Integer.toString(chunkZ), "~"); } else { return Collections.emptyList(); } diff --git a/carpetmodSrc/carpet/commands/CommandLoadedChunks.java b/carpetmodSrc/carpet/commands/CommandLoadedChunks.java index 235752c5..a0a0cb92 100644 --- a/carpetmodSrc/carpet/commands/CommandLoadedChunks.java +++ b/carpetmodSrc/carpet/commands/CommandLoadedChunks.java @@ -2,8 +2,8 @@ import carpet.CarpetSettings; -import carpet.helpers.CustomHashMap; import it.unimi.dsi.fastutil.HashCommon; +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import net.minecraft.command.CommandException; import net.minecraft.command.ICommandSender; @@ -50,8 +50,6 @@ public void execute(MinecraftServer server, ICommandSender sender, String[] args if (args.length == 0) throw new WrongUsageException(getUsage(sender)); world = sender.getEntityWorld(); - ChunkProviderServer provider = (ChunkProviderServer) world.getChunkProvider(); - CustomHashMap loadedChunks = (CustomHashMap) provider.loadedChunks; try { switch (args[0]){ @@ -77,9 +75,10 @@ public void execute(MinecraftServer server, ICommandSender sender, String[] args String fileName = "loadedchunks-" + new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSSS").format(new Date()) + ".csv"; try (PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(fileName)))) { pw.println("index,key,x,z,hash"); - long[] keys = loadedChunks.getKey(); - Object[] values = loadedChunks.getValues(); - for (int i = 0, n = loadedChunks.getHashSize(); i <= n; i++) { + long[] keys = (long[]) getPrivateMethods(world, "key"); + Object[] values = (Object[]) getPrivateMethods(world, "value"); + int getHashSize = (int) getPrivateMethods(world, "n"); + for (int i = 0, n = getHashSize; i <= n; i++) { long key = keys[i]; Chunk val = (Chunk) values[i]; if (val == null) { @@ -102,6 +101,19 @@ public void execute(MinecraftServer server, ICommandSender sender, String[] args } + private Object getPrivateMethods(World world, String name){ + ChunkProviderServer provider = (ChunkProviderServer) world.getChunkProvider(); + Long2ObjectOpenHashMap loadedChunks = (Long2ObjectOpenHashMap) provider.loadedChunks; + try { + Field f = loadedChunks.getClass().getDeclaredField(name); + f.setAccessible(true); + return f.get(loadedChunks); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + protected Long2ObjectOpenHashMap getLoadedChunks (ICommandSender sender){ world = sender.getEntityWorld(); ChunkProviderServer provider = (ChunkProviderServer) world.getChunkProvider(); diff --git a/carpetmodSrc/carpet/helpers/CustomHashMap.java b/carpetmodSrc/carpet/helpers/CustomHashMap.java deleted file mode 100644 index eeff0368..00000000 --- a/carpetmodSrc/carpet/helpers/CustomHashMap.java +++ /dev/null @@ -1,21 +0,0 @@ -package carpet.helpers; - -import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; - -public class CustomHashMap extends Long2ObjectOpenHashMap { - public CustomHashMap(int expected) { - super(expected); - } - - public long[] getKey() { - return key; - } - - public V[] getValues() { - return value; - } - - public int getHashSize() { - return n; - } -} \ No newline at end of file From 4457194ae06280e0948ab48f9680878552be94d8 Mon Sep 17 00:00:00 2001 From: Unknown Date: Wed, 26 Jan 2022 16:26:33 +0100 Subject: [PATCH 27/46] Added regen and repop to chunk command --- .../carpet/commands/CommandChunk.java | 76 ++++++++++++++++++- 1 file changed, 74 insertions(+), 2 deletions(-) diff --git a/carpetmodSrc/carpet/commands/CommandChunk.java b/carpetmodSrc/carpet/commands/CommandChunk.java index c2b5565f..b72c2475 100644 --- a/carpetmodSrc/carpet/commands/CommandChunk.java +++ b/carpetmodSrc/carpet/commands/CommandChunk.java @@ -6,12 +6,16 @@ import net.minecraft.command.ICommandSender; import net.minecraft.command.WrongUsageException; import net.minecraft.server.MinecraftServer; +import net.minecraft.server.management.PlayerChunkMapEntry; +import net.minecraft.util.HttpUtil; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.ChunkPos; import net.minecraft.util.text.TextComponentString; import net.minecraft.world.World; +import net.minecraft.world.WorldServer; import net.minecraft.world.chunk.Chunk; import net.minecraft.world.gen.ChunkProviderServer; +import net.minecraft.world.gen.IChunkGenerator; import javax.annotation.Nullable; import java.util.Collections; @@ -25,7 +29,7 @@ public class CommandChunk extends CommandCarpetBase public String getUsage(ICommandSender sender) { - return "Usage: chunk "; + return "Usage: chunk "; } public String getName() @@ -58,6 +62,15 @@ public void execute(MinecraftServer server, ICommandSender sender, String[] args case "unload": unload(sender, chunkX, chunkZ); return; + case "regen": + regen(sender, chunkX, chunkZ); + return; + case "repop": + repop(sender, chunkX, chunkZ); + return; + case "asyncrepop": + asyncrepop(sender, chunkX, chunkZ); + return; case "info": default: info(sender, chunkX, chunkZ); @@ -68,6 +81,65 @@ public void execute(MinecraftServer server, ICommandSender sender, String[] args } } + private boolean checkRepopLoaded(int x, int z){ + return world.isChunkLoaded(x, z, false) + && world.isChunkLoaded(x+1, z, false) + && world.isChunkLoaded(x, z+1, false) + && world.isChunkLoaded(x+1, z+1, false); + } + + private void regen(ICommandSender sender, int x, int z) { + if(!checkRepopLoaded(x, z)) { + sender.sendMessage(new TextComponentString(("Area not loaded for re-population"))); + } + + ChunkProviderServer chunkProvider = (ChunkProviderServer) world.getChunkProvider(); + long i = ChunkPos.asLong(x, z); + chunkProvider.loadedChunks.remove(i); + Chunk chunk = chunkProvider.chunkGenerator.generateChunk(x, z); + chunkProvider.loadedChunks.put(i, chunk); + chunk.onLoad(); + chunk.setTerrainPopulated(true); + chunk.onTick(false); + PlayerChunkMapEntry entry = ((WorldServer)world).playerChunkMap.getEntry(x, z); + if (entry != null && entry.chunk != null) { + entry.chunk = chunk; + entry.sentToPlayers = false; + entry.sendToPlayers(); + } + } + + private void repop(ICommandSender sender, int x, int z) { + if(!checkRepopLoaded(x, z)) { + sender.sendMessage(new TextComponentString(("Area not loaded for re-population"))); + } + + ChunkProviderServer chunkProvider = (ChunkProviderServer) world.getChunkProvider(); + IChunkGenerator chunkGenerator = chunkProvider.chunkGenerator; + Chunk chunk = chunkProvider.loadChunk(x, z); + chunk.setUnpopulated(); + chunk.populate(chunkProvider, chunkGenerator); + } + + private void asyncrepop(ICommandSender sender, int x, int z) { + if(!checkRepopLoaded(x, z)) { + sender.sendMessage(new TextComponentString(("Area not loaded for re-population"))); + } + + HttpUtil.DOWNLOADER_EXECUTOR.submit(() -> { + try { + ChunkProviderServer chunkProvider = (ChunkProviderServer) world.getChunkProvider(); + IChunkGenerator chunkGenerator = chunkProvider.chunkGenerator; + Chunk chunk = chunkProvider.loadChunk(x, z); + chunk.setUnpopulated(); + chunk.populate(chunkProvider, chunkGenerator); + System.out.println("Chunk async repop end."); + } catch(Throwable e) { + e.printStackTrace(); + } + }); + } + protected void info(ICommandSender sender, int x, int z) throws NoSuchFieldException, IllegalAccessException { if(!world.isChunkLoaded(x, z, false)) { sender.sendMessage(new TextComponentString(("Chunk is not loaded"))); @@ -98,7 +170,7 @@ public List getTabCompletions(MinecraftServer server, ICommandSender sen int chunkZ = sender.getPosition().getZ() >> 4; if (args.length == 1) { - return getListOfStringsMatchingLastWord(args, "info", "load", "unload"); + return getListOfStringsMatchingLastWord(args, "info", "load", "unload", "regen", "repop", "asyncrepop"); } else if (args.length == 2) { return getListOfStringsMatchingLastWord(args, Integer.toString(chunkX), "~"); } else if (args.length == 3) { From 9b5f441a989a47c39a7c86dcccf8d5a29679e826 Mon Sep 17 00:00:00 2001 From: Unknown Date: Thu, 27 Jan 2022 00:16:24 +0100 Subject: [PATCH 28/46] Added proper crash report crashes with crash report fix Skyrising: Fixed stack-overflow crashes with crash report stack-overflowing with stack-overflow fix. --- .../net/minecraft/init/Bootstrap.java.patch | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/patches/net/minecraft/init/Bootstrap.java.patch b/patches/net/minecraft/init/Bootstrap.java.patch index c0803902..0e1fa9e0 100644 --- a/patches/net/minecraft/init/Bootstrap.java.patch +++ b/patches/net/minecraft/init/Bootstrap.java.patch @@ -21,7 +21,15 @@ import net.minecraft.block.BlockLiquid; import net.minecraft.block.BlockPumpkin; import net.minecraft.block.BlockShulkerBox; -@@ -58,11 +64,7 @@ +@@ -16,6 +22,7 @@ + import net.minecraft.block.BlockTNT; + import net.minecraft.block.material.Material; + import net.minecraft.block.state.IBlockState; ++import net.minecraft.crash.CrashReport; + import net.minecraft.dispenser.BehaviorDefaultDispenseItem; + import net.minecraft.dispenser.BehaviorProjectileDispense; + import net.minecraft.dispenser.IBehaviorDispenseItem; +@@ -58,11 +65,7 @@ import net.minecraft.tileentity.TileEntityDispenser; import net.minecraft.tileentity.TileEntityShulkerBox; import net.minecraft.tileentity.TileEntitySkull; @@ -34,7 +42,7 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.biome.Biome; -@@ -476,6 +478,9 @@ +@@ -476,6 +479,9 @@ } }); @@ -44,3 +52,14 @@ for (EnumDyeColor enumdyecolor : EnumDyeColor.values()) { BlockDispenser.field_149943_a.func_82595_a(Item.func_150898_a(BlockShulkerBox.func_190952_a(enumdyecolor)), new Bootstrap.BehaviorDispenseShulkerBox()); +@@ -486,6 +492,10 @@ + { + if (!field_151355_a) + { ++ // Fix the crash report without carpet rule. DON'T PUT A GOD-DAMN CARPET RULE FOR THIS OR I WILL GET MAD! ++ // Mojang even added this in 16. CARPET-XCOM ++ CrashReport.func_85055_a(new Exception(), "Dummy"); ++ + field_151355_a = true; + func_179868_d(); + SoundEvent.func_187504_b(); From 137ced3a0a3932d8dd0ff8b6b5885cc873aff3b5 Mon Sep 17 00:00:00 2001 From: Unknown Date: Thu, 27 Jan 2022 00:18:40 +0100 Subject: [PATCH 29/46] Added some json I have no clue about --- jsons/1.12.2.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsons/1.12.2.json b/jsons/1.12.2.json index dbe4d3f4..ce7b3798 100644 --- a/jsons/1.12.2.json +++ b/jsons/1.12.2.json @@ -1 +1 @@ -{"assetIndex": {"id": "1.12", "sha1": "1584b57c1a0b5e593fad1f5b8f78536ca640547b", "size": 143138, "totalSize": 129336389, "url": "https://launchermeta.mojang.com/v1/packages/1584b57c1a0b5e593fad1f5b8f78536ca640547b/1.12.json"}, "assets": "1.12", "downloads": {"client": {"sha1": "0f275bc1547d01fa5f56ba34bdc87d981ee12daf", "size": 10180113, "url": "https://launcher.mojang.com/v1/objects/0f275bc1547d01fa5f56ba34bdc87d981ee12daf/client.jar"}, "server": {"sha1": "886945bfb2b978778c3a0288fd7fab09d315b25f", "size": 30222121, "url": "https://launcher.mojang.com/v1/objects/886945bfb2b978778c3a0288fd7fab09d315b25f/server.jar"}}, "id": "1.12.2", "libraries": [{"downloads": {"artifact": {"path": "com/mojang/patchy/1.1/patchy-1.1.jar", "sha1": "aef610b34a1be37fa851825f12372b78424d8903", "size": 15817, "url": "https://libraries.minecraft.net/com/mojang/patchy/1.1/patchy-1.1.jar"}}, "name": "com.mojang:patchy:1.1"}, {"downloads": {"artifact": {"path": "oshi-project/oshi-core/1.1/oshi-core-1.1.jar", "sha1": "9ddf7b048a8d701be231c0f4f95fd986198fd2d8", "size": 30973, "url": "https://libraries.minecraft.net/oshi-project/oshi-core/1.1/oshi-core-1.1.jar"}}, "name": "oshi-project:oshi-core:1.1"}, {"downloads": {"artifact": {"path": "net/java/dev/jna/jna/4.4.0/jna-4.4.0.jar", "sha1": "cb208278274bf12ebdb56c61bd7407e6f774d65a", "size": 1091208, "url": "https://libraries.minecraft.net/net/java/dev/jna/jna/4.4.0/jna-4.4.0.jar"}}, "name": "net.java.dev.jna:jna:4.4.0"}, {"downloads": {"artifact": {"path": "net/java/dev/jna/platform/3.4.0/platform-3.4.0.jar", "sha1": "e3f70017be8100d3d6923f50b3d2ee17714e9c13", "size": 913436, "url": "https://libraries.minecraft.net/net/java/dev/jna/platform/3.4.0/platform-3.4.0.jar"}}, "name": "net.java.dev.jna:platform:3.4.0"}, {"downloads": {"artifact": {"path": "com/ibm/icu/icu4j-core-mojang/51.2/icu4j-core-mojang-51.2.jar", "sha1": "63d216a9311cca6be337c1e458e587f99d382b84", "size": 1634692, "url": "https://libraries.minecraft.net/com/ibm/icu/icu4j-core-mojang/51.2/icu4j-core-mojang-51.2.jar"}}, "name": "com.ibm.icu:icu4j-core-mojang:51.2"}, {"downloads": {"artifact": {"path": "net/sf/jopt-simple/jopt-simple/5.0.3/jopt-simple-5.0.3.jar", "sha1": "cdd846cfc4e0f7eefafc02c0f5dce32b9303aa2a", "size": 78175, "url": "https://libraries.minecraft.net/net/sf/jopt-simple/jopt-simple/5.0.3/jopt-simple-5.0.3.jar"}}, "name": "net.sf.jopt-simple:jopt-simple:5.0.3"}, {"downloads": {"artifact": {"path": "com/paulscode/codecjorbis/20101023/codecjorbis-20101023.jar", "sha1": "c73b5636faf089d9f00e8732a829577de25237ee", "size": 103871, "url": "https://libraries.minecraft.net/com/paulscode/codecjorbis/20101023/codecjorbis-20101023.jar"}}, "name": "com.paulscode:codecjorbis:20101023"}, {"downloads": {"artifact": {"path": "com/paulscode/codecwav/20101023/codecwav-20101023.jar", "sha1": "12f031cfe88fef5c1dd36c563c0a3a69bd7261da", "size": 5618, "url": "https://libraries.minecraft.net/com/paulscode/codecwav/20101023/codecwav-20101023.jar"}}, "name": "com.paulscode:codecwav:20101023"}, {"downloads": {"artifact": {"path": "com/paulscode/libraryjavasound/20101123/libraryjavasound-20101123.jar", "sha1": "5c5e304366f75f9eaa2e8cca546a1fb6109348b3", "size": 21679, "url": "https://libraries.minecraft.net/com/paulscode/libraryjavasound/20101123/libraryjavasound-20101123.jar"}}, "name": "com.paulscode:libraryjavasound:20101123"}, {"downloads": {"artifact": {"path": "com/paulscode/librarylwjglopenal/20100824/librarylwjglopenal-20100824.jar", "sha1": "73e80d0794c39665aec3f62eee88ca91676674ef", "size": 18981, "url": "https://libraries.minecraft.net/com/paulscode/librarylwjglopenal/20100824/librarylwjglopenal-20100824.jar"}}, "name": "com.paulscode:librarylwjglopenal:20100824"}, {"downloads": {"artifact": {"path": "com/paulscode/soundsystem/20120107/soundsystem-20120107.jar", "sha1": "419c05fe9be71f792b2d76cfc9b67f1ed0fec7f6", "size": 65020, "url": "https://libraries.minecraft.net/com/paulscode/soundsystem/20120107/soundsystem-20120107.jar"}}, "name": "com.paulscode:soundsystem:20120107"}, {"downloads": {"artifact": {"path": "io/netty/netty-all/4.1.9.Final/netty-all-4.1.9.Final.jar", "sha1": "0097860965d6a0a6b98e7f569f3f966727b8db75", "size": 3511093, "url": "https://libraries.minecraft.net/io/netty/netty-all/4.1.9.Final/netty-all-4.1.9.Final.jar"}}, "name": "io.netty:netty-all:4.1.9.Final"}, {"downloads": {"artifact": {"path": "com/google/guava/guava/21.0/guava-21.0.jar", "sha1": "3a3d111be1be1b745edfa7d91678a12d7ed38709", "size": 2521113, "url": "https://libraries.minecraft.net/com/google/guava/guava/21.0/guava-21.0.jar"}}, "name": "com.google.guava:guava:21.0"}, {"downloads": {"artifact": {"path": "org/apache/commons/commons-lang3/3.5/commons-lang3-3.5.jar", "sha1": "6c6c702c89bfff3cd9e80b04d668c5e190d588c6", "size": 479881, "url": "https://libraries.minecraft.net/org/apache/commons/commons-lang3/3.5/commons-lang3-3.5.jar"}}, "name": "org.apache.commons:commons-lang3:3.5"}, {"downloads": {"artifact": {"path": "commons-io/commons-io/2.5/commons-io-2.5.jar", "sha1": "2852e6e05fbb95076fc091f6d1780f1f8fe35e0f", "size": 208700, "url": "https://libraries.minecraft.net/commons-io/commons-io/2.5/commons-io-2.5.jar"}}, "name": "commons-io:commons-io:2.5"}, {"downloads": {"artifact": {"path": "commons-codec/commons-codec/1.10/commons-codec-1.10.jar", "sha1": "4b95f4897fa13f2cd904aee711aeafc0c5295cd8", "size": 284184, "url": "https://libraries.minecraft.net/commons-codec/commons-codec/1.10/commons-codec-1.10.jar"}}, "name": "commons-codec:commons-codec:1.10"}, {"downloads": {"artifact": {"path": "net/java/jinput/jinput/2.0.5/jinput-2.0.5.jar", "sha1": "39c7796b469a600f72380316f6b1f11db6c2c7c4", "size": 208338, "url": "https://libraries.minecraft.net/net/java/jinput/jinput/2.0.5/jinput-2.0.5.jar"}}, "name": "net.java.jinput:jinput:2.0.5"}, {"downloads": {"artifact": {"path": "net/java/jutils/jutils/1.0.0/jutils-1.0.0.jar", "sha1": "e12fe1fda814bd348c1579329c86943d2cd3c6a6", "size": 7508, "url": "https://libraries.minecraft.net/net/java/jutils/jutils/1.0.0/jutils-1.0.0.jar"}}, "name": "net.java.jutils:jutils:1.0.0"}, {"downloads": {"artifact": {"path": "com/google/code/gson/gson/2.8.0/gson-2.8.0.jar", "sha1": "c4ba5371a29ac9b2ad6129b1d39ea38750043eff", "size": 231952, "url": "https://libraries.minecraft.net/com/google/code/gson/gson/2.8.0/gson-2.8.0.jar"}}, "name": "com.google.code.gson:gson:2.8.0"}, {"downloads": {"artifact": {"path": "com/mojang/authlib/1.5.25/authlib-1.5.25.jar", "sha1": "9834cdf236c22e84b946bba989e2f94ef5897c3c", "size": 65621, "url": "https://libraries.minecraft.net/com/mojang/authlib/1.5.25/authlib-1.5.25.jar"}}, "name": "com.mojang:authlib:1.5.25"}, {"downloads": {"artifact": {"path": "com/mojang/realms/1.10.22/realms-1.10.22.jar", "sha1": "bd0dccebdf3744c75f1ca20063f16e8f7d5e663f", "size": 7135057, "url": "https://libraries.minecraft.net/com/mojang/realms/1.10.22/realms-1.10.22.jar"}}, "name": "com.mojang:realms:1.10.22"}, {"downloads": {"artifact": {"path": "org/apache/commons/commons-compress/1.8.1/commons-compress-1.8.1.jar", "sha1": "a698750c16740fd5b3871425f4cb3bbaa87f529d", "size": 365552, "url": "https://libraries.minecraft.net/org/apache/commons/commons-compress/1.8.1/commons-compress-1.8.1.jar"}}, "name": "org.apache.commons:commons-compress:1.8.1"}, {"downloads": {"artifact": {"path": "org/apache/httpcomponents/httpclient/4.3.3/httpclient-4.3.3.jar", "sha1": "18f4247ff4572a074444572cee34647c43e7c9c7", "size": 589512, "url": "https://libraries.minecraft.net/org/apache/httpcomponents/httpclient/4.3.3/httpclient-4.3.3.jar"}}, "name": "org.apache.httpcomponents:httpclient:4.3.3"}, {"downloads": {"artifact": {"path": "commons-logging/commons-logging/1.1.3/commons-logging-1.1.3.jar", "sha1": "f6f66e966c70a83ffbdb6f17a0919eaf7c8aca7f", "size": 62050, "url": "https://libraries.minecraft.net/commons-logging/commons-logging/1.1.3/commons-logging-1.1.3.jar"}}, "name": "commons-logging:commons-logging:1.1.3"}, {"downloads": {"artifact": {"path": "org/apache/httpcomponents/httpcore/4.3.2/httpcore-4.3.2.jar", "sha1": "31fbbff1ddbf98f3aa7377c94d33b0447c646b6e", "size": 282269, "url": "https://libraries.minecraft.net/org/apache/httpcomponents/httpcore/4.3.2/httpcore-4.3.2.jar"}}, "name": "org.apache.httpcomponents:httpcore:4.3.2"}, {"downloads": {"artifact": {"path": "it/unimi/dsi/fastutil/7.1.0/fastutil-7.1.0.jar", "sha1": "9835253257524c1be7ab50c057aa2d418fb72082", "size": 17655579, "url": "https://libraries.minecraft.net/it/unimi/dsi/fastutil/7.1.0/fastutil-7.1.0.jar"}}, "name": "it.unimi.dsi:fastutil:7.1.0"}, {"downloads": {"artifact": {"path": "org/apache/logging/log4j/log4j-api/2.8.1/log4j-api-2.8.1.jar", "sha1": "e801d13612e22cad62a3f4f3fe7fdbe6334a8e72", "size": 228859, "url": "https://libraries.minecraft.net/org/apache/logging/log4j/log4j-api/2.8.1/log4j-api-2.8.1.jar"}}, "name": "org.apache.logging.log4j:log4j-api:2.8.1"}, {"downloads": {"artifact": {"path": "org/apache/logging/log4j/log4j-core/2.8.1/log4j-core-2.8.1.jar", "sha1": "4ac28ff2f1ddf05dae3043a190451e8c46b73c31", "size": 1402925, "url": "https://libraries.minecraft.net/org/apache/logging/log4j/log4j-core/2.8.1/log4j-core-2.8.1.jar"}}, "name": "org.apache.logging.log4j:log4j-core:2.8.1"}, {"downloads": {"artifact": {"path": "org/lwjgl/lwjgl/lwjgl/2.9.4-nightly-20150209/lwjgl-2.9.4-nightly-20150209.jar", "sha1": "697517568c68e78ae0b4544145af031c81082dfe", "size": 1047168, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl/2.9.4-nightly-20150209/lwjgl-2.9.4-nightly-20150209.jar"}}, "name": "org.lwjgl.lwjgl:lwjgl:2.9.4-nightly-20150209", "rules": [{"action": "allow"}, {"action": "disallow", "os": {"name": "osx"}}]}, {"downloads": {"artifact": {"path": "org/lwjgl/lwjgl/lwjgl_util/2.9.4-nightly-20150209/lwjgl_util-2.9.4-nightly-20150209.jar", "sha1": "d51a7c040a721d13efdfbd34f8b257b2df882ad0", "size": 173887, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl_util/2.9.4-nightly-20150209/lwjgl_util-2.9.4-nightly-20150209.jar"}}, "name": "org.lwjgl.lwjgl:lwjgl_util:2.9.4-nightly-20150209", "rules": [{"action": "allow"}, {"action": "disallow", "os": {"name": "osx"}}]}, {"downloads": {"artifact": {"path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209.jar", "sha1": "b04f3ee8f5e43fa3b162981b50bb72fe1acabb33", "size": 22, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209.jar"}, "classifiers": {"natives-linux": {"path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-linux.jar", "sha1": "931074f46c795d2f7b30ed6395df5715cfd7675b", "size": 578680, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-linux.jar"}, "natives-osx": {"path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar", "sha1": "bcab850f8f487c3f4c4dbabde778bb82bd1a40ed", "size": 426822, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar"}, "natives-windows": {"path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-windows.jar", "sha1": "b84d5102b9dbfabfeb5e43c7e2828d98a7fc80e0", "size": 613748, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-windows.jar"}}}, "extract": {"exclude": ["META-INF/"]}, "name": "org.lwjgl.lwjgl:lwjgl-platform:2.9.4-nightly-20150209", "natives": {"linux": "natives-linux", "osx": "natives-osx", "windows": "natives-windows"}, "rules": [{"action": "allow"}, {"action": "disallow", "os": {"name": "osx"}}]}, {"downloads": {"artifact": {"path": "org/lwjgl/lwjgl/lwjgl/2.9.2-nightly-20140822/lwjgl-2.9.2-nightly-20140822.jar", "sha1": "7707204c9ffa5d91662de95f0a224e2f721b22af", "size": 1045632, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl/2.9.2-nightly-20140822/lwjgl-2.9.2-nightly-20140822.jar"}}, "name": "org.lwjgl.lwjgl:lwjgl:2.9.2-nightly-20140822", "rules": [{"action": "allow", "os": {"name": "osx"}}]}, {"downloads": {"artifact": {"path": "org/lwjgl/lwjgl/lwjgl_util/2.9.2-nightly-20140822/lwjgl_util-2.9.2-nightly-20140822.jar", "sha1": "f0e612c840a7639c1f77f68d72a28dae2f0c8490", "size": 173887, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl_util/2.9.2-nightly-20140822/lwjgl_util-2.9.2-nightly-20140822.jar"}}, "name": "org.lwjgl.lwjgl:lwjgl_util:2.9.2-nightly-20140822", "rules": [{"action": "allow", "os": {"name": "osx"}}]}, {"downloads": {"classifiers": {"natives-linux": {"path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.2-nightly-20140822/lwjgl-platform-2.9.2-nightly-20140822-natives-linux.jar", "sha1": "d898a33b5d0a6ef3fed3a4ead506566dce6720a5", "size": 578539, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.2-nightly-20140822/lwjgl-platform-2.9.2-nightly-20140822-natives-linux.jar"}, "natives-osx": {"path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.2-nightly-20140822/lwjgl-platform-2.9.2-nightly-20140822-natives-osx.jar", "sha1": "79f5ce2fea02e77fe47a3c745219167a542121d7", "size": 468116, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.2-nightly-20140822/lwjgl-platform-2.9.2-nightly-20140822-natives-osx.jar"}, "natives-windows": {"path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.2-nightly-20140822/lwjgl-platform-2.9.2-nightly-20140822-natives-windows.jar", "sha1": "78b2a55ce4dc29c6b3ec4df8ca165eba05f9b341", "size": 613680, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.2-nightly-20140822/lwjgl-platform-2.9.2-nightly-20140822-natives-windows.jar"}}}, "extract": {"exclude": ["META-INF/"]}, "name": "org.lwjgl.lwjgl:lwjgl-platform:2.9.2-nightly-20140822", "natives": {"linux": "natives-linux", "osx": "natives-osx", "windows": "natives-windows"}, "rules": [{"action": "allow", "os": {"name": "osx"}}]}, {"downloads": {"classifiers": {"natives-linux": {"path": "net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-linux.jar", "sha1": "7ff832a6eb9ab6a767f1ade2b548092d0fa64795", "size": 10362, "url": "https://libraries.minecraft.net/net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-linux.jar"}, "natives-osx": {"path": "net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-osx.jar", "sha1": "53f9c919f34d2ca9de8c51fc4e1e8282029a9232", "size": 12186, "url": "https://libraries.minecraft.net/net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-osx.jar"}, "natives-windows": {"path": "net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-windows.jar", "sha1": "385ee093e01f587f30ee1c8a2ee7d408fd732e16", "size": 155179, "url": "https://libraries.minecraft.net/net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-windows.jar"}}}, "extract": {"exclude": ["META-INF/"]}, "name": "net.java.jinput:jinput-platform:2.0.5", "natives": {"linux": "natives-linux", "osx": "natives-osx", "windows": "natives-windows"}}, {"downloads": {"artifact": {"path": "com/mojang/text2speech/1.10.3/text2speech-1.10.3.jar", "sha1": "48fd510879dff266c3815947de66e3d4809f8668", "size": 11055, "url": "https://libraries.minecraft.net/com/mojang/text2speech/1.10.3/text2speech-1.10.3.jar"}}, "name": "com.mojang:text2speech:1.10.3"}, {"downloads": {"artifact": {"path": "com/mojang/text2speech/1.10.3/text2speech-1.10.3.jar", "sha1": "48fd510879dff266c3815947de66e3d4809f8668", "size": 11055, "url": "https://libraries.minecraft.net/com/mojang/text2speech/1.10.3/text2speech-1.10.3.jar"}, "classifiers": {"natives-linux": {"path": "com/mojang/text2speech/1.10.3/text2speech-1.10.3-natives-linux.jar", "sha1": "ab7896aec3b3dd272b06194357f2d98f832c0cfc", "size": 7833, "url": "https://libraries.minecraft.net/com/mojang/text2speech/1.10.3/text2speech-1.10.3-natives-linux.jar"}, "natives-windows": {"path": "com/mojang/text2speech/1.10.3/text2speech-1.10.3-natives-windows.jar", "sha1": "84a4b856389cc4f485275b1f63497a95a857a443", "size": 81217, "url": "https://libraries.minecraft.net/com/mojang/text2speech/1.10.3/text2speech-1.10.3-natives-windows.jar"}, "sources": {"path": "com/mojang/text2speech/1.10.3/text2speech-1.10.3-sources.jar", "sha1": "404339fe43d1011ee046a249b0ec7ae9ce04a834", "size": 4632, "url": "https://libraries.minecraft.net/com/mojang/text2speech/1.10.3/text2speech-1.10.3-sources.jar"}}}, "extract": {"exclude": ["META-INF/"]}, "name": "com.mojang:text2speech:1.10.3", "natives": {"linux": "natives-linux", "windows": "natives-windows"}}, {"downloads": {"artifact": {"path": "ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0.jar", "sha1": "6ef160c3133a78de015830860197602ca1c855d3", "size": 40502, "url": "https://libraries.minecraft.net/ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0.jar"}, "classifiers": {"javadoc": {"path": "ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0-javadoc.jar", "sha1": "fb0092f22cb4fe8e631452f577b7a238778abf2a", "size": 174060, "url": "https://libraries.minecraft.net/ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0-javadoc.jar"}, "natives-osx": {"path": "ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0-natives-osx.jar", "sha1": "08befab4894d55875f33c3d300f4f71e6e828f64", "size": 5629, "url": "https://libraries.minecraft.net/ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0-natives-osx.jar"}, "sources": {"path": "ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0-sources.jar", "sha1": "865837a198189aee737019561ece842827f24278", "size": 43283, "url": "https://libraries.minecraft.net/ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0-sources.jar"}}}, "extract": {"exclude": ["META-INF/"]}, "name": "ca.weblite:java-objc-bridge:1.0.0", "natives": {"osx": "natives-osx"}, "rules": [{"action": "allow", "os": {"name": "osx"}}]}, {"downloads": {"artifact": {"path": "ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0.jar", "sha1": "6ef160c3133a78de015830860197602ca1c855d3", "size": 40502, "url": "https://libraries.minecraft.net/ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0.jar"}}, "name": "ca.weblite:java-objc-bridge:1.0.0", "rules": [{"action": "allow", "os": {"name": "osx"}}]}], "logging": {"client": {"argument": "-Dlog4j.configurationFile=${path}", "file": {"id": "client-1.12.xml", "sha1": "ef4f57b922df243d0cef096efe808c72db042149", "size": 877, "url": "https://launcher.mojang.com/v1/objects/ef4f57b922df243d0cef096efe808c72db042149/client-1.12.xml"}, "type": "log4j2-xml"}}, "mainClass": "net.minecraft.client.main.Main", "minecraftArguments": "--username ${auth_player_name} --version ${version_name} --gameDir ${game_directory} --assetsDir ${assets_root} --assetIndex ${assets_index_name} --uuid ${auth_uuid} --accessToken ${auth_access_token} --userType ${user_type} --versionType ${version_type}", "minimumLauncherVersion": 18, "releaseTime": "2017-09-18T08:39:46+00:00", "time": "2017-09-18T08:39:46+00:00", "type": "release"} +{"assetIndex": {"id": "1.12", "sha1": "1584b57c1a0b5e593fad1f5b8f78536ca640547b", "size": 143138, "totalSize": 129336389, "url": "https://launchermeta.mojang.com/v1/packages/1584b57c1a0b5e593fad1f5b8f78536ca640547b/1.12.json"}, "assets": "1.12", "complianceLevel": 0, "downloads": {"client": {"sha1": "0f275bc1547d01fa5f56ba34bdc87d981ee12daf", "size": 10180113, "url": "https://launcher.mojang.com/v1/objects/0f275bc1547d01fa5f56ba34bdc87d981ee12daf/client.jar"}, "server": {"sha1": "886945bfb2b978778c3a0288fd7fab09d315b25f", "size": 30222121, "url": "https://launcher.mojang.com/v1/objects/886945bfb2b978778c3a0288fd7fab09d315b25f/server.jar"}}, "id": "1.12.2", "javaVersion": {"component": "jre-legacy", "majorVersion": 8}, "libraries": [{"downloads": {"artifact": {"path": "com/mojang/patchy/1.3.9/patchy-1.3.9.jar", "sha1": "eb8bb7b66fa0e2152b1b40b3856e82f7619439ee", "size": 23581, "url": "https://libraries.minecraft.net/com/mojang/patchy/1.3.9/patchy-1.3.9.jar"}}, "name": "com.mojang:patchy:1.3.9"}, {"downloads": {"artifact": {"path": "oshi-project/oshi-core/1.1/oshi-core-1.1.jar", "sha1": "9ddf7b048a8d701be231c0f4f95fd986198fd2d8", "size": 30973, "url": "https://libraries.minecraft.net/oshi-project/oshi-core/1.1/oshi-core-1.1.jar"}}, "name": "oshi-project:oshi-core:1.1"}, {"downloads": {"artifact": {"path": "net/java/dev/jna/jna/4.4.0/jna-4.4.0.jar", "sha1": "cb208278274bf12ebdb56c61bd7407e6f774d65a", "size": 1091208, "url": "https://libraries.minecraft.net/net/java/dev/jna/jna/4.4.0/jna-4.4.0.jar"}}, "name": "net.java.dev.jna:jna:4.4.0"}, {"downloads": {"artifact": {"path": "net/java/dev/jna/platform/3.4.0/platform-3.4.0.jar", "sha1": "e3f70017be8100d3d6923f50b3d2ee17714e9c13", "size": 913436, "url": "https://libraries.minecraft.net/net/java/dev/jna/platform/3.4.0/platform-3.4.0.jar"}}, "name": "net.java.dev.jna:platform:3.4.0"}, {"downloads": {"artifact": {"path": "com/ibm/icu/icu4j-core-mojang/51.2/icu4j-core-mojang-51.2.jar", "sha1": "63d216a9311cca6be337c1e458e587f99d382b84", "size": 1634692, "url": "https://libraries.minecraft.net/com/ibm/icu/icu4j-core-mojang/51.2/icu4j-core-mojang-51.2.jar"}}, "name": "com.ibm.icu:icu4j-core-mojang:51.2"}, {"downloads": {"artifact": {"path": "net/sf/jopt-simple/jopt-simple/5.0.3/jopt-simple-5.0.3.jar", "sha1": "cdd846cfc4e0f7eefafc02c0f5dce32b9303aa2a", "size": 78175, "url": "https://libraries.minecraft.net/net/sf/jopt-simple/jopt-simple/5.0.3/jopt-simple-5.0.3.jar"}}, "name": "net.sf.jopt-simple:jopt-simple:5.0.3"}, {"downloads": {"artifact": {"path": "com/paulscode/codecjorbis/20101023/codecjorbis-20101023.jar", "sha1": "c73b5636faf089d9f00e8732a829577de25237ee", "size": 103871, "url": "https://libraries.minecraft.net/com/paulscode/codecjorbis/20101023/codecjorbis-20101023.jar"}}, "name": "com.paulscode:codecjorbis:20101023"}, {"downloads": {"artifact": {"path": "com/paulscode/codecwav/20101023/codecwav-20101023.jar", "sha1": "12f031cfe88fef5c1dd36c563c0a3a69bd7261da", "size": 5618, "url": "https://libraries.minecraft.net/com/paulscode/codecwav/20101023/codecwav-20101023.jar"}}, "name": "com.paulscode:codecwav:20101023"}, {"downloads": {"artifact": {"path": "com/paulscode/libraryjavasound/20101123/libraryjavasound-20101123.jar", "sha1": "5c5e304366f75f9eaa2e8cca546a1fb6109348b3", "size": 21679, "url": "https://libraries.minecraft.net/com/paulscode/libraryjavasound/20101123/libraryjavasound-20101123.jar"}}, "name": "com.paulscode:libraryjavasound:20101123"}, {"downloads": {"artifact": {"path": "com/paulscode/librarylwjglopenal/20100824/librarylwjglopenal-20100824.jar", "sha1": "73e80d0794c39665aec3f62eee88ca91676674ef", "size": 18981, "url": "https://libraries.minecraft.net/com/paulscode/librarylwjglopenal/20100824/librarylwjglopenal-20100824.jar"}}, "name": "com.paulscode:librarylwjglopenal:20100824"}, {"downloads": {"artifact": {"path": "com/paulscode/soundsystem/20120107/soundsystem-20120107.jar", "sha1": "419c05fe9be71f792b2d76cfc9b67f1ed0fec7f6", "size": 65020, "url": "https://libraries.minecraft.net/com/paulscode/soundsystem/20120107/soundsystem-20120107.jar"}}, "name": "com.paulscode:soundsystem:20120107"}, {"downloads": {"artifact": {"path": "io/netty/netty-all/4.1.9.Final/netty-all-4.1.9.Final.jar", "sha1": "0097860965d6a0a6b98e7f569f3f966727b8db75", "size": 3511093, "url": "https://libraries.minecraft.net/io/netty/netty-all/4.1.9.Final/netty-all-4.1.9.Final.jar"}}, "name": "io.netty:netty-all:4.1.9.Final"}, {"downloads": {"artifact": {"path": "com/google/guava/guava/21.0/guava-21.0.jar", "sha1": "3a3d111be1be1b745edfa7d91678a12d7ed38709", "size": 2521113, "url": "https://libraries.minecraft.net/com/google/guava/guava/21.0/guava-21.0.jar"}}, "name": "com.google.guava:guava:21.0"}, {"downloads": {"artifact": {"path": "org/apache/commons/commons-lang3/3.5/commons-lang3-3.5.jar", "sha1": "6c6c702c89bfff3cd9e80b04d668c5e190d588c6", "size": 479881, "url": "https://libraries.minecraft.net/org/apache/commons/commons-lang3/3.5/commons-lang3-3.5.jar"}}, "name": "org.apache.commons:commons-lang3:3.5"}, {"downloads": {"artifact": {"path": "commons-io/commons-io/2.5/commons-io-2.5.jar", "sha1": "2852e6e05fbb95076fc091f6d1780f1f8fe35e0f", "size": 208700, "url": "https://libraries.minecraft.net/commons-io/commons-io/2.5/commons-io-2.5.jar"}}, "name": "commons-io:commons-io:2.5"}, {"downloads": {"artifact": {"path": "commons-codec/commons-codec/1.10/commons-codec-1.10.jar", "sha1": "4b95f4897fa13f2cd904aee711aeafc0c5295cd8", "size": 284184, "url": "https://libraries.minecraft.net/commons-codec/commons-codec/1.10/commons-codec-1.10.jar"}}, "name": "commons-codec:commons-codec:1.10"}, {"downloads": {"artifact": {"path": "net/java/jinput/jinput/2.0.5/jinput-2.0.5.jar", "sha1": "39c7796b469a600f72380316f6b1f11db6c2c7c4", "size": 208338, "url": "https://libraries.minecraft.net/net/java/jinput/jinput/2.0.5/jinput-2.0.5.jar"}}, "name": "net.java.jinput:jinput:2.0.5"}, {"downloads": {"artifact": {"path": "net/java/jutils/jutils/1.0.0/jutils-1.0.0.jar", "sha1": "e12fe1fda814bd348c1579329c86943d2cd3c6a6", "size": 7508, "url": "https://libraries.minecraft.net/net/java/jutils/jutils/1.0.0/jutils-1.0.0.jar"}}, "name": "net.java.jutils:jutils:1.0.0"}, {"downloads": {"artifact": {"path": "com/google/code/gson/gson/2.8.0/gson-2.8.0.jar", "sha1": "c4ba5371a29ac9b2ad6129b1d39ea38750043eff", "size": 231952, "url": "https://libraries.minecraft.net/com/google/code/gson/gson/2.8.0/gson-2.8.0.jar"}}, "name": "com.google.code.gson:gson:2.8.0"}, {"downloads": {"artifact": {"path": "com/mojang/authlib/1.5.25/authlib-1.5.25.jar", "sha1": "9834cdf236c22e84b946bba989e2f94ef5897c3c", "size": 65621, "url": "https://libraries.minecraft.net/com/mojang/authlib/1.5.25/authlib-1.5.25.jar"}}, "name": "com.mojang:authlib:1.5.25"}, {"downloads": {"artifact": {"path": "com/mojang/realms/1.10.22/realms-1.10.22.jar", "sha1": "bd0dccebdf3744c75f1ca20063f16e8f7d5e663f", "size": 7135057, "url": "https://libraries.minecraft.net/com/mojang/realms/1.10.22/realms-1.10.22.jar"}}, "name": "com.mojang:realms:1.10.22"}, {"downloads": {"artifact": {"path": "org/apache/commons/commons-compress/1.8.1/commons-compress-1.8.1.jar", "sha1": "a698750c16740fd5b3871425f4cb3bbaa87f529d", "size": 365552, "url": "https://libraries.minecraft.net/org/apache/commons/commons-compress/1.8.1/commons-compress-1.8.1.jar"}}, "name": "org.apache.commons:commons-compress:1.8.1"}, {"downloads": {"artifact": {"path": "org/apache/httpcomponents/httpclient/4.3.3/httpclient-4.3.3.jar", "sha1": "18f4247ff4572a074444572cee34647c43e7c9c7", "size": 589512, "url": "https://libraries.minecraft.net/org/apache/httpcomponents/httpclient/4.3.3/httpclient-4.3.3.jar"}}, "name": "org.apache.httpcomponents:httpclient:4.3.3"}, {"downloads": {"artifact": {"path": "commons-logging/commons-logging/1.1.3/commons-logging-1.1.3.jar", "sha1": "f6f66e966c70a83ffbdb6f17a0919eaf7c8aca7f", "size": 62050, "url": "https://libraries.minecraft.net/commons-logging/commons-logging/1.1.3/commons-logging-1.1.3.jar"}}, "name": "commons-logging:commons-logging:1.1.3"}, {"downloads": {"artifact": {"path": "org/apache/httpcomponents/httpcore/4.3.2/httpcore-4.3.2.jar", "sha1": "31fbbff1ddbf98f3aa7377c94d33b0447c646b6e", "size": 282269, "url": "https://libraries.minecraft.net/org/apache/httpcomponents/httpcore/4.3.2/httpcore-4.3.2.jar"}}, "name": "org.apache.httpcomponents:httpcore:4.3.2"}, {"downloads": {"artifact": {"path": "it/unimi/dsi/fastutil/7.1.0/fastutil-7.1.0.jar", "sha1": "9835253257524c1be7ab50c057aa2d418fb72082", "size": 17655579, "url": "https://libraries.minecraft.net/it/unimi/dsi/fastutil/7.1.0/fastutil-7.1.0.jar"}}, "name": "it.unimi.dsi:fastutil:7.1.0"}, {"downloads": {"artifact": {"path": "org/apache/logging/log4j/log4j-api/2.8.1/log4j-api-2.8.1.jar", "sha1": "e801d13612e22cad62a3f4f3fe7fdbe6334a8e72", "size": 228859, "url": "https://libraries.minecraft.net/org/apache/logging/log4j/log4j-api/2.8.1/log4j-api-2.8.1.jar"}}, "name": "org.apache.logging.log4j:log4j-api:2.8.1"}, {"downloads": {"artifact": {"path": "org/apache/logging/log4j/log4j-core/2.8.1/log4j-core-2.8.1.jar", "sha1": "4ac28ff2f1ddf05dae3043a190451e8c46b73c31", "size": 1402925, "url": "https://libraries.minecraft.net/org/apache/logging/log4j/log4j-core/2.8.1/log4j-core-2.8.1.jar"}}, "name": "org.apache.logging.log4j:log4j-core:2.8.1"}, {"downloads": {"artifact": {"path": "org/lwjgl/lwjgl/lwjgl/2.9.4-nightly-20150209/lwjgl-2.9.4-nightly-20150209.jar", "sha1": "697517568c68e78ae0b4544145af031c81082dfe", "size": 1047168, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl/2.9.4-nightly-20150209/lwjgl-2.9.4-nightly-20150209.jar"}}, "name": "org.lwjgl.lwjgl:lwjgl:2.9.4-nightly-20150209", "rules": [{"action": "allow"}, {"action": "disallow", "os": {"name": "osx"}}]}, {"downloads": {"artifact": {"path": "org/lwjgl/lwjgl/lwjgl_util/2.9.4-nightly-20150209/lwjgl_util-2.9.4-nightly-20150209.jar", "sha1": "d51a7c040a721d13efdfbd34f8b257b2df882ad0", "size": 173887, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl_util/2.9.4-nightly-20150209/lwjgl_util-2.9.4-nightly-20150209.jar"}}, "name": "org.lwjgl.lwjgl:lwjgl_util:2.9.4-nightly-20150209", "rules": [{"action": "allow"}, {"action": "disallow", "os": {"name": "osx"}}]}, {"downloads": {"artifact": {"path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209.jar", "sha1": "b04f3ee8f5e43fa3b162981b50bb72fe1acabb33", "size": 22, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209.jar"}, "classifiers": {"natives-linux": {"path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-linux.jar", "sha1": "931074f46c795d2f7b30ed6395df5715cfd7675b", "size": 578680, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-linux.jar"}, "natives-osx": {"path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar", "sha1": "bcab850f8f487c3f4c4dbabde778bb82bd1a40ed", "size": 426822, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar"}, "natives-windows": {"path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-windows.jar", "sha1": "b84d5102b9dbfabfeb5e43c7e2828d98a7fc80e0", "size": 613748, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-windows.jar"}}}, "extract": {"exclude": ["META-INF/"]}, "name": "org.lwjgl.lwjgl:lwjgl-platform:2.9.4-nightly-20150209", "natives": {"linux": "natives-linux", "osx": "natives-osx", "windows": "natives-windows"}, "rules": [{"action": "allow"}, {"action": "disallow", "os": {"name": "osx"}}]}, {"downloads": {"artifact": {"path": "org/lwjgl/lwjgl/lwjgl/2.9.2-nightly-20140822/lwjgl-2.9.2-nightly-20140822.jar", "sha1": "7707204c9ffa5d91662de95f0a224e2f721b22af", "size": 1045632, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl/2.9.2-nightly-20140822/lwjgl-2.9.2-nightly-20140822.jar"}}, "name": "org.lwjgl.lwjgl:lwjgl:2.9.2-nightly-20140822", "rules": [{"action": "allow", "os": {"name": "osx"}}]}, {"downloads": {"artifact": {"path": "org/lwjgl/lwjgl/lwjgl_util/2.9.2-nightly-20140822/lwjgl_util-2.9.2-nightly-20140822.jar", "sha1": "f0e612c840a7639c1f77f68d72a28dae2f0c8490", "size": 173887, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl_util/2.9.2-nightly-20140822/lwjgl_util-2.9.2-nightly-20140822.jar"}}, "name": "org.lwjgl.lwjgl:lwjgl_util:2.9.2-nightly-20140822", "rules": [{"action": "allow", "os": {"name": "osx"}}]}, {"downloads": {"classifiers": {"natives-linux": {"path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.2-nightly-20140822/lwjgl-platform-2.9.2-nightly-20140822-natives-linux.jar", "sha1": "d898a33b5d0a6ef3fed3a4ead506566dce6720a5", "size": 578539, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.2-nightly-20140822/lwjgl-platform-2.9.2-nightly-20140822-natives-linux.jar"}, "natives-osx": {"path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.2-nightly-20140822/lwjgl-platform-2.9.2-nightly-20140822-natives-osx.jar", "sha1": "79f5ce2fea02e77fe47a3c745219167a542121d7", "size": 468116, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.2-nightly-20140822/lwjgl-platform-2.9.2-nightly-20140822-natives-osx.jar"}, "natives-windows": {"path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.2-nightly-20140822/lwjgl-platform-2.9.2-nightly-20140822-natives-windows.jar", "sha1": "78b2a55ce4dc29c6b3ec4df8ca165eba05f9b341", "size": 613680, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.2-nightly-20140822/lwjgl-platform-2.9.2-nightly-20140822-natives-windows.jar"}}}, "extract": {"exclude": ["META-INF/"]}, "name": "org.lwjgl.lwjgl:lwjgl-platform:2.9.2-nightly-20140822", "natives": {"linux": "natives-linux", "osx": "natives-osx", "windows": "natives-windows"}, "rules": [{"action": "allow", "os": {"name": "osx"}}]}, {"downloads": {"classifiers": {"natives-linux": {"path": "net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-linux.jar", "sha1": "7ff832a6eb9ab6a767f1ade2b548092d0fa64795", "size": 10362, "url": "https://libraries.minecraft.net/net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-linux.jar"}, "natives-osx": {"path": "net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-osx.jar", "sha1": "53f9c919f34d2ca9de8c51fc4e1e8282029a9232", "size": 12186, "url": "https://libraries.minecraft.net/net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-osx.jar"}, "natives-windows": {"path": "net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-windows.jar", "sha1": "385ee093e01f587f30ee1c8a2ee7d408fd732e16", "size": 155179, "url": "https://libraries.minecraft.net/net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-windows.jar"}}}, "extract": {"exclude": ["META-INF/"]}, "name": "net.java.jinput:jinput-platform:2.0.5", "natives": {"linux": "natives-linux", "osx": "natives-osx", "windows": "natives-windows"}}, {"downloads": {"artifact": {"path": "com/mojang/text2speech/1.10.3/text2speech-1.10.3.jar", "sha1": "48fd510879dff266c3815947de66e3d4809f8668", "size": 11055, "url": "https://libraries.minecraft.net/com/mojang/text2speech/1.10.3/text2speech-1.10.3.jar"}}, "name": "com.mojang:text2speech:1.10.3"}, {"downloads": {"artifact": {"path": "com/mojang/text2speech/1.10.3/text2speech-1.10.3.jar", "sha1": "48fd510879dff266c3815947de66e3d4809f8668", "size": 11055, "url": "https://libraries.minecraft.net/com/mojang/text2speech/1.10.3/text2speech-1.10.3.jar"}, "classifiers": {"natives-linux": {"path": "com/mojang/text2speech/1.10.3/text2speech-1.10.3-natives-linux.jar", "sha1": "ab7896aec3b3dd272b06194357f2d98f832c0cfc", "size": 7833, "url": "https://libraries.minecraft.net/com/mojang/text2speech/1.10.3/text2speech-1.10.3-natives-linux.jar"}, "natives-windows": {"path": "com/mojang/text2speech/1.10.3/text2speech-1.10.3-natives-windows.jar", "sha1": "84a4b856389cc4f485275b1f63497a95a857a443", "size": 81217, "url": "https://libraries.minecraft.net/com/mojang/text2speech/1.10.3/text2speech-1.10.3-natives-windows.jar"}, "sources": {"path": "com/mojang/text2speech/1.10.3/text2speech-1.10.3-sources.jar", "sha1": "404339fe43d1011ee046a249b0ec7ae9ce04a834", "size": 4632, "url": "https://libraries.minecraft.net/com/mojang/text2speech/1.10.3/text2speech-1.10.3-sources.jar"}}}, "extract": {"exclude": ["META-INF/"]}, "name": "com.mojang:text2speech:1.10.3", "natives": {"linux": "natives-linux", "windows": "natives-windows"}}, {"downloads": {"artifact": {"path": "ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0.jar", "sha1": "6ef160c3133a78de015830860197602ca1c855d3", "size": 40502, "url": "https://libraries.minecraft.net/ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0.jar"}, "classifiers": {"javadoc": {"path": "ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0-javadoc.jar", "sha1": "fb0092f22cb4fe8e631452f577b7a238778abf2a", "size": 174060, "url": "https://libraries.minecraft.net/ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0-javadoc.jar"}, "natives-osx": {"path": "ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0-natives-osx.jar", "sha1": "08befab4894d55875f33c3d300f4f71e6e828f64", "size": 5629, "url": "https://libraries.minecraft.net/ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0-natives-osx.jar"}, "sources": {"path": "ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0-sources.jar", "sha1": "865837a198189aee737019561ece842827f24278", "size": 43283, "url": "https://libraries.minecraft.net/ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0-sources.jar"}}}, "extract": {"exclude": ["META-INF/"]}, "name": "ca.weblite:java-objc-bridge:1.0.0", "natives": {"osx": "natives-osx"}, "rules": [{"action": "allow", "os": {"name": "osx"}}]}, {"downloads": {"artifact": {"path": "ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0.jar", "sha1": "6ef160c3133a78de015830860197602ca1c855d3", "size": 40502, "url": "https://libraries.minecraft.net/ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0.jar"}}, "name": "ca.weblite:java-objc-bridge:1.0.0", "rules": [{"action": "allow", "os": {"name": "osx"}}]}], "logging": {"client": {"argument": "-Dlog4j.configurationFile=${path}", "file": {"id": "client-1.12.xml", "sha1": "bd65e7d2e3c237be76cfbef4c2405033d7f91521", "size": 888, "url": "https://launcher.mojang.com/v1/objects/bd65e7d2e3c237be76cfbef4c2405033d7f91521/client-1.12.xml"}, "type": "log4j2-xml"}}, "mainClass": "net.minecraft.client.main.Main", "minecraftArguments": "--username ${auth_player_name} --version ${version_name} --gameDir ${game_directory} --assetsDir ${assets_root} --assetIndex ${assets_index_name} --uuid ${auth_uuid} --accessToken ${auth_access_token} --userType ${user_type} --versionType ${version_type}", "minimumLauncherVersion": 18, "releaseTime": "2017-09-18T08:39:46+00:00", "time": "2017-09-18T08:39:46+00:00", "type": "release"} From aa06e4ca7f3a79cea78f80129741e6d21a68f6d6 Mon Sep 17 00:00:00 2001 From: Unknown Date: Thu, 27 Jan 2022 00:37:10 +0100 Subject: [PATCH 30/46] Fixed so zetblock doesn't need chunk loading --- .../carpet/commands/CommandZetBlock.java | 161 +++++++++--------- 1 file changed, 77 insertions(+), 84 deletions(-) diff --git a/carpetmodSrc/carpet/commands/CommandZetBlock.java b/carpetmodSrc/carpet/commands/CommandZetBlock.java index 11932326..69a2867d 100644 --- a/carpetmodSrc/carpet/commands/CommandZetBlock.java +++ b/carpetmodSrc/carpet/commands/CommandZetBlock.java @@ -75,90 +75,83 @@ public void execute(MinecraftServer server, ICommandSender sender, String[] args World world = sender.getEntityWorld(); - if (!world.isBlockLoaded(blockpos)) - { - throw new CommandException("commands.setblock.outOfWorld", new Object[0]); - } - else - { - NBTTagCompound nbttagcompound = new NBTTagCompound(); - boolean flag = false; - - if (args.length >= 7 && block.hasTileEntity()) - { - String s = buildString(args, 6); - - try - { - nbttagcompound = JsonToNBT.getTagFromJson(s); - flag = true; - } - catch (NBTException nbtexception) - { - throw new CommandException("commands.setblock.tagError", new Object[] {nbtexception.getMessage()}); - } - } - - EntityPlayerMP worldEditPlayer = sender instanceof EntityPlayerMP ? (EntityPlayerMP) sender : null; - NBTTagCompound worldEditTag = flag ? nbttagcompound : null; - - if (args.length >= 6) - { - if ("destroy".equals(args[5])) - { - WorldEditBridge.recordBlockEdit(worldEditPlayer, world, blockpos, Blocks.AIR.getDefaultState(), worldEditTag); - CapturedDrops.setCapturingDrops(true); - world.destroyBlock(blockpos, true); - CapturedDrops.setCapturingDrops(false); - for (EntityItem drop : CapturedDrops.getCapturedDrops()) - WorldEditBridge.recordEntityCreation(worldEditPlayer, world, drop); - CapturedDrops.clearCapturedDrops(); - - if (block == Blocks.AIR) - { - notifyCommandListener(sender, this, "commands.setblock.success", new Object[0]); - return; - } - } - else if ("keep".equals(args[5]) && !world.isAirBlock(blockpos)) - { - throw new CommandException("commands.setblock.noChange", new Object[0]); - } - } - - WorldEditBridge.recordBlockEdit(worldEditPlayer, world, blockpos, iblockstate, worldEditTag); - - TileEntity tileentity1 = world.getTileEntity(blockpos); - - if (tileentity1 != null && tileentity1 instanceof IInventory) - { - ((IInventory)tileentity1).clear(); - } - - if (!world.setBlockState(blockpos, iblockstate, 2)) - { - throw new CommandException("commands.setblock.noChange", new Object[0]); - } - else - { - if (flag) - { - TileEntity tileentity = world.getTileEntity(blockpos); - - if (tileentity != null) - { - nbttagcompound.setInteger("x", blockpos.getX()); - nbttagcompound.setInteger("y", blockpos.getY()); - nbttagcompound.setInteger("z", blockpos.getZ()); - tileentity.readFromNBT(nbttagcompound); - } - } - - world.notifyNeighborsRespectDebug(blockpos, iblockstate.getBlock(), false); - sender.setCommandStat(CommandResultStats.Type.AFFECTED_BLOCKS, 1); - notifyCommandListener(sender, this, "commands.setblock.success", new Object[0]); - } - } + NBTTagCompound nbttagcompound = new NBTTagCompound(); + boolean flag = false; + + if (args.length >= 7 && block.hasTileEntity()) + { + String s = buildString(args, 6); + + try + { + nbttagcompound = JsonToNBT.getTagFromJson(s); + flag = true; + } + catch (NBTException nbtexception) + { + throw new CommandException("commands.setblock.tagError", new Object[] {nbtexception.getMessage()}); + } + } + + EntityPlayerMP worldEditPlayer = sender instanceof EntityPlayerMP ? (EntityPlayerMP) sender : null; + NBTTagCompound worldEditTag = flag ? nbttagcompound : null; + + if (args.length >= 6) + { + if ("destroy".equals(args[5])) + { + WorldEditBridge.recordBlockEdit(worldEditPlayer, world, blockpos, Blocks.AIR.getDefaultState(), worldEditTag); + CapturedDrops.setCapturingDrops(true); + world.destroyBlock(blockpos, true); + CapturedDrops.setCapturingDrops(false); + for (EntityItem drop : CapturedDrops.getCapturedDrops()) + WorldEditBridge.recordEntityCreation(worldEditPlayer, world, drop); + CapturedDrops.clearCapturedDrops(); + + if (block == Blocks.AIR) + { + notifyCommandListener(sender, this, "commands.setblock.success", new Object[0]); + return; + } + } + else if ("keep".equals(args[5]) && !world.isAirBlock(blockpos)) + { + throw new CommandException("commands.setblock.noChange", new Object[0]); + } + } + + WorldEditBridge.recordBlockEdit(worldEditPlayer, world, blockpos, iblockstate, worldEditTag); + + TileEntity tileentity1 = world.getTileEntity(blockpos); + + if (tileentity1 != null && tileentity1 instanceof IInventory) + { + ((IInventory)tileentity1).clear(); + } + + if (!world.setBlockState(blockpos, iblockstate, 2)) + { + throw new CommandException("commands.setblock.noChange", new Object[0]); + } + else + { + if (flag) + { + TileEntity tileentity = world.getTileEntity(blockpos); + + if (tileentity != null) + { + nbttagcompound.setInteger("x", blockpos.getX()); + nbttagcompound.setInteger("y", blockpos.getY()); + nbttagcompound.setInteger("z", blockpos.getZ()); + tileentity.readFromNBT(nbttagcompound); + } + } + + world.notifyNeighborsRespectDebug(blockpos, iblockstate.getBlock(), false); + sender.setCommandStat(CommandResultStats.Type.AFFECTED_BLOCKS, 1); + notifyCommandListener(sender, this, "commands.setblock.success", new Object[0]); + } } } From 75c47ed4da6c7ede0babb319207228694e692e74 Mon Sep 17 00:00:00 2001 From: Unknown Date: Thu, 27 Jan 2022 00:38:55 +0100 Subject: [PATCH 31/46] v22_01_27 --- carpetmodSrc/carpet/CarpetSettings.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/carpetmodSrc/carpet/CarpetSettings.java b/carpetmodSrc/carpet/CarpetSettings.java index 94303b0b..74a2e938 100644 --- a/carpetmodSrc/carpet/CarpetSettings.java +++ b/carpetmodSrc/carpet/CarpetSettings.java @@ -45,7 +45,7 @@ public class CarpetSettings public static boolean locked = false; // TODO: replace these constants at build time - public static final String carpetVersion = "v21_11_10"; + public static final String carpetVersion = "v22_01_27"; public static final String minecraftVersion = "1.12.2"; public static final String mcpMappings = "39-1.12"; From bb25419a338234ef965bada470c495d11e480b0f Mon Sep 17 00:00:00 2001 From: Unknown Date: Tue, 8 Feb 2022 08:42:14 +0100 Subject: [PATCH 32/46] Added Command Palette --- .../carpet/commands/CarpetCommands.java | 1 + .../carpet/commands/CommandPalette.java | 258 ++++++++++++++++++ .../net/minecraft/util/BitArray.java.patch | 14 + .../chunk/BlockStateContainer.java.patch | 17 ++ .../chunk/BlockStatePaletteHashMap.java.patch | 11 + .../chunk/BlockStatePaletteLinear.java.patch | 11 + .../storage/ExtendedBlockStorage.java.patch | 9 + 7 files changed, 321 insertions(+) create mode 100644 carpetmodSrc/carpet/commands/CommandPalette.java create mode 100644 patches/net/minecraft/util/BitArray.java.patch create mode 100644 patches/net/minecraft/world/chunk/BlockStateContainer.java.patch create mode 100644 patches/net/minecraft/world/chunk/BlockStatePaletteHashMap.java.patch create mode 100644 patches/net/minecraft/world/chunk/BlockStatePaletteLinear.java.patch diff --git a/carpetmodSrc/carpet/commands/CarpetCommands.java b/carpetmodSrc/carpet/commands/CarpetCommands.java index e879d628..f32849f2 100644 --- a/carpetmodSrc/carpet/commands/CarpetCommands.java +++ b/carpetmodSrc/carpet/commands/CarpetCommands.java @@ -46,6 +46,7 @@ public static void register(CommandHandler handler) { handler.registerCommand(new CommandChunk()); handler.registerCommand(new CommandLoadedChunks()); handler.registerCommand(new CommandZetBlock()); + handler.registerCommand(new CommandPalette()); // ----- RSMM Start ----- // handler.registerCommand(new MeterCommand(CarpetServer.rsmmServer)); diff --git a/carpetmodSrc/carpet/commands/CommandPalette.java b/carpetmodSrc/carpet/commands/CommandPalette.java new file mode 100644 index 00000000..c97e21ba --- /dev/null +++ b/carpetmodSrc/carpet/commands/CommandPalette.java @@ -0,0 +1,258 @@ +package carpet.commands; + +import net.minecraft.block.BlockColored; +import net.minecraft.block.state.IBlockState; +import net.minecraft.command.CommandException; +import net.minecraft.command.ICommandSender; +import net.minecraft.command.WrongUsageException; +import net.minecraft.init.Blocks; +import net.minecraft.item.EnumDyeColor; +import net.minecraft.server.MinecraftServer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.BitArray; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.text.TextComponentString; +import net.minecraft.world.World; +import net.minecraft.world.chunk.*; +import net.minecraft.world.chunk.storage.ExtendedBlockStorage; + +import javax.annotation.Nullable; +import java.util.*; + +public class CommandPalette extends CommandCarpetBase { + /** + * Gets the name of the command + */ + + public String getUsage(ICommandSender sender) { + return "Usage: palette <4 to 14>"; + } + + public String getName() { + return "palette"; + } + + /** + * Callback for when the command is executed + */ + public void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException { + if (!command_enabled("commandChunk", sender)) return; + + try { + BlockPos pos = new BlockPos(sender.getPosition().getX(), sender.getPosition().getY(), sender.getPosition().getZ()); + if (args.length < 4 && args[0].equals("blockInfo")) { + throw new WrongUsageException(getUsage(sender)); + } else if (args.length >= 4) { + pos = parseBlockPos(sender, args, 1, false); + } + World world = sender.getEntityWorld(); + Chunk chunk = world.getChunk(pos); + ExtendedBlockStorage[] list = chunk.getBlockStorageArray(); + int h = pos.getY() >> 4; + if (h < 0) h = 0; + if (h > 15) h = 15; + ExtendedBlockStorage ebs = list[h]; + BlockStateContainer bsc = ebs.getBlockStateContainer(); + int bits = bsc.getBits(); + + switch (args[0]) { + case "bits": + sender.sendMessage(new TextComponentString("Palette bit size: " + bits)); + return; + case "size": + getSize(sender, bsc); + return; + case "blockInfo": + boolean isFull = false; + if (args.length >= 5) isFull = args[4].equals("full"); + infoPalette(sender, bsc, pos, isFull); + return; + case "fill": + int bitSize = -1; + int type = 1; + if (args.length >= 5) type = args[4].equals("full") ? 2 : 1; + if (args.length >= 6) bitSize = parseInt(args[5]); + fill(sender, bsc, pos, type, bitSize); + return; + default: + throw new WrongUsageException(getUsage(sender)); + + } + } catch (Exception e) { + e.printStackTrace(); + throw new WrongUsageException(getUsage(sender)); + } + } + + private static IBlockState[] backup = null; + private static HashMap tileEntityList = new HashMap<>(); + + private static void fill(ICommandSender sender, BlockStateContainer bsc, BlockPos pos, int type, int bitSize) { + if (type != 3 && backup != null) type = 3; + + if (bitSize < 1 || bitSize > 64) bitSize = bsc.getStorage().getBitsPerEntry(); + + BlockPos basePos = new BlockPos(pos.getX() >>> 4 << 4, pos.getY() >>> 4 << 4, pos.getZ() >>> 4 << 4); + int color = -1; + int storeJ = -1; + if (type != 3) { + backup = new IBlockState[4096]; + } + HashSet backupSet = new HashSet<>(); + for (int i = 0; i < 4096; i++) { + BlockPos set = getBlockIndex(i, basePos); + if (type == 1) { + int j = i * bitSize / 64; + int k = ((i + 1) * bitSize - 1) / 64; + + if (j != k) { + backup[i] = sender.getEntityWorld().getBlockState(set); + TileEntity te = sender.getEntityWorld().getTileEntity(set); + if (te != null) { + tileEntityList.put(set, te); + sender.getEntityWorld().removeTileEntity(set); + } + sender.getEntityWorld().setBlockState(set, Blocks.GLASS.getDefaultState(), 128); + } + } else if (type == 2) { + backup[i] = sender.getEntityWorld().getBlockState(set); + TileEntity te = sender.getEntityWorld().getTileEntity(set); + if (te != null) { + tileEntityList.put(set, te); + sender.getEntityWorld().removeTileEntity(set); + } + set = getBlockIndex(i, basePos); + int j = i * bitSize / 64; + int k = ((i + 1) * bitSize - 1) / 64; + + if (j != storeJ) { + storeJ = j; + color = (color + 1) & 15; + } + + if (j != k) { + sender.getEntityWorld().setBlockState(set, Blocks.GLASS.getDefaultState(), 128); + } else { + sender.getEntityWorld().setBlockState(set, Blocks.STAINED_GLASS.getDefaultState().withProperty(BlockColored.COLOR, EnumDyeColor.byMetadata(color)), 128); + } + } else if (type == 3) { + if (backup[i] != null && !backupSet.contains(set)) { + backupSet.add(set); + sender.getEntityWorld().setBlockState(set, backup[i], 128); + TileEntity te = tileEntityList.get(set); + if (te != null) { + sender.getEntityWorld().removeTileEntity(set); + te.validate(); + sender.getEntityWorld().setTileEntity(set, te); + } + } + } + } + if (type == 3) { + backup = null; + tileEntityList.clear(); + } + } + + private void infoPalette(ICommandSender sender, BlockStateContainer bsc, BlockPos pos, boolean full) { + BitArray bArray = bsc.getStorage(); + int bits = bArray.getBitsPerEntry(); + int index = getIndex(pos); + int i = index * bits; + int j = i / 64; + int k = ((index + 1) * bits - 1) / 64; + int l = i % 64; + long[] longArray = bArray.getBackingLongArray(); + + if (j == k) { + displayJKBits(sender, longArray[j], l, l + bits - 1, ""); + if (full) { + for (BlockPos bp : getArrayFromJK(j, k, bits, pos)) { + sender.sendMessage(new TextComponentString(bp.toString())); + } + } + } else { + displayJKBits(sender, longArray[j], l, 64, "1"); + displayJKBits(sender, longArray[k], 0, (l + bits - 1) % 64, "2"); + if (full) { + for (BlockPos bp : getArrayFromJK(j, k, bits, pos)) { + sender.sendMessage(new TextComponentString(bp.toString())); + } + } + } + } + + private static void displayJKBits(ICommandSender sender, long longString, long l1, long l2, String append) { + StringBuilder sb = new StringBuilder(); + + String add = "§f"; + for (int bitNum = 0; bitNum < 64; bitNum++) { + char s = (longString & 1) == 1 ? '1' : '0'; + longString = longString >> 1; + if (bitNum == l1) add = "§c"; + sb.append(add + s); + if (bitNum == l2) add = "§f"; + } + sender.sendMessage(new TextComponentString("L" + append + ":" + sb)); + } + + private static BlockPos[] getArrayFromJK(int j, int k, int bits, BlockPos pos) { + BlockPos basePos = new BlockPos(pos.getX() >>> 4 << 4, pos.getY() >>> 4 << 4, pos.getZ() >>> 4 << 4); + BlockPos.MutableBlockPos mute = new BlockPos.MutableBlockPos(); + ArrayList list = new ArrayList<>(); + for (int x = 0; x < 16; ++x) { + for (int y = 0; y < 16; ++y) { + for (int z = 0; z < 16; ++z) { + int index = getIndex(mute.setPos(x, y, z)); + int jj = x / 64; + int kk = ((index + 1) * bits - 1) / 64; + if (jj == j || kk == k) { + list.add(new BlockPos(x, y, z).add(basePos)); + } + } + } + } + return list.toArray(new BlockPos[0]); + } + + private static int getIndex(BlockPos pos) { + int x = pos.getX() & 15; + int y = pos.getY() & 15; + int z = pos.getZ() & 15; + + return y << 8 | z << 4 | x; + } + + private static BlockPos getBlockIndex(int index, BlockPos pos) { + int x = (pos.getX() & ~0xF) | (index & 0xF); + int y = (pos.getY() & ~0xF) | ((index >>> 8) & 0xF); + int z = (pos.getZ() & ~0xF) | ((index >>> 4) & 0xF); + + return new BlockPos(x, y, z); + } + + private void getSize(ICommandSender sender, BlockStateContainer bsc) { + IBlockStatePalette ibsp = bsc.getPalette(); + if (ibsp instanceof BlockStatePaletteLinear) { + sender.sendMessage(new TextComponentString("Palette size: " + ((BlockStatePaletteLinear) ibsp).paletteSize())); + } else if (ibsp instanceof BlockStatePaletteHashMap) { + sender.sendMessage(new TextComponentString("Palette size: " + ((BlockStatePaletteHashMap) ibsp).paletteSize())); + } else if (ibsp instanceof BlockStatePaletteRegistry) { + sender.sendMessage(new TextComponentString("Palette size MAX aka 4096")); + } + } + + public List getTabCompletions(MinecraftServer server, ICommandSender sender, String[] args, @Nullable BlockPos targetPos) { + if (args.length == 1) { + return getListOfStringsMatchingLastWord(args, "bits", "size", "blockInfo", "fill"); + } else if (args.length >= 2 && args.length <= 4) { + return getTabCompletionCoordinate(args, 1, targetPos); + } else if (args.length == 5 || args[0].equals("blockInfo") || args[0].equals("fill")) { + return getListOfStringsMatchingLastWord(args, "full", "normal"); + } else if (args.length == 6 && args[0].equals("fill")) { + return getListOfStringsMatchingLastWord(args, "4", "5", "14"); + } else { + return Collections.emptyList(); + } + } +} diff --git a/patches/net/minecraft/util/BitArray.java.patch b/patches/net/minecraft/util/BitArray.java.patch new file mode 100644 index 00000000..7a33b744 --- /dev/null +++ b/patches/net/minecraft/util/BitArray.java.patch @@ -0,0 +1,14 @@ +--- ../src-base/minecraft/net/minecraft/util/BitArray.java ++++ ../src-work/minecraft/net/minecraft/util/BitArray.java +@@ -65,4 +65,11 @@ + { + return this.field_188148_d; + } ++ ++ public long getMaxEntryValue(){ ++ return field_188147_c; ++ } ++ public int getBitsPerEntry(){ ++ return field_188146_b; ++ } + } diff --git a/patches/net/minecraft/world/chunk/BlockStateContainer.java.patch b/patches/net/minecraft/world/chunk/BlockStateContainer.java.patch new file mode 100644 index 00000000..85847045 --- /dev/null +++ b/patches/net/minecraft/world/chunk/BlockStateContainer.java.patch @@ -0,0 +1,17 @@ +--- ../src-base/minecraft/net/minecraft/world/chunk/BlockStateContainer.java ++++ ../src-work/minecraft/net/minecraft/world/chunk/BlockStateContainer.java +@@ -146,4 +146,14 @@ + { + return 1 + this.field_186022_c.func_186040_a() + PacketBuffer.func_150790_a(this.field_186021_b.func_188144_b()) + this.field_186021_b.func_188143_a().length * 8; + } ++ ++ public BitArray getStorage(){ ++ return field_186021_b; ++ } ++ public IBlockStatePalette getPalette(){ ++ return field_186022_c; ++ } ++ public int getBits(){ ++ return field_186024_e; ++ } + } diff --git a/patches/net/minecraft/world/chunk/BlockStatePaletteHashMap.java.patch b/patches/net/minecraft/world/chunk/BlockStatePaletteHashMap.java.patch new file mode 100644 index 00000000..b802c78f --- /dev/null +++ b/patches/net/minecraft/world/chunk/BlockStatePaletteHashMap.java.patch @@ -0,0 +1,11 @@ +--- ../src-base/minecraft/net/minecraft/world/chunk/BlockStatePaletteHashMap.java ++++ ../src-work/minecraft/net/minecraft/world/chunk/BlockStatePaletteHashMap.java +@@ -64,4 +64,8 @@ + + return i; + } ++ ++ public int paletteSize(){ ++ return field_186046_a.func_186810_b(); ++ } + } diff --git a/patches/net/minecraft/world/chunk/BlockStatePaletteLinear.java.patch b/patches/net/minecraft/world/chunk/BlockStatePaletteLinear.java.patch new file mode 100644 index 00000000..39621154 --- /dev/null +++ b/patches/net/minecraft/world/chunk/BlockStatePaletteLinear.java.patch @@ -0,0 +1,11 @@ +--- ../src-base/minecraft/net/minecraft/world/chunk/BlockStatePaletteLinear.java ++++ ../src-work/minecraft/net/minecraft/world/chunk/BlockStatePaletteLinear.java +@@ -70,4 +70,8 @@ + + return i; + } ++ ++ public int paletteSize(){ ++ return field_186045_d; ++ } + } diff --git a/patches/net/minecraft/world/chunk/storage/ExtendedBlockStorage.java.patch b/patches/net/minecraft/world/chunk/storage/ExtendedBlockStorage.java.patch index f66168e3..b7b3d3ee 100644 --- a/patches/net/minecraft/world/chunk/storage/ExtendedBlockStorage.java.patch +++ b/patches/net/minecraft/world/chunk/storage/ExtendedBlockStorage.java.patch @@ -23,3 +23,12 @@ } public boolean func_76675_b() +@@ -147,4 +154,8 @@ + { + this.field_76685_h = p_76666_1_; + } ++ ++ public BlockStateContainer getBlockStateContainer() { ++ return field_177488_d; ++ } + } From 0279a581719f083b2c6cf68165b591271ced080c Mon Sep 17 00:00:00 2001 From: Unknown Date: Tue, 8 Feb 2022 17:10:22 +0100 Subject: [PATCH 33/46] added block matching in info, fixed bugs and improved errors --- .../carpet/commands/CommandPalette.java | 78 ++++++++++++++----- 1 file changed, 58 insertions(+), 20 deletions(-) diff --git a/carpetmodSrc/carpet/commands/CommandPalette.java b/carpetmodSrc/carpet/commands/CommandPalette.java index c97e21ba..d7f4d3f8 100644 --- a/carpetmodSrc/carpet/commands/CommandPalette.java +++ b/carpetmodSrc/carpet/commands/CommandPalette.java @@ -1,7 +1,9 @@ package carpet.commands; +import net.minecraft.block.Block; import net.minecraft.block.BlockColored; import net.minecraft.block.state.IBlockState; +import net.minecraft.command.CommandBase; import net.minecraft.command.CommandException; import net.minecraft.command.ICommandSender; import net.minecraft.command.WrongUsageException; @@ -25,7 +27,7 @@ public class CommandPalette extends CommandCarpetBase { */ public String getUsage(ICommandSender sender) { - return "Usage: palette <4 to 14>"; + return "Usage: palette <4 to 13>"; } public String getName() { @@ -40,7 +42,7 @@ public void execute(MinecraftServer server, ICommandSender sender, String[] args try { BlockPos pos = new BlockPos(sender.getPosition().getX(), sender.getPosition().getY(), sender.getPosition().getZ()); - if (args.length < 4 && args[0].equals("blockInfo")) { + if (args.length < 4 && args[0].equals("posInfo")) { throw new WrongUsageException(getUsage(sender)); } else if (args.length >= 4) { pos = parseBlockPos(sender, args, 1, false); @@ -62,10 +64,18 @@ public void execute(MinecraftServer server, ICommandSender sender, String[] args case "size": getSize(sender, bsc); return; - case "blockInfo": + case "posInfo": boolean isFull = false; if (args.length >= 5) isFull = args[4].equals("full"); - infoPalette(sender, bsc, pos, isFull); + Block block = null; + if (args.length >= 6) block = CommandBase.getBlockByText(sender, args[5]); + IBlockState iblockstate = null; + if (args.length >= 7 && block != null) { + iblockstate = convertArgToBlockState(block, args[6]); + } else if (block != null) { + iblockstate = block.getDefaultState(); + } + infoPalette(sender, bsc, pos, isFull, iblockstate); return; case "fill": int bitSize = -1; @@ -154,7 +164,7 @@ private static void fill(ICommandSender sender, BlockStateContainer bsc, BlockPo } } - private void infoPalette(ICommandSender sender, BlockStateContainer bsc, BlockPos pos, boolean full) { + private void infoPalette(ICommandSender sender, BlockStateContainer bsc, BlockPos pos, boolean full, IBlockState blockState) { BitArray bArray = bsc.getStorage(); int bits = bArray.getBitsPerEntry(); int index = getIndex(pos); @@ -180,6 +190,37 @@ private void infoPalette(ICommandSender sender, BlockStateContainer bsc, BlockPo } } } + if (blockState != null && bsc.getPalette() instanceof BlockStatePaletteRegistry && j != k) { + int blockStateBits = Block.BLOCK_STATE_IDS.get(blockState); + int leftBits = 64 - l; + int rightBits = bits - leftBits; + int leftMask = (1 << leftBits) - 1; + int rightMask = ((1 << rightBits) - 1) << leftBits; + int blockStateMaskL = blockStateBits & leftMask; + int blockStateMaskR = blockStateBits & rightMask; + sender.sendMessage(new TextComponentString("Left bit match:")); + for(int itr = 0; itr < Block.BLOCK_STATE_IDS.size(); itr++){ + IBlockState ibs = Block.BLOCK_STATE_IDS.getByValue(itr); + if(ibs != null) { + int left = itr & leftMask; + if(left == blockStateMaskL){ + String s = String.format("%"+bits+"s", Integer.toBinaryString(itr)).replace(' ', '0') + " " + ibs.toString().replace("minecraft:", ""); + sender.sendMessage(new TextComponentString(s)); + } + } + } + sender.sendMessage(new TextComponentString("Right bit match:")); + for(int itr = 0; itr < Block.BLOCK_STATE_IDS.size(); itr++){ + IBlockState ibs = Block.BLOCK_STATE_IDS.getByValue(itr); + if(ibs != null) { + int right = itr & rightMask; + if(right == blockStateMaskR){ + String s = String.format("%"+bits+"s", Integer.toBinaryString(itr)).replace(' ', '0') + " " + ibs.toString().replace("minecraft:", ""); + sender.sendMessage(new TextComponentString(s)); + } + } + } + } } private static void displayJKBits(ICommandSender sender, long longString, long l1, long l2, String append) { @@ -193,23 +234,18 @@ private static void displayJKBits(ICommandSender sender, long longString, long l sb.append(add + s); if (bitNum == l2) add = "§f"; } - sender.sendMessage(new TextComponentString("L" + append + ":" + sb)); + sender.sendMessage(new TextComponentString("§8L" + append + ":" + sb)); } private static BlockPos[] getArrayFromJK(int j, int k, int bits, BlockPos pos) { BlockPos basePos = new BlockPos(pos.getX() >>> 4 << 4, pos.getY() >>> 4 << 4, pos.getZ() >>> 4 << 4); - BlockPos.MutableBlockPos mute = new BlockPos.MutableBlockPos(); ArrayList list = new ArrayList<>(); - for (int x = 0; x < 16; ++x) { - for (int y = 0; y < 16; ++y) { - for (int z = 0; z < 16; ++z) { - int index = getIndex(mute.setPos(x, y, z)); - int jj = x / 64; - int kk = ((index + 1) * bits - 1) / 64; - if (jj == j || kk == k) { - list.add(new BlockPos(x, y, z).add(basePos)); - } - } + for(int index = 0; index < 4096; index++){ + int i = index * bits; + int jj = i / 64; + int kk = ((index + 1) * bits - 1) / 64; + if (jj == j || kk == k || jj == k || kk == j) { + list.add(getBlockIndex(index, basePos)); } } return list.toArray(new BlockPos[0]); @@ -244,13 +280,15 @@ private void getSize(ICommandSender sender, BlockStateContainer bsc) { public List getTabCompletions(MinecraftServer server, ICommandSender sender, String[] args, @Nullable BlockPos targetPos) { if (args.length == 1) { - return getListOfStringsMatchingLastWord(args, "bits", "size", "blockInfo", "fill"); + return getListOfStringsMatchingLastWord(args, "bits", "size", "posInfo", "fill"); } else if (args.length >= 2 && args.length <= 4) { return getTabCompletionCoordinate(args, 1, targetPos); - } else if (args.length == 5 || args[0].equals("blockInfo") || args[0].equals("fill")) { + } else if (args.length == 5 && (args[0].equals("posInfo") || args[0].equals("fill"))) { return getListOfStringsMatchingLastWord(args, "full", "normal"); } else if (args.length == 6 && args[0].equals("fill")) { - return getListOfStringsMatchingLastWord(args, "4", "5", "14"); + return getListOfStringsMatchingLastWord(args, "4", "5", "13"); + } else if (args.length == 6 && args[0].equals("posInfo")) { + return getListOfStringsMatchingLastWord(args, Block.REGISTRY.getKeys()); } else { return Collections.emptyList(); } From c7a4e9d4cbf32c50a560d5f9e715eedeff419cd3 Mon Sep 17 00:00:00 2001 From: 2No2Name <2No2Name@web.de> Date: Wed, 9 Feb 2022 03:43:40 +0100 Subject: [PATCH 34/46] fix: remove patch that causes invisible chunk sections due to change of fallback palette --- carpetmodSrc/carpet/CarpetSettings.java | 3 -- .../block/BlockPistonBase.java.patch | 34 +++---------- .../block/BlockPistonMoving.java.patch | 51 ------------------- 3 files changed, 6 insertions(+), 82 deletions(-) delete mode 100644 patches/net/minecraft/block/BlockPistonMoving.java.patch diff --git a/carpetmodSrc/carpet/CarpetSettings.java b/carpetmodSrc/carpet/CarpetSettings.java index 74a2e938..78493211 100644 --- a/carpetmodSrc/carpet/CarpetSettings.java +++ b/carpetmodSrc/carpet/CarpetSettings.java @@ -642,9 +642,6 @@ public static enum RedstoneDustAlgorithm { }) public static boolean boundingBoxFix = false; - @Rule(desc = "Blocks inherit the original light opacity and light values while being pushed with a piston", category = OPTIMIZATIONS) - public static boolean movingBlockLightOptimization = false; - @Rule(desc = "Chunk saving issues that causes entites and blocks to duplicate or disappear", category = FIX, extra = "By Theosib") @BugFixDefault public static boolean entityDuplicationFix = false; diff --git a/patches/net/minecraft/block/BlockPistonBase.java.patch b/patches/net/minecraft/block/BlockPistonBase.java.patch index 89aa2ee4..2a655882 100644 --- a/patches/net/minecraft/block/BlockPistonBase.java.patch +++ b/patches/net/minecraft/block/BlockPistonBase.java.patch @@ -197,7 +197,7 @@ } List list2 = blockpistonstructurehelper.func_177252_d(); -@@ -358,15 +456,70 @@ +@@ -358,15 +456,50 @@ --k; aiblockstate[k] = iblockstate; } @@ -228,33 +228,11 @@ + } + // ----- RSMM End ----- // IBlockState iblockstate2 = p_176319_1_.func_180495_p(blockpos3); -- p_176319_1_.func_180501_a(blockpos3, Blocks.field_150350_a.func_176223_P(), 2); + p_176319_1_.func_180501_a(blockpos3, Blocks.field_150350_a.func_176223_P(), 2); blockpos3 = blockpos3.func_177972_a(enumfacing); -- p_176319_1_.func_180501_a(blockpos3, Blocks.field_180384_M.func_176223_P().func_177226_a(field_176387_N, p_176319_3_), 4); + p_176319_1_.func_180501_a(blockpos3, Blocks.field_180384_M.func_176223_P().func_177226_a(field_176387_N, p_176319_3_), 4); - p_176319_1_.func_175690_a(blockpos3, BlockPistonMoving.func_185588_a(list1.get(l), p_176319_3_, p_176319_4_, false)); -+ // Added the properties of opacity and light to the moving block as to minimize light updates. CARPET-XCOM -+ if(CarpetSettings.movingBlockLightOptimization){ -+ BlockPos posOld = list.get(l); -+ boolean remove = true; -+ for (int backwardCheck = l - 1; backwardCheck >= 0; --backwardCheck){ -+ BlockPos blockposCheck = list.get(backwardCheck); -+ if(blockposCheck.func_177972_a(enumfacing).equals(posOld)){ -+ remove = false; -+ break; -+ } -+ } -+ IBlockState iBlockState = Blocks.field_180384_M.func_176223_P().func_177226_a(field_176387_N, p_176319_3_) -+ .func_177226_a(BlockPistonMoving.OPACITY, Math.min(iblockstate2.func_185891_c(), 15)) -+ .func_177226_a(BlockPistonMoving.LIGHT, iblockstate2.func_185906_d()); -+ p_176319_1_.func_180501_a(blockpos3, iBlockState, 20); -+ if(remove){ -+ p_176319_1_.func_180501_a(posOld, Blocks.field_150350_a.func_176223_P(), 2); -+ } -+ p_176319_1_.func_190522_c(blockpos3, iBlockState.func_177230_c()); -+ }else{ -+ p_176319_1_.func_180501_a(list.get(l), Blocks.field_150350_a.func_176223_P(), 2); -+ p_176319_1_.func_180501_a(blockpos3, Blocks.field_180384_M.func_176223_P().func_177226_a(field_176387_N, p_176319_3_), 4); -+ } ++ + // Movable Tile entity fix CARPET-2No2Name + if(CarpetSettings.autocrafter && iblockstate2 instanceof BlockWorkbench){ + TileEntity tilePiston = BlockPistonMoving.func_185588_a(list1.get(l), p_176319_3_, p_176319_4_, false); @@ -271,7 +249,7 @@ --k; aiblockstate[k] = iblockstate2; } -@@ -397,6 +550,8 @@ +@@ -397,6 +530,8 @@ p_176319_1_.func_175685_c(blockpos2, Blocks.field_150332_K, false); } @@ -280,7 +258,7 @@ return true; } } -@@ -439,4 +594,9 @@ +@@ -439,4 +574,9 @@ p_193383_2_ = this.func_176221_a(p_193383_2_, p_193383_1_, p_193383_3_); return p_193383_2_.func_177229_b(field_176387_N) != p_193383_4_.func_176734_d() && ((Boolean)p_193383_2_.func_177229_b(field_176320_b)).booleanValue() ? BlockFaceShape.UNDEFINED : BlockFaceShape.SOLID; } diff --git a/patches/net/minecraft/block/BlockPistonMoving.java.patch b/patches/net/minecraft/block/BlockPistonMoving.java.patch deleted file mode 100644 index a6d32fcd..00000000 --- a/patches/net/minecraft/block/BlockPistonMoving.java.patch +++ /dev/null @@ -1,51 +0,0 @@ ---- ../src-base/minecraft/net/minecraft/block/BlockPistonMoving.java -+++ ../src-work/minecraft/net/minecraft/block/BlockPistonMoving.java -@@ -28,15 +28,21 @@ - import net.minecraft.world.IBlockAccess; - import net.minecraft.world.World; - -+import net.minecraft.block.properties.PropertyInteger; -+ - public class BlockPistonMoving extends BlockContainer - { - public static final PropertyDirection field_176426_a = BlockPistonExtension.field_176387_N; - public static final PropertyEnum field_176425_b = BlockPistonExtension.field_176325_b; - -+ // Getting propertys from other sources as its apparently laggy to create your own. CARPET-XCOM -+ public static final PropertyInteger OPACITY = BlockDaylightDetector.field_176436_a; -+ public static final PropertyInteger LIGHT = BlockLiquid.field_176367_b; -+ - public BlockPistonMoving() - { - super(Material.field_76233_E); -- this.func_180632_j(this.field_176227_L.func_177621_b().func_177226_a(field_176426_a, EnumFacing.NORTH).func_177226_a(field_176425_b, BlockPistonExtension.EnumPistonType.DEFAULT)); -+ this.func_180632_j(this.field_176227_L.func_177621_b().func_177226_a(field_176426_a, EnumFacing.NORTH).func_177226_a(field_176425_b, BlockPistonExtension.EnumPistonType.DEFAULT).func_177226_a(OPACITY, 0).func_177226_a(LIGHT, 0)); - this.func_149711_c(-1.0F); - } - -@@ -207,11 +213,24 @@ - - protected BlockStateContainer func_180661_e() - { -- return new BlockStateContainer(this, new IProperty[] {field_176426_a, field_176425_b}); -+ // Adding the propertys to the list of allowed propertys. CARPET-XCOM -+ return new BlockStateContainer(this, new IProperty[] {field_176426_a, field_176425_b, OPACITY, LIGHT}); - } - - public BlockFaceShape func_193383_a(IBlockAccess p_193383_1_, IBlockState p_193383_2_, BlockPos p_193383_3_, EnumFacing p_193383_4_) - { - return BlockFaceShape.UNDEFINED; - } -+ -+ // Grabbing the inherited properties from the parrent block that is moved and setting it to the moving block. CARPET-XCOM -+ @Override -+ public int func_149717_k(IBlockState state) -+ { -+ return state.func_177229_b(OPACITY); -+ } -+ @Override -+ public int func_149750_m(IBlockState state) -+ { -+ return state.func_177229_b(LIGHT); -+ } - } From 123fd98d5b8ee67d33e4e138cd2cf0d1d814d877 Mon Sep 17 00:00:00 2001 From: Unknown Date: Wed, 9 Feb 2022 15:50:55 +0100 Subject: [PATCH 35/46] Added miner tweaks, messages and fixes to palette command --- .../carpet/commands/CommandPalette.java | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/carpetmodSrc/carpet/commands/CommandPalette.java b/carpetmodSrc/carpet/commands/CommandPalette.java index d7f4d3f8..42e30a61 100644 --- a/carpetmodSrc/carpet/commands/CommandPalette.java +++ b/carpetmodSrc/carpet/commands/CommandPalette.java @@ -27,7 +27,7 @@ public class CommandPalette extends CommandCarpetBase { */ public String getUsage(ICommandSender sender) { - return "Usage: palette <4 to 13>"; + return "Usage: palette <4-8 | 13>"; } public String getName() { @@ -199,27 +199,31 @@ private void infoPalette(ICommandSender sender, BlockStateContainer bsc, BlockPo int blockStateMaskL = blockStateBits & leftMask; int blockStateMaskR = blockStateBits & rightMask; sender.sendMessage(new TextComponentString("Left bit match:")); - for(int itr = 0; itr < Block.BLOCK_STATE_IDS.size(); itr++){ + for (int itr = 0; itr < Block.BLOCK_STATE_IDS.size(); itr++) { IBlockState ibs = Block.BLOCK_STATE_IDS.getByValue(itr); - if(ibs != null) { + if (ibs != null) { int left = itr & leftMask; - if(left == blockStateMaskL){ - String s = String.format("%"+bits+"s", Integer.toBinaryString(itr)).replace(' ', '0') + " " + ibs.toString().replace("minecraft:", ""); + if (left == blockStateMaskL) { + String s = String.format("%" + bits + "s", Integer.toBinaryString(itr)).replace(' ', '0') + " " + ibs.toString().replace("minecraft:", ""); sender.sendMessage(new TextComponentString(s)); } } } sender.sendMessage(new TextComponentString("Right bit match:")); - for(int itr = 0; itr < Block.BLOCK_STATE_IDS.size(); itr++){ + for (int itr = 0; itr < Block.BLOCK_STATE_IDS.size(); itr++) { IBlockState ibs = Block.BLOCK_STATE_IDS.getByValue(itr); - if(ibs != null) { + if (ibs != null) { int right = itr & rightMask; - if(right == blockStateMaskR){ - String s = String.format("%"+bits+"s", Integer.toBinaryString(itr)).replace(' ', '0') + " " + ibs.toString().replace("minecraft:", ""); + if (right == blockStateMaskR) { + String s = String.format("%" + bits + "s", Integer.toBinaryString(itr)).replace(' ', '0') + " " + ibs.toString().replace("minecraft:", ""); sender.sendMessage(new TextComponentString(s)); } } } + } else if (blockState != null && j != k) { + sender.sendMessage(new TextComponentString("This location doesn't share two bit arrays.")); + } else if (blockState != null && bsc.getPalette() instanceof BlockStatePaletteRegistry) { + sender.sendMessage(new TextComponentString("This subchunk doesn't have enough palettes, add more palettes.")); } } @@ -240,7 +244,7 @@ private static void displayJKBits(ICommandSender sender, long longString, long l private static BlockPos[] getArrayFromJK(int j, int k, int bits, BlockPos pos) { BlockPos basePos = new BlockPos(pos.getX() >>> 4 << 4, pos.getY() >>> 4 << 4, pos.getZ() >>> 4 << 4); ArrayList list = new ArrayList<>(); - for(int index = 0; index < 4096; index++){ + for (int index = 0; index < 4096; index++) { int i = index * bits; int jj = i / 64; int kk = ((index + 1) * bits - 1) / 64; @@ -274,7 +278,7 @@ private void getSize(ICommandSender sender, BlockStateContainer bsc) { } else if (ibsp instanceof BlockStatePaletteHashMap) { sender.sendMessage(new TextComponentString("Palette size: " + ((BlockStatePaletteHashMap) ibsp).paletteSize())); } else if (ibsp instanceof BlockStatePaletteRegistry) { - sender.sendMessage(new TextComponentString("Palette size MAX aka 4096")); + sender.sendMessage(new TextComponentString("Palette size MAX aka " + Block.BLOCK_STATE_IDS.size())); } } @@ -286,11 +290,11 @@ public List getTabCompletions(MinecraftServer server, ICommandSender sen } else if (args.length == 5 && (args[0].equals("posInfo") || args[0].equals("fill"))) { return getListOfStringsMatchingLastWord(args, "full", "normal"); } else if (args.length == 6 && args[0].equals("fill")) { - return getListOfStringsMatchingLastWord(args, "4", "5", "13"); + return getListOfStringsMatchingLastWord(args, "4", "5", "6", "7", "8", "13"); } else if (args.length == 6 && args[0].equals("posInfo")) { return getListOfStringsMatchingLastWord(args, Block.REGISTRY.getKeys()); } else { return Collections.emptyList(); } } -} +} \ No newline at end of file From 4819e1c4c08e3e9d3966cd8f9e0a5628e96401da Mon Sep 17 00:00:00 2001 From: Unknown Date: Wed, 9 Feb 2022 15:51:08 +0100 Subject: [PATCH 36/46] v22_02_09 --- carpetmodSrc/carpet/CarpetSettings.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/carpetmodSrc/carpet/CarpetSettings.java b/carpetmodSrc/carpet/CarpetSettings.java index 78493211..6f6a72ff 100644 --- a/carpetmodSrc/carpet/CarpetSettings.java +++ b/carpetmodSrc/carpet/CarpetSettings.java @@ -45,7 +45,7 @@ public class CarpetSettings public static boolean locked = false; // TODO: replace these constants at build time - public static final String carpetVersion = "v22_01_27"; + public static final String carpetVersion = "v22_02_09"; public static final String minecraftVersion = "1.12.2"; public static final String mcpMappings = "39-1.12"; From e44817bf0730ffd37dd7301ed88b3c7ba9a48d27 Mon Sep 17 00:00:00 2001 From: Joe Date: Thu, 24 Feb 2022 16:34:04 +0000 Subject: [PATCH 37/46] Add saveSavestates rule --- carpetmodSrc/carpet/CarpetSettings.java | 3 + .../carpet/helpers/SaveSavestatesHelper.java | 63 +++++++++++++++++++ .../inventory/ItemStackHelper.java.patch | 25 ++++++++ 3 files changed, 91 insertions(+) create mode 100644 carpetmodSrc/carpet/helpers/SaveSavestatesHelper.java create mode 100644 patches/net/minecraft/inventory/ItemStackHelper.java.patch diff --git a/carpetmodSrc/carpet/CarpetSettings.java b/carpetmodSrc/carpet/CarpetSettings.java index 6f6a72ff..88d2533e 100644 --- a/carpetmodSrc/carpet/CarpetSettings.java +++ b/carpetmodSrc/carpet/CarpetSettings.java @@ -787,6 +787,9 @@ private static boolean validateRandomTickOptimization(boolean value) { @Rule(desc = "Sends invisible duplicate UUID entities to clients", category = FIX) public static boolean sendDuplicateEntitiesToClients = false; + @Rule(desc = "Enables best-effort saving of savestated chunks", category = FIX) + public static boolean saveSavestates = false; + // ===== FEATURES ===== // @Rule(desc = "Enables skyblock on 1.12, all blocks but end portal frames will be removed in newly generated chunks.", category = FEATURE, extra = "WARNING! Don't turn on if not planning to play skyblock.") diff --git a/carpetmodSrc/carpet/helpers/SaveSavestatesHelper.java b/carpetmodSrc/carpet/helpers/SaveSavestatesHelper.java new file mode 100644 index 00000000..1109b026 --- /dev/null +++ b/carpetmodSrc/carpet/helpers/SaveSavestatesHelper.java @@ -0,0 +1,63 @@ +package carpet.helpers; + +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.util.NonNullList; +import org.apache.commons.lang3.tuple.Pair; + +import java.util.ArrayList; +import java.util.List; + +public class SaveSavestatesHelper { + public static void trySaveItemsCompressed(NBTTagCompound destTag, NonNullList items, boolean saveEmpty) { + List> itemsAndSlots = new ArrayList<>(items.size()); + for (int i = 0; i < items.size(); i++) { + itemsAndSlots.add(Pair.of(i, items.get(i))); + } + + itemsAndSlots.sort((a, b) -> compareItems(a.getRight(), b.getRight())); + + NBTTagList itemsTag = new NBTTagList(); + for (Pair itemAndSlot : itemsAndSlots) { + int slot = itemAndSlot.getLeft(); + ItemStack item = itemAndSlot.getRight(); + if (!item.isEmpty()) { + NBTTagCompound itemTag = new NBTTagCompound(); + itemTag.setByte("Slot", (byte) slot); + item.writeToNBT(itemTag); + itemsTag.appendTag(itemTag); + } + } + + if (!itemsTag.isEmpty() || saveEmpty) { + destTag.setTag("Items", itemsTag); + } + } + + private static int compareItems(ItemStack a, ItemStack b) { + int idA = Item.getIdFromItem(a.getItem()); + int idB = Item.getIdFromItem(b.getItem()); + if (idA != idB) { + return Integer.compare(idA, idB); + } + + NBTTagCompound tagA = a.getTagCompound(); + NBTTagCompound tagB = b.getTagCompound(); + if (tagA != null && tagB != null) { + NBTTagList pagesA = tagA.getTagList("pages", 8); + NBTTagList pagesB = tagB.getTagList("pages", 8); + for (int page = 0; page < Math.min(pagesA.tagCount(), pagesB.tagCount()); page++) { + String pageA = pagesA.getStringTagAt(page); + String pageB = pagesB.getStringTagAt(page); + int cmp = pageA.compareTo(pageB); + if (cmp != 0) { + return cmp; + } + } + } + + return 0; + } +} diff --git a/patches/net/minecraft/inventory/ItemStackHelper.java.patch b/patches/net/minecraft/inventory/ItemStackHelper.java.patch new file mode 100644 index 00000000..31bb7f67 --- /dev/null +++ b/patches/net/minecraft/inventory/ItemStackHelper.java.patch @@ -0,0 +1,25 @@ +--- ../src-base/minecraft/net/minecraft/inventory/ItemStackHelper.java ++++ ../src-work/minecraft/net/minecraft/inventory/ItemStackHelper.java +@@ -6,6 +6,9 @@ + import net.minecraft.nbt.NBTTagList; + import net.minecraft.util.NonNullList; + ++import carpet.CarpetSettings; ++import carpet.helpers.SaveSavestatesHelper; ++ + public class ItemStackHelper + { + public static ItemStack func_188382_a(List p_188382_0_, int p_188382_1_, int p_188382_2_) +@@ -25,6 +28,12 @@ + + public static NBTTagCompound func_191281_a(NBTTagCompound p_191281_0_, NonNullList p_191281_1_, boolean p_191281_2_) + { ++ if (CarpetSettings.saveSavestates) ++ { ++ SaveSavestatesHelper.trySaveItemsCompressed(p_191281_0_, p_191281_1_, p_191281_2_); ++ return p_191281_0_; ++ } ++ + NBTTagList nbttaglist = new NBTTagList(); + + for (int i = 0; i < p_191281_1_.size(); ++i) From a7735070b850c54d0e9b86e5aa25f4d980ab9ab0 Mon Sep 17 00:00:00 2001 From: johannes-schmatz <67289119+johannes-schmatz@users.noreply.github.com> Date: Mon, 28 Feb 2022 13:28:11 +0000 Subject: [PATCH 38/46] Use launcher.mojang.com instead of s3.amazonaws.com to download server.jar (#170) * let mktest.sh use launcher.mojang.com instead of amazonaws to download the server jar * use launcher.mojang.com in the docs instead of amazonaws for downloading the server jar --- docs/usage/install.rst | 2 +- mktest.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/usage/install.rst b/docs/usage/install.rst index ad148c2f..ae195133 100644 --- a/docs/usage/install.rst +++ b/docs/usage/install.rst @@ -35,7 +35,7 @@ First, create a clean directory (folder). For this tutorial, we call it ``carpet``. There, download the vanilla jar and Carpet patch. * `Download the 1.12.2 vanilla server jar - `_. + `_. * `Download the latest Carpet patch `_. diff --git a/mktest.sh b/mktest.sh index 8beb25e7..ca3ca148 100755 --- a/mktest.sh +++ b/mktest.sh @@ -69,7 +69,7 @@ else cp "$GRADLE_CACHE_JAR" "$MC_JAR" else echo "Downloading server ..." - wget "https://s3.amazonaws.com/Minecraft.Download/versions/1.12.2/minecraft_server.1.12.2.jar" -O "$MC_JAR" || { echo "failed to download MC jar" && exit 1; } + wget "https://launcher.mojang.com/v1/objects/886945bfb2b978778c3a0288fd7fab09d315b25f/server.jar" -O "$MC_JAR" || { echo "failed to download MC jar" && exit 1; } cp "$MC_JAR" "$MC_JAR.orig" fi fi From 5cc8751e8b54a59b41b0fd196f7280037b1fa4c7 Mon Sep 17 00:00:00 2001 From: Joe Date: Mon, 14 Mar 2022 00:05:32 +0000 Subject: [PATCH 39/46] Add /feel and /colon, add noupdate option to /zetblock --- .../carpet/commands/CarpetCommands.java | 8 +- .../carpet/commands/CommandColon.java | 318 ++++++++++++++++++ carpetmodSrc/carpet/commands/CommandFeel.java | 270 +++++++++++++++ .../carpet/commands/CommandZetBlock.java | 15 +- .../minecraft/command/CommandFill.java.patch | 6 +- 5 files changed, 609 insertions(+), 8 deletions(-) create mode 100644 carpetmodSrc/carpet/commands/CommandColon.java create mode 100644 carpetmodSrc/carpet/commands/CommandFeel.java diff --git a/carpetmodSrc/carpet/commands/CarpetCommands.java b/carpetmodSrc/carpet/commands/CarpetCommands.java index f32849f2..f2c1f3aa 100644 --- a/carpetmodSrc/carpet/commands/CarpetCommands.java +++ b/carpetmodSrc/carpet/commands/CarpetCommands.java @@ -7,15 +7,19 @@ public class CarpetCommands { public static void register(CommandHandler handler) { // Sorted alphabetically to make merge conflicts less likely + // For Xcom: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z + handler.registerCommand(new CommandAutosave()); handler.registerCommand(new CommandBlockInfo()); handler.registerCommand(new CommandCarpet()); handler.registerCommand(new CommandChunk()); + handler.registerCommand(new CommandColon()); handler.registerCommand(new CommandCounter()); handler.registerCommand(new CommandDebugCarpet()); handler.registerCommand(new CommandDebuglogger()); handler.registerCommand(new CommandDistance()); handler.registerCommand(new CommandEntityInfo()); + handler.registerCommand(new CommandFeel()); handler.registerCommand(new CommandFillBiome()); handler.registerCommand(new CommandGMC()); handler.registerCommand(new CommandGMS()); @@ -25,6 +29,7 @@ public static void register(CommandHandler handler) { handler.registerCommand(new CommandLight()); handler.registerCommand(new CommandLoadedChunks()); handler.registerCommand(new CommandLog()); + handler.registerCommand(new CommandPalette()); handler.registerCommand(new CommandPerimeter()); handler.registerCommand(new CommandPing()); handler.registerCommand(new CommandPlayer()); @@ -43,10 +48,7 @@ public static void register(CommandHandler handler) { handler.registerCommand(new CommandUnload13()); handler.registerCommand(new CommandUpdateCarpet()); handler.registerCommand(new CommandWaypoint()); - handler.registerCommand(new CommandChunk()); - handler.registerCommand(new CommandLoadedChunks()); handler.registerCommand(new CommandZetBlock()); - handler.registerCommand(new CommandPalette()); // ----- RSMM Start ----- // handler.registerCommand(new MeterCommand(CarpetServer.rsmmServer)); diff --git a/carpetmodSrc/carpet/commands/CommandColon.java b/carpetmodSrc/carpet/commands/CommandColon.java new file mode 100644 index 00000000..b88a29bb --- /dev/null +++ b/carpetmodSrc/carpet/commands/CommandColon.java @@ -0,0 +1,318 @@ +package carpet.commands; + +import com.google.common.base.Predicate; +import com.google.common.collect.Lists; +import java.util.Collections; +import java.util.Deque; +import java.util.List; +import javax.annotation.Nullable; +import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; +import net.minecraft.command.CommandBase; +import net.minecraft.command.CommandClone; +import net.minecraft.command.CommandException; +import net.minecraft.command.CommandResultStats; +import net.minecraft.command.ICommandSender; +import net.minecraft.command.WrongUsageException; +import net.minecraft.init.Blocks; +import net.minecraft.inventory.IInventory; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.server.MinecraftServer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.NextTickListEntry; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureBoundingBox; + +import carpet.CarpetSettings; +import carpet.worldedit.WorldEditBridge; +import net.minecraft.entity.player.EntityPlayerMP; + +public class CommandColon extends CommandBase +{ + /** + * Gets the name of the command + */ + public String getName() + { + return "colon"; + } + + /** + * Return the required permission level for this command. + */ + public int getRequiredPermissionLevel() + { + return 2; + } + + /** + * Gets the usage string for the command. + */ + public String getUsage(ICommandSender sender) + { + return "commands.clone.usage"; + } + + /** + * Callback for when the command is executed + */ + public void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException + { + if (args.length < 9) + { + throw new WrongUsageException("commands.clone.usage", new Object[0]); + } + else + { + sender.setCommandStat(CommandResultStats.Type.AFFECTED_BLOCKS, 0); + BlockPos blockpos = parseBlockPos(sender, args, 0, false); + BlockPos blockpos1 = parseBlockPos(sender, args, 3, false); + BlockPos blockpos2 = parseBlockPos(sender, args, 6, false); + StructureBoundingBox structureboundingbox = new StructureBoundingBox(blockpos, blockpos1); + StructureBoundingBox structureboundingbox1 = new StructureBoundingBox(blockpos2, blockpos2.add(structureboundingbox.getLength())); + + boolean flag = false; + Block block = null; + Predicate predicate = null; + + if ((args.length < 11 || !"force".equals(args[10]) && !"move".equals(args[10]) && !"force_noupdate".equals(args[10]) && !"move_noupdate".equals(args[10])) && structureboundingbox.intersectsWith(structureboundingbox1)) + { + throw new CommandException("commands.clone.noOverlap", new Object[0]); + } + else + { + if (args.length >= 11 && ("move".equals(args[10]) || "move_noupdate".equals(args[10]))) + { + flag = true; + } + + boolean update = true; + if (args.length >= 11 && ("noupdate".equals(args[10]) || "force_noupdate".equals(args[10]) || "move_noupdate".equals(args[10]))) + { + update = false; + } + + if (structureboundingbox.minY >= 0 && structureboundingbox.maxY < 256 && structureboundingbox1.minY >= 0 && structureboundingbox1.maxY < 256) + { + World world = sender.getEntityWorld(); + + boolean flag1 = false; + + if (args.length >= 10) + { + if ("masked".equals(args[9])) + { + flag1 = true; + } + else if ("filtered".equals(args[9])) + { + if (args.length < 12) + { + throw new WrongUsageException("commands.clone.usage", new Object[0]); + } + + block = getBlockByText(sender, args[11]); + + if (args.length >= 13) + { + predicate = convertArgToBlockStatePredicate(block, args[12]); + } + } + } + + List list = Lists.newArrayList(); + List list1 = Lists.newArrayList(); + List list2 = Lists.newArrayList(); + Deque deque = Lists.newLinkedList(); + BlockPos blockpos3 = new BlockPos(structureboundingbox1.minX - structureboundingbox.minX, structureboundingbox1.minY - structureboundingbox.minY, structureboundingbox1.minZ - structureboundingbox.minZ); + + for (int j = structureboundingbox.minZ; j <= structureboundingbox.maxZ; ++j) + { + for (int k = structureboundingbox.minY; k <= structureboundingbox.maxY; ++k) + { + for (int l = structureboundingbox.minX; l <= structureboundingbox.maxX; ++l) + { + BlockPos blockpos4 = new BlockPos(l, k, j); + BlockPos blockpos5 = blockpos4.add(blockpos3); + IBlockState iblockstate = world.getBlockState(blockpos4); + + if ((!flag1 || iblockstate.getBlock() != Blocks.AIR) && (block == null || iblockstate.getBlock() == block && (predicate == null || predicate.apply(iblockstate)))) + { + TileEntity tileentity = world.getTileEntity(blockpos4); + + if (tileentity != null) + { + NBTTagCompound nbttagcompound = tileentity.writeToNBT(new NBTTagCompound()); + list1.add(new StaticCloneData(blockpos5, iblockstate, nbttagcompound)); + deque.addLast(blockpos4); + } + else if (!iblockstate.isFullBlock() && !iblockstate.isFullCube()) + { + list2.add(new StaticCloneData(blockpos5, iblockstate, (NBTTagCompound)null)); + deque.addFirst(blockpos4); + } + else + { + list.add(new StaticCloneData(blockpos5, iblockstate, (NBTTagCompound)null)); + deque.addLast(blockpos4); + } + } + } + } + } + + EntityPlayerMP worldEditPlayer = sender instanceof EntityPlayerMP ? (EntityPlayerMP) sender : null; + + if (flag) + { + for (BlockPos blockpos6 : deque) + { + WorldEditBridge.recordBlockEdit(worldEditPlayer, world, blockpos6, Blocks.AIR.getDefaultState(), null); + TileEntity tileentity1 = world.getTileEntity(blockpos6); + + if (tileentity1 instanceof IInventory) + { + ((IInventory)tileentity1).clear(); + } + + world.setBlockState(blockpos6, Blocks.BARRIER.getDefaultState(), 2 | (update?0:128)); //carpet + } + + for (BlockPos blockpos7 : deque) + { + world.setBlockState(blockpos7, Blocks.AIR.getDefaultState(), (update?3:131)); //carpet + } + } + + List list3 = Lists.newArrayList(); + list3.addAll(list); + list3.addAll(list1); + list3.addAll(list2); + List list4 = Lists.reverse(list3); + + for (StaticCloneData commandclone$staticclonedata : list4) + { + WorldEditBridge.recordBlockEdit(worldEditPlayer, world, commandclone$staticclonedata.pos, commandclone$staticclonedata.blockState, commandclone$staticclonedata.nbt); + TileEntity tileentity2 = world.getTileEntity(commandclone$staticclonedata.pos); + + if (tileentity2 instanceof IInventory) + { + ((IInventory)tileentity2).clear(); + } + + world.setBlockState(commandclone$staticclonedata.pos, Blocks.BARRIER.getDefaultState(), 2 | (update?0:128)); //carpet + } + + int i = 0; + + for (StaticCloneData commandclone$staticclonedata1 : list3) + { + if (world.setBlockState(commandclone$staticclonedata1.pos, commandclone$staticclonedata1.blockState, 2 | (update?0:128))) //carpet + { + ++i; + } + } + for (StaticCloneData commandclone$staticclonedata2 : list1) + { + TileEntity tileentity3 = world.getTileEntity(commandclone$staticclonedata2.pos); + + if (commandclone$staticclonedata2.nbt != null && tileentity3 != null) + { + commandclone$staticclonedata2.nbt.setInteger("x", commandclone$staticclonedata2.pos.getX()); + commandclone$staticclonedata2.nbt.setInteger("y", commandclone$staticclonedata2.pos.getY()); + commandclone$staticclonedata2.nbt.setInteger("z", commandclone$staticclonedata2.pos.getZ()); + tileentity3.readFromNBT(commandclone$staticclonedata2.nbt); + tileentity3.markDirty(); + } + + world.setBlockState(commandclone$staticclonedata2.pos, commandclone$staticclonedata2.blockState, 2); + } + + /*carpet mod */ + if (update) + { + /*carpet mod end EXTRA INDENTATION START*/ + for (StaticCloneData commandclone$staticclonedata3 : list4) + { + world.notifyNeighborsRespectDebug(commandclone$staticclonedata3.pos, commandclone$staticclonedata3.blockState.getBlock(), false); + } + + List list5 = world.getPendingBlockUpdates(structureboundingbox, false); + + if (list5 != null) + { + for (NextTickListEntry nextticklistentry : list5) + { + if (structureboundingbox.isVecInside(nextticklistentry.position)) + { + BlockPos blockpos8 = nextticklistentry.position.add(blockpos3); + world.scheduleBlockUpdate(blockpos8, nextticklistentry.getBlock(), (int)(nextticklistentry.scheduledTime - world.getWorldInfo().getWorldTotalTime()), nextticklistentry.priority); + } + } + } + } //carpet mod back extra indentation + + if (i <= 0) + { + throw new CommandException("commands.clone.failed", new Object[0]); + } + else + { + sender.setCommandStat(CommandResultStats.Type.AFFECTED_BLOCKS, i); + notifyCommandListener(sender, this, "commands.clone.success", new Object[] {i}); + } + } + else + { + throw new CommandException("commands.clone.outOfWorld", new Object[0]); + } + } + } + } + + /** + * Get a list of options for when the user presses the TAB key + */ + public List getTabCompletions(MinecraftServer server, ICommandSender sender, String[] args, @Nullable BlockPos targetPos) + { + if (args.length > 0 && args.length <= 3) + { + return getTabCompletionCoordinate(args, 0, targetPos); + } + else if (args.length > 3 && args.length <= 6) + { + return getTabCompletionCoordinate(args, 3, targetPos); + } + else if (args.length > 6 && args.length <= 9) + { + return getTabCompletionCoordinate(args, 6, targetPos); + } + else if (args.length == 10) + { + return getListOfStringsMatchingLastWord(args, new String[] {"replace", "masked", "filtered"}); + } + else if (args.length == 11) + { + return getListOfStringsMatchingLastWord(args, new String[] {"normal", "force", "move", "noupdate", "force_noupdate", "move_noupdate"}); + } + else + { + return args.length == 12 && "filtered".equals(args[9]) ? getListOfStringsMatchingLastWord(args, Block.REGISTRY.getKeys()) : Collections.emptyList(); + } + } + + static class StaticCloneData + { + public final BlockPos pos; + public final IBlockState blockState; + public final NBTTagCompound nbt; + + public StaticCloneData(BlockPos posIn, IBlockState stateIn, NBTTagCompound compoundIn) + { + this.pos = posIn; + this.blockState = stateIn; + this.nbt = compoundIn; + } + } +} diff --git a/carpetmodSrc/carpet/commands/CommandFeel.java b/carpetmodSrc/carpet/commands/CommandFeel.java new file mode 100644 index 00000000..e3e87d93 --- /dev/null +++ b/carpetmodSrc/carpet/commands/CommandFeel.java @@ -0,0 +1,270 @@ +package carpet.commands; + +import com.google.common.collect.Lists; +import java.util.Collections; +import java.util.List; +import java.util.Locale; +import java.util.function.Predicate; +import javax.annotation.Nullable; +import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; +import net.minecraft.command.CommandBase; +import net.minecraft.command.CommandException; +import net.minecraft.command.CommandResultStats; +import net.minecraft.command.ICommandSender; +import net.minecraft.command.WrongUsageException; +import net.minecraft.init.Blocks; +import net.minecraft.inventory.IInventory; +import net.minecraft.nbt.JsonToNBT; +import net.minecraft.nbt.NBTException; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.server.MinecraftServer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import carpet.CarpetSettings; +import carpet.helpers.CapturedDrops; +import carpet.worldedit.WorldEditBridge; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.player.EntityPlayerMP; + +public class CommandFeel extends CommandBase +{ + /** + * Gets the name of the command + */ + public String getName() + { + return "feel"; + } + + /** + * Return the required permission level for this command. + */ + public int getRequiredPermissionLevel() + { + return 2; + } + + /** + * Gets the usage string for the command. + */ + public String getUsage(ICommandSender sender) + { + return "commands.fill.usage"; + } + + /** + * Callback for when the command is executed + */ + public void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException + { + if (args.length < 7) + { + throw new WrongUsageException("commands.fill.usage", new Object[0]); + } + else + { + sender.setCommandStat(CommandResultStats.Type.AFFECTED_BLOCKS, 0); + BlockPos blockpos = parseBlockPos(sender, args, 0, false); + BlockPos blockpos1 = parseBlockPos(sender, args, 3, false); + Block block = CommandBase.getBlockByText(sender, args[6]); + IBlockState iblockstate; + + if (args.length >= 8) + { + iblockstate = convertArgToBlockState(block, args[7]); + } + else + { + iblockstate = block.getDefaultState(); + } + + BlockPos blockpos2 = new BlockPos(Math.min(blockpos.getX(), blockpos1.getX()), Math.min(blockpos.getY(), blockpos1.getY()), Math.min(blockpos.getZ(), blockpos1.getZ())); + BlockPos blockpos3 = new BlockPos(Math.max(blockpos.getX(), blockpos1.getX()), Math.max(blockpos.getY(), blockpos1.getY()), Math.max(blockpos.getZ(), blockpos1.getZ())); + int i = (blockpos3.getX() - blockpos2.getX() + 1) * (blockpos3.getY() - blockpos2.getY() + 1) * (blockpos3.getZ() - blockpos2.getZ() + 1); + + if (blockpos2.getY() >= 0 && blockpos3.getY() < 256) + { + World world = sender.getEntityWorld(); + + NBTTagCompound nbttagcompound = new NBTTagCompound(); + boolean flag = false; + + if (args.length >= 10 && block.hasTileEntity()) + { + String s = buildString(args, 9); + + try + { + nbttagcompound = JsonToNBT.getTagFromJson(s); + flag = true; + } + catch (NBTException nbtexception) + { + throw new CommandException("commands.fill.tagError", new Object[] {nbtexception.getMessage()}); + } + } + + FillType mode; + try { + mode = args.length <= 8 ? FillType.REPLACE : FillType.valueOf(args[8].toUpperCase(Locale.ROOT)); + } catch (IllegalArgumentException e) { + mode = FillType.REPLACE; + } + Block toReplace = null; + Predicate toReplacePredicate = state -> true; + if ((mode == FillType.REPLACE || mode == FillType.NOUPDATE) && args.length > 9) { + toReplace = CommandBase.getBlockByText(sender, args[9]); + if (args.length > 10 && !args[10].equals("-1") && !args[10].equals("*")) { + toReplacePredicate = CommandBase.convertArgToBlockStatePredicate(toReplace, args[10]); + } + } + + EntityPlayerMP worldEditPlayer = sender instanceof EntityPlayerMP ? (EntityPlayerMP) sender : null; + NBTTagCompound worldEditTag = flag ? nbttagcompound : null; + + List list = Lists.newArrayList(); + i = 0; + + for (int l = blockpos2.getZ(); l <= blockpos3.getZ(); ++l) + { + for (int i1 = blockpos2.getY(); i1 <= blockpos3.getY(); ++i1) + { + for (int j1 = blockpos2.getX(); j1 <= blockpos3.getX(); ++j1) + { + BlockPos blockpos4 = new BlockPos(j1, i1, l); + + if (args.length >= 9) + { + if (mode != FillType.OUTLINE && mode != FillType.HOLLOW) + { + if (mode == FillType.DESTROY) + { + WorldEditBridge.recordBlockEdit(worldEditPlayer, world, blockpos4, Blocks.AIR.getDefaultState(), worldEditTag); + CapturedDrops.setCapturingDrops(true); + world.destroyBlock(blockpos4, true); + CapturedDrops.setCapturingDrops(false); + for (EntityItem drop : CapturedDrops.getCapturedDrops()) + WorldEditBridge.recordEntityCreation(worldEditPlayer, world, drop); + CapturedDrops.clearCapturedDrops(); + } + else if (mode == FillType.KEEP) + { + if (!world.isAirBlock(blockpos4)) + { + continue; + } + } + else if ((mode == FillType.REPLACE || mode == FillType.NOUPDATE) && !block.hasTileEntity() && args.length > 9) + { + IBlockState state = world.getBlockState(blockpos4); + if (state.getBlock() != toReplace || !toReplacePredicate.test(state)) + { + continue; + } + } + } + else if (j1 != blockpos2.getX() && j1 != blockpos3.getX() && i1 != blockpos2.getY() && i1 != blockpos3.getY() && l != blockpos2.getZ() && l != blockpos3.getZ()) + { + if (mode == FillType.HOLLOW) + { + WorldEditBridge.recordBlockEdit(worldEditPlayer, world, blockpos4, Blocks.AIR.getDefaultState(), worldEditTag); + world.setBlockState(blockpos4, Blocks.AIR.getDefaultState(), 2); + list.add(blockpos4); + } + + continue; + } + } + + WorldEditBridge.recordBlockEdit(worldEditPlayer, world, blockpos4, iblockstate, worldEditTag); + TileEntity tileentity1 = world.getTileEntity(blockpos4); + + if (tileentity1 != null && tileentity1 instanceof IInventory) + { + ((IInventory)tileentity1).clear(); + } + + if (world.setBlockState(blockpos4, iblockstate, 2 | (mode != FillType.NOUPDATE?0:128) )) //CM + { + list.add(blockpos4); + ++i; + + if (flag) + { + TileEntity tileentity = world.getTileEntity(blockpos4); + + if (tileentity != null) + { + nbttagcompound.setInteger("x", blockpos4.getX()); + nbttagcompound.setInteger("y", blockpos4.getY()); + nbttagcompound.setInteger("z", blockpos4.getZ()); + tileentity.readFromNBT(nbttagcompound); + } + } + } + } + } + } + + /*carpet mod */ + if (mode != FillType.NOUPDATE) + { + /*carpet mod end EXTRA INDENT*/ + for (BlockPos blockpos5 : list) + { + Block block2 = world.getBlockState(blockpos5).getBlock(); + world.notifyNeighborsRespectDebug(blockpos5, block2, false); + } + } //carpet mod back extra indentation + + if (i <= 0) + { + throw new CommandException("commands.fill.failed", new Object[0]); + } + else + { + sender.setCommandStat(CommandResultStats.Type.AFFECTED_BLOCKS, i); + notifyCommandListener(sender, this, "commands.fill.success", new Object[] {i}); + } + } + else + { + throw new CommandException("commands.fill.outOfWorld", new Object[0]); + } + } + } + + /** + * Get a list of options for when the user presses the TAB key + */ + public List getTabCompletions(MinecraftServer server, ICommandSender sender, String[] args, @Nullable BlockPos targetPos) + { + if (args.length > 0 && args.length <= 3) + { + return getTabCompletionCoordinate(args, 0, targetPos); + } + else if (args.length > 3 && args.length <= 6) + { + return getTabCompletionCoordinate(args, 3, targetPos); + } + else if (args.length == 7) + { + return getListOfStringsMatchingLastWord(args, Block.REGISTRY.getKeys()); + } + else if (args.length == 9) + { + return getListOfStringsMatchingLastWord(args, new String[] {"replace", "destroy", "keep", "hollow", "outline", "noupdate", "replace_noupdate"}); + } + else + { + return args.length == 10 && ("replace".equalsIgnoreCase(args[8]) || "noupdate".equalsIgnoreCase(args[8])) ? getListOfStringsMatchingLastWord(args, Block.REGISTRY.getKeys()) : Collections.emptyList(); + } + } + + enum FillType { + REPLACE, DESTROY, KEEP, HOLLOW, OUTLINE, NOUPDATE; + } +} diff --git a/carpetmodSrc/carpet/commands/CommandZetBlock.java b/carpetmodSrc/carpet/commands/CommandZetBlock.java index 69a2867d..7faf103f 100644 --- a/carpetmodSrc/carpet/commands/CommandZetBlock.java +++ b/carpetmodSrc/carpet/commands/CommandZetBlock.java @@ -96,6 +96,8 @@ public void execute(MinecraftServer server, ICommandSender sender, String[] args EntityPlayerMP worldEditPlayer = sender instanceof EntityPlayerMP ? (EntityPlayerMP) sender : null; NBTTagCompound worldEditTag = flag ? nbttagcompound : null; + boolean updates = true; + if (args.length >= 6) { if ("destroy".equals(args[5])) @@ -118,6 +120,10 @@ else if ("keep".equals(args[5]) && !world.isAirBlock(blockpos)) { throw new CommandException("commands.setblock.noChange", new Object[0]); } + else if ("noupdate".equals(args[5])) + { + updates = false; + } } WorldEditBridge.recordBlockEdit(worldEditPlayer, world, blockpos, iblockstate, worldEditTag); @@ -129,7 +135,7 @@ else if ("keep".equals(args[5]) && !world.isAirBlock(blockpos)) ((IInventory)tileentity1).clear(); } - if (!world.setBlockState(blockpos, iblockstate, 2)) + if (!world.setBlockState(blockpos, iblockstate, 2 | (updates ? 0 : 128))) { throw new CommandException("commands.setblock.noChange", new Object[0]); } @@ -148,7 +154,10 @@ else if ("keep".equals(args[5]) && !world.isAirBlock(blockpos)) } } - world.notifyNeighborsRespectDebug(blockpos, iblockstate.getBlock(), false); + if (updates) + { + world.notifyNeighborsRespectDebug(blockpos, iblockstate.getBlock(), false); + } sender.setCommandStat(CommandResultStats.Type.AFFECTED_BLOCKS, 1); notifyCommandListener(sender, this, "commands.setblock.success", new Object[0]); } @@ -170,7 +179,7 @@ else if (args.length == 4) } else { - return args.length == 6 ? getListOfStringsMatchingLastWord(args, new String[] {"replace", "destroy", "keep"}) : Collections.emptyList(); + return args.length == 6 ? getListOfStringsMatchingLastWord(args, new String[] {"replace", "destroy", "keep", "noupdate"}) : Collections.emptyList(); } } } diff --git a/patches/net/minecraft/command/CommandFill.java.patch b/patches/net/minecraft/command/CommandFill.java.patch index dcb35dc4..2881f671 100644 --- a/patches/net/minecraft/command/CommandFill.java.patch +++ b/patches/net/minecraft/command/CommandFill.java.patch @@ -49,14 +49,16 @@ } else if ("keep".equals(p_184881_3_[8])) { -@@ -137,6 +152,7 @@ +@@ -137,7 +152,8 @@ { if ("hollow".equals(p_184881_3_[8])) { +- world.func_180501_a(blockpos4, Blocks.field_150350_a.func_176223_P(), 2); + WorldEditBridge.recordBlockEdit(worldEditPlayer, world, blockpos4, Blocks.field_150350_a.func_176223_P(), worldEditTag); - world.func_180501_a(blockpos4, Blocks.field_150350_a.func_176223_P(), 2); ++ world.func_180501_a(blockpos4, Blocks.field_150350_a.func_176223_P(), 2 | (CarpetSettings.fillUpdates?0:128)); // CM list.add(blockpos4); } + @@ -145,6 +161,7 @@ } } From f9d1e9829325a4d8e2e06b788527901d38547301 Mon Sep 17 00:00:00 2001 From: Space Walker <48224626+SpaceWalkerRS@users.noreply.github.com> Date: Tue, 22 Mar 2022 19:28:48 +0100 Subject: [PATCH 40/46] Add integration with the new Redstone Multimeter mod (#169) * update rsmm * rename currentDepth -> currentBlockEventDepth * moved some chest code out of patches * moved code from World into TickTaskExecutor and from WorldServer into MultimeterServerProvider, moved MultimeterServer instance from MinecraftServer into CarpetServer * moved even more code out of patches * tag some og rsmm code with 'legacy' --- carpetmodSrc/carpet/CarpetServer.java | 13 +- carpetmodSrc/carpet/CarpetSettings.java | 11 +- .../carpet/commands/CarpetCommands.java | 5 +- .../rsmm/server/RSMMServer.java | 2 +- .../multimeter/RedstoneMultimeter.java | 15 + .../redstone/multimeter/block/Meterable.java | 17 + .../multimeter/block/MeterableBlock.java | 24 + .../multimeter/block/PowerSource.java | 24 + .../multimeter/command/MeterGroupCommand.java | 494 +++++++++++++++ .../redstone/multimeter/common/DimPos.java | 116 ++++ .../redstone/multimeter/common/TickPhase.java | 113 ++++ .../multimeter/common/TickPhaseTree.java | 180 ++++++ .../redstone/multimeter/common/TickTask.java | 79 +++ .../multimeter/common/meter/Meter.java | 151 +++++ .../multimeter/common/meter/MeterGroup.java | 201 +++++++ .../common/meter/MeterProperties.java | 275 +++++++++ .../common/meter/MeterPropertiesManager.java | 33 + .../common/meter/event/EventType.java | 92 +++ .../common/meter/event/MeterEvent.java | 44 ++ .../multimeter/common/meter/log/EventLog.java | 103 ++++ .../common/meter/log/LogManager.java | 17 + .../common/meter/log/MeterLogs.java | 180 ++++++ .../common/network/AbstractPacketHandler.java | 53 ++ .../common/network/PacketManager.java | 43 ++ .../multimeter/common/network/RSMMPacket.java | 24 + .../network/packets/AddMeterPacket.java | 36 ++ .../packets/ClearMeterGroupPacket.java | 29 + .../network/packets/HandshakePacket.java | 37 ++ .../packets/MeterGroupDefaultPacket.java | 29 + .../packets/MeterGroupRefreshPacket.java | 45 ++ .../packets/MeterGroupSubscriptionPacket.java | 56 ++ .../network/packets/MeterLogsPacket.java | 35 ++ .../network/packets/MeterUpdatePacket.java | 40 ++ .../network/packets/MeterUpdatesPacket.java | 86 +++ .../network/packets/RemoveMeterPacket.java | 35 ++ .../network/packets/ServerTickPacket.java | 35 ++ .../packets/TeleportToMeterPacket.java | 35 ++ .../network/packets/TickPhaseTreePacket.java | 35 ++ .../multimeter/helper/BlockChestHelper.java | 59 ++ .../multimeter/helper/WorldHelper.java | 114 ++++ .../multimeter/interfaces/IBlock.java | 24 + .../registry/SupplierClazzRegistry.java | 52 ++ .../multimeter/server/Multimeter.java | 568 ++++++++++++++++++ .../multimeter/server/MultimeterServer.java | 269 +++++++++ .../server/ServerPacketHandler.java | 62 ++ .../server/meter/ServerMeterGroup.java | 278 +++++++++ .../meter/ServerMeterPropertiesManager.java | 44 ++ .../meter/event/MeterEventPredicate.java | 11 + .../meter/event/MeterEventSupplier.java | 31 + .../server/meter/log/ServerLogManager.java | 90 +++ .../multimeter/server/option/Options.java | 37 ++ .../server/option/OptionsManager.java | 71 +++ .../redstone/multimeter/util/AxisUtils.java | 19 + .../redstone/multimeter/util/ColorUtils.java | 118 ++++ .../multimeter/util/DimensionUtils.java | 40 ++ .../multimeter/util/IdentifierUtils.java | 26 + .../redstone/multimeter/util/ListUtils.java | 29 + .../redstone/multimeter/util/NbtUtils.java | 41 ++ .../redstone/multimeter/util/TextUtils.java | 25 + patches/net/minecraft/block/Block.java.patch | 22 +- .../minecraft/block/BlockButton.java.patch | 31 + .../net/minecraft/block/BlockChest.java.patch | 64 +- .../block/BlockDaylightDetector.java.patch | 31 + .../minecraft/block/BlockDispenser.java.patch | 41 +- .../net/minecraft/block/BlockDoor.java.patch | 65 ++ .../block/BlockEndPortalFrame.java.patch | 24 + .../minecraft/block/BlockFenceGate.java.patch | 36 +- .../minecraft/block/BlockHopper.java.patch | 36 +- .../net/minecraft/block/BlockLever.java.patch | 33 + .../net/minecraft/block/BlockNote.java.patch | 44 +- .../minecraft/block/BlockObserver.java.patch | 30 +- .../block/BlockPistonBase.java.patch | 85 ++- .../block/BlockPressurePlate.java.patch | 33 + .../BlockPressurePlateWeighted.java.patch | 31 + .../block/BlockRailDetector.java.patch | 31 +- .../block/BlockRailPowered.java.patch | 44 +- .../block/BlockRedstoneComparator.java.patch | 44 +- .../block/BlockRedstoneDiode.java.patch | 55 +- .../block/BlockRedstoneLight.java.patch | 33 + .../block/BlockRedstoneOre.java.patch | 24 + .../block/BlockRedstoneRepeater.java.patch | 35 +- .../block/BlockRedstoneTorch.java.patch | 57 +- .../block/BlockRedstoneWire.java.patch | 69 ++- .../minecraft/block/BlockTrapDoor.java.patch | 41 ++ .../minecraft/block/BlockTripWire.java.patch | 24 + .../block/BlockTripWireHook.java.patch | 31 + .../network/NetHandlerPlayServer.java.patch | 44 +- .../server/MinecraftServer.java.patch | 86 ++- .../PlayerInteractionManager.java.patch | 19 +- .../server/management/PlayerList.java.patch | 27 +- .../tileentity/TileEntityChest.java.patch | 27 +- .../TileEntityComparator.java.patch | 22 +- patches/net/minecraft/world/World.java.patch | 117 ++-- .../minecraft/world/WorldServer.java.patch | 232 ++++++- .../minecraft/world/chunk/Chunk.java.patch | 61 +- .../world/end/DragonFightManager.java.patch | 29 +- 96 files changed, 6362 insertions(+), 246 deletions(-) create mode 100644 carpetmodSrc/redstone/multimeter/RedstoneMultimeter.java create mode 100644 carpetmodSrc/redstone/multimeter/block/Meterable.java create mode 100644 carpetmodSrc/redstone/multimeter/block/MeterableBlock.java create mode 100644 carpetmodSrc/redstone/multimeter/block/PowerSource.java create mode 100644 carpetmodSrc/redstone/multimeter/command/MeterGroupCommand.java create mode 100644 carpetmodSrc/redstone/multimeter/common/DimPos.java create mode 100644 carpetmodSrc/redstone/multimeter/common/TickPhase.java create mode 100644 carpetmodSrc/redstone/multimeter/common/TickPhaseTree.java create mode 100644 carpetmodSrc/redstone/multimeter/common/TickTask.java create mode 100644 carpetmodSrc/redstone/multimeter/common/meter/Meter.java create mode 100644 carpetmodSrc/redstone/multimeter/common/meter/MeterGroup.java create mode 100644 carpetmodSrc/redstone/multimeter/common/meter/MeterProperties.java create mode 100644 carpetmodSrc/redstone/multimeter/common/meter/MeterPropertiesManager.java create mode 100644 carpetmodSrc/redstone/multimeter/common/meter/event/EventType.java create mode 100644 carpetmodSrc/redstone/multimeter/common/meter/event/MeterEvent.java create mode 100644 carpetmodSrc/redstone/multimeter/common/meter/log/EventLog.java create mode 100644 carpetmodSrc/redstone/multimeter/common/meter/log/LogManager.java create mode 100644 carpetmodSrc/redstone/multimeter/common/meter/log/MeterLogs.java create mode 100644 carpetmodSrc/redstone/multimeter/common/network/AbstractPacketHandler.java create mode 100644 carpetmodSrc/redstone/multimeter/common/network/PacketManager.java create mode 100644 carpetmodSrc/redstone/multimeter/common/network/RSMMPacket.java create mode 100644 carpetmodSrc/redstone/multimeter/common/network/packets/AddMeterPacket.java create mode 100644 carpetmodSrc/redstone/multimeter/common/network/packets/ClearMeterGroupPacket.java create mode 100644 carpetmodSrc/redstone/multimeter/common/network/packets/HandshakePacket.java create mode 100644 carpetmodSrc/redstone/multimeter/common/network/packets/MeterGroupDefaultPacket.java create mode 100644 carpetmodSrc/redstone/multimeter/common/network/packets/MeterGroupRefreshPacket.java create mode 100644 carpetmodSrc/redstone/multimeter/common/network/packets/MeterGroupSubscriptionPacket.java create mode 100644 carpetmodSrc/redstone/multimeter/common/network/packets/MeterLogsPacket.java create mode 100644 carpetmodSrc/redstone/multimeter/common/network/packets/MeterUpdatePacket.java create mode 100644 carpetmodSrc/redstone/multimeter/common/network/packets/MeterUpdatesPacket.java create mode 100644 carpetmodSrc/redstone/multimeter/common/network/packets/RemoveMeterPacket.java create mode 100644 carpetmodSrc/redstone/multimeter/common/network/packets/ServerTickPacket.java create mode 100644 carpetmodSrc/redstone/multimeter/common/network/packets/TeleportToMeterPacket.java create mode 100644 carpetmodSrc/redstone/multimeter/common/network/packets/TickPhaseTreePacket.java create mode 100644 carpetmodSrc/redstone/multimeter/helper/BlockChestHelper.java create mode 100644 carpetmodSrc/redstone/multimeter/helper/WorldHelper.java create mode 100644 carpetmodSrc/redstone/multimeter/interfaces/IBlock.java create mode 100644 carpetmodSrc/redstone/multimeter/registry/SupplierClazzRegistry.java create mode 100644 carpetmodSrc/redstone/multimeter/server/Multimeter.java create mode 100644 carpetmodSrc/redstone/multimeter/server/MultimeterServer.java create mode 100644 carpetmodSrc/redstone/multimeter/server/ServerPacketHandler.java create mode 100644 carpetmodSrc/redstone/multimeter/server/meter/ServerMeterGroup.java create mode 100644 carpetmodSrc/redstone/multimeter/server/meter/ServerMeterPropertiesManager.java create mode 100644 carpetmodSrc/redstone/multimeter/server/meter/event/MeterEventPredicate.java create mode 100644 carpetmodSrc/redstone/multimeter/server/meter/event/MeterEventSupplier.java create mode 100644 carpetmodSrc/redstone/multimeter/server/meter/log/ServerLogManager.java create mode 100644 carpetmodSrc/redstone/multimeter/server/option/Options.java create mode 100644 carpetmodSrc/redstone/multimeter/server/option/OptionsManager.java create mode 100644 carpetmodSrc/redstone/multimeter/util/AxisUtils.java create mode 100644 carpetmodSrc/redstone/multimeter/util/ColorUtils.java create mode 100644 carpetmodSrc/redstone/multimeter/util/DimensionUtils.java create mode 100644 carpetmodSrc/redstone/multimeter/util/IdentifierUtils.java create mode 100644 carpetmodSrc/redstone/multimeter/util/ListUtils.java create mode 100644 carpetmodSrc/redstone/multimeter/util/NbtUtils.java create mode 100644 carpetmodSrc/redstone/multimeter/util/TextUtils.java create mode 100644 patches/net/minecraft/block/BlockButton.java.patch create mode 100644 patches/net/minecraft/block/BlockDaylightDetector.java.patch create mode 100644 patches/net/minecraft/block/BlockDoor.java.patch create mode 100644 patches/net/minecraft/block/BlockEndPortalFrame.java.patch create mode 100644 patches/net/minecraft/block/BlockLever.java.patch create mode 100644 patches/net/minecraft/block/BlockPressurePlate.java.patch create mode 100644 patches/net/minecraft/block/BlockPressurePlateWeighted.java.patch create mode 100644 patches/net/minecraft/block/BlockRedstoneLight.java.patch create mode 100644 patches/net/minecraft/block/BlockRedstoneOre.java.patch create mode 100644 patches/net/minecraft/block/BlockTrapDoor.java.patch create mode 100644 patches/net/minecraft/block/BlockTripWire.java.patch create mode 100644 patches/net/minecraft/block/BlockTripWireHook.java.patch diff --git a/carpetmodSrc/carpet/CarpetServer.java b/carpetmodSrc/carpet/CarpetServer.java index dd2e87ee..898cf49d 100644 --- a/carpetmodSrc/carpet/CarpetServer.java +++ b/carpetmodSrc/carpet/CarpetServer.java @@ -23,6 +23,7 @@ import net.minecraft.server.MinecraftServer; import net.minecraft.util.Tuple; import net.minecraft.world.WorldServer; +import redstone.multimeter.server.MultimeterServer; public class CarpetServer // static for now - easier to handle all around the code, its one anyways { @@ -32,8 +33,9 @@ public class CarpetServer // static for now - easier to handle all around the co public static MinecraftServer minecraft_server; public static PluginChannelManager pluginChannels; - public static RSMMServer rsmmServer; - public static ToggleableChannelHandler rsmmChannel; + public static RSMMServer legacyRsmmServer; + public static MultimeterServer rsmmServer; + public static ToggleableChannelHandler legacyRsmmChannel; public static ToggleableChannelHandler wecuiChannel; public static boolean playerInventoryStacking = false; public static int limitITTCounter; @@ -49,8 +51,9 @@ public static void init(MinecraftServer server) //aka constructor of this static CCServer = new CarpetClientServer(server); pluginChannels.register(CCServer); - rsmmServer = new RSMMServer(server); - rsmmChannel = new ToggleableChannelHandler(pluginChannels, rsmmServer.createChannelHandler(), false); + rsmmServer = new MultimeterServer(server); + legacyRsmmServer = new RSMMServer(server); + legacyRsmmChannel = new ToggleableChannelHandler(pluginChannels, legacyRsmmServer.createChannelHandler(), false); wecuiChannel = new ToggleableChannelHandler(pluginChannels, WorldEditBridge.createChannelHandler(), false); } public static void onServerLoaded(MinecraftServer server) @@ -111,7 +114,7 @@ public static void onWorldsSaved(MinecraftServer server) public static void tick(MinecraftServer server) { TickSpeed.tick(server); - if (CarpetSettings.redstoneMultimeter) + if (CarpetSettings.redstoneMultimeterLegacy) { TickStartEventDispatcher.dispatchEvent(server.getTickCounter()); } diff --git a/carpetmodSrc/carpet/CarpetSettings.java b/carpetmodSrc/carpet/CarpetSettings.java index 88d2533e..e3fcd4ed 100644 --- a/carpetmodSrc/carpet/CarpetSettings.java +++ b/carpetmodSrc/carpet/CarpetSettings.java @@ -299,13 +299,18 @@ public static enum HopperCounters @SurvivalDefault public static boolean cactusCounter = false; - @Rule(desc = "Enables integration with redstone multimeter mod", category = {CREATIVE, SURVIVAL}, validator = "validateRedstoneMultimeter", extra = { + @Rule(desc = "Enables integration with NarcolepticFrog's Redstone Multimeter mod", category = {CREATIVE, SURVIVAL}, validator = "validateRedstoneMultimeterLegacy", extra = { "Required clients with RSMM Mod by Narcoleptic Frog. Enables multiplayer experience with RSMM Mod" }) + public static boolean redstoneMultimeterLegacy = false; + + @Rule(desc = "Enables integration with the new Redstone Multimeter mod", category = {CREATIVE, SURVIVAL, COMMANDS}, extra = { + "To use, the new Redstone Multimeter mod must be installed client-side as well" + }) public static boolean redstoneMultimeter = false; - private static boolean validateRedstoneMultimeter(boolean value) { - CarpetServer.rsmmChannel.setEnabled(value); + private static boolean validateRedstoneMultimeterLegacy(boolean value) { + CarpetServer.legacyRsmmChannel.setEnabled(value); return true; } diff --git a/carpetmodSrc/carpet/commands/CarpetCommands.java b/carpetmodSrc/carpet/commands/CarpetCommands.java index f2c1f3aa..142de5dc 100644 --- a/carpetmodSrc/carpet/commands/CarpetCommands.java +++ b/carpetmodSrc/carpet/commands/CarpetCommands.java @@ -3,6 +3,7 @@ import carpet.CarpetServer; import narcolepticfrog.rsmm.MeterCommand; import net.minecraft.command.CommandHandler; +import redstone.multimeter.command.MeterGroupCommand; public class CarpetCommands { public static void register(CommandHandler handler) { @@ -51,7 +52,9 @@ public static void register(CommandHandler handler) { handler.registerCommand(new CommandZetBlock()); // ----- RSMM Start ----- // - handler.registerCommand(new MeterCommand(CarpetServer.rsmmServer)); + handler.registerCommand(new MeterCommand(CarpetServer.legacyRsmmServer)); // ----- RSMM End ----- // + + handler.registerCommand(new MeterGroupCommand(CarpetServer.rsmmServer)); } } diff --git a/carpetmodSrc/narcolepticfrog/rsmm/server/RSMMServer.java b/carpetmodSrc/narcolepticfrog/rsmm/server/RSMMServer.java index e015ef21..b463ee7f 100644 --- a/carpetmodSrc/narcolepticfrog/rsmm/server/RSMMServer.java +++ b/carpetmodSrc/narcolepticfrog/rsmm/server/RSMMServer.java @@ -218,7 +218,7 @@ public void onPlayerDisconnect(EntityPlayerMP player) { @Override public void onCustomPayload(EntityPlayerMP sender, String channel, PacketBuffer data) { - if (CarpetSettings.redstoneMultimeter && "RSMM".equals(channel)) { + if (CarpetSettings.redstoneMultimeterLegacy && "RSMM".equals(channel)) { RSMMSPacket packet = RSMMSPacket.fromBuffer(data); if (packet == null) return; packet.process(getOrCreateMeterGroup(sender)); diff --git a/carpetmodSrc/redstone/multimeter/RedstoneMultimeter.java b/carpetmodSrc/redstone/multimeter/RedstoneMultimeter.java new file mode 100644 index 00000000..79e2f392 --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/RedstoneMultimeter.java @@ -0,0 +1,15 @@ +package redstone.multimeter; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class RedstoneMultimeter { + + public static final String MOD_NAME = "Redstone Multimeter"; + public static final String MOD_VERSION = "1.6.0"; + public static final String NAMESPACE = "redstone_multimeter"; + public static final String MINECRAFT_NAMESPACE = "minecraft"; + public static final String CONFIG_PATH = "config/" + NAMESPACE; + public static final Logger LOGGER = LogManager.getLogger(MOD_NAME); + +} diff --git a/carpetmodSrc/redstone/multimeter/block/Meterable.java b/carpetmodSrc/redstone/multimeter/block/Meterable.java new file mode 100644 index 00000000..accfee2d --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/block/Meterable.java @@ -0,0 +1,17 @@ +package redstone.multimeter.block; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import redstone.multimeter.interfaces.IBlock; + +public interface Meterable extends IBlock { + + @Override + default boolean isMeterable() { + return true; + } + + public boolean isActive(World world, BlockPos pos, IBlockState state); + +} diff --git a/carpetmodSrc/redstone/multimeter/block/MeterableBlock.java b/carpetmodSrc/redstone/multimeter/block/MeterableBlock.java new file mode 100644 index 00000000..bb33ff89 --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/block/MeterableBlock.java @@ -0,0 +1,24 @@ +package redstone.multimeter.block; + +import carpet.CarpetSettings; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import redstone.multimeter.helper.WorldHelper; + +public interface MeterableBlock extends Meterable { + + default void logPowered(World world, BlockPos pos, boolean powered) { + if (CarpetSettings.redstoneMultimeter && !world.isRemote) { + WorldHelper.getMultimeter().logPowered(world, pos, powered); + } + } + + default void logPowered(World world, BlockPos pos, IBlockState state) { + if (CarpetSettings.redstoneMultimeter && !world.isRemote) { + WorldHelper.getMultimeter().logPowered(world, pos, state); + } + } +} diff --git a/carpetmodSrc/redstone/multimeter/block/PowerSource.java b/carpetmodSrc/redstone/multimeter/block/PowerSource.java new file mode 100644 index 00000000..af06f826 --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/block/PowerSource.java @@ -0,0 +1,24 @@ +package redstone.multimeter.block; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import redstone.multimeter.interfaces.IBlock; + +public interface PowerSource extends IBlock { + + public static final int MIN_POWER = 0; + public static final int MAX_POWER = 15; + + @Override + default boolean isPowerSource() { + return true; + } + + default boolean logPowerChangeOnStateChange() { + return true; + } + + public int getPowerLevel(World world, BlockPos pos, IBlockState state); + +} diff --git a/carpetmodSrc/redstone/multimeter/command/MeterGroupCommand.java b/carpetmodSrc/redstone/multimeter/command/MeterGroupCommand.java new file mode 100644 index 00000000..b55256ef --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/command/MeterGroupCommand.java @@ -0,0 +1,494 @@ +package redstone.multimeter.command; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.UUID; + +import net.minecraft.command.CommandBase; +import net.minecraft.command.CommandException; +import net.minecraft.command.CommandNotFoundException; +import net.minecraft.command.ICommandSender; +import net.minecraft.command.WrongUsageException; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.server.MinecraftServer; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.text.TextComponentString; + +import redstone.multimeter.RedstoneMultimeter; +import redstone.multimeter.common.meter.MeterGroup; +import redstone.multimeter.server.Multimeter; +import redstone.multimeter.server.MultimeterServer; +import redstone.multimeter.server.meter.ServerMeterGroup; + +public class MeterGroupCommand extends CommandBase { + + private static final String COMMAND_NAME = "metergroup"; + + private static final String USAGE_LIST = singleUsage("list"); + + private static final String USAGE_SUBSCRIBE_DEFAULT = singleUsage("subscribe"); + private static final String USAGE_SUBSCRIBE_NAME = singleUsage("subscribe "); + private static final String USAGE_SUBSCRIBE = buildUsage(USAGE_SUBSCRIBE_DEFAULT, USAGE_SUBSCRIBE_NAME); + + private static final String USAGE_UNSUBSCRIBE = singleUsage("unsubscribe"); + + private static final String USAGE_PRIVATE_QUERY = singleUsage("private"); + private static final String USAGE_PRIVATE_SET = singleUsage("private "); + private static final String USAGE_PRIVATE = buildUsage(USAGE_PRIVATE_QUERY, USAGE_PRIVATE_SET); + + private static final String USAGE_MEMBERS_LIST = singleUsage("members list"); + private static final String USAGE_MEMBERS_ADD = singleUsage("members add "); + private static final String USAGE_MEMBERS_REMOVE = singleUsage("members remove "); + private static final String USAGE_MEMBERS_CLEAR = singleUsage("members clear"); + private static final String USAGE_MEMBERS = buildUsage(USAGE_MEMBERS_LIST, USAGE_MEMBERS_ADD, USAGE_MEMBERS_REMOVE, USAGE_MEMBERS_CLEAR); + + private static final String USAGE_CLEAR = singleUsage("clear"); + + private static final String TOTAL_USAGE_MEMBER = buildUsage(USAGE_LIST, USAGE_SUBSCRIBE, USAGE_UNSUBSCRIBE, USAGE_CLEAR); + private static final String TOTAL_USAGE_OWNER = buildUsage(USAGE_LIST, USAGE_SUBSCRIBE, USAGE_UNSUBSCRIBE, USAGE_PRIVATE, USAGE_MEMBERS, USAGE_CLEAR); + + private static String singleUsage(String usage) { + return String.format("/%s %s", COMMAND_NAME, usage); + } + + private static String buildUsage(String... usages) { + return String.join(" OR ", usages); + } + + private final MultimeterServer server; + private final Multimeter multimeter; + + public MeterGroupCommand(MultimeterServer server) { + this.server = server; + this.multimeter = this.server.getMultimeter(); + } + + @Override + public String getName() { + return COMMAND_NAME; + } + + @Override + public String getUsage(ICommandSender sender) { + try { + if (isOwnerOfSubscription(sender)) { + return TOTAL_USAGE_OWNER; + } + } catch (CommandException e) { + + } + + return TOTAL_USAGE_MEMBER; + } + + @Override + public List getTabCompletions(MinecraftServer minecraftServer, ICommandSender sender, String[] args, BlockPos pos) { + boolean isOwner = false; + + try { + isOwner = isOwnerOfSubscription(sender); + } catch (CommandException e) { + + } + + switch (args.length) { + case 1: + if (isOwner) { + return getListOfStringsMatchingLastWord(args, "clear", "subscribe", "unsubscribe", "private", "members", "list"); + } else { + return getListOfStringsMatchingLastWord(args, "clear", "subscribe", "unsubscribe", "list"); + } + case 2: + switch (args[0]) { + case "subscribe": + try { + return getListOfStringsMatchingLastWord(args, listMeterGroups(sender)); + } catch (CommandException e) { + + } + + break; + case "private": + if (isOwner) { + return getListOfStringsMatchingLastWord(args, "true", "false"); + } + + break; + case "members": + if (isOwner) { + return getListOfStringsMatchingLastWord(args, "clear", "add", "remove", "list"); + } + + break; + } + + break; + case 3: + if (isOwner && args[0].equals("members")) { + switch (args[1]) { + case "add": + return getListOfStringsMatchingLastWord(args, minecraftServer.getOnlinePlayerNames()); + case "remove": + try { + return getListOfStringsMatchingLastWord(args, listMembers(sender).keySet()); + } catch (CommandException e) { + + } + + break; + } + } + + break; + } + + return Collections.emptyList(); + } + + @Override + public void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException { + if (!isMultimeterClient(sender)) { + throw new CommandNotFoundException(); + } + + if (args.length > 0) { + switch (args[0]) { + case "list": + if (args.length == 1) { + list(sender); + return; + } + + throw new WrongUsageException(USAGE_LIST); + case "subscribe": + if (args.length == 1) { + subscribe(sender, null); + return; + } + + String name = ""; + + for (int index = 1; index < args.length; index++) { + name += args[index] + " "; + } + + subscribe(sender, name); + return; + case "unsubscribe": + if (args.length == 1) { + unsubscribe(sender); + return; + } + + throw new WrongUsageException(USAGE_UNSUBSCRIBE); + case "private": + if (!isOwnerOfSubscription(sender)) { + break; + } + + switch (args.length) { + case 1: + queryPrivate(sender); + return; + case 2: + switch (args[1]) { + case "true": + setPrivate(sender, true); + return; + case "false": + setPrivate(sender, false); + return; + } + + throw new WrongUsageException(USAGE_PRIVATE_SET); + } + + throw new WrongUsageException(USAGE_PRIVATE); + case "members": + if (!isOwnerOfSubscription(sender)) { + break; + } + + if (args.length > 1) { + switch (args[1]) { + case "list": + if (args.length == 2) { + membersList(sender); + return; + } + + throw new WrongUsageException(USAGE_MEMBERS_LIST); + case "add": + if (args.length == 3) { + membersAdd(sender, getPlayers(server, sender, args[2])); + return; + } + + throw new WrongUsageException(USAGE_MEMBERS_ADD); + case "remove": + if (args.length == 3) { + membersRemove(sender, args[2]); + return; + } + + throw new WrongUsageException(USAGE_MEMBERS_REMOVE); + case "clear": + if (args.length == 2) { + membersClear(sender); + return; + } + + throw new WrongUsageException(USAGE_MEMBERS_CLEAR); + } + } + + throw new WrongUsageException(USAGE_MEMBERS); + case "clear": + if (args.length == 1) { + clear(sender); + return; + } + + throw new WrongUsageException(USAGE_CLEAR); + } + } + + throw new WrongUsageException(getUsage(sender)); + } + + private boolean isMultimeterClient(ICommandSender sender) throws CommandException { + return execute(sender, player -> multimeter.getMultimeterServer().isMultimeterClient(player)); + } + + private boolean isOwnerOfSubscription(ICommandSender sender) throws CommandException { + return execute(sender, player -> multimeter.isOwnerOfSubscription(player)); + } + + private Collection listMeterGroups(ICommandSender sender) throws CommandException { + List names = new ArrayList<>(); + + command(sender, player -> { + for (ServerMeterGroup meterGroup : multimeter.getMeterGroups()) { + if (!meterGroup.isPrivate() || meterGroup.hasMember(player) || meterGroup.isOwnedBy(player)) { + names.add(meterGroup.getName()); + } + } + }); + + return names; + } + + private Map listMembers(ICommandSender sender) throws CommandException { + Map names = new HashMap<>(); + + command(sender, player -> { + ServerMeterGroup meterGroup = multimeter.getSubscription(player); + + if (meterGroup != null && meterGroup.isOwnedBy(player)) { + for (UUID playerUUID : meterGroup.getMembers()) { + String playerName = multimeter.getMultimeterServer().getPlayerName(playerUUID); + + if (playerName != null) { + names.put(playerName, playerUUID); + } + } + } + }); + + return names; + } + + private void list(ICommandSender sender) throws CommandException { + Collection names = listMeterGroups(sender); + + if (names.isEmpty()) { + sender.sendMessage(new TextComponentString("There are no meter groups yet!")); + } else { + String message = "Meter groups:\n " + String.join("\n ", names); + sender.sendMessage(new TextComponentString(message)); + } + } + + private void subscribe(ICommandSender sender, String name) throws CommandException { + command(sender, player -> { + if (name == null) { + multimeter.subscribeToDefaultMeterGroup(player); + sender.sendMessage(new TextComponentString("Subscribed to default meter group")); + } else if (multimeter.hasMeterGroup(name)) { + ServerMeterGroup meterGroup = multimeter.getMeterGroup(name); + + if (!meterGroup.isPrivate() || meterGroup.hasMember(player) || meterGroup.isOwnedBy(player)) { + multimeter.subscribeToMeterGroup(meterGroup, player); + sender.sendMessage(new TextComponentString(String.format("Subscribed to meter group \'%s\'", name))); + } else { + sender.sendMessage(new TextComponentString("That meter group is private!")); + } + } else { + if (MeterGroup.isValidName(name)) { + multimeter.createMeterGroup(player, name); + sender.sendMessage(new TextComponentString(String.format("Created meter group \'%s\'", name))); + } else { + sender.sendMessage(new TextComponentString(String.format("\'%s\' is not a valid meter group name!", name))); + } + } + }); + } + + private void unsubscribe(ICommandSender sender) throws CommandException { + command(sender, (meterGroup, player) -> { + multimeter.unsubscribeFromMeterGroup(meterGroup, player); + sender.sendMessage(new TextComponentString(String.format("Unsubscribed from meter group \'%s\'", meterGroup.getName()))); + }); + } + + private void queryPrivate(ICommandSender sender) throws CommandException { + command(sender, (meterGroup, player) -> { + String status = meterGroup.isPrivate() ? "private" : "public"; + sender.sendMessage(new TextComponentString(String.format("Meter group \'%s\' is %s", meterGroup.getName(), status))); + }); + } + + private void setPrivate(ICommandSender sender, boolean isPrivate) throws CommandException { + command(sender, (meterGroup, player) -> { + if (meterGroup.isOwnedBy(player)) { + meterGroup.setPrivate(isPrivate); + sender.sendMessage(new TextComponentString(String.format("Meter group \'%s\' is now %s", meterGroup.getName(), (isPrivate ? "private" : "public")))); + } else { + sender.sendMessage(new TextComponentString("Only the owner of a meter group can change its privacy!")); + } + }); + } + + private void membersList(ICommandSender sender) throws CommandException { + Map members = listMembers(sender); + + commandMembers(sender, (meterGroup, owner) -> { + if (members.isEmpty()) { + sender.sendMessage(new TextComponentString(String.format("Meter group \'%s\' has no members yet!", meterGroup.getName()))); + } else { + String message = String.format("Members of meter group \'%s\':\n ", meterGroup.getName()) + String.join("\n ", members.keySet()); + sender.sendMessage(new TextComponentString(message)); + } + }); + } + + private void membersAdd(ICommandSender sender, Collection players) throws CommandException { + commandMembers(sender, (meterGroup, owner) -> { + for (EntityPlayerMP player : players) { + if (player == owner) { + sender.sendMessage(new TextComponentString("You cannot add yourself as a member!")); + } else if (meterGroup.hasMember(player)) { + sender.sendMessage(new TextComponentString(String.format("Player \'%s\' is already a member of meter group \'%s\'!", player.getName(), meterGroup.getName()))); + } else if (!multimeter.getMultimeterServer().isMultimeterClient(player)) { + sender.sendMessage(new TextComponentString(String.format("You cannot add player \'%s\' as a member; they do not have %s installed!", player.getName(), RedstoneMultimeter.MOD_NAME))); + } else { + multimeter.addMemberToMeterGroup(meterGroup, player.getUniqueID()); + sender.sendMessage(new TextComponentString(String.format("Player \'%s\' is now a member of meter group \'%s\'", player.getName(), meterGroup.getName()))); + } + } + }); + } + + private void membersRemove(ICommandSender sender, String playerName) throws CommandException { + commandMembers(sender, (meterGroup, owner) -> { + Entry member = findMember(listMembers(sender), playerName); + + if (member == null) { + EntityPlayerMP player = multimeter.getMultimeterServer().getPlayer(playerName); + + if (player == owner) { + sender.sendMessage(new TextComponentString("You cannot remove yourself as a member!")); + } else { + sender.sendMessage(new TextComponentString(String.format("Meter group \'%s\' has no member with the name \'%s\'!", meterGroup.getName(), playerName))); + } + } else { + multimeter.removeMemberFromMeterGroup(meterGroup, member.getValue()); + sender.sendMessage(new TextComponentString(String.format("Player \'%s\' is no longer a member of meter group \'%s\'", member.getKey(), meterGroup.getName()))); + } + }); + } + + private Entry findMember(Map members, String playerName) { + String key = playerName.toLowerCase(); + + for (Entry member : members.entrySet()) { + if (member.getKey().toLowerCase().equals(key)) { + return member; + } + } + + return null; + } + + private void membersClear(ICommandSender sender) throws CommandException { + commandMembers(sender, (meterGroup, owner) -> { + multimeter.clearMembersOfMeterGroup(meterGroup); + sender.sendMessage(new TextComponentString(String.format("Removed all members from meter group \'%s\'", meterGroup.getName()))); + }); + } + + private void commandMembers(ICommandSender sender, MeterGroupCommandExecutor command) throws CommandException { + command(sender, (meterGroup, player) -> { + if (meterGroup.isOwnedBy(player)) { + command.execute(meterGroup, player); + + if (!meterGroup.isPrivate()) { + sender.sendMessage(new TextComponentString("NOTE: this meter group is public; adding/removing members will not have any effect until you make it private!")); + } + } + }); + } + + private void clear(ICommandSender sender) throws CommandException { + command(sender, (meterGroup, player) -> { + multimeter.clearMeterGroup(meterGroup); + sender.sendMessage(new TextComponentString(String.format("Removed all meters in meter group \'%s\'", meterGroup.getName()))); + }); + } + + private void command(ICommandSender sender, MeterGroupCommandExecutor command) throws CommandException { + command(sender, player -> { + ServerMeterGroup meterGroup = multimeter.getSubscription(player); + + if (meterGroup == null) { + sender.sendMessage(new TextComponentString("Please subscribe to a meter group first!")); + } else { + command.execute(meterGroup, player); + } + }); + } + + private void command(ICommandSender sender, MultimeterCommandExecutor command) throws CommandException { + execute(sender, player -> { command.execute(player); return true; }); + } + + private boolean execute(ICommandSender sender, CommandExecutor command) throws CommandException { + return command.execute(getCommandSenderAsPlayer(sender)); + } + + @FunctionalInterface + private interface MultimeterCommandExecutor { + + public void execute(EntityPlayerMP player) throws CommandException; + + } + + @FunctionalInterface + private interface MeterGroupCommandExecutor { + + public void execute(ServerMeterGroup meterGroup, EntityPlayerMP player) throws CommandException; + + } + + @FunctionalInterface + private interface CommandExecutor { + + public boolean execute(EntityPlayerMP player) throws CommandException; + + } +} diff --git a/carpetmodSrc/redstone/multimeter/common/DimPos.java b/carpetmodSrc/redstone/multimeter/common/DimPos.java new file mode 100644 index 00000000..97cbfe2f --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/common/DimPos.java @@ -0,0 +1,116 @@ +package redstone.multimeter.common; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumFacing.Axis; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import redstone.multimeter.util.AxisUtils; +import redstone.multimeter.util.DimensionUtils; +import redstone.multimeter.util.NbtUtils; + +public class DimPos { + + private final ResourceLocation dimensionId; + private final BlockPos blockPos; + + public DimPos(ResourceLocation dimensionId, BlockPos blockPos) { + this.dimensionId = dimensionId; + this.blockPos = blockPos.toImmutable(); + } + + public DimPos(ResourceLocation dimensionId, int x, int y, int z) { + this(dimensionId, new BlockPos(x, y, z)); + } + + public DimPos(World world, BlockPos pos) { + this(DimensionUtils.getId(world.provider.getDimensionType()), pos); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof DimPos) { + DimPos pos = (DimPos)obj; + return pos.dimensionId.equals(dimensionId) && pos.blockPos.equals(blockPos); + } + + return false; + } + + @Override + public int hashCode() { + return blockPos.hashCode() + 31 * dimensionId.hashCode(); + } + + @Override + public String toString() { + return String.format("%s[%d, %d, %d]", dimensionId.toString(), blockPos.getX(), blockPos.getY(), blockPos.getZ()); + } + + public ResourceLocation getDimensionId() { + return dimensionId; + } + + public boolean isOf(World world) { + return DimensionUtils.getId(world.provider.getDimensionType()).equals(dimensionId); + } + + public DimPos offset(ResourceLocation dimensionId) { + return new DimPos(dimensionId, blockPos); + } + + public BlockPos getBlockPos() { + return blockPos; + } + + public DimPos offset(EnumFacing dir) { + return offset(dir, 1); + } + + public DimPos offset(EnumFacing dir, int distance) { + return new DimPos(dimensionId, blockPos.offset(dir, distance)); + } + + public DimPos offset(Axis axis) { + return offset(axis, 1); + } + + public DimPos offset(Axis axis, int distance) { + int dx = AxisUtils.choose(axis, distance, 0, 0); + int dy = AxisUtils.choose(axis, 0, distance, 0); + int dz = AxisUtils.choose(axis, 0, 0, distance); + + return offset(dx, dy, dz); + } + + public DimPos offset(int dx, int dy, int dz) { + return new DimPos(dimensionId, blockPos.add(dx, dy, dz)); + } + + public NBTTagCompound toNbt() { + NBTTagCompound nbt = new NBTTagCompound(); + + // The key is "world id" to match RSMM for 1.16+ + // Keeping this key consistent between versions + // allows clients and servers of different versions + // to communicate effectively through the use of + // mods like ViaVersion or multiconnect + nbt.setTag("world id", NbtUtils.identifierToNbt(dimensionId)); + nbt.setInteger("x", blockPos.getX()); + nbt.setInteger("y", blockPos.getY()); + nbt.setInteger("z", blockPos.getZ()); + + return nbt; + } + + public static DimPos fromNbt(NBTTagCompound nbt) { + ResourceLocation dimensionId = NbtUtils.nbtToIdentifier(nbt.getCompoundTag("world id")); + int x = nbt.getInteger("x"); + int y = nbt.getInteger("y"); + int z = nbt.getInteger("z"); + + return new DimPos(dimensionId, x, y, z); + } +} diff --git a/carpetmodSrc/redstone/multimeter/common/TickPhase.java b/carpetmodSrc/redstone/multimeter/common/TickPhase.java new file mode 100644 index 00000000..128e6f9a --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/common/TickPhase.java @@ -0,0 +1,113 @@ +package redstone.multimeter.common; + +import java.util.Arrays; + +import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTTagByteArray; + +import redstone.multimeter.util.NbtUtils; + +public class TickPhase { + + public static final TickPhase UNKNOWN = new TickPhase(TickTask.UNKNOWN); + + private final TickTask[] tasks; + + public TickPhase(TickTask... tasks) { + this.tasks = tasks; + } + + @Override + public boolean equals(Object obj) { + if (obj == null || !(obj instanceof TickPhase)) { + return false; + } + + return Arrays.equals(tasks, ((TickPhase)obj).tasks); + } + + @Override + public String toString() { + String string = tasks[0].getName(); + + for (int index = 1; index < tasks.length; index++) { + string += " > " + tasks[index].getName(); + } + + return string; + } + + public TickPhase startTask(TickTask task) { + if (this == UNKNOWN || tasks.length == 0) { + return new TickPhase(task); + } + + TickTask[] array = new TickTask[tasks.length + 1]; + + for (int index = 0; index < tasks.length; index++) { + array[index] = tasks[index]; + } + array[tasks.length] = task; + + return new TickPhase(array); + } + + public TickPhase endTask() { + if (this == UNKNOWN || tasks.length == 1) { + return UNKNOWN; + } + + TickTask[] array = new TickTask[tasks.length - 1]; + + for (int index = 0; index < array.length; index++) { + array[index] = tasks[index]; + } + + return new TickPhase(array); + } + + public TickPhase swapTask(TickTask task) { + if (this == UNKNOWN || tasks.length == 1) { + return new TickPhase(new TickTask[] { task }); + } + + TickTask[] array = new TickTask[tasks.length]; + + for (int index = 0; index < tasks.length; index++) { + array[index] = tasks[index]; + } + array[array.length - 1] = task; + + return new TickPhase(array); + } + + public NBTBase toNbt() { + if (this == UNKNOWN) { + return NbtUtils.NULL; + } + + byte[] array = new byte[tasks.length]; + + for (int index = 0; index < array.length; index++) { + array[index] = (byte)tasks[index].getIndex(); + } + + return new NBTTagByteArray(array); + } + + public static TickPhase fromNbt(NBTBase nbt) { + if (nbt.getId() != NbtUtils.TYPE_BYTE_ARRAY) { + return UNKNOWN; + } + + NBTTagByteArray nbtArray = (NBTTagByteArray)nbt; + byte[] array = nbtArray.getByteArray(); + TickTask[] tasks = new TickTask[array.length]; + + for (int index = 0; index < tasks.length; index++) { + tasks[index] = TickTask.fromIndex(array[index]); + } + + return new TickPhase(tasks); + } +} diff --git a/carpetmodSrc/redstone/multimeter/common/TickPhaseTree.java b/carpetmodSrc/redstone/multimeter/common/TickPhaseTree.java new file mode 100644 index 00000000..ed1f9581 --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/common/TickPhaseTree.java @@ -0,0 +1,180 @@ +package redstone.multimeter.common; + +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.nbt.NBTTagByteArray; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.nbt.NBTTagString; + +import redstone.multimeter.RedstoneMultimeter; +import redstone.multimeter.util.NbtUtils; + +public class TickPhaseTree { + + public final TickTaskNode root; + + private TickTaskNode current; + private boolean building; + private boolean complete; + + public TickPhaseTree() { + this.root = new TickTaskNode(null, TickTask.UNKNOWN); + + this.current = root; + this.building = false; + this.complete = false; + } + + public boolean isComplete() { + return complete; + } + + public boolean isBuilding() { + return building; + } + + public void start() { + if (building) { + RedstoneMultimeter.LOGGER.warn("Cannot start building tick phase tree: already building!"); + } else { + root.children.clear(); + current = root; + building = true; + complete = false; + } + } + + public void end() { + if (building) { + building = false; + complete = true; + } else { + RedstoneMultimeter.LOGGER.warn("Cannot complete tick phase tree: not building!"); + } + } + + public void startTask(TickTask task, String... args) { + if (building) { + current = new TickTaskNode(current, task, args); + current.parent.children.add(current); + } + } + + public void endTask() { + if (building) { + current = current.parent; + + if (current == null) { + current = root; // we should never get here + } + } + } + + public void swapTask(TickTask task, String... args) { + if (building) { + endTask(); + startTask(task, args); + } + } + + public NBTTagCompound toNbt() { + NBTTagList tasks = new NBTTagList(); + NBTTagList args = new NBTTagList(); + + addNode(tasks, args, root, 0); + + NBTTagCompound nbt = new NBTTagCompound(); + nbt.setTag("tasks", tasks); + nbt.setTag("args", args); + + return nbt; + } + + private void addNode(NBTTagList tasks, NBTTagList args, TickTaskNode node, int depth) { + if (depth > 0) { // depth 0 is root + byte[] array = new byte[3]; + array[0] = (byte)depth; + array[1] = (byte)node.task.getIndex(); + array[2] = (byte)node.args.length; + NBTTagByteArray taskNbt = new NBTTagByteArray(array); + + tasks.appendTag(taskNbt); + + for (int index = 0; index < node.args.length; index++) { + String arg = node.args[index]; + NBTTagString argNbt = new NBTTagString(arg); + + args.appendTag(argNbt); + } + } + + depth++; + + for (int index = 0; index < node.children.size(); index++) { + addNode(tasks, args, node.children.get(index), depth); + } + } + + public void fromNbt(NBTTagCompound nbt) { + NBTTagList tasks = nbt.getTagList("tasks", NbtUtils.TYPE_BYTE_ARRAY); + NBTTagList args = nbt.getTagList("args", NbtUtils.TYPE_STRING); + + if (!tasks.isEmpty()) { + start(); + addNode(tasks, args, 0, 0, 0); + end(); + } + } + + private void addNode(NBTTagList tasks, NBTTagList args, int taskIndex, int argIndex, int lastDepth) { + NBTTagByteArray taskNbt = (NBTTagByteArray)tasks.get(taskIndex); + byte[] array = taskNbt.getByteArray(); + int depth = array[0]; + TickTask task = TickTask.fromIndex(array[1]); + int argsLength = array[2]; + + String[] taskArgs; + + if (argsLength > 0) { + taskArgs = new String[argsLength]; + + for (int i = 0; i < argsLength && argIndex < args.tagCount(); ) { + taskArgs[i++] = args.getStringTagAt(argIndex++); + } + } else { + taskArgs = new String[0]; + } + + int endedTasks = lastDepth - depth; + + while (endedTasks-- > 0) { + endTask(); + } + if (depth > lastDepth) { + startTask(task, taskArgs); + } else { + swapTask(task, taskArgs); + } + + if (++taskIndex < tasks.tagCount()) { + addNode(tasks, args, taskIndex, argIndex, depth); + } + } + + public class TickTaskNode { + + public final TickTaskNode parent; + public final List children; + public final TickTask task; + public final String[] args; + + public TickTaskNode(TickTaskNode parent, TickTask task, String... args) { + this.parent = parent; + this.children = new ArrayList<>(); + this.task = task; + this.args = args; + } + } +} diff --git a/carpetmodSrc/redstone/multimeter/common/TickTask.java b/carpetmodSrc/redstone/multimeter/common/TickTask.java new file mode 100644 index 00000000..4b500223 --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/common/TickTask.java @@ -0,0 +1,79 @@ +package redstone.multimeter.common; + +public enum TickTask { + + UNKNOWN ( 0, "unknown"), + TICK ( 1, "tick"), + COMMAND_FUNCTIONS ( 2, "command functions"), + LEVELS ( 3, "levels"), + TICK_WORLD ( 4, "tick world"), + WORLD_BORDER ( 5, "world border"), + WEATHER ( 6, "weather"), + WAKE_SLEEPING_PLAYERS( 7, "wake sleeping players"), + CHUNK_SOURCE ( 8, "chunk source"), + PURGE_UNLOADED_CHUNKS( 9, "purge unloaded chunks"), + TICK_CHUNKS (10, "tick chunks"), + MOB_SPAWNING (11, "mob spawning"), + TICK_CHUNK (12, "tick chunk"), + THUNDER (13, "thunder"), + PRECIPITATION (14, "precipitation"), + RANDOM_TICKS (15, "random ticks"), + CUSTOM_MOB_SPAWNING (16, "custom mob spawning"), + BROADCAST_CHUNKS (17, "broadcast chunks"), + UNLOAD_CHUNKS (18, "unload chunks"), + CHUNK_MAP (19, "chunk map"), + TICK_TIME (20, "tick time"), + SCHEDULED_TICKS (21, "scheduled ticks"), + BLOCK_TICKS (22, "block ticks"), + FLUID_TICKS (23, "fluid ticks"), + VILLAGES (24, "villages"), + RAIDS (25, "raids"), + PORTALS (26, "portals"), + BLOCK_EVENTS (27, "block events"), + ENTITIES (28, "entities"), + REGULAR_ENTITIES (29, "regular entities"), + GLOBAL_ENTITIES (30, "global entities"), + PLAYERS (31, "players"), + DRAGON_FIGHT (32, "dragon fight"), + BLOCK_ENTITIES (33, "block entities"), + ENTITY_MANAGEMENT (34, "entity management"), + CONNECTIONS (35, "connections"), + PLAYER_PING (36, "player ping"), + SERVER_GUI (37, "server gui"), + AUTOSAVE (38, "autosave"), + PACKETS (39, "packets"); + + public static final TickTask[] ALL; + + static { + ALL = new TickTask[values().length]; + + for (TickTask task : values()) { + ALL[task.index] = task; + } + } + + private final int index; + private final String name; + + private TickTask(int index, String name) { + this.index = index; + this.name = name; + } + + public int getIndex() { + return index; + } + + public static TickTask fromIndex(int index) { + if (index > 0 && index < ALL.length) { + return ALL[index]; + } + + return UNKNOWN; + } + + public String getName() { + return name; + } +} diff --git a/carpetmodSrc/redstone/multimeter/common/meter/Meter.java b/carpetmodSrc/redstone/multimeter/common/meter/Meter.java new file mode 100644 index 00000000..af8bed8c --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/common/meter/Meter.java @@ -0,0 +1,151 @@ +package redstone.multimeter.common.meter; + +import java.util.concurrent.atomic.AtomicLong; +import java.util.function.Consumer; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.World; + +import redstone.multimeter.common.DimPos; +import redstone.multimeter.common.meter.MeterProperties.MutableMeterProperties; +import redstone.multimeter.common.meter.event.EventType; +import redstone.multimeter.common.meter.log.MeterLogs; + +public class Meter { + + private static final AtomicLong ID_COUNTER = new AtomicLong(0); + + private final long id; + private final MutableMeterProperties properties; + private final MeterLogs logs; + + /** true if the block at this position is receiving power */ + private boolean powered; + /** true if the block at this position is emitting power or active in another way */ + private boolean active; + + /** This property is used on the client to hide a meter in the HUD */ + private boolean hidden; + + public Meter(long id, MutableMeterProperties properties) { + this.id = id; + this.properties = properties.toMutable(); + this.logs = new MeterLogs(); + } + + public Meter(MutableMeterProperties properties) { + this(ID_COUNTER.getAndIncrement(), properties); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof Meter) { + Meter meter = (Meter)obj; + return meter.id == id; + } + + return false; + } + + public long getId() { + return id; + } + + public MeterProperties getProperties() { + return properties.toImmutable(); + } + + public MeterLogs getLogs() { + return logs; + } + + public void applyUpdate(Consumer update) { + update.accept(properties); + } + + public DimPos getPos() { + return properties.getPos(); + } + + public boolean isIn(World world) { + return properties.getPos().isOf(world); + } + + public String getName() { + return properties.getName(); + } + + public int getColor() { + return properties.getColor(); + } + + public boolean isMovable() { + return properties.getMovable(); + } + + public int getEventTypes() { + return properties.getEventTypes(); + } + + public boolean isMetering(EventType type) { + return properties.hasEventType(type); + } + + public boolean isPowered() { + return powered; + } + + public boolean isActive() { + return active; + } + + public boolean setPowered(boolean powered) { + boolean wasPowered = this.powered; + this.powered = powered; + + return wasPowered != powered; + } + + public boolean setActive(boolean active) { + boolean wasActive = this.active; + this.active = active; + + return wasActive != active; + } + + public boolean isHidden() { + return hidden; + } + + public void toggleHidden() { + setHidden(!hidden); + } + + public void setHidden(boolean hidden) { + this.hidden = hidden; + } + + public NBTTagCompound toNbt() { + NBTTagCompound nbt = new NBTTagCompound(); + + nbt.setLong("id", id); + nbt.setTag("properties", properties.toNbt()); + nbt.setBoolean("powered", powered); + nbt.setBoolean("active", active); + + return nbt; + } + + public static Meter fromNbt(NBTTagCompound nbt) { + long id = nbt.getLong("id"); + MeterProperties properties = MeterProperties.fromNbt(nbt.getCompoundTag("properties")); + boolean powered = nbt.getBoolean("powered"); + boolean active = nbt.getBoolean("active"); + + Meter meter = new Meter(id, properties.toMutable()); + meter.setPowered(powered); + meter.setActive(active); + + return meter; + } +} diff --git a/carpetmodSrc/redstone/multimeter/common/meter/MeterGroup.java b/carpetmodSrc/redstone/multimeter/common/meter/MeterGroup.java new file mode 100644 index 00000000..cbc6d3ab --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/common/meter/MeterGroup.java @@ -0,0 +1,201 @@ +package redstone.multimeter.common.meter; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; + +import redstone.multimeter.common.DimPos; +import redstone.multimeter.common.meter.log.LogManager; +import redstone.multimeter.util.NbtUtils; + +public abstract class MeterGroup { + + private final String name; + private final List meters; + private final Map idToIndex; + private final Map posToIndex; + + protected MeterGroup(String name) { + this.name = name; + this.meters = new ArrayList<>(); + this.idToIndex = new HashMap<>(); + this.posToIndex = new HashMap<>(); + } + + public static boolean isValidName(String name) { + return !name.trim().isEmpty() && name.length() <= getMaxNameLength(); + } + + public static int getMaxNameLength() { + return 64; + } + + public String getName() { + return name; + } + + public void clear() { + meters.clear(); + idToIndex.clear(); + posToIndex.clear(); + getLogManager().clearLogs(); + } + + public boolean hasMeters() { + return !meters.isEmpty(); + } + + public List getMeters() { + return Collections.unmodifiableList(meters); + } + + public boolean hasMeter(long id) { + return idToIndex.containsKey(id); + } + + public boolean hasMeterAt(DimPos pos) { + return posToIndex.containsKey(pos); + } + + public Meter getMeter(long id) { + return fromIndex(idToIndex.getOrDefault(id, -1)); + } + + public Meter getMeterAt(DimPos pos) { + return fromIndex(posToIndex.getOrDefault(pos, -1)); + } + + private Meter fromIndex(int index) { + return (index < 0 || index >= meters.size()) ? null : meters.get(index); + } + + protected boolean addMeter(Meter meter) { + // This check prevents meters from being added twice and + // multiple meters from being added at the same position. + if (idToIndex.containsKey(meter.getId()) || posToIndex.containsKey(meter.getPos())) { + return false; + } + + idToIndex.put(meter.getId(), meters.size()); + posToIndex.put(meter.getPos(), meters.size()); + meters.add(meter); + + meterAdded(meter); + + return true; + } + + protected boolean removeMeter(Meter meter) { + int index = idToIndex.getOrDefault(meter.getId(), -1); + + if (index < 0 || index >= meters.size()) { + return false; + } + + meters.remove(index); + idToIndex.remove(meter.getId(), index); + posToIndex.remove(meter.getPos(), index); + + for (; index < meters.size(); index++) { + Meter m = meters.get(index); + + idToIndex.compute(m.getId(), (id, prevIndex) -> prevIndex - 1); + posToIndex.compute(m.getPos(), (pos, prevIndex) -> prevIndex - 1); + } + + meterRemoved(meter); + + return true; + } + + protected boolean updateMeter(Meter meter, MeterProperties newProperties) { + meter.applyUpdate(properties -> { + boolean changed = false; + + if (newProperties.getPos() != null) { + moveMeter(meter, newProperties.getPos()); + } + if (newProperties.getName() != null) { + changed |= properties.setName(newProperties.getName()); + } + if (newProperties.getColor() != null) { + changed |= properties.setColor(newProperties.getColor()); + } + if (newProperties.getMovable() != null) { + changed |= properties.setMovable(newProperties.getMovable()); + } + if (newProperties.getEventTypes() != null) { + changed |= properties.setEventTypes(newProperties.getEventTypes()); + } + + if (changed) { + meterUpdated(meter); + } + }); + + return true; + } + + protected void moveMeter(Meter meter, DimPos newPos) { + long id = meter.getId(); + DimPos pos = meter.getPos(); + + if (pos.equals(newPos)) { + return; + } + + int index = idToIndex.getOrDefault(id, -1); + + if (index < 0 || index >= meters.size()) { + return; + } + + posToIndex.remove(pos, index); + posToIndex.put(newPos, index); + + meter.applyUpdate(properties -> { + if (properties.setPos(newPos)) { + meterUpdated(meter); + } + }); + } + + protected abstract void meterAdded(Meter meter); + + protected abstract void meterRemoved(Meter meter); + + protected abstract void meterUpdated(Meter meter); + + public abstract LogManager getLogManager(); + + public NBTTagCompound toNbt() { + NBTTagList list = new NBTTagList(); + + for (Meter meter : meters) { + list.appendTag(meter.toNbt()); + } + + NBTTagCompound nbt = new NBTTagCompound(); + nbt.setTag("meters", list); + + return nbt; + } + + public void updateFromNbt(NBTTagCompound nbt) { + clear(); + + NBTTagList list = nbt.getTagList("meters", NbtUtils.TYPE_COMPOUND); + + for (int index = 0; index < list.tagCount(); index++) { + NBTTagCompound meterNbt = list.getCompoundTagAt(index); + Meter meter = Meter.fromNbt(meterNbt); + + addMeter(meter); + } + } +} diff --git a/carpetmodSrc/redstone/multimeter/common/meter/MeterProperties.java b/carpetmodSrc/redstone/multimeter/common/meter/MeterProperties.java new file mode 100644 index 00000000..92a8edc4 --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/common/meter/MeterProperties.java @@ -0,0 +1,275 @@ +package redstone.multimeter.common.meter; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +import net.minecraft.nbt.NBTTagCompound; + +import redstone.multimeter.common.DimPos; +import redstone.multimeter.common.meter.event.EventType; +import redstone.multimeter.util.ColorUtils; + +public class MeterProperties { + + private DimPos pos; + private String name; + private Integer color; + private Boolean movable; + private Integer eventTypes; + + public MeterProperties() { + + } + + public MeterProperties(DimPos pos, String name, Integer color, Boolean movable, Integer eventTypes) { + this.pos = pos; + this.name = name; + this.color = color; + this.movable = movable; + this.eventTypes = eventTypes; + } + + @Override + public String toString() { + return String.format("MeterProperties[pos: %s, name: %s, color: %s, movable: %s, event types: %s]", pos, name, color, movable, eventTypes); + } + + public DimPos getPos() { + return pos; + } + + public String getName() { + return name; + } + + public Integer getColor() { + return color; + } + + public Boolean getMovable() { + return movable; + } + + public Integer getEventTypes() { + return eventTypes; + } + + public boolean hasEventType(EventType type) { + return eventTypes != null && (eventTypes & type.flag()) != 0; + } + + public MutableMeterProperties toMutable() { + return new MutableMeterProperties().fill(this); + } + + public MeterProperties toImmutable() { + return this; + } + + public NBTTagCompound toNbt() { + NBTTagCompound nbt = new NBTTagCompound(); + + if (pos != null) { + nbt.setTag("pos", pos.toNbt()); + } + if (name != null) { + nbt.setString("name", name); + } + if (color != null) { + nbt.setInteger("color", color); + } + if (movable != null) { + nbt.setBoolean("movable", movable); + } + if (eventTypes != null) { + nbt.setInteger("event types", eventTypes); + } + + return nbt; + } + + public static MeterProperties fromNbt(NBTTagCompound nbt) { + MeterProperties properties = new MeterProperties(); + + if (nbt.hasKey("pos")) { + properties.pos = DimPos.fromNbt(nbt.getCompoundTag("pos")); + } + if (nbt.hasKey("name")) { + properties.name = nbt.getString("name"); + } + if (nbt.hasKey("color")) { + properties.color = nbt.getInteger("color"); + } + if (nbt.hasKey("movable")) { + properties.movable = nbt.getBoolean("movable"); + } + if (nbt.hasKey("event types")) { + properties.eventTypes = nbt.getInteger("event types"); + } + + return properties; + } + + public JsonObject toJson() { + JsonObject json = new JsonObject(); + + if (name != null) { + json.addProperty("name", name); + } + if (color != null) { + json.addProperty("color", ColorUtils.toRGBString(color)); + } + if (movable != null) { + json.addProperty("movable", movable); + } + if (eventTypes != null) { + JsonArray types = new JsonArray(); + + for (EventType type : EventType.ALL) { + if (hasEventType(type)) { + types.add(type.getName()); + } + } + + json.add("event_types", types); + } + + return json; + } + + public static MeterProperties fromJson(JsonObject json) { + MeterProperties properties = new MeterProperties(); + + if (json.has("name")) { + JsonElement nameJson = json.get("name"); + + if (nameJson.isJsonPrimitive()) { + properties.name = nameJson.getAsString(); + } + } + if (json.has("color")) { + JsonElement colorJson = json.get("color"); + + if (colorJson.isJsonPrimitive()) { + try { + properties.color = ColorUtils.fromRGBString(colorJson.getAsString()); + } catch (NumberFormatException e) { + + } + } + } + if (json.has("movable")) { + JsonElement movableJson = json.get("movable"); + + if (movableJson.isJsonPrimitive()) { + properties.movable = movableJson.getAsBoolean(); + } + } + if (json.has("event_types")) { + JsonElement typesJson = json.get("event_types"); + + if (typesJson.isJsonArray()) { + properties.eventTypes = 0; + JsonArray types = typesJson.getAsJsonArray(); + + for (int index = 0; index < types.size(); index++) { + JsonElement typeJson = types.get(index); + + if (typeJson.isJsonPrimitive()) { + String typeName = typeJson.getAsString(); + EventType type = EventType.fromName(typeName); + + if (type != null) { + properties.eventTypes |= type.flag(); + } + } + } + } + } + + return properties; + } + + public static class MutableMeterProperties extends MeterProperties { + + public boolean setPos(DimPos pos) { + DimPos prevPos = super.pos; + super.pos = pos; + + return prevPos == null || !prevPos.equals(pos); + } + + public boolean setName(String name) { + String prevName = super.name; + super.name = name; + + return prevName == null || !prevName.equals(name); + } + + public boolean setColor(Integer color) { + Integer prevColor = super.color; + super.color = color; + + return prevColor == null || !prevColor.equals(color); + } + + public boolean setMovable(Boolean movable) { + Boolean prevMovable = super.movable; + super.movable = movable; + + return prevMovable == null || !prevMovable.equals(movable); + } + + public boolean setEventTypes(Integer eventTypes) { + Integer prevEventTypes = super.eventTypes; + super.eventTypes = eventTypes; + + return prevEventTypes == null || !prevEventTypes.equals(eventTypes); + } + + public boolean toggleEventType(EventType type) { + if (super.eventTypes == null) { + super.eventTypes = 0; + } + + return setEventTypes(super.eventTypes ^ type.flag()); + } + + public MutableMeterProperties toMutable() { + return this; + } + + public MeterProperties toImmutable() { + return new MeterProperties(super.pos, super.name, super.color, super.movable, super.eventTypes); + } + + /** + * If a property does not yet have a value, copy the value + * from the given properties. + */ + public MutableMeterProperties fill(MeterProperties properties) { + if (properties == null) { + return this; + } + + if (super.pos == null) { + super.pos = properties.pos; + } + if (super.name == null) { + super.name = properties.name; + } + if (super.color == null) { + super.color = properties.color; + } + if (super.movable == null) { + super.movable = properties.movable; + } + if (super.eventTypes == null) { + super.eventTypes = properties.eventTypes; + } + + return this; + } + } +} diff --git a/carpetmodSrc/redstone/multimeter/common/meter/MeterPropertiesManager.java b/carpetmodSrc/redstone/multimeter/common/meter/MeterPropertiesManager.java new file mode 100644 index 00000000..c941bfbe --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/common/meter/MeterPropertiesManager.java @@ -0,0 +1,33 @@ +package redstone.multimeter.common.meter; + +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import redstone.multimeter.common.DimPos; +import redstone.multimeter.common.meter.MeterProperties.MutableMeterProperties; + +public abstract class MeterPropertiesManager { + + public boolean validate(MutableMeterProperties properties) { + DimPos pos = properties.getPos(); + + if (pos == null) { + return false; + } + + World world = getWorldOf(pos); + + if (world == null) { + return false; + } + + postValidation(properties, world, pos.getBlockPos()); + + return true; + } + + protected abstract World getWorldOf(DimPos pos); + + protected abstract void postValidation(MutableMeterProperties properties, World world, BlockPos pos); + +} diff --git a/carpetmodSrc/redstone/multimeter/common/meter/event/EventType.java b/carpetmodSrc/redstone/multimeter/common/meter/event/EventType.java new file mode 100644 index 00000000..9c4496c2 --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/common/meter/event/EventType.java @@ -0,0 +1,92 @@ +package redstone.multimeter.common.meter.event; + +import java.util.HashMap; +import java.util.Map; + +import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTTagByte; + +import redstone.multimeter.util.NbtUtils; + +public enum EventType { + + UNKNOWN(-1, "unknown"), + POWERED(0, "powered"), + ACTIVE(1, "active"), + MOVED(2, "moved"), + POWER_CHANGE(3, "power_change"), + RANDOM_TICK(4, "random_tick"), + SCHEDULED_TICK(5, "scheduled_tick"), + BLOCK_EVENT(6, "block_event"), + ENTITY_TICK(7, "entity_tick"), + BLOCK_ENTITY_TICK(8, "block_entity_tick"), + BLOCK_UPDATE(9, "block_update"), + COMPARATOR_UPDATE(10, "comparator_update"), + SHAPE_UPDATE(11, "shape_update"), + OBSERVER_UPDATE(12, "observer_update"), + INTERACT_BLOCK(13, "interact_block"); + + public static final EventType[] ALL; + private static final Map BY_NAME; + + static { + EventType[] types = values(); + + ALL = new EventType[types.length - 1]; + BY_NAME = new HashMap<>(); + + for (int index = 1; index < types.length; index++) { + EventType type = types[index]; + + ALL[type.index] = type; + BY_NAME.put(type.name, type); + } + } + + private final int index; + private final String name; + + private EventType(int index, String name) { + this.index = index; + this.name = name; + } + + public int getIndex() { + return index; + } + + public static EventType fromIndex(int index) { + if (index >= 0 && index < ALL.length) { + return ALL[index]; + } + + return UNKNOWN; + } + + public String getName() { + return name; + } + + public static EventType fromName(String name) { + return BY_NAME.getOrDefault(name, UNKNOWN); + } + + public int flag() { + return 1 << index; + } + + public NBTBase toNbt() { + return new NBTTagByte((byte)index); + } + + public static EventType fromNbt(NBTBase nbt) { + if (nbt.getId() != NbtUtils.TYPE_BYTE) { + return UNKNOWN; + } + + NBTTagByte NBTTagByte = (NBTTagByte)nbt; + int index = NBTTagByte.getByte(); + + return fromIndex(index); + } +} diff --git a/carpetmodSrc/redstone/multimeter/common/meter/event/MeterEvent.java b/carpetmodSrc/redstone/multimeter/common/meter/event/MeterEvent.java new file mode 100644 index 00000000..c4ed81b5 --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/common/meter/event/MeterEvent.java @@ -0,0 +1,44 @@ +package redstone.multimeter.common.meter.event; + +import net.minecraft.nbt.NBTTagCompound; + +public class MeterEvent { + + private EventType type; + private int metadata; + + private MeterEvent() { + + } + + public MeterEvent(EventType type, int metadata) { + this.type = type; + this.metadata = metadata; + } + + public EventType getType() { + return type; + } + + public int getMetadata() { + return metadata; + } + + public NBTTagCompound toNbt() { + NBTTagCompound nbt = new NBTTagCompound(); + + nbt.setTag("type", type.toNbt()); + nbt.setInteger("metadata", metadata); + + return nbt; + } + + public static MeterEvent fromNbt(NBTTagCompound nbt) { + MeterEvent event = new MeterEvent(); + + event.type = EventType.fromNbt(nbt.getTag("type")); + event.metadata = nbt.getInteger("metadata"); + + return event; + } +} diff --git a/carpetmodSrc/redstone/multimeter/common/meter/log/EventLog.java b/carpetmodSrc/redstone/multimeter/common/meter/log/EventLog.java new file mode 100644 index 00000000..6403e324 --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/common/meter/log/EventLog.java @@ -0,0 +1,103 @@ +package redstone.multimeter.common.meter.log; + +import net.minecraft.nbt.NBTTagCompound; + +import redstone.multimeter.common.TickPhase; +import redstone.multimeter.common.meter.event.MeterEvent; + +public class EventLog { + + private long tick; + private int subtick; + private TickPhase tickPhase; + private MeterEvent event; + + private EventLog() { + + } + + public EventLog(long tick, int subtick, TickPhase tickPhase, MeterEvent event) { + this.tick = tick; + this.subtick = subtick; + this.tickPhase = tickPhase; + this.event = event; + } + + public long getTick() { + return tick; + } + + public int getSubtick() { + return subtick; + } + + public boolean isAt(long tick) { + return this.tick == tick; + } + + public boolean isAt(long tick, int subtick) { + return this.tick == tick && this.subtick == subtick; + } + + public boolean isBefore(long tick) { + return this.tick < tick; + } + + public boolean isBefore(long tick, int subtick) { + if (this.tick == tick) { + return this.subtick < subtick; + } + + return this.tick < tick; + } + + public boolean isBefore(EventLog event) { + return isBefore(event.getTick(), event.getSubtick()); + } + + public boolean isAfter(long tick) { + return this.tick > tick; + } + + public boolean isAfter(long tick, int subtick) { + if (this.tick == tick) { + return this.subtick > subtick; + } + + return this.tick > tick; + } + + public boolean isAfter(EventLog event) { + return isAfter(event.getTick(), event.getSubtick()); + } + + public TickPhase getTickPhase() { + return tickPhase; + } + + public MeterEvent getEvent() { + return event; + } + + public NBTTagCompound toNbt() { + NBTTagCompound nbt = new NBTTagCompound(); + + nbt.setTag("meter event", event.toNbt()); + nbt.setLong("tick", tick); + nbt.setInteger("subtick", subtick); + nbt.setTag("tick phase", tickPhase.toNbt()); + + return nbt; + } + + public static EventLog fromNbt(NBTTagCompound nbt) { + EventLog log = new EventLog(); + + log.event = MeterEvent.fromNbt(nbt.getCompoundTag("meter event")); + log.tick = nbt.getLong("tick"); + log.subtick = nbt.getInteger("subtick"); + log.tickPhase = TickPhase.fromNbt(nbt.getTag("tick phase")); + + return log; + } +} diff --git a/carpetmodSrc/redstone/multimeter/common/meter/log/LogManager.java b/carpetmodSrc/redstone/multimeter/common/meter/log/LogManager.java new file mode 100644 index 00000000..bb1b99bb --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/common/meter/log/LogManager.java @@ -0,0 +1,17 @@ +package redstone.multimeter.common.meter.log; + +import redstone.multimeter.common.meter.Meter; +import redstone.multimeter.common.meter.MeterGroup; + +public abstract class LogManager { + + protected abstract MeterGroup getMeterGroup(); + + protected abstract long getLastTick(); + + public void clearLogs() { + for (Meter meter : getMeterGroup().getMeters()) { + meter.getLogs().clear(); + } + } +} diff --git a/carpetmodSrc/redstone/multimeter/common/meter/log/MeterLogs.java b/carpetmodSrc/redstone/multimeter/common/meter/log/MeterLogs.java new file mode 100644 index 00000000..98e37d7b --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/common/meter/log/MeterLogs.java @@ -0,0 +1,180 @@ +package redstone.multimeter.common.meter.log; + +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; + +import redstone.multimeter.common.meter.event.EventType; +import redstone.multimeter.util.ListUtils; +import redstone.multimeter.util.NbtUtils; + +public class MeterLogs { + + private final List[] eventLogs; + + private long lastLoggedTick = -1; + + public MeterLogs() { + @SuppressWarnings("unchecked") + List[] lists = new List[EventType.ALL.length]; + + for (int index = 0; index < lists.length; index++) { + lists[index] = new ArrayList<>(); + } + + this.eventLogs = lists; + } + + public void clear() { + for (List logs : eventLogs) { + logs.clear(); + } + + lastLoggedTick = -1; + } + + public boolean isEmpty() { + return lastLoggedTick < 0; + } + + private List getLogs(EventType type) { + return eventLogs[type.getIndex()]; + } + + public void add(EventLog log) { + EventType type = log.getEvent().getType(); + List logs = getLogs(type); + + logs.add(log); + + if (log.getTick() > lastLoggedTick) { + lastLoggedTick = log.getTick(); + } + } + + public void clearOldLogs(long cutoff) { + for (List logs : eventLogs) { + while (!logs.isEmpty()) { + EventLog log = logs.get(0); + + if (log.getTick() > cutoff) { + break; + } + + logs.remove(0); + } + } + } + + public EventLog getLog(EventType type, int index) { + if (index < 0) { + return null; + } + + List logs = getLogs(type); + + if (index >= logs.size()) { + return null; + } + + return logs.get(index); + } + + public int getLastLogBefore(EventType type, long tick) { + return getLastLogBefore(type, tick, 0); + } + + public int getLastLogBefore(EventType type, long tick, int subick) { + List logs = getLogs(type); + + if (logs.isEmpty() || !logs.get(0).isBefore(tick, subick)) { + return -1; + } + if (tick > lastLoggedTick) { + return logs.size() - 1; + } + + int index = ListUtils.binarySearch(logs, event -> event.isBefore(tick, subick)); + EventLog log = logs.get(index); + + while (!log.isBefore(tick, subick)) { + if (index == 0) { + return -1; + } + + log = logs.get(--index); + } + + return index; + + } + + public EventLog getLastLogBefore(long tick) { + return getLastLogBefore(tick, 0); + } + + public EventLog getLastLogBefore(long tick, int subtick) { + EventLog lastLog = null; + + for (EventType type : EventType.ALL) { + int index = getLastLogBefore(type, tick, subtick); + EventLog log = getLog(type, index); + + if (lastLog == null || (log != null && log.isAfter(lastLog))) { + lastLog = log; + } + } + + return lastLog; + } + + public EventLog getLogAt(long tick, int subtick) { + EventLog log = getLastLogBefore(tick, subtick + 1); + return log != null && log.isAt(tick, subtick) ? log : null; + } + + public NBTTagCompound toNbt() { + NBTTagCompound nbt = new NBTTagCompound(); + + for (EventType type : EventType.ALL) { + NBTTagList logs = toNbt(type); + + if (!logs.isEmpty()) { + nbt.setTag(type.getName(), logs); + } + } + + return nbt; + } + + private NBTTagList toNbt(EventType type) { + NBTTagList list = new NBTTagList(); + + for (EventLog log : getLogs(type)) { + list.appendTag(log.toNbt()); + } + + return list; + } + + public void updateFromNbt(NBTTagCompound nbt) { + for (String key : nbt.getKeySet()) { + EventType type = EventType.fromName(key); + + if (type != null) { + updateFromNbt(type, nbt.getTagList(key, NbtUtils.TYPE_COMPOUND)); + } + } + } + + public void updateFromNbt(EventType type, NBTTagList logs) { + for (int index = 0; index < logs.tagCount(); index++) { + NBTTagCompound nbt = logs.getCompoundTagAt(index); + EventLog log = EventLog.fromNbt(nbt); + + add(log); + } + } +} diff --git a/carpetmodSrc/redstone/multimeter/common/network/AbstractPacketHandler.java b/carpetmodSrc/redstone/multimeter/common/network/AbstractPacketHandler.java new file mode 100644 index 00000000..493d878b --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/common/network/AbstractPacketHandler.java @@ -0,0 +1,53 @@ +package redstone.multimeter.common.network; + +import java.io.IOException; + +import carpet.CarpetSettings; + +import io.netty.buffer.Unpooled; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.Packet; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.ResourceLocation; + +public abstract class AbstractPacketHandler { + + protected

Packet encode(P packet) { + ResourceLocation id = PacketManager.getId(packet); + + if (id == null) { + throw new IllegalStateException("Unable to encode packet: " + packet.getClass()); + } + + NBTTagCompound data = new NBTTagCompound(); + packet.encode(data); + + PacketBuffer buffer = new PacketBuffer(Unpooled.buffer()); + + buffer.writeResourceLocation(id); + buffer.writeCompoundTag(data); + + return toCustomPayload(PacketManager.getPacketChannelId(), buffer); + } + + protected abstract Packet toCustomPayload(String id, PacketBuffer buffer); + + public abstract

void send(P packet); + + protected

P decode(PacketBuffer buffer) throws IOException { + ResourceLocation id = buffer.readResourceLocation(); + P packet = PacketManager.createPacket(id); + + if (packet == null) { + throw new IllegalStateException("Unable to decode packet: " + id); + } + + if (CarpetSettings.redstoneMultimeter || packet.force()) { + NBTTagCompound data = buffer.readCompoundTag(); + packet.decode(data); + } + + return packet; + } +} diff --git a/carpetmodSrc/redstone/multimeter/common/network/PacketManager.java b/carpetmodSrc/redstone/multimeter/common/network/PacketManager.java new file mode 100644 index 00000000..745c8435 --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/common/network/PacketManager.java @@ -0,0 +1,43 @@ +package redstone.multimeter.common.network; + +import net.minecraft.util.ResourceLocation; + +import redstone.multimeter.common.network.packets.*; +import redstone.multimeter.registry.SupplierClazzRegistry; + +public class PacketManager { + + private static final SupplierClazzRegistry PACKETS; + + public static String getPacketChannelId() { + return PACKETS.getId().getNamespace(); + } + + public static

ResourceLocation getId(P packet) { + return PACKETS.getId(packet); + } + + public static

P createPacket(ResourceLocation id) { + return PACKETS.get(id); + } + + static { + + PACKETS = new SupplierClazzRegistry<>("network"); + + PACKETS.register("handshake" , HandshakePacket.class , () -> new HandshakePacket()); + PACKETS.register("tick_phase_tree" , TickPhaseTreePacket.class , () -> new TickPhaseTreePacket()); + PACKETS.register("server_tick" , ServerTickPacket.class , () -> new ServerTickPacket()); + PACKETS.register("meter_group_subscription", MeterGroupSubscriptionPacket.class, () -> new MeterGroupSubscriptionPacket()); + PACKETS.register("meter_group_default" , MeterGroupDefaultPacket.class , () -> new MeterGroupDefaultPacket()); + PACKETS.register("meter_group_refresh" , MeterGroupRefreshPacket.class , () -> new MeterGroupRefreshPacket()); + PACKETS.register("meter_updates" , MeterUpdatesPacket.class , () -> new MeterUpdatesPacket()); + PACKETS.register("meter_logs" , MeterLogsPacket.class , () -> new MeterLogsPacket()); + PACKETS.register("clear_meter_group" , ClearMeterGroupPacket.class , () -> new ClearMeterGroupPacket()); + PACKETS.register("add_meter" , AddMeterPacket.class , () -> new AddMeterPacket()); + PACKETS.register("remove_meter" , RemoveMeterPacket.class , () -> new RemoveMeterPacket()); + PACKETS.register("meter_update" , MeterUpdatePacket.class , () -> new MeterUpdatePacket()); + PACKETS.register("teleport_to_meter" , TeleportToMeterPacket.class , () -> new TeleportToMeterPacket()); + + } +} diff --git a/carpetmodSrc/redstone/multimeter/common/network/RSMMPacket.java b/carpetmodSrc/redstone/multimeter/common/network/RSMMPacket.java new file mode 100644 index 00000000..c0e74ddf --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/common/network/RSMMPacket.java @@ -0,0 +1,24 @@ +package redstone.multimeter.common.network; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.nbt.NBTTagCompound; + +import redstone.multimeter.server.MultimeterServer; + +public interface RSMMPacket { + + public void encode(NBTTagCompound data); + + public void decode(NBTTagCompound data); + + public void execute(MultimeterServer server, EntityPlayerMP player); + + /** + * Most RSMM packets are ignored if the redstoneMultimeter carpet + * rule is not enabled. Some packets are handled anyway in order + * to keep RSMM working properly when the carpet rule is toggled. + */ + default boolean force() { + return false; + } +} diff --git a/carpetmodSrc/redstone/multimeter/common/network/packets/AddMeterPacket.java b/carpetmodSrc/redstone/multimeter/common/network/packets/AddMeterPacket.java new file mode 100644 index 00000000..c7baae3f --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/common/network/packets/AddMeterPacket.java @@ -0,0 +1,36 @@ +package redstone.multimeter.common.network.packets; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.nbt.NBTTagCompound; + +import redstone.multimeter.common.meter.MeterProperties; +import redstone.multimeter.common.network.RSMMPacket; +import redstone.multimeter.server.MultimeterServer; + +public class AddMeterPacket implements RSMMPacket { + + private MeterProperties properties; + + public AddMeterPacket() { + + } + + public AddMeterPacket(MeterProperties properties) { + this.properties = properties; + } + + @Override + public void encode(NBTTagCompound data) { + data.setTag("properties", properties.toNbt()); + } + + @Override + public void decode(NBTTagCompound data) { + properties = MeterProperties.fromNbt(data.getCompoundTag("properties")); + } + + @Override + public void execute(MultimeterServer server, EntityPlayerMP player) { + server.getMultimeter().addMeter(player, properties); + } +} diff --git a/carpetmodSrc/redstone/multimeter/common/network/packets/ClearMeterGroupPacket.java b/carpetmodSrc/redstone/multimeter/common/network/packets/ClearMeterGroupPacket.java new file mode 100644 index 00000000..5b7f0fbc --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/common/network/packets/ClearMeterGroupPacket.java @@ -0,0 +1,29 @@ +package redstone.multimeter.common.network.packets; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.nbt.NBTTagCompound; + +import redstone.multimeter.common.network.RSMMPacket; +import redstone.multimeter.server.MultimeterServer; + +public class ClearMeterGroupPacket implements RSMMPacket { + + public ClearMeterGroupPacket() { + + } + + @Override + public void encode(NBTTagCompound data) { + + } + + @Override + public void decode(NBTTagCompound data) { + + } + + @Override + public void execute(MultimeterServer server, EntityPlayerMP player) { + + } +} diff --git a/carpetmodSrc/redstone/multimeter/common/network/packets/HandshakePacket.java b/carpetmodSrc/redstone/multimeter/common/network/packets/HandshakePacket.java new file mode 100644 index 00000000..942b8f91 --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/common/network/packets/HandshakePacket.java @@ -0,0 +1,37 @@ +package redstone.multimeter.common.network.packets; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.nbt.NBTTagCompound; + +import redstone.multimeter.RedstoneMultimeter; +import redstone.multimeter.common.network.RSMMPacket; +import redstone.multimeter.server.MultimeterServer; + +public class HandshakePacket implements RSMMPacket { + + private String modVersion; + + public HandshakePacket() { + modVersion = RedstoneMultimeter.MOD_VERSION; + } + + @Override + public void encode(NBTTagCompound data) { + data.setString("mod version", modVersion); + } + + @Override + public void decode(NBTTagCompound data) { + modVersion = data.getString("mod version"); + } + + @Override + public void execute(MultimeterServer server, EntityPlayerMP player) { + server.onHandshake(player, modVersion); + } + + @Override + public boolean force() { + return true; + } +} diff --git a/carpetmodSrc/redstone/multimeter/common/network/packets/MeterGroupDefaultPacket.java b/carpetmodSrc/redstone/multimeter/common/network/packets/MeterGroupDefaultPacket.java new file mode 100644 index 00000000..822f778e --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/common/network/packets/MeterGroupDefaultPacket.java @@ -0,0 +1,29 @@ +package redstone.multimeter.common.network.packets; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.nbt.NBTTagCompound; + +import redstone.multimeter.common.network.RSMMPacket; +import redstone.multimeter.server.MultimeterServer; + +public class MeterGroupDefaultPacket implements RSMMPacket { + + public MeterGroupDefaultPacket() { + + } + + @Override + public void encode(NBTTagCompound data) { + + } + + @Override + public void decode(NBTTagCompound data) { + + } + + @Override + public void execute(MultimeterServer server, EntityPlayerMP player) { + + } +} diff --git a/carpetmodSrc/redstone/multimeter/common/network/packets/MeterGroupRefreshPacket.java b/carpetmodSrc/redstone/multimeter/common/network/packets/MeterGroupRefreshPacket.java new file mode 100644 index 00000000..c59b50eb --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/common/network/packets/MeterGroupRefreshPacket.java @@ -0,0 +1,45 @@ +package redstone.multimeter.common.network.packets; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.nbt.NBTTagCompound; + +import redstone.multimeter.common.meter.MeterGroup; +import redstone.multimeter.common.network.RSMMPacket; +import redstone.multimeter.server.Multimeter; +import redstone.multimeter.server.MultimeterServer; + +public class MeterGroupRefreshPacket implements RSMMPacket { + + private String name; + private NBTTagCompound meterGroupData; + + public MeterGroupRefreshPacket() { + + } + + public MeterGroupRefreshPacket(MeterGroup meterGroup) { + this.name = meterGroup.getName(); + this.meterGroupData = meterGroup.toNbt(); + } + + @Override + public void encode(NBTTagCompound data) { + data.setString("name", name); + data.setTag("data", meterGroupData); + } + + @Override + public void decode(NBTTagCompound data) { + name = data.getString("name"); + meterGroupData = data.getCompoundTag("data"); + } + + @Override + public void execute(MultimeterServer server, EntityPlayerMP player) { + Multimeter multimeter = server.getMultimeter(); + + if (multimeter.hasSubscription(player)) { + multimeter.refreshMeterGroup(player); + } + } +} diff --git a/carpetmodSrc/redstone/multimeter/common/network/packets/MeterGroupSubscriptionPacket.java b/carpetmodSrc/redstone/multimeter/common/network/packets/MeterGroupSubscriptionPacket.java new file mode 100644 index 00000000..d9c1c8b3 --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/common/network/packets/MeterGroupSubscriptionPacket.java @@ -0,0 +1,56 @@ +package redstone.multimeter.common.network.packets; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.nbt.NBTTagCompound; + +import redstone.multimeter.common.network.RSMMPacket; +import redstone.multimeter.server.Multimeter; +import redstone.multimeter.server.MultimeterServer; +import redstone.multimeter.server.meter.ServerMeterGroup; + +public class MeterGroupSubscriptionPacket implements RSMMPacket { + + private String name; + private boolean subscribed; + + public MeterGroupSubscriptionPacket() { + + } + + public MeterGroupSubscriptionPacket(String name, boolean subscribed) { + this.name = name; + this.subscribed = subscribed; + } + + @Override + public void encode(NBTTagCompound data) { + data.setString("name", name); + data.setBoolean("subscribed", subscribed); + } + + @Override + public void decode(NBTTagCompound data) { + name = data.getString("name"); + subscribed = data.getBoolean("subscribed"); + } + + @Override + public void execute(MultimeterServer server, EntityPlayerMP player) { + Multimeter multimeter = server.getMultimeter(); + ServerMeterGroup meterGroup = multimeter.getMeterGroup(name); + + if (subscribed) { + if (meterGroup == null) { + multimeter.createMeterGroup(player, name); + } else { + multimeter.subscribeToMeterGroup(meterGroup, player); + } + } else { + if (meterGroup == null) { + multimeter.refreshMeterGroup(player); + } else { + multimeter.unsubscribeFromMeterGroup(meterGroup, player); + } + } + } +} diff --git a/carpetmodSrc/redstone/multimeter/common/network/packets/MeterLogsPacket.java b/carpetmodSrc/redstone/multimeter/common/network/packets/MeterLogsPacket.java new file mode 100644 index 00000000..ccf0ff2b --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/common/network/packets/MeterLogsPacket.java @@ -0,0 +1,35 @@ +package redstone.multimeter.common.network.packets; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.nbt.NBTTagCompound; + +import redstone.multimeter.common.network.RSMMPacket; +import redstone.multimeter.server.MultimeterServer; + +public class MeterLogsPacket implements RSMMPacket { + + private NBTTagCompound logsData; + + public MeterLogsPacket() { + + } + + public MeterLogsPacket(NBTTagCompound data) { + this.logsData = data; + } + + @Override + public void encode(NBTTagCompound data) { + data.setTag("logs", logsData); + } + + @Override + public void decode(NBTTagCompound data) { + logsData = data.getCompoundTag("logs"); + } + + @Override + public void execute(MultimeterServer server, EntityPlayerMP player) { + + } +} diff --git a/carpetmodSrc/redstone/multimeter/common/network/packets/MeterUpdatePacket.java b/carpetmodSrc/redstone/multimeter/common/network/packets/MeterUpdatePacket.java new file mode 100644 index 00000000..315c4748 --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/common/network/packets/MeterUpdatePacket.java @@ -0,0 +1,40 @@ +package redstone.multimeter.common.network.packets; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.nbt.NBTTagCompound; + +import redstone.multimeter.common.meter.MeterProperties; +import redstone.multimeter.common.network.RSMMPacket; +import redstone.multimeter.server.MultimeterServer; + +public class MeterUpdatePacket implements RSMMPacket { + + private long id; + private MeterProperties properties; + + public MeterUpdatePacket() { + + } + + public MeterUpdatePacket(long id, MeterProperties properties) { + this.id = id; + this.properties = properties; + } + + @Override + public void encode(NBTTagCompound data) { + data.setLong("id", id); + data.setTag("properties", properties.toNbt()); + } + + @Override + public void decode(NBTTagCompound data) { + id = data.getLong("id"); + properties = MeterProperties.fromNbt(data.getCompoundTag("properties")); + } + + @Override + public void execute(MultimeterServer server, EntityPlayerMP player) { + server.getMultimeter().updateMeter(player, id, properties); + } +} diff --git a/carpetmodSrc/redstone/multimeter/common/network/packets/MeterUpdatesPacket.java b/carpetmodSrc/redstone/multimeter/common/network/packets/MeterUpdatesPacket.java new file mode 100644 index 00000000..376328d1 --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/common/network/packets/MeterUpdatesPacket.java @@ -0,0 +1,86 @@ +package redstone.multimeter.common.network.packets; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import it.unimi.dsi.fastutil.longs.Long2ObjectMap.Entry; +import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.nbt.NBTTagLong; + +import redstone.multimeter.common.meter.MeterProperties; +import redstone.multimeter.common.network.RSMMPacket; +import redstone.multimeter.server.MultimeterServer; +import redstone.multimeter.util.NbtUtils; + +public class MeterUpdatesPacket implements RSMMPacket { + + private List removedMeters; + private Long2ObjectMap meterUpdates; + + public MeterUpdatesPacket() { + this.removedMeters = new ArrayList<>(); + this.meterUpdates = new Long2ObjectOpenHashMap<>(); + } + + public MeterUpdatesPacket(List removedMeters, Map updates) { + this.removedMeters = new ArrayList<>(removedMeters); + this.meterUpdates = new Long2ObjectOpenHashMap<>(updates); + } + + @Override + public void encode(NBTTagCompound data) { + NBTTagList ids = new NBTTagList(); + NBTTagList list = new NBTTagList(); + + for (int index = 0; index < removedMeters.size(); index++) { + long id = removedMeters.get(index); + + NBTTagLong nbt = new NBTTagLong(id); + ids.appendTag(nbt); + } + for (Entry entry : meterUpdates.long2ObjectEntrySet()) { + long id = entry.getLongKey(); + MeterProperties update = entry.getValue(); + + NBTTagCompound nbt = update.toNbt(); + nbt.setLong("id", id); + list.appendTag(nbt); + } + + data.setTag("removed meters", ids); + data.setTag("meter updates", list); + } + + @Override + public void decode(NBTTagCompound data) { + NBTTagList ids = data.getTagList("removed meters", NbtUtils.TYPE_LONG); + NBTTagList list = data.getTagList("meter updates", NbtUtils.TYPE_COMPOUND); + + for (int index = 0; index < ids.tagCount(); index++) { + NBTBase nbt = ids.get(index); + + if (nbt.getId() == NbtUtils.TYPE_LONG) { + removedMeters.add(((NBTTagLong)nbt).getLong()); + } + } + for (int index = 0; index < list.tagCount(); index++) { + NBTTagCompound nbt = list.getCompoundTagAt(index); + + long id = nbt.getLong("id"); + MeterProperties update = MeterProperties.fromNbt(nbt); + meterUpdates.put(id, update); + } + } + + @Override + public void execute(MultimeterServer server, EntityPlayerMP player) { + + } +} diff --git a/carpetmodSrc/redstone/multimeter/common/network/packets/RemoveMeterPacket.java b/carpetmodSrc/redstone/multimeter/common/network/packets/RemoveMeterPacket.java new file mode 100644 index 00000000..2f1b9d33 --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/common/network/packets/RemoveMeterPacket.java @@ -0,0 +1,35 @@ +package redstone.multimeter.common.network.packets; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.nbt.NBTTagCompound; + +import redstone.multimeter.common.network.RSMMPacket; +import redstone.multimeter.server.MultimeterServer; + +public class RemoveMeterPacket implements RSMMPacket { + + private long id; + + public RemoveMeterPacket() { + + } + + public RemoveMeterPacket(long id) { + this.id = id; + } + + @Override + public void encode(NBTTagCompound data) { + data.setLong("id", id); + } + + @Override + public void decode(NBTTagCompound data) { + id = data.getLong("id"); + } + + @Override + public void execute(MultimeterServer server, EntityPlayerMP player) { + server.getMultimeter().removeMeter(player, id); + } +} diff --git a/carpetmodSrc/redstone/multimeter/common/network/packets/ServerTickPacket.java b/carpetmodSrc/redstone/multimeter/common/network/packets/ServerTickPacket.java new file mode 100644 index 00000000..b7ba2609 --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/common/network/packets/ServerTickPacket.java @@ -0,0 +1,35 @@ +package redstone.multimeter.common.network.packets; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.nbt.NBTTagCompound; + +import redstone.multimeter.common.network.RSMMPacket; +import redstone.multimeter.server.MultimeterServer; + +public class ServerTickPacket implements RSMMPacket { + + private long serverTime; + + public ServerTickPacket() { + + } + + public ServerTickPacket(long serverTime) { + this.serverTime = serverTime; + } + + @Override + public void encode(NBTTagCompound data) { + data.setLong("server time", serverTime); + } + + @Override + public void decode(NBTTagCompound data) { + serverTime = data.getLong("server time"); + } + + @Override + public void execute(MultimeterServer server, EntityPlayerMP player) { + + } +} diff --git a/carpetmodSrc/redstone/multimeter/common/network/packets/TeleportToMeterPacket.java b/carpetmodSrc/redstone/multimeter/common/network/packets/TeleportToMeterPacket.java new file mode 100644 index 00000000..63649cd4 --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/common/network/packets/TeleportToMeterPacket.java @@ -0,0 +1,35 @@ +package redstone.multimeter.common.network.packets; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.nbt.NBTTagCompound; + +import redstone.multimeter.common.network.RSMMPacket; +import redstone.multimeter.server.MultimeterServer; + +public class TeleportToMeterPacket implements RSMMPacket { + + private long id; + + public TeleportToMeterPacket() { + + } + + public TeleportToMeterPacket(long id) { + this.id = id; + } + + @Override + public void encode(NBTTagCompound data) { + data.setLong("id", id); + } + + @Override + public void decode(NBTTagCompound data) { + id = data.getLong("id"); + } + + @Override + public void execute(MultimeterServer server, EntityPlayerMP player) { + server.getMultimeter().teleportToMeter(player, id); + } +} diff --git a/carpetmodSrc/redstone/multimeter/common/network/packets/TickPhaseTreePacket.java b/carpetmodSrc/redstone/multimeter/common/network/packets/TickPhaseTreePacket.java new file mode 100644 index 00000000..ef3d4463 --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/common/network/packets/TickPhaseTreePacket.java @@ -0,0 +1,35 @@ +package redstone.multimeter.common.network.packets; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.nbt.NBTTagCompound; + +import redstone.multimeter.common.network.RSMMPacket; +import redstone.multimeter.server.MultimeterServer; + +public class TickPhaseTreePacket implements RSMMPacket { + + private NBTTagCompound nbt; + + public TickPhaseTreePacket() { + + } + + public TickPhaseTreePacket(NBTTagCompound nbt) { + this.nbt = nbt; + } + + @Override + public void encode(NBTTagCompound data) { + data.setTag("tick phase tree", nbt); + } + + @Override + public void decode(NBTTagCompound data) { + nbt = data.getCompoundTag("tick phase tree"); + } + + @Override + public void execute(MultimeterServer server, EntityPlayerMP player) { + server.refreshTickPhaseTree(player); + } +} diff --git a/carpetmodSrc/redstone/multimeter/helper/BlockChestHelper.java b/carpetmodSrc/redstone/multimeter/helper/BlockChestHelper.java new file mode 100644 index 00000000..09af3870 --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/helper/BlockChestHelper.java @@ -0,0 +1,59 @@ +package redstone.multimeter.helper; + +import carpet.CarpetSettings; +import net.minecraft.block.BlockChest; +import net.minecraft.block.state.IBlockState; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.tileentity.TileEntityChest; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.world.World; +import net.minecraft.world.WorldServer; + +import redstone.multimeter.block.PowerSource; +import redstone.multimeter.server.Multimeter; +import redstone.multimeter.server.MultimeterServer; + +public class BlockChestHelper { + + public static boolean isTrapped(BlockChest chest) { + return chest.chestType == BlockChest.Type.TRAP; + } + + public static boolean isTrapped(TileEntityChest chest) { + return chest.getChestType() == BlockChest.Type.TRAP; + } + + public static int getPower(World world, BlockPos pos, IBlockState state) { + TileEntity blockEntity = world.getTileEntity(pos); + + if (blockEntity instanceof TileEntityChest) { + return getPowerFromViewerCount(((TileEntityChest)blockEntity).numPlayersUsing); + } + + return PowerSource.MIN_POWER; + } + + public static int getPowerFromViewerCount(int viewerCount) { + return MathHelper.clamp(viewerCount, PowerSource.MIN_POWER, PowerSource.MAX_POWER); + } + + public static void onInvOpenOrClosed(TileEntityChest chest, boolean open) { + if (CarpetSettings.redstoneMultimeter && isTrapped(chest)) { + WorldServer world = (WorldServer)chest.getWorld(); + BlockPos pos = chest.getPos(); + + MultimeterServer server = WorldHelper.getMultimeterServer(); + Multimeter multimeter = server.getMultimeter(); + + int viewerCount = chest.numPlayersUsing; + int oldViewerCount = open ? viewerCount - 1 : viewerCount + 1; + + int oldPower = BlockChestHelper.getPowerFromViewerCount(oldViewerCount); + int newPower = BlockChestHelper.getPowerFromViewerCount(viewerCount); + + multimeter.logPowerChange(world, pos, oldPower, newPower); + multimeter.logActive(world, pos, newPower > PowerSource.MIN_POWER); + } + } +} diff --git a/carpetmodSrc/redstone/multimeter/helper/WorldHelper.java b/carpetmodSrc/redstone/multimeter/helper/WorldHelper.java new file mode 100644 index 00000000..473df9c1 --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/helper/WorldHelper.java @@ -0,0 +1,114 @@ +package redstone.multimeter.helper; + +import carpet.CarpetServer; +import carpet.CarpetSettings; + +import net.minecraft.block.BlockEventData; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.Entity; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.NextTickListEntry; +import net.minecraft.world.World; + +import redstone.multimeter.common.TickTask; +import redstone.multimeter.server.Multimeter; +import redstone.multimeter.server.MultimeterServer; + +public class WorldHelper { + + public static int currentBlockEventDepth; + + public static MultimeterServer getMultimeterServer() { + return CarpetServer.rsmmServer; + } + + public static Multimeter getMultimeter() { + return CarpetServer.rsmmServer.getMultimeter(); + } + + public static void startTickTask(TickTask task, String... args) { + startTickTask(true, task, args); + } + + public static void startTickTask(boolean updateTree, TickTask task, String... args) { + if (CarpetSettings.redstoneMultimeter) { + getMultimeterServer().startTickTask(updateTree, task, args); + } + } + + public static void endTickTask() { + endTickTask(true); + } + + public static void endTickTask(boolean updateTree) { + if (CarpetSettings.redstoneMultimeter) { + getMultimeterServer().endTickTask(updateTree); + } + } + + public static void swapTickTask(TickTask task, String... args) { + swapTickTask(true, task, args); + } + + public static void swapTickTask(boolean updateTree, TickTask task, String... args) { + if (CarpetSettings.redstoneMultimeter) { + getMultimeterServer().swapTickTask(updateTree, task, args); + } + } + + public static void onBlockUpdate(World world, BlockPos pos, IBlockState state) { + if (CarpetSettings.redstoneMultimeter) { + MultimeterServer server = getMultimeterServer(); + Multimeter multimeter = server.getMultimeter(); + + multimeter.logBlockUpdate(world, pos); + + if (state.getBlock().logPoweredOnBlockUpdate()) { + multimeter.logPowered(world, pos, state); + } + } + } + + public static void onObserverUpdate(World world, BlockPos pos) { + if (CarpetSettings.redstoneMultimeter) { + getMultimeter().logObserverUpdate(world, pos); + } + } + + public static void onEntityTick(World world, Entity entity) { + if (CarpetSettings.redstoneMultimeter) { + getMultimeter().logEntityTick(world, entity); + } + } + + public static void onBlockEntityTick(World world, TileEntity blockEntity) { + if (CarpetSettings.redstoneMultimeter) { + getMultimeter().logBlockEntityTick(world, blockEntity); + } + } + + public static void onComparatorUpdate(World world, BlockPos pos) { + if (CarpetSettings.redstoneMultimeter) { + getMultimeter().logComparatorUpdate(world, pos); + } + } + + public static void onRandomTick(World world, BlockPos pos) { + if (CarpetSettings.redstoneMultimeter) { + getMultimeter().logRandomTick(world, pos); + } + } + + public static void onScheduledTick(World world, NextTickListEntry scheduledTick) { + if (CarpetSettings.redstoneMultimeter) { + getMultimeter().logScheduledTick(world, scheduledTick); + } + } + + public static void onBlockEvent(World world, BlockEventData blockEvent) { + if (CarpetSettings.redstoneMultimeter) { + getMultimeter().logBlockEvent(world, blockEvent, currentBlockEventDepth); + } + } +} diff --git a/carpetmodSrc/redstone/multimeter/interfaces/IBlock.java b/carpetmodSrc/redstone/multimeter/interfaces/IBlock.java new file mode 100644 index 00000000..b8b139b9 --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/interfaces/IBlock.java @@ -0,0 +1,24 @@ +package redstone.multimeter.interfaces; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +public interface IBlock { + + default boolean isMeterable() { + return false; + } + + default boolean isPowerSource() { + return false; + } + + default boolean logPoweredOnBlockUpdate() { + return true; + } + + default boolean isPowered(World world, BlockPos pos, IBlockState state) { + return world.isBlockPowered(pos); + } +} diff --git a/carpetmodSrc/redstone/multimeter/registry/SupplierClazzRegistry.java b/carpetmodSrc/redstone/multimeter/registry/SupplierClazzRegistry.java new file mode 100644 index 00000000..1eda701a --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/registry/SupplierClazzRegistry.java @@ -0,0 +1,52 @@ +package redstone.multimeter.registry; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.Supplier; + +import net.minecraft.util.ResourceLocation; + +import redstone.multimeter.RedstoneMultimeter; + +public class SupplierClazzRegistry { + + private final ResourceLocation id; + private final Map, ResourceLocation> clazzToId; + private final Map> idToSupplier; + + public SupplierClazzRegistry(String name) { + this.id = new ResourceLocation(RedstoneMultimeter.NAMESPACE, name); + this.clazzToId = new HashMap<>(); + this.idToSupplier = new HashMap<>(); + } + + public ResourceLocation getId() { + return id; + } + + @SuppressWarnings("unchecked") + public

P get(ResourceLocation id) { + Supplier objSupplier = idToSupplier.get(id); + return objSupplier == null ? null : (P)objSupplier.get(); + } + + public

ResourceLocation getId(P obj) { + return clazzToId.get(obj.getClass()); + } + + public

void register(String name, Class

clazz, Supplier

supplier) { + String namespace = id.getNamespace(); + String path = String.format("%s/%s", id.getPath(), name); + ResourceLocation id = new ResourceLocation(namespace, path); + + if (clazzToId.containsKey(clazz)) { + throw new IllegalStateException("Registry " + this.id + " already registered an entry with clazz " + clazz); + } + if (idToSupplier.containsKey(id)) { + throw new IllegalStateException("Registry " + this.id + " already registered an entry with id " + id); + } + + clazzToId.put(clazz, id); + idToSupplier.put(id, supplier); + } +} diff --git a/carpetmodSrc/redstone/multimeter/server/Multimeter.java b/carpetmodSrc/redstone/multimeter/server/Multimeter.java new file mode 100644 index 00000000..d1d332b8 --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/server/Multimeter.java @@ -0,0 +1,568 @@ +package redstone.multimeter.server; + +import java.text.NumberFormat; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Locale; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockEventData; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.Style; +import net.minecraft.util.text.TextComponentString; +import net.minecraft.util.text.TextFormatting; +import net.minecraft.util.text.event.ClickEvent; +import net.minecraft.util.text.event.HoverEvent; +import net.minecraft.world.NextTickListEntry; +import net.minecraft.world.World; +import net.minecraft.world.WorldServer; + +import redstone.multimeter.block.Meterable; +import redstone.multimeter.block.PowerSource; +import redstone.multimeter.common.DimPos; +import redstone.multimeter.common.meter.Meter; +import redstone.multimeter.common.meter.MeterGroup; +import redstone.multimeter.common.meter.MeterProperties; +import redstone.multimeter.common.meter.MeterProperties.MutableMeterProperties; +import redstone.multimeter.common.meter.event.EventType; +import redstone.multimeter.common.network.packets.ClearMeterGroupPacket; +import redstone.multimeter.common.network.packets.MeterGroupDefaultPacket; +import redstone.multimeter.common.network.packets.MeterGroupRefreshPacket; +import redstone.multimeter.common.network.packets.MeterGroupSubscriptionPacket; +import redstone.multimeter.server.meter.ServerMeterGroup; +import redstone.multimeter.server.meter.ServerMeterPropertiesManager; +import redstone.multimeter.server.meter.event.MeterEventPredicate; +import redstone.multimeter.server.meter.event.MeterEventSupplier; +import redstone.multimeter.server.option.Options; +import redstone.multimeter.server.option.OptionsManager; + +public class Multimeter { + + private static final NumberFormat NUMBER_FORMAT = NumberFormat.getNumberInstance(Locale.US); + + private final MultimeterServer server; + private final Map meterGroups; + private final Map subscriptions; + private final Set activeMeterGroups; + private final Set idleMeterGroups; + private final ServerMeterPropertiesManager meterPropertiesManager; + + public Options options; + + public Multimeter(MultimeterServer server) { + this.server = server; + this.meterGroups = new LinkedHashMap<>(); + this.subscriptions = new HashMap<>(); + this.activeMeterGroups = new HashSet<>(); + this.idleMeterGroups = new HashSet<>(); + this.meterPropertiesManager = new ServerMeterPropertiesManager(this); + + reloadOptions(); + } + + public MultimeterServer getMultimeterServer() { + return server; + } + + public Collection getMeterGroups() { + return Collections.unmodifiableCollection(meterGroups.values()); + } + + public ServerMeterGroup getMeterGroup(String name) { + return meterGroups.get(name); + } + + public boolean hasMeterGroup(String name) { + return meterGroups.containsKey(name); + } + + public ServerMeterGroup getSubscription(EntityPlayerMP player) { + return subscriptions.get(player.getUniqueID()); + } + + public boolean hasSubscription(EntityPlayerMP player) { + return subscriptions.containsKey(player.getUniqueID()); + } + + public boolean isOwnerOfSubscription(EntityPlayerMP player) { + ServerMeterGroup meterGroup = getSubscription(player); + return meterGroup != null && meterGroup.isOwnedBy(player); + } + + public void reloadOptions() { + if (server.isDedicated()) { + options = OptionsManager.load(server.getConfigFolder()); + } else { + options = new Options(); + } + } + + public void tickStart(boolean paused) { + if (!paused) { + removeIdleMeterGroups(); + + for (ServerMeterGroup meterGroup : meterGroups.values()) { + meterGroup.tick(); + } + } + } + + public void tickEnd(boolean paused) { + broadcastMeterUpdates(); + + if (!paused) { + broadcastMeterLogs(); + } + } + + private void removeIdleMeterGroups() { + Iterator it = idleMeterGroups.iterator(); + + while (it.hasNext()) { + ServerMeterGroup meterGroup = it.next(); + + if (tryRemoveMeterGroup(meterGroup)) { + it.remove(); + } + } + } + + private boolean tryRemoveMeterGroup(ServerMeterGroup meterGroup) { + if (meterGroup.hasMeters() && !meterGroup.isPastIdleTimeLimit()) { + return false; + } + + meterGroups.remove(meterGroup.getName(), meterGroup); + + if (meterGroup.hasMeters()) { + notifyOwnerOfRemoval(meterGroup); + } + + return true; + } + + private void notifyOwnerOfRemoval(ServerMeterGroup meterGroup) { + UUID ownerUUID = meterGroup.getOwner(); + EntityPlayerMP owner = server.getPlayer(ownerUUID); + + if (owner != null) { + ITextComponent message = new TextComponentString(String.format("One of your meter groups, \'%s\', was idle for more than %d ticks and has been removed.", meterGroup.getName(), options.meter_group.max_idle_time)); + server.sendMessage(owner, message, false); + } + } + + private void broadcastMeterUpdates() { + for (ServerMeterGroup meterGroup : meterGroups.values()) { + meterGroup.flushUpdates(); + } + } + + private void broadcastMeterLogs() { + for (ServerMeterGroup meterGroup : meterGroups.values()) { + meterGroup.getLogManager().flushLogs(); + } + } + + public void onPlayerJoin(EntityPlayerMP player) { + + } + + public void onPlayerLeave(EntityPlayerMP player) { + ServerMeterGroup meterGroup = getSubscription(player); + + if (meterGroup != null) { + removeSubscriberFromMeterGroup(meterGroup, player); + } + } + + public void addMeter(EntityPlayerMP player, MeterProperties properties) { + ServerMeterGroup meterGroup = getSubscription(player); + + if (meterGroup != null) { + if (meterGroup.isPastMeterLimit()) { + ITextComponent message = new TextComponentString(String.format("meter limit (%d) reached!", options.meter_group.meter_limit)); + server.sendMessage(player, message, true); + } else if (!addMeter(meterGroup, properties)) { + refreshMeterGroup(meterGroup, player); + } + } + } + + public boolean addMeter(ServerMeterGroup meterGroup, MeterProperties meterProperties) { + MutableMeterProperties properties = meterProperties.toMutable(); + + if (!meterPropertiesManager.validate(properties) || !meterGroup.addMeter(properties)) { + return false; + } + + DimPos pos = properties.getPos(); + World world = server.getWorldOf(pos); + BlockPos blockPos = pos.getBlockPos(); + IBlockState state = world.getBlockState(blockPos); + + logPowered(world, blockPos, state); + logActive(world, blockPos, state); + + return true; + } + + public void removeMeter(EntityPlayerMP player, long id) { + ServerMeterGroup meterGroup = getSubscription(player); + + if (meterGroup != null && !meterGroup.removeMeter(id)) { + refreshMeterGroup(meterGroup, player); + } + } + + public void updateMeter(EntityPlayerMP player, long id, MeterProperties newProperties) { + ServerMeterGroup meterGroup = getSubscription(player); + + if (meterGroup != null && !meterGroup.updateMeter(id, newProperties)) { + refreshMeterGroup(meterGroup, player); + } + } + + public void clearMeterGroup(EntityPlayerMP player) { + ServerMeterGroup meterGroup = getSubscription(player); + + if (meterGroup != null) { + clearMeterGroup(meterGroup); + } + } + + public void clearMeterGroup(ServerMeterGroup meterGroup) { + meterGroup.clear(); + + ClearMeterGroupPacket packet = new ClearMeterGroupPacket(); + server.getPacketHandler().sendToSubscribers(packet, meterGroup); + } + + public void createMeterGroup(EntityPlayerMP player, String name) { + if (!MeterGroup.isValidName(name) || meterGroups.containsKey(name)) { + return; + } + + ServerMeterGroup meterGroup = new ServerMeterGroup(this, name, player); + meterGroups.put(name, meterGroup); + + subscribeToMeterGroup(meterGroup, player); + } + + public void subscribeToMeterGroup(ServerMeterGroup meterGroup, EntityPlayerMP player) { + ServerMeterGroup prevSubscription = getSubscription(player); + + if (prevSubscription == meterGroup) { + refreshMeterGroup(meterGroup, player); + } else { + if (prevSubscription != null) { + removeSubscriberFromMeterGroup(prevSubscription, player); + } + + addSubscriberToMeterGroup(meterGroup, player); + onSubscriptionChanged(player, prevSubscription, meterGroup); + } + } + + public void subscribeToDefaultMeterGroup(EntityPlayerMP player) { + MeterGroupDefaultPacket packet = new MeterGroupDefaultPacket(); + server.getPacketHandler().sendToPlayer(packet, player); + } + + private void addSubscriberToMeterGroup(ServerMeterGroup meterGroup, EntityPlayerMP player) { + UUID playerUUID = player.getUniqueID(); + + subscriptions.put(playerUUID, meterGroup); + meterGroup.addSubscriber(playerUUID); + + if (meterGroup.updateIdleState()) { + activeMeterGroups.add(meterGroup); + idleMeterGroups.remove(meterGroup); + } + } + + public void unsubscribeFromMeterGroup(EntityPlayerMP player) { + ServerMeterGroup meterGroup = getSubscription(player); + + if (meterGroup != null) { + unsubscribeFromMeterGroup(meterGroup, player); + } + } + + public void unsubscribeFromMeterGroup(ServerMeterGroup meterGroup, EntityPlayerMP player) { + if (meterGroup.hasSubscriber(player)) { + removeSubscriberFromMeterGroup(meterGroup, player); + onSubscriptionChanged(player, meterGroup, null); + } + } + + private void removeSubscriberFromMeterGroup(ServerMeterGroup meterGroup, EntityPlayerMP player) { + UUID playerUUID = player.getUniqueID(); + + subscriptions.remove(playerUUID, meterGroup); + meterGroup.removeSubscriber(playerUUID); + + if (meterGroup.updateIdleState()) { + activeMeterGroups.remove(meterGroup); + idleMeterGroups.add(meterGroup); + } + } + + private void onSubscriptionChanged(EntityPlayerMP player, ServerMeterGroup prevSubscription, ServerMeterGroup newSubscription) { + MeterGroupSubscriptionPacket packet; + + if (newSubscription == null) { + packet = new MeterGroupSubscriptionPacket(prevSubscription.getName(), false); + } else { + packet = new MeterGroupSubscriptionPacket(newSubscription.getName(), true); + } + + server.getPacketHandler().sendToPlayer(packet, player); + server.getPlayerManager().updatePermissionLevel(player); + } + + public void clearMembersOfMeterGroup(ServerMeterGroup meterGroup) { + for (UUID playerUUID : meterGroup.getMembers()) { + removeMemberFromMeterGroup(meterGroup, playerUUID); + } + } + + public void addMemberToMeterGroup(ServerMeterGroup meterGroup, UUID playerUUID) { + if (meterGroup.hasMember(playerUUID) || meterGroup.isOwnedBy(playerUUID)) { + return; + } + + EntityPlayerMP player = server.getPlayer(playerUUID); + + if (player == null) { + return; + } + + meterGroup.addMember(playerUUID); + + ITextComponent message = new TextComponentString(""). + appendSibling(new TextComponentString(String.format("You have been invited to meter group \'%s\' - click ", meterGroup.getName()))). + appendSibling(new TextComponentString("[here]").setStyle(new Style(). + setColor(TextFormatting.GREEN). + setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponentString(String.format("Subscribe to meter group \'%s\'", meterGroup.getName())))). + setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, String.format("/metergroup subscribe %s", meterGroup.getName()))) + )). + appendSibling(new TextComponentString(" to subscribe to it.")); + server.sendMessage(player, message, false); + } + + public void removeMemberFromMeterGroup(ServerMeterGroup meterGroup, UUID playerUUID) { + if (!meterGroup.hasMember(playerUUID)) { + return; + } + + meterGroup.removeMember(playerUUID); + + if (meterGroup.isPrivate()) { + EntityPlayerMP player = server.getPlayer(playerUUID); + + if (player != null && meterGroup.hasSubscriber(playerUUID)) { + unsubscribeFromMeterGroup(meterGroup, player); + + ITextComponent message = new TextComponentString(String.format("The owner of meter group \'%s\' has removed you as a member!", meterGroup.getName())); + server.sendMessage(player, message, false); + } + } + } + + public void refreshMeterGroup(EntityPlayerMP player) { + ServerMeterGroup meterGroup = getSubscription(player); + + if (meterGroup != null) { + refreshMeterGroup(meterGroup, player); + } + } + + private void refreshMeterGroup(ServerMeterGroup meterGroup, EntityPlayerMP player) { + MeterGroupRefreshPacket packet = new MeterGroupRefreshPacket(meterGroup); + server.getPacketHandler().sendToPlayer(packet, player); + } + + public void teleportToMeter(EntityPlayerMP player, long id) { + if (!options.meter.allow_teleports) { + ITextComponent message = new TextComponentString("This server does not allow meter teleporting!"); + server.sendMessage(player, message, false); + + return; + } + + ServerMeterGroup meterGroup = getSubscription(player); + + if (meterGroup != null) { + Meter meter = meterGroup.getMeter(id); + + if (meter != null) { + DimPos pos = meter.getPos(); + WorldServer newWorld = server.getWorldOf(pos); + + if (newWorld != null) { + BlockPos blockPos = pos.getBlockPos(); + + double newX = blockPos.getX() + 0.5D; + double newY = blockPos.getY(); + double newZ = blockPos.getZ() + 0.5D; + float yaw = player.rotationYaw; + float pitch = player.rotationPitch; + + player.changeDimension(newWorld.provider.getDimensionType().getId()); + player.connection.setPlayerLocation(newX, newY, newZ, yaw, pitch); + + ITextComponent text = new TextComponentString(String.format("Teleported to meter \"%s\"", meter.getName())); + server.sendMessage(player, text, false); + } + } + } + } + + public void onBlockChange(World world, BlockPos pos, IBlockState oldState, IBlockState newState) { + Block oldBlock = oldState.getBlock(); + Block newBlock = newState.getBlock(); + + if (oldBlock == newBlock && newBlock.isPowerSource() && ((PowerSource)newBlock).logPowerChangeOnStateChange()) { + logPowerChange(world, pos, oldState, newState); + } + + boolean wasMeterable = oldBlock.isMeterable(); + boolean isMeterable = newBlock.isMeterable(); + + if (wasMeterable || isMeterable) { + logActive(world, pos, newState); + } + } + + public void logPowered(World world, BlockPos pos, boolean powered) { + tryLogEvent(world, pos, EventType.POWERED, powered ? 1 : 0, (meterGroup, meter, event) -> meter.setPowered(powered)); + } + + public void logPowered(World world, BlockPos pos, IBlockState state) { + tryLogEvent(world, pos, (meterGroup, meter, event) -> meter.setPowered(event.getMetadata() != 0), new MeterEventSupplier(EventType.POWERED, () -> { + return state.getBlock().isPowered(world, pos, state) ? 1 : 0; + })); + } + + public void logActive(World world, BlockPos pos, boolean active) { + tryLogEvent(world, pos, EventType.ACTIVE, active ? 1 : 0, (meterGroup, meter, event) -> meter.setActive(active)); + } + + public void logActive(World world, BlockPos pos, IBlockState state) { + tryLogEvent(world, pos, (meterGroup, meter, event) -> meter.setActive(event.getMetadata() != 0), new MeterEventSupplier(EventType.ACTIVE, () -> { + Block block = state.getBlock(); + return block.isMeterable() && ((Meterable)block).isActive(world, pos, state) ? 1 : 0; + })); + } + + public void logMoved(World world, BlockPos blockPos, EnumFacing dir) { + tryLogEvent(world, blockPos, EventType.MOVED, dir.getIndex()); + } + + public void moveMeters(World world, BlockPos blockPos, EnumFacing dir) { + DimPos pos = new DimPos(world, blockPos); + + for (ServerMeterGroup meterGroup : activeMeterGroups) { + meterGroup.tryMoveMeter(pos, dir); + } + } + + public void logPowerChange(World world, BlockPos pos, int oldPower, int newPower) { + if (oldPower != newPower) { + tryLogEvent(world, pos, EventType.POWER_CHANGE, (oldPower << 8) | newPower); + } + } + + public void logPowerChange(World world, BlockPos pos, IBlockState oldState, IBlockState newState) { + tryLogEvent(world, pos, (meterGroup, meter, event) -> { + int data = event.getMetadata(); + int oldPower = (data >> 8) & 0xFF; + int newPower = data & 0xFF; + + return oldPower != newPower; + }, new MeterEventSupplier(EventType.POWER_CHANGE, () -> { + PowerSource block = (PowerSource)newState.getBlock(); + int oldPower = block.getPowerLevel(world, pos, oldState); + int newPower = block.getPowerLevel(world, pos, newState); + + return (oldPower << 8) | newPower; + })); + } + + public void logRandomTick(World world, BlockPos pos) { + tryLogEvent(world, pos, EventType.RANDOM_TICK, 0); + } + + public void logScheduledTick(World world, NextTickListEntry scheduledTick) { + tryLogEvent(world, scheduledTick.position, EventType.SCHEDULED_TICK, scheduledTick.priority); + } + + public void logBlockEvent(World world, BlockEventData blockEvent, int depth) { + tryLogEvent(world, blockEvent.getPosition(), EventType.BLOCK_EVENT, (depth << 4) | blockEvent.getEventID()); + } + + public void logEntityTick(World world, Entity entity) { + tryLogEvent(world, entity.getPosition(), EventType.ENTITY_TICK, 0); + } + + public void logBlockEntityTick(World world, TileEntity blockEntity) { + tryLogEvent(world, blockEntity.getPos(), EventType.BLOCK_ENTITY_TICK, 0); + } + + public void logBlockUpdate(World world, BlockPos pos) { + tryLogEvent(world, pos, EventType.BLOCK_UPDATE, 0); + } + + public void logComparatorUpdate(World world, BlockPos pos) { + tryLogEvent(world, pos, EventType.COMPARATOR_UPDATE, 0); + } + + public void logShapeUpdate(World world, BlockPos pos, EnumFacing dir) { + tryLogEvent(world, pos, EventType.SHAPE_UPDATE, dir.getIndex()); + } + + public void logObserverUpdate(World world, BlockPos pos) { + tryLogEvent(world, pos, EventType.OBSERVER_UPDATE, 0); + } + + public void logInteractBlock(World world, BlockPos pos) { + tryLogEvent(world, pos, EventType.INTERACT_BLOCK, 0); + } + + private void tryLogEvent(World world, BlockPos pos, EventType type, int data) { + tryLogEvent(world, pos, type, data, (meterGroup, meter, event) -> true); + } + + private void tryLogEvent(World world, BlockPos pos, EventType type, int data, MeterEventPredicate predicate) { + tryLogEvent(world, pos, predicate, new MeterEventSupplier(type, () -> data)); + } + + private void tryLogEvent(World world, BlockPos blockPos, MeterEventPredicate predicate, MeterEventSupplier supplier) { + if (options.hasEventType(supplier.type())) { + DimPos pos = new DimPos(world, blockPos); + + for (ServerMeterGroup meterGroup : activeMeterGroups) { + meterGroup.tryLogEvent(pos, predicate, supplier); + } + } + } + + static { + + NUMBER_FORMAT.setGroupingUsed(false); + + } +} diff --git a/carpetmodSrc/redstone/multimeter/server/MultimeterServer.java b/carpetmodSrc/redstone/multimeter/server/MultimeterServer.java new file mode 100644 index 00000000..9a6d2c0d --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/server/MultimeterServer.java @@ -0,0 +1,269 @@ +package redstone.multimeter.server; + +import java.io.File; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +import carpet.CarpetSettings; +import carpet.helpers.TickSpeed; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.management.PlayerList; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.world.DimensionType; +import net.minecraft.world.World; +import net.minecraft.world.WorldServer; + +import redstone.multimeter.RedstoneMultimeter; +import redstone.multimeter.common.DimPos; +import redstone.multimeter.common.TickPhase; +import redstone.multimeter.common.TickPhaseTree; +import redstone.multimeter.common.TickTask; +import redstone.multimeter.common.network.packets.HandshakePacket; +import redstone.multimeter.common.network.packets.ServerTickPacket; +import redstone.multimeter.common.network.packets.TickPhaseTreePacket; +import redstone.multimeter.server.meter.ServerMeterGroup; +import redstone.multimeter.util.DimensionUtils; + +public class MultimeterServer { + + private final MinecraftServer server; + private final ServerPacketHandler packetHandler; + private final Multimeter multimeter; + private final Map connectedPlayers; + private final Map playerNameCache; + private final TickPhaseTree tickPhaseTree; + + private TickPhase tickPhase; + /** true if the OverWorld already ticked time */ + private boolean tickedTime; + + public MultimeterServer(MinecraftServer server) { + this.server = server; + this.packetHandler = new ServerPacketHandler(this); + this.multimeter = new Multimeter(this); + this.connectedPlayers = new HashMap<>(); + this.playerNameCache = new HashMap<>(); + this.tickPhaseTree = new TickPhaseTree(); + + this.tickPhase = TickPhase.UNKNOWN; + this.tickedTime = false; + } + + public MinecraftServer getMinecraftServer() { + return server; + } + + public ServerPacketHandler getPacketHandler() { + return packetHandler; + } + + public Multimeter getMultimeter() { + return multimeter; + } + + public TickPhaseTree getTickPhaseTree() { + return tickPhaseTree; + } + + public boolean isDedicated() { + return server.isDedicatedServer(); + } + + public File getConfigFolder() { + return new File(server.getDataDirectory(), RedstoneMultimeter.CONFIG_PATH); + } + + public TickPhase getTickPhase() { + return tickPhase; + } + + public void startTickTask(boolean updateTree, TickTask task, String... args) { + tickPhase = tickPhase.startTask(task); + if (updateTree) { + tickPhaseTree.startTask(task, args); + } + } + + public void endTickTask(boolean updateTree) { + tickPhase = tickPhase.endTask(); + if (updateTree) { + tickPhaseTree.endTask(); + } + } + + public void swapTickTask(boolean updateTree, TickTask task, String... args) { + tickPhase = tickPhase.swapTask(task); + if (updateTree) { + tickPhaseTree.swapTask(task, args); + } + } + + public void onOverworldTickTime() { + tickedTime = true; + } + + public long getCurrentTick() { + long tick = server.getWorld(DimensionType.OVERWORLD.getId()).getTotalWorldTime(); + + if (!tickedTime) { + tick++; + } + + return tick; + } + + public boolean isPaused() { + return server.isPaused() || !TickSpeed.process_entities; + } + + public void tickStart() { + boolean paused = isPaused(); + + if (!paused) { + tickedTime = false; + + if (server.getTickCounter() % 72000 == 0) { + cleanPlayerNameCache(); + } + if (shouldBuildTickPhaseTree()) { + tickPhaseTree.start(); + } + } + + tickPhase = TickPhase.UNKNOWN; + multimeter.tickStart(paused); + } + + private void cleanPlayerNameCache() { + playerNameCache.keySet().removeIf(playerUUID -> { + for (ServerMeterGroup meterGroup : multimeter.getMeterGroups()) { + if (meterGroup.hasMember(playerUUID)) { + return false; + } + } + + return true; + }); + } + + private boolean shouldBuildTickPhaseTree() { + return CarpetSettings.redstoneMultimeter && !tickPhaseTree.isComplete() && !tickPhaseTree.isBuilding(); + } + + public void tickEnd() { + boolean paused = isPaused(); + + if (!paused) { + ServerTickPacket packet = new ServerTickPacket(getCurrentTick()); + + for (EntityPlayerMP player : server.getPlayerList().getPlayers()) { + if (multimeter.hasSubscription(player)) { + packetHandler.sendToPlayer(packet, player); + } + } + } + if (tickPhaseTree.isBuilding()) { + tickPhaseTree.end(); + } + + tickPhase = TickPhase.UNKNOWN; + multimeter.tickEnd(paused); + } + + public void onPlayerJoin(EntityPlayerMP player) { + multimeter.onPlayerJoin(player); + playerNameCache.remove(player.getUniqueID()); + } + + public void onPlayerLeave(EntityPlayerMP player) { + multimeter.onPlayerLeave(player); + connectedPlayers.remove(player.getUniqueID()); + playerNameCache.put(player.getUniqueID(), player.getName()); + } + + public void onHandshake(EntityPlayerMP player, String modVersion) { + if (connectedPlayers.put(player.getUniqueID(), modVersion) == null) { + HandshakePacket packet = new HandshakePacket(); + packetHandler.sendToPlayer(packet, player); + + refreshTickPhaseTree(player); + } + } + + public void refreshTickPhaseTree(EntityPlayerMP player) { + if (tickPhaseTree.isComplete()) { + TickPhaseTreePacket packet = new TickPhaseTreePacket(tickPhaseTree.toNbt()); + packetHandler.sendToPlayer(packet, player); + } + } + + public WorldServer getWorld(ResourceLocation dimensionId) { + DimensionType type = DimensionUtils.getType(dimensionId); + return server.getWorld(type.getId()); + } + + public WorldServer getWorldOf(DimPos pos) { + return getWorld(pos.getDimensionId()); + } + + public IBlockState getBlockState(DimPos pos) { + World world = getWorldOf(pos); + + if (world != null) { + return world.getBlockState(pos.getBlockPos()); + } + + return null; + } + + public PlayerList getPlayerManager() { + return server.getPlayerList(); + } + + public EntityPlayerMP getPlayer(UUID playerUUID) { + return server.getPlayerList().getPlayerByUUID(playerUUID); + } + + public String getPlayerName(UUID playerUUID) { + EntityPlayerMP player = getPlayer(playerUUID); + return player == null ? playerNameCache.get(playerUUID) : player.getName(); + } + + public EntityPlayerMP getPlayer(String playerName) { + return server.getPlayerList().getPlayerByUsername(playerName); + } + + public boolean isMultimeterClient(UUID playerUUID) { + return connectedPlayers.containsKey(playerUUID); + } + + public boolean isMultimeterClient(EntityPlayerMP player) { + return connectedPlayers.containsKey(player.getUniqueID()); + } + + public Collection collectPlayers(Collection playerUUIDs) { + Set players = new LinkedHashSet<>(); + + for (UUID playerUUID : playerUUIDs) { + EntityPlayerMP player = getPlayer(playerUUID); + + if (player != null) { + players.add(player); + } + } + + return players; + } + + public void sendMessage(EntityPlayerMP player, ITextComponent message, boolean actionBar) { + player.sendStatusMessage(message, actionBar); + } +} diff --git a/carpetmodSrc/redstone/multimeter/server/ServerPacketHandler.java b/carpetmodSrc/redstone/multimeter/server/ServerPacketHandler.java new file mode 100644 index 00000000..acdd4bca --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/server/ServerPacketHandler.java @@ -0,0 +1,62 @@ +package redstone.multimeter.server; + +import java.util.Collection; + +import carpet.CarpetSettings; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.network.Packet; +import net.minecraft.network.PacketBuffer; +import net.minecraft.network.play.server.SPacketCustomPayload; + +import redstone.multimeter.common.network.AbstractPacketHandler; +import redstone.multimeter.common.network.RSMMPacket; +import redstone.multimeter.server.meter.ServerMeterGroup; + +public class ServerPacketHandler extends AbstractPacketHandler { + + private final MultimeterServer server; + + public ServerPacketHandler(MultimeterServer server) { + this.server = server; + } + + @Override + protected Packet toCustomPayload(String id, PacketBuffer buffer) { + return new SPacketCustomPayload(id, buffer); + } + + @Override + public

void send(P packet) { + Packet mcPacket = encode(packet); + server.getPlayerManager().sendPacketToAllPlayers(mcPacket); + } + + public

void sendToPlayer(P packet, EntityPlayerMP player) { + player.connection.sendPacket(encode(packet)); + } + + public

void sendToPlayers(P packet, Collection players) { + Packet mcPacket = encode(packet); + + for (EntityPlayerMP player : players) { + player.connection.sendPacket(mcPacket); + } + } + + public

void sendToSubscribers(P packet, ServerMeterGroup meterGroup) { + sendToPlayers(packet, server.collectPlayers(meterGroup.getSubscribers())); + } + + public void onPacketReceived(PacketBuffer buffer, EntityPlayerMP player) { + try { + RSMMPacket packet = decode(buffer); + + if (CarpetSettings.redstoneMultimeter || packet.force()) { + packet.execute(server, player); + } + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/carpetmodSrc/redstone/multimeter/server/meter/ServerMeterGroup.java b/carpetmodSrc/redstone/multimeter/server/meter/ServerMeterGroup.java new file mode 100644 index 00000000..dde9d738 --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/server/meter/ServerMeterGroup.java @@ -0,0 +1,278 @@ +package redstone.multimeter.server.meter; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.util.EnumFacing; +import net.minecraft.world.World; + +import redstone.multimeter.common.DimPos; +import redstone.multimeter.common.meter.Meter; +import redstone.multimeter.common.meter.MeterGroup; +import redstone.multimeter.common.meter.MeterProperties; +import redstone.multimeter.common.meter.MeterProperties.MutableMeterProperties; +import redstone.multimeter.common.meter.event.MeterEvent; +import redstone.multimeter.common.network.packets.MeterUpdatesPacket; +import redstone.multimeter.server.Multimeter; +import redstone.multimeter.server.meter.event.MeterEventPredicate; +import redstone.multimeter.server.meter.event.MeterEventSupplier; +import redstone.multimeter.server.meter.log.ServerLogManager; + +public class ServerMeterGroup extends MeterGroup { + + private final Multimeter multimeter; + private final ServerLogManager logManager; + + private final UUID owner; + private final Set members; + private final Set subscribers; + + private final List removedMeters; + private final Map meterUpdates; + + private boolean isPrivate; + private boolean idle; + private long idleTime; + + public ServerMeterGroup(Multimeter multimeter, String name, EntityPlayerMP owner) { + super(name); + + this.multimeter = multimeter; + this.logManager = new ServerLogManager(this); + + this.owner = owner.getUniqueID(); + this.members = new HashSet<>(); + this.subscribers = new HashSet<>(); + + this.removedMeters = new ArrayList<>(); + this.meterUpdates = new LinkedHashMap<>(); + + this.isPrivate = false; + this.idle = true; + this.idleTime = 0L; + } + + @Override + public void clear() { + super.clear(); + + removedMeters.clear(); + meterUpdates.clear(); + } + + @Override + protected void moveMeter(Meter meter, DimPos newPos) { + if (hasMeterAt(newPos)) { + return; + } + + World world = multimeter.getMultimeterServer().getWorldOf(newPos); + + if (world == null) { + return; + } + + super.moveMeter(meter, newPos); + } + + @Override + protected void meterAdded(Meter meter) { + meterUpdates.putIfAbsent(meter.getId(), meter.getProperties()); + } + + @Override + protected void meterRemoved(Meter meter) { + removedMeters.add(meter.getId()); + meterUpdates.remove(meter.getId()); + } + + @Override + protected void meterUpdated(Meter meter) { + meterUpdates.putIfAbsent(meter.getId(), meter.getProperties()); + } + + @Override + public ServerLogManager getLogManager() { + return logManager; + } + + public Multimeter getMultimeter() { + return multimeter; + } + + public boolean addMeter(MutableMeterProperties properties) { + return addMeter(new Meter(properties)); + } + + public boolean removeMeter(long id) { + return hasMeter(id) && removeMeter(getMeter(id)); + } + + public boolean updateMeter(long id, MeterProperties newProperties) { + return hasMeter(id) && updateMeter(getMeter(id), newProperties); + } + + public void tryMoveMeter(DimPos pos, EnumFacing dir) { + if (!hasMeterAt(pos)) { + return; + } + + Meter meter = getMeterAt(pos); + + if (!meter.isMovable()) { + return; + } + + moveMeter(meter, pos.offset(dir)); + } + + public boolean isPastMeterLimit() { + int limit = multimeter.options.meter_group.meter_limit; + return limit >= 0 && getMeters().size() >= limit; + } + + public UUID getOwner() { + return owner; + } + + public boolean isOwnedBy(EntityPlayerMP player) { + return isOwnedBy(player.getUniqueID()); + } + + public boolean isOwnedBy(UUID playerUUID) { + return owner.equals(playerUUID); + } + + public boolean hasMembers() { + return !members.isEmpty(); + } + + public Collection getMembers() { + return Collections.unmodifiableCollection(members); + } + + public boolean hasMember(EntityPlayerMP player) { + return hasMember(player.getUniqueID()); + } + + public boolean hasMember(UUID playerUUID) { + return members.contains(playerUUID); + } + + public void addMember(UUID playerUUID) { + members.add(playerUUID); + } + + public void removeMember(UUID playerUUID) { + members.remove(playerUUID); + } + + public void clearMembers() { + members.clear(); + } + + public boolean hasSubscribers() { + return !subscribers.isEmpty(); + } + + public Collection getSubscribers() { + return Collections.unmodifiableCollection(subscribers); + } + + public boolean hasSubscriber(EntityPlayerMP player) { + return hasSubscriber(player.getUniqueID()); + } + + public boolean hasSubscriber(UUID playerUUID) { + return subscribers.contains(playerUUID); + } + + public void addSubscriber(UUID playerUUID) { + subscribers.add(playerUUID); + } + + public void removeSubscriber(UUID playerUUID) { + subscribers.remove(playerUUID); + } + + public boolean isPrivate() { + return isPrivate; + } + + public void setPrivate(boolean isPrivate) { + this.isPrivate = isPrivate; + + if (isPrivate) { + for (UUID playerUUID : subscribers) { + if (playerUUID != owner) { + addMember(playerUUID); + } + } + } + } + + public boolean isIdle() { + return idle; + } + + public long getIdleTime() { + return idleTime; + } + + public boolean updateIdleState() { + boolean wasIdle = idle; + idle = !hasSubscribers(); + + if (wasIdle && !idle) { + idleTime = 0L; + } + + return wasIdle != idle; + } + + public boolean isPastIdleTimeLimit() { + return idle && multimeter.options.meter_group.max_idle_time >= 0 && idleTime > multimeter.options.meter_group.max_idle_time; + } + + public void tick() { + if (idle) { + idleTime++; + } + + logManager.tick(); + } + + public void flushUpdates() { + if (removedMeters.isEmpty() && meterUpdates.isEmpty()) { + return; + } + + MeterUpdatesPacket packet = new MeterUpdatesPacket(removedMeters, meterUpdates); + multimeter.getMultimeterServer().getPacketHandler().sendToSubscribers(packet, this); + + removedMeters.clear(); + meterUpdates.clear(); + } + + public void tryLogEvent(DimPos pos, MeterEventPredicate predicate, MeterEventSupplier supplier) { + if (hasMeterAt(pos)) { + Meter meter = getMeterAt(pos); + + if (meter.isMetering(supplier.type())) { + MeterEvent event = supplier.get(); + + if (predicate.test(this, meter, event)) { + logManager.logEvent(meter, supplier.get()); + } + } + } + } +} diff --git a/carpetmodSrc/redstone/multimeter/server/meter/ServerMeterPropertiesManager.java b/carpetmodSrc/redstone/multimeter/server/meter/ServerMeterPropertiesManager.java new file mode 100644 index 00000000..e5d32cc2 --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/server/meter/ServerMeterPropertiesManager.java @@ -0,0 +1,44 @@ +package redstone.multimeter.server.meter; + +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import redstone.multimeter.common.DimPos; +import redstone.multimeter.common.meter.MeterProperties.MutableMeterProperties; +import redstone.multimeter.common.meter.MeterPropertiesManager; +import redstone.multimeter.common.meter.event.EventType; +import redstone.multimeter.server.Multimeter; +import redstone.multimeter.util.ColorUtils; + +public class ServerMeterPropertiesManager extends MeterPropertiesManager { + + private final Multimeter multimeter; + + public ServerMeterPropertiesManager(Multimeter multimeter) { + this.multimeter = multimeter; + } + + @Override + protected World getWorldOf(DimPos pos) { + return multimeter.getMultimeterServer().getWorldOf(pos); + } + + @Override + protected void postValidation(MutableMeterProperties properties, World world, BlockPos pos) { + // These are the backup values for if the saved defaults + // do not fully populate the meter settings. + + if (properties.getName() == null) { + properties.setName("Meter"); + } + if (properties.getColor() == null) { + properties.setColor(ColorUtils.nextColor()); + } + if (properties.getMovable() == null) { + properties.setMovable(true); + } + if (properties.getEventTypes() == null) { + properties.setEventTypes(EventType.POWERED.flag() | EventType.MOVED.flag()); + } + } +} diff --git a/carpetmodSrc/redstone/multimeter/server/meter/event/MeterEventPredicate.java b/carpetmodSrc/redstone/multimeter/server/meter/event/MeterEventPredicate.java new file mode 100644 index 00000000..27a9f776 --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/server/meter/event/MeterEventPredicate.java @@ -0,0 +1,11 @@ +package redstone.multimeter.server.meter.event; + +import redstone.multimeter.common.meter.Meter; +import redstone.multimeter.common.meter.event.MeterEvent; +import redstone.multimeter.server.meter.ServerMeterGroup; + +public interface MeterEventPredicate { + + public boolean test(ServerMeterGroup meterGroup, Meter meter, MeterEvent event); + +} diff --git a/carpetmodSrc/redstone/multimeter/server/meter/event/MeterEventSupplier.java b/carpetmodSrc/redstone/multimeter/server/meter/event/MeterEventSupplier.java new file mode 100644 index 00000000..86cc38df --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/server/meter/event/MeterEventSupplier.java @@ -0,0 +1,31 @@ +package redstone.multimeter.server.meter.event; + +import java.util.function.Supplier; + +import redstone.multimeter.common.meter.event.EventType; +import redstone.multimeter.common.meter.event.MeterEvent; + +public class MeterEventSupplier { + + private final EventType type; + private final Supplier dataSupplier; + + private MeterEvent event; + + public MeterEventSupplier(EventType type, Supplier dataSupplier) { + this.type = type; + this.dataSupplier = dataSupplier; + } + + public EventType type() { + return type; + } + + public MeterEvent get() { + if (event == null) { + event = new MeterEvent(type, dataSupplier.get()); + } + + return event; + } +} diff --git a/carpetmodSrc/redstone/multimeter/server/meter/log/ServerLogManager.java b/carpetmodSrc/redstone/multimeter/server/meter/log/ServerLogManager.java new file mode 100644 index 00000000..75db821a --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/server/meter/log/ServerLogManager.java @@ -0,0 +1,90 @@ +package redstone.multimeter.server.meter.log; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; + +import redstone.multimeter.common.TickPhase; +import redstone.multimeter.common.meter.Meter; +import redstone.multimeter.common.meter.event.MeterEvent; +import redstone.multimeter.common.meter.log.EventLog; +import redstone.multimeter.common.meter.log.LogManager; +import redstone.multimeter.common.network.packets.MeterLogsPacket; +import redstone.multimeter.server.meter.ServerMeterGroup; + +public class ServerLogManager extends LogManager { + + private final ServerMeterGroup meterGroup; + + private int nextSubtick; + + public ServerLogManager(ServerMeterGroup meterGroup) { + this.meterGroup = meterGroup; + } + + @Override + protected ServerMeterGroup getMeterGroup() { + return meterGroup; + } + + @Override + protected long getLastTick() { + return meterGroup.getMultimeter().getMultimeterServer().getCurrentTick(); + } + + @Override + public void clearLogs() { + super.clearLogs(); + + nextSubtick = 0; + } + + public void tick() { + nextSubtick = 0; + } + + public void logEvent(Meter meter, MeterEvent event) { + long tick = getLastTick(); + int subtick = nextSubtick++; + TickPhase phase = meterGroup.getMultimeter().getMultimeterServer().getTickPhase(); + + EventLog log = new EventLog(tick, subtick, phase, event); + meter.getLogs().add(log); + } + + public void flushLogs() { + if (nextSubtick == 0) { + return; + } + + NBTTagList list = new NBTTagList(); + + for (Meter meter : meterGroup.getMeters()) { + if (meter.getLogs().isEmpty()) { + continue; + } + + long id = meter.getId(); + NBTTagCompound logs = meter.getLogs().toNbt(); + + NBTTagCompound nbt = new NBTTagCompound(); + nbt.setLong("id", id); + nbt.setTag("logs", logs); + nbt.setBoolean("powered", meter.isPowered()); + nbt.setBoolean("active", meter.isActive()); + list.appendTag(nbt); + + meter.getLogs().clear(); + } + + if (list.isEmpty()) { + return; + } + + NBTTagCompound nbt = new NBTTagCompound(); + nbt.setInteger("subticks", nextSubtick); + nbt.setTag("logs", list); + + MeterLogsPacket packet = new MeterLogsPacket(nbt); + meterGroup.getMultimeter().getMultimeterServer().getPacketHandler().sendToSubscribers(packet, meterGroup); + } +} diff --git a/carpetmodSrc/redstone/multimeter/server/option/Options.java b/carpetmodSrc/redstone/multimeter/server/option/Options.java new file mode 100644 index 00000000..3836e923 --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/server/option/Options.java @@ -0,0 +1,37 @@ +package redstone.multimeter.server.option; + +import redstone.multimeter.common.meter.event.EventType; + +public class Options { + + public Meter meter = new Meter(); + public MeterGroup meter_group = new MeterGroup(); + public EventTypes event_types = new EventTypes(); + + public class Meter { + + public boolean allow_teleports = true; + + } + + public class MeterGroup { + + public int meter_limit = -1; + public int max_idle_time = 72000; + + } + + public class EventTypes { + + public String allowed = "all"; // "all", "blacklist", "whitelist" + public String[] blacklist = { }; + public String[] whitelist = { }; + + } + + protected transient int enabledEventTypes = ~0; + + public boolean hasEventType(EventType type) { + return (enabledEventTypes & type.flag()) != 0; + } +} diff --git a/carpetmodSrc/redstone/multimeter/server/option/OptionsManager.java b/carpetmodSrc/redstone/multimeter/server/option/OptionsManager.java new file mode 100644 index 00000000..d0af16e5 --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/server/option/OptionsManager.java @@ -0,0 +1,71 @@ +package redstone.multimeter.server.option; + +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import redstone.multimeter.common.meter.event.EventType; + +public class OptionsManager { + + private static final String FILE_NAME = "options.json"; + private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); + + public static Options load(File folder) { + File file = new File(folder, FILE_NAME); + return validate(file.exists() ? read(file) : write(file)); + } + + private static Options read(File file) { + try (FileReader fr = new FileReader(file)) { + return GSON.fromJson(fr, Options.class); + } catch (IOException e) { + return new Options(); + } + } + + private static Options write(File file) { + Options options = new Options(); + + try (FileWriter fw = new FileWriter(file)) { + fw.write(GSON.toJson(options)); + } catch (IOException e) { + + } + + return options; + } + + private static Options validate(Options options) { + switch (options.event_types.allowed) { + case "blacklist": + for (String name : options.event_types.blacklist) { + EventType type = EventType.fromName(name); + + if (type != null) { + options.enabledEventTypes &= ~type.flag(); + } + } + + break; + case "whitelist": + options.enabledEventTypes = 0; + + for (String name : options.event_types.whitelist) { + EventType type = EventType.fromName(name); + + if (type != null) { + options.enabledEventTypes |= type.flag(); + } + } + + break; + } + + return options; + } +} diff --git a/carpetmodSrc/redstone/multimeter/util/AxisUtils.java b/carpetmodSrc/redstone/multimeter/util/AxisUtils.java new file mode 100644 index 00000000..79460677 --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/util/AxisUtils.java @@ -0,0 +1,19 @@ +package redstone.multimeter.util; + +import net.minecraft.util.EnumFacing.Axis; + +public class AxisUtils { + + public static final int choose(Axis axis, int x, int y, int z) { + switch (axis) { + case X: + return x; + case Y: + return y; + case Z: + return z; + } + + return 0; + } +} diff --git a/carpetmodSrc/redstone/multimeter/util/ColorUtils.java b/carpetmodSrc/redstone/multimeter/util/ColorUtils.java new file mode 100644 index 00000000..5179eeb2 --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/util/ColorUtils.java @@ -0,0 +1,118 @@ +package redstone.multimeter.util; + +import java.awt.Color; + +public class ColorUtils { + + private static int colorIndex = 0; + + public static int nextColor() { + return nextColor(true); + } + + public static int nextColor(boolean cycleIndex) { + float hue = ((colorIndex * 11) % 8 + (colorIndex / 8) / 2.0F) / 8.0F; + + if (cycleIndex) { + colorIndex = (colorIndex + 1) % 16; + } + + return 0xFFFFFF & Color.HSBtoRGB(hue, 0.7F, 1.0F); + } + + public static int getAlpha(int argb) { + return (argb >> 24) & 0xFF; + } + + public static int getRed(int argb) { + return (argb >> 16) & 0xFF; + } + + public static int getGreen(int argb) { + return (argb >> 8) & 0xFF; + } + + public static int getBlue(int argb) { + return argb & 0xFF; + } + + public static int fromAlpha(int alpha) { + return (alpha & 0xFF) << 24; + } + + public static int fromRed(int red) { + return (red & 0xFF) << 16; + } + + public static int fromGreen(int green) { + return (green & 0xFF) << 8; + } + + public static int fromBlue(int blue) { + return blue & 0xFF; + } + + public static int setAlpha(int color, int alpha) { + return color & (~(0xFF << 24)) | (alpha << 24); + } + + public static int setRed(int color, int red) { + return color & (~(0xFF << 16)) | (red << 16); + } + + public static int setGreen(int color, int green) { + return color & (~(0xFF << 8)) | (green << 8); + } + + public static int setBlue(int color, int blue) { + return color & ~0xFF | blue; + } + + public static int fromRGB(int red, int green, int blue) { + return fromRed(red) | fromGreen(green) | fromBlue(blue); + } + + public static int fromARGB(int alpha, int red, int green, int blue) { + return fromARGB(alpha, fromRGB(red, green, blue)); + } + + public static int fromARGB(int alpha, int rgb) { + return fromAlpha(alpha) | rgb; + } + + public static int fromRGBString(String string) { + if (string.length() > 6) { + throw new NumberFormatException("Too many characters!"); + } + + return Integer.valueOf(string, 16); + } + + public static int fromARGBString(String string) { + if (string.length() > 8) { + throw new NumberFormatException("Too many characters!"); + } + + return Integer.valueOf(string, 16); + } + + public static String toRGBString(int color) { + String hex = Integer.toHexString(color & 0xFFFFFF); + + while (hex.length() < 6) { + hex = "0" + hex; + } + + return hex.toUpperCase(); + } + + public static String toARGBString(int color) { + String hex = Integer.toHexString(color & 0xFFFFFFFF); + + while (hex.length() < 8) { + hex = "0" + hex; + } + + return hex.toUpperCase(); + } +} diff --git a/carpetmodSrc/redstone/multimeter/util/DimensionUtils.java b/carpetmodSrc/redstone/multimeter/util/DimensionUtils.java new file mode 100644 index 00000000..a4256fe3 --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/util/DimensionUtils.java @@ -0,0 +1,40 @@ +package redstone.multimeter.util; + +import java.util.HashMap; +import java.util.Map; + +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.DimensionType; + +public class DimensionUtils { + + private static final Map ID_TO_TYPE; + private static final Map TYPE_TO_ID; + + private static void register(ResourceLocation id, DimensionType type) { + ID_TO_TYPE.put(id, type); + TYPE_TO_ID.put(type, id); + } + + private static void register(String name, DimensionType type) { + register(new ResourceLocation(name), type); + } + + public static DimensionType getType(ResourceLocation id) { + return ID_TO_TYPE.get(id); + } + + public static ResourceLocation getId(DimensionType type) { + return TYPE_TO_ID.get(type); + } + + static { + + ID_TO_TYPE = new HashMap<>(); + TYPE_TO_ID = new HashMap<>(); + + for (DimensionType type : DimensionType.values()) { + register(type.getName(), type); + } + } +} diff --git a/carpetmodSrc/redstone/multimeter/util/IdentifierUtils.java b/carpetmodSrc/redstone/multimeter/util/IdentifierUtils.java new file mode 100644 index 00000000..01095e1a --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/util/IdentifierUtils.java @@ -0,0 +1,26 @@ +package redstone.multimeter.util; + +import net.minecraft.util.ResourceLocation; + +public class IdentifierUtils { + + public static boolean isValid(ResourceLocation id) { + return isValid(id.getNamespace(), id.getPath()); + } + + public static boolean isValid(String namespace, String path) { + return isValidNamespace(namespace) && isValidPath(path); + } + + public static boolean isValidNamespace(String namespace) { + return namespace.chars().allMatch(chr -> { + return chr == '-' || chr == '.' || chr == '_' || (chr >= 'a' && chr <= 'z') || (chr >= '0' && chr <= '9'); + }); + } + + public static boolean isValidPath(String namespace) { + return namespace.chars().allMatch(chr -> { + return chr == '-' || chr == '.' || chr == '/' || chr == '_' || (chr >= 'a' && chr <= 'z') || (chr >= '0' && chr <= '9'); + }); + } +} diff --git a/carpetmodSrc/redstone/multimeter/util/ListUtils.java b/carpetmodSrc/redstone/multimeter/util/ListUtils.java new file mode 100644 index 00000000..df974492 --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/util/ListUtils.java @@ -0,0 +1,29 @@ +package redstone.multimeter.util; + +import java.util.List; +import java.util.function.Function; + +public class ListUtils { + + public static int binarySearch(List list, Function tooLow) { + return binarySearch(list, 0, list.size() - 1, tooLow); + } + + public static int binarySearch(List list, int low, int high, Function tooLow) { + if (list.isEmpty()) { + return -1; + } + + while (high > low) { + int mid = (low + high) / 2; + + if (tooLow.apply(list.get(mid))) { + low = mid + 1; + } else { + high = mid; + } + } + + return low; + } +} diff --git a/carpetmodSrc/redstone/multimeter/util/NbtUtils.java b/carpetmodSrc/redstone/multimeter/util/NbtUtils.java new file mode 100644 index 00000000..92ff0117 --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/util/NbtUtils.java @@ -0,0 +1,41 @@ +package redstone.multimeter.util; + +import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTTagByte; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.ResourceLocation; + +public class NbtUtils { + + public static final byte TYPE_NULL = 0; + public static final byte TYPE_BYTE = 1; + public static final byte TYPE_SHORT = 2; + public static final byte TYPE_INT = 3; + public static final byte TYPE_LONG = 4; + public static final byte TYPE_FLOAT = 5; + public static final byte TYPE_DOUBLE = 6; + public static final byte TYPE_BYTE_ARRAY = 7; + public static final byte TYPE_STRING = 8; + public static final byte TYPE_LIST = 9; + public static final byte TYPE_COMPOUND = 10; + public static final byte TYPE_INT_ARRAY = 11; + public static final byte TYPE_LONG_ARRAY = 12; + + public static final NBTBase NULL = new NBTTagByte((byte)0); + + public static NBTTagCompound identifierToNbt(ResourceLocation id) { + NBTTagCompound nbt = new NBTTagCompound(); + + nbt.setString("namespace", id.getNamespace()); + nbt.setString("path", id.getPath()); + + return nbt; + } + + public static ResourceLocation nbtToIdentifier(NBTTagCompound nbt) { + String namespace = nbt.getString("namespace"); + String path = nbt.getString("path"); + + return new ResourceLocation(namespace, path); + } +} diff --git a/carpetmodSrc/redstone/multimeter/util/TextUtils.java b/carpetmodSrc/redstone/multimeter/util/TextUtils.java new file mode 100644 index 00000000..4eb80585 --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/util/TextUtils.java @@ -0,0 +1,25 @@ +package redstone.multimeter.util; + +import java.util.List; + +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.Style; +import net.minecraft.util.text.TextComponentString; +import net.minecraft.util.text.TextFormatting; + +public class TextUtils { + + public static void addFancyText(List lines, String title, Object info) { + addFancyText(lines, title, info.toString()); + } + + public static void addFancyText(List lines, String title, String info) { + lines.add(formatFancyText(title, info)); + } + + public static ITextComponent formatFancyText(String title, Object info) { + return new TextComponentString(""). + appendSibling(new TextComponentString(title + ": ").setStyle(new Style().setColor(TextFormatting.GOLD))). + appendSibling(new TextComponentString(info.toString())); + } +} diff --git a/patches/net/minecraft/block/Block.java.patch b/patches/net/minecraft/block/Block.java.patch index 81bc4606..1e5afda9 100644 --- a/patches/net/minecraft/block/Block.java.patch +++ b/patches/net/minecraft/block/Block.java.patch @@ -42,18 +42,22 @@ import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; -@@ -48,6 +49,10 @@ +@@ -48,7 +49,13 @@ import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; +-public class Block ++import redstone.multimeter.interfaces.IBlock; ++ +import carpet.helpers.CapturedDrops; +import carpet.helpers.StatHelper; +import carpet.patches.BlockWool; + - public class Block ++public class Block implements IBlock /* RSMM */ { private static final ResourceLocation field_176230_a = new ResourceLocation("air"); -@@ -74,7 +79,7 @@ + public static final RegistryNamespacedDefaultedByKey field_149771_c = new RegistryNamespacedDefaultedByKey(field_176230_a); +@@ -74,7 +81,7 @@ public float field_149765_K; protected final BlockStateContainer field_176227_L; private IBlockState field_176228_M; @@ -62,7 +66,7 @@ public static int func_149682_b(Block p_149682_0_) { -@@ -236,7 +241,7 @@ +@@ -236,7 +243,7 @@ return this; } @@ -71,7 +75,7 @@ { this.field_149786_r = p_149713_1_; return this; -@@ -328,7 +333,7 @@ +@@ -328,7 +335,7 @@ return this.field_149782_v; } @@ -80,7 +84,7 @@ { this.field_149789_z = p_149675_1_; return this; -@@ -400,7 +405,10 @@ +@@ -400,7 +407,10 @@ public void func_180645_a(World p_180645_1_, BlockPos p_180645_2_, IBlockState p_180645_3_, Random p_180645_4_) { @@ -91,7 +95,7 @@ } public void func_180650_b(World p_180650_1_, BlockPos p_180650_2_, IBlockState p_180650_3_, Random p_180650_4_) -@@ -489,8 +497,17 @@ +@@ -489,8 +499,17 @@ double d1 = (double)(p_180635_0_.field_73012_v.nextFloat() * 0.5F) + 0.25D; double d2 = (double)(p_180635_0_.field_73012_v.nextFloat() * 0.5F) + 0.25D; EntityItem entityitem = new EntityItem(p_180635_0_, (double)p_180635_1_.func_177958_n() + d0, (double)p_180635_1_.func_177956_o() + d1, (double)p_180635_1_.func_177952_p() + d2, p_180635_2_); @@ -109,7 +113,7 @@ } } -@@ -594,7 +611,10 @@ +@@ -594,7 +613,10 @@ public void func_180657_a(World p_180657_1_, EntityPlayer p_180657_2_, BlockPos p_180657_3_, IBlockState p_180657_4_, @Nullable TileEntity p_180657_5_, ItemStack p_180657_6_) { @@ -121,7 +125,7 @@ p_180657_2_.func_71020_j(0.005F); if (this.func_149700_E() && EnchantmentHelper.func_77506_a(Enchantments.field_185306_r, p_180657_6_) > 0) -@@ -849,7 +869,8 @@ +@@ -849,7 +871,8 @@ func_176219_a(32, "deadbush", (new BlockDeadBush()).func_149711_c(0.0F).func_149672_a(SoundType.field_185850_c).func_149663_c("deadbush")); func_176219_a(33, "piston", (new BlockPistonBase(false)).func_149663_c("pistonBase")); func_176219_a(34, "piston_head", (new BlockPistonExtension()).func_149663_c("pistonBase")); diff --git a/patches/net/minecraft/block/BlockButton.java.patch b/patches/net/minecraft/block/BlockButton.java.patch new file mode 100644 index 00000000..ade8c891 --- /dev/null +++ b/patches/net/minecraft/block/BlockButton.java.patch @@ -0,0 +1,31 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockButton.java ++++ ../src-work/minecraft/net/minecraft/block/BlockButton.java +@@ -24,7 +24,10 @@ + import net.minecraft.world.IBlockAccess; + import net.minecraft.world.World; + +-public abstract class BlockButton extends BlockDirectional ++import redstone.multimeter.block.Meterable; ++import redstone.multimeter.block.PowerSource; ++ ++public abstract class BlockButton extends BlockDirectional implements Meterable /* RSMM */, PowerSource /* RSMM */ + { + public static final PropertyBool field_176584_b = PropertyBool.func_177716_a("powered"); + protected static final AxisAlignedBB field_185618_b = new AxisAlignedBB(0.3125D, 0.875D, 0.375D, 0.6875D, 1.0D, 0.625D); +@@ -365,4 +368,16 @@ + { + return BlockFaceShape.UNDEFINED; + } ++ ++ // RSMM ++ @Override ++ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ return state.func_177229_b(field_176584_b); ++ } ++ ++ // RSMM ++ @Override ++ public int getPowerLevel(World world, BlockPos pos, IBlockState state) { ++ return state.func_177229_b(field_176584_b) ? MAX_POWER : MIN_POWER; ++ } + } diff --git a/patches/net/minecraft/block/BlockChest.java.patch b/patches/net/minecraft/block/BlockChest.java.patch index d0a1edc5..c9c03675 100644 --- a/patches/net/minecraft/block/BlockChest.java.patch +++ b/patches/net/minecraft/block/BlockChest.java.patch @@ -1,6 +1,19 @@ --- ../src-base/minecraft/net/minecraft/block/BlockChest.java +++ ../src-work/minecraft/net/minecraft/block/BlockChest.java -@@ -67,21 +67,21 @@ +@@ -32,7 +32,11 @@ + import net.minecraft.world.ILockableContainer; + import net.minecraft.world.World; + +-public class BlockChest extends BlockContainer ++import redstone.multimeter.block.Meterable; ++import redstone.multimeter.block.PowerSource; ++import redstone.multimeter.helper.BlockChestHelper; ++ ++public class BlockChest extends BlockContainer implements Meterable /* RSMM */, PowerSource /* RSMM */ + { + public static final PropertyDirection field_176459_a = BlockHorizontal.field_185512_D; + protected static final AxisAlignedBB field_185557_b = new AxisAlignedBB(0.0625D, 0.0D, 0.0D, 0.9375D, 0.875D, 0.9375D); +@@ -67,21 +71,21 @@ public AxisAlignedBB func_185496_a(IBlockState p_185496_1_, IBlockAccess p_185496_2_, BlockPos p_185496_3_) { @@ -26,7 +39,7 @@ } } -@@ -92,7 +92,7 @@ +@@ -92,7 +96,7 @@ for (EnumFacing enumfacing : EnumFacing.Plane.HORIZONTAL) { BlockPos blockpos = p_176213_2_.func_177972_a(enumfacing); @@ -35,7 +48,7 @@ if (iblockstate.func_177230_c() == this) { -@@ -172,10 +172,10 @@ +@@ -172,10 +176,10 @@ } else { @@ -50,7 +63,7 @@ EnumFacing enumfacing = (EnumFacing)p_176455_3_.func_177229_b(field_176459_a); if (iblockstate.func_177230_c() != this && iblockstate1.func_177230_c() != this) -@@ -186,8 +186,8 @@ +@@ -186,8 +190,8 @@ if (iblockstate2.func_177230_c() == this || iblockstate3.func_177230_c() == this) { BlockPos blockpos1 = iblockstate2.func_177230_c() == this ? p_176455_2_.func_177976_e() : p_176455_2_.func_177974_f(); @@ -61,7 +74,7 @@ enumfacing = EnumFacing.SOUTH; EnumFacing enumfacing2; -@@ -219,8 +219,8 @@ +@@ -219,8 +223,8 @@ else { BlockPos blockpos = iblockstate.func_177230_c() == this ? p_176455_2_.func_177978_c() : p_176455_2_.func_177968_d(); @@ -72,7 +85,7 @@ enumfacing = EnumFacing.EAST; EnumFacing enumfacing1; -@@ -368,7 +368,7 @@ +@@ -368,7 +372,7 @@ { for (EnumFacing enumfacing : EnumFacing.Plane.HORIZONTAL) { @@ -81,7 +94,7 @@ { return true; } -@@ -458,7 +458,7 @@ +@@ -458,7 +462,7 @@ for (EnumFacing enumfacing : EnumFacing.Plane.HORIZONTAL) { BlockPos blockpos = p_189418_2_.func_177972_a(enumfacing); @@ -90,3 +103,40 @@ if (block == this) { +@@ -595,6 +599,36 @@ + return BlockFaceShape.UNDEFINED; + } + ++ // RSMM ++ @Override ++ public boolean isMeterable() { ++ return BlockChestHelper.isTrapped(this); ++ } ++ ++ // RSMM ++ @Override ++ public boolean isPowerSource() { ++ return BlockChestHelper.isTrapped(this); ++ } ++ ++ // RSMM ++ @Override ++ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ return BlockChestHelper.isTrapped(this) && BlockChestHelper.getPower(world, pos, state) > MIN_POWER; ++ } ++ ++ // RSMM ++ @Override ++ public boolean logPowerChangeOnStateChange() { ++ return false; ++ } ++ ++ // RSMM ++ @Override ++ public int getPowerLevel(World world, BlockPos pos, IBlockState state) { ++ return BlockChestHelper.isTrapped(this) ? BlockChestHelper.getPower(world, pos, state) : MIN_POWER; ++ } ++ + public static enum Type + { + BASIC, diff --git a/patches/net/minecraft/block/BlockDaylightDetector.java.patch b/patches/net/minecraft/block/BlockDaylightDetector.java.patch new file mode 100644 index 00000000..b52fa6a5 --- /dev/null +++ b/patches/net/minecraft/block/BlockDaylightDetector.java.patch @@ -0,0 +1,31 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockDaylightDetector.java ++++ ../src-work/minecraft/net/minecraft/block/BlockDaylightDetector.java +@@ -25,7 +25,10 @@ + import net.minecraft.world.IBlockAccess; + import net.minecraft.world.World; + +-public class BlockDaylightDetector extends BlockContainer ++import redstone.multimeter.block.Meterable; ++import redstone.multimeter.block.PowerSource; ++ ++public class BlockDaylightDetector extends BlockContainer implements Meterable /* RSMM */, PowerSource /* RSMM */ + { + public static final PropertyInteger field_176436_a = PropertyInteger.func_177719_a("power", 0, 15); + protected static final AxisAlignedBB field_185566_b = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 1.0D, 0.375D, 1.0D); +@@ -173,4 +176,16 @@ + { + return p_193383_4_ == EnumFacing.DOWN ? BlockFaceShape.SOLID : BlockFaceShape.UNDEFINED; + } ++ ++ // RSMM ++ @Override ++ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ return state.func_177229_b(field_176436_a) > MIN_POWER; ++ } ++ ++ // RSMM ++ @Override ++ public int getPowerLevel(World world, BlockPos pos, IBlockState state) { ++ return state.func_177229_b(field_176436_a); ++ } + } diff --git a/patches/net/minecraft/block/BlockDispenser.java.patch b/patches/net/minecraft/block/BlockDispenser.java.patch index 7f8ea668..da58eddc 100644 --- a/patches/net/minecraft/block/BlockDispenser.java.patch +++ b/patches/net/minecraft/block/BlockDispenser.java.patch @@ -1,15 +1,19 @@ --- ../src-base/minecraft/net/minecraft/block/BlockDispenser.java +++ ../src-work/minecraft/net/minecraft/block/BlockDispenser.java -@@ -32,6 +32,8 @@ +@@ -32,7 +32,11 @@ import net.minecraft.util.registry.RegistryDefaulted; import net.minecraft.world.World; +-public class BlockDispenser extends BlockContainer ++import redstone.multimeter.block.MeterableBlock; ++ +import carpet.CarpetSettings; + - public class BlockDispenser extends BlockContainer ++public class BlockDispenser extends BlockContainer implements MeterableBlock /* RSMM */ { public static final PropertyDirection field_176441_a = BlockDirectional.field_176387_N; -@@ -54,6 +56,8 @@ + public static final PropertyBool field_176440_b = PropertyBool.func_177716_a("triggered"); +@@ -54,6 +58,8 @@ public void func_176213_c(World p_176213_1_, BlockPos p_176213_2_, IBlockState p_176213_3_) { super.func_176213_c(p_176213_1_, p_176213_2_, p_176213_3_); @@ -18,7 +22,7 @@ this.func_176438_e(p_176213_1_, p_176213_2_, p_176213_3_); } -@@ -153,7 +157,17 @@ +@@ -153,9 +159,21 @@ public void func_189540_a(IBlockState p_189540_1_, World p_189540_2_, BlockPos p_189540_3_, Block p_189540_4_, BlockPos p_189540_5_) { @@ -36,8 +40,12 @@ + /* end */ boolean flag1 = ((Boolean)p_189540_1_.func_177229_b(field_176440_b)).booleanValue(); ++ logPowered(p_189540_2_, p_189540_3_, flag); // RSMM ++ if (flag && !flag1) -@@ -187,7 +201,8 @@ + { + p_189540_2_.func_175684_a(p_189540_3_, this, this.func_149738_a(p_189540_2_)); +@@ -187,7 +205,8 @@ public void func_180633_a(World p_180633_1_, BlockPos p_180633_2_, IBlockState p_180633_3_, EntityLivingBase p_180633_4_, ItemStack p_180633_5_) { @@ -47,3 +55,26 @@ if (p_180633_5_.func_82837_s()) { +@@ -269,4 +288,22 @@ + { + return new BlockStateContainer(this, new IProperty[] {field_176441_a, field_176440_b}); + } ++ ++ // RSMM ++ @Override ++ public boolean logPoweredOnBlockUpdate() { ++ return false; ++ } ++ ++ // RSMM ++ @Override ++ public boolean isPowered(World world, BlockPos pos, IBlockState state) { ++ return world.func_175640_z(pos) || (CarpetSettings.quasiConnectivity && world.func_175640_z(pos.func_177984_a())); ++ } ++ ++ // RSMM ++ @Override ++ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ return state.func_177229_b(field_176440_b); ++ } + } diff --git a/patches/net/minecraft/block/BlockDoor.java.patch b/patches/net/minecraft/block/BlockDoor.java.patch new file mode 100644 index 00000000..2c5d134b --- /dev/null +++ b/patches/net/minecraft/block/BlockDoor.java.patch @@ -0,0 +1,65 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockDoor.java ++++ ../src-work/minecraft/net/minecraft/block/BlockDoor.java +@@ -1,6 +1,8 @@ + package net.minecraft.block; + + import java.util.Random; ++ ++import net.minecraft.block.BlockDoor.EnumDoorHalf; + import net.minecraft.block.material.EnumPushReaction; + import net.minecraft.block.material.MapColor; + import net.minecraft.block.material.Material; +@@ -27,7 +29,9 @@ + import net.minecraft.world.IBlockAccess; + import net.minecraft.world.World; + +-public class BlockDoor extends Block ++import redstone.multimeter.block.MeterableBlock; ++ ++public class BlockDoor extends Block implements MeterableBlock /* RSMM */ + { + public static final PropertyDirection field_176520_a = BlockHorizontal.field_185512_D; + public static final PropertyBool field_176519_b = PropertyBool.func_177716_a("open"); +@@ -222,6 +226,9 @@ + { + boolean flag = p_189540_2_.func_175640_z(p_189540_3_) || p_189540_2_.func_175640_z(blockpos1); + ++ logPowered(p_189540_2_, p_189540_3_, flag); // RSMM ++ logPowered(p_189540_2_, blockpos1, flag); // RSMM ++ + if (p_189540_4_ != this && (flag || p_189540_4_.func_176223_P().func_185897_m()) && flag != ((Boolean)iblockstate1.func_177229_b(field_176522_N)).booleanValue()) + { + p_189540_2_.func_180501_a(blockpos1, iblockstate1.func_177226_a(field_176522_N, Boolean.valueOf(flag)), 2); +@@ -439,6 +446,32 @@ + return BlockFaceShape.UNDEFINED; + } + ++ // RSMM ++ @Override ++ public boolean logPoweredOnBlockUpdate() { ++ return false; ++ } ++ ++ // RSMM ++ @Override ++ public boolean isPowered(World world, BlockPos pos, IBlockState state) { ++ return world.func_175640_z(pos) || world.func_175640_z(getOtherHalf(pos, state)); ++ } ++ ++ // RSMM ++ @Override ++ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ return state.func_177229_b(field_176519_b); ++ } ++ ++ // RSMM ++ private BlockPos getOtherHalf(BlockPos pos, IBlockState state) { ++ EnumDoorHalf half = state.func_177229_b(field_176523_O); ++ EnumFacing dir = (half == EnumDoorHalf.LOWER) ? EnumFacing.UP : EnumFacing.DOWN; ++ ++ return pos.func_177972_a(dir); ++ } ++ + public static enum EnumDoorHalf implements IStringSerializable + { + UPPER, diff --git a/patches/net/minecraft/block/BlockEndPortalFrame.java.patch b/patches/net/minecraft/block/BlockEndPortalFrame.java.patch new file mode 100644 index 00000000..3a1ab27b --- /dev/null +++ b/patches/net/minecraft/block/BlockEndPortalFrame.java.patch @@ -0,0 +1,24 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockEndPortalFrame.java ++++ ../src-work/minecraft/net/minecraft/block/BlockEndPortalFrame.java +@@ -29,7 +29,9 @@ + import net.minecraft.world.IBlockAccess; + import net.minecraft.world.World; + +-public class BlockEndPortalFrame extends Block ++import redstone.multimeter.block.Meterable; ++ ++public class BlockEndPortalFrame extends Block implements Meterable /* RSMM */ + { + public static final PropertyDirection field_176508_a = BlockHorizontal.field_185512_D; + public static final PropertyBool field_176507_b = PropertyBool.func_177716_a("eye"); +@@ -135,4 +137,10 @@ + { + return p_193383_4_ == EnumFacing.DOWN ? BlockFaceShape.SOLID : BlockFaceShape.UNDEFINED; + } ++ ++ // RSMM ++ @Override ++ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ return state.func_177229_b(field_176507_b); ++ } + } diff --git a/patches/net/minecraft/block/BlockFenceGate.java.patch b/patches/net/minecraft/block/BlockFenceGate.java.patch index ebd179ad..c305d2fc 100644 --- a/patches/net/minecraft/block/BlockFenceGate.java.patch +++ b/patches/net/minecraft/block/BlockFenceGate.java.patch @@ -1,17 +1,21 @@ --- ../src-base/minecraft/net/minecraft/block/BlockFenceGate.java +++ ../src-work/minecraft/net/minecraft/block/BlockFenceGate.java -@@ -20,6 +20,10 @@ +@@ -20,7 +20,13 @@ import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; +-public class BlockFenceGate extends BlockHorizontal ++import redstone.multimeter.block.MeterableBlock; ++ +import carpet.CarpetSettings; + + import carpet.CarpetSettings; + - public class BlockFenceGate extends BlockHorizontal ++public class BlockFenceGate extends BlockHorizontal implements MeterableBlock /* RSMM */ { public static final PropertyBool field_176466_a = PropertyBool.func_177716_a("open"); -@@ -77,7 +81,7 @@ + public static final PropertyBool field_176465_b = PropertyBool.func_177716_a("powered"); +@@ -77,7 +83,7 @@ public boolean func_176196_c(World p_176196_1_, BlockPos p_176196_2_) { @@ -20,3 +24,29 @@ } @Nullable +@@ -144,6 +150,8 @@ + { + boolean flag = p_189540_2_.func_175640_z(p_189540_3_); + ++ logPowered(p_189540_2_, p_189540_3_, flag); // RSMM ++ + if (((Boolean)p_189540_1_.func_177229_b(field_176465_b)).booleanValue() != flag) + { + p_189540_2_.func_180501_a(p_189540_3_, p_189540_1_.func_177226_a(field_176465_b, Boolean.valueOf(flag)).func_177226_a(field_176466_a, Boolean.valueOf(flag)), 2); +@@ -195,4 +203,16 @@ + return BlockFaceShape.UNDEFINED; + } + } ++ ++ // RSMM ++ @Override ++ public boolean logPoweredOnBlockUpdate() { ++ return false; ++ } ++ ++ // RSMM ++ @Override ++ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ return state.func_177229_b(field_176466_a); ++ } + } diff --git a/patches/net/minecraft/block/BlockHopper.java.patch b/patches/net/minecraft/block/BlockHopper.java.patch index 3aa79af7..32d940a1 100644 --- a/patches/net/minecraft/block/BlockHopper.java.patch +++ b/patches/net/minecraft/block/BlockHopper.java.patch @@ -1,15 +1,19 @@ --- ../src-base/minecraft/net/minecraft/block/BlockHopper.java +++ ../src-work/minecraft/net/minecraft/block/BlockHopper.java -@@ -31,6 +31,8 @@ +@@ -31,7 +31,11 @@ import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; +-public class BlockHopper extends BlockContainer ++import redstone.multimeter.block.MeterableBlock; ++ +import carpet.helpers.BlockRotator; + - public class BlockHopper extends BlockContainer ++public class BlockHopper extends BlockContainer implements MeterableBlock /* RSMM */ { public static final PropertyDirection field_176430_a = PropertyDirection.func_177712_a("facing", new Predicate() -@@ -71,6 +73,8 @@ + { +@@ -71,6 +75,8 @@ public IBlockState func_180642_a(World p_180642_1_, BlockPos p_180642_2_, EnumFacing p_180642_3_, float p_180642_4_, float p_180642_5_, float p_180642_6_, int p_180642_7_, EntityLivingBase p_180642_8_) { EnumFacing enumfacing = p_180642_3_.func_176734_d(); @@ -18,3 +22,29 @@ if (enumfacing == EnumFacing.UP) { +@@ -139,6 +145,8 @@ + { + boolean flag = !p_176427_1_.func_175640_z(p_176427_2_); + ++ logPowered(p_176427_1_, p_176427_2_, !flag); // RSMM ++ + if (flag != ((Boolean)p_176427_3_.func_177229_b(field_176429_b)).booleanValue()) + { + p_176427_1_.func_180501_a(p_176427_2_, p_176427_3_.func_177226_a(field_176429_b, Boolean.valueOf(flag)), 4); +@@ -230,4 +238,16 @@ + { + return p_193383_4_ == EnumFacing.UP ? BlockFaceShape.BOWL : BlockFaceShape.UNDEFINED; + } ++ ++ // RSMM ++ @Override ++ public boolean logPoweredOnBlockUpdate() { ++ return false; ++ } ++ ++ // RSMM ++ @Override ++ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ return state.func_177229_b(field_176429_b); ++ } + } diff --git a/patches/net/minecraft/block/BlockLever.java.patch b/patches/net/minecraft/block/BlockLever.java.patch new file mode 100644 index 00000000..0546e542 --- /dev/null +++ b/patches/net/minecraft/block/BlockLever.java.patch @@ -0,0 +1,33 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockLever.java ++++ ../src-work/minecraft/net/minecraft/block/BlockLever.java +@@ -23,7 +23,10 @@ + import net.minecraft.world.IBlockAccess; + import net.minecraft.world.World; + +-public class BlockLever extends Block ++import redstone.multimeter.block.Meterable; ++import redstone.multimeter.block.PowerSource; ++ ++public class BlockLever extends Block implements Meterable /* RSMM */, PowerSource /* RSMM */ + { + public static final PropertyEnum field_176360_a = PropertyEnum.func_177709_a("facing", BlockLever.EnumOrientation.class); + public static final PropertyBool field_176359_b = PropertyBool.func_177716_a("powered"); +@@ -309,6 +312,18 @@ + return BlockFaceShape.UNDEFINED; + } + ++ // RSMM ++ @Override ++ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ return state.func_177229_b(field_176359_b); ++ } ++ ++ // RSMM ++ @Override ++ public int getPowerLevel(World world, BlockPos pos, IBlockState state) { ++ return state.func_177229_b(field_176359_b) ? MAX_POWER : MIN_POWER; ++ } ++ + public static enum EnumOrientation implements IStringSerializable + { + DOWN_X(0, "down_x", EnumFacing.DOWN), diff --git a/patches/net/minecraft/block/BlockNote.java.patch b/patches/net/minecraft/block/BlockNote.java.patch index 0410eae1..274f4375 100644 --- a/patches/net/minecraft/block/BlockNote.java.patch +++ b/patches/net/minecraft/block/BlockNote.java.patch @@ -1,20 +1,28 @@ --- ../src-base/minecraft/net/minecraft/block/BlockNote.java +++ ../src-work/minecraft/net/minecraft/block/BlockNote.java -@@ -19,9 +19,13 @@ +@@ -19,9 +19,15 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +-public class BlockNote extends BlockContainer ++import redstone.multimeter.block.MeterableBlock; ++import redstone.multimeter.helper.WorldHelper; +import carpet.CarpetSettings; +import net.minecraft.init.Blocks; + - public class BlockNote extends BlockContainer ++public class BlockNote extends BlockContainer implements MeterableBlock /* RSMM */ { private static final List field_176434_a = Lists.newArrayList(SoundEvents.field_187682_dG, SoundEvents.field_187676_dE, SoundEvents.field_187688_dI, SoundEvents.field_187685_dH, SoundEvents.field_187679_dF, SoundEvents.field_193809_ey, SoundEvents.field_193807_ew, SoundEvents.field_193810_ez, SoundEvents.field_193808_ex, SoundEvents.field_193785_eE); + private SoundEvent saveSoundEvent; public BlockNote() { -@@ -37,6 +41,8 @@ +@@ -34,9 +40,13 @@ + boolean flag = p_189540_2_.func_175640_z(p_189540_3_); + TileEntity tileentity = p_189540_2_.func_175625_s(p_189540_3_); + ++ logPowered(p_189540_2_, p_189540_3_, flag); // RSMM ++ if (tileentity instanceof TileEntityNote) { TileEntityNote tileentitynote = (TileEntityNote)tileentity; @@ -23,10 +31,16 @@ if (tileentitynote.field_145880_i != flag) { -@@ -46,6 +52,12 @@ +@@ -46,6 +56,18 @@ } tileentitynote.field_145880_i = flag; ++ ++ // RSMM start ++ if (!p_189540_2_.field_72995_K) { ++ WorldHelper.getMultimeter().logActive(p_189540_2_, p_189540_3_, flag); ++ } ++ // RSMM end + + //Added note block imitation in 1.13 CARPET-XCOM + if(CarpetSettings.noteBlockImitationOf1_13) p_189540_2_.func_175685_c(p_189540_3_, this, true); @@ -36,7 +50,7 @@ } } } -@@ -68,6 +80,9 @@ +@@ -68,6 +90,9 @@ p_180639_4_.func_71029_a(StatList.field_188087_U); } @@ -46,7 +60,7 @@ return true; } } -@@ -113,4 +128,60 @@ +@@ -113,4 +138,78 @@ { return EnumBlockRenderType.MODEL; } @@ -105,5 +119,23 @@ + } + + return i; ++ } ++ ++ // RSMM ++ @Override ++ public boolean logPoweredOnBlockUpdate() { ++ return false; ++ } ++ ++ // RSMM ++ @Override ++ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ TileEntity blockEntity = world.func_175625_s(pos); ++ ++ if (blockEntity instanceof TileEntityNote) { ++ return ((TileEntityNote)blockEntity).field_145880_i; ++ } ++ ++ return false; + } } diff --git a/patches/net/minecraft/block/BlockObserver.java.patch b/patches/net/minecraft/block/BlockObserver.java.patch index 76d3fdfe..580c17c1 100644 --- a/patches/net/minecraft/block/BlockObserver.java.patch +++ b/patches/net/minecraft/block/BlockObserver.java.patch @@ -8,16 +8,21 @@ import net.minecraft.util.EnumFacing; import net.minecraft.util.Mirror; import net.minecraft.util.Rotation; -@@ -15,6 +16,8 @@ +@@ -15,7 +16,12 @@ import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; +-public class BlockObserver extends BlockDirectional ++import redstone.multimeter.block.Meterable; ++import redstone.multimeter.block.PowerSource; ++ +import carpet.CarpetSettings; + - public class BlockObserver extends BlockDirectional ++public class BlockObserver extends BlockDirectional implements Meterable /* RSMM */, PowerSource /* RSMM */ { public static final PropertyBool field_190963_a = PropertyBool.func_177716_a("powered"); -@@ -74,7 +77,18 @@ + +@@ -74,7 +80,18 @@ { if (!p_190960_2_.func_184145_b(p_190960_3_, this)) { @@ -37,7 +42,7 @@ } } } -@@ -125,7 +139,12 @@ +@@ -125,7 +142,12 @@ public IBlockState func_180642_a(World p_180642_1_, BlockPos p_180642_2_, EnumFacing p_180642_3_, float p_180642_4_, float p_180642_5_, float p_180642_6_, int p_180642_7_, EntityLivingBase p_180642_8_) { @@ -51,3 +56,20 @@ } public int func_176201_c(IBlockState p_176201_1_) +@@ -145,4 +167,16 @@ + { + return this.func_176223_P().func_177226_a(field_176387_N, EnumFacing.func_82600_a(p_176203_1_ & 7)); + } ++ ++ // RSMM ++ @Override ++ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ return state.func_177229_b(field_190963_a); ++ } ++ ++ // RSMM ++ @Override ++ public int getPowerLevel(World world, BlockPos pos, IBlockState state) { ++ return state.func_177229_b(field_190963_a) ? MAX_POWER : MIN_POWER; ++ } + } diff --git a/patches/net/minecraft/block/BlockPistonBase.java.patch b/patches/net/minecraft/block/BlockPistonBase.java.patch index 2a655882..6692462a 100644 --- a/patches/net/minecraft/block/BlockPistonBase.java.patch +++ b/patches/net/minecraft/block/BlockPistonBase.java.patch @@ -13,19 +13,25 @@ import net.minecraft.block.material.EnumPushReaction; import net.minecraft.block.material.Material; import net.minecraft.block.properties.IProperty; -@@ -29,6 +33,11 @@ +@@ -29,7 +33,16 @@ import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; +-public class BlockPistonBase extends BlockDirectional +import narcolepticfrog.rsmm.events.PistonPushEventDispatcher; +import carpet.CarpetSettings; +import carpet.utils.PistonFixes; +import net.minecraft.world.WorldServer; + - public class BlockPistonBase extends BlockDirectional ++import redstone.multimeter.block.MeterableBlock; ++import redstone.multimeter.helper.WorldHelper; ++import redstone.multimeter.server.Multimeter; ++ ++public class BlockPistonBase extends BlockDirectional implements MeterableBlock /* RSMM */ { public static final PropertyBool field_176320_b = PropertyBool.func_177716_a("extended"); -@@ -39,6 +48,7 @@ + protected static final AxisAlignedBB field_185648_b = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 0.75D, 1.0D, 1.0D); +@@ -39,6 +52,7 @@ protected static final AxisAlignedBB field_185652_f = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 1.0D, 0.75D, 1.0D); protected static final AxisAlignedBB field_185653_g = new AxisAlignedBB(0.0D, 0.25D, 0.0D, 1.0D, 1.0D, 1.0D); private final boolean field_150082_a; @@ -33,7 +39,7 @@ public BlockPistonBase(boolean p_i45443_1_) { -@@ -99,7 +109,8 @@ +@@ -99,7 +113,8 @@ public void func_180633_a(World p_180633_1_, BlockPos p_180633_2_, IBlockState p_180633_3_, EntityLivingBase p_180633_4_, ItemStack p_180633_5_) { @@ -43,7 +49,7 @@ if (!p_180633_1_.field_72995_K) { -@@ -130,23 +141,83 @@ +@@ -130,43 +145,117 @@ private void func_176316_e(World p_176316_1_, BlockPos p_176316_2_, IBlockState p_176316_3_) { @@ -127,24 +133,49 @@ + return 0; + } + ++ // RSMM - wrapped method + public boolean func_176318_b(World p_176318_1_, BlockPos p_176318_2_, EnumFacing p_176318_3_) { ++ boolean powered = _shouldBeExtended(p_176318_1_, p_176318_2_, p_176318_3_); ++ logPowered(p_176318_1_, p_176318_2_, powered); // RSMM ++ return powered; ++ } ++ ++ private boolean _shouldBeExtended(World worldIn, BlockPos pos, EnumFacing facing) ++ { for (EnumFacing enumfacing : EnumFacing.values()) { -@@ -162,6 +233,12 @@ +- if (enumfacing != p_176318_3_ && p_176318_1_.func_175709_b(p_176318_2_.func_177972_a(enumfacing), enumfacing)) ++ if (enumfacing != facing && worldIn.func_175709_b(pos.func_177972_a(enumfacing), enumfacing)) + { + return true; + } + } + +- if (p_176318_1_.func_175709_b(p_176318_2_, EnumFacing.DOWN)) ++ if (worldIn.func_175709_b(pos, EnumFacing.DOWN)) + { + return true; } else { +- BlockPos blockpos = p_176318_2_.func_177984_a(); + /* carpet mod */ + if (!CarpetSettings.quasiConnectivity) + { + return false; + } + /* end */ - BlockPos blockpos = p_176318_2_.func_177984_a(); ++ BlockPos blockpos = pos.func_177984_a(); for (EnumFacing enumfacing1 : EnumFacing.values()) -@@ -240,7 +317,11 @@ + { +- if (enumfacing1 != EnumFacing.DOWN && p_176318_1_.func_175709_b(blockpos.func_177972_a(enumfacing1), enumfacing1)) ++ if (enumfacing1 != EnumFacing.DOWN && worldIn.func_175709_b(blockpos.func_177972_a(enumfacing1), enumfacing1)) + { + return true; + } +@@ -240,7 +329,11 @@ } } } @@ -157,7 +188,7 @@ if (!flag1 && iblockstate.func_185904_a() != Material.field_151579_a && func_185646_a(iblockstate, p_189539_2_, blockpos, enumfacing.func_176734_d(), false, enumfacing) && (iblockstate.func_185905_o() == EnumPushReaction.NORMAL || block == Blocks.field_150331_J || block == Blocks.field_150320_F)) { this.func_176319_a(p_189539_2_, p_189539_3_, enumfacing, false); -@@ -307,7 +388,15 @@ +@@ -307,7 +400,15 @@ return false; } @@ -174,7 +205,7 @@ } else { -@@ -319,6 +408,14 @@ +@@ -319,6 +420,14 @@ return false; } } @@ -189,7 +220,7 @@ private boolean func_176319_a(World p_176319_1_, BlockPos p_176319_2_, EnumFacing p_176319_3_, boolean p_176319_4_) { -@@ -342,6 +439,7 @@ +@@ -342,6 +451,7 @@ { BlockPos blockpos = list.get(i); list1.add(p_176319_1_.func_180495_p(blockpos).func_185899_b(p_176319_1_, blockpos)); @@ -197,7 +228,7 @@ } List list2 = blockpistonstructurehelper.func_177252_d(); -@@ -358,15 +456,50 @@ +@@ -358,15 +468,76 @@ --k; aiblockstate[k] = iblockstate; } @@ -223,9 +254,15 @@ { BlockPos blockpos3 = list.get(l); + // ----- RSMM Start ------ // -+ if (CarpetSettings.redstoneMultimeter) { ++ if (CarpetSettings.redstoneMultimeterLegacy) { + PistonPushEventDispatcher.dispatchEvent(p_176319_1_, blockpos3, enumfacing); + } ++ if (CarpetSettings.redstoneMultimeter && !p_176319_1_.field_72995_K) { ++ Multimeter multimeter = WorldHelper.getMultimeter(); ++ ++ multimeter.logMoved(p_176319_1_, blockpos3, enumfacing); ++ multimeter.moveMeters(p_176319_1_, blockpos3, enumfacing); ++ } + // ----- RSMM End ----- // IBlockState iblockstate2 = p_176319_1_.func_180495_p(blockpos3); p_176319_1_.func_180501_a(blockpos3, Blocks.field_150350_a.func_176223_P(), 2); @@ -249,7 +286,7 @@ --k; aiblockstate[k] = iblockstate2; } -@@ -397,6 +530,8 @@ +@@ -397,6 +568,8 @@ p_176319_1_.func_175685_c(blockpos2, Blocks.field_150332_K, false); } @@ -258,11 +295,29 @@ return true; } } -@@ -439,4 +574,9 @@ +@@ -439,4 +612,27 @@ p_193383_2_ = this.func_176221_a(p_193383_2_, p_193383_1_, p_193383_3_); return p_193383_2_.func_177229_b(field_176387_N) != p_193383_4_.func_176734_d() && ((Boolean)p_193383_2_.func_177229_b(field_176320_b)).booleanValue() ? BlockFaceShape.UNDEFINED : BlockFaceShape.SOLID; } + ++ // RSMM ++ @Override ++ public boolean logPoweredOnBlockUpdate() { ++ return false; ++ } ++ ++ // RSMM ++ @Override ++ public boolean isPowered(World world, BlockPos pos, IBlockState state) { ++ return func_176318_b(world, pos, state.func_177229_b(field_176387_N)); ++ } ++ ++ // RSMM ++ @Override ++ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ return state.func_177229_b(field_176320_b); ++ } ++ + // Added method for checking if block is being pushed for duping fixes CARPET-XCOM + public static boolean isBeingPushed(BlockPos pos){ + return dupeFixLocations.contains(pos); diff --git a/patches/net/minecraft/block/BlockPressurePlate.java.patch b/patches/net/minecraft/block/BlockPressurePlate.java.patch new file mode 100644 index 00000000..abf1a923 --- /dev/null +++ b/patches/net/minecraft/block/BlockPressurePlate.java.patch @@ -0,0 +1,33 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockPressurePlate.java ++++ ../src-work/minecraft/net/minecraft/block/BlockPressurePlate.java +@@ -15,7 +15,10 @@ + import net.minecraft.util.math.BlockPos; + import net.minecraft.world.World; + +-public class BlockPressurePlate extends BlockBasePressurePlate ++import redstone.multimeter.block.Meterable; ++import redstone.multimeter.block.PowerSource; ++ ++public class BlockPressurePlate extends BlockBasePressurePlate implements Meterable /* RSMM */, PowerSource /* RSMM */ + { + public static final PropertyBool field_176580_a = PropertyBool.func_177716_a("powered"); + private final BlockPressurePlate.Sensitivity field_150069_a; +@@ -107,6 +110,18 @@ + return new BlockStateContainer(this, new IProperty[] {field_176580_a}); + } + ++ // RSMM ++ @Override ++ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ return state.func_177229_b(field_176580_a); ++ } ++ ++ // RSMM ++ @Override ++ public int getPowerLevel(World world, BlockPos pos, IBlockState state) { ++ return state.func_177229_b(field_176580_a) ? MAX_POWER : MIN_POWER; ++ } ++ + public static enum Sensitivity + { + EVERYTHING, diff --git a/patches/net/minecraft/block/BlockPressurePlateWeighted.java.patch b/patches/net/minecraft/block/BlockPressurePlateWeighted.java.patch new file mode 100644 index 00000000..cbd704b3 --- /dev/null +++ b/patches/net/minecraft/block/BlockPressurePlateWeighted.java.patch @@ -0,0 +1,31 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockPressurePlateWeighted.java ++++ ../src-work/minecraft/net/minecraft/block/BlockPressurePlateWeighted.java +@@ -14,7 +14,10 @@ + import net.minecraft.util.math.MathHelper; + import net.minecraft.world.World; + +-public class BlockPressurePlateWeighted extends BlockBasePressurePlate ++import redstone.multimeter.block.Meterable; ++import redstone.multimeter.block.PowerSource; ++ ++public class BlockPressurePlateWeighted extends BlockBasePressurePlate implements Meterable /* RSMM */, PowerSource /* RSMM */ + { + public static final PropertyInteger field_176579_a = PropertyInteger.func_177719_a("power", 0, 15); + private final int field_150068_a; +@@ -85,4 +88,16 @@ + { + return new BlockStateContainer(this, new IProperty[] {field_176579_a}); + } ++ ++ // RSMM ++ @Override ++ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ return state.func_177229_b(field_176579_a) > MIN_POWER; ++ } ++ ++ // RSMM ++ @Override ++ public int getPowerLevel(World world, BlockPos pos, IBlockState state) { ++ return state.func_177229_b(field_176579_a); ++ } + } diff --git a/patches/net/minecraft/block/BlockRailDetector.java.patch b/patches/net/minecraft/block/BlockRailDetector.java.patch index 0b52e661..e40b9f2c 100644 --- a/patches/net/minecraft/block/BlockRailDetector.java.patch +++ b/patches/net/minecraft/block/BlockRailDetector.java.patch @@ -1,6 +1,18 @@ --- ../src-base/minecraft/net/minecraft/block/BlockRailDetector.java +++ ../src-work/minecraft/net/minecraft/block/BlockRailDetector.java -@@ -220,6 +220,14 @@ +@@ -23,7 +23,10 @@ + import net.minecraft.world.IBlockAccess; + import net.minecraft.world.World; + +-public class BlockRailDetector extends BlockRailBase ++import redstone.multimeter.block.Meterable; ++import redstone.multimeter.block.PowerSource; ++ ++public class BlockRailDetector extends BlockRailBase implements Meterable /* RSMM */, PowerSource /* RSMM */ + { + public static final PropertyEnum field_176573_b = PropertyEnum.func_177708_a("shape", BlockRailBase.EnumRailDirection.class, new Predicate() + { +@@ -220,6 +223,14 @@ switch ((BlockRailBase.EnumRailDirection)p_185499_1_.func_177229_b(field_176573_b)) { @@ -15,3 +27,20 @@ case ASCENDING_EAST: return p_185499_1_.func_177226_a(field_176573_b, BlockRailBase.EnumRailDirection.ASCENDING_WEST); case ASCENDING_WEST: +@@ -352,4 +363,16 @@ + { + return new BlockStateContainer(this, new IProperty[] {field_176573_b, field_176574_M}); + } ++ ++ // RSMM ++ @Override ++ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ return state.func_177229_b(field_176574_M); ++ } ++ ++ // RSMM ++ @Override ++ public int getPowerLevel(World world, BlockPos pos, IBlockState state) { ++ return state.func_177229_b(field_176574_M) ? MAX_POWER : MIN_POWER; ++ } + } diff --git a/patches/net/minecraft/block/BlockRailPowered.java.patch b/patches/net/minecraft/block/BlockRailPowered.java.patch index 244845d2..3823d0de 100644 --- a/patches/net/minecraft/block/BlockRailPowered.java.patch +++ b/patches/net/minecraft/block/BlockRailPowered.java.patch @@ -1,15 +1,19 @@ --- ../src-base/minecraft/net/minecraft/block/BlockRailPowered.java +++ ../src-work/minecraft/net/minecraft/block/BlockRailPowered.java -@@ -12,6 +12,8 @@ +@@ -12,7 +12,11 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +-public class BlockRailPowered extends BlockRailBase ++import redstone.multimeter.block.MeterableBlock; ++ +import carpet.CarpetSettings; + - public class BlockRailPowered extends BlockRailBase ++public class BlockRailPowered extends BlockRailBase implements MeterableBlock /* RSMM */ { public static final PropertyEnum field_176568_b = PropertyEnum.func_177708_a("shape", BlockRailBase.EnumRailDirection.class, new Predicate() -@@ -32,7 +34,11 @@ + { +@@ -32,7 +36,11 @@ @SuppressWarnings("incomplete-switch") protected boolean func_176566_a(World p_176566_1_, BlockPos p_176566_2_, IBlockState p_176566_3_, boolean p_176566_4_, int p_176566_5_) { @@ -22,7 +26,16 @@ { return false; } -@@ -228,6 +234,14 @@ +@@ -184,6 +192,8 @@ + boolean flag = ((Boolean)p_189541_1_.func_177229_b(field_176569_M)).booleanValue(); + boolean flag1 = p_189541_2_.func_175640_z(p_189541_3_) || this.func_176566_a(p_189541_2_, p_189541_3_, p_189541_1_, true, 0) || this.func_176566_a(p_189541_2_, p_189541_3_, p_189541_1_, false, 0); + ++ logPowered(p_189541_2_, p_189541_3_, flag1); // RSMM ++ + if (flag1 != flag) + { + p_189541_2_.func_180501_a(p_189541_3_, p_189541_1_.func_177226_a(field_176569_M, Boolean.valueOf(flag1)), 3); +@@ -228,6 +238,14 @@ switch ((BlockRailBase.EnumRailDirection)p_185499_1_.func_177229_b(field_176568_b)) { @@ -37,3 +50,26 @@ case ASCENDING_EAST: return p_185499_1_.func_177226_a(field_176568_b, BlockRailBase.EnumRailDirection.ASCENDING_WEST); case ASCENDING_WEST: +@@ -360,4 +378,22 @@ + { + return new BlockStateContainer(this, new IProperty[] {field_176568_b, field_176569_M}); + } ++ ++ // RSMM ++ @Override ++ public boolean logPoweredOnBlockUpdate() { ++ return false; ++ } ++ ++ // RSMM ++ @Override ++ public boolean isPowered(World world, BlockPos pos, IBlockState state) { ++ return world.func_175640_z(pos) || func_176566_a(world, pos, state, true, 0) || func_176566_a(world, pos, state, false, 0); ++ } ++ ++ // RSMM ++ @Override ++ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ return state.func_177229_b(field_176569_M); ++ } + } diff --git a/patches/net/minecraft/block/BlockRedstoneComparator.java.patch b/patches/net/minecraft/block/BlockRedstoneComparator.java.patch index 254bfca4..5900a299 100644 --- a/patches/net/minecraft/block/BlockRedstoneComparator.java.patch +++ b/patches/net/minecraft/block/BlockRedstoneComparator.java.patch @@ -27,7 +27,16 @@ { return 2; } -@@ -206,8 +210,32 @@ +@@ -155,6 +159,8 @@ + } + } + ++ logPowered(p_176397_1_, p_176397_2_, i > MIN_POWER); // RSMM ++ + return i; + } + +@@ -206,8 +212,32 @@ { p_176398_1_.func_175654_a(p_176398_2_, this, 2, 0); } @@ -60,7 +69,7 @@ } private void func_176462_k(World p_176462_1_, BlockPos p_176462_2_, IBlockState p_176462_3_) -@@ -249,6 +277,22 @@ +@@ -249,6 +279,22 @@ } this.func_176462_k(p_180650_1_, p_180650_2_, p_180650_3_); @@ -83,3 +92,34 @@ } public void func_176213_c(World p_176213_1_, BlockPos p_176213_2_, IBlockState p_176213_3_) +@@ -319,6 +365,30 @@ + return this.func_176223_P().func_177226_a(field_185512_D, p_180642_8_.func_174811_aO().func_176734_d()).func_177226_a(field_176464_a, Boolean.valueOf(false)).func_177226_a(field_176463_b, BlockRedstoneComparator.Mode.COMPARE); + } + ++ // RSMM ++ @Override ++ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ return getPowerLevel(world, pos, state) > MIN_POWER; ++ } ++ ++ // RSMM ++ @Override ++ public boolean logPowerChangeOnStateChange() { ++ return false; ++ } ++ ++ // RSMM ++ @Override ++ public int getPowerLevel(World world, BlockPos pos, IBlockState state) { ++ TileEntity blockEntity = world.func_175625_s(pos); ++ ++ if (blockEntity instanceof TileEntityComparator) { ++ return ((TileEntityComparator)blockEntity).func_145996_a(); ++ } ++ ++ return MIN_POWER; ++ } ++ + public static enum Mode implements IStringSerializable + { + COMPARE("compare"), diff --git a/patches/net/minecraft/block/BlockRedstoneDiode.java.patch b/patches/net/minecraft/block/BlockRedstoneDiode.java.patch index fd443639..2d4cb5ae 100644 --- a/patches/net/minecraft/block/BlockRedstoneDiode.java.patch +++ b/patches/net/minecraft/block/BlockRedstoneDiode.java.patch @@ -1,6 +1,18 @@ --- ../src-base/minecraft/net/minecraft/block/BlockRedstoneDiode.java +++ ../src-work/minecraft/net/minecraft/block/BlockRedstoneDiode.java -@@ -64,7 +64,7 @@ +@@ -13,7 +13,10 @@ + import net.minecraft.world.IBlockAccess; + import net.minecraft.world.World; + +-public abstract class BlockRedstoneDiode extends BlockHorizontal ++import redstone.multimeter.block.MeterableBlock; ++import redstone.multimeter.block.PowerSource; ++ ++public abstract class BlockRedstoneDiode extends BlockHorizontal implements MeterableBlock /* RSMM */, PowerSource /* RSMM */ + { + protected static final AxisAlignedBB field_185548_c = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 1.0D, 0.125D, 1.0D); + protected final boolean field_149914_a; +@@ -64,7 +67,7 @@ if (!flag) { @@ -9,7 +21,7 @@ } } } -@@ -129,7 +129,7 @@ +@@ -129,7 +132,7 @@ i = -2; } @@ -18,7 +30,21 @@ } } } -@@ -276,12 +276,12 @@ +@@ -139,9 +142,12 @@ + return false; + } + ++ // RSMM - capture return value + protected boolean func_176404_e(World p_176404_1_, BlockPos p_176404_2_, IBlockState p_176404_3_) + { +- return this.func_176397_f(p_176404_1_, p_176404_2_, p_176404_3_) > 0; ++ boolean powered = this.func_176397_f(p_176404_1_, p_176404_2_, p_176404_3_) > 0; ++ logPowered(p_176404_1_, p_176404_2_, powered); // RSMM ++ return powered; + } + + protected int func_176397_f(World p_176397_1_, BlockPos p_176397_2_, IBlockState p_176397_3_) +@@ -276,12 +282,12 @@ } } @@ -34,3 +60,26 @@ protected abstract IBlockState func_180674_e(IBlockState p_180674_1_); +@@ -296,4 +302,22 @@ + { + return p_193383_4_ == EnumFacing.DOWN ? BlockFaceShape.SOLID : BlockFaceShape.UNDEFINED; + } ++ ++ // RSMM ++ @Override ++ public boolean logPoweredOnBlockUpdate() { ++ return false; ++ } ++ ++ // RSMM ++ @Override ++ public boolean isPowered(World world, BlockPos pos, IBlockState state) { ++ return func_176404_e(world, pos, state); ++ } ++ ++ // RSMM ++ @Override ++ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ return field_149914_a; ++ } + } diff --git a/patches/net/minecraft/block/BlockRedstoneLight.java.patch b/patches/net/minecraft/block/BlockRedstoneLight.java.patch new file mode 100644 index 00000000..570cf672 --- /dev/null +++ b/patches/net/minecraft/block/BlockRedstoneLight.java.patch @@ -0,0 +1,33 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockRedstoneLight.java ++++ ../src-work/minecraft/net/minecraft/block/BlockRedstoneLight.java +@@ -9,7 +9,9 @@ + import net.minecraft.util.math.BlockPos; + import net.minecraft.world.World; + +-public class BlockRedstoneLight extends Block ++import redstone.multimeter.block.MeterableBlock; ++ ++public class BlockRedstoneLight extends Block implements MeterableBlock /* RSMM */ + { + private final boolean field_150171_a; + +@@ -58,6 +60,8 @@ + { + if (!p_180650_1_.field_72995_K) + { ++ logPowered(p_180650_1_, p_180650_2_, p_180650_3_); // RSMM ++ + if (this.field_150171_a && !p_180650_1_.func_175640_z(p_180650_2_)) + { + p_180650_1_.func_180501_a(p_180650_2_, Blocks.field_150379_bu.func_176223_P(), 2); +@@ -79,4 +83,10 @@ + { + return new ItemStack(Blocks.field_150379_bu); + } ++ ++ // RSMM ++ @Override ++ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ return field_150171_a; ++ } + } diff --git a/patches/net/minecraft/block/BlockRedstoneOre.java.patch b/patches/net/minecraft/block/BlockRedstoneOre.java.patch new file mode 100644 index 00000000..7d1cc2d4 --- /dev/null +++ b/patches/net/minecraft/block/BlockRedstoneOre.java.patch @@ -0,0 +1,24 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockRedstoneOre.java ++++ ../src-work/minecraft/net/minecraft/block/BlockRedstoneOre.java +@@ -15,7 +15,9 @@ + import net.minecraft.util.math.BlockPos; + import net.minecraft.world.World; + +-public class BlockRedstoneOre extends Block ++import redstone.multimeter.block.Meterable; ++ ++public class BlockRedstoneOre extends Block implements Meterable /* RSMM */ + { + private final boolean field_150187_a; + +@@ -155,4 +157,10 @@ + { + return new ItemStack(Item.func_150898_a(Blocks.field_150450_ax), 1, this.func_180651_a(p_185473_3_)); + } ++ ++ // RSMM ++ @Override ++ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ return field_150187_a; ++ } + } diff --git a/patches/net/minecraft/block/BlockRedstoneRepeater.java.patch b/patches/net/minecraft/block/BlockRedstoneRepeater.java.patch index bb7f8993..2ab6249d 100644 --- a/patches/net/minecraft/block/BlockRedstoneRepeater.java.patch +++ b/patches/net/minecraft/block/BlockRedstoneRepeater.java.patch @@ -1,15 +1,17 @@ --- ../src-base/minecraft/net/minecraft/block/BlockRedstoneRepeater.java +++ ../src-work/minecraft/net/minecraft/block/BlockRedstoneRepeater.java -@@ -20,6 +20,8 @@ +@@ -19,7 +19,10 @@ + import net.minecraft.util.text.translation.I18n; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; ++import net.minecraft.world.WorldServer; +import carpet.CarpetSettings; + public class BlockRedstoneRepeater extends BlockRedstoneDiode { public static final PropertyBool field_176411_a = PropertyBool.func_177716_a("locked"); -@@ -64,9 +66,20 @@ +@@ -64,9 +67,20 @@ } } @@ -32,3 +34,32 @@ } protected IBlockState func_180674_e(IBlockState p_180674_1_) +@@ -95,9 +109,16 @@ + return new ItemStack(Items.field_151107_aW); + } + ++ // RSMM - capture return value + public boolean func_176405_b(IBlockAccess p_176405_1_, BlockPos p_176405_2_, IBlockState p_176405_3_) + { +- return this.func_176407_c(p_176405_1_, p_176405_2_, p_176405_3_) > 0; ++ boolean locked = this.func_176407_c(p_176405_1_, p_176405_2_, p_176405_3_) > 0; ++ // RSMM start ++ if (locked && p_176405_1_ instanceof WorldServer) { ++ logPowered((WorldServer)p_176405_1_, p_176405_2_, p_176405_3_); ++ } ++ // RSMM end ++ return locked; + } + + protected boolean func_185545_A(IBlockState p_185545_1_) +@@ -128,4 +149,10 @@ + { + return new BlockStateContainer(this, new IProperty[] {field_185512_D, field_176410_b, field_176411_a}); + } ++ ++ // RSMM ++ @Override ++ public int getPowerLevel(World world, BlockPos pos, IBlockState state) { ++ return field_149914_a ? MAX_POWER : MIN_POWER; ++ } + } diff --git a/patches/net/minecraft/block/BlockRedstoneTorch.java.patch b/patches/net/minecraft/block/BlockRedstoneTorch.java.patch index e6af38eb..9ec186d8 100644 --- a/patches/net/minecraft/block/BlockRedstoneTorch.java.patch +++ b/patches/net/minecraft/block/BlockRedstoneTorch.java.patch @@ -1,15 +1,35 @@ --- ../src-base/minecraft/net/minecraft/block/BlockRedstoneTorch.java +++ ../src-work/minecraft/net/minecraft/block/BlockRedstoneTorch.java -@@ -19,6 +19,8 @@ +@@ -19,7 +19,12 @@ import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; +-public class BlockRedstoneTorch extends BlockTorch ++import redstone.multimeter.block.MeterableBlock; ++import redstone.multimeter.block.PowerSource; ++ +import carpet.CarpetSettings; + - public class BlockRedstoneTorch extends BlockTorch ++public class BlockRedstoneTorch extends BlockTorch implements MeterableBlock /* RSMM */, PowerSource /* RSMM */ { private static final Map> field_150112_b = Maps.>newHashMap(); -@@ -149,7 +151,7 @@ + private final boolean field_150113_a; +@@ -97,10 +102,13 @@ + return this.field_150113_a && p_180656_1_.func_177229_b(field_176596_a) != p_180656_4_ ? 15 : 0; + } + ++ // RSMM - capture return value + private boolean func_176597_g(World p_176597_1_, BlockPos p_176597_2_, IBlockState p_176597_3_) + { + EnumFacing enumfacing = ((EnumFacing)p_176597_3_.func_177229_b(field_176596_a)).func_176734_d(); +- return p_176597_1_.func_175709_b(p_176597_2_.func_177972_a(enumfacing), enumfacing); ++ boolean powered = p_176597_1_.func_175709_b(p_176597_2_.func_177972_a(enumfacing), enumfacing); ++ logPowered(p_176597_1_, p_176597_2_, powered); // RSMM ++ return powered; + } + + public void func_180645_a(World p_180645_1_, BlockPos p_180645_2_, IBlockState p_180645_3_, Random p_180645_4_) +@@ -149,7 +157,7 @@ { if (!this.func_176592_e(p_189540_2_, p_189540_3_, p_189540_1_)) { @@ -18,3 +38,34 @@ { p_189540_2_.func_175684_a(p_189540_3_, this, this.func_149738_a(p_189540_2_)); } +@@ -181,6 +189,30 @@ + return p_149667_1_ == Blocks.field_150437_az || p_149667_1_ == Blocks.field_150429_aA; + } + ++ // RSMM ++ @Override ++ public boolean logPoweredOnBlockUpdate() { ++ return false; ++ } ++ ++ // RSMM ++ @Override ++ public boolean isPowered(World world, BlockPos pos, IBlockState state) { ++ return func_176597_g(world, pos, state); ++ } ++ ++ // RSMM ++ @Override ++ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ return field_150113_a; ++ } ++ ++ // RSMM ++ @Override ++ public int getPowerLevel(World world, BlockPos pos, IBlockState state) { ++ return field_150113_a ? MAX_POWER : MIN_POWER; ++ } ++ + static class Toggle + { + BlockPos field_180111_a; diff --git a/patches/net/minecraft/block/BlockRedstoneWire.java.patch b/patches/net/minecraft/block/BlockRedstoneWire.java.patch index 7c026b3e..1ffd366f 100644 --- a/patches/net/minecraft/block/BlockRedstoneWire.java.patch +++ b/patches/net/minecraft/block/BlockRedstoneWire.java.patch @@ -7,18 +7,23 @@ import com.google.common.collect.Lists; import com.google.common.collect.Sets; import java.util.EnumSet; -@@ -27,6 +28,10 @@ +@@ -27,7 +28,14 @@ import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; +-public class BlockRedstoneWire extends Block ++import redstone.multimeter.block.MeterableBlock; ++import redstone.multimeter.block.PowerSource; ++ +import carpet.CarpetSettings; +import carpet.helpers.RedstoneWireTurbo; +import java.util.Collections; + - public class BlockRedstoneWire extends Block ++public class BlockRedstoneWire extends Block implements MeterableBlock /* RSMM */, PowerSource /* RSMM */ { public static final PropertyEnum field_176348_a = PropertyEnum.func_177709_a("north", BlockRedstoneWire.EnumAttachPosition.class); -@@ -35,9 +40,11 @@ + public static final PropertyEnum field_176347_b = PropertyEnum.func_177709_a("east", BlockRedstoneWire.EnumAttachPosition.class); +@@ -35,9 +43,11 @@ public static final PropertyEnum field_176350_N = PropertyEnum.func_177709_a("west", BlockRedstoneWire.EnumAttachPosition.class); public static final PropertyInteger field_176351_O = PropertyInteger.func_177719_a("power", 0, 15); protected static final AxisAlignedBB[] field_185700_f = new AxisAlignedBB[] {new AxisAlignedBB(0.1875D, 0.0D, 0.1875D, 0.8125D, 0.0625D, 0.8125D), new AxisAlignedBB(0.1875D, 0.0D, 0.1875D, 0.8125D, 0.0625D, 1.0D), new AxisAlignedBB(0.0D, 0.0D, 0.1875D, 0.8125D, 0.0625D, 0.8125D), new AxisAlignedBB(0.0D, 0.0D, 0.1875D, 0.8125D, 0.0625D, 1.0D), new AxisAlignedBB(0.1875D, 0.0D, 0.0D, 0.8125D, 0.0625D, 0.8125D), new AxisAlignedBB(0.1875D, 0.0D, 0.0D, 0.8125D, 0.0625D, 1.0D), new AxisAlignedBB(0.0D, 0.0D, 0.0D, 0.8125D, 0.0625D, 0.8125D), new AxisAlignedBB(0.0D, 0.0D, 0.0D, 0.8125D, 0.0625D, 1.0D), new AxisAlignedBB(0.1875D, 0.0D, 0.1875D, 1.0D, 0.0625D, 0.8125D), new AxisAlignedBB(0.1875D, 0.0D, 0.1875D, 1.0D, 0.0625D, 1.0D), new AxisAlignedBB(0.0D, 0.0D, 0.1875D, 1.0D, 0.0625D, 0.8125D), new AxisAlignedBB(0.0D, 0.0D, 0.1875D, 1.0D, 0.0625D, 1.0D), new AxisAlignedBB(0.1875D, 0.0D, 0.0D, 1.0D, 0.0625D, 0.8125D), new AxisAlignedBB(0.1875D, 0.0D, 0.0D, 1.0D, 0.0625D, 1.0D), new AxisAlignedBB(0.0D, 0.0D, 0.0D, 1.0D, 0.0625D, 0.8125D), new AxisAlignedBB(0.0D, 0.0D, 0.0D, 1.0D, 0.0625D, 1.0D)}; @@ -31,7 +36,7 @@ public BlockRedstoneWire() { super(Material.field_151594_q); -@@ -142,21 +149,26 @@ +@@ -142,21 +152,26 @@ return p_176196_1_.func_180495_p(p_176196_2_.func_177977_b()).func_185896_q() || p_176196_1_.func_180495_p(p_176196_2_.func_177977_b()).func_177230_c() == Blocks.field_150426_aN; } @@ -63,7 +68,7 @@ { IBlockState iblockstate = p_176345_4_; int i = ((Integer)p_176345_4_.func_177229_b(field_176351_O)).intValue(); -@@ -166,54 +178,65 @@ +@@ -166,53 +181,66 @@ int k = p_176345_1_.func_175687_A(p_176345_2_); this.field_150181_a = true; @@ -157,11 +162,11 @@ - { - j = k; - } -- ++ logPowered(p_176345_1_, p_176345_2_, j > MIN_POWER); // RSMM + if (i != j) { - p_176345_4_ = p_176345_4_.func_177226_a(field_176351_O, Integer.valueOf(j)); -@@ -223,11 +246,15 @@ +@@ -223,11 +251,15 @@ p_176345_1_.func_180501_a(p_176345_2_, p_176345_4_, 2); } @@ -181,7 +186,7 @@ } } -@@ -251,7 +278,7 @@ +@@ -251,7 +283,7 @@ { if (!p_176213_1_.field_72995_K) { @@ -190,7 +195,7 @@ for (EnumFacing enumfacing : EnumFacing.Plane.VERTICAL) { -@@ -290,7 +317,7 @@ +@@ -290,7 +322,7 @@ p_180663_1_.func_175685_c(p_180663_2_.func_177972_a(enumfacing), this, false); } @@ -199,7 +204,7 @@ for (EnumFacing enumfacing1 : EnumFacing.Plane.HORIZONTAL) { -@@ -332,7 +359,7 @@ +@@ -332,7 +364,7 @@ { if (this.func_176196_c(p_189540_2_, p_189540_3_)) { @@ -208,7 +213,7 @@ } else { -@@ -354,6 +381,12 @@ +@@ -354,6 +386,12 @@ public int func_180656_a(IBlockState p_180656_1_, IBlockAccess p_180656_2_, BlockPos p_180656_3_, EnumFacing p_180656_4_) { @@ -221,7 +226,7 @@ if (!this.field_150181_a) { return 0; -@@ -361,6 +394,8 @@ +@@ -361,6 +399,8 @@ else { int i = ((Integer)p_180656_1_.func_177229_b(field_176351_O)).intValue(); @@ -230,7 +235,7 @@ if (i == 0) { -@@ -398,7 +433,8 @@ +@@ -398,7 +438,8 @@ } } @@ -240,7 +245,7 @@ { BlockPos blockpos = p_176339_2_.func_177972_a(p_176339_3_); IBlockState iblockstate = p_176339_1_.func_180495_p(blockpos); -@@ -435,6 +471,12 @@ +@@ -435,6 +476,12 @@ protected static boolean func_176343_a(IBlockState p_176343_0_, @Nullable EnumFacing p_176343_1_) { @@ -253,3 +258,37 @@ Block block = p_176343_0_.func_177230_c(); if (block == Blocks.field_150488_af) +@@ -514,6 +561,33 @@ + return BlockFaceShape.UNDEFINED; + } + ++ // RSMM ++ @Override ++ public boolean logPoweredOnBlockUpdate() { ++ return false; ++ } ++ ++ // RSMM ++ // This method is only called on blocks where 'logPoweredOnBlockUpdate' ++ // returns 'true', so it does not really matter that a potentially ++ // incorrect value is returned. ++ @Override ++ public boolean isPowered(World world, BlockPos pos, IBlockState state) { ++ return state.func_177229_b(field_176351_O) > MIN_POWER; ++ } ++ ++ // RSMM ++ @Override ++ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ return state.func_177229_b(field_176351_O) > MIN_POWER; ++ } ++ ++ // RSMM ++ @Override ++ public int getPowerLevel(World world, BlockPos pos, IBlockState state) { ++ return state.func_177229_b(field_176351_O); ++ } ++ + static enum EnumAttachPosition implements IStringSerializable + { + UP("up"), diff --git a/patches/net/minecraft/block/BlockTrapDoor.java.patch b/patches/net/minecraft/block/BlockTrapDoor.java.patch new file mode 100644 index 00000000..99c33c5d --- /dev/null +++ b/patches/net/minecraft/block/BlockTrapDoor.java.patch @@ -0,0 +1,41 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockTrapDoor.java ++++ ../src-work/minecraft/net/minecraft/block/BlockTrapDoor.java +@@ -22,7 +22,9 @@ + import net.minecraft.world.IBlockAccess; + import net.minecraft.world.World; + +-public class BlockTrapDoor extends Block ++import redstone.multimeter.block.MeterableBlock; ++ ++public class BlockTrapDoor extends Block implements MeterableBlock /* RSMM */ + { + public static final PropertyDirection field_176284_a = BlockHorizontal.field_185512_D; + public static final PropertyBool field_176283_b = PropertyBool.func_177716_a("open"); +@@ -125,6 +127,8 @@ + { + boolean flag = p_189540_2_.func_175640_z(p_189540_3_); + ++ logPowered(p_189540_2_, p_189540_3_, flag); // RSMM ++ + if (flag || p_189540_4_.func_176223_P().func_185897_m()) + { + boolean flag1 = ((Boolean)p_189540_1_.func_177229_b(field_176283_b)).booleanValue(); +@@ -241,6 +245,18 @@ + return (p_193383_4_ == EnumFacing.UP && p_193383_2_.func_177229_b(field_176285_M) == BlockTrapDoor.DoorHalf.TOP || p_193383_4_ == EnumFacing.DOWN && p_193383_2_.func_177229_b(field_176285_M) == BlockTrapDoor.DoorHalf.BOTTOM) && !((Boolean)p_193383_2_.func_177229_b(field_176283_b)).booleanValue() ? BlockFaceShape.SOLID : BlockFaceShape.UNDEFINED; + } + ++ // RSMM ++ @Override ++ public boolean logPoweredOnBlockUpdate() { ++ return false; ++ } ++ ++ // RSMM ++ @Override ++ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ return state.func_177229_b(field_176283_b); ++ } ++ + public static enum DoorHalf implements IStringSerializable + { + TOP("top"), diff --git a/patches/net/minecraft/block/BlockTripWire.java.patch b/patches/net/minecraft/block/BlockTripWire.java.patch new file mode 100644 index 00000000..d4e1bc8d --- /dev/null +++ b/patches/net/minecraft/block/BlockTripWire.java.patch @@ -0,0 +1,24 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockTripWire.java ++++ ../src-work/minecraft/net/minecraft/block/BlockTripWire.java +@@ -23,7 +23,9 @@ + import net.minecraft.world.IBlockAccess; + import net.minecraft.world.World; + +-public class BlockTripWire extends Block ++import redstone.multimeter.block.Meterable; ++ ++public class BlockTripWire extends Block implements Meterable /* RSMM */ + { + public static final PropertyBool field_176293_a = PropertyBool.func_177716_a("powered"); + public static final PropertyBool field_176294_M = PropertyBool.func_177716_a("attached"); +@@ -266,4 +268,10 @@ + { + return BlockFaceShape.UNDEFINED; + } ++ ++ // RSMM ++ @Override ++ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ return state.func_177229_b(field_176293_a); ++ } + } diff --git a/patches/net/minecraft/block/BlockTripWireHook.java.patch b/patches/net/minecraft/block/BlockTripWireHook.java.patch new file mode 100644 index 00000000..eb3ef08e --- /dev/null +++ b/patches/net/minecraft/block/BlockTripWireHook.java.patch @@ -0,0 +1,31 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockTripWireHook.java ++++ ../src-work/minecraft/net/minecraft/block/BlockTripWireHook.java +@@ -25,7 +25,10 @@ + import net.minecraft.world.IBlockAccess; + import net.minecraft.world.World; + +-public class BlockTripWireHook extends Block ++import redstone.multimeter.block.Meterable; ++import redstone.multimeter.block.PowerSource; ++ ++public class BlockTripWireHook extends Block implements Meterable /* RSMM */, PowerSource /* RSMM */ + { + public static final PropertyDirection field_176264_a = BlockHorizontal.field_185512_D; + public static final PropertyBool field_176263_b = PropertyBool.func_177716_a("powered"); +@@ -353,4 +356,16 @@ + { + return BlockFaceShape.UNDEFINED; + } ++ ++ // RSMM ++ @Override ++ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ return state.func_177229_b(field_176263_b); ++ } ++ ++ // RSMM ++ @Override ++ public int getPowerLevel(World world, BlockPos pos, IBlockState state) { ++ return state.func_177229_b(field_176263_b) ? MAX_POWER : MIN_POWER; ++ } + } diff --git a/patches/net/minecraft/network/NetHandlerPlayServer.java.patch b/patches/net/minecraft/network/NetHandlerPlayServer.java.patch index f9a06fc1..589fef07 100644 --- a/patches/net/minecraft/network/NetHandlerPlayServer.java.patch +++ b/patches/net/minecraft/network/NetHandlerPlayServer.java.patch @@ -15,7 +15,7 @@ import net.minecraft.server.MinecraftServer; import net.minecraft.tileentity.CommandBlockBaseLogic; import net.minecraft.tileentity.TileEntity; -@@ -121,15 +123,24 @@ +@@ -121,15 +123,26 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -26,6 +26,8 @@ +import net.minecraft.world.gen.structure.template.Template; +import net.minecraft.server.management.PlayerInteractionManager; + ++import redstone.multimeter.common.network.PacketManager; ++ +import static carpet.commands.CommandGMS.setPlayerToSurvival; + public class NetHandlerPlayServer implements INetHandlerPlayServer, ITickable @@ -48,7 +50,7 @@ private long field_194404_h; private int field_147374_l; private int field_147375_m; -@@ -257,9 +268,19 @@ +@@ -257,9 +270,19 @@ { this.func_194028_b(new TextComponentTranslation("multiplayer.disconnect.idling", new Object[0])); } @@ -69,7 +71,7 @@ { this.field_184349_l = this.field_147369_b.field_70165_t; this.field_184350_m = this.field_147369_b.field_70163_u; -@@ -297,6 +318,11 @@ +@@ -297,6 +320,11 @@ { PacketThreadUtil.func_180031_a(p_147358_1_, this, this.field_147369_b.func_71121_q()); this.field_147369_b.func_110430_a(p_147358_1_.func_149620_c(), p_147358_1_.func_192620_b(), p_147358_1_.func_149618_e(), p_147358_1_.func_149617_f()); @@ -81,7 +83,7 @@ } private static boolean func_183006_b(CPacketPlayer p_183006_0_) -@@ -500,6 +526,10 @@ +@@ -500,6 +528,10 @@ double d10 = this.field_147369_b.field_70159_w * this.field_147369_b.field_70159_w + this.field_147369_b.field_70181_x * this.field_147369_b.field_70181_x + this.field_147369_b.field_70179_y * this.field_147369_b.field_70179_y; double d11 = d7 * d7 + d8 * d8 + d9 * d9; @@ -92,7 +94,7 @@ if (this.field_147369_b.func_70608_bn()) { if (d11 > 1.0D) -@@ -518,7 +548,7 @@ +@@ -518,7 +550,7 @@ i = 1; } @@ -101,7 +103,7 @@ { float f2 = this.field_147369_b.func_184613_cA() ? 300.0F : 100.0F; -@@ -564,7 +594,9 @@ +@@ -564,7 +596,9 @@ this.field_147369_b.func_70080_a(d4, d5, d6, f, f1); this.field_147369_b.func_71000_j(this.field_147369_b.field_70165_t - d0, this.field_147369_b.field_70163_u - d1, this.field_147369_b.field_70161_v - d2); @@ -112,7 +114,7 @@ { boolean flag1 = worldserver.func_184144_a(this.field_147369_b, this.field_147369_b.func_174813_aQ().func_186664_h(0.0625D)).isEmpty(); -@@ -627,6 +659,8 @@ +@@ -627,6 +661,8 @@ public void func_147345_a(CPacketPlayerDigging p_147345_1_) { @@ -121,7 +123,7 @@ PacketThreadUtil.func_180031_a(p_147345_1_, this, this.field_147369_b.func_71121_q()); WorldServer worldserver = this.field_147367_d.func_71218_a(this.field_147369_b.field_71093_bK); BlockPos blockpos = p_147345_1_.func_179715_a(); -@@ -731,7 +765,10 @@ +@@ -731,7 +767,10 @@ { if (this.field_184362_y == null && this.field_147369_b.func_70092_e((double)blockpos.func_177958_n() + 0.5D, (double)blockpos.func_177956_o() + 0.5D, (double)blockpos.func_177952_p() + 0.5D) < 64.0D && !this.field_147367_d.func_175579_a(worldserver, blockpos, this.field_147369_b) && worldserver.func_175723_af().func_177746_a(blockpos)) { @@ -132,7 +134,7 @@ } } else -@@ -755,12 +792,16 @@ +@@ -755,12 +794,16 @@ if (!itemstack.func_190926_b()) { @@ -149,7 +151,7 @@ PacketThreadUtil.func_180031_a(p_175088_1_, this, this.field_147369_b.func_71121_q()); if (this.field_147369_b.func_175149_v()) -@@ -796,13 +837,13 @@ +@@ -796,13 +839,13 @@ this.field_147369_b.field_71093_bK = entity.field_71093_bK; this.func_147359_a(new SPacketRespawn(this.field_147369_b.field_71093_bK, worldserver1.func_175659_aa(), worldserver1.func_72912_H().func_76067_t(), this.field_147369_b.field_71134_c.func_73081_b())); this.field_147367_d.func_184103_al().func_187243_f(this.field_147369_b); @@ -165,7 +167,7 @@ worldserver2.func_72838_d(this.field_147369_b); worldserver2.func_72866_a(this.field_147369_b, false); } -@@ -841,6 +882,11 @@ +@@ -841,6 +884,11 @@ textcomponenttranslation.func_150256_b().func_150238_a(TextFormatting.YELLOW); this.field_147367_d.func_184103_al().func_148539_a(textcomponenttranslation); this.field_147369_b.func_71123_m(); @@ -177,7 +179,7 @@ this.field_147367_d.func_184103_al().func_72367_e(this.field_147369_b); if (this.field_147367_d.func_71264_H() && this.field_147369_b.func_70005_c_().equals(this.field_147367_d.func_71214_G())) -@@ -1019,13 +1065,15 @@ +@@ -1019,13 +1067,15 @@ break; case START_FALL_FLYING: @@ -198,7 +200,7 @@ } } else -@@ -1147,11 +1195,15 @@ +@@ -1147,11 +1197,15 @@ } else { @@ -214,7 +216,7 @@ this.field_147369_b.field_71137_h = true; this.field_147369_b.field_71070_bA.func_75142_b(); this.field_147369_b.func_71113_k(); -@@ -1355,7 +1407,27 @@ +@@ -1355,8 +1409,33 @@ PacketThreadUtil.func_180031_a(p_147349_1_, this, this.field_147369_b.func_71121_q()); String s = p_147349_1_.func_149559_c(); @@ -239,11 +241,17 @@ + } + PlayerInteractionManager.activateInstantMine = true; + } -+ else if ("MC|BEdit".equals(s)) ++ // RSMM packet handling ++ else if (PacketManager.getPacketChannelId().equals(s)) { ++ CarpetServer.rsmmServer.getPacketHandler().onPacketReceived(p_147349_1_.func_180760_b(), field_147369_b); ++ } ++ else if ("MC|BEdit".equals(s)) ++ { PacketBuffer packetbuffer = p_147349_1_.func_180760_b(); -@@ -1666,13 +1738,14 @@ + try +@@ -1666,13 +1745,14 @@ String s8 = packetbuffer5.func_150789_c(32); tileentitystructure.func_184405_a(TileEntityStructure.Mode.valueOf(s8)); tileentitystructure.func_184404_a(packetbuffer5.func_150789_c(64)); @@ -264,7 +272,7 @@ tileentitystructure.func_184409_c(new BlockPos(l2, i3, j)); String s2 = packetbuffer5.func_150789_c(32); tileentitystructure.func_184411_a(Mirror.valueOf(s2)); -@@ -1709,6 +1782,17 @@ +@@ -1709,6 +1789,17 @@ } else { @@ -282,7 +290,7 @@ this.field_147369_b.func_146105_b(new TextComponentTranslation("structure_block.load_prepare", new Object[] {s4}), false); } } -@@ -1750,5 +1834,9 @@ +@@ -1750,5 +1841,9 @@ field_147370_c.error("Couldn't pick item", (Throwable)exception); } } diff --git a/patches/net/minecraft/server/MinecraftServer.java.patch b/patches/net/minecraft/server/MinecraftServer.java.patch index 00660e02..ba816d3e 100644 --- a/patches/net/minecraft/server/MinecraftServer.java.patch +++ b/patches/net/minecraft/server/MinecraftServer.java.patch @@ -9,7 +9,15 @@ import com.google.common.collect.Lists; import com.google.common.collect.Queues; import com.google.common.util.concurrent.Futures; -@@ -86,6 +89,15 @@ +@@ -82,10 +85,23 @@ + import net.minecraft.world.storage.ISaveFormat; + import net.minecraft.world.storage.ISaveHandler; + import net.minecraft.world.storage.WorldInfo; ++ ++import redstone.multimeter.common.TickTask; ++import redstone.multimeter.helper.WorldHelper; ++ + import org.apache.commons.lang3.Validate; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -25,7 +33,7 @@ public abstract class MinecraftServer implements ICommandSender, Runnable, IThreadListener, ISnooperInfo { private static final Logger field_147145_h = LogManager.getLogger(); -@@ -144,6 +156,7 @@ +@@ -144,6 +160,7 @@ public MinecraftServer(File p_i47054_1_, Proxy p_i47054_2_, DataFixer p_i47054_3_, YggdrasilAuthenticationService p_i47054_4_, MinecraftSessionService p_i47054_5_, GameProfileRepository p_i47054_6_, PlayerProfileCache p_i47054_7_) { @@ -33,7 +41,7 @@ this.field_110456_c = p_i47054_2_; this.field_152364_T = p_i47054_4_; this.field_147143_S = p_i47054_5_; -@@ -273,7 +286,9 @@ +@@ -273,7 +290,9 @@ this.field_71318_t.func_72364_a(this.field_71305_c); this.func_147139_a(this.func_147135_j()); @@ -43,7 +51,7 @@ } protected void func_71222_d() -@@ -285,25 +300,32 @@ +@@ -285,25 +304,32 @@ int i1 = 0; this.func_71192_d("menu.generatingTerrain"); int j1 = 0; @@ -91,7 +99,7 @@ } } -@@ -341,7 +363,7 @@ +@@ -341,7 +367,7 @@ public abstract boolean func_183002_r(); @@ -100,7 +108,7 @@ { this.field_71302_d = p_71216_1_; this.field_71303_e = p_71216_2_; -@@ -375,6 +397,7 @@ +@@ -375,6 +401,7 @@ } } } @@ -108,7 +116,7 @@ } protected void func_71260_j() -@@ -389,6 +412,8 @@ +@@ -389,6 +416,8 @@ if (this.field_71318_t != null) { field_147145_h.info("Saving players"); @@ -117,7 +125,7 @@ this.field_71318_t.func_72389_g(); this.field_71318_t.func_72392_r(); } -@@ -450,18 +475,33 @@ +@@ -450,18 +479,33 @@ { this.field_175591_ab = func_130071_aq(); long i = 0L; @@ -153,7 +161,7 @@ j = 2000L; this.field_71299_R = this.field_175591_ab; } -@@ -474,6 +514,7 @@ +@@ -474,6 +518,7 @@ i += j; this.field_175591_ab = k; @@ -161,7 +169,7 @@ if (this.field_71305_c[0].func_73056_e()) { -@@ -482,14 +523,33 @@ +@@ -482,14 +527,33 @@ } else { @@ -198,7 +206,7 @@ this.field_71296_Q = true; } } -@@ -594,6 +654,12 @@ +@@ -594,6 +658,15 @@ long i = System.nanoTime(); ++this.field_71315_w; @@ -207,11 +215,14 @@ + { + CarpetProfiler.start_tick_profiling(); + } ++ ++ CarpetServer.rsmmServer.tickStart(); // RSMM ++ WorldHelper.startTickTask(TickTask.TICK); // RSMM + if (this.field_71295_T) { this.field_71295_T = false; -@@ -620,13 +686,21 @@ +@@ -620,13 +693,23 @@ this.field_147147_p.func_151318_b().func_151330_a(agameprofile); } @@ -220,6 +231,7 @@ { + CarpetProfiler.start_section(null, "Autosave"); this.field_71304_b.func_76320_a("save"); ++ WorldHelper.startTickTask(TickTask.AUTOSAVE); // RSMM + this.field_71318_t.storeFakePlayerData(); this.field_71318_t.func_72389_g(); + if(carpet.carpetclient.CarpetClientChunkLogger.logger.enabled) @@ -227,17 +239,21 @@ this.func_71267_a(true); + carpet.carpetclient.CarpetClientChunkLogger.resetReason(); this.field_71304_b.func_76319_b(); ++ WorldHelper.endTickTask(); // RSMM + CarpetProfiler.end_current_section(); } + LagSpikeHelper.processLagSpikes(null, LagSpikeHelper.TickPhase.AUTOSAVE, LagSpikeHelper.PrePostSubPhase.POST); this.field_71304_b.func_76320_a("tallying"); this.field_71311_j[this.field_71315_w % 100] = System.nanoTime() - i; -@@ -645,12 +719,30 @@ +@@ -645,12 +728,34 @@ this.field_71304_b.func_76319_b(); this.field_71304_b.func_76319_b(); + ++ WorldHelper.endTickTask(); // RSMM ++ CarpetServer.rsmmServer.tickEnd(); // RSMM ++ + // ChunkLogger - 0x-CARPET + if(CarpetClientChunkLogger.logger.enabled) { + CarpetClientChunkLogger.logger.sendAll(); @@ -259,20 +275,24 @@ { + LagSpikeHelper.processLagSpikes(null, LagSpikeHelper.TickPhase.TICK, LagSpikeHelper.PrePostSubPhase.PRE); this.field_71304_b.func_76320_a("jobs"); ++ WorldHelper.startTickTask(TickTask.PACKETS); // RSMM + LagSpikeHelper.processLagSpikes(null, LagSpikeHelper.TickPhase.PLAYER, LagSpikeHelper.PrePostSubPhase.PRE); synchronized (this.field_175589_i) { while (!this.field_175589_i.isEmpty()) -@@ -658,6 +750,7 @@ +@@ -658,8 +763,10 @@ Util.func_181617_a(this.field_175589_i.poll(), field_147145_h); } } + LagSpikeHelper.processLagSpikes(null, LagSpikeHelper.TickPhase.PLAYER, LagSpikeHelper.PrePostSubPhase.POST); this.field_71304_b.func_76318_c("levels"); ++ WorldHelper.swapTickTask(TickTask.LEVELS); // RSMM -@@ -672,6 +765,7 @@ + for (int j = 0; j < this.field_71305_c.length; ++j) + { +@@ -672,6 +779,7 @@ { return worldserver.func_72912_H().func_76065_j(); }); @@ -280,7 +300,7 @@ if (this.field_71315_w % 20 == 0) { -@@ -686,27 +780,44 @@ +@@ -686,27 +794,46 @@ { worldserver.func_72835_b(); } @@ -302,7 +322,9 @@ try { ++ WorldHelper.startTickTask(TickTask.ENTITIES); // RSMM worldserver.func_72939_s(); ++ WorldHelper.endTickTask(); // RSMM } + catch (ThrowableSuppression e) + { @@ -327,29 +349,37 @@ this.field_71304_b.func_76319_b(); this.field_71304_b.func_76319_b(); } -@@ -714,10 +825,12 @@ +@@ -714,13 +841,19 @@ this.field_71312_k[j][this.field_71315_w % 100] = System.nanoTime() - i; } + CarpetProfiler.start_section(null, "Network"); this.field_71304_b.func_76318_c("connection"); ++ WorldHelper.swapTickTask(TickTask.CONNECTIONS); // RSMM this.func_147137_ag().func_151269_c(); this.field_71304_b.func_76318_c("players"); ++ WorldHelper.swapTickTask(TickTask.PLAYER_PING); // RSMM this.field_71318_t.func_72374_b(); + CarpetProfiler.end_current_section(); this.field_71304_b.func_76318_c("commandFunctions"); ++ WorldHelper.swapTickTask(TickTask.COMMAND_FUNCTIONS); // RSMM this.func_193030_aL().func_73660_a(); this.field_71304_b.func_76318_c("tickables"); -@@ -728,6 +841,8 @@ ++ WorldHelper.swapTickTask(TickTask.SERVER_GUI); // RSMM + + for (int k = 0; k < this.field_71322_p.size(); ++k) + { +@@ -728,6 +861,9 @@ } this.field_71304_b.func_76319_b(); ++ WorldHelper.endTickTask(); // RSMM + + PistonFixes.onEndTick(); } public boolean func_71255_r() -@@ -939,7 +1054,7 @@ +@@ -939,7 +1075,7 @@ public String getServerModName() { @@ -358,3 +388,21 @@ } public CrashReport func_71230_b(CrashReport p_71230_1_) +@@ -1512,6 +1648,7 @@ + { + if (this.func_152345_ab()) + { ++ CarpetServer.rsmmServer.getMultimeter().reloadOptions(); // RSMM + this.func_184103_al().func_72389_g(); + this.field_71305_c[0].func_184146_ak().func_186522_a(); + this.func_191949_aK().func_192779_a(); +@@ -1523,4 +1660,9 @@ + this.func_152344_a(this::func_193031_aM); + } + } ++ ++ // RSMM ++ public boolean isPaused() { ++ return false; ++ } + } diff --git a/patches/net/minecraft/server/management/PlayerInteractionManager.java.patch b/patches/net/minecraft/server/management/PlayerInteractionManager.java.patch index 5be8a337..b7321feb 100644 --- a/patches/net/minecraft/server/management/PlayerInteractionManager.java.patch +++ b/patches/net/minecraft/server/management/PlayerInteractionManager.java.patch @@ -8,10 +8,12 @@ import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; -@@ -26,6 +27,10 @@ +@@ -26,6 +27,12 @@ import net.minecraft.world.World; import net.minecraft.world.WorldServer; ++import redstone.multimeter.helper.WorldHelper; ++ +import carpet.helpers.BlockRotator; +import carpet.CarpetSettings; +import carpet.worldedit.WorldEditBridge; @@ -19,7 +21,7 @@ public class PlayerInteractionManager { public World field_73092_a; -@@ -39,6 +44,8 @@ +@@ -39,6 +46,8 @@ private BlockPos field_180241_i = BlockPos.field_177992_a; private int field_73093_n; private int field_73094_o = -1; @@ -28,7 +30,7 @@ public PlayerInteractionManager(World p_i1524_1_) { -@@ -137,6 +144,12 @@ +@@ -137,6 +146,12 @@ public void func_180784_a(BlockPos p_180784_1_, EnumFacing p_180784_2_) { @@ -41,7 +43,7 @@ if (this.func_73083_d()) { if (!this.field_73092_a.func_175719_a((EntityPlayer)null, p_180784_1_, p_180784_2_)) -@@ -191,6 +204,11 @@ +@@ -191,6 +206,11 @@ this.field_73088_d = true; this.field_180240_f = p_180784_1_; int i = (int)(f * 10.0F); @@ -53,7 +55,7 @@ this.field_73092_a.func_175715_c(this.field_73090_b.func_145782_y(), p_180784_1_, i); this.field_73094_o = i; } -@@ -235,8 +253,10 @@ +@@ -235,8 +255,10 @@ { IBlockState iblockstate = this.field_73092_a.func_180495_p(p_180235_1_); iblockstate.func_177230_c().func_176208_a(this.field_73092_a, p_180235_1_, iblockstate, this.field_73090_b); @@ -65,7 +67,7 @@ if (flag) { iblockstate.func_177230_c().func_176206_d(this.field_73092_a, p_180235_1_, iblockstate); -@@ -288,7 +308,15 @@ +@@ -288,7 +310,15 @@ } this.field_73092_a.func_180498_a(this.field_73090_b, 2001, p_180237_1_, Block.func_176210_f(iblockstate)); @@ -82,7 +84,7 @@ if (this.func_73083_d()) { -@@ -307,10 +335,19 @@ +@@ -307,10 +337,19 @@ if (flag1 && flag) { @@ -102,7 +104,7 @@ return flag1; } } -@@ -402,10 +439,22 @@ +@@ -402,10 +441,23 @@ } else { @@ -122,6 +124,7 @@ + { + return EnumActionResult.PASS; + } ++ WorldHelper.getMultimeter().logInteractBlock(p_187251_2_, p_187251_5_); // RSMM if (iblockstate.func_177230_c().func_180639_a(p_187251_2_, p_187251_5_, iblockstate, p_187251_1_, p_187251_4_, p_187251_6_, p_187251_7_, p_187251_8_, p_187251_9_)) { return EnumActionResult.SUCCESS; diff --git a/patches/net/minecraft/server/management/PlayerList.java.patch b/patches/net/minecraft/server/management/PlayerList.java.patch index 20180fbd..8e784bde 100644 --- a/patches/net/minecraft/server/management/PlayerList.java.patch +++ b/patches/net/minecraft/server/management/PlayerList.java.patch @@ -49,7 +49,16 @@ nethandlerplayserver.func_147359_a(new SPacketJoinGame(p_72355_2_.func_145782_y(), p_72355_2_.field_71134_c.func_73081_b(), worldinfo.func_76093_s(), worldserver.field_73011_w.func_186058_p().func_186068_a(), worldserver.func_175659_aa(), this.func_72352_l(), worldinfo.func_76067_t(), worldserver.func_82736_K().func_82766_b("reducedDebugInfo"))); nethandlerplayserver.func_147359_a(new SPacketCustomPayload("MC|Brand", (new PacketBuffer(Unpooled.buffer())).func_180714_a(this.func_72365_p().getServerModName()))); nethandlerplayserver.func_147359_a(new SPacketServerDifficulty(worldinfo.func_176130_y(), worldinfo.func_176123_z())); -@@ -343,6 +348,8 @@ +@@ -202,6 +207,8 @@ + } + + p_72355_2_.func_71116_b(); ++ ++ CarpetServer.rsmmServer.onPlayerJoin(p_72355_2_); // RSMM + } + + protected void func_96456_a(ServerScoreboard p_96456_1_, EntityPlayerMP p_96456_2_) +@@ -343,6 +350,8 @@ worldserver.func_72838_d(p_72377_1_); this.func_72375_a(p_72377_1_, (WorldServer)null); @@ -58,16 +67,18 @@ } public void func_72358_d(EntityPlayerMP p_72358_1_) -@@ -352,6 +359,8 @@ +@@ -352,6 +361,10 @@ public void func_72367_e(EntityPlayerMP p_72367_1_) { ++ CarpetServer.rsmmServer.onPlayerLeave(p_72367_1_); // RSMM ++ + //CM player logging off + CarpetServer.playerDisconnected(p_72367_1_); WorldServer worldserver = p_72367_1_.func_71121_q(); p_72367_1_.func_71029_a(StatList.field_75947_j); this.func_72391_b(p_72367_1_); -@@ -452,6 +461,11 @@ +@@ -452,6 +465,11 @@ for (EntityPlayerMP entityplayermp1 : list) { @@ -79,7 +90,7 @@ entityplayermp1.field_71135_a.func_194028_b(new TextComponentTranslation("multiplayer.disconnect.duplicate_login", new Object[0])); } -@@ -474,6 +488,7 @@ +@@ -474,6 +492,7 @@ p_72368_1_.func_71121_q().func_73039_n().func_72787_a(p_72368_1_); p_72368_1_.func_71121_q().func_73039_n().func_72790_b(p_72368_1_); p_72368_1_.func_71121_q().func_184164_w().func_72695_c(p_72368_1_); @@ -87,7 +98,7 @@ this.field_72404_b.remove(p_72368_1_); this.field_72400_f.func_71218_a(p_72368_1_.field_71093_bK).func_72973_f(p_72368_1_); BlockPos blockpos = p_72368_1_.func_180470_cg(); -@@ -496,6 +511,7 @@ +@@ -496,6 +515,7 @@ entityplayermp.func_145769_d(p_72368_1_.func_145782_y()); entityplayermp.func_174817_o(p_72368_1_); entityplayermp.func_184819_a(p_72368_1_.func_184591_cq()); @@ -95,7 +106,7 @@ for (String s : p_72368_1_.func_184216_O()) { -@@ -560,7 +576,11 @@ +@@ -560,7 +580,11 @@ WorldServer worldserver1 = this.field_72400_f.func_71218_a(p_187242_1_.field_71093_bK); p_187242_1_.field_71135_a.func_147359_a(new SPacketRespawn(p_187242_1_.field_71093_bK, p_187242_1_.field_70170_p.func_175659_aa(), p_187242_1_.field_70170_p.func_72912_H().func_76067_t(), p_187242_1_.field_71134_c.func_73081_b())); this.func_187243_f(p_187242_1_); @@ -108,7 +119,7 @@ p_187242_1_.field_70128_L = false; this.func_82448_a(p_187242_1_, i, worldserver, worldserver1); this.func_72375_a(p_187242_1_, worldserver); -@@ -630,6 +650,12 @@ +@@ -630,6 +654,12 @@ } } @@ -121,7 +132,7 @@ p_82448_3_.field_72984_F.func_76319_b(); if (p_82448_2_ != 1) -@@ -1097,4 +1123,26 @@ +@@ -1097,4 +1127,26 @@ playeradvancements.func_193766_b(); } } diff --git a/patches/net/minecraft/tileentity/TileEntityChest.java.patch b/patches/net/minecraft/tileentity/TileEntityChest.java.patch index e9b7834e..591b2b89 100644 --- a/patches/net/minecraft/tileentity/TileEntityChest.java.patch +++ b/patches/net/minecraft/tileentity/TileEntityChest.java.patch @@ -1,13 +1,14 @@ --- ../src-base/minecraft/net/minecraft/tileentity/TileEntityChest.java +++ ../src-work/minecraft/net/minecraft/tileentity/TileEntityChest.java -@@ -23,7 +23,10 @@ +@@ -22,8 +22,11 @@ + import net.minecraft.util.datafix.walkers.ItemStackDataLists; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; - --public class TileEntityChest extends TileEntityLockableLoot implements ITickable ++import redstone.multimeter.helper.BlockChestHelper; +import carpet.CarpetSettings; +import carpet.helpers.TileEntityOptimizer.ILazyTileEntity; -+ + +-public class TileEntityChest extends TileEntityLockableLoot implements ITickable +public class TileEntityChest extends TileEntityLockableLoot implements ITickable, ILazyTileEntity { private NonNullList field_145985_p = NonNullList.func_191197_a(27, ItemStack.field_190927_a); @@ -74,7 +75,23 @@ if (p_145842_1_ == 1) { this.field_145987_o = p_145842_2_; -@@ -386,4 +408,14 @@ +@@ -324,6 +346,7 @@ + } + + ++this.field_145987_o; ++ BlockChestHelper.onInvOpenOrClosed(this, true); // RSMM + this.field_145850_b.func_175641_c(this.field_174879_c, this.func_145838_q(), 1, this.field_145987_o); + this.field_145850_b.func_175685_c(this.field_174879_c, this.func_145838_q(), false); + +@@ -339,6 +362,7 @@ + if (!p_174886_1_.func_175149_v() && this.func_145838_q() instanceof BlockChest) + { + --this.field_145987_o; ++ BlockChestHelper.onInvOpenOrClosed(this, false); // RSMM + this.field_145850_b.func_175641_c(this.field_174879_c, this.func_145838_q(), 1, this.field_145987_o); + this.field_145850_b.func_175685_c(this.field_174879_c, this.func_145838_q(), false); + +@@ -386,4 +410,14 @@ { return this.field_145985_p; } diff --git a/patches/net/minecraft/tileentity/TileEntityComparator.java.patch b/patches/net/minecraft/tileentity/TileEntityComparator.java.patch index 730a8d7b..284f6685 100644 --- a/patches/net/minecraft/tileentity/TileEntityComparator.java.patch +++ b/patches/net/minecraft/tileentity/TileEntityComparator.java.patch @@ -1,6 +1,14 @@ --- ../src-base/minecraft/net/minecraft/tileentity/TileEntityComparator.java +++ ../src-work/minecraft/net/minecraft/tileentity/TileEntityComparator.java -@@ -5,6 +5,10 @@ +@@ -1,10 +1,18 @@ + package net.minecraft.tileentity; + ++import carpet.CarpetSettings; ++ + import net.minecraft.nbt.NBTTagCompound; + ++import redstone.multimeter.helper.WorldHelper; ++ public class TileEntityComparator extends TileEntity { private int field_145997_a; @@ -11,3 +19,15 @@ public NBTTagCompound func_189515_b(NBTTagCompound p_189515_1_) { +@@ -26,6 +34,11 @@ + + public void func_145995_a(int p_145995_1_) + { ++ // RSMM start ++ if (CarpetSettings.redstoneMultimeter && !field_145850_b.field_72995_K) { ++ WorldHelper.getMultimeter().logPowerChange(field_145850_b, field_174879_c, field_145997_a, p_145995_1_); ++ } ++ // RSMM end + this.field_145997_a = p_145995_1_; + } + } diff --git a/patches/net/minecraft/world/World.java.patch b/patches/net/minecraft/world/World.java.patch index af893c93..8774b608 100644 --- a/patches/net/minecraft/world/World.java.patch +++ b/patches/net/minecraft/world/World.java.patch @@ -19,10 +19,12 @@ import javax.annotation.Nullable; import net.minecraft.advancements.AdvancementManager; import net.minecraft.advancements.FunctionManager; -@@ -60,10 +58,21 @@ +@@ -60,10 +58,23 @@ import net.minecraft.world.storage.WorldSavedData; import net.minecraft.world.storage.loot.LootTableManager; ++import redstone.multimeter.common.TickTask; ++import redstone.multimeter.helper.WorldHelper; +import carpet.utils.CarpetProfiler; +import carpet.utils.Messenger; +import carpet.CarpetSettings; @@ -42,7 +44,7 @@ public final List field_72996_f = Lists.newArrayList(); protected final List field_72997_g = Lists.newArrayList(); public final List field_147482_g = Lists.newArrayList(); -@@ -75,7 +84,7 @@ +@@ -75,7 +86,7 @@ protected final IntHashMap field_175729_l = new IntHashMap(); private final long field_73001_c = 16777215L; private int field_73008_k; @@ -51,7 +53,7 @@ protected final int field_73006_m = 1013904223; protected float field_73003_n; protected float field_73004_o; -@@ -105,6 +114,13 @@ +@@ -105,6 +116,13 @@ private final WorldBorder field_175728_M; int[] field_72994_J; @@ -65,7 +67,7 @@ protected World(ISaveHandler p_i45749_1_, WorldInfo p_i45749_2_, WorldProvider p_i45749_3_, Profiler p_i45749_4_, boolean p_i45749_5_) { this.field_73021_x = Lists.newArrayList(this.field_184152_t); -@@ -119,6 +135,7 @@ +@@ -119,6 +137,7 @@ this.field_73011_w = p_i45749_3_; this.field_72995_K = p_i45749_5_; this.field_175728_M = p_i45749_3_.func_177501_r(); @@ -73,7 +75,7 @@ } public World func_175643_b() -@@ -269,7 +286,7 @@ +@@ -269,7 +288,7 @@ } } @@ -82,7 +84,7 @@ public Chunk func_175726_f(BlockPos p_175726_1_) { -@@ -286,6 +303,16 @@ +@@ -286,6 +305,16 @@ return this.func_175680_a(p_190526_1_, p_190526_2_, false) ? true : this.field_73020_y.func_191062_e(p_190526_1_, p_190526_2_); } @@ -99,7 +101,7 @@ public boolean func_180501_a(BlockPos p_180501_1_, IBlockState p_180501_2_, int p_180501_3_) { if (this.func_189509_E(p_180501_1_)) -@@ -300,7 +327,8 @@ +@@ -300,7 +329,8 @@ { Chunk chunk = this.func_175726_f(p_180501_1_); Block block = p_180501_2_.func_177230_c(); @@ -109,7 +111,7 @@ if (iblockstate == null) { -@@ -329,7 +357,8 @@ +@@ -329,7 +359,8 @@ this.func_175666_e(p_180501_1_, block); } } @@ -119,7 +121,7 @@ { this.func_190522_c(p_180501_1_, block); } -@@ -430,8 +459,36 @@ +@@ -430,8 +461,36 @@ this.func_190529_b(p_190522_1_.func_177968_d(), p_190522_2_, p_190522_1_); } @@ -156,7 +158,7 @@ this.func_190524_a(p_175685_1_.func_177976_e(), p_175685_2_, p_175685_1_); this.func_190524_a(p_175685_1_.func_177974_f(), p_175685_2_, p_175685_1_); this.func_190524_a(p_175685_1_.func_177977_b(), p_175685_2_, p_175685_1_); -@@ -447,6 +504,44 @@ +@@ -447,6 +506,44 @@ public void func_175695_a(BlockPos p_175695_1_, Block p_175695_2_, EnumFacing p_175695_3_) { @@ -201,7 +203,7 @@ if (p_175695_3_ != EnumFacing.WEST) { this.func_190524_a(p_175695_1_.func_177976_e(), p_175695_2_, p_175695_1_); -@@ -480,6 +575,11 @@ +@@ -480,12 +577,18 @@ public void func_190524_a(BlockPos p_190524_1_, final Block p_190524_2_, BlockPos p_190524_3_) { @@ -213,12 +215,19 @@ if (!this.field_72995_K) { IBlockState iblockstate = this.func_180495_p(p_190524_1_); -@@ -509,11 +609,21 @@ + + try + { ++ WorldHelper.onBlockUpdate(this, p_190524_1_, iblockstate); // RSMM + iblockstate.func_189546_a(this, p_190524_1_, p_190524_2_, p_190524_3_); + } + catch (Throwable throwable) +@@ -509,11 +612,21 @@ CrashReportCategory.func_175750_a(crashreportcategory, p_190524_1_, iblockstate); throw new ReportedException(crashreport); } + // ----- RSMM Start ----- // -+ if (CarpetSettings.redstoneMultimeter) { ++ if (CarpetSettings.redstoneMultimeterLegacy) { + StateChangeEventDispatcher.dispatchEvent(this, p_190524_1_); + } + // ----- RSMM End ----- // @@ -235,19 +244,27 @@ if (!this.field_72995_K) { IBlockState iblockstate = this.func_180495_p(p_190529_1_); -@@ -546,6 +656,11 @@ +@@ -522,6 +635,7 @@ + { + try + { ++ WorldHelper.onObserverUpdate(this, p_190529_1_); // RSMM + ((BlockObserver)iblockstate.func_177230_c()).func_190962_b(iblockstate, this, p_190529_1_, p_190529_2_, p_190529_3_); + } + catch (Throwable throwable) +@@ -546,6 +660,11 @@ throw new ReportedException(crashreport); } } + // ----- RSMM Start ----- // -+ if (CarpetSettings.redstoneMultimeter) { ++ if (CarpetSettings.redstoneMultimeterLegacy) { + StateChangeEventDispatcher.dispatchEvent(this, p_190529_1_); + } + // ----- RSMM End ----- // } } -@@ -1076,6 +1191,18 @@ +@@ -1076,6 +1195,18 @@ public void func_72900_e(Entity p_72900_1_) { @@ -266,7 +283,7 @@ if (p_72900_1_.func_184207_aI()) { p_72900_1_.func_184226_ay(); -@@ -1098,6 +1225,18 @@ +@@ -1098,6 +1229,18 @@ public void func_72973_f(Entity p_72973_1_) { @@ -285,7 +302,7 @@ p_72973_1_.func_184174_b(false); p_72973_1_.func_70106_y(); -@@ -1126,6 +1265,9 @@ +@@ -1126,6 +1269,9 @@ private boolean func_191504_a(@Nullable Entity p_191504_1_, AxisAlignedBB p_191504_2_, boolean p_191504_3_, @Nullable List p_191504_4_) { @@ -295,15 +312,25 @@ int i = MathHelper.func_76128_c(p_191504_2_.field_72340_a) - 1; int j = MathHelper.func_76143_f(p_191504_2_.field_72336_d) + 1; int k = MathHelper.func_76128_c(p_191504_2_.field_72338_b) - 1; -@@ -1339,6 +1481,7 @@ +@@ -1338,7 +1484,9 @@ + { this.field_72984_F.func_76320_a("entities"); this.field_72984_F.func_76320_a("global"); ++ WorldHelper.startTickTask(TickTask.GLOBAL_ENTITIES); // RSMM + LagSpikeHelper.processLagSpikes(this, LagSpikeHelper.TickPhase.ENTITY, LagSpikeHelper.EntitySubPhase.PRE); for (int i = 0; i < this.field_73007_j.size(); ++i) { Entity entity = this.field_73007_j.get(i); -@@ -1370,6 +1513,9 @@ +@@ -1346,6 +1494,7 @@ + try + { + ++entity.field_70173_aa; ++ WorldHelper.onEntityTick(this, entity); // RSMM + entity.func_70071_h_(); + } + catch (Throwable throwable2) +@@ -1370,6 +1519,9 @@ this.field_73007_j.remove(i--); } } @@ -313,12 +340,13 @@ this.field_72984_F.func_76318_c("remove"); this.field_72996_f.removeAll(this.field_72997_g); -@@ -1393,11 +1539,13 @@ +@@ -1393,11 +1545,14 @@ this.field_72997_g.clear(); this.func_184147_l(); + LagSpikeHelper.processLagSpikes(this, LagSpikeHelper.TickPhase.ENTITY, LagSpikeHelper.EntitySubPhase.POST_PLAYERS); this.field_72984_F.func_76318_c("regular"); ++ WorldHelper.swapTickTask(TickTask.REGULAR_ENTITIES); // RSMM for (int i1 = 0; i1 < this.field_72996_f.size(); ++i1) { @@ -327,7 +355,7 @@ Entity entity3 = entity2.func_184187_bx(); if (entity3 != null) -@@ -1416,7 +1564,10 @@ +@@ -1416,7 +1571,10 @@ { try { @@ -339,7 +367,7 @@ } catch (Throwable throwable1) { -@@ -1437,31 +1588,50 @@ +@@ -1437,31 +1595,51 @@ if (entity2.field_70175_ag && this.func_175680_a(l1, i2, true)) { @@ -361,6 +389,7 @@ + CarpetProfiler.start_section(world_name, "tileentities"); this.field_72984_F.func_76318_c("blockEntities"); ++ WorldHelper.swapTickTask(TickTask.BLOCK_ENTITIES); // RSMM + LagSpikeHelper.processLagSpikes(this, LagSpikeHelper.TickPhase.TILE_ENTITY, LagSpikeHelper.PrePostSubPhase.PRE); if (!this.field_147483_b.isEmpty()) @@ -392,7 +421,7 @@ if (!tileentity.func_145837_r() && tileentity.func_145830_o()) { -@@ -1471,12 +1641,14 @@ +@@ -1471,12 +1649,15 @@ { try { @@ -407,13 +436,14 @@ + { + return String.valueOf((Object) TileEntity.func_190559_a(tileentity.getClass())); + }); ++ WorldHelper.onBlockEntityTick(this, tileentity); // RSMM + ((ITickable) tileentity).func_73660_a(); + this.field_72984_F.func_76319_b(); + } } catch (Throwable throwable) { -@@ -1490,16 +1662,26 @@ +@@ -1490,16 +1671,26 @@ if (tileentity.func_145837_r()) { @@ -440,7 +470,7 @@ this.field_147481_N = false; this.field_72984_F.func_76318_c("pendingBlockEntities"); -@@ -1528,6 +1710,8 @@ +@@ -1528,9 +1719,12 @@ this.field_147484_a.clear(); } @@ -449,7 +479,11 @@ this.field_72984_F.func_76319_b(); this.field_72984_F.func_76319_b(); -@@ -1602,11 +1786,15 @@ ++ WorldHelper.endTickTask(); // RSMM + } + + protected void func_184147_l() +@@ -1602,11 +1796,16 @@ if (p_72866_1_.func_184218_aH()) { @@ -462,12 +496,13 @@ { - p_72866_1_.func_70071_h_(); + if(!CarpetSettings.commandLazyChunkBehavior || LazyChunkBehaviorHelper.shouldUpdate(p_72866_1_)) { ++ WorldHelper.onEntityTick(this, p_72866_1_); // RSMM + p_72866_1_.func_70071_h_(); + } } } -@@ -1648,7 +1836,8 @@ +@@ -1648,7 +1847,8 @@ this.func_72964_e(p_72866_1_.field_70176_ah, p_72866_1_.field_70164_aj).func_76608_a(p_72866_1_, p_72866_1_.field_70162_ai); } @@ -477,7 +512,7 @@ { p_72866_1_.field_70175_ag = false; } -@@ -1670,7 +1859,11 @@ +@@ -1670,7 +1870,11 @@ } else { @@ -490,7 +525,7 @@ } } } -@@ -1689,7 +1882,7 @@ +@@ -1689,7 +1893,7 @@ { Entity entity4 = list.get(j2); @@ -499,7 +534,7 @@ { return false; } -@@ -2153,6 +2346,16 @@ +@@ -2153,6 +2357,16 @@ { this.field_72986_A.func_76090_f(this.field_73012_v.nextInt(168000) + 12000); } @@ -516,7 +551,7 @@ } else { -@@ -2177,6 +2380,16 @@ +@@ -2177,6 +2391,16 @@ { this.field_72986_A.func_76080_g(this.field_73012_v.nextInt(168000) + 12000); } @@ -533,7 +568,7 @@ } else { -@@ -2387,6 +2600,11 @@ +@@ -2387,6 +2611,11 @@ public boolean func_180500_c(EnumSkyBlock p_180500_1_, BlockPos p_180500_2_) { @@ -545,7 +580,7 @@ if (!this.func_175648_a(p_180500_2_, 17, false)) { return false; -@@ -2699,7 +2917,8 @@ +@@ -2699,7 +2928,8 @@ IBlockState iblockstate1 = this.func_180495_p(p_190527_2_); AxisAlignedBB axisalignedbb = p_190527_3_ ? null : p_190527_1_.func_176223_P().func_185890_d(this, p_190527_2_); @@ -555,7 +590,7 @@ { return false; } -@@ -3267,30 +3486,41 @@ +@@ -3267,30 +3497,43 @@ public void func_175666_e(BlockPos p_175666_1_, Block p_175666_2_) { @@ -591,12 +626,14 @@ - if (Blocks.field_150441_bU.func_185547_C(iblockstate1)) - { + if (Blocks.field_150441_bU.func_185547_C(iblockstate1)) { ++ WorldHelper.onComparatorUpdate(this, blockpos1); // RSMM iblockstate1.func_189546_a(this, blockpos1, p_175666_2_, p_175666_1_); + } else if (iblockstate1.func_185915_l()) { + blockpos1 = blockpos1.func_177972_a(enumfacing); + iblockstate1 = this.func_180495_p(blockpos1); + + if (Blocks.field_150441_bU.func_185547_C(iblockstate1)) { ++ WorldHelper.onComparatorUpdate(this, blockpos1); // RSMM + iblockstate1.func_189546_a(this, blockpos1, p_175666_2_, p_175666_1_); + } } @@ -605,14 +642,14 @@ } + carpet.carpetclient.CarpetClientChunkLogger.resetReason(); + // ----- RSMM Start ----- // -+ if (CarpetSettings.redstoneMultimeter) { ++ if (CarpetSettings.redstoneMultimeterLegacy) { + StateChangeEventDispatcher.dispatchEvent(this, p_175666_1_); + } + // ----- RSMM End ----- // } public DifficultyInstance func_175649_E(BlockPos p_175649_1_) -@@ -3361,4 +3591,128 @@ +@@ -3361,4 +3604,130 @@ { return null; } @@ -642,6 +679,7 @@ + + try + { ++ WorldHelper.onBlockUpdate(this, pos, iblockstate); // RSMM + iblockstate.func_189546_a(this, pos, blockIn, fromPos); + } + catch (ThrowableSuppression e) @@ -674,7 +712,7 @@ + throw new ReportedException(crashreport); + } + // ----- RSMM Start ----- // -+ if (CarpetSettings.redstoneMultimeter) { ++ if (CarpetSettings.redstoneMultimeterLegacy) { + StateChangeEventDispatcher.dispatchEvent(this, pos); + } + // ----- RSMM End ----- // @@ -692,6 +730,7 @@ + { + try + { ++ WorldHelper.onObserverUpdate(this, pos); // RSMM + ((BlockObserver)iblockstate.func_177230_c()).func_190962_b(iblockstate, this, pos, changedBlock, changedBlockPos); + } + catch (StackOverflowError e) @@ -721,7 +760,7 @@ + } + } + // ----- RSMM Start ----- // -+ if (CarpetSettings.redstoneMultimeter) { ++ if (CarpetSettings.redstoneMultimeterLegacy) { + StateChangeEventDispatcher.dispatchEvent(this, pos); + } + // ----- RSMM End ----- // diff --git a/patches/net/minecraft/world/WorldServer.java.patch b/patches/net/minecraft/world/WorldServer.java.patch index 9c2f5b5c..e3104758 100644 --- a/patches/net/minecraft/world/WorldServer.java.patch +++ b/patches/net/minecraft/world/WorldServer.java.patch @@ -17,7 +17,15 @@ import java.util.stream.Collectors; import javax.annotation.Nullable; import net.minecraft.advancements.AdvancementManager; -@@ -60,6 +62,7 @@ +@@ -50,6 +52,7 @@ + import net.minecraft.scoreboard.ServerScoreboard; + import net.minecraft.server.MinecraftServer; + import net.minecraft.server.management.PlayerChunkMap; ++import net.minecraft.tileentity.TileEntity; + import net.minecraft.util.EnumParticleTypes; + import net.minecraft.util.IProgressUpdate; + import net.minecraft.util.IThreadListener; +@@ -60,6 +63,7 @@ import net.minecraft.util.math.ChunkPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; @@ -25,7 +33,15 @@ import net.minecraft.village.VillageCollection; import net.minecraft.village.VillageSiege; import net.minecraft.world.biome.Biome; -@@ -80,14 +83,24 @@ +@@ -77,17 +81,32 @@ + import net.minecraft.world.storage.WorldInfo; + import net.minecraft.world.storage.WorldSavedDataCallableSave; + import net.minecraft.world.storage.loot.LootTableManager; ++ ++import redstone.multimeter.common.TickTask; ++import redstone.multimeter.helper.WorldHelper; ++import redstone.multimeter.util.DimensionUtils; ++ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -53,7 +69,7 @@ private final Map field_175741_N = Maps.newHashMap(); public boolean field_73058_d; private boolean field_73068_P; -@@ -99,6 +112,13 @@ +@@ -99,6 +118,14 @@ private int field_147489_T; private final List field_94579_S = Lists.newArrayList(); @@ -63,11 +79,20 @@ + public boolean blockActionsProcessed; + public ScheduledBlockEventSerializer blockEventSerializer; + public static boolean loginMinecartFix = false; ++ private final String dimensionName; // RSMM + public WorldServer(MinecraftServer p_i45921_1_, ISaveHandler p_i45921_2_, WorldInfo p_i45921_3_, int p_i45921_4_, Profiler p_i45921_5_) { super(p_i45921_2_, p_i45921_3_, DimensionType.func_186069_a(p_i45921_4_).func_186070_d(), p_i45921_5_, false); -@@ -159,11 +179,28 @@ +@@ -111,6 +138,7 @@ + this.func_72966_v(); + this.func_72947_a(); + this.func_175723_af().func_177725_a(p_i45921_1_.func_175580_aG()); ++ this.dimensionName = DimensionUtils.getId(this.field_73011_w.func_186058_p()).toString(); + } + + public World func_175643_b() +@@ -159,11 +187,30 @@ this.func_175723_af().func_177750_a(this.field_72986_A.func_176137_E()); } @@ -92,11 +117,13 @@ + if(CarpetSettings.limitITTupdates > 0 && field_73061_a.func_152345_ab()) { + CarpetServer.limitITTCounter = 0; + } ++ ++ WorldHelper.startTickTask(TickTask.TICK_WORLD, dimensionName); // RSMM + super.func_72835_b(); if (this.func_72912_H().func_76093_s() && this.func_175659_aa() != EnumDifficulty.HARD) -@@ -184,15 +221,26 @@ +@@ -184,15 +231,30 @@ this.func_73053_d(); } @@ -105,6 +132,7 @@ + {// extra indent + this.field_72984_F.func_76320_a("mobSpawner"); ++ WorldHelper.startTickTask(TickTask.MOB_SPAWNING); // RSMM + CarpetProfiler.start_section(world_name, "spawning"); + LagSpikeHelper.processLagSpikes(this, LagSpikeHelper.TickPhase.MOB_SPAWNING, LagSpikeHelper.PrePostSubPhase.PRE); @@ -114,23 +142,41 @@ } + LagSpikeHelper.processLagSpikes(this, LagSpikeHelper.TickPhase.MOB_SPAWNING, LagSpikeHelper.PrePostSubPhase.POST); + CarpetProfiler.end_current_section(); ++ WorldHelper.endTickTask(); // RSMM + }//end indent this.field_72984_F.func_76318_c("chunkSource"); ++ WorldHelper.startTickTask(TickTask.CHUNK_SOURCE); // RSMM + LagSpikeHelper.processLagSpikes(this, LagSpikeHelper.TickPhase.CHUNK_UNLOADING, LagSpikeHelper.PrePostSubPhase.PRE); this.field_73020_y.func_73156_b(); + LagSpikeHelper.processLagSpikes(this, LagSpikeHelper.TickPhase.CHUNK_UNLOADING, LagSpikeHelper.PrePostSubPhase.POST); ++ WorldHelper.endTickTask(); // RSMM int j = this.func_72967_a(1.0F); if (j != this.func_175657_ab()) -@@ -200,26 +248,81 @@ +@@ -200,26 +262,106 @@ this.func_175692_b(j); } + if (TickSpeed.process_entities) + { // CM extra indent ++ // RSMM start ++ boolean tickTime = field_73011_w.func_186058_p() == DimensionType.OVERWORLD; ++ ++ if (tickTime) { ++ WorldHelper.startTickTask(TickTask.TICK_TIME); ++ } ++ // RSMM end ++ this.field_72986_A.func_82572_b(this.field_72986_A.func_82573_f() + 1L); ++ // RSMM start ++ if (tickTime) { ++ WorldHelper.getMultimeterServer().onOverworldTickTime(); ++ WorldHelper.endTickTask(); ++ } ++ // RSMM ++ if (this.func_82736_K().func_82766_b("doDaylightCycle")) { this.field_72986_A.func_76068_b(this.field_72986_A.func_76073_f() + 1L); @@ -138,6 +184,7 @@ - this.field_72984_F.func_76318_c("tickPending"); - this.func_72955_a(false); ++ WorldHelper.startTickTask(TickTask.SCHEDULED_TICKS); // RSMM + + CarpetProfiler.start_section(world_name, "blocks"); + @@ -155,29 +202,36 @@ + } + + CarpetProfiler.end_current_section(); ++ WorldHelper.endTickTask(); // RSMM + -+ } ++ } //end indent + CarpetProfiler.start_section(world_name, "blocks"); this.field_72984_F.func_76318_c("tickBlocks"); ++ WorldHelper.startTickTask(TickTask.TICK_CHUNKS); // RSMM + LagSpikeHelper.processLagSpikes(this, LagSpikeHelper.TickPhase.RANDOM_TICK, LagSpikeHelper.PrePostSubPhase.PRE); this.func_147456_g(); + LagSpikeHelper.processLagSpikes(this, LagSpikeHelper.TickPhase.RANDOM_TICK, LagSpikeHelper.PrePostSubPhase.POST); + CarpetProfiler.end_current_section(); this.field_72984_F.func_76318_c("chunkMap"); ++ WorldHelper.swapTickTask(TickTask.CHUNK_MAP); // RSMM + LagSpikeHelper.processLagSpikes(this, LagSpikeHelper.TickPhase.PLAYER_CHUNK_MAP, LagSpikeHelper.PrePostSubPhase.PRE); this.field_73063_M.func_72693_b(); + LagSpikeHelper.processLagSpikes(this, LagSpikeHelper.TickPhase.PLAYER_CHUNK_MAP, LagSpikeHelper.PrePostSubPhase.POST); ++ WorldHelper.endTickTask(); // RSMM + + if (TickSpeed.process_entities) + { // CM indent this.field_72984_F.func_76318_c("village"); ++ WorldHelper.startTickTask(TickTask.VILLAGES); // RSMM + LagSpikeHelper.processLagSpikes(this, LagSpikeHelper.TickPhase.VILLAGE, LagSpikeHelper.PrePostSubPhase.PRE); this.field_72982_D.func_75544_a(); this.field_175740_d.func_75528_a(); + LagSpikeHelper.processLagSpikes(this, LagSpikeHelper.TickPhase.VILLAGE, LagSpikeHelper.PrePostSubPhase.POST); this.field_72984_F.func_76318_c("portalForcer"); ++ WorldHelper.swapTickTask(TickTask.PORTALS); // RSMM this.field_85177_Q.func_85189_a(this.func_82737_E()); -+ } ++ WorldHelper.endTickTask(); // RSMM ++ } //end indent + + // NewLight PHIPRO-CARPET + if (CarpetSettings.newLight) @@ -191,6 +245,8 @@ this.func_147488_Z(); + LagSpikeHelper.processLagSpikes(this, LagSpikeHelper.TickPhase.BLOCK_EVENT, LagSpikeHelper.PrePostSubPhase.POST); + ++ WorldHelper.endTickTask(); // RSMM ++ + if(LoggerRegistry.__rng){ + LoggerRegistry.getLogger("rng").log(()-> new ITextComponent[]{ + Messenger.s(null, String.format("RNG BlockEv. t:%d seed:%d d:%s", field_73061_a.func_71259_af(), getRandSeed(), field_73011_w.func_186058_p().name())) @@ -207,7 +263,7 @@ } @Nullable -@@ -255,8 +358,15 @@ +@@ -255,13 +397,22 @@ ++j; } } @@ -225,7 +281,23 @@ } } -@@ -287,6 +397,28 @@ + protected void func_73053_d() + { ++ WorldHelper.startTickTask(TickTask.WAKE_SLEEPING_PLAYERS); // RSMM ++ + this.field_73068_P = false; + + for (EntityPlayer entityplayer : this.field_73010_i.stream().filter(EntityPlayer::func_70608_bn).collect(Collectors.toList())) +@@ -273,6 +424,8 @@ + { + this.func_73051_P(); + } ++ ++ WorldHelper.endTickTask(); // RSMM + } + + private void func_73051_P() +@@ -287,6 +440,28 @@ { if (this.field_73068_P && !this.field_72995_K) { @@ -254,7 +326,7 @@ for (EntityPlayer entityplayer : this.field_73010_i) { if (!entityplayer.func_175149_v() && !entityplayer.func_71026_bH()) -@@ -303,7 +435,7 @@ +@@ -303,7 +478,7 @@ } } @@ -263,7 +335,7 @@ { return this.func_72863_F().func_73149_a(p_175680_1_, p_175680_2_); } -@@ -344,6 +476,7 @@ +@@ -344,6 +519,7 @@ boolean flag = this.func_72896_J(); boolean flag1 = this.func_72911_I(); this.field_72984_F.func_76320_a("pollingChunks"); @@ -271,32 +343,71 @@ for (Iterator iterator = this.field_73063_M.func_187300_b(); iterator.hasNext(); this.field_72984_F.func_76319_b()) { -@@ -355,9 +488,14 @@ +@@ -354,10 +530,18 @@ + this.field_72984_F.func_76318_c("checkNextLight"); chunk.func_76594_o(); this.field_72984_F.func_76318_c("tickChunk"); ++ WorldHelper.startTickTask(false, TickTask.TICK_CHUNK); // RSMM chunk.func_150804_b(false); + if (!TickSpeed.process_entities) + { // skipping the rest of the block processing + this.field_72984_F.func_76319_b(); ++ WorldHelper.endTickTask(false); // RSMM + continue; + } this.field_72984_F.func_76318_c("thunder"); ++ WorldHelper.swapTickTask(false, TickTask.THUNDER); // RSMM - if (flag && flag1 && this.field_73012_v.nextInt(100000) == 0) + if (overworldIceOnly && flag && flag1 && this.field_73012_v.nextInt(100000) == 0) { this.field_73005_l = this.field_73005_l * 3 + 1013904223; int l = this.field_73005_l >> 2; -@@ -385,7 +523,7 @@ +@@ -384,8 +568,9 @@ + } this.field_72984_F.func_76318_c("iceandsnow"); ++ WorldHelper.swapTickTask(false, TickTask.PRECIPITATION); // RSMM - if (this.field_73012_v.nextInt(16) == 0) + if (overworldIceOnly && this.field_73012_v.nextInt(16) == 0) { this.field_73005_l = this.field_73005_l * 3 + 1013904223; int j2 = this.field_73005_l >> 2; -@@ -443,7 +581,7 @@ +@@ -409,6 +594,7 @@ + } + + this.field_72984_F.func_76318_c("tickBlocks"); ++ WorldHelper.swapTickTask(false, TickTask.RANDOM_TICKS); // RSMM + + if (i > 0) + { +@@ -429,7 +615,15 @@ + + if (block.func_149653_t()) + { +- block.func_180645_a(this, new BlockPos(k1 + j, i2 + extendedblockstorage.func_76662_d(), l1 + k), iblockstate, this.field_73012_v); ++ // RSMM start - capture position of random tick ++ int x = k1 + j; ++ int z = l1 + k; ++ int y = i2 + extendedblockstorage.func_76662_d(); ++ BlockPos pos = new BlockPos(x, y, z); ++ WorldHelper.onRandomTick(this, pos); ++ // RSMM end ++ ++ block.func_180645_a(this, pos, iblockstate, this.field_73012_v); + } + + this.field_72984_F.func_76319_b(); +@@ -437,13 +631,15 @@ + } + } + } ++ ++ WorldHelper.endTickTask(false); // RSMM + } + + this.field_72984_F.func_76319_b(); } } @@ -305,7 +416,7 @@ { BlockPos blockpos = this.func_175725_q(p_175736_1_); AxisAlignedBB axisalignedbb = (new AxisAlignedBB(blockpos, new BlockPos(blockpos.func_177958_n(), this.func_72800_K(), blockpos.func_177952_p()))).func_186662_g(3.0D); -@@ -472,13 +610,25 @@ +@@ -472,13 +668,25 @@ public boolean func_175691_a(BlockPos p_175691_1_, Block p_175691_2_) { @@ -333,7 +444,7 @@ return this.field_73064_N.contains(nextticklistentry); } -@@ -501,17 +651,29 @@ +@@ -501,17 +709,29 @@ if (iblockstate.func_185904_a() != Material.field_151579_a && iblockstate.func_177230_c() == p_175654_2_) { @@ -365,7 +476,7 @@ if (this.func_175667_e(p_175654_1_)) { -@@ -531,7 +693,13 @@ +@@ -531,7 +751,13 @@ public void func_180497_b(BlockPos p_180497_1_, Block p_180497_2_, int p_180497_3_, int p_180497_4_) { @@ -380,7 +491,7 @@ nextticklistentry.func_82753_a(p_180497_4_); Material material = p_180497_2_.func_176223_P().func_185904_a(); -@@ -549,7 +717,8 @@ +@@ -549,7 +775,8 @@ public void func_72939_s() { @@ -390,7 +501,25 @@ { if (this.field_80004_Q++ >= 300) { -@@ -644,9 +813,18 @@ +@@ -567,6 +794,8 @@ + + protected void func_184147_l() + { ++ WorldHelper.startTickTask(TickTask.PLAYERS); // RSMM ++ + super.func_184147_l(); + this.field_72984_F.func_76318_c("players"); + +@@ -621,6 +850,8 @@ + + this.field_72984_F.func_76319_b(); + } ++ ++ WorldHelper.endTickTask(); // RSMM + } + + public void func_82742_i() +@@ -644,9 +875,18 @@ } else { @@ -411,7 +540,7 @@ } this.field_72984_F.func_76320_a("cleaning"); -@@ -677,6 +855,8 @@ +@@ -677,12 +917,15 @@ if (this.func_175707_a(nextticklistentry1.field_180282_a.func_177982_a(0, 0, 0), nextticklistentry1.field_180282_a.func_177982_a(0, 0, 0))) { @@ -420,7 +549,14 @@ IBlockState iblockstate = this.func_180495_p(nextticklistentry1.field_180282_a); if (iblockstate.func_185904_a() != Material.field_151579_a && Block.func_149680_a(iblockstate.func_177230_c(), nextticklistentry1.func_151351_a())) -@@ -699,6 +879,7 @@ + { + try + { ++ WorldHelper.onScheduledTick(this, nextticklistentry1); // RSMM + iblockstate.func_177230_c().func_180650_b(this, nextticklistentry1.field_180282_a, iblockstate, this.field_73012_v); + } + catch (Throwable throwable) +@@ -699,6 +942,7 @@ this.func_175684_a(nextticklistentry1.field_180282_a, nextticklistentry1.func_151351_a(), 0); } } @@ -428,7 +564,7 @@ this.field_72984_F.func_76319_b(); this.field_94579_S.clear(); -@@ -950,11 +1131,18 @@ +@@ -950,11 +1194,18 @@ chunkproviderserver.func_186027_a(p_73044_1_); @@ -448,7 +584,7 @@ } } } -@@ -1033,9 +1221,15 @@ +@@ -1033,9 +1284,15 @@ } else { @@ -464,7 +600,7 @@ return false; } -@@ -1055,6 +1249,7 @@ +@@ -1055,6 +1312,7 @@ this.field_175729_l.func_76038_a(p_72923_1_.func_145782_y(), p_72923_1_); this.field_175741_N.put(p_72923_1_.func_110124_au(), p_72923_1_); Entity[] aentity = p_72923_1_.func_70021_al(); @@ -472,7 +608,7 @@ if (aentity != null) { -@@ -1139,6 +1334,7 @@ +@@ -1139,10 +1397,15 @@ } this.field_147490_S[this.field_147489_T].add(blockeventdata); @@ -480,7 +616,15 @@ } private void func_147488_Z() -@@ -1150,14 +1346,19 @@ + { ++ WorldHelper.startTickTask(TickTask.BLOCK_EVENTS); // RSMM ++ ++ WorldHelper.currentBlockEventDepth = 0; // RSMM ++ + while (!this.field_147490_S[this.field_147489_T].isEmpty()) + { + int i = this.field_147489_T; +@@ -1150,19 +1413,33 @@ for (BlockEventData blockeventdata : this.field_147490_S[i]) { @@ -494,13 +638,45 @@ + carpet.carpetclient.CarpetClientChunkLogger.resetReason(); this.field_147490_S[i].clear(); ++ ++ WorldHelper.currentBlockEventDepth++; } + // [CM] Piston ghost blocks fix + this.blockActionsProcessed = true; ++ ++ WorldHelper.endTickTask(); // RSMM } private boolean func_147485_a(BlockEventData p_147485_1_) -@@ -1299,4 +1500,19 @@ + { + IBlockState iblockstate = this.func_180495_p(p_147485_1_.func_180328_a()); ++ // RSMM start ++ if (iblockstate.func_177230_c() == p_147485_1_.func_151337_f()) { ++ WorldHelper.onBlockEvent(this, p_147485_1_); ++ } ++ // RSMM end + return iblockstate.func_177230_c() == p_147485_1_.func_151337_f() ? iblockstate.func_189547_a(this, p_147485_1_.func_180328_a(), p_147485_1_.func_151339_d(), p_147485_1_.func_151338_e()) : false; + } + +@@ -1173,6 +1450,8 @@ + + protected void func_72979_l() + { ++ WorldHelper.startTickTask(TickTask.WEATHER); // RSMM ++ + boolean flag = this.func_72896_J(); + super.func_72979_l(); + +@@ -1200,6 +1479,8 @@ + this.field_73061_a.func_184103_al().func_148540_a(new SPacketChangeGameState(7, this.field_73004_o)); + this.field_73061_a.func_184103_al().func_148540_a(new SPacketChangeGameState(8, this.field_73017_q)); + } ++ ++ WorldHelper.endTickTask(); // RSMM + } + + @Nullable +@@ -1299,4 +1580,19 @@ { } } diff --git a/patches/net/minecraft/world/chunk/Chunk.java.patch b/patches/net/minecraft/world/chunk/Chunk.java.patch index 79a64567..deb4b685 100644 --- a/patches/net/minecraft/world/chunk/Chunk.java.patch +++ b/patches/net/minecraft/world/chunk/Chunk.java.patch @@ -1,9 +1,6 @@ --- ../src-base/minecraft/net/minecraft/world/chunk/Chunk.java +++ ../src-work/minecraft/net/minecraft/world/chunk/Chunk.java -@@ -1,12 +1,11 @@ - package net.minecraft.world.chunk; - -+import carpet.CarpetServer; +@@ -3,10 +3,8 @@ import com.google.common.base.Predicate; import com.google.common.collect.Maps; import com.google.common.collect.Queues; @@ -16,7 +13,13 @@ import java.util.concurrent.ConcurrentLinkedQueue; import javax.annotation.Nullable; import net.minecraft.block.Block; -@@ -38,6 +37,11 @@ +@@ -35,9 +33,17 @@ + import net.minecraft.world.chunk.storage.ExtendedBlockStorage; + import net.minecraft.world.gen.ChunkGeneratorDebug; + import net.minecraft.world.gen.IChunkGenerator; ++ ++import redstone.multimeter.helper.WorldHelper; ++ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -28,7 +31,7 @@ public class Chunk { private static final Logger field_150817_t = LogManager.getLogger(); -@@ -66,13 +70,17 @@ +@@ -66,13 +72,17 @@ private final ConcurrentLinkedQueue field_177447_w; public boolean field_189550_d; @@ -47,7 +50,7 @@ this.field_76649_t = 4096; this.field_177447_w = Queues.newConcurrentLinkedQueue(); this.field_76645_j = (ClassInheritanceMultiMap[])(new ClassInheritanceMultiMap[16]); -@@ -188,38 +196,43 @@ +@@ -188,38 +198,43 @@ if (this.field_76637_e.field_73011_w.func_191066_m()) { @@ -116,7 +119,7 @@ } } } -@@ -307,7 +320,13 @@ +@@ -307,7 +322,13 @@ private void func_76615_h(int p_76615_1_, int p_76615_2_, int p_76615_3_) { @@ -131,7 +134,7 @@ int j = i; if (p_76615_2_ > i) -@@ -322,66 +341,72 @@ +@@ -322,66 +343,72 @@ if (j != i) { @@ -249,7 +252,7 @@ } int l1 = this.field_76634_f[p_76615_3_ << 4 | p_76615_1_]; -@@ -399,6 +424,12 @@ +@@ -399,6 +426,12 @@ this.field_82912_p = l1; } @@ -262,7 +265,7 @@ if (this.field_76637_e.field_73011_w.func_191066_m()) { for (EnumFacing enumfacing : EnumFacing.Plane.HORIZONTAL) -@@ -478,12 +509,19 @@ +@@ -478,12 +511,19 @@ } } @@ -285,7 +288,7 @@ int l = k << 4 | i; if (j >= this.field_76638_b[l] - 1) -@@ -492,15 +530,15 @@ +@@ -492,15 +532,15 @@ } int i1 = this.field_76634_f[l]; @@ -304,7 +307,7 @@ Block block1 = iblockstate.func_177230_c(); ExtendedBlockStorage extendedblockstorage = this.field_76652_q[j >> 4]; boolean flag = false; -@@ -515,19 +553,23 @@ +@@ -515,19 +555,29 @@ extendedblockstorage = new ExtendedBlockStorage(j >> 4 << 4, this.field_76637_e.field_73011_w.func_191066_m()); this.field_76652_q[j >> 4] = extendedblockstorage; flag = j >= i1; @@ -317,6 +320,12 @@ - extendedblockstorage.func_177484_a(i, j & 15, k, p_177436_2_); + extendedblockstorage.func_177484_a(i, j & 15, k, state); ++ // RSMM start ++ if (CarpetSettings.redstoneMultimeter && !field_76637_e.field_72995_K) { ++ WorldHelper.getMultimeter().onBlockChange(field_76637_e, pos, iblockstate, state); ++ } ++ // RSMM end ++ if (block1 != block) { - if (!this.field_76637_e.field_72995_K) @@ -332,7 +341,7 @@ } } -@@ -537,13 +579,13 @@ +@@ -537,13 +587,13 @@ } else { @@ -348,7 +357,7 @@ int k1 = iblockstate.func_185891_c(); if (j1 > 0) -@@ -558,15 +600,17 @@ +@@ -558,15 +608,17 @@ this.func_76615_h(i, j, k); } @@ -371,7 +380,7 @@ if (tileentity != null) { -@@ -574,19 +618,30 @@ +@@ -574,19 +626,30 @@ } } @@ -407,17 +416,17 @@ } if (tileentity1 != null) -@@ -596,6 +651,9 @@ +@@ -596,6 +659,9 @@ } this.field_76643_l = true; + // ----- RSMM Start ----- // -+ if (CarpetSettings.redstoneMultimeter) { StateChangeEventDispatcher.dispatchEvent(this.func_177412_p(), pos); } ++ if (CarpetSettings.redstoneMultimeterLegacy) { StateChangeEventDispatcher.dispatchEvent(this.func_177412_p(), pos); } + // ----- RSMM End ----- // return iblockstate; } } -@@ -603,6 +661,7 @@ +@@ -603,6 +669,7 @@ public int func_177413_a(EnumSkyBlock p_177413_1_, BlockPos p_177413_2_) { @@ -425,7 +434,7 @@ int i = p_177413_2_.func_177958_n() & 15; int j = p_177413_2_.func_177956_o(); int k = p_177413_2_.func_177952_p() & 15; -@@ -633,7 +692,12 @@ +@@ -633,7 +700,12 @@ { extendedblockstorage = new ExtendedBlockStorage(j >> 4 << 4, this.field_76637_e.field_73011_w.func_191066_m()); this.field_76652_q[j >> 4] = extendedblockstorage; @@ -439,7 +448,7 @@ } this.field_76643_l = true; -@@ -653,6 +717,7 @@ +@@ -653,6 +725,7 @@ public int func_177443_a(BlockPos p_177443_1_, int p_177443_2_) { @@ -447,7 +456,7 @@ int i = p_177443_1_.func_177958_n() & 15; int j = p_177443_1_.func_177956_o(); int k = p_177443_1_.func_177952_p() & 15; -@@ -819,6 +884,10 @@ +@@ -819,6 +892,10 @@ { this.field_76637_e.func_175650_b(classinheritancemultimap); } @@ -458,7 +467,7 @@ } public void func_76623_d() -@@ -964,13 +1033,40 @@ +@@ -964,13 +1041,40 @@ { if (p_186034_1_.func_185933_a(this, this.field_76635_g, this.field_76647_h)) { @@ -500,7 +509,7 @@ this.func_76630_e(); } } -@@ -1018,10 +1114,13 @@ +@@ -1018,10 +1122,13 @@ this.field_150815_m = true; @@ -518,7 +527,7 @@ while (!this.field_177447_w.isEmpty()) { -@@ -1041,6 +1140,11 @@ +@@ -1041,6 +1148,11 @@ return this.field_150815_m && this.field_76646_k && this.field_150814_l; } @@ -530,7 +539,7 @@ public boolean func_186035_j() { return this.field_150815_m; -@@ -1389,4 +1493,67 @@ +@@ -1389,4 +1501,67 @@ QUEUED, CHECK; } diff --git a/patches/net/minecraft/world/end/DragonFightManager.java.patch b/patches/net/minecraft/world/end/DragonFightManager.java.patch index b8b1bdaf..8c2595c9 100644 --- a/patches/net/minecraft/world/end/DragonFightManager.java.patch +++ b/patches/net/minecraft/world/end/DragonFightManager.java.patch @@ -1,6 +1,13 @@ --- ../src-base/minecraft/net/minecraft/world/end/DragonFightManager.java +++ ../src-work/minecraft/net/minecraft/world/end/DragonFightManager.java -@@ -48,6 +48,8 @@ +@@ -45,9 +45,15 @@ + import net.minecraft.world.gen.feature.WorldGenEndGateway; + import net.minecraft.world.gen.feature.WorldGenEndPodium; + import net.minecraft.world.gen.feature.WorldGenSpikes; ++ ++import redstone.multimeter.common.TickTask; ++import redstone.multimeter.helper.WorldHelper; ++ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -9,7 +16,25 @@ public class DragonFightManager { private static final Logger field_186107_a = LogManager.getLogger(); -@@ -437,6 +439,8 @@ +@@ -149,6 +155,8 @@ + + public void func_186105_b() + { ++ WorldHelper.startTickTask(TickTask.DRAGON_FIGHT); // RSMM ++ + this.field_186109_c.func_186758_d(!this.field_186117_k); + + if (++this.field_186116_j >= 20) +@@ -244,6 +252,8 @@ + } + } + } ++ ++ WorldHelper.endTickTask(); // RSMM + } + + protected void func_186095_a(DragonSpawnManager p_186095_1_) +@@ -437,6 +447,8 @@ } } From 458ba712a83e914daeb19257b9b4951a8ca64c14 Mon Sep 17 00:00:00 2001 From: Joe Date: Tue, 22 Mar 2022 18:30:39 +0000 Subject: [PATCH 41/46] Fix BlockPistonBase.java.patch --- patches/net/minecraft/block/BlockPistonBase.java.patch | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/patches/net/minecraft/block/BlockPistonBase.java.patch b/patches/net/minecraft/block/BlockPistonBase.java.patch index 6692462a..099d96e2 100644 --- a/patches/net/minecraft/block/BlockPistonBase.java.patch +++ b/patches/net/minecraft/block/BlockPistonBase.java.patch @@ -228,7 +228,7 @@ } List list2 = blockpistonstructurehelper.func_177252_d(); -@@ -358,15 +468,76 @@ +@@ -358,15 +468,56 @@ --k; aiblockstate[k] = iblockstate; } @@ -286,7 +286,7 @@ --k; aiblockstate[k] = iblockstate2; } -@@ -397,6 +568,8 @@ +@@ -397,6 +548,8 @@ p_176319_1_.func_175685_c(blockpos2, Blocks.field_150332_K, false); } @@ -295,7 +295,7 @@ return true; } } -@@ -439,4 +612,27 @@ +@@ -439,4 +592,27 @@ p_193383_2_ = this.func_176221_a(p_193383_2_, p_193383_1_, p_193383_3_); return p_193383_2_.func_177229_b(field_176387_N) != p_193383_4_.func_176734_d() && ((Boolean)p_193383_2_.func_177229_b(field_176320_b)).booleanValue() ? BlockFaceShape.UNDEFINED : BlockFaceShape.SOLID; } From 0d064195b49290eff1e00c576e2727b8c01740db Mon Sep 17 00:00:00 2001 From: Joe Date: Tue, 22 Mar 2022 18:34:24 +0000 Subject: [PATCH 42/46] Bump version to v22_03_22 --- carpetmodSrc/carpet/CarpetSettings.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/carpetmodSrc/carpet/CarpetSettings.java b/carpetmodSrc/carpet/CarpetSettings.java index e3fcd4ed..f26a591f 100644 --- a/carpetmodSrc/carpet/CarpetSettings.java +++ b/carpetmodSrc/carpet/CarpetSettings.java @@ -45,7 +45,7 @@ public class CarpetSettings public static boolean locked = false; // TODO: replace these constants at build time - public static final String carpetVersion = "v22_02_09"; + public static final String carpetVersion = "v22_03_22"; public static final String minecraftVersion = "1.12.2"; public static final String mcpMappings = "39-1.12"; From dbcb395ad0d9c203477b8078636a9287c929b88b Mon Sep 17 00:00:00 2001 From: Joe Date: Tue, 16 Aug 2022 12:47:03 +0100 Subject: [PATCH 43/46] Add non-Java-8 warning, and fix World.getRandSeed for new Java versions --- carpetmodSrc/carpet/CarpetServer.java | 8 ++ .../carpet/utils/JavaVersionUtil.java | 118 ++++++++++++++++++ patches/net/minecraft/world/World.java.patch | 91 ++++++-------- 3 files changed, 166 insertions(+), 51 deletions(-) create mode 100644 carpetmodSrc/carpet/utils/JavaVersionUtil.java diff --git a/carpetmodSrc/carpet/CarpetServer.java b/carpetmodSrc/carpet/CarpetServer.java index 898cf49d..5d88c46c 100644 --- a/carpetmodSrc/carpet/CarpetServer.java +++ b/carpetmodSrc/carpet/CarpetServer.java @@ -23,6 +23,7 @@ import net.minecraft.server.MinecraftServer; import net.minecraft.util.Tuple; import net.minecraft.world.WorldServer; +import org.apache.logging.log4j.LogManager; import redstone.multimeter.server.MultimeterServer; public class CarpetServer // static for now - easier to handle all around the code, its one anyways @@ -44,6 +45,13 @@ public class CarpetServer // static for now - easier to handle all around the co public static void init(MinecraftServer server) //aka constructor of this static singleton class { + if (JavaVersionUtil.JAVA_VERSION != 8) + { + LogManager.getLogger().warn("!!!!!!!!!!"); + LogManager.getLogger().warn("1.12 TECH SERVERS SHOULD BE RUN USING JAVA 8, DETECTED JAVA " + JavaVersionUtil.JAVA_VERSION); + LogManager.getLogger().warn("!!!!!!!!!!"); + } + minecraft_server = server; pluginChannels = new PluginChannelManager(server); pluginChannels.register(PUBSUB_MESSENGER); diff --git a/carpetmodSrc/carpet/utils/JavaVersionUtil.java b/carpetmodSrc/carpet/utils/JavaVersionUtil.java new file mode 100644 index 00000000..1a18e604 --- /dev/null +++ b/carpetmodSrc/carpet/utils/JavaVersionUtil.java @@ -0,0 +1,118 @@ +package carpet.utils; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; + +public final class JavaVersionUtil { + public static final int JAVA_VERSION = getJavaVersion(); + + private JavaVersionUtil() {} + + private static int getJavaVersion() { + String version = System.getProperty("java.version"); + if (version.startsWith("1.")) { + // old format (Java 8 and below) + return version.charAt(2) - '0'; + } else { + // new format (Java 9 and above) + int dotIndex = version.indexOf('.'); + if (dotIndex == -1) { + return Integer.parseInt(version); + } else { + return Integer.parseInt(version.substring(0, dotIndex)); + } + } + } + + public static FieldAccessor objectFieldAccessor(Class ownerClass, String name, Class fieldType) { + Field field; + try { + field = ownerClass.getDeclaredField(name); + } catch (NoSuchFieldException e) { + throw new RuntimeException("Could not find field", e); + } + if (field.getType() != fieldType) { + throw new RuntimeException("Field has wrong type, expected \"" + fieldType.getName() + "\", got \"" + field.getType().getName() + "\""); + } + if (fieldType.isPrimitive()) { + throw new RuntimeException("objectFieldAccessor does not work for primitive field types"); + } + + try { + field.setAccessible(true); + } catch (RuntimeException e) { // InaccessibleObjectException + if (JAVA_VERSION <= 8) { + throw e; + } + long fieldOffset = UnsafeFieldAccessor.unsafe.objectFieldOffset(field); + return new UnsafeFieldAccessor<>(ownerClass, fieldOffset); + } + + try { + return new MethodHandleFieldAccessor<>(MethodHandles.lookup().unreflectGetter(field)); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + public interface FieldAccessor { + T get(Object instance); + } + + private static class MethodHandleFieldAccessor implements FieldAccessor { + private final MethodHandle getter; + + private MethodHandleFieldAccessor(MethodHandle getter) { + this.getter = getter; + } + + @SuppressWarnings("unchecked") + @Override + public T get(Object instance) { + try { + return (T) getter.invoke(instance); + } catch (Throwable e) { + throw new RuntimeException(e); + } + } + } + + private static class UnsafeFieldAccessor implements FieldAccessor { + private static final sun.misc.Unsafe unsafe = getUnsafe(); + + private final Class ownerClass; + private final long fieldOffset; + + private UnsafeFieldAccessor(Class ownerClass, long fieldOffset) { + this.ownerClass = ownerClass; + this.fieldOffset = fieldOffset; + } + + @SuppressWarnings("unchecked") + @Override + public T get(Object instance) { + return (T) unsafe.getObject(ownerClass.cast(instance), fieldOffset); + } + + private static sun.misc.Unsafe getUnsafe() { + try { + Field field = null; + for (Field f : sun.misc.Unsafe.class.getDeclaredFields()) { + if (Modifier.isStatic(f.getModifiers()) && f.getType() == sun.misc.Unsafe.class) { + field = f; + break; + } + } + if (field == null) { + throw new RuntimeException("Unable to get Unsafe instance"); + } + field.setAccessible(true); + return (sun.misc.Unsafe) field.get(null); + } catch (ReflectiveOperationException e) { + throw new RuntimeException("Unable to get Unsafe instance", e); + } + } + } +} diff --git a/patches/net/minecraft/world/World.java.patch b/patches/net/minecraft/world/World.java.patch index 8774b608..8cfc805c 100644 --- a/patches/net/minecraft/world/World.java.patch +++ b/patches/net/minecraft/world/World.java.patch @@ -1,6 +1,6 @@ --- ../src-base/minecraft/net/minecraft/world/World.java +++ ../src-work/minecraft/net/minecraft/world/World.java -@@ -4,13 +4,11 @@ +@@ -4,13 +4,10 @@ import com.google.common.base.MoreObjects; import com.google.common.base.Predicate; import com.google.common.collect.Lists; @@ -12,14 +12,13 @@ -import java.util.UUID; -import java.util.function.Supplier; + -+import java.lang.reflect.Field; +import java.util.*; +import java.util.concurrent.atomic.AtomicLong; + import javax.annotation.Nullable; import net.minecraft.advancements.AdvancementManager; import net.minecraft.advancements.FunctionManager; -@@ -60,10 +58,23 @@ +@@ -60,10 +57,23 @@ import net.minecraft.world.storage.WorldSavedData; import net.minecraft.world.storage.loot.LootTableManager; @@ -44,7 +43,7 @@ public final List field_72996_f = Lists.newArrayList(); protected final List field_72997_g = Lists.newArrayList(); public final List field_147482_g = Lists.newArrayList(); -@@ -75,7 +86,7 @@ +@@ -75,7 +85,7 @@ protected final IntHashMap field_175729_l = new IntHashMap(); private final long field_73001_c = 16777215L; private int field_73008_k; @@ -53,7 +52,7 @@ protected final int field_73006_m = 1013904223; protected float field_73003_n; protected float field_73004_o; -@@ -105,6 +116,13 @@ +@@ -105,6 +115,13 @@ private final WorldBorder field_175728_M; int[] field_72994_J; @@ -67,7 +66,7 @@ protected World(ISaveHandler p_i45749_1_, WorldInfo p_i45749_2_, WorldProvider p_i45749_3_, Profiler p_i45749_4_, boolean p_i45749_5_) { this.field_73021_x = Lists.newArrayList(this.field_184152_t); -@@ -119,6 +137,7 @@ +@@ -119,6 +136,7 @@ this.field_73011_w = p_i45749_3_; this.field_72995_K = p_i45749_5_; this.field_175728_M = p_i45749_3_.func_177501_r(); @@ -75,7 +74,7 @@ } public World func_175643_b() -@@ -269,7 +288,7 @@ +@@ -269,7 +287,7 @@ } } @@ -84,7 +83,7 @@ public Chunk func_175726_f(BlockPos p_175726_1_) { -@@ -286,6 +305,16 @@ +@@ -286,6 +304,16 @@ return this.func_175680_a(p_190526_1_, p_190526_2_, false) ? true : this.field_73020_y.func_191062_e(p_190526_1_, p_190526_2_); } @@ -101,7 +100,7 @@ public boolean func_180501_a(BlockPos p_180501_1_, IBlockState p_180501_2_, int p_180501_3_) { if (this.func_189509_E(p_180501_1_)) -@@ -300,7 +329,8 @@ +@@ -300,7 +328,8 @@ { Chunk chunk = this.func_175726_f(p_180501_1_); Block block = p_180501_2_.func_177230_c(); @@ -111,7 +110,7 @@ if (iblockstate == null) { -@@ -329,7 +359,8 @@ +@@ -329,7 +358,8 @@ this.func_175666_e(p_180501_1_, block); } } @@ -121,7 +120,7 @@ { this.func_190522_c(p_180501_1_, block); } -@@ -430,8 +461,36 @@ +@@ -430,8 +460,36 @@ this.func_190529_b(p_190522_1_.func_177968_d(), p_190522_2_, p_190522_1_); } @@ -158,7 +157,7 @@ this.func_190524_a(p_175685_1_.func_177976_e(), p_175685_2_, p_175685_1_); this.func_190524_a(p_175685_1_.func_177974_f(), p_175685_2_, p_175685_1_); this.func_190524_a(p_175685_1_.func_177977_b(), p_175685_2_, p_175685_1_); -@@ -447,6 +506,44 @@ +@@ -447,6 +505,44 @@ public void func_175695_a(BlockPos p_175695_1_, Block p_175695_2_, EnumFacing p_175695_3_) { @@ -203,7 +202,7 @@ if (p_175695_3_ != EnumFacing.WEST) { this.func_190524_a(p_175695_1_.func_177976_e(), p_175695_2_, p_175695_1_); -@@ -480,12 +577,18 @@ +@@ -480,12 +576,18 @@ public void func_190524_a(BlockPos p_190524_1_, final Block p_190524_2_, BlockPos p_190524_3_) { @@ -222,7 +221,7 @@ iblockstate.func_189546_a(this, p_190524_1_, p_190524_2_, p_190524_3_); } catch (Throwable throwable) -@@ -509,11 +612,21 @@ +@@ -509,11 +611,21 @@ CrashReportCategory.func_175750_a(crashreportcategory, p_190524_1_, iblockstate); throw new ReportedException(crashreport); } @@ -244,7 +243,7 @@ if (!this.field_72995_K) { IBlockState iblockstate = this.func_180495_p(p_190529_1_); -@@ -522,6 +635,7 @@ +@@ -522,6 +634,7 @@ { try { @@ -252,7 +251,7 @@ ((BlockObserver)iblockstate.func_177230_c()).func_190962_b(iblockstate, this, p_190529_1_, p_190529_2_, p_190529_3_); } catch (Throwable throwable) -@@ -546,6 +660,11 @@ +@@ -546,6 +659,11 @@ throw new ReportedException(crashreport); } } @@ -264,7 +263,7 @@ } } -@@ -1076,6 +1195,18 @@ +@@ -1076,6 +1194,18 @@ public void func_72900_e(Entity p_72900_1_) { @@ -283,7 +282,7 @@ if (p_72900_1_.func_184207_aI()) { p_72900_1_.func_184226_ay(); -@@ -1098,6 +1229,18 @@ +@@ -1098,6 +1228,18 @@ public void func_72973_f(Entity p_72973_1_) { @@ -302,7 +301,7 @@ p_72973_1_.func_184174_b(false); p_72973_1_.func_70106_y(); -@@ -1126,6 +1269,9 @@ +@@ -1126,6 +1268,9 @@ private boolean func_191504_a(@Nullable Entity p_191504_1_, AxisAlignedBB p_191504_2_, boolean p_191504_3_, @Nullable List p_191504_4_) { @@ -312,7 +311,7 @@ int i = MathHelper.func_76128_c(p_191504_2_.field_72340_a) - 1; int j = MathHelper.func_76143_f(p_191504_2_.field_72336_d) + 1; int k = MathHelper.func_76128_c(p_191504_2_.field_72338_b) - 1; -@@ -1338,7 +1484,9 @@ +@@ -1338,7 +1483,9 @@ { this.field_72984_F.func_76320_a("entities"); this.field_72984_F.func_76320_a("global"); @@ -322,7 +321,7 @@ for (int i = 0; i < this.field_73007_j.size(); ++i) { Entity entity = this.field_73007_j.get(i); -@@ -1346,6 +1494,7 @@ +@@ -1346,6 +1493,7 @@ try { ++entity.field_70173_aa; @@ -330,7 +329,7 @@ entity.func_70071_h_(); } catch (Throwable throwable2) -@@ -1370,6 +1519,9 @@ +@@ -1370,6 +1518,9 @@ this.field_73007_j.remove(i--); } } @@ -340,7 +339,7 @@ this.field_72984_F.func_76318_c("remove"); this.field_72996_f.removeAll(this.field_72997_g); -@@ -1393,11 +1545,14 @@ +@@ -1393,11 +1544,14 @@ this.field_72997_g.clear(); this.func_184147_l(); @@ -355,7 +354,7 @@ Entity entity3 = entity2.func_184187_bx(); if (entity3 != null) -@@ -1416,7 +1571,10 @@ +@@ -1416,7 +1570,10 @@ { try { @@ -367,7 +366,7 @@ } catch (Throwable throwable1) { -@@ -1437,31 +1595,51 @@ +@@ -1437,31 +1594,51 @@ if (entity2.field_70175_ag && this.func_175680_a(l1, i2, true)) { @@ -421,7 +420,7 @@ if (!tileentity.func_145837_r() && tileentity.func_145830_o()) { -@@ -1471,12 +1649,15 @@ +@@ -1471,12 +1648,15 @@ { try { @@ -443,7 +442,7 @@ } catch (Throwable throwable) { -@@ -1490,16 +1671,26 @@ +@@ -1490,16 +1670,26 @@ if (tileentity.func_145837_r()) { @@ -470,7 +469,7 @@ this.field_147481_N = false; this.field_72984_F.func_76318_c("pendingBlockEntities"); -@@ -1528,9 +1719,12 @@ +@@ -1528,9 +1718,12 @@ this.field_147484_a.clear(); } @@ -483,7 +482,7 @@ } protected void func_184147_l() -@@ -1602,11 +1796,16 @@ +@@ -1602,11 +1795,16 @@ if (p_72866_1_.func_184218_aH()) { @@ -502,7 +501,7 @@ } } -@@ -1648,7 +1847,8 @@ +@@ -1648,7 +1846,8 @@ this.func_72964_e(p_72866_1_.field_70176_ah, p_72866_1_.field_70164_aj).func_76608_a(p_72866_1_, p_72866_1_.field_70162_ai); } @@ -512,7 +511,7 @@ { p_72866_1_.field_70175_ag = false; } -@@ -1670,7 +1870,11 @@ +@@ -1670,7 +1869,11 @@ } else { @@ -525,7 +524,7 @@ } } } -@@ -1689,7 +1893,7 @@ +@@ -1689,7 +1892,7 @@ { Entity entity4 = list.get(j2); @@ -534,7 +533,7 @@ { return false; } -@@ -2153,6 +2357,16 @@ +@@ -2153,6 +2356,16 @@ { this.field_72986_A.func_76090_f(this.field_73012_v.nextInt(168000) + 12000); } @@ -551,7 +550,7 @@ } else { -@@ -2177,6 +2391,16 @@ +@@ -2177,6 +2390,16 @@ { this.field_72986_A.func_76080_g(this.field_73012_v.nextInt(168000) + 12000); } @@ -568,7 +567,7 @@ } else { -@@ -2387,6 +2611,11 @@ +@@ -2387,6 +2610,11 @@ public boolean func_180500_c(EnumSkyBlock p_180500_1_, BlockPos p_180500_2_) { @@ -580,7 +579,7 @@ if (!this.func_175648_a(p_180500_2_, 17, false)) { return false; -@@ -2699,7 +2928,8 @@ +@@ -2699,7 +2927,8 @@ IBlockState iblockstate1 = this.func_180495_p(p_190527_2_); AxisAlignedBB axisalignedbb = p_190527_3_ ? null : p_190527_1_.func_176223_P().func_185890_d(this, p_190527_2_); @@ -590,7 +589,7 @@ { return false; } -@@ -3267,30 +3497,43 @@ +@@ -3267,30 +3496,43 @@ public void func_175666_e(BlockPos p_175666_1_, Block p_175666_2_) { @@ -649,25 +648,15 @@ } public DifficultyInstance func_175649_E(BlockPos p_175649_1_) -@@ -3361,4 +3604,130 @@ +@@ -3361,4 +3603,120 @@ { return null; } + -+ AtomicLong scrambledSeed; ++ private static final carpet.utils.JavaVersionUtil.FieldAccessor SEED_ACCESSOR = ++ carpet.utils.JavaVersionUtil.objectFieldAccessor(Random.class, "seed", AtomicLong.class); + public long getRandSeed(){ -+ try -+ { -+ if(scrambledSeed == null) { -+ Field field = Random.class.getDeclaredField("seed"); -+ field.setAccessible(true); -+ scrambledSeed = (AtomicLong) field.get(field_73012_v); //this needs to be XOR'd with 0x5DEECE66DL -+ } -+ return scrambledSeed.get(); -+ // Minecraft.getMinecraft().player.sendChatMessage(chunk.x + ", " + chunk.z + ", seed " + theSeed); -+ } catch (Exception e) {} -+ -+ return 0; ++ return SEED_ACCESSOR.get(this.field_73012_v).get(); + } + + // Update Suppression crash fixes CARPET-XCOM From c4031199f404249f5bbfa5e71d04babd1fa97793 Mon Sep 17 00:00:00 2001 From: Noa Laznik Date: Sun, 11 Feb 2024 20:23:17 +0000 Subject: [PATCH 44/46] Make tick freeze work properly (#177) * Don't process block events in tick freeze * Tick freeze, freeze tick counter --- .../server/MinecraftServer.java.patch | 29 +++++---- .../minecraft/world/WorldServer.java.patch | 59 ++++++++++--------- 2 files changed, 48 insertions(+), 40 deletions(-) diff --git a/patches/net/minecraft/server/MinecraftServer.java.patch b/patches/net/minecraft/server/MinecraftServer.java.patch index ba816d3e..be240c52 100644 --- a/patches/net/minecraft/server/MinecraftServer.java.patch +++ b/patches/net/minecraft/server/MinecraftServer.java.patch @@ -206,9 +206,14 @@ this.field_71296_Q = true; } } -@@ -594,6 +658,15 @@ +@@ -592,8 +656,19 @@ + protected void func_71217_p() + { long i = System.nanoTime(); - ++this.field_71315_w; +- ++this.field_71315_w; ++ if (TickSpeed.process_entities){ // CM ++ ++this.field_71315_w; ++ } + CarpetServer.tick(this); + if (CarpetProfiler.tick_health_requested != 0L) @@ -222,7 +227,7 @@ if (this.field_71295_T) { this.field_71295_T = false; -@@ -620,13 +693,23 @@ +@@ -620,13 +695,23 @@ this.field_147147_p.func_151318_b().func_151330_a(agameprofile); } @@ -246,7 +251,7 @@ this.field_71304_b.func_76320_a("tallying"); this.field_71311_j[this.field_71315_w % 100] = System.nanoTime() - i; -@@ -645,12 +728,34 @@ +@@ -645,12 +730,34 @@ this.field_71304_b.func_76319_b(); this.field_71304_b.func_76319_b(); @@ -281,7 +286,7 @@ synchronized (this.field_175589_i) { while (!this.field_175589_i.isEmpty()) -@@ -658,8 +763,10 @@ +@@ -658,8 +765,10 @@ Util.func_181617_a(this.field_175589_i.poll(), field_147145_h); } } @@ -292,7 +297,7 @@ for (int j = 0; j < this.field_71305_c.length; ++j) { -@@ -672,6 +779,7 @@ +@@ -672,6 +781,7 @@ { return worldserver.func_72912_H().func_76065_j(); }); @@ -300,7 +305,7 @@ if (this.field_71315_w % 20 == 0) { -@@ -686,27 +794,46 @@ +@@ -686,27 +796,46 @@ { worldserver.func_72835_b(); } @@ -349,7 +354,7 @@ this.field_71304_b.func_76319_b(); this.field_71304_b.func_76319_b(); } -@@ -714,13 +841,19 @@ +@@ -714,13 +843,19 @@ this.field_71312_k[j][this.field_71315_w % 100] = System.nanoTime() - i; } @@ -369,7 +374,7 @@ for (int k = 0; k < this.field_71322_p.size(); ++k) { -@@ -728,6 +861,9 @@ +@@ -728,6 +863,9 @@ } this.field_71304_b.func_76319_b(); @@ -379,7 +384,7 @@ } public boolean func_71255_r() -@@ -939,7 +1075,7 @@ +@@ -939,7 +1077,7 @@ public String getServerModName() { @@ -388,7 +393,7 @@ } public CrashReport func_71230_b(CrashReport p_71230_1_) -@@ -1512,6 +1648,7 @@ +@@ -1512,6 +1650,7 @@ { if (this.func_152345_ab()) { @@ -396,7 +401,7 @@ this.func_184103_al().func_72389_g(); this.field_71305_c[0].func_184146_ak().func_186522_a(); this.func_191949_aK().func_192779_a(); -@@ -1523,4 +1660,9 @@ +@@ -1523,4 +1662,9 @@ this.func_152344_a(this::func_193031_aM); } } diff --git a/patches/net/minecraft/world/WorldServer.java.patch b/patches/net/minecraft/world/WorldServer.java.patch index e3104758..5e765253 100644 --- a/patches/net/minecraft/world/WorldServer.java.patch +++ b/patches/net/minecraft/world/WorldServer.java.patch @@ -154,7 +154,7 @@ int j = this.func_72967_a(1.0F); if (j != this.func_175657_ab()) -@@ -200,26 +262,106 @@ +@@ -200,26 +262,109 @@ this.func_175692_b(j); } @@ -241,9 +241,12 @@ + } this.field_72984_F.func_76319_b(); + ++ if (TickSpeed.process_entities) ++ { // CM indent + LagSpikeHelper.processLagSpikes(this, LagSpikeHelper.TickPhase.BLOCK_EVENT, LagSpikeHelper.PrePostSubPhase.PRE); this.func_147488_Z(); + LagSpikeHelper.processLagSpikes(this, LagSpikeHelper.TickPhase.BLOCK_EVENT, LagSpikeHelper.PrePostSubPhase.POST); ++ } //end indent + + WorldHelper.endTickTask(); // RSMM + @@ -263,7 +266,7 @@ } @Nullable -@@ -255,13 +397,22 @@ +@@ -255,13 +400,22 @@ ++j; } } @@ -288,7 +291,7 @@ this.field_73068_P = false; for (EntityPlayer entityplayer : this.field_73010_i.stream().filter(EntityPlayer::func_70608_bn).collect(Collectors.toList())) -@@ -273,6 +424,8 @@ +@@ -273,6 +427,8 @@ { this.func_73051_P(); } @@ -297,7 +300,7 @@ } private void func_73051_P() -@@ -287,6 +440,28 @@ +@@ -287,6 +443,28 @@ { if (this.field_73068_P && !this.field_72995_K) { @@ -326,7 +329,7 @@ for (EntityPlayer entityplayer : this.field_73010_i) { if (!entityplayer.func_175149_v() && !entityplayer.func_71026_bH()) -@@ -303,7 +478,7 @@ +@@ -303,7 +481,7 @@ } } @@ -335,7 +338,7 @@ { return this.func_72863_F().func_73149_a(p_175680_1_, p_175680_2_); } -@@ -344,6 +519,7 @@ +@@ -344,6 +522,7 @@ boolean flag = this.func_72896_J(); boolean flag1 = this.func_72911_I(); this.field_72984_F.func_76320_a("pollingChunks"); @@ -343,7 +346,7 @@ for (Iterator iterator = this.field_73063_M.func_187300_b(); iterator.hasNext(); this.field_72984_F.func_76319_b()) { -@@ -354,10 +530,18 @@ +@@ -354,10 +533,18 @@ this.field_72984_F.func_76318_c("checkNextLight"); chunk.func_76594_o(); this.field_72984_F.func_76318_c("tickChunk"); @@ -363,7 +366,7 @@ { this.field_73005_l = this.field_73005_l * 3 + 1013904223; int l = this.field_73005_l >> 2; -@@ -384,8 +568,9 @@ +@@ -384,8 +571,9 @@ } this.field_72984_F.func_76318_c("iceandsnow"); @@ -374,7 +377,7 @@ { this.field_73005_l = this.field_73005_l * 3 + 1013904223; int j2 = this.field_73005_l >> 2; -@@ -409,6 +594,7 @@ +@@ -409,6 +597,7 @@ } this.field_72984_F.func_76318_c("tickBlocks"); @@ -382,7 +385,7 @@ if (i > 0) { -@@ -429,7 +615,15 @@ +@@ -429,7 +618,15 @@ if (block.func_149653_t()) { @@ -399,7 +402,7 @@ } this.field_72984_F.func_76319_b(); -@@ -437,13 +631,15 @@ +@@ -437,13 +634,15 @@ } } } @@ -416,7 +419,7 @@ { BlockPos blockpos = this.func_175725_q(p_175736_1_); AxisAlignedBB axisalignedbb = (new AxisAlignedBB(blockpos, new BlockPos(blockpos.func_177958_n(), this.func_72800_K(), blockpos.func_177952_p()))).func_186662_g(3.0D); -@@ -472,13 +668,25 @@ +@@ -472,13 +671,25 @@ public boolean func_175691_a(BlockPos p_175691_1_, Block p_175691_2_) { @@ -444,7 +447,7 @@ return this.field_73064_N.contains(nextticklistentry); } -@@ -501,17 +709,29 @@ +@@ -501,17 +712,29 @@ if (iblockstate.func_185904_a() != Material.field_151579_a && iblockstate.func_177230_c() == p_175654_2_) { @@ -476,7 +479,7 @@ if (this.func_175667_e(p_175654_1_)) { -@@ -531,7 +751,13 @@ +@@ -531,7 +754,13 @@ public void func_180497_b(BlockPos p_180497_1_, Block p_180497_2_, int p_180497_3_, int p_180497_4_) { @@ -491,7 +494,7 @@ nextticklistentry.func_82753_a(p_180497_4_); Material material = p_180497_2_.func_176223_P().func_185904_a(); -@@ -549,7 +775,8 @@ +@@ -549,7 +778,8 @@ public void func_72939_s() { @@ -501,7 +504,7 @@ { if (this.field_80004_Q++ >= 300) { -@@ -567,6 +794,8 @@ +@@ -567,6 +797,8 @@ protected void func_184147_l() { @@ -510,7 +513,7 @@ super.func_184147_l(); this.field_72984_F.func_76318_c("players"); -@@ -621,6 +850,8 @@ +@@ -621,6 +853,8 @@ this.field_72984_F.func_76319_b(); } @@ -519,7 +522,7 @@ } public void func_82742_i() -@@ -644,9 +875,18 @@ +@@ -644,9 +878,18 @@ } else { @@ -540,7 +543,7 @@ } this.field_72984_F.func_76320_a("cleaning"); -@@ -677,12 +917,15 @@ +@@ -677,12 +920,15 @@ if (this.func_175707_a(nextticklistentry1.field_180282_a.func_177982_a(0, 0, 0), nextticklistentry1.field_180282_a.func_177982_a(0, 0, 0))) { @@ -556,7 +559,7 @@ iblockstate.func_177230_c().func_180650_b(this, nextticklistentry1.field_180282_a, iblockstate, this.field_73012_v); } catch (Throwable throwable) -@@ -699,6 +942,7 @@ +@@ -699,6 +945,7 @@ this.func_175684_a(nextticklistentry1.field_180282_a, nextticklistentry1.func_151351_a(), 0); } } @@ -564,7 +567,7 @@ this.field_72984_F.func_76319_b(); this.field_94579_S.clear(); -@@ -950,11 +1194,18 @@ +@@ -950,11 +1197,18 @@ chunkproviderserver.func_186027_a(p_73044_1_); @@ -584,7 +587,7 @@ } } } -@@ -1033,9 +1284,15 @@ +@@ -1033,9 +1287,15 @@ } else { @@ -600,7 +603,7 @@ return false; } -@@ -1055,6 +1312,7 @@ +@@ -1055,6 +1315,7 @@ this.field_175729_l.func_76038_a(p_72923_1_.func_145782_y(), p_72923_1_); this.field_175741_N.put(p_72923_1_.func_110124_au(), p_72923_1_); Entity[] aentity = p_72923_1_.func_70021_al(); @@ -608,7 +611,7 @@ if (aentity != null) { -@@ -1139,10 +1397,15 @@ +@@ -1139,10 +1400,15 @@ } this.field_147490_S[this.field_147489_T].add(blockeventdata); @@ -624,7 +627,7 @@ while (!this.field_147490_S[this.field_147489_T].isEmpty()) { int i = this.field_147489_T; -@@ -1150,19 +1413,33 @@ +@@ -1150,19 +1416,33 @@ for (BlockEventData blockeventdata : this.field_147490_S[i]) { @@ -658,7 +661,7 @@ return iblockstate.func_177230_c() == p_147485_1_.func_151337_f() ? iblockstate.func_189547_a(this, p_147485_1_.func_180328_a(), p_147485_1_.func_151339_d(), p_147485_1_.func_151338_e()) : false; } -@@ -1173,6 +1450,8 @@ +@@ -1173,6 +1453,8 @@ protected void func_72979_l() { @@ -667,7 +670,7 @@ boolean flag = this.func_72896_J(); super.func_72979_l(); -@@ -1200,6 +1479,8 @@ +@@ -1200,6 +1482,8 @@ this.field_73061_a.func_184103_al().func_148540_a(new SPacketChangeGameState(7, this.field_73004_o)); this.field_73061_a.func_184103_al().func_148540_a(new SPacketChangeGameState(8, this.field_73017_q)); } @@ -676,7 +679,7 @@ } @Nullable -@@ -1299,4 +1580,19 @@ +@@ -1299,4 +1583,19 @@ { } } From c382a2ff1c8ed9982ec532c8ca65af7220332d46 Mon Sep 17 00:00:00 2001 From: Space Walker <48224626+SpaceWalkerRS@users.noreply.github.com> Date: Wed, 10 Apr 2024 18:47:54 +0200 Subject: [PATCH 45/46] update RSMM to v1.14 (#181) --- .../multimeter/RedstoneMultimeter.java | 3 +- .../redstone/multimeter/block/Meterable.java | 5 +- .../multimeter/block/MeterableBlock.java | 4 +- .../multimeter/block/PowerSource.java | 6 +- .../multimeter/command/MeterGroupCommand.java | 384 ++++++++-------- .../redstone/multimeter/common/DimPos.java | 120 +++-- .../redstone/multimeter/common/PruneType.java | 19 + .../redstone/multimeter/common/TickPhase.java | 62 +-- .../multimeter/common/TickPhaseTree.java | 165 +++++-- .../redstone/multimeter/common/TickTask.java | 111 ++--- .../multimeter/common/meter/ColorPicker.java | 36 ++ .../multimeter/common/meter/Meter.java | 78 ++-- .../multimeter/common/meter/MeterGroup.java | 161 ++++--- .../common/meter/MeterProperties.java | 120 +++-- .../common/meter/MeterPropertiesManager.java | 22 +- .../common/meter/event/EventType.java | 41 +- .../common/meter/event/MeterEvent.java | 23 +- .../multimeter/common/meter/log/EventLog.java | 47 +- .../common/meter/log/LogManager.java | 6 +- .../common/meter/log/MeterLogs.java | 131 +++--- .../common/network/AbstractPacketHandler.java | 53 --- .../common/network/PacketHandler.java | 46 ++ .../common/network/PacketManager.java | 43 -- .../multimeter/common/network/Packets.java | 43 ++ .../multimeter/common/network/RSMMPacket.java | 10 +- .../network/packets/AddMeterPacket.java | 15 +- .../packets/ClearMeterGroupPacket.java | 14 +- .../network/packets/HandshakePacket.java | 14 +- .../packets/MeterGroupDefaultPacket.java | 14 +- .../packets/MeterGroupRefreshPacket.java | 17 +- .../packets/MeterGroupSubscriptionPacket.java | 27 +- .../network/packets/MeterIndexPacket.java | 38 ++ .../network/packets/MeterLogsPacket.java | 26 +- .../network/packets/MeterUpdatePacket.java | 15 +- .../network/packets/MeterUpdatesPacket.java | 99 +++-- .../packets/RebuildTickPhaseTreePacket.java | 26 ++ .../network/packets/RemoveMeterPacket.java | 15 +- .../packets/TeleportToMeterPacket.java | 15 +- .../network/packets/TickPhaseTreePacket.java | 15 +- ...verTickPacket.java => TickTimePacket.java} | 30 +- .../multimeter/helper/WorldHelper.java | 58 +-- .../multimeter/interfaces/IBlock.java | 16 +- .../registry/SupplierClazzRegistry.java | 52 --- .../multimeter/registry/SupplierRegistry.java | 51 +++ .../multimeter/server/Multimeter.java | 416 +++++++++--------- .../multimeter/server/MultimeterServer.java | 258 +++++------ .../multimeter/server/PlayerList.java | 138 ++++++ .../server/ServerPacketHandler.java | 50 +-- .../server/meter/ServerMeterGroup.java | 206 +++++---- .../meter/ServerMeterPropertiesManager.java | 18 +- .../server/meter/log/ServerLogManager.java | 100 +++-- .../multimeter/server/option/Options.java | 26 +- .../server/option/OptionsManager.java | 40 +- .../redstone/multimeter/util/AxisUtils.java | 6 +- .../redstone/multimeter/util/ColorUtils.java | 68 ++- .../multimeter/util/DimensionUtils.java | 40 -- .../redstone/multimeter/util/ListUtils.java | 18 +- .../redstone/multimeter/util/NbtUtils.java | 23 +- .../redstone/multimeter/util/TextUtils.java | 25 -- jsons/1.12.2.json | 2 +- .../minecraft/block/BlockButton.java.patch | 4 +- .../net/minecraft/block/BlockChest.java.patch | 10 +- .../block/BlockDaylightDetector.java.patch | 4 +- .../minecraft/block/BlockDispenser.java.patch | 8 +- .../net/minecraft/block/BlockDoor.java.patch | 10 +- .../block/BlockEndPortalFrame.java.patch | 2 +- .../minecraft/block/BlockFenceGate.java.patch | 6 +- .../minecraft/block/BlockHopper.java.patch | 16 +- .../net/minecraft/block/BlockLever.java.patch | 4 +- .../net/minecraft/block/BlockNote.java.patch | 8 +- .../minecraft/block/BlockObserver.java.patch | 4 +- .../block/BlockPistonBase.java.patch | 12 +- .../block/BlockPressurePlate.java.patch | 4 +- .../BlockPressurePlateWeighted.java.patch | 4 +- .../block/BlockRailDetector.java.patch | 4 +- .../block/BlockRailPowered.java.patch | 8 +- .../block/BlockRedstoneComparator.java.patch | 31 +- .../block/BlockRedstoneDiode.java.patch | 8 +- .../block/BlockRedstoneLight.java.patch | 4 +- .../block/BlockRedstoneOre.java.patch | 2 +- .../block/BlockRedstoneRepeater.java.patch | 4 +- .../block/BlockRedstoneTorch.java.patch | 10 +- .../block/BlockRedstoneWire.java.patch | 10 +- .../minecraft/block/BlockTrapDoor.java.patch | 6 +- .../minecraft/block/BlockTripWire.java.patch | 2 +- .../block/BlockTripWireHook.java.patch | 4 +- .../network/NetHandlerPlayServer.java.patch | 6 +- .../server/MinecraftServer.java.patch | 50 +-- .../server/management/PlayerList.java.patch | 35 +- .../TileEntityComparator.java.patch | 2 +- .../tileentity/TileEntityHopper.java.patch | 57 ++- patches/net/minecraft/world/World.java.patch | 41 +- .../minecraft/world/WorldServer.java.patch | 123 ++++-- 93 files changed, 2251 insertions(+), 1982 deletions(-) create mode 100644 carpetmodSrc/redstone/multimeter/common/PruneType.java create mode 100644 carpetmodSrc/redstone/multimeter/common/meter/ColorPicker.java delete mode 100644 carpetmodSrc/redstone/multimeter/common/network/AbstractPacketHandler.java create mode 100644 carpetmodSrc/redstone/multimeter/common/network/PacketHandler.java delete mode 100644 carpetmodSrc/redstone/multimeter/common/network/PacketManager.java create mode 100644 carpetmodSrc/redstone/multimeter/common/network/Packets.java create mode 100644 carpetmodSrc/redstone/multimeter/common/network/packets/MeterIndexPacket.java create mode 100644 carpetmodSrc/redstone/multimeter/common/network/packets/RebuildTickPhaseTreePacket.java rename carpetmodSrc/redstone/multimeter/common/network/packets/{ServerTickPacket.java => TickTimePacket.java} (51%) delete mode 100644 carpetmodSrc/redstone/multimeter/registry/SupplierClazzRegistry.java create mode 100644 carpetmodSrc/redstone/multimeter/registry/SupplierRegistry.java create mode 100644 carpetmodSrc/redstone/multimeter/server/PlayerList.java delete mode 100644 carpetmodSrc/redstone/multimeter/util/DimensionUtils.java delete mode 100644 carpetmodSrc/redstone/multimeter/util/TextUtils.java diff --git a/carpetmodSrc/redstone/multimeter/RedstoneMultimeter.java b/carpetmodSrc/redstone/multimeter/RedstoneMultimeter.java index 79e2f392..2af088dc 100644 --- a/carpetmodSrc/redstone/multimeter/RedstoneMultimeter.java +++ b/carpetmodSrc/redstone/multimeter/RedstoneMultimeter.java @@ -6,9 +6,8 @@ public class RedstoneMultimeter { public static final String MOD_NAME = "Redstone Multimeter"; - public static final String MOD_VERSION = "1.6.0"; + public static final String MOD_VERSION = "1.14.0"; public static final String NAMESPACE = "redstone_multimeter"; - public static final String MINECRAFT_NAMESPACE = "minecraft"; public static final String CONFIG_PATH = "config/" + NAMESPACE; public static final Logger LOGGER = LogManager.getLogger(MOD_NAME); diff --git a/carpetmodSrc/redstone/multimeter/block/Meterable.java b/carpetmodSrc/redstone/multimeter/block/Meterable.java index accfee2d..18135d7c 100644 --- a/carpetmodSrc/redstone/multimeter/block/Meterable.java +++ b/carpetmodSrc/redstone/multimeter/block/Meterable.java @@ -3,15 +3,16 @@ import net.minecraft.block.state.IBlockState; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; + import redstone.multimeter.interfaces.IBlock; public interface Meterable extends IBlock { @Override - default boolean isMeterable() { + default boolean rsmm$isMeterable() { return true; } - public boolean isActive(World world, BlockPos pos, IBlockState state); + public boolean rsmm$isActive(World world, BlockPos pos, IBlockState state); } diff --git a/carpetmodSrc/redstone/multimeter/block/MeterableBlock.java b/carpetmodSrc/redstone/multimeter/block/MeterableBlock.java index bb33ff89..ffb91cb7 100644 --- a/carpetmodSrc/redstone/multimeter/block/MeterableBlock.java +++ b/carpetmodSrc/redstone/multimeter/block/MeterableBlock.java @@ -10,13 +10,13 @@ public interface MeterableBlock extends Meterable { - default void logPowered(World world, BlockPos pos, boolean powered) { + default void rsmm$logPowered(World world, BlockPos pos, boolean powered) { if (CarpetSettings.redstoneMultimeter && !world.isRemote) { WorldHelper.getMultimeter().logPowered(world, pos, powered); } } - default void logPowered(World world, BlockPos pos, IBlockState state) { + default void rsmm$logPowered(World world, BlockPos pos, IBlockState state) { if (CarpetSettings.redstoneMultimeter && !world.isRemote) { WorldHelper.getMultimeter().logPowered(world, pos, state); } diff --git a/carpetmodSrc/redstone/multimeter/block/PowerSource.java b/carpetmodSrc/redstone/multimeter/block/PowerSource.java index af06f826..888a1176 100644 --- a/carpetmodSrc/redstone/multimeter/block/PowerSource.java +++ b/carpetmodSrc/redstone/multimeter/block/PowerSource.java @@ -11,14 +11,14 @@ public interface PowerSource extends IBlock { public static final int MAX_POWER = 15; @Override - default boolean isPowerSource() { + default boolean rsmm$isPowerSource() { return true; } - default boolean logPowerChangeOnStateChange() { + default boolean rsmm$logPowerChangeOnStateChange() { return true; } - public int getPowerLevel(World world, BlockPos pos, IBlockState state); + public int rsmm$getPowerLevel(World world, BlockPos pos, IBlockState state); } diff --git a/carpetmodSrc/redstone/multimeter/command/MeterGroupCommand.java b/carpetmodSrc/redstone/multimeter/command/MeterGroupCommand.java index b55256ef..5b7ad410 100644 --- a/carpetmodSrc/redstone/multimeter/command/MeterGroupCommand.java +++ b/carpetmodSrc/redstone/multimeter/command/MeterGroupCommand.java @@ -8,6 +8,7 @@ import java.util.Map; import java.util.Map.Entry; import java.util.UUID; +import java.util.function.Function; import net.minecraft.command.CommandBase; import net.minecraft.command.CommandException; @@ -26,76 +27,62 @@ import redstone.multimeter.server.meter.ServerMeterGroup; public class MeterGroupCommand extends CommandBase { - + private static final String COMMAND_NAME = "metergroup"; private static final String USAGE_LIST = singleUsage("list"); - + private static final String USAGE_SUBSCRIBE_DEFAULT = singleUsage("subscribe"); private static final String USAGE_SUBSCRIBE_NAME = singleUsage("subscribe "); private static final String USAGE_SUBSCRIBE = buildUsage(USAGE_SUBSCRIBE_DEFAULT, USAGE_SUBSCRIBE_NAME); - + private static final String USAGE_UNSUBSCRIBE = singleUsage("unsubscribe"); - + private static final String USAGE_PRIVATE_QUERY = singleUsage("private"); private static final String USAGE_PRIVATE_SET = singleUsage("private "); private static final String USAGE_PRIVATE = buildUsage(USAGE_PRIVATE_QUERY, USAGE_PRIVATE_SET); - + private static final String USAGE_MEMBERS_LIST = singleUsage("members list"); private static final String USAGE_MEMBERS_ADD = singleUsage("members add "); private static final String USAGE_MEMBERS_REMOVE = singleUsage("members remove "); private static final String USAGE_MEMBERS_CLEAR = singleUsage("members clear"); private static final String USAGE_MEMBERS = buildUsage(USAGE_MEMBERS_LIST, USAGE_MEMBERS_ADD, USAGE_MEMBERS_REMOVE, USAGE_MEMBERS_CLEAR); - + private static final String USAGE_CLEAR = singleUsage("clear"); - - private static final String TOTAL_USAGE_MEMBER = buildUsage(USAGE_LIST, USAGE_SUBSCRIBE, USAGE_UNSUBSCRIBE, USAGE_CLEAR); - private static final String TOTAL_USAGE_OWNER = buildUsage(USAGE_LIST, USAGE_SUBSCRIBE, USAGE_UNSUBSCRIBE, USAGE_PRIVATE, USAGE_MEMBERS, USAGE_CLEAR); - + + private static final String TOTAL_USAGE_MEMBER = buildUsage(USAGE_LIST, USAGE_SUBSCRIBE, USAGE_UNSUBSCRIBE, USAGE_CLEAR); + private static final String TOTAL_USAGE_OWNER = buildUsage(USAGE_LIST, USAGE_SUBSCRIBE, USAGE_UNSUBSCRIBE, USAGE_PRIVATE, USAGE_MEMBERS, USAGE_CLEAR); + private static String singleUsage(String usage) { return String.format("/%s %s", COMMAND_NAME, usage); } - + private static String buildUsage(String... usages) { return String.join(" OR ", usages); } - + private final MultimeterServer server; private final Multimeter multimeter; - + public MeterGroupCommand(MultimeterServer server) { this.server = server; this.multimeter = this.server.getMultimeter(); } - + @Override public String getName() { return COMMAND_NAME; } @Override - public String getUsage(ICommandSender sender) { - try { - if (isOwnerOfSubscription(sender)) { - return TOTAL_USAGE_OWNER; - } - } catch (CommandException e) { - - } - - return TOTAL_USAGE_MEMBER; + public String getUsage(ICommandSender source) { + return isOwnerOfSubscription(source) ? TOTAL_USAGE_OWNER : TOTAL_USAGE_MEMBER; } - + @Override - public List getTabCompletions(MinecraftServer minecraftServer, ICommandSender sender, String[] args, BlockPos pos) { - boolean isOwner = false; - - try { - isOwner = isOwnerOfSubscription(sender); - } catch (CommandException e) { - - } - + public List getTabCompletions(MinecraftServer server, ICommandSender source, String[] args, BlockPos pos) { + boolean isOwner = isOwnerOfSubscription(source); + switch (args.length) { case 1: if (isOwner) { @@ -106,389 +93,374 @@ public List getTabCompletions(MinecraftServer minecraftServer, ICommandS case 2: switch (args[0]) { case "subscribe": - try { - return getListOfStringsMatchingLastWord(args, listMeterGroups(sender)); - } catch (CommandException e) { - - } - - break; + return getListOfStringsMatchingLastWord(args, listMeterGroups(source)); case "private": if (isOwner) { return getListOfStringsMatchingLastWord(args, "true", "false"); } - + break; case "members": if (isOwner) { return getListOfStringsMatchingLastWord(args, "clear", "add", "remove", "list"); } - + break; } - + break; case 3: if (isOwner && args[0].equals("members")) { switch (args[1]) { case "add": - return getListOfStringsMatchingLastWord(args, minecraftServer.getOnlinePlayerNames()); + return getListOfStringsMatchingLastWord(args, server.getOnlinePlayerNames()); case "remove": - try { - return getListOfStringsMatchingLastWord(args, listMembers(sender).keySet()); - } catch (CommandException e) { - - } - - break; + return getListOfStringsMatchingLastWord(args, listMembers(source).keySet()); } } - + break; } - + return Collections.emptyList(); } @Override - public void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException { - if (!isMultimeterClient(sender)) { + public void execute(MinecraftServer server, ICommandSender source, String[] args) throws CommandException { + if (!isMultimeterClient(source)) { throw new CommandNotFoundException(); } - + if (args.length > 0) { switch (args[0]) { case "list": if (args.length == 1) { - list(sender); + list(source); return; } - + throw new WrongUsageException(USAGE_LIST); case "subscribe": if (args.length == 1) { - subscribe(sender, null); + subscribe(source, null); return; } - + String name = ""; - + for (int index = 1; index < args.length; index++) { name += args[index] + " "; } - - subscribe(sender, name); + + subscribe(source, name); return; case "unsubscribe": if (args.length == 1) { - unsubscribe(sender); + unsubscribe(source); return; } - + throw new WrongUsageException(USAGE_UNSUBSCRIBE); case "private": - if (!isOwnerOfSubscription(sender)) { + if (!isOwnerOfSubscription(source)) { break; } - + switch (args.length) { case 1: - queryPrivate(sender); + queryPrivate(source); return; case 2: switch (args[1]) { case "true": - setPrivate(sender, true); + setPrivate(source, true); return; case "false": - setPrivate(sender, false); + setPrivate(source, false); return; } - + throw new WrongUsageException(USAGE_PRIVATE_SET); } - + throw new WrongUsageException(USAGE_PRIVATE); case "members": - if (!isOwnerOfSubscription(sender)) { + if (!isOwnerOfSubscription(source)) { break; } - + if (args.length > 1) { switch (args[1]) { case "list": if (args.length == 2) { - membersList(sender); + membersList(source); return; } - + throw new WrongUsageException(USAGE_MEMBERS_LIST); case "add": if (args.length == 3) { - membersAdd(sender, getPlayers(server, sender, args[2])); + membersAdd(source, getPlayers(server, source, args[2])); return; } - + throw new WrongUsageException(USAGE_MEMBERS_ADD); case "remove": if (args.length == 3) { - membersRemove(sender, args[2]); + membersRemovePlayer(source, args[2]); return; } - + throw new WrongUsageException(USAGE_MEMBERS_REMOVE); case "clear": if (args.length == 2) { - membersClear(sender); + membersClear(source); return; } - + throw new WrongUsageException(USAGE_MEMBERS_CLEAR); } } - + throw new WrongUsageException(USAGE_MEMBERS); case "clear": if (args.length == 1) { - clear(sender); + clear(source); return; } - + throw new WrongUsageException(USAGE_CLEAR); } } - - throw new WrongUsageException(getUsage(sender)); + + throw new WrongUsageException(getUsage(source)); } - - private boolean isMultimeterClient(ICommandSender sender) throws CommandException { - return execute(sender, player -> multimeter.getMultimeterServer().isMultimeterClient(player)); + + private boolean isMultimeterClient(ICommandSender source) { + return run(source, player -> server.isMultimeterClient(player)); } - - private boolean isOwnerOfSubscription(ICommandSender sender) throws CommandException { - return execute(sender, player -> multimeter.isOwnerOfSubscription(player)); + + private boolean isOwnerOfSubscription(ICommandSender source) { + return run(source, player -> multimeter.isOwnerOfSubscription(player)); } - - private Collection listMeterGroups(ICommandSender sender) throws CommandException { + + private Collection listMeterGroups(ICommandSender source) { List names = new ArrayList<>(); - - command(sender, player -> { + + command(source, player -> { for (ServerMeterGroup meterGroup : multimeter.getMeterGroups()) { if (!meterGroup.isPrivate() || meterGroup.hasMember(player) || meterGroup.isOwnedBy(player)) { names.add(meterGroup.getName()); } } }); - + return names; } - - private Map listMembers(ICommandSender sender) throws CommandException { + + private Map listMembers(ICommandSender source) { Map names = new HashMap<>(); - - command(sender, player -> { + + command(source, player -> { ServerMeterGroup meterGroup = multimeter.getSubscription(player); - + if (meterGroup != null && meterGroup.isOwnedBy(player)) { for (UUID playerUUID : meterGroup.getMembers()) { - String playerName = multimeter.getMultimeterServer().getPlayerName(playerUUID); - + String playerName = multimeter.getServer().getPlayerList().getName(playerUUID); + if (playerName != null) { names.put(playerName, playerUUID); } } } }); - + return names; } - - private void list(ICommandSender sender) throws CommandException { - Collection names = listMeterGroups(sender); - + + private void list(ICommandSender source) { + Collection names = listMeterGroups(source); + if (names.isEmpty()) { - sender.sendMessage(new TextComponentString("There are no meter groups yet!")); + source.sendMessage(new TextComponentString("There are no meter groups yet!")); } else { String message = "Meter groups:\n " + String.join("\n ", names); - sender.sendMessage(new TextComponentString(message)); + source.sendMessage(new TextComponentString(message)); } } - - private void subscribe(ICommandSender sender, String name) throws CommandException { - command(sender, player -> { + + private void subscribe(ICommandSender source, String name) { + command(source, player -> { if (name == null) { multimeter.subscribeToDefaultMeterGroup(player); - sender.sendMessage(new TextComponentString("Subscribed to default meter group")); + source.sendMessage(new TextComponentString("Subscribed to default meter group")); } else if (multimeter.hasMeterGroup(name)) { ServerMeterGroup meterGroup = multimeter.getMeterGroup(name); - + if (!meterGroup.isPrivate() || meterGroup.hasMember(player) || meterGroup.isOwnedBy(player)) { multimeter.subscribeToMeterGroup(meterGroup, player); - sender.sendMessage(new TextComponentString(String.format("Subscribed to meter group \'%s\'", name))); + source.sendMessage(new TextComponentString(String.format("Subscribed to meter group \'%s\'", name))); } else { - sender.sendMessage(new TextComponentString("That meter group is private!")); + source.sendMessage(new TextComponentString("That meter group is private!")); } } else { if (MeterGroup.isValidName(name)) { multimeter.createMeterGroup(player, name); - sender.sendMessage(new TextComponentString(String.format("Created meter group \'%s\'", name))); + source.sendMessage(new TextComponentString(String.format("Created meter group \'%s\'", name))); } else { - sender.sendMessage(new TextComponentString(String.format("\'%s\' is not a valid meter group name!", name))); + source.sendMessage(new TextComponentString(String.format("\'%s\' is not a valid meter group name!", name))); } } }); } - - private void unsubscribe(ICommandSender sender) throws CommandException { - command(sender, (meterGroup, player) -> { + + private void unsubscribe(ICommandSender source) { + command(source, (meterGroup, player) -> { multimeter.unsubscribeFromMeterGroup(meterGroup, player); - sender.sendMessage(new TextComponentString(String.format("Unsubscribed from meter group \'%s\'", meterGroup.getName()))); + source.sendMessage(new TextComponentString(String.format("Unsubscribed from meter group \'%s\'", meterGroup.getName()))); }); } - - private void queryPrivate(ICommandSender sender) throws CommandException { - command(sender, (meterGroup, player) -> { + + private void queryPrivate(ICommandSender source) { + command(source, (meterGroup, player) -> { String status = meterGroup.isPrivate() ? "private" : "public"; - sender.sendMessage(new TextComponentString(String.format("Meter group \'%s\' is %s", meterGroup.getName(), status))); + source.sendMessage(new TextComponentString(String.format("Meter group \'%s\' is %s", meterGroup.getName(), status))); }); } - - private void setPrivate(ICommandSender sender, boolean isPrivate) throws CommandException { - command(sender, (meterGroup, player) -> { + + private void setPrivate(ICommandSender source, boolean isPrivate) { + command(source, (meterGroup, player) -> { if (meterGroup.isOwnedBy(player)) { meterGroup.setPrivate(isPrivate); - sender.sendMessage(new TextComponentString(String.format("Meter group \'%s\' is now %s", meterGroup.getName(), (isPrivate ? "private" : "public")))); + source.sendMessage(new TextComponentString(String.format("Meter group \'%s\' is now %s", meterGroup.getName(), (isPrivate ? "private" : "public")))); } else { - sender.sendMessage(new TextComponentString("Only the owner of a meter group can change its privacy!")); + source.sendMessage(new TextComponentString("Only the owner of a meter group can change its privacy!")); } }); } - - private void membersList(ICommandSender sender) throws CommandException { - Map members = listMembers(sender); - - commandMembers(sender, (meterGroup, owner) -> { + + private void membersList(ICommandSender source) { + Map members = listMembers(source); + + commandMembers(source, (meterGroup, owner) -> { if (members.isEmpty()) { - sender.sendMessage(new TextComponentString(String.format("Meter group \'%s\' has no members yet!", meterGroup.getName()))); + source.sendMessage(new TextComponentString(String.format("Meter group \'%s\' has no members yet!", meterGroup.getName()))); } else { String message = String.format("Members of meter group \'%s\':\n ", meterGroup.getName()) + String.join("\n ", members.keySet()); - sender.sendMessage(new TextComponentString(message)); + source.sendMessage(new TextComponentString(message)); } }); } - - private void membersAdd(ICommandSender sender, Collection players) throws CommandException { - commandMembers(sender, (meterGroup, owner) -> { + + private void membersAdd(ICommandSender source, Collection players) { + commandMembers(source, (meterGroup, owner) -> { for (EntityPlayerMP player : players) { if (player == owner) { - sender.sendMessage(new TextComponentString("You cannot add yourself as a member!")); + source.sendMessage(new TextComponentString("You cannot add yourself as a member!")); } else if (meterGroup.hasMember(player)) { - sender.sendMessage(new TextComponentString(String.format("Player \'%s\' is already a member of meter group \'%s\'!", player.getName(), meterGroup.getName()))); - } else if (!multimeter.getMultimeterServer().isMultimeterClient(player)) { - sender.sendMessage(new TextComponentString(String.format("You cannot add player \'%s\' as a member; they do not have %s installed!", player.getName(), RedstoneMultimeter.MOD_NAME))); + source.sendMessage(new TextComponentString(String.format("Player \'%s\' is already a member of meter group \'%s\'!", player.getName(), meterGroup.getName()))); + } else if (!multimeter.getServer().isMultimeterClient(player)) { + source.sendMessage(new TextComponentString(String.format("You cannot add player \'%s\' as a member; they do not have %s installed!", player.getName(), RedstoneMultimeter.MOD_NAME))); } else { multimeter.addMemberToMeterGroup(meterGroup, player.getUniqueID()); - sender.sendMessage(new TextComponentString(String.format("Player \'%s\' is now a member of meter group \'%s\'", player.getName(), meterGroup.getName()))); + source.sendMessage(new TextComponentString(String.format("Player \'%s\' is now a member of meter group \'%s\'", player.getName(), meterGroup.getName()))); } } }); } - - private void membersRemove(ICommandSender sender, String playerName) throws CommandException { - commandMembers(sender, (meterGroup, owner) -> { - Entry member = findMember(listMembers(sender), playerName); - + + private void membersRemovePlayer(ICommandSender source, String playerName) { + commandMembers(source, (meterGroup, owner) -> { + Entry member = findMember(listMembers(source), playerName); + if (member == null) { - EntityPlayerMP player = multimeter.getMultimeterServer().getPlayer(playerName); - + EntityPlayerMP player = multimeter.getServer().getPlayerList().get(playerName); + if (player == owner) { - sender.sendMessage(new TextComponentString("You cannot remove yourself as a member!")); + source.sendMessage(new TextComponentString("You cannot remove yourself as a member!")); } else { - sender.sendMessage(new TextComponentString(String.format("Meter group \'%s\' has no member with the name \'%s\'!", meterGroup.getName(), playerName))); + source.sendMessage(new TextComponentString(String.format("Meter group \'%s\' has no member with the name \'%s\'!", meterGroup.getName(), playerName))); } } else { multimeter.removeMemberFromMeterGroup(meterGroup, member.getValue()); - sender.sendMessage(new TextComponentString(String.format("Player \'%s\' is no longer a member of meter group \'%s\'", member.getKey(), meterGroup.getName()))); + source.sendMessage(new TextComponentString(String.format("Player \'%s\' is no longer a member of meter group \'%s\'", member.getKey(), meterGroup.getName()))); } }); } - + private Entry findMember(Map members, String playerName) { String key = playerName.toLowerCase(); - + for (Entry member : members.entrySet()) { if (member.getKey().toLowerCase().equals(key)) { return member; } } - + return null; } - - private void membersClear(ICommandSender sender) throws CommandException { - commandMembers(sender, (meterGroup, owner) -> { + + private void membersClear(ICommandSender source) { + commandMembers(source, (meterGroup, owner) -> { multimeter.clearMembersOfMeterGroup(meterGroup); - sender.sendMessage(new TextComponentString(String.format("Removed all members from meter group \'%s\'", meterGroup.getName()))); + source.sendMessage(new TextComponentString(String.format("Removed all members from meter group \'%s\'", meterGroup.getName()))); }); } - - private void commandMembers(ICommandSender sender, MeterGroupCommandExecutor command) throws CommandException { - command(sender, (meterGroup, player) -> { + + private void commandMembers(ICommandSender source, MeterGroupCommandExecutor command) { + command(source, (meterGroup, player) -> { if (meterGroup.isOwnedBy(player)) { - command.execute(meterGroup, player); - + command.run(meterGroup, player); + if (!meterGroup.isPrivate()) { - sender.sendMessage(new TextComponentString("NOTE: this meter group is public; adding/removing members will not have any effect until you make it private!")); + source.sendMessage(new TextComponentString("NOTE: this meter group is public; adding/removing members will not have any effect until you make it private!")); } } }); } - - private void clear(ICommandSender sender) throws CommandException { - command(sender, (meterGroup, player) -> { + + private void clear(ICommandSender source) { + command(source, (meterGroup, player) -> { multimeter.clearMeterGroup(meterGroup); - sender.sendMessage(new TextComponentString(String.format("Removed all meters in meter group \'%s\'", meterGroup.getName()))); + source.sendMessage(new TextComponentString(String.format("Removed all meters in meter group \'%s\'", meterGroup.getName()))); }); } - - private void command(ICommandSender sender, MeterGroupCommandExecutor command) throws CommandException { - command(sender, player -> { + + private void command(ICommandSender source, MeterGroupCommandExecutor command) { + command(source, player -> { ServerMeterGroup meterGroup = multimeter.getSubscription(player); - + if (meterGroup == null) { - sender.sendMessage(new TextComponentString("Please subscribe to a meter group first!")); + source.sendMessage(new TextComponentString("Please subscribe to a meter group first!")); } else { - command.execute(meterGroup, player); + command.run(meterGroup, player); } }); } - - private void command(ICommandSender sender, MultimeterCommandExecutor command) throws CommandException { - execute(sender, player -> { command.execute(player); return true; }); - } - - private boolean execute(ICommandSender sender, CommandExecutor command) throws CommandException { - return command.execute(getCommandSenderAsPlayer(sender)); + + private void command(ICommandSender source, MultimeterCommandExecutor command) { + run(source, p -> { command.run(p); return true; }); } - - @FunctionalInterface - private interface MultimeterCommandExecutor { - - public void execute(EntityPlayerMP player) throws CommandException; - + + private boolean run(ICommandSender source, Function command) { + try { + return command.apply(getCommandSenderAsPlayer(source)); + } catch (CommandException e) { + return false; + } } - + @FunctionalInterface - private interface MeterGroupCommandExecutor { - - public void execute(ServerMeterGroup meterGroup, EntityPlayerMP player) throws CommandException; - + private static interface MultimeterCommandExecutor { + + public void run(EntityPlayerMP player); + } - + @FunctionalInterface - private interface CommandExecutor { - - public boolean execute(EntityPlayerMP player) throws CommandException; - + private static interface MeterGroupCommandExecutor { + + public void run(ServerMeterGroup meterGroup, EntityPlayerMP player); + } } diff --git a/carpetmodSrc/redstone/multimeter/common/DimPos.java b/carpetmodSrc/redstone/multimeter/common/DimPos.java index 97cbfe2f..bec47255 100644 --- a/carpetmodSrc/redstone/multimeter/common/DimPos.java +++ b/carpetmodSrc/redstone/multimeter/common/DimPos.java @@ -1,116 +1,114 @@ package redstone.multimeter.common; +import com.google.common.base.Objects; + import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing.Axis; -import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import redstone.multimeter.util.AxisUtils; -import redstone.multimeter.util.DimensionUtils; -import redstone.multimeter.util.NbtUtils; public class DimPos { - - private final ResourceLocation dimensionId; - private final BlockPos blockPos; - - public DimPos(ResourceLocation dimensionId, BlockPos blockPos) { - this.dimensionId = dimensionId; - this.blockPos = blockPos.toImmutable(); - } - - public DimPos(ResourceLocation dimensionId, int x, int y, int z) { - this(dimensionId, new BlockPos(x, y, z)); - } - + + private final String dimension; + private final BlockPos pos; + + public DimPos(String dimension, BlockPos pos) { + this.dimension = dimension; + this.pos = pos.toImmutable(); + } + + public DimPos(String dimension, int x, int y, int z) { + this(dimension, new BlockPos(x, y, z)); + } + public DimPos(World world, BlockPos pos) { - this(DimensionUtils.getId(world.provider.getDimensionType()), pos); + this(world.provider.getDimensionType().getName(), pos); } - + @Override public boolean equals(Object obj) { if (obj instanceof DimPos) { - DimPos pos = (DimPos)obj; - return pos.dimensionId.equals(dimensionId) && pos.blockPos.equals(blockPos); + DimPos other = (DimPos)obj; + return other.dimension.equals(dimension) && other.pos.equals(pos); } - + return false; } - + @Override public int hashCode() { - return blockPos.hashCode() + 31 * dimensionId.hashCode(); + return Objects.hashCode(dimension, pos); } - + @Override public String toString() { - return String.format("%s[%d, %d, %d]", dimensionId.toString(), blockPos.getX(), blockPos.getY(), blockPos.getZ()); + return String.format("%s[%d, %d, %d]", dimension.toString(), pos.getX(), pos.getY(), pos.getZ()); } - - public ResourceLocation getDimensionId() { - return dimensionId; + + public String getDimension() { + return dimension; } - - public boolean isOf(World world) { - return DimensionUtils.getId(world.provider.getDimensionType()).equals(dimensionId); + + public boolean is(World world) { + return world.provider.getDimensionType().getName().equals(dimension); } - - public DimPos offset(ResourceLocation dimensionId) { - return new DimPos(dimensionId, blockPos); + + public DimPos offset(String dimension) { + return new DimPos(dimension, pos); } - + public BlockPos getBlockPos() { - return blockPos; + return pos; + } + + public boolean is(BlockPos pos) { + return pos.equals(this.pos); } - + public DimPos offset(EnumFacing dir) { return offset(dir, 1); } - + public DimPos offset(EnumFacing dir, int distance) { - return new DimPos(dimensionId, blockPos.offset(dir, distance)); + return new DimPos(dimension, pos.offset(dir, distance)); } - + public DimPos offset(Axis axis) { return offset(axis, 1); } - + public DimPos offset(Axis axis, int distance) { int dx = AxisUtils.choose(axis, distance, 0, 0); int dy = AxisUtils.choose(axis, 0, distance, 0); int dz = AxisUtils.choose(axis, 0, 0, distance); - - return offset(dx, dy, dz); + + return new DimPos(dimension, pos.add(dx, dy, dz)); } - + public DimPos offset(int dx, int dy, int dz) { - return new DimPos(dimensionId, blockPos.add(dx, dy, dz)); + return new DimPos(dimension, pos.add(dx, dy, dz)); } - + public NBTTagCompound toNbt() { NBTTagCompound nbt = new NBTTagCompound(); - - // The key is "world id" to match RSMM for 1.16+ - // Keeping this key consistent between versions - // allows clients and servers of different versions - // to communicate effectively through the use of - // mods like ViaVersion or multiconnect - nbt.setTag("world id", NbtUtils.identifierToNbt(dimensionId)); - nbt.setInteger("x", blockPos.getX()); - nbt.setInteger("y", blockPos.getY()); - nbt.setInteger("z", blockPos.getZ()); - + + nbt.setString("dim", dimension); + nbt.setInteger("x", pos.getX()); + nbt.setInteger("y", pos.getY()); + nbt.setInteger("z", pos.getZ()); + return nbt; } - + public static DimPos fromNbt(NBTTagCompound nbt) { - ResourceLocation dimensionId = NbtUtils.nbtToIdentifier(nbt.getCompoundTag("world id")); + String dimension = nbt.getString("dim"); int x = nbt.getInteger("x"); int y = nbt.getInteger("y"); int z = nbt.getInteger("z"); - - return new DimPos(dimensionId, x, y, z); + + return new DimPos(dimension, x, y, z); } } diff --git a/carpetmodSrc/redstone/multimeter/common/PruneType.java b/carpetmodSrc/redstone/multimeter/common/PruneType.java new file mode 100644 index 00000000..b2a048bd --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/common/PruneType.java @@ -0,0 +1,19 @@ +package redstone.multimeter.common; + +public enum PruneType { + + NONE (0), + BRANCH (1), + SIBLING(2), + TREE (3); + + private final int level; + + private PruneType(int level) { + this.level = level; + } + + public boolean is(PruneType type) { + return level >= type.level; + } +} diff --git a/carpetmodSrc/redstone/multimeter/common/TickPhase.java b/carpetmodSrc/redstone/multimeter/common/TickPhase.java index 128e6f9a..3414d08b 100644 --- a/carpetmodSrc/redstone/multimeter/common/TickPhase.java +++ b/carpetmodSrc/redstone/multimeter/common/TickPhase.java @@ -8,106 +8,110 @@ import redstone.multimeter.util.NbtUtils; public class TickPhase { - + public static final TickPhase UNKNOWN = new TickPhase(TickTask.UNKNOWN); - + private final TickTask[] tasks; - + public TickPhase(TickTask... tasks) { this.tasks = tasks; } - + @Override public boolean equals(Object obj) { if (obj == null || !(obj instanceof TickPhase)) { return false; } - + return Arrays.equals(tasks, ((TickPhase)obj).tasks); } - + @Override public String toString() { String string = tasks[0].getName(); - + for (int index = 1; index < tasks.length; index++) { string += " > " + tasks[index].getName(); } - + return string; } - + public TickPhase startTask(TickTask task) { if (this == UNKNOWN || tasks.length == 0) { return new TickPhase(task); } - + TickTask[] array = new TickTask[tasks.length + 1]; - + for (int index = 0; index < tasks.length; index++) { array[index] = tasks[index]; } array[tasks.length] = task; - + return new TickPhase(array); } - + public TickPhase endTask() { if (this == UNKNOWN || tasks.length == 1) { return UNKNOWN; } - + TickTask[] array = new TickTask[tasks.length - 1]; - + for (int index = 0; index < array.length; index++) { array[index] = tasks[index]; } - + return new TickPhase(array); } - + public TickPhase swapTask(TickTask task) { if (this == UNKNOWN || tasks.length == 1) { return new TickPhase(new TickTask[] { task }); } - + TickTask[] array = new TickTask[tasks.length]; - + for (int index = 0; index < tasks.length; index++) { array[index] = tasks[index]; } array[array.length - 1] = task; - + return new TickPhase(array); } - + + public TickTask peekTask() { + return tasks.length == 0 ? TickTask.UNKNOWN : tasks[tasks.length - 1]; + } + public NBTBase toNbt() { if (this == UNKNOWN) { return NbtUtils.NULL; } - + byte[] array = new byte[tasks.length]; - + for (int index = 0; index < array.length; index++) { array[index] = (byte)tasks[index].getIndex(); } - + return new NBTTagByteArray(array); } - + public static TickPhase fromNbt(NBTBase nbt) { if (nbt.getId() != NbtUtils.TYPE_BYTE_ARRAY) { return UNKNOWN; } - + NBTTagByteArray nbtArray = (NBTTagByteArray)nbt; byte[] array = nbtArray.getByteArray(); TickTask[] tasks = new TickTask[array.length]; - + for (int index = 0; index < tasks.length; index++) { - tasks[index] = TickTask.fromIndex(array[index]); + tasks[index] = TickTask.byIndex(array[index]); } - + return new TickPhase(tasks); } } diff --git a/carpetmodSrc/redstone/multimeter/common/TickPhaseTree.java b/carpetmodSrc/redstone/multimeter/common/TickPhaseTree.java index ed1f9581..8267acf2 100644 --- a/carpetmodSrc/redstone/multimeter/common/TickPhaseTree.java +++ b/carpetmodSrc/redstone/multimeter/common/TickPhaseTree.java @@ -1,7 +1,11 @@ package redstone.multimeter.common; import java.util.ArrayList; +import java.util.EnumSet; +import java.util.Iterator; import java.util.List; +import java.util.Set; +import java.util.Stack; import net.minecraft.nbt.NBTTagByteArray; import net.minecraft.nbt.NBTTagCompound; @@ -12,29 +16,40 @@ import redstone.multimeter.util.NbtUtils; public class TickPhaseTree { - - public final TickTaskNode root; - - private TickTaskNode current; + + public final Node root; + + private Node current; private boolean building; private boolean complete; - + public TickPhaseTree() { - this.root = new TickTaskNode(null, TickTask.UNKNOWN); - + this.root = new Node(null, TickTask.UNKNOWN); + this.current = root; this.building = false; this.complete = false; } - + public boolean isComplete() { return complete; } - + public boolean isBuilding() { return building; } - + + public void reset() { + if (building) { + RedstoneMultimeter.LOGGER.warn("Cannot reset tick phase tree: currently building!"); + } else { + root.children.clear(); + current = root; + building = false; + complete = false; + } + } + public void start() { if (building) { RedstoneMultimeter.LOGGER.warn("Cannot start building tick phase tree: already building!"); @@ -45,110 +60,116 @@ public void start() { complete = false; } } - + public void end() { if (building) { building = false; complete = true; + + prune(); } else { RedstoneMultimeter.LOGGER.warn("Cannot complete tick phase tree: not building!"); } } - + + private void prune() { + new Pruner().run(); + } + public void startTask(TickTask task, String... args) { if (building) { - current = new TickTaskNode(current, task, args); + current = new Node(current, task, args); current.parent.children.add(current); } } - + public void endTask() { if (building) { current = current.parent; - + if (current == null) { current = root; // we should never get here } } } - + public void swapTask(TickTask task, String... args) { if (building) { endTask(); startTask(task, args); } } - + public NBTTagCompound toNbt() { NBTTagList tasks = new NBTTagList(); NBTTagList args = new NBTTagList(); - + addNode(tasks, args, root, 0); - + NBTTagCompound nbt = new NBTTagCompound(); nbt.setTag("tasks", tasks); nbt.setTag("args", args); - + return nbt; } - - private void addNode(NBTTagList tasks, NBTTagList args, TickTaskNode node, int depth) { + + private void addNode(NBTTagList tasks, NBTTagList args, Node node, int depth) { if (depth > 0) { // depth 0 is root byte[] array = new byte[3]; array[0] = (byte)depth; array[1] = (byte)node.task.getIndex(); array[2] = (byte)node.args.length; NBTTagByteArray taskNbt = new NBTTagByteArray(array); - + tasks.appendTag(taskNbt); - + for (int index = 0; index < node.args.length; index++) { String arg = node.args[index]; NBTTagString argNbt = new NBTTagString(arg); - + args.appendTag(argNbt); } } - + depth++; - + for (int index = 0; index < node.children.size(); index++) { addNode(tasks, args, node.children.get(index), depth); } } - + public void fromNbt(NBTTagCompound nbt) { NBTTagList tasks = nbt.getTagList("tasks", NbtUtils.TYPE_BYTE_ARRAY); NBTTagList args = nbt.getTagList("args", NbtUtils.TYPE_STRING); - + if (!tasks.isEmpty()) { start(); addNode(tasks, args, 0, 0, 0); end(); } } - + private void addNode(NBTTagList tasks, NBTTagList args, int taskIndex, int argIndex, int lastDepth) { NBTTagByteArray taskNbt = (NBTTagByteArray)tasks.get(taskIndex); byte[] array = taskNbt.getByteArray(); int depth = array[0]; - TickTask task = TickTask.fromIndex(array[1]); + TickTask task = TickTask.byIndex(array[1]); int argsLength = array[2]; - + String[] taskArgs; - + if (argsLength > 0) { taskArgs = new String[argsLength]; - - for (int i = 0; i < argsLength && argIndex < args.tagCount(); ) { + + for (int i = 0; i < argsLength && argIndex < args.tagCount();) { taskArgs[i++] = args.getStringTagAt(argIndex++); } } else { taskArgs = new String[0]; } - + int endedTasks = lastDepth - depth; - + while (endedTasks-- > 0) { endTask(); } @@ -157,24 +178,78 @@ private void addNode(NBTTagList tasks, NBTTagList args, int taskIndex, int argIn } else { swapTask(task, taskArgs); } - + if (++taskIndex < tasks.tagCount()) { addNode(tasks, args, taskIndex, argIndex, depth); } } - - public class TickTaskNode { - - public final TickTaskNode parent; - public final List children; + + public class Node { + + public final Node parent; + public final List children; public final TickTask task; public final String[] args; - - public TickTaskNode(TickTaskNode parent, TickTask task, String... args) { + + public Node(Node parent, TickTask task, String... args) { this.parent = parent; this.children = new ArrayList<>(); this.task = task; this.args = args; } } + + private class Pruner { + + private final Set tasks = EnumSet.noneOf(TickTask.class); + private final Stack> layers = new Stack<>(); + private final Stack phase = new Stack<>(); + + private void run() { + tasks.clear(); + layers.clear(); + phase.clear(); + + layers.push(EnumSet.noneOf(TickTask.class)); + + prune(root); + } + + private boolean prune(Node node) { + TickTask task = node.task; + PruneType type = task.getPruneType(); + + if (type.is(PruneType.TREE) && tasks.contains(task)) { + return true; + } + + Set layer = layers.peek(); + + if (type.is(PruneType.SIBLING) && layer.contains(task)) { + return true; + } + if (type.is(PruneType.BRANCH) && phase.contains(task)) { + return true; + } + + tasks.add(task); + layer.add(task); + + phase.push(task); + layers.push(EnumSet.noneOf(TickTask.class)); + + for (Iterator it = node.children.iterator(); it.hasNext(); ) { + Node child = it.next(); + + if (prune(child)) { + it.remove(); + } + } + + phase.pop(); + layers.pop(); + + return false; + } + } } diff --git a/carpetmodSrc/redstone/multimeter/common/TickTask.java b/carpetmodSrc/redstone/multimeter/common/TickTask.java index 4b500223..efdb11ab 100644 --- a/carpetmodSrc/redstone/multimeter/common/TickTask.java +++ b/carpetmodSrc/redstone/multimeter/common/TickTask.java @@ -1,79 +1,86 @@ package redstone.multimeter.common; public enum TickTask { - - UNKNOWN ( 0, "unknown"), - TICK ( 1, "tick"), - COMMAND_FUNCTIONS ( 2, "command functions"), - LEVELS ( 3, "levels"), - TICK_WORLD ( 4, "tick world"), - WORLD_BORDER ( 5, "world border"), - WEATHER ( 6, "weather"), - WAKE_SLEEPING_PLAYERS( 7, "wake sleeping players"), - CHUNK_SOURCE ( 8, "chunk source"), - PURGE_UNLOADED_CHUNKS( 9, "purge unloaded chunks"), - TICK_CHUNKS (10, "tick chunks"), - MOB_SPAWNING (11, "mob spawning"), - TICK_CHUNK (12, "tick chunk"), - THUNDER (13, "thunder"), - PRECIPITATION (14, "precipitation"), - RANDOM_TICKS (15, "random ticks"), - CUSTOM_MOB_SPAWNING (16, "custom mob spawning"), - BROADCAST_CHUNKS (17, "broadcast chunks"), - UNLOAD_CHUNKS (18, "unload chunks"), - CHUNK_MAP (19, "chunk map"), - TICK_TIME (20, "tick time"), - SCHEDULED_TICKS (21, "scheduled ticks"), - BLOCK_TICKS (22, "block ticks"), - FLUID_TICKS (23, "fluid ticks"), - VILLAGES (24, "villages"), - RAIDS (25, "raids"), - PORTALS (26, "portals"), - BLOCK_EVENTS (27, "block events"), - ENTITIES (28, "entities"), - REGULAR_ENTITIES (29, "regular entities"), - GLOBAL_ENTITIES (30, "global entities"), - PLAYERS (31, "players"), - DRAGON_FIGHT (32, "dragon fight"), - BLOCK_ENTITIES (33, "block entities"), - ENTITY_MANAGEMENT (34, "entity management"), - CONNECTIONS (35, "connections"), - PLAYER_PING (36, "player ping"), - SERVER_GUI (37, "server gui"), - AUTOSAVE (38, "autosave"), - PACKETS (39, "packets"); - + + UNKNOWN ( 0, "unknown" , PruneType.NONE), + TICK ( 1, "tick" , PruneType.TREE), + COMMAND_FUNCTIONS ( 2, "command functions" , PruneType.TREE), + LEVELS ( 3, "levels" , PruneType.TREE), + TICK_LEVEL ( 4, "tick level" , PruneType.BRANCH), + WORLD_BORDER ( 5, "world border" , PruneType.BRANCH), + WEATHER ( 6, "weather" , PruneType.BRANCH), + WAKE_SLEEPING_PLAYERS( 7, "wake sleeping players", PruneType.BRANCH), + CHUNK_SOURCE ( 8, "chunk source" , PruneType.BRANCH), + PURGE_UNLOADED_CHUNKS( 9, "purge unloaded chunks", PruneType.BRANCH), + TICK_CHUNKS (10, "tick chunks" , PruneType.BRANCH), + MOB_SPAWNING (11, "mob spawning" , PruneType.SIBLING), + TICK_CHUNK (12, "tick chunk" , PruneType.SIBLING), + THUNDER (13, "thunder" , PruneType.SIBLING), + PRECIPITATION (14, "precipitation" , PruneType.SIBLING), + RANDOM_TICKS (15, "random ticks" , PruneType.SIBLING), + CUSTOM_MOB_SPAWNING (16, "custom mob spawning" , PruneType.BRANCH), + BROADCAST_CHUNKS (17, "broadcast chunks" , PruneType.SIBLING), + UNLOAD_CHUNKS (18, "unload chunks" , PruneType.BRANCH), + CHUNK_MAP (19, "chunk map" , PruneType.BRANCH), + TICK_TIME (20, "tick time" , PruneType.BRANCH), + SCHEDULED_TICKS (21, "scheduled ticks" , PruneType.BRANCH), + BLOCK_TICKS (22, "block ticks" , PruneType.BRANCH), + FLUID_TICKS (23, "fluid ticks" , PruneType.BRANCH), + VILLAGES (24, "villages" , PruneType.BRANCH), + RAIDS (25, "raids" , PruneType.BRANCH), + PORTALS (26, "portals" , PruneType.BRANCH), + BLOCK_EVENTS (27, "block events" , PruneType.BRANCH), + ENTITIES (28, "entities" , PruneType.BRANCH), + REGULAR_ENTITIES (29, "regular entities" , PruneType.BRANCH), + GLOBAL_ENTITIES (30, "global entities" , PruneType.BRANCH), + PLAYERS (31, "players" , PruneType.BRANCH), + DRAGON_FIGHT (32, "dragon fight" , PruneType.BRANCH), + BLOCK_ENTITIES (33, "block entities" , PruneType.BRANCH), + ENTITY_MANAGEMENT (34, "entity management" , PruneType.BRANCH), + CONNECTIONS (35, "connections" , PruneType.TREE), + PLAYER_PING (36, "player ping" , PruneType.TREE), + SERVER_GUI (37, "server gui" , PruneType.TREE), + AUTOSAVE (38, "autosave" , PruneType.TREE), + PACKETS (39, "packets" , PruneType.TREE); + public static final TickTask[] ALL; - + static { + ALL = new TickTask[values().length]; - + for (TickTask task : values()) { ALL[task.index] = task; } } - + private final int index; private final String name; - - private TickTask(int index, String name) { + private final PruneType pruneType; + + private TickTask(int index, String name, PruneType pruneType) { this.index = index; this.name = name; + this.pruneType = pruneType; } - + public int getIndex() { return index; } - - public static TickTask fromIndex(int index) { + + public static TickTask byIndex(int index) { if (index > 0 && index < ALL.length) { return ALL[index]; } - + return UNKNOWN; } - + public String getName() { return name; } + + public PruneType getPruneType() { + return pruneType; + } } diff --git a/carpetmodSrc/redstone/multimeter/common/meter/ColorPicker.java b/carpetmodSrc/redstone/multimeter/common/meter/ColorPicker.java new file mode 100644 index 00000000..883a529f --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/common/meter/ColorPicker.java @@ -0,0 +1,36 @@ +package redstone.multimeter.common.meter; + +import java.awt.Color; + +import redstone.multimeter.util.ColorUtils; + +public enum ColorPicker { + + RANDOM { + + private int index; + + @Override + public int next() { + float hue = ((index * 11) % 8 + (index / 8) / 2.0F) / 8.0F; + index = (index + 1) % 16; + + return ColorUtils.setAlpha(Color.HSBtoRGB(hue, 0.7F, 1.0F), 0xFF); + } + }, + RAINBOW { + + private int index; + + @Override + public int next() { + float hue = index / 32.0F; + index = (index + 1) % 32; + + return ColorUtils.setAlpha(Color.HSBtoRGB(hue, 0.7F, 1.0F), 0xFF); + } + }; + + public abstract int next(); + +} diff --git a/carpetmodSrc/redstone/multimeter/common/meter/Meter.java b/carpetmodSrc/redstone/multimeter/common/meter/Meter.java index af8bed8c..bad78607 100644 --- a/carpetmodSrc/redstone/multimeter/common/meter/Meter.java +++ b/carpetmodSrc/redstone/multimeter/common/meter/Meter.java @@ -12,140 +12,140 @@ import redstone.multimeter.common.meter.log.MeterLogs; public class Meter { - + private static final AtomicLong ID_COUNTER = new AtomicLong(0); - + private final long id; private final MutableMeterProperties properties; private final MeterLogs logs; - + /** true if the block at this position is receiving power */ private boolean powered; /** true if the block at this position is emitting power or active in another way */ private boolean active; - - /** This property is used on the client to hide a meter in the HUD */ + + /** this property is used on the client to hide a meter in the HUD */ private boolean hidden; - + public Meter(long id, MutableMeterProperties properties) { this.id = id; - this.properties = properties.toMutable(); + this.properties = properties.mutable(); this.logs = new MeterLogs(); } - + public Meter(MutableMeterProperties properties) { this(ID_COUNTER.getAndIncrement(), properties); } - + @Override public boolean equals(Object obj) { if (obj instanceof Meter) { Meter meter = (Meter)obj; return meter.id == id; } - + return false; } - + public long getId() { return id; } - + public MeterProperties getProperties() { - return properties.toImmutable(); + return properties.immutable(); } - + public MeterLogs getLogs() { return logs; } - + public void applyUpdate(Consumer update) { update.accept(properties); } - + public DimPos getPos() { return properties.getPos(); } - + public boolean isIn(World world) { - return properties.getPos().isOf(world); + return properties.getPos().is(world); } - + public String getName() { return properties.getName(); } - + public int getColor() { return properties.getColor(); } - + public boolean isMovable() { return properties.getMovable(); } - + public int getEventTypes() { return properties.getEventTypes(); } - + public boolean isMetering(EventType type) { return properties.hasEventType(type); } - + public boolean isPowered() { return powered; } - + public boolean isActive() { return active; } - + public boolean setPowered(boolean powered) { boolean wasPowered = this.powered; this.powered = powered; - + return wasPowered != powered; } - + public boolean setActive(boolean active) { boolean wasActive = this.active; this.active = active; - + return wasActive != active; } - + public boolean isHidden() { return hidden; } - + public void toggleHidden() { setHidden(!hidden); } - + public void setHidden(boolean hidden) { this.hidden = hidden; } - + public NBTTagCompound toNbt() { NBTTagCompound nbt = new NBTTagCompound(); - + nbt.setLong("id", id); nbt.setTag("properties", properties.toNbt()); nbt.setBoolean("powered", powered); nbt.setBoolean("active", active); - + return nbt; } - + public static Meter fromNbt(NBTTagCompound nbt) { long id = nbt.getLong("id"); MeterProperties properties = MeterProperties.fromNbt(nbt.getCompoundTag("properties")); boolean powered = nbt.getBoolean("powered"); boolean active = nbt.getBoolean("active"); - - Meter meter = new Meter(id, properties.toMutable()); + + Meter meter = new Meter(id, properties.mutable()); meter.setPowered(powered); meter.setActive(active); - + return meter; } } diff --git a/carpetmodSrc/redstone/multimeter/common/meter/MeterGroup.java b/carpetmodSrc/redstone/multimeter/common/meter/MeterGroup.java index cbc6d3ab..561d6ed8 100644 --- a/carpetmodSrc/redstone/multimeter/common/meter/MeterGroup.java +++ b/carpetmodSrc/redstone/multimeter/common/meter/MeterGroup.java @@ -14,109 +14,109 @@ import redstone.multimeter.util.NbtUtils; public abstract class MeterGroup { - + private final String name; private final List meters; - private final Map idToIndex; - private final Map posToIndex; - + private final Map byId; + private final Map byPos; + protected MeterGroup(String name) { this.name = name; this.meters = new ArrayList<>(); - this.idToIndex = new HashMap<>(); - this.posToIndex = new HashMap<>(); + this.byId = new HashMap<>(); + this.byPos = new HashMap<>(); } - + public static boolean isValidName(String name) { return !name.trim().isEmpty() && name.length() <= getMaxNameLength(); } - + public static int getMaxNameLength() { return 64; } - + public String getName() { return name; } - + public void clear() { meters.clear(); - idToIndex.clear(); - posToIndex.clear(); + byId.clear(); + byPos.clear(); getLogManager().clearLogs(); } - + public boolean hasMeters() { return !meters.isEmpty(); } - + public List getMeters() { return Collections.unmodifiableList(meters); } - + public boolean hasMeter(long id) { - return idToIndex.containsKey(id); + return byId.containsKey(id); } - + public boolean hasMeterAt(DimPos pos) { - return posToIndex.containsKey(pos); + return byPos.containsKey(pos); } - + public Meter getMeter(long id) { - return fromIndex(idToIndex.getOrDefault(id, -1)); + return fromIndex(byId.getOrDefault(id, -1)); } - + public Meter getMeterAt(DimPos pos) { - return fromIndex(posToIndex.getOrDefault(pos, -1)); + return fromIndex(byPos.getOrDefault(pos, -1)); } - + private Meter fromIndex(int index) { return (index < 0 || index >= meters.size()) ? null : meters.get(index); } - + protected boolean addMeter(Meter meter) { // This check prevents meters from being added twice and // multiple meters from being added at the same position. - if (idToIndex.containsKey(meter.getId()) || posToIndex.containsKey(meter.getPos())) { + if (byId.containsKey(meter.getId()) || byPos.containsKey(meter.getPos())) { return false; } - - idToIndex.put(meter.getId(), meters.size()); - posToIndex.put(meter.getPos(), meters.size()); + + byId.put(meter.getId(), meters.size()); + byPos.put(meter.getPos(), meters.size()); meters.add(meter); - + meterAdded(meter); - + return true; } - + protected boolean removeMeter(Meter meter) { - int index = idToIndex.getOrDefault(meter.getId(), -1); - + int index = byId.getOrDefault(meter.getId(), -1); + if (index < 0 || index >= meters.size()) { return false; } - + meters.remove(index); - idToIndex.remove(meter.getId(), index); - posToIndex.remove(meter.getPos(), index); - + byId.remove(meter.getId(), index); + byPos.remove(meter.getPos(), index); + for (; index < meters.size(); index++) { Meter m = meters.get(index); - - idToIndex.compute(m.getId(), (id, prevIndex) -> prevIndex - 1); - posToIndex.compute(m.getPos(), (pos, prevIndex) -> prevIndex - 1); + + byId.compute(m.getId(), (id, prevIndex) -> prevIndex - 1); + byPos.compute(m.getPos(), (pos, prevIndex) -> prevIndex - 1); } - + meterRemoved(meter); - + return true; } - + protected boolean updateMeter(Meter meter, MeterProperties newProperties) { meter.applyUpdate(properties -> { boolean changed = false; - + if (newProperties.getPos() != null) { moveMeter(meter, newProperties.getPos()); } @@ -132,69 +132,96 @@ protected boolean updateMeter(Meter meter, MeterProperties newProperties) { if (newProperties.getEventTypes() != null) { changed |= properties.setEventTypes(newProperties.getEventTypes()); } - + if (changed) { meterUpdated(meter); } }); - + return true; } - + protected void moveMeter(Meter meter, DimPos newPos) { long id = meter.getId(); DimPos pos = meter.getPos(); - + if (pos.equals(newPos)) { return; } - - int index = idToIndex.getOrDefault(id, -1); - + + int index = byId.getOrDefault(id, -1); + if (index < 0 || index >= meters.size()) { return; } - - posToIndex.remove(pos, index); - posToIndex.put(newPos, index); - + + byPos.remove(pos, index); + byPos.put(newPos, index); + meter.applyUpdate(properties -> { if (properties.setPos(newPos)) { meterUpdated(meter); } }); } - + + protected boolean setIndex(Meter meter, int index) { + int oldIndex = byId.getOrDefault(meter.getId(), -1); + + if (index < 0 || index >= meters.size() || oldIndex < 0) { + return false; + } + + meters.remove(oldIndex); + meters.add(index, meter); + + int start = Math.min(oldIndex, index); + int end = Math.max(oldIndex, index); + + for (index = start; index <= end; index++) { + meter = meters.get(index); + + byId.put(meter.getId(), index); + byPos.put(meter.getPos(), index); + + indexChanged(meter); + } + + return true; + } + protected abstract void meterAdded(Meter meter); - + protected abstract void meterRemoved(Meter meter); - + protected abstract void meterUpdated(Meter meter); - + + protected abstract void indexChanged(Meter meter); + public abstract LogManager getLogManager(); - + public NBTTagCompound toNbt() { NBTTagList list = new NBTTagList(); - + for (Meter meter : meters) { list.appendTag(meter.toNbt()); } - + NBTTagCompound nbt = new NBTTagCompound(); nbt.setTag("meters", list); - + return nbt; } - + public void updateFromNbt(NBTTagCompound nbt) { clear(); - + NBTTagList list = nbt.getTagList("meters", NbtUtils.TYPE_COMPOUND); - + for (int index = 0; index < list.tagCount(); index++) { NBTTagCompound meterNbt = list.getCompoundTagAt(index); Meter meter = Meter.fromNbt(meterNbt); - + addMeter(meter); } } diff --git a/carpetmodSrc/redstone/multimeter/common/meter/MeterProperties.java b/carpetmodSrc/redstone/multimeter/common/meter/MeterProperties.java index 92a8edc4..23538d32 100644 --- a/carpetmodSrc/redstone/multimeter/common/meter/MeterProperties.java +++ b/carpetmodSrc/redstone/multimeter/common/meter/MeterProperties.java @@ -5,23 +5,22 @@ import com.google.gson.JsonObject; import net.minecraft.nbt.NBTTagCompound; - import redstone.multimeter.common.DimPos; import redstone.multimeter.common.meter.event.EventType; import redstone.multimeter.util.ColorUtils; public class MeterProperties { - + private DimPos pos; private String name; private Integer color; private Boolean movable; private Integer eventTypes; - + public MeterProperties() { - + } - + public MeterProperties(DimPos pos, String name, Integer color, Boolean movable, Integer eventTypes) { this.pos = pos; this.name = name; @@ -29,47 +28,47 @@ public MeterProperties(DimPos pos, String name, Integer color, Boolean movable, this.movable = movable; this.eventTypes = eventTypes; } - + @Override public String toString() { return String.format("MeterProperties[pos: %s, name: %s, color: %s, movable: %s, event types: %s]", pos, name, color, movable, eventTypes); } - + public DimPos getPos() { return pos; } - + public String getName() { return name; } - + public Integer getColor() { return color; } - + public Boolean getMovable() { return movable; } - + public Integer getEventTypes() { return eventTypes; } - + public boolean hasEventType(EventType type) { return eventTypes != null && (eventTypes & type.flag()) != 0; } - - public MutableMeterProperties toMutable() { + + public MutableMeterProperties mutable() { return new MutableMeterProperties().fill(this); } - - public MeterProperties toImmutable() { + + public MeterProperties immutable() { return this; } - + public NBTTagCompound toNbt() { NBTTagCompound nbt = new NBTTagCompound(); - + if (pos != null) { nbt.setTag("pos", pos.toNbt()); } @@ -85,13 +84,13 @@ public NBTTagCompound toNbt() { if (eventTypes != null) { nbt.setInteger("event types", eventTypes); } - + return nbt; } - + public static MeterProperties fromNbt(NBTTagCompound nbt) { MeterProperties properties = new MeterProperties(); - + if (nbt.hasKey("pos")) { properties.pos = DimPos.fromNbt(nbt.getCompoundTag("pos")); } @@ -107,13 +106,13 @@ public static MeterProperties fromNbt(NBTTagCompound nbt) { if (nbt.hasKey("event types")) { properties.eventTypes = nbt.getInteger("event types"); } - + return properties; } - + public JsonObject toJson() { JsonObject json = new JsonObject(); - + if (name != null) { json.addProperty("name", name); } @@ -125,61 +124,61 @@ public JsonObject toJson() { } if (eventTypes != null) { JsonArray types = new JsonArray(); - + for (EventType type : EventType.ALL) { if (hasEventType(type)) { types.add(type.getName()); } } - + json.add("event_types", types); } - + return json; } - + public static MeterProperties fromJson(JsonObject json) { MeterProperties properties = new MeterProperties(); - + if (json.has("name")) { JsonElement nameJson = json.get("name"); - + if (nameJson.isJsonPrimitive()) { properties.name = nameJson.getAsString(); } } if (json.has("color")) { JsonElement colorJson = json.get("color"); - + if (colorJson.isJsonPrimitive()) { try { properties.color = ColorUtils.fromRGBString(colorJson.getAsString()); } catch (NumberFormatException e) { - + } } } if (json.has("movable")) { JsonElement movableJson = json.get("movable"); - + if (movableJson.isJsonPrimitive()) { properties.movable = movableJson.getAsBoolean(); } } if (json.has("event_types")) { JsonElement typesJson = json.get("event_types"); - + if (typesJson.isJsonArray()) { properties.eventTypes = 0; JsonArray types = typesJson.getAsJsonArray(); - + for (int index = 0; index < types.size(); index++) { JsonElement typeJson = types.get(index); - + if (typeJson.isJsonPrimitive()) { String typeName = typeJson.getAsString(); - EventType type = EventType.fromName(typeName); - + EventType type = EventType.byName(typeName); + if (type != null) { properties.eventTypes |= type.flag(); } @@ -187,72 +186,71 @@ public static MeterProperties fromJson(JsonObject json) { } } } - + return properties; } - + public static class MutableMeterProperties extends MeterProperties { - + public boolean setPos(DimPos pos) { DimPos prevPos = super.pos; super.pos = pos; - + return prevPos == null || !prevPos.equals(pos); } - + public boolean setName(String name) { String prevName = super.name; super.name = name; - + return prevName == null || !prevName.equals(name); } - + public boolean setColor(Integer color) { Integer prevColor = super.color; super.color = color; - + return prevColor == null || !prevColor.equals(color); } - + public boolean setMovable(Boolean movable) { Boolean prevMovable = super.movable; super.movable = movable; - + return prevMovable == null || !prevMovable.equals(movable); } - + public boolean setEventTypes(Integer eventTypes) { Integer prevEventTypes = super.eventTypes; super.eventTypes = eventTypes; - + return prevEventTypes == null || !prevEventTypes.equals(eventTypes); } - + public boolean toggleEventType(EventType type) { if (super.eventTypes == null) { super.eventTypes = 0; } - + return setEventTypes(super.eventTypes ^ type.flag()); } - - public MutableMeterProperties toMutable() { + + public MutableMeterProperties mutable() { return this; } - - public MeterProperties toImmutable() { + + public MeterProperties immutable() { return new MeterProperties(super.pos, super.name, super.color, super.movable, super.eventTypes); } - + /** - * If a property does not yet have a value, copy the value - * from the given properties. + * If a property does not yet have a value, copy the value from the given properties. */ public MutableMeterProperties fill(MeterProperties properties) { if (properties == null) { return this; } - + if (super.pos == null) { super.pos = properties.pos; } @@ -268,7 +266,7 @@ public MutableMeterProperties fill(MeterProperties properties) { if (super.eventTypes == null) { super.eventTypes = properties.eventTypes; } - + return this; } } diff --git a/carpetmodSrc/redstone/multimeter/common/meter/MeterPropertiesManager.java b/carpetmodSrc/redstone/multimeter/common/meter/MeterPropertiesManager.java index c941bfbe..c456bb26 100644 --- a/carpetmodSrc/redstone/multimeter/common/meter/MeterPropertiesManager.java +++ b/carpetmodSrc/redstone/multimeter/common/meter/MeterPropertiesManager.java @@ -7,27 +7,27 @@ import redstone.multimeter.common.meter.MeterProperties.MutableMeterProperties; public abstract class MeterPropertiesManager { - + public boolean validate(MutableMeterProperties properties) { DimPos pos = properties.getPos(); - + if (pos == null) { return false; } - - World world = getWorldOf(pos); - + + World world = getWorld(pos); + if (world == null) { return false; } - + postValidation(properties, world, pos.getBlockPos()); - + return true; } - - protected abstract World getWorldOf(DimPos pos); - + + protected abstract World getWorld(DimPos pos); + protected abstract void postValidation(MutableMeterProperties properties, World world, BlockPos pos); - + } diff --git a/carpetmodSrc/redstone/multimeter/common/meter/event/EventType.java b/carpetmodSrc/redstone/multimeter/common/meter/event/EventType.java index 9c4496c2..c8cb2e4c 100644 --- a/carpetmodSrc/redstone/multimeter/common/meter/event/EventType.java +++ b/carpetmodSrc/redstone/multimeter/common/meter/event/EventType.java @@ -9,7 +9,7 @@ import redstone.multimeter.util.NbtUtils; public enum EventType { - + UNKNOWN(-1, "unknown"), POWERED(0, "powered"), ACTIVE(1, "active"), @@ -25,68 +25,69 @@ public enum EventType { SHAPE_UPDATE(11, "shape_update"), OBSERVER_UPDATE(12, "observer_update"), INTERACT_BLOCK(13, "interact_block"); - + public static final EventType[] ALL; private static final Map BY_NAME; - + static { + EventType[] types = values(); - + ALL = new EventType[types.length - 1]; BY_NAME = new HashMap<>(); - + for (int index = 1; index < types.length; index++) { EventType type = types[index]; - + ALL[type.index] = type; BY_NAME.put(type.name, type); } } - + private final int index; private final String name; - + private EventType(int index, String name) { this.index = index; this.name = name; } - + public int getIndex() { return index; } - - public static EventType fromIndex(int index) { + + public static EventType byIndex(int index) { if (index >= 0 && index < ALL.length) { return ALL[index]; } return UNKNOWN; } - + public String getName() { return name; } - - public static EventType fromName(String name) { + + public static EventType byName(String name) { return BY_NAME.getOrDefault(name, UNKNOWN); } - + public int flag() { return 1 << index; } - + public NBTBase toNbt() { return new NBTTagByte((byte)index); } - + public static EventType fromNbt(NBTBase nbt) { if (nbt.getId() != NbtUtils.TYPE_BYTE) { return UNKNOWN; } - + NBTTagByte NBTTagByte = (NBTTagByte)nbt; int index = NBTTagByte.getByte(); - - return fromIndex(index); + + return byIndex(index); } } diff --git a/carpetmodSrc/redstone/multimeter/common/meter/event/MeterEvent.java b/carpetmodSrc/redstone/multimeter/common/meter/event/MeterEvent.java index c4ed81b5..cee89289 100644 --- a/carpetmodSrc/redstone/multimeter/common/meter/event/MeterEvent.java +++ b/carpetmodSrc/redstone/multimeter/common/meter/event/MeterEvent.java @@ -3,42 +3,41 @@ import net.minecraft.nbt.NBTTagCompound; public class MeterEvent { - + private EventType type; private int metadata; - + private MeterEvent() { - } - + public MeterEvent(EventType type, int metadata) { this.type = type; this.metadata = metadata; } - + public EventType getType() { return type; } - + public int getMetadata() { return metadata; } - + public NBTTagCompound toNbt() { NBTTagCompound nbt = new NBTTagCompound(); - + nbt.setTag("type", type.toNbt()); nbt.setInteger("metadata", metadata); - + return nbt; } - + public static MeterEvent fromNbt(NBTTagCompound nbt) { MeterEvent event = new MeterEvent(); - + event.type = EventType.fromNbt(nbt.getTag("type")); event.metadata = nbt.getInteger("metadata"); - + return event; } } diff --git a/carpetmodSrc/redstone/multimeter/common/meter/log/EventLog.java b/carpetmodSrc/redstone/multimeter/common/meter/log/EventLog.java index 6403e324..f671271f 100644 --- a/carpetmodSrc/redstone/multimeter/common/meter/log/EventLog.java +++ b/carpetmodSrc/redstone/multimeter/common/meter/log/EventLog.java @@ -6,98 +6,97 @@ import redstone.multimeter.common.meter.event.MeterEvent; public class EventLog { - + private long tick; private int subtick; private TickPhase tickPhase; private MeterEvent event; - + private EventLog() { - } - + public EventLog(long tick, int subtick, TickPhase tickPhase, MeterEvent event) { this.tick = tick; this.subtick = subtick; this.tickPhase = tickPhase; this.event = event; } - + public long getTick() { return tick; } - + public int getSubtick() { return subtick; } - + public boolean isAt(long tick) { return this.tick == tick; } - + public boolean isAt(long tick, int subtick) { return this.tick == tick && this.subtick == subtick; } - + public boolean isBefore(long tick) { return this.tick < tick; } - + public boolean isBefore(long tick, int subtick) { if (this.tick == tick) { return this.subtick < subtick; } - + return this.tick < tick; } - + public boolean isBefore(EventLog event) { return isBefore(event.getTick(), event.getSubtick()); } - + public boolean isAfter(long tick) { return this.tick > tick; } - + public boolean isAfter(long tick, int subtick) { if (this.tick == tick) { return this.subtick > subtick; } - + return this.tick > tick; } - + public boolean isAfter(EventLog event) { return isAfter(event.getTick(), event.getSubtick()); } - + public TickPhase getTickPhase() { return tickPhase; } - + public MeterEvent getEvent() { return event; } - + public NBTTagCompound toNbt() { NBTTagCompound nbt = new NBTTagCompound(); - + nbt.setTag("meter event", event.toNbt()); nbt.setLong("tick", tick); nbt.setInteger("subtick", subtick); nbt.setTag("tick phase", tickPhase.toNbt()); - + return nbt; } - + public static EventLog fromNbt(NBTTagCompound nbt) { EventLog log = new EventLog(); - + log.event = MeterEvent.fromNbt(nbt.getCompoundTag("meter event")); log.tick = nbt.getLong("tick"); log.subtick = nbt.getInteger("subtick"); log.tickPhase = TickPhase.fromNbt(nbt.getTag("tick phase")); - + return log; } } diff --git a/carpetmodSrc/redstone/multimeter/common/meter/log/LogManager.java b/carpetmodSrc/redstone/multimeter/common/meter/log/LogManager.java index bb1b99bb..f8746252 100644 --- a/carpetmodSrc/redstone/multimeter/common/meter/log/LogManager.java +++ b/carpetmodSrc/redstone/multimeter/common/meter/log/LogManager.java @@ -4,11 +4,9 @@ import redstone.multimeter.common.meter.MeterGroup; public abstract class LogManager { - + protected abstract MeterGroup getMeterGroup(); - - protected abstract long getLastTick(); - + public void clearLogs() { for (Meter meter : getMeterGroup().getMeters()) { meter.getLogs().clear(); diff --git a/carpetmodSrc/redstone/multimeter/common/meter/log/MeterLogs.java b/carpetmodSrc/redstone/multimeter/common/meter/log/MeterLogs.java index 98e37d7b..62a1e2a1 100644 --- a/carpetmodSrc/redstone/multimeter/common/meter/log/MeterLogs.java +++ b/carpetmodSrc/redstone/multimeter/common/meter/log/MeterLogs.java @@ -1,6 +1,7 @@ package redstone.multimeter.common.meter.log; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import net.minecraft.nbt.NBTTagCompound; @@ -11,170 +12,172 @@ import redstone.multimeter.util.NbtUtils; public class MeterLogs { - + private final List[] eventLogs; - - private long lastLoggedTick = -1; - + + private long count = 0; + public MeterLogs() { @SuppressWarnings("unchecked") List[] lists = new List[EventType.ALL.length]; - + for (int index = 0; index < lists.length; index++) { lists[index] = new ArrayList<>(); } - + this.eventLogs = lists; } - + public void clear() { for (List logs : eventLogs) { logs.clear(); } - - lastLoggedTick = -1; + + count = 0; } - + public boolean isEmpty() { - return lastLoggedTick < 0; + return count == 0; } - + private List getLogs(EventType type) { return eventLogs[type.getIndex()]; } - + public void add(EventLog log) { EventType type = log.getEvent().getType(); List logs = getLogs(type); - - logs.add(log); - - if (log.getTick() > lastLoggedTick) { - lastLoggedTick = log.getTick(); - } + + logs.add(getLastLogBefore(type, log.getTick(), log.getSubtick()) + 1, log); + + count++; } - + public void clearOldLogs(long cutoff) { for (List logs : eventLogs) { while (!logs.isEmpty()) { EventLog log = logs.get(0); - + if (log.getTick() > cutoff) { break; } - + logs.remove(0); } } } - + public EventLog getLog(EventType type, int index) { if (index < 0) { return null; } - + List logs = getLogs(type); - + if (index >= logs.size()) { return null; } - + return logs.get(index); } - + public int getLastLogBefore(EventType type, long tick) { return getLastLogBefore(type, tick, 0); } - - public int getLastLogBefore(EventType type, long tick, int subick) { + + public int getLastLogBefore(EventType type, long tick, int subtick) { List logs = getLogs(type); - - if (logs.isEmpty() || !logs.get(0).isBefore(tick, subick)) { + + if (logs.isEmpty() || !logs.get(0).isBefore(tick, subtick)) { return -1; } - if (tick > lastLoggedTick) { + if (logs.get(logs.size() - 1).isBefore(tick, subtick)) { return logs.size() - 1; } - - int index = ListUtils.binarySearch(logs, event -> event.isBefore(tick, subick)); + + int index = ListUtils.binarySearch(logs, event -> event.isBefore(tick, subtick)); EventLog log = logs.get(index); - - while (!log.isBefore(tick, subick)) { + + while (!log.isBefore(tick, subtick)) { if (index == 0) { return -1; } - + log = logs.get(--index); } - + return index; - } - + public EventLog getLastLogBefore(long tick) { return getLastLogBefore(tick, 0); } - + public EventLog getLastLogBefore(long tick, int subtick) { EventLog lastLog = null; - + for (EventType type : EventType.ALL) { int index = getLastLogBefore(type, tick, subtick); EventLog log = getLog(type, index); - + if (lastLog == null || (log != null && log.isAfter(lastLog))) { lastLog = log; } } - + return lastLog; } - + public EventLog getLogAt(long tick, int subtick) { EventLog log = getLastLogBefore(tick, subtick + 1); return log != null && log.isAt(tick, subtick) ? log : null; } - + public NBTTagCompound toNbt() { NBTTagCompound nbt = new NBTTagCompound(); - + for (EventType type : EventType.ALL) { NBTTagList logs = toNbt(type); - + if (!logs.isEmpty()) { nbt.setTag(type.getName(), logs); } } - + return nbt; } - + private NBTTagList toNbt(EventType type) { NBTTagList list = new NBTTagList(); - + for (EventLog log : getLogs(type)) { list.appendTag(log.toNbt()); } - + return list; } - - public void updateFromNbt(NBTTagCompound nbt) { + + public static Collection fromNbt(NBTTagCompound nbt) { + Collection logs = new ArrayList<>(); + for (String key : nbt.getKeySet()) { - EventType type = EventType.fromName(key); - + EventType type = EventType.byName(key); + if (type != null) { - updateFromNbt(type, nbt.getTagList(key, NbtUtils.TYPE_COMPOUND)); + logs.addAll(fromNbt(type, nbt.getTagList(key, NbtUtils.TYPE_COMPOUND))); } } + + return logs; } - - public void updateFromNbt(EventType type, NBTTagList logs) { - for (int index = 0; index < logs.tagCount(); index++) { - NBTTagCompound nbt = logs.getCompoundTagAt(index); - EventLog log = EventLog.fromNbt(nbt); - - add(log); + + public static Collection fromNbt(EventType type, NBTTagList nbt) { + Collection logs = new ArrayList<>(); + + for (int i = 0; i < nbt.tagCount(); i++) { + logs.add(EventLog.fromNbt(nbt.getCompoundTagAt(i))); } + + return logs; } } diff --git a/carpetmodSrc/redstone/multimeter/common/network/AbstractPacketHandler.java b/carpetmodSrc/redstone/multimeter/common/network/AbstractPacketHandler.java deleted file mode 100644 index 493d878b..00000000 --- a/carpetmodSrc/redstone/multimeter/common/network/AbstractPacketHandler.java +++ /dev/null @@ -1,53 +0,0 @@ -package redstone.multimeter.common.network; - -import java.io.IOException; - -import carpet.CarpetSettings; - -import io.netty.buffer.Unpooled; - -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.network.Packet; -import net.minecraft.network.PacketBuffer; -import net.minecraft.util.ResourceLocation; - -public abstract class AbstractPacketHandler { - - protected

Packet encode(P packet) { - ResourceLocation id = PacketManager.getId(packet); - - if (id == null) { - throw new IllegalStateException("Unable to encode packet: " + packet.getClass()); - } - - NBTTagCompound data = new NBTTagCompound(); - packet.encode(data); - - PacketBuffer buffer = new PacketBuffer(Unpooled.buffer()); - - buffer.writeResourceLocation(id); - buffer.writeCompoundTag(data); - - return toCustomPayload(PacketManager.getPacketChannelId(), buffer); - } - - protected abstract Packet toCustomPayload(String id, PacketBuffer buffer); - - public abstract

void send(P packet); - - protected

P decode(PacketBuffer buffer) throws IOException { - ResourceLocation id = buffer.readResourceLocation(); - P packet = PacketManager.createPacket(id); - - if (packet == null) { - throw new IllegalStateException("Unable to decode packet: " + id); - } - - if (CarpetSettings.redstoneMultimeter || packet.force()) { - NBTTagCompound data = buffer.readCompoundTag(); - packet.decode(data); - } - - return packet; - } -} diff --git a/carpetmodSrc/redstone/multimeter/common/network/PacketHandler.java b/carpetmodSrc/redstone/multimeter/common/network/PacketHandler.java new file mode 100644 index 00000000..bd92bd75 --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/common/network/PacketHandler.java @@ -0,0 +1,46 @@ +package redstone.multimeter.common.network; + +import java.io.IOException; + +import io.netty.buffer.Unpooled; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.Packet; +import net.minecraft.network.PacketBuffer; + +public abstract class PacketHandler { + + public Packet encode(RSMMPacket packet) { + String key = Packets.getKey(packet); + + if (key == null) { + throw new IllegalStateException("Unable to encode packet: " + packet.getClass()); + } + + NBTTagCompound data = new NBTTagCompound(); + packet.encode(data); + + PacketBuffer buffer = new PacketBuffer(Unpooled.buffer()); + + buffer.writeString(key); + buffer.writeCompoundTag(data); + + return toCustomPayload(Packets.getChannel(), buffer); + } + + protected abstract Packet toCustomPayload(String channel, PacketBuffer data); + + protected RSMMPacket decode(PacketBuffer buffer) throws IOException { + String key = buffer.readString(32767); + RSMMPacket packet = Packets.create(key); + + if (packet == null) { + throw new IllegalStateException("Unable to decode packet: " + key); + } + + NBTTagCompound data = buffer.readCompoundTag(); + packet.decode(data); + + return packet; + } +} diff --git a/carpetmodSrc/redstone/multimeter/common/network/PacketManager.java b/carpetmodSrc/redstone/multimeter/common/network/PacketManager.java deleted file mode 100644 index 745c8435..00000000 --- a/carpetmodSrc/redstone/multimeter/common/network/PacketManager.java +++ /dev/null @@ -1,43 +0,0 @@ -package redstone.multimeter.common.network; - -import net.minecraft.util.ResourceLocation; - -import redstone.multimeter.common.network.packets.*; -import redstone.multimeter.registry.SupplierClazzRegistry; - -public class PacketManager { - - private static final SupplierClazzRegistry PACKETS; - - public static String getPacketChannelId() { - return PACKETS.getId().getNamespace(); - } - - public static

ResourceLocation getId(P packet) { - return PACKETS.getId(packet); - } - - public static

P createPacket(ResourceLocation id) { - return PACKETS.get(id); - } - - static { - - PACKETS = new SupplierClazzRegistry<>("network"); - - PACKETS.register("handshake" , HandshakePacket.class , () -> new HandshakePacket()); - PACKETS.register("tick_phase_tree" , TickPhaseTreePacket.class , () -> new TickPhaseTreePacket()); - PACKETS.register("server_tick" , ServerTickPacket.class , () -> new ServerTickPacket()); - PACKETS.register("meter_group_subscription", MeterGroupSubscriptionPacket.class, () -> new MeterGroupSubscriptionPacket()); - PACKETS.register("meter_group_default" , MeterGroupDefaultPacket.class , () -> new MeterGroupDefaultPacket()); - PACKETS.register("meter_group_refresh" , MeterGroupRefreshPacket.class , () -> new MeterGroupRefreshPacket()); - PACKETS.register("meter_updates" , MeterUpdatesPacket.class , () -> new MeterUpdatesPacket()); - PACKETS.register("meter_logs" , MeterLogsPacket.class , () -> new MeterLogsPacket()); - PACKETS.register("clear_meter_group" , ClearMeterGroupPacket.class , () -> new ClearMeterGroupPacket()); - PACKETS.register("add_meter" , AddMeterPacket.class , () -> new AddMeterPacket()); - PACKETS.register("remove_meter" , RemoveMeterPacket.class , () -> new RemoveMeterPacket()); - PACKETS.register("meter_update" , MeterUpdatePacket.class , () -> new MeterUpdatePacket()); - PACKETS.register("teleport_to_meter" , TeleportToMeterPacket.class , () -> new TeleportToMeterPacket()); - - } -} diff --git a/carpetmodSrc/redstone/multimeter/common/network/Packets.java b/carpetmodSrc/redstone/multimeter/common/network/Packets.java new file mode 100644 index 00000000..206b9510 --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/common/network/Packets.java @@ -0,0 +1,43 @@ +package redstone.multimeter.common.network; + +import redstone.multimeter.common.network.packets.*; +import redstone.multimeter.registry.SupplierRegistry; + +public class Packets { + + private static final SupplierRegistry REGISTRY; + + public static String getChannel() { + return REGISTRY.getRegistryKey(); + } + + public static String getKey(RSMMPacket packet) { + return REGISTRY.getKey(packet); + } + + public static RSMMPacket create(String key) { + return REGISTRY.get(key); + } + + static { + + REGISTRY = new SupplierRegistry<>(); + + REGISTRY.register("handshake" , HandshakePacket.class , () -> new HandshakePacket()); + REGISTRY.register("tick_phase_tree" , TickPhaseTreePacket.class , () -> new TickPhaseTreePacket()); + REGISTRY.register("rebuild_tick_phase_tree" , RebuildTickPhaseTreePacket.class , () -> new RebuildTickPhaseTreePacket()); + REGISTRY.register("tick_time" , TickTimePacket.class , () -> new TickTimePacket()); + REGISTRY.register("meter_group_subscription", MeterGroupSubscriptionPacket.class, () -> new MeterGroupSubscriptionPacket()); + REGISTRY.register("meter_group_default" , MeterGroupDefaultPacket.class , () -> new MeterGroupDefaultPacket()); + REGISTRY.register("meter_group_refresh" , MeterGroupRefreshPacket.class , () -> new MeterGroupRefreshPacket()); + REGISTRY.register("meter_updates" , MeterUpdatesPacket.class , () -> new MeterUpdatesPacket()); + REGISTRY.register("meter_logs" , MeterLogsPacket.class , () -> new MeterLogsPacket()); + REGISTRY.register("clear_meter_group" , ClearMeterGroupPacket.class , () -> new ClearMeterGroupPacket()); + REGISTRY.register("add_meter" , AddMeterPacket.class , () -> new AddMeterPacket()); + REGISTRY.register("remove_meter" , RemoveMeterPacket.class , () -> new RemoveMeterPacket()); + REGISTRY.register("meter_update" , MeterUpdatePacket.class , () -> new MeterUpdatePacket()); + REGISTRY.register("meter_index" , MeterIndexPacket.class , () -> new MeterIndexPacket()); + REGISTRY.register("teleport_to_meter" , TeleportToMeterPacket.class , () -> new TeleportToMeterPacket()); + + } +} diff --git a/carpetmodSrc/redstone/multimeter/common/network/RSMMPacket.java b/carpetmodSrc/redstone/multimeter/common/network/RSMMPacket.java index c0e74ddf..8cad13d6 100644 --- a/carpetmodSrc/redstone/multimeter/common/network/RSMMPacket.java +++ b/carpetmodSrc/redstone/multimeter/common/network/RSMMPacket.java @@ -6,13 +6,13 @@ import redstone.multimeter.server.MultimeterServer; public interface RSMMPacket { - + public void encode(NBTTagCompound data); - + public void decode(NBTTagCompound data); - - public void execute(MultimeterServer server, EntityPlayerMP player); - + + public void handle(MultimeterServer server, EntityPlayerMP player); + /** * Most RSMM packets are ignored if the redstoneMultimeter carpet * rule is not enabled. Some packets are handled anyway in order diff --git a/carpetmodSrc/redstone/multimeter/common/network/packets/AddMeterPacket.java b/carpetmodSrc/redstone/multimeter/common/network/packets/AddMeterPacket.java index c7baae3f..8fdad9fa 100644 --- a/carpetmodSrc/redstone/multimeter/common/network/packets/AddMeterPacket.java +++ b/carpetmodSrc/redstone/multimeter/common/network/packets/AddMeterPacket.java @@ -8,29 +8,28 @@ import redstone.multimeter.server.MultimeterServer; public class AddMeterPacket implements RSMMPacket { - + private MeterProperties properties; - + public AddMeterPacket() { - } - + public AddMeterPacket(MeterProperties properties) { this.properties = properties; } - + @Override public void encode(NBTTagCompound data) { data.setTag("properties", properties.toNbt()); } - + @Override public void decode(NBTTagCompound data) { properties = MeterProperties.fromNbt(data.getCompoundTag("properties")); } - + @Override - public void execute(MultimeterServer server, EntityPlayerMP player) { + public void handle(MultimeterServer server, EntityPlayerMP player) { server.getMultimeter().addMeter(player, properties); } } diff --git a/carpetmodSrc/redstone/multimeter/common/network/packets/ClearMeterGroupPacket.java b/carpetmodSrc/redstone/multimeter/common/network/packets/ClearMeterGroupPacket.java index 5b7f0fbc..e986f0d6 100644 --- a/carpetmodSrc/redstone/multimeter/common/network/packets/ClearMeterGroupPacket.java +++ b/carpetmodSrc/redstone/multimeter/common/network/packets/ClearMeterGroupPacket.java @@ -7,23 +7,19 @@ import redstone.multimeter.server.MultimeterServer; public class ClearMeterGroupPacket implements RSMMPacket { - + public ClearMeterGroupPacket() { - } - + @Override public void encode(NBTTagCompound data) { - } - + @Override public void decode(NBTTagCompound data) { - } - + @Override - public void execute(MultimeterServer server, EntityPlayerMP player) { - + public void handle(MultimeterServer server, EntityPlayerMP player) { } } diff --git a/carpetmodSrc/redstone/multimeter/common/network/packets/HandshakePacket.java b/carpetmodSrc/redstone/multimeter/common/network/packets/HandshakePacket.java index 942b8f91..30289fa4 100644 --- a/carpetmodSrc/redstone/multimeter/common/network/packets/HandshakePacket.java +++ b/carpetmodSrc/redstone/multimeter/common/network/packets/HandshakePacket.java @@ -8,28 +8,28 @@ import redstone.multimeter.server.MultimeterServer; public class HandshakePacket implements RSMMPacket { - + private String modVersion; - + public HandshakePacket() { modVersion = RedstoneMultimeter.MOD_VERSION; } - + @Override public void encode(NBTTagCompound data) { data.setString("mod version", modVersion); } - + @Override public void decode(NBTTagCompound data) { modVersion = data.getString("mod version"); } - + @Override - public void execute(MultimeterServer server, EntityPlayerMP player) { + public void handle(MultimeterServer server, EntityPlayerMP player) { server.onHandshake(player, modVersion); } - + @Override public boolean force() { return true; diff --git a/carpetmodSrc/redstone/multimeter/common/network/packets/MeterGroupDefaultPacket.java b/carpetmodSrc/redstone/multimeter/common/network/packets/MeterGroupDefaultPacket.java index 822f778e..a380e5f4 100644 --- a/carpetmodSrc/redstone/multimeter/common/network/packets/MeterGroupDefaultPacket.java +++ b/carpetmodSrc/redstone/multimeter/common/network/packets/MeterGroupDefaultPacket.java @@ -7,23 +7,19 @@ import redstone.multimeter.server.MultimeterServer; public class MeterGroupDefaultPacket implements RSMMPacket { - + public MeterGroupDefaultPacket() { - } - + @Override public void encode(NBTTagCompound data) { - } - + @Override public void decode(NBTTagCompound data) { - } - + @Override - public void execute(MultimeterServer server, EntityPlayerMP player) { - + public void handle(MultimeterServer server, EntityPlayerMP player) { } } diff --git a/carpetmodSrc/redstone/multimeter/common/network/packets/MeterGroupRefreshPacket.java b/carpetmodSrc/redstone/multimeter/common/network/packets/MeterGroupRefreshPacket.java index c59b50eb..18fb181f 100644 --- a/carpetmodSrc/redstone/multimeter/common/network/packets/MeterGroupRefreshPacket.java +++ b/carpetmodSrc/redstone/multimeter/common/network/packets/MeterGroupRefreshPacket.java @@ -9,35 +9,34 @@ import redstone.multimeter.server.MultimeterServer; public class MeterGroupRefreshPacket implements RSMMPacket { - + private String name; private NBTTagCompound meterGroupData; - + public MeterGroupRefreshPacket() { - } - + public MeterGroupRefreshPacket(MeterGroup meterGroup) { this.name = meterGroup.getName(); this.meterGroupData = meterGroup.toNbt(); } - + @Override public void encode(NBTTagCompound data) { data.setString("name", name); data.setTag("data", meterGroupData); } - + @Override public void decode(NBTTagCompound data) { name = data.getString("name"); meterGroupData = data.getCompoundTag("data"); } - + @Override - public void execute(MultimeterServer server, EntityPlayerMP player) { + public void handle(MultimeterServer server, EntityPlayerMP player) { Multimeter multimeter = server.getMultimeter(); - + if (multimeter.hasSubscription(player)) { multimeter.refreshMeterGroup(player); } diff --git a/carpetmodSrc/redstone/multimeter/common/network/packets/MeterGroupSubscriptionPacket.java b/carpetmodSrc/redstone/multimeter/common/network/packets/MeterGroupSubscriptionPacket.java index d9c1c8b3..fc904a14 100644 --- a/carpetmodSrc/redstone/multimeter/common/network/packets/MeterGroupSubscriptionPacket.java +++ b/carpetmodSrc/redstone/multimeter/common/network/packets/MeterGroupSubscriptionPacket.java @@ -9,37 +9,36 @@ import redstone.multimeter.server.meter.ServerMeterGroup; public class MeterGroupSubscriptionPacket implements RSMMPacket { - + private String name; - private boolean subscribed; - + private boolean subscribe; + public MeterGroupSubscriptionPacket() { - } - + public MeterGroupSubscriptionPacket(String name, boolean subscribed) { this.name = name; - this.subscribed = subscribed; + this.subscribe = subscribed; } - + @Override public void encode(NBTTagCompound data) { data.setString("name", name); - data.setBoolean("subscribed", subscribed); + data.setBoolean("subscribe", subscribe); } - + @Override public void decode(NBTTagCompound data) { name = data.getString("name"); - subscribed = data.getBoolean("subscribed"); + subscribe = data.getBoolean("subscribe"); } - + @Override - public void execute(MultimeterServer server, EntityPlayerMP player) { + public void handle(MultimeterServer server, EntityPlayerMP player) { Multimeter multimeter = server.getMultimeter(); ServerMeterGroup meterGroup = multimeter.getMeterGroup(name); - - if (subscribed) { + + if (subscribe) { if (meterGroup == null) { multimeter.createMeterGroup(player, name); } else { diff --git a/carpetmodSrc/redstone/multimeter/common/network/packets/MeterIndexPacket.java b/carpetmodSrc/redstone/multimeter/common/network/packets/MeterIndexPacket.java new file mode 100644 index 00000000..bbb1bad2 --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/common/network/packets/MeterIndexPacket.java @@ -0,0 +1,38 @@ +package redstone.multimeter.common.network.packets; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.nbt.NBTTagCompound; + +import redstone.multimeter.common.network.RSMMPacket; +import redstone.multimeter.server.MultimeterServer; + +public class MeterIndexPacket implements RSMMPacket { + + private long id; + private int index; + + public MeterIndexPacket() { + } + + public MeterIndexPacket(long id, int index) { + this.id = id; + this.index = index; + } + + @Override + public void encode(NBTTagCompound data) { + data.setLong("id", id); + data.setInteger("index", index); + } + + @Override + public void decode(NBTTagCompound data) { + id = data.getLong("id"); + index = data.getInteger("index"); + } + + @Override + public void handle(MultimeterServer server, EntityPlayerMP player) { + server.getMultimeter().setMeterIndex(player, id, index); + } +} diff --git a/carpetmodSrc/redstone/multimeter/common/network/packets/MeterLogsPacket.java b/carpetmodSrc/redstone/multimeter/common/network/packets/MeterLogsPacket.java index ccf0ff2b..f4cf862f 100644 --- a/carpetmodSrc/redstone/multimeter/common/network/packets/MeterLogsPacket.java +++ b/carpetmodSrc/redstone/multimeter/common/network/packets/MeterLogsPacket.java @@ -2,34 +2,34 @@ import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; import redstone.multimeter.common.network.RSMMPacket; import redstone.multimeter.server.MultimeterServer; +import redstone.multimeter.util.NbtUtils; public class MeterLogsPacket implements RSMMPacket { - - private NBTTagCompound logsData; - + + private NBTTagList logsData; + public MeterLogsPacket() { - } - - public MeterLogsPacket(NBTTagCompound data) { - this.logsData = data; + + public MeterLogsPacket(NBTTagList logsData) { + this.logsData = logsData; } - + @Override public void encode(NBTTagCompound data) { data.setTag("logs", logsData); } - + @Override public void decode(NBTTagCompound data) { - logsData = data.getCompoundTag("logs"); + logsData = data.getTagList("logs", NbtUtils.TYPE_COMPOUND); } - + @Override - public void execute(MultimeterServer server, EntityPlayerMP player) { - + public void handle(MultimeterServer server, EntityPlayerMP player) { } } diff --git a/carpetmodSrc/redstone/multimeter/common/network/packets/MeterUpdatePacket.java b/carpetmodSrc/redstone/multimeter/common/network/packets/MeterUpdatePacket.java index 315c4748..d2503ca6 100644 --- a/carpetmodSrc/redstone/multimeter/common/network/packets/MeterUpdatePacket.java +++ b/carpetmodSrc/redstone/multimeter/common/network/packets/MeterUpdatePacket.java @@ -8,33 +8,32 @@ import redstone.multimeter.server.MultimeterServer; public class MeterUpdatePacket implements RSMMPacket { - + private long id; private MeterProperties properties; - + public MeterUpdatePacket() { - } - + public MeterUpdatePacket(long id, MeterProperties properties) { this.id = id; this.properties = properties; } - + @Override public void encode(NBTTagCompound data) { data.setLong("id", id); data.setTag("properties", properties.toNbt()); } - + @Override public void decode(NBTTagCompound data) { id = data.getLong("id"); properties = MeterProperties.fromNbt(data.getCompoundTag("properties")); } - + @Override - public void execute(MultimeterServer server, EntityPlayerMP player) { + public void handle(MultimeterServer server, EntityPlayerMP player) { server.getMultimeter().updateMeter(player, id, properties); } } diff --git a/carpetmodSrc/redstone/multimeter/common/network/packets/MeterUpdatesPacket.java b/carpetmodSrc/redstone/multimeter/common/network/packets/MeterUpdatesPacket.java index 376328d1..f71edf56 100644 --- a/carpetmodSrc/redstone/multimeter/common/network/packets/MeterUpdatesPacket.java +++ b/carpetmodSrc/redstone/multimeter/common/network/packets/MeterUpdatesPacket.java @@ -9,7 +9,6 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.nbt.NBTBase; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.nbt.NBTTagLong; @@ -23,64 +22,92 @@ public class MeterUpdatesPacket implements RSMMPacket { private List removedMeters; private Long2ObjectMap meterUpdates; + private List meters; public MeterUpdatesPacket() { this.removedMeters = new ArrayList<>(); this.meterUpdates = new Long2ObjectOpenHashMap<>(); + this.meters = new ArrayList<>(); } - public MeterUpdatesPacket(List removedMeters, Map updates) { + public MeterUpdatesPacket(List removedMeters, Map updates, List meters) { this.removedMeters = new ArrayList<>(removedMeters); this.meterUpdates = new Long2ObjectOpenHashMap<>(updates); + this.meters = new ArrayList<>(meters); } @Override public void encode(NBTTagCompound data) { - NBTTagList ids = new NBTTagList(); - NBTTagList list = new NBTTagList(); - - for (int index = 0; index < removedMeters.size(); index++) { - long id = removedMeters.get(index); - - NBTTagLong nbt = new NBTTagLong(id); - ids.appendTag(nbt); + if (!removedMeters.isEmpty()) { + NBTTagList list = new NBTTagList(); + + for (int i = 0; i < removedMeters.size(); i++) { + list.appendTag(new NBTTagLong(removedMeters.get(i))); + } + + data.setTag("removed", list); + } + if (!meterUpdates.isEmpty()) { + NBTTagList list = new NBTTagList(); + + for (Entry entry : meterUpdates.long2ObjectEntrySet()) { + long id = entry.getLongKey(); + MeterProperties update = entry.getValue(); + + NBTTagCompound nbt = update.toNbt(); + nbt.setLong("id", id); + list.appendTag(nbt); + } + + data.setTag("updates", list); } - for (Entry entry : meterUpdates.long2ObjectEntrySet()) { - long id = entry.getLongKey(); - MeterProperties update = entry.getValue(); - - NBTTagCompound nbt = update.toNbt(); - nbt.setLong("id", id); - list.appendTag(nbt); + if (!meters.isEmpty()) { + NBTTagList list = new NBTTagList(); + + for (int i = 0; i < meters.size(); i++) { + list.appendTag(new NBTTagLong(meters.get(i))); + } + + data.setTag("meters", list); } - - data.setTag("removed meters", ids); - data.setTag("meter updates", list); } @Override public void decode(NBTTagCompound data) { - NBTTagList ids = data.getTagList("removed meters", NbtUtils.TYPE_LONG); - NBTTagList list = data.getTagList("meter updates", NbtUtils.TYPE_COMPOUND); - - for (int index = 0; index < ids.tagCount(); index++) { - NBTBase nbt = ids.get(index); - - if (nbt.getId() == NbtUtils.TYPE_LONG) { - removedMeters.add(((NBTTagLong)nbt).getLong()); + if (data.hasKey("removed")) { + NBTTagList ids = data.getTagList("removed", NbtUtils.TYPE_LONG); + + for (int i = 0; i < ids.tagCount(); i++) { + NBTTagLong nbt = (NBTTagLong)ids.get(i); + long id = nbt.getLong(); + + removedMeters.add(id); + } + } + if (data.hasKey("updates")) { + NBTTagList updates = data.getTagList("updates", NbtUtils.TYPE_COMPOUND); + + for (int i = 0; i < updates.tagCount(); i++) { + NBTTagCompound nbt = updates.getCompoundTagAt(i); + long id = nbt.getLong("id"); + MeterProperties update = MeterProperties.fromNbt(nbt); + + meterUpdates.put(id, update); } } - for (int index = 0; index < list.tagCount(); index++) { - NBTTagCompound nbt = list.getCompoundTagAt(index); - - long id = nbt.getLong("id"); - MeterProperties update = MeterProperties.fromNbt(nbt); - meterUpdates.put(id, update); + if (data.hasKey("meters")) { + NBTTagList ids = data.getTagList("meters", NbtUtils.TYPE_LONG); + + for (int i = 0; i < ids.tagCount(); i++) { + NBTTagLong nbt = (NBTTagLong)ids.get(i); + long id = nbt.getLong(); + + meters.add(id); + } } } @Override - public void execute(MultimeterServer server, EntityPlayerMP player) { - + public void handle(MultimeterServer server, EntityPlayerMP player) { } } diff --git a/carpetmodSrc/redstone/multimeter/common/network/packets/RebuildTickPhaseTreePacket.java b/carpetmodSrc/redstone/multimeter/common/network/packets/RebuildTickPhaseTreePacket.java new file mode 100644 index 00000000..bd381ea5 --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/common/network/packets/RebuildTickPhaseTreePacket.java @@ -0,0 +1,26 @@ +package redstone.multimeter.common.network.packets; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.nbt.NBTTagCompound; + +import redstone.multimeter.common.network.RSMMPacket; +import redstone.multimeter.server.MultimeterServer; + +public class RebuildTickPhaseTreePacket implements RSMMPacket { + + public RebuildTickPhaseTreePacket() { + } + + @Override + public void encode(NBTTagCompound data) { + } + + @Override + public void decode(NBTTagCompound data) { + } + + @Override + public void handle(MultimeterServer server, EntityPlayerMP player) { + server.rebuildTickPhaseTree(player); + } +} diff --git a/carpetmodSrc/redstone/multimeter/common/network/packets/RemoveMeterPacket.java b/carpetmodSrc/redstone/multimeter/common/network/packets/RemoveMeterPacket.java index 2f1b9d33..f17c63a1 100644 --- a/carpetmodSrc/redstone/multimeter/common/network/packets/RemoveMeterPacket.java +++ b/carpetmodSrc/redstone/multimeter/common/network/packets/RemoveMeterPacket.java @@ -7,29 +7,28 @@ import redstone.multimeter.server.MultimeterServer; public class RemoveMeterPacket implements RSMMPacket { - + private long id; - + public RemoveMeterPacket() { - } - + public RemoveMeterPacket(long id) { this.id = id; } - + @Override public void encode(NBTTagCompound data) { data.setLong("id", id); } - + @Override public void decode(NBTTagCompound data) { id = data.getLong("id"); } - + @Override - public void execute(MultimeterServer server, EntityPlayerMP player) { + public void handle(MultimeterServer server, EntityPlayerMP player) { server.getMultimeter().removeMeter(player, id); } } diff --git a/carpetmodSrc/redstone/multimeter/common/network/packets/TeleportToMeterPacket.java b/carpetmodSrc/redstone/multimeter/common/network/packets/TeleportToMeterPacket.java index 63649cd4..1e6bf5fe 100644 --- a/carpetmodSrc/redstone/multimeter/common/network/packets/TeleportToMeterPacket.java +++ b/carpetmodSrc/redstone/multimeter/common/network/packets/TeleportToMeterPacket.java @@ -7,29 +7,28 @@ import redstone.multimeter.server.MultimeterServer; public class TeleportToMeterPacket implements RSMMPacket { - + private long id; - + public TeleportToMeterPacket() { - } - + public TeleportToMeterPacket(long id) { this.id = id; } - + @Override public void encode(NBTTagCompound data) { data.setLong("id", id); } - + @Override public void decode(NBTTagCompound data) { id = data.getLong("id"); } - + @Override - public void execute(MultimeterServer server, EntityPlayerMP player) { + public void handle(MultimeterServer server, EntityPlayerMP player) { server.getMultimeter().teleportToMeter(player, id); } } diff --git a/carpetmodSrc/redstone/multimeter/common/network/packets/TickPhaseTreePacket.java b/carpetmodSrc/redstone/multimeter/common/network/packets/TickPhaseTreePacket.java index ef3d4463..375e99c4 100644 --- a/carpetmodSrc/redstone/multimeter/common/network/packets/TickPhaseTreePacket.java +++ b/carpetmodSrc/redstone/multimeter/common/network/packets/TickPhaseTreePacket.java @@ -7,29 +7,28 @@ import redstone.multimeter.server.MultimeterServer; public class TickPhaseTreePacket implements RSMMPacket { - + private NBTTagCompound nbt; - + public TickPhaseTreePacket() { - } - + public TickPhaseTreePacket(NBTTagCompound nbt) { this.nbt = nbt; } - + @Override public void encode(NBTTagCompound data) { data.setTag("tick phase tree", nbt); } - + @Override public void decode(NBTTagCompound data) { nbt = data.getCompoundTag("tick phase tree"); } - + @Override - public void execute(MultimeterServer server, EntityPlayerMP player) { + public void handle(MultimeterServer server, EntityPlayerMP player) { server.refreshTickPhaseTree(player); } } diff --git a/carpetmodSrc/redstone/multimeter/common/network/packets/ServerTickPacket.java b/carpetmodSrc/redstone/multimeter/common/network/packets/TickTimePacket.java similarity index 51% rename from carpetmodSrc/redstone/multimeter/common/network/packets/ServerTickPacket.java rename to carpetmodSrc/redstone/multimeter/common/network/packets/TickTimePacket.java index b7ba2609..8020fe79 100644 --- a/carpetmodSrc/redstone/multimeter/common/network/packets/ServerTickPacket.java +++ b/carpetmodSrc/redstone/multimeter/common/network/packets/TickTimePacket.java @@ -6,30 +6,28 @@ import redstone.multimeter.common.network.RSMMPacket; import redstone.multimeter.server.MultimeterServer; -public class ServerTickPacket implements RSMMPacket { - - private long serverTime; - - public ServerTickPacket() { - +public class TickTimePacket implements RSMMPacket { + + private long gameTime; + + public TickTimePacket() { } - - public ServerTickPacket(long serverTime) { - this.serverTime = serverTime; + + public TickTimePacket(long serverTime) { + this.gameTime = serverTime; } - + @Override public void encode(NBTTagCompound data) { - data.setLong("server time", serverTime); + data.setLong("game time", gameTime); } - + @Override public void decode(NBTTagCompound data) { - serverTime = data.getLong("server time"); + gameTime = data.getLong("game time"); } - + @Override - public void execute(MultimeterServer server, EntityPlayerMP player) { - + public void handle(MultimeterServer server, EntityPlayerMP player) { } } diff --git a/carpetmodSrc/redstone/multimeter/helper/WorldHelper.java b/carpetmodSrc/redstone/multimeter/helper/WorldHelper.java index 473df9c1..b94bc5e0 100644 --- a/carpetmodSrc/redstone/multimeter/helper/WorldHelper.java +++ b/carpetmodSrc/redstone/multimeter/helper/WorldHelper.java @@ -3,12 +3,10 @@ import carpet.CarpetServer; import carpet.CarpetSettings; -import net.minecraft.block.BlockEventData; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.Entity; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.math.BlockPos; -import net.minecraft.world.NextTickListEntry; import net.minecraft.world.World; import redstone.multimeter.common.TickTask; @@ -16,47 +14,35 @@ import redstone.multimeter.server.MultimeterServer; public class WorldHelper { - + public static int currentBlockEventDepth; - + public static MultimeterServer getMultimeterServer() { return CarpetServer.rsmmServer; } - + public static Multimeter getMultimeter() { return CarpetServer.rsmmServer.getMultimeter(); } - + public static void startTickTask(TickTask task, String... args) { - startTickTask(true, task, args); - } - - public static void startTickTask(boolean updateTree, TickTask task, String... args) { if (CarpetSettings.redstoneMultimeter) { - getMultimeterServer().startTickTask(updateTree, task, args); + getMultimeterServer().startTickTask(task, args); } } - + public static void endTickTask() { - endTickTask(true); - } - - public static void endTickTask(boolean updateTree) { if (CarpetSettings.redstoneMultimeter) { - getMultimeterServer().endTickTask(updateTree); + getMultimeterServer().endTickTask(); } } - + public static void swapTickTask(TickTask task, String... args) { - swapTickTask(true, task, args); - } - - public static void swapTickTask(boolean updateTree, TickTask task, String... args) { if (CarpetSettings.redstoneMultimeter) { - getMultimeterServer().swapTickTask(updateTree, task, args); + getMultimeterServer().swapTickTask(task, args); } } - + public static void onBlockUpdate(World world, BlockPos pos, IBlockState state) { if (CarpetSettings.redstoneMultimeter) { MultimeterServer server = getMultimeterServer(); @@ -64,51 +50,51 @@ public static void onBlockUpdate(World world, BlockPos pos, IBlockState state) { multimeter.logBlockUpdate(world, pos); - if (state.getBlock().logPoweredOnBlockUpdate()) { + if (state.getBlock().rsmm$logPoweredOnBlockUpdate()) { multimeter.logPowered(world, pos, state); } } } - + public static void onObserverUpdate(World world, BlockPos pos) { if (CarpetSettings.redstoneMultimeter) { getMultimeter().logObserverUpdate(world, pos); } } - + public static void onEntityTick(World world, Entity entity) { if (CarpetSettings.redstoneMultimeter) { getMultimeter().logEntityTick(world, entity); } } - + public static void onBlockEntityTick(World world, TileEntity blockEntity) { if (CarpetSettings.redstoneMultimeter) { getMultimeter().logBlockEntityTick(world, blockEntity); } } - + public static void onComparatorUpdate(World world, BlockPos pos) { if (CarpetSettings.redstoneMultimeter) { getMultimeter().logComparatorUpdate(world, pos); } } - + public static void onRandomTick(World world, BlockPos pos) { if (CarpetSettings.redstoneMultimeter) { getMultimeter().logRandomTick(world, pos); } } - - public static void onScheduledTick(World world, NextTickListEntry scheduledTick) { + + public static void onScheduledTick(World world, BlockPos pos, int priority, boolean scheduling) { if (CarpetSettings.redstoneMultimeter) { - getMultimeter().logScheduledTick(world, scheduledTick); + getMultimeter().logScheduledTick(world, pos, priority, scheduling); } } - - public static void onBlockEvent(World world, BlockEventData blockEvent) { + + public static void onBlockEvent(World world, BlockPos pos, int type, boolean scheduling) { if (CarpetSettings.redstoneMultimeter) { - getMultimeter().logBlockEvent(world, blockEvent, currentBlockEventDepth); + getMultimeter().logBlockEvent(world, pos, type, currentBlockEventDepth, scheduling); } } } diff --git a/carpetmodSrc/redstone/multimeter/interfaces/IBlock.java b/carpetmodSrc/redstone/multimeter/interfaces/IBlock.java index b8b139b9..c762c8b0 100644 --- a/carpetmodSrc/redstone/multimeter/interfaces/IBlock.java +++ b/carpetmodSrc/redstone/multimeter/interfaces/IBlock.java @@ -5,20 +5,20 @@ import net.minecraft.world.World; public interface IBlock { - - default boolean isMeterable() { + + default boolean rsmm$isMeterable() { return false; } - - default boolean isPowerSource() { + + default boolean rsmm$isPowerSource() { return false; } - - default boolean logPoweredOnBlockUpdate() { + + default boolean rsmm$logPoweredOnBlockUpdate() { return true; } - - default boolean isPowered(World world, BlockPos pos, IBlockState state) { + + default boolean rsmm$isPowered(World world, BlockPos pos, IBlockState state) { return world.isBlockPowered(pos); } } diff --git a/carpetmodSrc/redstone/multimeter/registry/SupplierClazzRegistry.java b/carpetmodSrc/redstone/multimeter/registry/SupplierClazzRegistry.java deleted file mode 100644 index 1eda701a..00000000 --- a/carpetmodSrc/redstone/multimeter/registry/SupplierClazzRegistry.java +++ /dev/null @@ -1,52 +0,0 @@ -package redstone.multimeter.registry; - -import java.util.HashMap; -import java.util.Map; -import java.util.function.Supplier; - -import net.minecraft.util.ResourceLocation; - -import redstone.multimeter.RedstoneMultimeter; - -public class SupplierClazzRegistry { - - private final ResourceLocation id; - private final Map, ResourceLocation> clazzToId; - private final Map> idToSupplier; - - public SupplierClazzRegistry(String name) { - this.id = new ResourceLocation(RedstoneMultimeter.NAMESPACE, name); - this.clazzToId = new HashMap<>(); - this.idToSupplier = new HashMap<>(); - } - - public ResourceLocation getId() { - return id; - } - - @SuppressWarnings("unchecked") - public

P get(ResourceLocation id) { - Supplier objSupplier = idToSupplier.get(id); - return objSupplier == null ? null : (P)objSupplier.get(); - } - - public

ResourceLocation getId(P obj) { - return clazzToId.get(obj.getClass()); - } - - public

void register(String name, Class

clazz, Supplier

supplier) { - String namespace = id.getNamespace(); - String path = String.format("%s/%s", id.getPath(), name); - ResourceLocation id = new ResourceLocation(namespace, path); - - if (clazzToId.containsKey(clazz)) { - throw new IllegalStateException("Registry " + this.id + " already registered an entry with clazz " + clazz); - } - if (idToSupplier.containsKey(id)) { - throw new IllegalStateException("Registry " + this.id + " already registered an entry with id " + id); - } - - clazzToId.put(clazz, id); - idToSupplier.put(id, supplier); - } -} diff --git a/carpetmodSrc/redstone/multimeter/registry/SupplierRegistry.java b/carpetmodSrc/redstone/multimeter/registry/SupplierRegistry.java new file mode 100644 index 00000000..bf63645c --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/registry/SupplierRegistry.java @@ -0,0 +1,51 @@ +package redstone.multimeter.registry; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.Supplier; + +import redstone.multimeter.RedstoneMultimeter; + +public class SupplierRegistry { + + private final String key; + private final Map, String> byKey; + private final Map> keys; + + public SupplierRegistry() { + this(RedstoneMultimeter.NAMESPACE); + } + + public SupplierRegistry(String key) { + this.key = key; + this.byKey = new HashMap<>(); + this.keys = new HashMap<>(); + } + + public String getRegistryKey() { + return key; + } + + public T get(String key) { + Supplier supplier = keys.get(key); + return supplier == null ? null : supplier.get(); + } + + public String getKey(T obj) { + return byKey.get(obj.getClass()); + } + + public

void register(String name, Class

type, Supplier

supplier) { + String key = this.key + "|" + name; + + if (byKey.containsKey(type)) { + throw new IllegalStateException("Registry " + this.key + " already registered an entry with type " + type); + } + if (keys.containsKey(key)) { + throw new IllegalStateException("Registry " + this.key + " already registered an entry with key " + key); + } + + byKey.put(type, key); + keys.put(key, supplier); + } +} diff --git a/carpetmodSrc/redstone/multimeter/server/Multimeter.java b/carpetmodSrc/redstone/multimeter/server/Multimeter.java index d1d332b8..29c39dc5 100644 --- a/carpetmodSrc/redstone/multimeter/server/Multimeter.java +++ b/carpetmodSrc/redstone/multimeter/server/Multimeter.java @@ -11,9 +11,11 @@ import java.util.Map; import java.util.Set; import java.util.UUID; +import java.util.function.Supplier; + +import com.google.common.base.Suppliers; import net.minecraft.block.Block; -import net.minecraft.block.BlockEventData; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayerMP; @@ -26,7 +28,6 @@ import net.minecraft.util.text.TextFormatting; import net.minecraft.util.text.event.ClickEvent; import net.minecraft.util.text.event.HoverEvent; -import net.minecraft.world.NextTickListEntry; import net.minecraft.world.World; import net.minecraft.world.WorldServer; @@ -45,23 +46,22 @@ import redstone.multimeter.server.meter.ServerMeterGroup; import redstone.multimeter.server.meter.ServerMeterPropertiesManager; import redstone.multimeter.server.meter.event.MeterEventPredicate; -import redstone.multimeter.server.meter.event.MeterEventSupplier; import redstone.multimeter.server.option.Options; import redstone.multimeter.server.option.OptionsManager; public class Multimeter { - + private static final NumberFormat NUMBER_FORMAT = NumberFormat.getNumberInstance(Locale.US); - + private final MultimeterServer server; private final Map meterGroups; private final Map subscriptions; private final Set activeMeterGroups; private final Set idleMeterGroups; private final ServerMeterPropertiesManager meterPropertiesManager; - + public Options options; - + public Multimeter(MultimeterServer server) { this.server = server; this.meterGroups = new LinkedHashMap<>(); @@ -69,128 +69,129 @@ public Multimeter(MultimeterServer server) { this.activeMeterGroups = new HashSet<>(); this.idleMeterGroups = new HashSet<>(); this.meterPropertiesManager = new ServerMeterPropertiesManager(this); - + reloadOptions(); } - - public MultimeterServer getMultimeterServer() { + + public MultimeterServer getServer() { return server; } - + public Collection getMeterGroups() { return Collections.unmodifiableCollection(meterGroups.values()); } - + public ServerMeterGroup getMeterGroup(String name) { return meterGroups.get(name); } - + public boolean hasMeterGroup(String name) { return meterGroups.containsKey(name); } - + public ServerMeterGroup getSubscription(EntityPlayerMP player) { return subscriptions.get(player.getUniqueID()); } - + public boolean hasSubscription(EntityPlayerMP player) { return subscriptions.containsKey(player.getUniqueID()); } - + public boolean isOwnerOfSubscription(EntityPlayerMP player) { ServerMeterGroup meterGroup = getSubscription(player); return meterGroup != null && meterGroup.isOwnedBy(player); } - + public void reloadOptions() { if (server.isDedicated()) { - options = OptionsManager.load(server.getConfigFolder()); + options = OptionsManager.load(server.getConfigDirectory()); } else { options = new Options(); } } - + public void tickStart(boolean paused) { if (!paused) { removeIdleMeterGroups(); - + for (ServerMeterGroup meterGroup : meterGroups.values()) { meterGroup.tick(); } } } - + public void tickEnd(boolean paused) { broadcastMeterUpdates(); - + if (!paused) { broadcastMeterLogs(); } } - + private void removeIdleMeterGroups() { Iterator it = idleMeterGroups.iterator(); - + while (it.hasNext()) { ServerMeterGroup meterGroup = it.next(); - - if (tryRemoveMeterGroup(meterGroup)) { + + if (removeIdleMeterGroup(meterGroup)) { it.remove(); } } } - - private boolean tryRemoveMeterGroup(ServerMeterGroup meterGroup) { + + private boolean removeIdleMeterGroup(ServerMeterGroup meterGroup) { if (meterGroup.hasMeters() && !meterGroup.isPastIdleTimeLimit()) { return false; } - + meterGroups.remove(meterGroup.getName(), meterGroup); - + if (meterGroup.hasMeters()) { notifyOwnerOfRemoval(meterGroup); } - + return true; } - + private void notifyOwnerOfRemoval(ServerMeterGroup meterGroup) { - UUID ownerUUID = meterGroup.getOwner(); - EntityPlayerMP owner = server.getPlayer(ownerUUID); - + UUID ownerUuid = meterGroup.getOwner(); + EntityPlayerMP owner = server.getPlayerList().get(ownerUuid); + if (owner != null) { ITextComponent message = new TextComponentString(String.format("One of your meter groups, \'%s\', was idle for more than %d ticks and has been removed.", meterGroup.getName(), options.meter_group.max_idle_time)); server.sendMessage(owner, message, false); } } - + private void broadcastMeterUpdates() { for (ServerMeterGroup meterGroup : meterGroups.values()) { - meterGroup.flushUpdates(); + meterGroup.broadcastUpdates(); } } - + private void broadcastMeterLogs() { for (ServerMeterGroup meterGroup : meterGroups.values()) { - meterGroup.getLogManager().flushLogs(); + meterGroup.getLogManager().broadcastLogs(); } } - + public void onPlayerJoin(EntityPlayerMP player) { - + server.refreshTickPhaseTree(player); + server.getPlayerList().updatePermissions(player); } - + public void onPlayerLeave(EntityPlayerMP player) { ServerMeterGroup meterGroup = getSubscription(player); - + if (meterGroup != null) { removeSubscriberFromMeterGroup(meterGroup, player); } } - + public void addMeter(EntityPlayerMP player, MeterProperties properties) { ServerMeterGroup meterGroup = getSubscription(player); - + if (meterGroup != null) { if (meterGroup.isPastMeterLimit()) { ITextComponent message = new TextComponentString(String.format("meter limit (%d) reached!", options.meter_group.meter_limit)); @@ -200,369 +201,382 @@ public void addMeter(EntityPlayerMP player, MeterProperties properties) { } } } - + public boolean addMeter(ServerMeterGroup meterGroup, MeterProperties meterProperties) { - MutableMeterProperties properties = meterProperties.toMutable(); - + MutableMeterProperties properties = meterProperties.mutable(); + if (!meterPropertiesManager.validate(properties) || !meterGroup.addMeter(properties)) { return false; } - + DimPos pos = properties.getPos(); - World world = server.getWorldOf(pos); + World world = server.getWorld(pos); BlockPos blockPos = pos.getBlockPos(); IBlockState state = world.getBlockState(blockPos); - + logPowered(world, blockPos, state); logActive(world, blockPos, state); - + return true; } - + public void removeMeter(EntityPlayerMP player, long id) { ServerMeterGroup meterGroup = getSubscription(player); - + if (meterGroup != null && !meterGroup.removeMeter(id)) { refreshMeterGroup(meterGroup, player); } } - + public void updateMeter(EntityPlayerMP player, long id, MeterProperties newProperties) { ServerMeterGroup meterGroup = getSubscription(player); - + if (meterGroup != null && !meterGroup.updateMeter(id, newProperties)) { refreshMeterGroup(meterGroup, player); } } - + + public void setMeterIndex(EntityPlayerMP player, long id, int index) { + ServerMeterGroup meterGroup = getSubscription(player); + + if (meterGroup != null && !meterGroup.setMeterIndex(id, index)) { + refreshMeterGroup(meterGroup, player); + } + } + public void clearMeterGroup(EntityPlayerMP player) { ServerMeterGroup meterGroup = getSubscription(player); - + if (meterGroup != null) { clearMeterGroup(meterGroup); } } - + public void clearMeterGroup(ServerMeterGroup meterGroup) { meterGroup.clear(); - + ClearMeterGroupPacket packet = new ClearMeterGroupPacket(); - server.getPacketHandler().sendToSubscribers(packet, meterGroup); + server.getPlayerList().send(packet, meterGroup); } - + public void createMeterGroup(EntityPlayerMP player, String name) { if (!MeterGroup.isValidName(name) || meterGroups.containsKey(name)) { return; } - + ServerMeterGroup meterGroup = new ServerMeterGroup(this, name, player); meterGroups.put(name, meterGroup); - + subscribeToMeterGroup(meterGroup, player); } - + public void subscribeToMeterGroup(ServerMeterGroup meterGroup, EntityPlayerMP player) { ServerMeterGroup prevSubscription = getSubscription(player); - + if (prevSubscription == meterGroup) { refreshMeterGroup(meterGroup, player); } else { if (prevSubscription != null) { removeSubscriberFromMeterGroup(prevSubscription, player); } - + addSubscriberToMeterGroup(meterGroup, player); onSubscriptionChanged(player, prevSubscription, meterGroup); } } - + public void subscribeToDefaultMeterGroup(EntityPlayerMP player) { MeterGroupDefaultPacket packet = new MeterGroupDefaultPacket(); - server.getPacketHandler().sendToPlayer(packet, player); + server.getPlayerList().send(packet, player); } - + private void addSubscriberToMeterGroup(ServerMeterGroup meterGroup, EntityPlayerMP player) { - UUID playerUUID = player.getUniqueID(); - - subscriptions.put(playerUUID, meterGroup); - meterGroup.addSubscriber(playerUUID); - + UUID playerUuid = player.getUniqueID(); + + subscriptions.put(playerUuid, meterGroup); + meterGroup.addSubscriber(playerUuid); + if (meterGroup.updateIdleState()) { activeMeterGroups.add(meterGroup); idleMeterGroups.remove(meterGroup); } } - + public void unsubscribeFromMeterGroup(EntityPlayerMP player) { ServerMeterGroup meterGroup = getSubscription(player); - + if (meterGroup != null) { unsubscribeFromMeterGroup(meterGroup, player); } } - + public void unsubscribeFromMeterGroup(ServerMeterGroup meterGroup, EntityPlayerMP player) { if (meterGroup.hasSubscriber(player)) { removeSubscriberFromMeterGroup(meterGroup, player); onSubscriptionChanged(player, meterGroup, null); } } - + private void removeSubscriberFromMeterGroup(ServerMeterGroup meterGroup, EntityPlayerMP player) { - UUID playerUUID = player.getUniqueID(); - - subscriptions.remove(playerUUID, meterGroup); - meterGroup.removeSubscriber(playerUUID); - + UUID playerUuid = player.getUniqueID(); + + subscriptions.remove(playerUuid, meterGroup); + meterGroup.removeSubscriber(playerUuid); + if (meterGroup.updateIdleState()) { activeMeterGroups.remove(meterGroup); idleMeterGroups.add(meterGroup); } } - + private void onSubscriptionChanged(EntityPlayerMP player, ServerMeterGroup prevSubscription, ServerMeterGroup newSubscription) { MeterGroupSubscriptionPacket packet; - + if (newSubscription == null) { packet = new MeterGroupSubscriptionPacket(prevSubscription.getName(), false); } else { packet = new MeterGroupSubscriptionPacket(newSubscription.getName(), true); } - - server.getPacketHandler().sendToPlayer(packet, player); - server.getPlayerManager().updatePermissionLevel(player); + + server.getPlayerList().send(packet, player); + server.getPlayerList().updatePermissions(player); } - + public void clearMembersOfMeterGroup(ServerMeterGroup meterGroup) { - for (UUID playerUUID : meterGroup.getMembers()) { - removeMemberFromMeterGroup(meterGroup, playerUUID); + for (UUID playerUuid : meterGroup.getMembers()) { + removeMemberFromMeterGroup(meterGroup, playerUuid); } } - - public void addMemberToMeterGroup(ServerMeterGroup meterGroup, UUID playerUUID) { - if (meterGroup.hasMember(playerUUID) || meterGroup.isOwnedBy(playerUUID)) { + + public void addMemberToMeterGroup(ServerMeterGroup meterGroup, UUID playerUuid) { + if (meterGroup.hasMember(playerUuid) || meterGroup.isOwnedBy(playerUuid)) { return; } - - EntityPlayerMP player = server.getPlayer(playerUUID); - + + EntityPlayerMP player = server.getPlayerList().get(playerUuid); + if (player == null) { return; } - - meterGroup.addMember(playerUUID); - - ITextComponent message = new TextComponentString(""). - appendSibling(new TextComponentString(String.format("You have been invited to meter group \'%s\' - click ", meterGroup.getName()))). - appendSibling(new TextComponentString("[here]").setStyle(new Style(). - setColor(TextFormatting.GREEN). - setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponentString(String.format("Subscribe to meter group \'%s\'", meterGroup.getName())))). - setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, String.format("/metergroup subscribe %s", meterGroup.getName()))) - )). - appendSibling(new TextComponentString(" to subscribe to it.")); + + meterGroup.addMember(playerUuid); + + ITextComponent message = new TextComponentString("") + .appendSibling(new TextComponentString(String.format("You have been invited to meter group \'%s\' - click ", meterGroup.getName()))) + .appendSibling(new TextComponentString("[here]").setStyle(new Style() + .setColor(TextFormatting.GREEN) + .setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, + new TextComponentString(String.format("Subscribe to meter group \'%s\'", meterGroup.getName())))) + .setClickEvent( + new ClickEvent(ClickEvent.Action.RUN_COMMAND, String.format("/metergroup subscribe %s", meterGroup.getName()))) + )).appendSibling(new TextComponentString(" to subscribe to it.")); server.sendMessage(player, message, false); } - - public void removeMemberFromMeterGroup(ServerMeterGroup meterGroup, UUID playerUUID) { - if (!meterGroup.hasMember(playerUUID)) { + + public void removeMemberFromMeterGroup(ServerMeterGroup meterGroup, UUID playerUuid) { + if (!meterGroup.hasMember(playerUuid)) { return; } - - meterGroup.removeMember(playerUUID); - + + meterGroup.removeMember(playerUuid); + if (meterGroup.isPrivate()) { - EntityPlayerMP player = server.getPlayer(playerUUID); - - if (player != null && meterGroup.hasSubscriber(playerUUID)) { + EntityPlayerMP player = server.getPlayerList().get(playerUuid); + + if (player != null && meterGroup.hasSubscriber(playerUuid)) { unsubscribeFromMeterGroup(meterGroup, player); - + ITextComponent message = new TextComponentString(String.format("The owner of meter group \'%s\' has removed you as a member!", meterGroup.getName())); server.sendMessage(player, message, false); } } } - + public void refreshMeterGroup(EntityPlayerMP player) { ServerMeterGroup meterGroup = getSubscription(player); - + if (meterGroup != null) { refreshMeterGroup(meterGroup, player); } } - + private void refreshMeterGroup(ServerMeterGroup meterGroup, EntityPlayerMP player) { MeterGroupRefreshPacket packet = new MeterGroupRefreshPacket(meterGroup); - server.getPacketHandler().sendToPlayer(packet, player); + server.getPlayerList().send(packet, player); } - + public void teleportToMeter(EntityPlayerMP player, long id) { if (!options.meter.allow_teleports) { ITextComponent message = new TextComponentString("This server does not allow meter teleporting!"); server.sendMessage(player, message, false); - + return; } - + ServerMeterGroup meterGroup = getSubscription(player); - + if (meterGroup != null) { Meter meter = meterGroup.getMeter(id); - + if (meter != null) { DimPos pos = meter.getPos(); - WorldServer newWorld = server.getWorldOf(pos); - + WorldServer newWorld = server.getWorld(pos); + if (newWorld != null) { BlockPos blockPos = pos.getBlockPos(); - + double newX = blockPos.getX() + 0.5D; double newY = blockPos.getY(); double newZ = blockPos.getZ() + 0.5D; - float yaw = player.rotationYaw; - float pitch = player.rotationPitch; - + float newYaw = player.rotationYaw; + float newPitch = player.rotationPitch; + player.changeDimension(newWorld.provider.getDimensionType().getId()); - player.connection.setPlayerLocation(newX, newY, newZ, yaw, pitch); - + player.connection.setPlayerLocation(newX, newY, newZ, newYaw, newPitch); + ITextComponent text = new TextComponentString(String.format("Teleported to meter \"%s\"", meter.getName())); server.sendMessage(player, text, false); } } } } - + public void onBlockChange(World world, BlockPos pos, IBlockState oldState, IBlockState newState) { Block oldBlock = oldState.getBlock(); Block newBlock = newState.getBlock(); - - if (oldBlock == newBlock && newBlock.isPowerSource() && ((PowerSource)newBlock).logPowerChangeOnStateChange()) { + + if (oldBlock == newBlock && newBlock.rsmm$isPowerSource() && ((PowerSource)newBlock).rsmm$logPowerChangeOnStateChange()) { logPowerChange(world, pos, oldState, newState); } - - boolean wasMeterable = oldBlock.isMeterable(); - boolean isMeterable = newBlock.isMeterable(); - + + boolean wasMeterable = oldBlock.rsmm$isMeterable(); + boolean isMeterable = newBlock.rsmm$isMeterable(); + if (wasMeterable || isMeterable) { logActive(world, pos, newState); } } - + public void logPowered(World world, BlockPos pos, boolean powered) { tryLogEvent(world, pos, EventType.POWERED, powered ? 1 : 0, (meterGroup, meter, event) -> meter.setPowered(powered)); } - + public void logPowered(World world, BlockPos pos, IBlockState state) { - tryLogEvent(world, pos, (meterGroup, meter, event) -> meter.setPowered(event.getMetadata() != 0), new MeterEventSupplier(EventType.POWERED, () -> { - return state.getBlock().isPowered(world, pos, state) ? 1 : 0; - })); + tryLogEvent(world, pos, EventType.POWERED, () -> { + return state.getBlock().rsmm$isPowered(world, pos, state) ? 1 : 0; + }, (meterGroup, meter, event) -> { + return meter.setPowered(event.getMetadata() != 0); + }); } - + public void logActive(World world, BlockPos pos, boolean active) { tryLogEvent(world, pos, EventType.ACTIVE, active ? 1 : 0, (meterGroup, meter, event) -> meter.setActive(active)); } - + public void logActive(World world, BlockPos pos, IBlockState state) { - tryLogEvent(world, pos, (meterGroup, meter, event) -> meter.setActive(event.getMetadata() != 0), new MeterEventSupplier(EventType.ACTIVE, () -> { + tryLogEvent(world, pos, EventType.ACTIVE, () -> { Block block = state.getBlock(); - return block.isMeterable() && ((Meterable)block).isActive(world, pos, state) ? 1 : 0; - })); + return block.rsmm$isMeterable() && ((Meterable)block).rsmm$isActive(world, pos, state) ? 1 : 0; + }, (meterGroup, meter, event) -> meter.setActive(event.getMetadata() != 0)); } - + public void logMoved(World world, BlockPos blockPos, EnumFacing dir) { tryLogEvent(world, blockPos, EventType.MOVED, dir.getIndex()); } - + public void moveMeters(World world, BlockPos blockPos, EnumFacing dir) { DimPos pos = new DimPos(world, blockPos); - + for (ServerMeterGroup meterGroup : activeMeterGroups) { meterGroup.tryMoveMeter(pos, dir); } } - + public void logPowerChange(World world, BlockPos pos, int oldPower, int newPower) { if (oldPower != newPower) { tryLogEvent(world, pos, EventType.POWER_CHANGE, (oldPower << 8) | newPower); } } - + public void logPowerChange(World world, BlockPos pos, IBlockState oldState, IBlockState newState) { - tryLogEvent(world, pos, (meterGroup, meter, event) -> { + tryLogEvent(world, pos, EventType.POWER_CHANGE, () -> { + PowerSource block = (PowerSource)newState.getBlock(); + int oldPower = block.rsmm$getPowerLevel(world, pos, oldState); + int newPower = block.rsmm$getPowerLevel(world, pos, newState); + + return (oldPower << 8) | newPower; + }, (meterGroup, meter, event) -> { int data = event.getMetadata(); int oldPower = (data >> 8) & 0xFF; - int newPower = data & 0xFF; - + int newPower = data & 0xFF; + return oldPower != newPower; - }, new MeterEventSupplier(EventType.POWER_CHANGE, () -> { - PowerSource block = (PowerSource)newState.getBlock(); - int oldPower = block.getPowerLevel(world, pos, oldState); - int newPower = block.getPowerLevel(world, pos, newState); - - return (oldPower << 8) | newPower; - })); + }); } - + public void logRandomTick(World world, BlockPos pos) { - tryLogEvent(world, pos, EventType.RANDOM_TICK, 0); + tryLogEvent(world, pos, EventType.RANDOM_TICK); } - - public void logScheduledTick(World world, NextTickListEntry scheduledTick) { - tryLogEvent(world, scheduledTick.position, EventType.SCHEDULED_TICK, scheduledTick.priority); + + public void logScheduledTick(World world, BlockPos pos, int priority, boolean scheduling) { + tryLogEvent(world, pos, EventType.SCHEDULED_TICK, (scheduling ? (1 << 30) : 0) | (priority + 3)); } - - public void logBlockEvent(World world, BlockEventData blockEvent, int depth) { - tryLogEvent(world, blockEvent.getPosition(), EventType.BLOCK_EVENT, (depth << 4) | blockEvent.getEventID()); + + public void logBlockEvent(World world, BlockPos pos, int type, int depth, boolean queueing) { + tryLogEvent(world, pos, EventType.BLOCK_EVENT, (queueing ? (1 << 30) : 0) | (depth << 4) | type); } - + public void logEntityTick(World world, Entity entity) { - tryLogEvent(world, entity.getPosition(), EventType.ENTITY_TICK, 0); + tryLogEvent(world, entity.getPosition(), EventType.ENTITY_TICK); } - + public void logBlockEntityTick(World world, TileEntity blockEntity) { - tryLogEvent(world, blockEntity.getPos(), EventType.BLOCK_ENTITY_TICK, 0); + tryLogEvent(world, blockEntity.getPos(), EventType.BLOCK_ENTITY_TICK); } - + public void logBlockUpdate(World world, BlockPos pos) { - tryLogEvent(world, pos, EventType.BLOCK_UPDATE, 0); + tryLogEvent(world, pos, EventType.BLOCK_UPDATE); } - + public void logComparatorUpdate(World world, BlockPos pos) { - tryLogEvent(world, pos, EventType.COMPARATOR_UPDATE, 0); + tryLogEvent(world, pos, EventType.COMPARATOR_UPDATE); } - + public void logShapeUpdate(World world, BlockPos pos, EnumFacing dir) { tryLogEvent(world, pos, EventType.SHAPE_UPDATE, dir.getIndex()); } - + public void logObserverUpdate(World world, BlockPos pos) { - tryLogEvent(world, pos, EventType.OBSERVER_UPDATE, 0); + tryLogEvent(world, pos, EventType.OBSERVER_UPDATE); } - + public void logInteractBlock(World world, BlockPos pos) { - tryLogEvent(world, pos, EventType.INTERACT_BLOCK, 0); + tryLogEvent(world, pos, EventType.INTERACT_BLOCK); } - + + private void tryLogEvent(World world, BlockPos pos, EventType type) { + tryLogEvent(world, pos, type, 0); + } + private void tryLogEvent(World world, BlockPos pos, EventType type, int data) { tryLogEvent(world, pos, type, data, (meterGroup, meter, event) -> true); } - + private void tryLogEvent(World world, BlockPos pos, EventType type, int data, MeterEventPredicate predicate) { - tryLogEvent(world, pos, predicate, new MeterEventSupplier(type, () -> data)); + tryLogEvent(world, pos, type, Suppliers.memoize(() -> data), predicate); } - - private void tryLogEvent(World world, BlockPos blockPos, MeterEventPredicate predicate, MeterEventSupplier supplier) { - if (options.hasEventType(supplier.type())) { - DimPos pos = new DimPos(world, blockPos); - + + private void tryLogEvent(World world, BlockPos pos, EventType type, Supplier data, MeterEventPredicate predicate) { + if (options.hasEventType(type)) { for (ServerMeterGroup meterGroup : activeMeterGroups) { - meterGroup.tryLogEvent(pos, predicate, supplier); + meterGroup.tryLogEvent(world, pos, type, data, predicate); } } } - + static { - + NUMBER_FORMAT.setGroupingUsed(false); - + } } diff --git a/carpetmodSrc/redstone/multimeter/server/MultimeterServer.java b/carpetmodSrc/redstone/multimeter/server/MultimeterServer.java index 9a6d2c0d..d71e2502 100644 --- a/carpetmodSrc/redstone/multimeter/server/MultimeterServer.java +++ b/carpetmodSrc/redstone/multimeter/server/MultimeterServer.java @@ -1,268 +1,214 @@ package redstone.multimeter.server; import java.io.File; -import java.util.Collection; -import java.util.HashMap; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Set; import java.util.UUID; -import carpet.CarpetSettings; import carpet.helpers.TickSpeed; - import net.minecraft.block.state.IBlockState; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.server.MinecraftServer; -import net.minecraft.server.management.PlayerList; -import net.minecraft.util.ResourceLocation; import net.minecraft.util.text.ITextComponent; import net.minecraft.world.DimensionType; import net.minecraft.world.World; import net.minecraft.world.WorldServer; - import redstone.multimeter.RedstoneMultimeter; import redstone.multimeter.common.DimPos; import redstone.multimeter.common.TickPhase; import redstone.multimeter.common.TickPhaseTree; import redstone.multimeter.common.TickTask; import redstone.multimeter.common.network.packets.HandshakePacket; -import redstone.multimeter.common.network.packets.ServerTickPacket; +import redstone.multimeter.common.network.packets.TickTimePacket; import redstone.multimeter.common.network.packets.TickPhaseTreePacket; -import redstone.multimeter.server.meter.ServerMeterGroup; -import redstone.multimeter.util.DimensionUtils; public class MultimeterServer { - + private final MinecraftServer server; private final ServerPacketHandler packetHandler; + private final PlayerList playerList; private final Multimeter multimeter; - private final Map connectedPlayers; - private final Map playerNameCache; private final TickPhaseTree tickPhaseTree; - + + private boolean loaded; private TickPhase tickPhase; - /** true if the OverWorld already ticked time */ - private boolean tickedTime; - + public MultimeterServer(MinecraftServer server) { this.server = server; this.packetHandler = new ServerPacketHandler(this); + this.playerList = new PlayerList(this); this.multimeter = new Multimeter(this); - this.connectedPlayers = new HashMap<>(); - this.playerNameCache = new HashMap<>(); this.tickPhaseTree = new TickPhaseTree(); - + this.tickPhase = TickPhase.UNKNOWN; - this.tickedTime = false; } - + public MinecraftServer getMinecraftServer() { return server; } - + public ServerPacketHandler getPacketHandler() { return packetHandler; } - + public Multimeter getMultimeter() { return multimeter; } - + public TickPhaseTree getTickPhaseTree() { return tickPhaseTree; } - + + public long getTicks() { + return server.getTickCounter(); + } + public boolean isDedicated() { return server.isDedicatedServer(); } - - public File getConfigFolder() { + + public File getConfigDirectory() { return new File(server.getDataDirectory(), RedstoneMultimeter.CONFIG_PATH); } - + public TickPhase getTickPhase() { return tickPhase; } - - public void startTickTask(boolean updateTree, TickTask task, String... args) { + + public void worldLoaded() { + loaded = true; + } + + public void startTickTask(TickTask task, String... args) { tickPhase = tickPhase.startTask(task); - if (updateTree) { + if (tickPhaseTree.isBuilding()) { tickPhaseTree.startTask(task, args); } } - - public void endTickTask(boolean updateTree) { + + public void endTickTask() { tickPhase = tickPhase.endTask(); - if (updateTree) { + if (tickPhaseTree.isBuilding()) { tickPhaseTree.endTask(); } } - - public void swapTickTask(boolean updateTree, TickTask task, String... args) { + + public void swapTickTask(TickTask task, String... args) { tickPhase = tickPhase.swapTask(task); - if (updateTree) { + if (tickPhaseTree.isBuilding()) { tickPhaseTree.swapTask(task, args); } } - - public void onOverworldTickTime() { - tickedTime = true; - } - - public long getCurrentTick() { - long tick = server.getWorld(DimensionType.OVERWORLD.getId()).getTotalWorldTime(); - - if (!tickedTime) { - tick++; - } - - return tick; + + public TickTask getCurrentTickTask() { + return tickPhase.peekTask(); } - + public boolean isPaused() { - return server.isPaused() || !TickSpeed.process_entities; + return false; // integrated servers only + } + + public boolean isPausedOrFrozen() { + return isPaused() || !TickSpeed.process_entities; } - + public void tickStart() { boolean paused = isPaused(); - + if (!paused) { - tickedTime = false; - - if (server.getTickCounter() % 72000 == 0) { - cleanPlayerNameCache(); - } if (shouldBuildTickPhaseTree()) { tickPhaseTree.start(); } + + playerList.tick(); } - + tickPhase = TickPhase.UNKNOWN; multimeter.tickStart(paused); } - - private void cleanPlayerNameCache() { - playerNameCache.keySet().removeIf(playerUUID -> { - for (ServerMeterGroup meterGroup : multimeter.getMeterGroups()) { - if (meterGroup.hasMember(playerUUID)) { - return false; - } - } - - return true; - }); - } - + private boolean shouldBuildTickPhaseTree() { - return CarpetSettings.redstoneMultimeter && !tickPhaseTree.isComplete() && !tickPhaseTree.isBuilding(); + return loaded && !tickPhaseTree.isComplete() && !tickPhaseTree.isBuilding() && !isPausedOrFrozen() && !playerList.get().isEmpty(); } - + public void tickEnd() { boolean paused = isPaused(); - - if (!paused) { - ServerTickPacket packet = new ServerTickPacket(getCurrentTick()); - - for (EntityPlayerMP player : server.getPlayerList().getPlayers()) { - if (multimeter.hasSubscription(player)) { - packetHandler.sendToPlayer(packet, player); - } - } - } + if (tickPhaseTree.isBuilding()) { tickPhaseTree.end(); } - + tickPhase = TickPhase.UNKNOWN; multimeter.tickEnd(paused); } - + + public void tickTime(World world) { + TickTimePacket packet = new TickTimePacket(world.getWorldTime()); + playerList.send(packet, world.provider.getDimensionType()); + } + + public void onHandshake(EntityPlayerMP player, String modVersion) { + if (!playerList.has(player.getUniqueID())) { + playerList.add(player); + + HandshakePacket packet = new HandshakePacket(); + playerList.send(packet, player); + } + } + public void onPlayerJoin(EntityPlayerMP player) { multimeter.onPlayerJoin(player); - playerNameCache.remove(player.getUniqueID()); } - + public void onPlayerLeave(EntityPlayerMP player) { multimeter.onPlayerLeave(player); - connectedPlayers.remove(player.getUniqueID()); - playerNameCache.put(player.getUniqueID(), player.getName()); } - - public void onHandshake(EntityPlayerMP player, String modVersion) { - if (connectedPlayers.put(player.getUniqueID(), modVersion) == null) { - HandshakePacket packet = new HandshakePacket(); - packetHandler.sendToPlayer(packet, player); - - refreshTickPhaseTree(player); - } - } - + public void refreshTickPhaseTree(EntityPlayerMP player) { if (tickPhaseTree.isComplete()) { TickPhaseTreePacket packet = new TickPhaseTreePacket(tickPhaseTree.toNbt()); - packetHandler.sendToPlayer(packet, player); + playerList.send(packet, player); } } - - public WorldServer getWorld(ResourceLocation dimensionId) { - DimensionType type = DimensionUtils.getType(dimensionId); - return server.getWorld(type.getId()); - } - - public WorldServer getWorldOf(DimPos pos) { - return getWorld(pos.getDimensionId()); - } - - public IBlockState getBlockState(DimPos pos) { - World world = getWorldOf(pos); - - if (world != null) { - return world.getBlockState(pos.getBlockPos()); + + public void rebuildTickPhaseTree(EntityPlayerMP player) { + if (tickPhaseTree.isComplete()) { + tickPhaseTree.reset(); } - - return null; } - - public PlayerList getPlayerManager() { - return server.getPlayerList(); + + public WorldServer[] getWorlds() { + return server.worlds; } - - public EntityPlayerMP getPlayer(UUID playerUUID) { - return server.getPlayerList().getPlayerByUUID(playerUUID); + + public WorldServer getWorld(String key) { + return server.getWorld(DimensionType.byName(key).getId()); + } + + public WorldServer getWorld(DimPos pos) { + return getWorld(pos.getDimension()); } - - public String getPlayerName(UUID playerUUID) { - EntityPlayerMP player = getPlayer(playerUUID); - return player == null ? playerNameCache.get(playerUUID) : player.getName(); + + public IBlockState getIBlockState(DimPos pos) { + World world = getWorld(pos); + + if (world == null) { + return null; + } + + return world.getBlockState(pos.getBlockPos()); } - - public EntityPlayerMP getPlayer(String playerName) { - return server.getPlayerList().getPlayerByUsername(playerName); + + public PlayerList getPlayerList() { + return playerList; } - - public boolean isMultimeterClient(UUID playerUUID) { - return connectedPlayers.containsKey(playerUUID); + + public boolean isMultimeterClient(UUID uuid) { + return playerList.has(uuid); } - + public boolean isMultimeterClient(EntityPlayerMP player) { - return connectedPlayers.containsKey(player.getUniqueID()); - } - - public Collection collectPlayers(Collection playerUUIDs) { - Set players = new LinkedHashSet<>(); - - for (UUID playerUUID : playerUUIDs) { - EntityPlayerMP player = getPlayer(playerUUID); - - if (player != null) { - players.add(player); - } - } - - return players; + return playerList.has(player.getUniqueID()); } - + public void sendMessage(EntityPlayerMP player, ITextComponent message, boolean actionBar) { player.sendStatusMessage(message, actionBar); } diff --git a/carpetmodSrc/redstone/multimeter/server/PlayerList.java b/carpetmodSrc/redstone/multimeter/server/PlayerList.java new file mode 100644 index 00000000..f32ba9c7 --- /dev/null +++ b/carpetmodSrc/redstone/multimeter/server/PlayerList.java @@ -0,0 +1,138 @@ +package redstone.multimeter.server; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import java.util.function.Predicate; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.network.Packet; +import net.minecraft.world.DimensionType; + +import redstone.multimeter.common.network.RSMMPacket; +import redstone.multimeter.server.meter.ServerMeterGroup; + +public class PlayerList { + + private final MultimeterServer server; + + private final Map playersByUuid; + private final Map playersByName; + private final Map nameCache; + + public PlayerList(MultimeterServer server) { + this.server = server; + + this.playersByUuid = new HashMap<>(); + this.playersByName = new HashMap<>(); + this.nameCache = new HashMap<>(); + } + + public MultimeterServer getServer() { + return server; + } + + public void tick() { + if (server.getTicks() % 72000 == 0) { + cleanNameCache(); + } + } + + private void cleanNameCache() { + Collection meterGroups = server.getMultimeter().getMeterGroups(); + + nameCache.keySet().removeIf(uuid -> { + for (ServerMeterGroup meterGroup : meterGroups) { + if (meterGroup.hasMember(uuid)) { + return false; + } + } + + return true; + }); + } + + public void add(EntityPlayerMP player) { + if (!has(player.getUniqueID())) { + playersByUuid.put(player.getUniqueID(), player); + playersByName.put(player.getName(), player); + nameCache.remove(player.getUniqueID()); + + server.onPlayerJoin(player); + } + } + + public void remove(EntityPlayerMP player) { + if (has(player.getUniqueID())) { + playersByUuid.remove(player.getUniqueID()); + playersByName.remove(player.getName()); + nameCache.put(player.getUniqueID(), player.getName()); + + server.onPlayerLeave(player); + } + } + + public void respawn(EntityPlayerMP player) { + if (has(player.getUniqueID())) { + playersByUuid.put(player.getUniqueID(), player); + playersByName.put(player.getName(), player); + } + } + + public Collection get() { + return playersByUuid.values(); + } + + public EntityPlayerMP get(UUID uuid) { + return playersByUuid.get(uuid); + } + + public EntityPlayerMP get(String name) { + return playersByName.get(name); + } + + public boolean has(UUID uuid) { + return playersByUuid.containsKey(uuid); + } + + public boolean has(String name) { + return playersByName.containsKey(name); + } + + public String getName(UUID uuid) { + EntityPlayerMP player = get(uuid); + return player == null ? nameCache.get(uuid) : player.getName(); + } + + public void send(RSMMPacket packet) { + send(packet, player -> true); + } + + public void send(RSMMPacket packet, ServerMeterGroup meterGroup) { + send(packet, player -> meterGroup.hasSubscriber(player)); + } + + public void send(RSMMPacket packet, DimensionType dimension) { + send(packet, player -> player.world.provider.getDimensionType() == dimension); + } + + public void send(RSMMPacket packet, Predicate predicate) { + Packet mcPacket = server.getPacketHandler().encode(packet); + + for (EntityPlayerMP player : playersByUuid.values()) { + if (predicate.test(player)) { + player.connection.sendPacket(mcPacket); + } + } + } + + public void send(RSMMPacket packet, EntityPlayerMP player) { + Packet mcPacket = server.getPacketHandler().encode(packet); + player.connection.sendPacket(mcPacket); + } + + public void updatePermissions(EntityPlayerMP player) { + server.getMinecraftServer().getPlayerList().updatePermissionLevel(player); + } +} diff --git a/carpetmodSrc/redstone/multimeter/server/ServerPacketHandler.java b/carpetmodSrc/redstone/multimeter/server/ServerPacketHandler.java index acdd4bca..ab809439 100644 --- a/carpetmodSrc/redstone/multimeter/server/ServerPacketHandler.java +++ b/carpetmodSrc/redstone/multimeter/server/ServerPacketHandler.java @@ -1,60 +1,28 @@ package redstone.multimeter.server; -import java.util.Collection; - -import carpet.CarpetSettings; - import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.network.Packet; import net.minecraft.network.PacketBuffer; import net.minecraft.network.play.server.SPacketCustomPayload; -import redstone.multimeter.common.network.AbstractPacketHandler; -import redstone.multimeter.common.network.RSMMPacket; -import redstone.multimeter.server.meter.ServerMeterGroup; +import redstone.multimeter.common.network.PacketHandler; + +public class ServerPacketHandler extends PacketHandler { -public class ServerPacketHandler extends AbstractPacketHandler { - private final MultimeterServer server; - + public ServerPacketHandler(MultimeterServer server) { this.server = server; } @Override - protected Packet toCustomPayload(String id, PacketBuffer buffer) { - return new SPacketCustomPayload(id, buffer); - } - - @Override - public

void send(P packet) { - Packet mcPacket = encode(packet); - server.getPlayerManager().sendPacketToAllPlayers(mcPacket); + protected Packet toCustomPayload(String channel, PacketBuffer data) { + return new SPacketCustomPayload(channel, data); } - - public

void sendToPlayer(P packet, EntityPlayerMP player) { - player.connection.sendPacket(encode(packet)); - } - - public

void sendToPlayers(P packet, Collection players) { - Packet mcPacket = encode(packet); - - for (EntityPlayerMP player : players) { - player.connection.sendPacket(mcPacket); - } - } - - public

void sendToSubscribers(P packet, ServerMeterGroup meterGroup) { - sendToPlayers(packet, server.collectPlayers(meterGroup.getSubscribers())); - } - - public void onPacketReceived(PacketBuffer buffer, EntityPlayerMP player) { + + public void handlePacket(PacketBuffer data, EntityPlayerMP player) { try { - RSMMPacket packet = decode(buffer); - - if (CarpetSettings.redstoneMultimeter || packet.force()) { - packet.execute(server, player); - } + decode(data).handle(server, player); } catch (Exception e) { e.printStackTrace(); } diff --git a/carpetmodSrc/redstone/multimeter/server/meter/ServerMeterGroup.java b/carpetmodSrc/redstone/multimeter/server/meter/ServerMeterGroup.java index dde9d738..1f5a85c6 100644 --- a/carpetmodSrc/redstone/multimeter/server/meter/ServerMeterGroup.java +++ b/carpetmodSrc/redstone/multimeter/server/meter/ServerMeterGroup.java @@ -5,13 +5,16 @@ import java.util.Collections; import java.util.HashSet; import java.util.LinkedHashMap; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; +import java.util.function.Supplier; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import redstone.multimeter.common.DimPos; @@ -19,259 +22,276 @@ import redstone.multimeter.common.meter.MeterGroup; import redstone.multimeter.common.meter.MeterProperties; import redstone.multimeter.common.meter.MeterProperties.MutableMeterProperties; +import redstone.multimeter.common.meter.event.EventType; import redstone.multimeter.common.meter.event.MeterEvent; import redstone.multimeter.common.network.packets.MeterUpdatesPacket; import redstone.multimeter.server.Multimeter; import redstone.multimeter.server.meter.event.MeterEventPredicate; -import redstone.multimeter.server.meter.event.MeterEventSupplier; import redstone.multimeter.server.meter.log.ServerLogManager; public class ServerMeterGroup extends MeterGroup { - + private final Multimeter multimeter; private final ServerLogManager logManager; - + private final UUID owner; private final Set members; private final Set subscribers; - + private final List removedMeters; private final Map meterUpdates; - + private boolean meterIndicesChanged; + private boolean isPrivate; private boolean idle; private long idleTime; - + public ServerMeterGroup(Multimeter multimeter, String name, EntityPlayerMP owner) { super(name); - + this.multimeter = multimeter; this.logManager = new ServerLogManager(this); - + this.owner = owner.getUniqueID(); this.members = new HashSet<>(); this.subscribers = new HashSet<>(); - + this.removedMeters = new ArrayList<>(); this.meterUpdates = new LinkedHashMap<>(); - + this.isPrivate = false; this.idle = true; this.idleTime = 0L; } - + @Override public void clear() { super.clear(); - + removedMeters.clear(); meterUpdates.clear(); } - + @Override protected void moveMeter(Meter meter, DimPos newPos) { if (hasMeterAt(newPos)) { return; } - - World world = multimeter.getMultimeterServer().getWorldOf(newPos); - + + World world = multimeter.getServer().getWorld(newPos); + if (world == null) { return; } - + super.moveMeter(meter, newPos); } - + @Override protected void meterAdded(Meter meter) { meterUpdates.putIfAbsent(meter.getId(), meter.getProperties()); } - + @Override protected void meterRemoved(Meter meter) { removedMeters.add(meter.getId()); meterUpdates.remove(meter.getId()); } - + @Override protected void meterUpdated(Meter meter) { meterUpdates.putIfAbsent(meter.getId(), meter.getProperties()); } - + + @Override + protected void indexChanged(Meter meter) { + meterIndicesChanged = true; + } + @Override public ServerLogManager getLogManager() { return logManager; } - + public Multimeter getMultimeter() { return multimeter; } - + public boolean addMeter(MutableMeterProperties properties) { return addMeter(new Meter(properties)); } - + public boolean removeMeter(long id) { return hasMeter(id) && removeMeter(getMeter(id)); } - + public boolean updateMeter(long id, MeterProperties newProperties) { return hasMeter(id) && updateMeter(getMeter(id), newProperties); } - + public void tryMoveMeter(DimPos pos, EnumFacing dir) { if (!hasMeterAt(pos)) { return; } - + Meter meter = getMeterAt(pos); - + if (!meter.isMovable()) { return; } - + moveMeter(meter, pos.offset(dir)); } - + + public boolean setMeterIndex(long id, int index) { + return hasMeter(id) && setIndex(getMeter(id), index); + } + public boolean isPastMeterLimit() { int limit = multimeter.options.meter_group.meter_limit; return limit >= 0 && getMeters().size() >= limit; } - + public UUID getOwner() { return owner; } - + public boolean isOwnedBy(EntityPlayerMP player) { return isOwnedBy(player.getUniqueID()); } - - public boolean isOwnedBy(UUID playerUUID) { - return owner.equals(playerUUID); + + public boolean isOwnedBy(UUID playerUuid) { + return owner.equals(playerUuid); } - + public boolean hasMembers() { return !members.isEmpty(); } - + public Collection getMembers() { return Collections.unmodifiableCollection(members); } - + public boolean hasMember(EntityPlayerMP player) { return hasMember(player.getUniqueID()); } - - public boolean hasMember(UUID playerUUID) { - return members.contains(playerUUID); + + public boolean hasMember(UUID playerUuid) { + return members.contains(playerUuid); } - - public void addMember(UUID playerUUID) { - members.add(playerUUID); + + public void addMember(UUID playerUuid) { + members.add(playerUuid); } - - public void removeMember(UUID playerUUID) { - members.remove(playerUUID); + + public void removeMember(UUID playerUuid) { + members.remove(playerUuid); } - + public void clearMembers() { members.clear(); } - + public boolean hasSubscribers() { return !subscribers.isEmpty(); } - + public Collection getSubscribers() { return Collections.unmodifiableCollection(subscribers); } - + public boolean hasSubscriber(EntityPlayerMP player) { return hasSubscriber(player.getUniqueID()); } - - public boolean hasSubscriber(UUID playerUUID) { - return subscribers.contains(playerUUID); + + public boolean hasSubscriber(UUID playerUuid) { + return subscribers.contains(playerUuid); } - - public void addSubscriber(UUID playerUUID) { - subscribers.add(playerUUID); + + public void addSubscriber(UUID playerUuid) { + subscribers.add(playerUuid); } - - public void removeSubscriber(UUID playerUUID) { - subscribers.remove(playerUUID); + + public void removeSubscriber(UUID playerUuid) { + subscribers.remove(playerUuid); } - + public boolean isPrivate() { return isPrivate; } - + public void setPrivate(boolean isPrivate) { this.isPrivate = isPrivate; - + if (isPrivate) { - for (UUID playerUUID : subscribers) { - if (playerUUID != owner) { - addMember(playerUUID); + for (UUID playerUuid : subscribers) { + if (playerUuid != owner) { + addMember(playerUuid); } } } } - + public boolean isIdle() { return idle; } - + public long getIdleTime() { return idleTime; } - + public boolean updateIdleState() { boolean wasIdle = idle; idle = !hasSubscribers(); - + if (wasIdle && !idle) { idleTime = 0L; } - + return wasIdle != idle; } - + public boolean isPastIdleTimeLimit() { return idle && multimeter.options.meter_group.max_idle_time >= 0 && idleTime > multimeter.options.meter_group.max_idle_time; } - + public void tick() { if (idle) { idleTime++; } - - logManager.tick(); } - - public void flushUpdates() { - if (removedMeters.isEmpty() && meterUpdates.isEmpty()) { + + public void broadcastUpdates() { + if (removedMeters.isEmpty() && meterUpdates.isEmpty() && !meterIndicesChanged) { return; } - - MeterUpdatesPacket packet = new MeterUpdatesPacket(removedMeters, meterUpdates); - multimeter.getMultimeterServer().getPacketHandler().sendToSubscribers(packet, this); - + + List meters = new LinkedList<>(); + + if (meterIndicesChanged) { + for (Meter meter : getMeters()) { + meters.add(meter.getId()); + } + } + + MeterUpdatesPacket packet = new MeterUpdatesPacket(removedMeters, meterUpdates, meters); + multimeter.getServer().getPlayerList().send(packet, this); + removedMeters.clear(); meterUpdates.clear(); + + meterIndicesChanged = false; } - - public void tryLogEvent(DimPos pos, MeterEventPredicate predicate, MeterEventSupplier supplier) { - if (hasMeterAt(pos)) { - Meter meter = getMeterAt(pos); - - if (meter.isMetering(supplier.type())) { - MeterEvent event = supplier.get(); - - if (predicate.test(this, meter, event)) { - logManager.logEvent(meter, supplier.get()); - } + + public void tryLogEvent(World world, BlockPos blockPos, EventType type, Supplier data, MeterEventPredicate predicate) { + DimPos pos = new DimPos(world, blockPos); + Meter meter = getMeterAt(pos); + + if (meter != null && meter.isMetering(type)) { + MeterEvent event = new MeterEvent(type, data.get()); + + if (predicate.test(this, meter, event)) { + logManager.logEvent(world, meter, event); } } } diff --git a/carpetmodSrc/redstone/multimeter/server/meter/ServerMeterPropertiesManager.java b/carpetmodSrc/redstone/multimeter/server/meter/ServerMeterPropertiesManager.java index e5d32cc2..863d73a1 100644 --- a/carpetmodSrc/redstone/multimeter/server/meter/ServerMeterPropertiesManager.java +++ b/carpetmodSrc/redstone/multimeter/server/meter/ServerMeterPropertiesManager.java @@ -4,35 +4,35 @@ import net.minecraft.world.World; import redstone.multimeter.common.DimPos; +import redstone.multimeter.common.meter.ColorPicker; import redstone.multimeter.common.meter.MeterProperties.MutableMeterProperties; import redstone.multimeter.common.meter.MeterPropertiesManager; import redstone.multimeter.common.meter.event.EventType; import redstone.multimeter.server.Multimeter; -import redstone.multimeter.util.ColorUtils; public class ServerMeterPropertiesManager extends MeterPropertiesManager { - + private final Multimeter multimeter; - + public ServerMeterPropertiesManager(Multimeter multimeter) { this.multimeter = multimeter; } - + @Override - protected World getWorldOf(DimPos pos) { - return multimeter.getMultimeterServer().getWorldOf(pos); + protected World getWorld(DimPos pos) { + return multimeter.getServer().getWorld(pos); } - + @Override protected void postValidation(MutableMeterProperties properties, World world, BlockPos pos) { // These are the backup values for if the saved defaults // do not fully populate the meter settings. - + if (properties.getName() == null) { properties.setName("Meter"); } if (properties.getColor() == null) { - properties.setColor(ColorUtils.nextColor()); + properties.setColor(ColorPicker.RANDOM.next()); } if (properties.getMovable() == null) { properties.setMovable(true); diff --git a/carpetmodSrc/redstone/multimeter/server/meter/log/ServerLogManager.java b/carpetmodSrc/redstone/multimeter/server/meter/log/ServerLogManager.java index 75db821a..8440b14d 100644 --- a/carpetmodSrc/redstone/multimeter/server/meter/log/ServerLogManager.java +++ b/carpetmodSrc/redstone/multimeter/server/meter/log/ServerLogManager.java @@ -1,7 +1,11 @@ package redstone.multimeter.server.meter.log; +import it.unimi.dsi.fastutil.longs.Long2IntLinkedOpenHashMap; +import it.unimi.dsi.fastutil.longs.Long2IntMap; + import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; +import net.minecraft.world.World; import redstone.multimeter.common.TickPhase; import redstone.multimeter.common.meter.Meter; @@ -12,79 +16,97 @@ import redstone.multimeter.server.meter.ServerMeterGroup; public class ServerLogManager extends LogManager { - + private final ServerMeterGroup meterGroup; - - private int nextSubtick; - + private final Long2IntMap subticks; + + private long cutoff; + private int unsentLogs; + public ServerLogManager(ServerMeterGroup meterGroup) { this.meterGroup = meterGroup; + this.subticks = new Long2IntLinkedOpenHashMap(); + + this.cutoff = -1L; } - + @Override protected ServerMeterGroup getMeterGroup() { return meterGroup; } - - @Override - protected long getLastTick() { - return meterGroup.getMultimeter().getMultimeterServer().getCurrentTick(); - } - + @Override public void clearLogs() { super.clearLogs(); - - nextSubtick = 0; + + subticks.clear(); + + cutoff = -1L; + unsentLogs = 0; } - + public void tick() { - nextSubtick = 0; + cutoff = Long.MAX_VALUE; + + for (World world : meterGroup.getMultimeter().getServer().getWorlds()) { + long gameTime = world.getWorldTime(); + + if (gameTime < cutoff) { + cutoff = gameTime; + } + } + + subticks.long2IntEntrySet().removeIf(e -> e.getLongKey() < cutoff); + } + + private int nextSubtick(long tick) { + return subticks.compute(tick, (key, value) -> { + return value == null ? 0 : ++value; + }); } - - public void logEvent(Meter meter, MeterEvent event) { - long tick = getLastTick(); - int subtick = nextSubtick++; - TickPhase phase = meterGroup.getMultimeter().getMultimeterServer().getTickPhase(); - - EventLog log = new EventLog(tick, subtick, phase, event); - meter.getLogs().add(log); + + public void logEvent(World world, Meter meter, MeterEvent event) { + long tick = world.getWorldTime(); + int subtick = nextSubtick(tick); + TickPhase phase = meterGroup.getMultimeter().getServer().getTickPhase(); + + meter.getLogs().add(new EventLog(tick, subtick, phase, event)); + + unsentLogs++; } - - public void flushLogs() { - if (nextSubtick == 0) { + + public void broadcastLogs() { + if (unsentLogs == 0) { return; } - + NBTTagList list = new NBTTagList(); - + for (Meter meter : meterGroup.getMeters()) { if (meter.getLogs().isEmpty()) { continue; } - + long id = meter.getId(); NBTTagCompound logs = meter.getLogs().toNbt(); - + NBTTagCompound nbt = new NBTTagCompound(); nbt.setLong("id", id); nbt.setTag("logs", logs); nbt.setBoolean("powered", meter.isPowered()); nbt.setBoolean("active", meter.isActive()); list.appendTag(nbt); - + meter.getLogs().clear(); } - + if (list.isEmpty()) { return; } - - NBTTagCompound nbt = new NBTTagCompound(); - nbt.setInteger("subticks", nextSubtick); - nbt.setTag("logs", list); - - MeterLogsPacket packet = new MeterLogsPacket(nbt); - meterGroup.getMultimeter().getMultimeterServer().getPacketHandler().sendToSubscribers(packet, meterGroup); + + MeterLogsPacket packet = new MeterLogsPacket(list); + meterGroup.getMultimeter().getServer().getPlayerList().send(packet, meterGroup); + + unsentLogs = 0; } } diff --git a/carpetmodSrc/redstone/multimeter/server/option/Options.java b/carpetmodSrc/redstone/multimeter/server/option/Options.java index 3836e923..d07bf08e 100644 --- a/carpetmodSrc/redstone/multimeter/server/option/Options.java +++ b/carpetmodSrc/redstone/multimeter/server/option/Options.java @@ -3,34 +3,34 @@ import redstone.multimeter.common.meter.event.EventType; public class Options { - + public Meter meter = new Meter(); public MeterGroup meter_group = new MeterGroup(); public EventTypes event_types = new EventTypes(); - + public class Meter { - + public boolean allow_teleports = true; - + } - + public class MeterGroup { - - public int meter_limit = -1; + + public int meter_limit = -1; public int max_idle_time = 72000; - + } - + public class EventTypes { - + public String allowed = "all"; // "all", "blacklist", "whitelist" public String[] blacklist = { }; public String[] whitelist = { }; - + } - + protected transient int enabledEventTypes = ~0; - + public boolean hasEventType(EventType type) { return (enabledEventTypes & type.flag()) != 0; } diff --git a/carpetmodSrc/redstone/multimeter/server/option/OptionsManager.java b/carpetmodSrc/redstone/multimeter/server/option/OptionsManager.java index d0af16e5..2bab7b78 100644 --- a/carpetmodSrc/redstone/multimeter/server/option/OptionsManager.java +++ b/carpetmodSrc/redstone/multimeter/server/option/OptionsManager.java @@ -11,15 +11,15 @@ import redstone.multimeter.common.meter.event.EventType; public class OptionsManager { - + private static final String FILE_NAME = "options.json"; private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); - - public static Options load(File folder) { - File file = new File(folder, FILE_NAME); + + public static Options load(File dir) { + File file = new File(dir, FILE_NAME); return validate(file.exists() ? read(file) : write(file)); } - + private static Options read(File file) { try (FileReader fr = new FileReader(file)) { return GSON.fromJson(fr, Options.class); @@ -27,45 +27,49 @@ private static Options read(File file) { return new Options(); } } - + private static Options write(File file) { Options options = new Options(); - + try (FileWriter fw = new FileWriter(file)) { fw.write(GSON.toJson(options)); } catch (IOException e) { - + } - + return options; } - + private static Options validate(Options options) { switch (options.event_types.allowed) { + case "all": + break; case "blacklist": for (String name : options.event_types.blacklist) { - EventType type = EventType.fromName(name); - + EventType type = EventType.byName(name); + if (type != null) { options.enabledEventTypes &= ~type.flag(); } } - + break; case "whitelist": options.enabledEventTypes = 0; - + for (String name : options.event_types.whitelist) { - EventType type = EventType.fromName(name); - + EventType type = EventType.byName(name); + if (type != null) { options.enabledEventTypes |= type.flag(); } } - + break; + default: + throw new IllegalStateException("unknown event types filter " + options.event_types.allowed); } - + return options; } } diff --git a/carpetmodSrc/redstone/multimeter/util/AxisUtils.java b/carpetmodSrc/redstone/multimeter/util/AxisUtils.java index 79460677..322a73ac 100644 --- a/carpetmodSrc/redstone/multimeter/util/AxisUtils.java +++ b/carpetmodSrc/redstone/multimeter/util/AxisUtils.java @@ -3,8 +3,8 @@ import net.minecraft.util.EnumFacing.Axis; public class AxisUtils { - - public static final int choose(Axis axis, int x, int y, int z) { + + public static int choose(Axis axis, int x, int y, int z) { switch (axis) { case X: return x; @@ -13,7 +13,7 @@ public static final int choose(Axis axis, int x, int y, int z) { case Z: return z; } - + return 0; } } diff --git a/carpetmodSrc/redstone/multimeter/util/ColorUtils.java b/carpetmodSrc/redstone/multimeter/util/ColorUtils.java index 5179eeb2..2afa7935 100644 --- a/carpetmodSrc/redstone/multimeter/util/ColorUtils.java +++ b/carpetmodSrc/redstone/multimeter/util/ColorUtils.java @@ -1,118 +1,100 @@ package redstone.multimeter.util; -import java.awt.Color; - public class ColorUtils { - - private static int colorIndex = 0; - - public static int nextColor() { - return nextColor(true); - } - - public static int nextColor(boolean cycleIndex) { - float hue = ((colorIndex * 11) % 8 + (colorIndex / 8) / 2.0F) / 8.0F; - - if (cycleIndex) { - colorIndex = (colorIndex + 1) % 16; - } - - return 0xFFFFFF & Color.HSBtoRGB(hue, 0.7F, 1.0F); - } - + public static int getAlpha(int argb) { return (argb >> 24) & 0xFF; } - + public static int getRed(int argb) { return (argb >> 16) & 0xFF; } - + public static int getGreen(int argb) { return (argb >> 8) & 0xFF; } - + public static int getBlue(int argb) { return argb & 0xFF; } - + public static int fromAlpha(int alpha) { return (alpha & 0xFF) << 24; } - + public static int fromRed(int red) { return (red & 0xFF) << 16; } - + public static int fromGreen(int green) { return (green & 0xFF) << 8; } - + public static int fromBlue(int blue) { return blue & 0xFF; } - + public static int setAlpha(int color, int alpha) { return color & (~(0xFF << 24)) | (alpha << 24); } - + public static int setRed(int color, int red) { return color & (~(0xFF << 16)) | (red << 16); } - + public static int setGreen(int color, int green) { return color & (~(0xFF << 8)) | (green << 8); } - + public static int setBlue(int color, int blue) { return color & ~0xFF | blue; } - + public static int fromRGB(int red, int green, int blue) { return fromRed(red) | fromGreen(green) | fromBlue(blue); } - + public static int fromARGB(int alpha, int red, int green, int blue) { return fromARGB(alpha, fromRGB(red, green, blue)); } - + public static int fromARGB(int alpha, int rgb) { return fromAlpha(alpha) | rgb; } - + public static int fromRGBString(String string) { if (string.length() > 6) { throw new NumberFormatException("Too many characters!"); } - + return Integer.valueOf(string, 16); } - + public static int fromARGBString(String string) { if (string.length() > 8) { throw new NumberFormatException("Too many characters!"); } - + return Integer.valueOf(string, 16); } - + public static String toRGBString(int color) { String hex = Integer.toHexString(color & 0xFFFFFF); - + while (hex.length() < 6) { hex = "0" + hex; } - + return hex.toUpperCase(); } - + public static String toARGBString(int color) { String hex = Integer.toHexString(color & 0xFFFFFFFF); - + while (hex.length() < 8) { hex = "0" + hex; } - + return hex.toUpperCase(); } } diff --git a/carpetmodSrc/redstone/multimeter/util/DimensionUtils.java b/carpetmodSrc/redstone/multimeter/util/DimensionUtils.java deleted file mode 100644 index a4256fe3..00000000 --- a/carpetmodSrc/redstone/multimeter/util/DimensionUtils.java +++ /dev/null @@ -1,40 +0,0 @@ -package redstone.multimeter.util; - -import java.util.HashMap; -import java.util.Map; - -import net.minecraft.util.ResourceLocation; -import net.minecraft.world.DimensionType; - -public class DimensionUtils { - - private static final Map ID_TO_TYPE; - private static final Map TYPE_TO_ID; - - private static void register(ResourceLocation id, DimensionType type) { - ID_TO_TYPE.put(id, type); - TYPE_TO_ID.put(type, id); - } - - private static void register(String name, DimensionType type) { - register(new ResourceLocation(name), type); - } - - public static DimensionType getType(ResourceLocation id) { - return ID_TO_TYPE.get(id); - } - - public static ResourceLocation getId(DimensionType type) { - return TYPE_TO_ID.get(type); - } - - static { - - ID_TO_TYPE = new HashMap<>(); - TYPE_TO_ID = new HashMap<>(); - - for (DimensionType type : DimensionType.values()) { - register(type.getName(), type); - } - } -} diff --git a/carpetmodSrc/redstone/multimeter/util/ListUtils.java b/carpetmodSrc/redstone/multimeter/util/ListUtils.java index df974492..8639ec59 100644 --- a/carpetmodSrc/redstone/multimeter/util/ListUtils.java +++ b/carpetmodSrc/redstone/multimeter/util/ListUtils.java @@ -1,29 +1,29 @@ package redstone.multimeter.util; import java.util.List; -import java.util.function.Function; +import java.util.function.Predicate; public class ListUtils { - - public static int binarySearch(List list, Function tooLow) { + + public static int binarySearch(List list, Predicate tooLow) { return binarySearch(list, 0, list.size() - 1, tooLow); } - - public static int binarySearch(List list, int low, int high, Function tooLow) { + + public static int binarySearch(List list, int low, int high, Predicate tooLow) { if (list.isEmpty()) { return -1; } - + while (high > low) { int mid = (low + high) / 2; - - if (tooLow.apply(list.get(mid))) { + + if (tooLow.test(list.get(mid))) { low = mid + 1; } else { high = mid; } } - + return low; } } diff --git a/carpetmodSrc/redstone/multimeter/util/NbtUtils.java b/carpetmodSrc/redstone/multimeter/util/NbtUtils.java index 92ff0117..1dec17b4 100644 --- a/carpetmodSrc/redstone/multimeter/util/NbtUtils.java +++ b/carpetmodSrc/redstone/multimeter/util/NbtUtils.java @@ -2,11 +2,9 @@ import net.minecraft.nbt.NBTBase; import net.minecraft.nbt.NBTTagByte; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.ResourceLocation; public class NbtUtils { - + public static final byte TYPE_NULL = 0; public static final byte TYPE_BYTE = 1; public static final byte TYPE_SHORT = 2; @@ -20,22 +18,7 @@ public class NbtUtils { public static final byte TYPE_COMPOUND = 10; public static final byte TYPE_INT_ARRAY = 11; public static final byte TYPE_LONG_ARRAY = 12; - + public static final NBTBase NULL = new NBTTagByte((byte)0); - - public static NBTTagCompound identifierToNbt(ResourceLocation id) { - NBTTagCompound nbt = new NBTTagCompound(); - - nbt.setString("namespace", id.getNamespace()); - nbt.setString("path", id.getPath()); - - return nbt; - } - - public static ResourceLocation nbtToIdentifier(NBTTagCompound nbt) { - String namespace = nbt.getString("namespace"); - String path = nbt.getString("path"); - - return new ResourceLocation(namespace, path); - } + } diff --git a/carpetmodSrc/redstone/multimeter/util/TextUtils.java b/carpetmodSrc/redstone/multimeter/util/TextUtils.java deleted file mode 100644 index 4eb80585..00000000 --- a/carpetmodSrc/redstone/multimeter/util/TextUtils.java +++ /dev/null @@ -1,25 +0,0 @@ -package redstone.multimeter.util; - -import java.util.List; - -import net.minecraft.util.text.ITextComponent; -import net.minecraft.util.text.Style; -import net.minecraft.util.text.TextComponentString; -import net.minecraft.util.text.TextFormatting; - -public class TextUtils { - - public static void addFancyText(List lines, String title, Object info) { - addFancyText(lines, title, info.toString()); - } - - public static void addFancyText(List lines, String title, String info) { - lines.add(formatFancyText(title, info)); - } - - public static ITextComponent formatFancyText(String title, Object info) { - return new TextComponentString(""). - appendSibling(new TextComponentString(title + ": ").setStyle(new Style().setColor(TextFormatting.GOLD))). - appendSibling(new TextComponentString(info.toString())); - } -} diff --git a/jsons/1.12.2.json b/jsons/1.12.2.json index ce7b3798..fd4c093a 100644 --- a/jsons/1.12.2.json +++ b/jsons/1.12.2.json @@ -1 +1 @@ -{"assetIndex": {"id": "1.12", "sha1": "1584b57c1a0b5e593fad1f5b8f78536ca640547b", "size": 143138, "totalSize": 129336389, "url": "https://launchermeta.mojang.com/v1/packages/1584b57c1a0b5e593fad1f5b8f78536ca640547b/1.12.json"}, "assets": "1.12", "complianceLevel": 0, "downloads": {"client": {"sha1": "0f275bc1547d01fa5f56ba34bdc87d981ee12daf", "size": 10180113, "url": "https://launcher.mojang.com/v1/objects/0f275bc1547d01fa5f56ba34bdc87d981ee12daf/client.jar"}, "server": {"sha1": "886945bfb2b978778c3a0288fd7fab09d315b25f", "size": 30222121, "url": "https://launcher.mojang.com/v1/objects/886945bfb2b978778c3a0288fd7fab09d315b25f/server.jar"}}, "id": "1.12.2", "javaVersion": {"component": "jre-legacy", "majorVersion": 8}, "libraries": [{"downloads": {"artifact": {"path": "com/mojang/patchy/1.3.9/patchy-1.3.9.jar", "sha1": "eb8bb7b66fa0e2152b1b40b3856e82f7619439ee", "size": 23581, "url": "https://libraries.minecraft.net/com/mojang/patchy/1.3.9/patchy-1.3.9.jar"}}, "name": "com.mojang:patchy:1.3.9"}, {"downloads": {"artifact": {"path": "oshi-project/oshi-core/1.1/oshi-core-1.1.jar", "sha1": "9ddf7b048a8d701be231c0f4f95fd986198fd2d8", "size": 30973, "url": "https://libraries.minecraft.net/oshi-project/oshi-core/1.1/oshi-core-1.1.jar"}}, "name": "oshi-project:oshi-core:1.1"}, {"downloads": {"artifact": {"path": "net/java/dev/jna/jna/4.4.0/jna-4.4.0.jar", "sha1": "cb208278274bf12ebdb56c61bd7407e6f774d65a", "size": 1091208, "url": "https://libraries.minecraft.net/net/java/dev/jna/jna/4.4.0/jna-4.4.0.jar"}}, "name": "net.java.dev.jna:jna:4.4.0"}, {"downloads": {"artifact": {"path": "net/java/dev/jna/platform/3.4.0/platform-3.4.0.jar", "sha1": "e3f70017be8100d3d6923f50b3d2ee17714e9c13", "size": 913436, "url": "https://libraries.minecraft.net/net/java/dev/jna/platform/3.4.0/platform-3.4.0.jar"}}, "name": "net.java.dev.jna:platform:3.4.0"}, {"downloads": {"artifact": {"path": "com/ibm/icu/icu4j-core-mojang/51.2/icu4j-core-mojang-51.2.jar", "sha1": "63d216a9311cca6be337c1e458e587f99d382b84", "size": 1634692, "url": "https://libraries.minecraft.net/com/ibm/icu/icu4j-core-mojang/51.2/icu4j-core-mojang-51.2.jar"}}, "name": "com.ibm.icu:icu4j-core-mojang:51.2"}, {"downloads": {"artifact": {"path": "net/sf/jopt-simple/jopt-simple/5.0.3/jopt-simple-5.0.3.jar", "sha1": "cdd846cfc4e0f7eefafc02c0f5dce32b9303aa2a", "size": 78175, "url": "https://libraries.minecraft.net/net/sf/jopt-simple/jopt-simple/5.0.3/jopt-simple-5.0.3.jar"}}, "name": "net.sf.jopt-simple:jopt-simple:5.0.3"}, {"downloads": {"artifact": {"path": "com/paulscode/codecjorbis/20101023/codecjorbis-20101023.jar", "sha1": "c73b5636faf089d9f00e8732a829577de25237ee", "size": 103871, "url": "https://libraries.minecraft.net/com/paulscode/codecjorbis/20101023/codecjorbis-20101023.jar"}}, "name": "com.paulscode:codecjorbis:20101023"}, {"downloads": {"artifact": {"path": "com/paulscode/codecwav/20101023/codecwav-20101023.jar", "sha1": "12f031cfe88fef5c1dd36c563c0a3a69bd7261da", "size": 5618, "url": "https://libraries.minecraft.net/com/paulscode/codecwav/20101023/codecwav-20101023.jar"}}, "name": "com.paulscode:codecwav:20101023"}, {"downloads": {"artifact": {"path": "com/paulscode/libraryjavasound/20101123/libraryjavasound-20101123.jar", "sha1": "5c5e304366f75f9eaa2e8cca546a1fb6109348b3", "size": 21679, "url": "https://libraries.minecraft.net/com/paulscode/libraryjavasound/20101123/libraryjavasound-20101123.jar"}}, "name": "com.paulscode:libraryjavasound:20101123"}, {"downloads": {"artifact": {"path": "com/paulscode/librarylwjglopenal/20100824/librarylwjglopenal-20100824.jar", "sha1": "73e80d0794c39665aec3f62eee88ca91676674ef", "size": 18981, "url": "https://libraries.minecraft.net/com/paulscode/librarylwjglopenal/20100824/librarylwjglopenal-20100824.jar"}}, "name": "com.paulscode:librarylwjglopenal:20100824"}, {"downloads": {"artifact": {"path": "com/paulscode/soundsystem/20120107/soundsystem-20120107.jar", "sha1": "419c05fe9be71f792b2d76cfc9b67f1ed0fec7f6", "size": 65020, "url": "https://libraries.minecraft.net/com/paulscode/soundsystem/20120107/soundsystem-20120107.jar"}}, "name": "com.paulscode:soundsystem:20120107"}, {"downloads": {"artifact": {"path": "io/netty/netty-all/4.1.9.Final/netty-all-4.1.9.Final.jar", "sha1": "0097860965d6a0a6b98e7f569f3f966727b8db75", "size": 3511093, "url": "https://libraries.minecraft.net/io/netty/netty-all/4.1.9.Final/netty-all-4.1.9.Final.jar"}}, "name": "io.netty:netty-all:4.1.9.Final"}, {"downloads": {"artifact": {"path": "com/google/guava/guava/21.0/guava-21.0.jar", "sha1": "3a3d111be1be1b745edfa7d91678a12d7ed38709", "size": 2521113, "url": "https://libraries.minecraft.net/com/google/guava/guava/21.0/guava-21.0.jar"}}, "name": "com.google.guava:guava:21.0"}, {"downloads": {"artifact": {"path": "org/apache/commons/commons-lang3/3.5/commons-lang3-3.5.jar", "sha1": "6c6c702c89bfff3cd9e80b04d668c5e190d588c6", "size": 479881, "url": "https://libraries.minecraft.net/org/apache/commons/commons-lang3/3.5/commons-lang3-3.5.jar"}}, "name": "org.apache.commons:commons-lang3:3.5"}, {"downloads": {"artifact": {"path": "commons-io/commons-io/2.5/commons-io-2.5.jar", "sha1": "2852e6e05fbb95076fc091f6d1780f1f8fe35e0f", "size": 208700, "url": "https://libraries.minecraft.net/commons-io/commons-io/2.5/commons-io-2.5.jar"}}, "name": "commons-io:commons-io:2.5"}, {"downloads": {"artifact": {"path": "commons-codec/commons-codec/1.10/commons-codec-1.10.jar", "sha1": "4b95f4897fa13f2cd904aee711aeafc0c5295cd8", "size": 284184, "url": "https://libraries.minecraft.net/commons-codec/commons-codec/1.10/commons-codec-1.10.jar"}}, "name": "commons-codec:commons-codec:1.10"}, {"downloads": {"artifact": {"path": "net/java/jinput/jinput/2.0.5/jinput-2.0.5.jar", "sha1": "39c7796b469a600f72380316f6b1f11db6c2c7c4", "size": 208338, "url": "https://libraries.minecraft.net/net/java/jinput/jinput/2.0.5/jinput-2.0.5.jar"}}, "name": "net.java.jinput:jinput:2.0.5"}, {"downloads": {"artifact": {"path": "net/java/jutils/jutils/1.0.0/jutils-1.0.0.jar", "sha1": "e12fe1fda814bd348c1579329c86943d2cd3c6a6", "size": 7508, "url": "https://libraries.minecraft.net/net/java/jutils/jutils/1.0.0/jutils-1.0.0.jar"}}, "name": "net.java.jutils:jutils:1.0.0"}, {"downloads": {"artifact": {"path": "com/google/code/gson/gson/2.8.0/gson-2.8.0.jar", "sha1": "c4ba5371a29ac9b2ad6129b1d39ea38750043eff", "size": 231952, "url": "https://libraries.minecraft.net/com/google/code/gson/gson/2.8.0/gson-2.8.0.jar"}}, "name": "com.google.code.gson:gson:2.8.0"}, {"downloads": {"artifact": {"path": "com/mojang/authlib/1.5.25/authlib-1.5.25.jar", "sha1": "9834cdf236c22e84b946bba989e2f94ef5897c3c", "size": 65621, "url": "https://libraries.minecraft.net/com/mojang/authlib/1.5.25/authlib-1.5.25.jar"}}, "name": "com.mojang:authlib:1.5.25"}, {"downloads": {"artifact": {"path": "com/mojang/realms/1.10.22/realms-1.10.22.jar", "sha1": "bd0dccebdf3744c75f1ca20063f16e8f7d5e663f", "size": 7135057, "url": "https://libraries.minecraft.net/com/mojang/realms/1.10.22/realms-1.10.22.jar"}}, "name": "com.mojang:realms:1.10.22"}, {"downloads": {"artifact": {"path": "org/apache/commons/commons-compress/1.8.1/commons-compress-1.8.1.jar", "sha1": "a698750c16740fd5b3871425f4cb3bbaa87f529d", "size": 365552, "url": "https://libraries.minecraft.net/org/apache/commons/commons-compress/1.8.1/commons-compress-1.8.1.jar"}}, "name": "org.apache.commons:commons-compress:1.8.1"}, {"downloads": {"artifact": {"path": "org/apache/httpcomponents/httpclient/4.3.3/httpclient-4.3.3.jar", "sha1": "18f4247ff4572a074444572cee34647c43e7c9c7", "size": 589512, "url": "https://libraries.minecraft.net/org/apache/httpcomponents/httpclient/4.3.3/httpclient-4.3.3.jar"}}, "name": "org.apache.httpcomponents:httpclient:4.3.3"}, {"downloads": {"artifact": {"path": "commons-logging/commons-logging/1.1.3/commons-logging-1.1.3.jar", "sha1": "f6f66e966c70a83ffbdb6f17a0919eaf7c8aca7f", "size": 62050, "url": "https://libraries.minecraft.net/commons-logging/commons-logging/1.1.3/commons-logging-1.1.3.jar"}}, "name": "commons-logging:commons-logging:1.1.3"}, {"downloads": {"artifact": {"path": "org/apache/httpcomponents/httpcore/4.3.2/httpcore-4.3.2.jar", "sha1": "31fbbff1ddbf98f3aa7377c94d33b0447c646b6e", "size": 282269, "url": "https://libraries.minecraft.net/org/apache/httpcomponents/httpcore/4.3.2/httpcore-4.3.2.jar"}}, "name": "org.apache.httpcomponents:httpcore:4.3.2"}, {"downloads": {"artifact": {"path": "it/unimi/dsi/fastutil/7.1.0/fastutil-7.1.0.jar", "sha1": "9835253257524c1be7ab50c057aa2d418fb72082", "size": 17655579, "url": "https://libraries.minecraft.net/it/unimi/dsi/fastutil/7.1.0/fastutil-7.1.0.jar"}}, "name": "it.unimi.dsi:fastutil:7.1.0"}, {"downloads": {"artifact": {"path": "org/apache/logging/log4j/log4j-api/2.8.1/log4j-api-2.8.1.jar", "sha1": "e801d13612e22cad62a3f4f3fe7fdbe6334a8e72", "size": 228859, "url": "https://libraries.minecraft.net/org/apache/logging/log4j/log4j-api/2.8.1/log4j-api-2.8.1.jar"}}, "name": "org.apache.logging.log4j:log4j-api:2.8.1"}, {"downloads": {"artifact": {"path": "org/apache/logging/log4j/log4j-core/2.8.1/log4j-core-2.8.1.jar", "sha1": "4ac28ff2f1ddf05dae3043a190451e8c46b73c31", "size": 1402925, "url": "https://libraries.minecraft.net/org/apache/logging/log4j/log4j-core/2.8.1/log4j-core-2.8.1.jar"}}, "name": "org.apache.logging.log4j:log4j-core:2.8.1"}, {"downloads": {"artifact": {"path": "org/lwjgl/lwjgl/lwjgl/2.9.4-nightly-20150209/lwjgl-2.9.4-nightly-20150209.jar", "sha1": "697517568c68e78ae0b4544145af031c81082dfe", "size": 1047168, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl/2.9.4-nightly-20150209/lwjgl-2.9.4-nightly-20150209.jar"}}, "name": "org.lwjgl.lwjgl:lwjgl:2.9.4-nightly-20150209", "rules": [{"action": "allow"}, {"action": "disallow", "os": {"name": "osx"}}]}, {"downloads": {"artifact": {"path": "org/lwjgl/lwjgl/lwjgl_util/2.9.4-nightly-20150209/lwjgl_util-2.9.4-nightly-20150209.jar", "sha1": "d51a7c040a721d13efdfbd34f8b257b2df882ad0", "size": 173887, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl_util/2.9.4-nightly-20150209/lwjgl_util-2.9.4-nightly-20150209.jar"}}, "name": "org.lwjgl.lwjgl:lwjgl_util:2.9.4-nightly-20150209", "rules": [{"action": "allow"}, {"action": "disallow", "os": {"name": "osx"}}]}, {"downloads": {"artifact": {"path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209.jar", "sha1": "b04f3ee8f5e43fa3b162981b50bb72fe1acabb33", "size": 22, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209.jar"}, "classifiers": {"natives-linux": {"path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-linux.jar", "sha1": "931074f46c795d2f7b30ed6395df5715cfd7675b", "size": 578680, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-linux.jar"}, "natives-osx": {"path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar", "sha1": "bcab850f8f487c3f4c4dbabde778bb82bd1a40ed", "size": 426822, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar"}, "natives-windows": {"path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-windows.jar", "sha1": "b84d5102b9dbfabfeb5e43c7e2828d98a7fc80e0", "size": 613748, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-windows.jar"}}}, "extract": {"exclude": ["META-INF/"]}, "name": "org.lwjgl.lwjgl:lwjgl-platform:2.9.4-nightly-20150209", "natives": {"linux": "natives-linux", "osx": "natives-osx", "windows": "natives-windows"}, "rules": [{"action": "allow"}, {"action": "disallow", "os": {"name": "osx"}}]}, {"downloads": {"artifact": {"path": "org/lwjgl/lwjgl/lwjgl/2.9.2-nightly-20140822/lwjgl-2.9.2-nightly-20140822.jar", "sha1": "7707204c9ffa5d91662de95f0a224e2f721b22af", "size": 1045632, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl/2.9.2-nightly-20140822/lwjgl-2.9.2-nightly-20140822.jar"}}, "name": "org.lwjgl.lwjgl:lwjgl:2.9.2-nightly-20140822", "rules": [{"action": "allow", "os": {"name": "osx"}}]}, {"downloads": {"artifact": {"path": "org/lwjgl/lwjgl/lwjgl_util/2.9.2-nightly-20140822/lwjgl_util-2.9.2-nightly-20140822.jar", "sha1": "f0e612c840a7639c1f77f68d72a28dae2f0c8490", "size": 173887, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl_util/2.9.2-nightly-20140822/lwjgl_util-2.9.2-nightly-20140822.jar"}}, "name": "org.lwjgl.lwjgl:lwjgl_util:2.9.2-nightly-20140822", "rules": [{"action": "allow", "os": {"name": "osx"}}]}, {"downloads": {"classifiers": {"natives-linux": {"path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.2-nightly-20140822/lwjgl-platform-2.9.2-nightly-20140822-natives-linux.jar", "sha1": "d898a33b5d0a6ef3fed3a4ead506566dce6720a5", "size": 578539, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.2-nightly-20140822/lwjgl-platform-2.9.2-nightly-20140822-natives-linux.jar"}, "natives-osx": {"path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.2-nightly-20140822/lwjgl-platform-2.9.2-nightly-20140822-natives-osx.jar", "sha1": "79f5ce2fea02e77fe47a3c745219167a542121d7", "size": 468116, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.2-nightly-20140822/lwjgl-platform-2.9.2-nightly-20140822-natives-osx.jar"}, "natives-windows": {"path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.2-nightly-20140822/lwjgl-platform-2.9.2-nightly-20140822-natives-windows.jar", "sha1": "78b2a55ce4dc29c6b3ec4df8ca165eba05f9b341", "size": 613680, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.2-nightly-20140822/lwjgl-platform-2.9.2-nightly-20140822-natives-windows.jar"}}}, "extract": {"exclude": ["META-INF/"]}, "name": "org.lwjgl.lwjgl:lwjgl-platform:2.9.2-nightly-20140822", "natives": {"linux": "natives-linux", "osx": "natives-osx", "windows": "natives-windows"}, "rules": [{"action": "allow", "os": {"name": "osx"}}]}, {"downloads": {"classifiers": {"natives-linux": {"path": "net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-linux.jar", "sha1": "7ff832a6eb9ab6a767f1ade2b548092d0fa64795", "size": 10362, "url": "https://libraries.minecraft.net/net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-linux.jar"}, "natives-osx": {"path": "net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-osx.jar", "sha1": "53f9c919f34d2ca9de8c51fc4e1e8282029a9232", "size": 12186, "url": "https://libraries.minecraft.net/net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-osx.jar"}, "natives-windows": {"path": "net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-windows.jar", "sha1": "385ee093e01f587f30ee1c8a2ee7d408fd732e16", "size": 155179, "url": "https://libraries.minecraft.net/net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-windows.jar"}}}, "extract": {"exclude": ["META-INF/"]}, "name": "net.java.jinput:jinput-platform:2.0.5", "natives": {"linux": "natives-linux", "osx": "natives-osx", "windows": "natives-windows"}}, {"downloads": {"artifact": {"path": "com/mojang/text2speech/1.10.3/text2speech-1.10.3.jar", "sha1": "48fd510879dff266c3815947de66e3d4809f8668", "size": 11055, "url": "https://libraries.minecraft.net/com/mojang/text2speech/1.10.3/text2speech-1.10.3.jar"}}, "name": "com.mojang:text2speech:1.10.3"}, {"downloads": {"artifact": {"path": "com/mojang/text2speech/1.10.3/text2speech-1.10.3.jar", "sha1": "48fd510879dff266c3815947de66e3d4809f8668", "size": 11055, "url": "https://libraries.minecraft.net/com/mojang/text2speech/1.10.3/text2speech-1.10.3.jar"}, "classifiers": {"natives-linux": {"path": "com/mojang/text2speech/1.10.3/text2speech-1.10.3-natives-linux.jar", "sha1": "ab7896aec3b3dd272b06194357f2d98f832c0cfc", "size": 7833, "url": "https://libraries.minecraft.net/com/mojang/text2speech/1.10.3/text2speech-1.10.3-natives-linux.jar"}, "natives-windows": {"path": "com/mojang/text2speech/1.10.3/text2speech-1.10.3-natives-windows.jar", "sha1": "84a4b856389cc4f485275b1f63497a95a857a443", "size": 81217, "url": "https://libraries.minecraft.net/com/mojang/text2speech/1.10.3/text2speech-1.10.3-natives-windows.jar"}, "sources": {"path": "com/mojang/text2speech/1.10.3/text2speech-1.10.3-sources.jar", "sha1": "404339fe43d1011ee046a249b0ec7ae9ce04a834", "size": 4632, "url": "https://libraries.minecraft.net/com/mojang/text2speech/1.10.3/text2speech-1.10.3-sources.jar"}}}, "extract": {"exclude": ["META-INF/"]}, "name": "com.mojang:text2speech:1.10.3", "natives": {"linux": "natives-linux", "windows": "natives-windows"}}, {"downloads": {"artifact": {"path": "ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0.jar", "sha1": "6ef160c3133a78de015830860197602ca1c855d3", "size": 40502, "url": "https://libraries.minecraft.net/ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0.jar"}, "classifiers": {"javadoc": {"path": "ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0-javadoc.jar", "sha1": "fb0092f22cb4fe8e631452f577b7a238778abf2a", "size": 174060, "url": "https://libraries.minecraft.net/ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0-javadoc.jar"}, "natives-osx": {"path": "ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0-natives-osx.jar", "sha1": "08befab4894d55875f33c3d300f4f71e6e828f64", "size": 5629, "url": "https://libraries.minecraft.net/ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0-natives-osx.jar"}, "sources": {"path": "ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0-sources.jar", "sha1": "865837a198189aee737019561ece842827f24278", "size": 43283, "url": "https://libraries.minecraft.net/ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0-sources.jar"}}}, "extract": {"exclude": ["META-INF/"]}, "name": "ca.weblite:java-objc-bridge:1.0.0", "natives": {"osx": "natives-osx"}, "rules": [{"action": "allow", "os": {"name": "osx"}}]}, {"downloads": {"artifact": {"path": "ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0.jar", "sha1": "6ef160c3133a78de015830860197602ca1c855d3", "size": 40502, "url": "https://libraries.minecraft.net/ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0.jar"}}, "name": "ca.weblite:java-objc-bridge:1.0.0", "rules": [{"action": "allow", "os": {"name": "osx"}}]}], "logging": {"client": {"argument": "-Dlog4j.configurationFile=${path}", "file": {"id": "client-1.12.xml", "sha1": "bd65e7d2e3c237be76cfbef4c2405033d7f91521", "size": 888, "url": "https://launcher.mojang.com/v1/objects/bd65e7d2e3c237be76cfbef4c2405033d7f91521/client-1.12.xml"}, "type": "log4j2-xml"}}, "mainClass": "net.minecraft.client.main.Main", "minecraftArguments": "--username ${auth_player_name} --version ${version_name} --gameDir ${game_directory} --assetsDir ${assets_root} --assetIndex ${assets_index_name} --uuid ${auth_uuid} --accessToken ${auth_access_token} --userType ${user_type} --versionType ${version_type}", "minimumLauncherVersion": 18, "releaseTime": "2017-09-18T08:39:46+00:00", "time": "2017-09-18T08:39:46+00:00", "type": "release"} +{"assetIndex": {"id": "1.12", "sha1": "a21e1ded1a24ea1548dd8db0cf30b6acb02655a9", "size": 143136, "totalSize": 129843781, "url": "https://piston-meta.mojang.com/v1/packages/a21e1ded1a24ea1548dd8db0cf30b6acb02655a9/1.12.json"}, "assets": "1.12", "complianceLevel": 0, "downloads": {"client": {"sha1": "0f275bc1547d01fa5f56ba34bdc87d981ee12daf", "size": 10180113, "url": "https://piston-data.mojang.com/v1/objects/0f275bc1547d01fa5f56ba34bdc87d981ee12daf/client.jar"}, "server": {"sha1": "886945bfb2b978778c3a0288fd7fab09d315b25f", "size": 30222121, "url": "https://piston-data.mojang.com/v1/objects/886945bfb2b978778c3a0288fd7fab09d315b25f/server.jar"}}, "id": "1.12.2", "javaVersion": {"component": "jre-legacy", "majorVersion": 8}, "libraries": [{"downloads": {"artifact": {"path": "com/mojang/patchy/1.3.9/patchy-1.3.9.jar", "sha1": "eb8bb7b66fa0e2152b1b40b3856e82f7619439ee", "size": 23581, "url": "https://libraries.minecraft.net/com/mojang/patchy/1.3.9/patchy-1.3.9.jar"}}, "name": "com.mojang:patchy:1.3.9"}, {"downloads": {"artifact": {"path": "oshi-project/oshi-core/1.1/oshi-core-1.1.jar", "sha1": "9ddf7b048a8d701be231c0f4f95fd986198fd2d8", "size": 30973, "url": "https://libraries.minecraft.net/oshi-project/oshi-core/1.1/oshi-core-1.1.jar"}}, "name": "oshi-project:oshi-core:1.1"}, {"downloads": {"artifact": {"path": "net/java/dev/jna/jna/4.4.0/jna-4.4.0.jar", "sha1": "cb208278274bf12ebdb56c61bd7407e6f774d65a", "size": 1091208, "url": "https://libraries.minecraft.net/net/java/dev/jna/jna/4.4.0/jna-4.4.0.jar"}}, "name": "net.java.dev.jna:jna:4.4.0"}, {"downloads": {"artifact": {"path": "net/java/dev/jna/platform/3.4.0/platform-3.4.0.jar", "sha1": "e3f70017be8100d3d6923f50b3d2ee17714e9c13", "size": 913436, "url": "https://libraries.minecraft.net/net/java/dev/jna/platform/3.4.0/platform-3.4.0.jar"}}, "name": "net.java.dev.jna:platform:3.4.0"}, {"downloads": {"artifact": {"path": "com/ibm/icu/icu4j-core-mojang/51.2/icu4j-core-mojang-51.2.jar", "sha1": "63d216a9311cca6be337c1e458e587f99d382b84", "size": 1634692, "url": "https://libraries.minecraft.net/com/ibm/icu/icu4j-core-mojang/51.2/icu4j-core-mojang-51.2.jar"}}, "name": "com.ibm.icu:icu4j-core-mojang:51.2"}, {"downloads": {"artifact": {"path": "net/sf/jopt-simple/jopt-simple/5.0.3/jopt-simple-5.0.3.jar", "sha1": "cdd846cfc4e0f7eefafc02c0f5dce32b9303aa2a", "size": 78175, "url": "https://libraries.minecraft.net/net/sf/jopt-simple/jopt-simple/5.0.3/jopt-simple-5.0.3.jar"}}, "name": "net.sf.jopt-simple:jopt-simple:5.0.3"}, {"downloads": {"artifact": {"path": "com/paulscode/codecjorbis/20101023/codecjorbis-20101023.jar", "sha1": "c73b5636faf089d9f00e8732a829577de25237ee", "size": 103871, "url": "https://libraries.minecraft.net/com/paulscode/codecjorbis/20101023/codecjorbis-20101023.jar"}}, "name": "com.paulscode:codecjorbis:20101023"}, {"downloads": {"artifact": {"path": "com/paulscode/codecwav/20101023/codecwav-20101023.jar", "sha1": "12f031cfe88fef5c1dd36c563c0a3a69bd7261da", "size": 5618, "url": "https://libraries.minecraft.net/com/paulscode/codecwav/20101023/codecwav-20101023.jar"}}, "name": "com.paulscode:codecwav:20101023"}, {"downloads": {"artifact": {"path": "com/paulscode/libraryjavasound/20101123/libraryjavasound-20101123.jar", "sha1": "5c5e304366f75f9eaa2e8cca546a1fb6109348b3", "size": 21679, "url": "https://libraries.minecraft.net/com/paulscode/libraryjavasound/20101123/libraryjavasound-20101123.jar"}}, "name": "com.paulscode:libraryjavasound:20101123"}, {"downloads": {"artifact": {"path": "com/paulscode/librarylwjglopenal/20100824/librarylwjglopenal-20100824.jar", "sha1": "73e80d0794c39665aec3f62eee88ca91676674ef", "size": 18981, "url": "https://libraries.minecraft.net/com/paulscode/librarylwjglopenal/20100824/librarylwjglopenal-20100824.jar"}}, "name": "com.paulscode:librarylwjglopenal:20100824"}, {"downloads": {"artifact": {"path": "com/paulscode/soundsystem/20120107/soundsystem-20120107.jar", "sha1": "419c05fe9be71f792b2d76cfc9b67f1ed0fec7f6", "size": 65020, "url": "https://libraries.minecraft.net/com/paulscode/soundsystem/20120107/soundsystem-20120107.jar"}}, "name": "com.paulscode:soundsystem:20120107"}, {"downloads": {"artifact": {"path": "io/netty/netty-all/4.1.9.Final/netty-all-4.1.9.Final.jar", "sha1": "0097860965d6a0a6b98e7f569f3f966727b8db75", "size": 3511093, "url": "https://libraries.minecraft.net/io/netty/netty-all/4.1.9.Final/netty-all-4.1.9.Final.jar"}}, "name": "io.netty:netty-all:4.1.9.Final"}, {"downloads": {"artifact": {"path": "com/google/guava/guava/21.0/guava-21.0.jar", "sha1": "3a3d111be1be1b745edfa7d91678a12d7ed38709", "size": 2521113, "url": "https://libraries.minecraft.net/com/google/guava/guava/21.0/guava-21.0.jar"}}, "name": "com.google.guava:guava:21.0"}, {"downloads": {"artifact": {"path": "org/apache/commons/commons-lang3/3.5/commons-lang3-3.5.jar", "sha1": "6c6c702c89bfff3cd9e80b04d668c5e190d588c6", "size": 479881, "url": "https://libraries.minecraft.net/org/apache/commons/commons-lang3/3.5/commons-lang3-3.5.jar"}}, "name": "org.apache.commons:commons-lang3:3.5"}, {"downloads": {"artifact": {"path": "commons-io/commons-io/2.5/commons-io-2.5.jar", "sha1": "2852e6e05fbb95076fc091f6d1780f1f8fe35e0f", "size": 208700, "url": "https://libraries.minecraft.net/commons-io/commons-io/2.5/commons-io-2.5.jar"}}, "name": "commons-io:commons-io:2.5"}, {"downloads": {"artifact": {"path": "commons-codec/commons-codec/1.10/commons-codec-1.10.jar", "sha1": "4b95f4897fa13f2cd904aee711aeafc0c5295cd8", "size": 284184, "url": "https://libraries.minecraft.net/commons-codec/commons-codec/1.10/commons-codec-1.10.jar"}}, "name": "commons-codec:commons-codec:1.10"}, {"downloads": {"artifact": {"path": "net/java/jinput/jinput/2.0.5/jinput-2.0.5.jar", "sha1": "39c7796b469a600f72380316f6b1f11db6c2c7c4", "size": 208338, "url": "https://libraries.minecraft.net/net/java/jinput/jinput/2.0.5/jinput-2.0.5.jar"}}, "name": "net.java.jinput:jinput:2.0.5"}, {"downloads": {"artifact": {"path": "net/java/jutils/jutils/1.0.0/jutils-1.0.0.jar", "sha1": "e12fe1fda814bd348c1579329c86943d2cd3c6a6", "size": 7508, "url": "https://libraries.minecraft.net/net/java/jutils/jutils/1.0.0/jutils-1.0.0.jar"}}, "name": "net.java.jutils:jutils:1.0.0"}, {"downloads": {"artifact": {"path": "com/google/code/gson/gson/2.8.0/gson-2.8.0.jar", "sha1": "c4ba5371a29ac9b2ad6129b1d39ea38750043eff", "size": 231952, "url": "https://libraries.minecraft.net/com/google/code/gson/gson/2.8.0/gson-2.8.0.jar"}}, "name": "com.google.code.gson:gson:2.8.0"}, {"downloads": {"artifact": {"path": "com/mojang/authlib/1.5.25/authlib-1.5.25.jar", "sha1": "9834cdf236c22e84b946bba989e2f94ef5897c3c", "size": 65621, "url": "https://libraries.minecraft.net/com/mojang/authlib/1.5.25/authlib-1.5.25.jar"}}, "name": "com.mojang:authlib:1.5.25"}, {"downloads": {"artifact": {"path": "com/mojang/realms/1.10.22/realms-1.10.22.jar", "sha1": "bd0dccebdf3744c75f1ca20063f16e8f7d5e663f", "size": 7135057, "url": "https://libraries.minecraft.net/com/mojang/realms/1.10.22/realms-1.10.22.jar"}}, "name": "com.mojang:realms:1.10.22"}, {"downloads": {"artifact": {"path": "org/apache/commons/commons-compress/1.8.1/commons-compress-1.8.1.jar", "sha1": "a698750c16740fd5b3871425f4cb3bbaa87f529d", "size": 365552, "url": "https://libraries.minecraft.net/org/apache/commons/commons-compress/1.8.1/commons-compress-1.8.1.jar"}}, "name": "org.apache.commons:commons-compress:1.8.1"}, {"downloads": {"artifact": {"path": "org/apache/httpcomponents/httpclient/4.3.3/httpclient-4.3.3.jar", "sha1": "18f4247ff4572a074444572cee34647c43e7c9c7", "size": 589512, "url": "https://libraries.minecraft.net/org/apache/httpcomponents/httpclient/4.3.3/httpclient-4.3.3.jar"}}, "name": "org.apache.httpcomponents:httpclient:4.3.3"}, {"downloads": {"artifact": {"path": "commons-logging/commons-logging/1.1.3/commons-logging-1.1.3.jar", "sha1": "f6f66e966c70a83ffbdb6f17a0919eaf7c8aca7f", "size": 62050, "url": "https://libraries.minecraft.net/commons-logging/commons-logging/1.1.3/commons-logging-1.1.3.jar"}}, "name": "commons-logging:commons-logging:1.1.3"}, {"downloads": {"artifact": {"path": "org/apache/httpcomponents/httpcore/4.3.2/httpcore-4.3.2.jar", "sha1": "31fbbff1ddbf98f3aa7377c94d33b0447c646b6e", "size": 282269, "url": "https://libraries.minecraft.net/org/apache/httpcomponents/httpcore/4.3.2/httpcore-4.3.2.jar"}}, "name": "org.apache.httpcomponents:httpcore:4.3.2"}, {"downloads": {"artifact": {"path": "it/unimi/dsi/fastutil/7.1.0/fastutil-7.1.0.jar", "sha1": "9835253257524c1be7ab50c057aa2d418fb72082", "size": 17655579, "url": "https://libraries.minecraft.net/it/unimi/dsi/fastutil/7.1.0/fastutil-7.1.0.jar"}}, "name": "it.unimi.dsi:fastutil:7.1.0"}, {"downloads": {"artifact": {"path": "org/apache/logging/log4j/log4j-api/2.8.1/log4j-api-2.8.1.jar", "sha1": "e801d13612e22cad62a3f4f3fe7fdbe6334a8e72", "size": 228859, "url": "https://libraries.minecraft.net/org/apache/logging/log4j/log4j-api/2.8.1/log4j-api-2.8.1.jar"}}, "name": "org.apache.logging.log4j:log4j-api:2.8.1"}, {"downloads": {"artifact": {"path": "org/apache/logging/log4j/log4j-core/2.8.1/log4j-core-2.8.1.jar", "sha1": "4ac28ff2f1ddf05dae3043a190451e8c46b73c31", "size": 1402925, "url": "https://libraries.minecraft.net/org/apache/logging/log4j/log4j-core/2.8.1/log4j-core-2.8.1.jar"}}, "name": "org.apache.logging.log4j:log4j-core:2.8.1"}, {"downloads": {"artifact": {"path": "org/lwjgl/lwjgl/lwjgl/2.9.4-nightly-20150209/lwjgl-2.9.4-nightly-20150209.jar", "sha1": "697517568c68e78ae0b4544145af031c81082dfe", "size": 1047168, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl/2.9.4-nightly-20150209/lwjgl-2.9.4-nightly-20150209.jar"}}, "name": "org.lwjgl.lwjgl:lwjgl:2.9.4-nightly-20150209", "rules": [{"action": "allow"}, {"action": "disallow", "os": {"name": "osx"}}]}, {"downloads": {"artifact": {"path": "org/lwjgl/lwjgl/lwjgl_util/2.9.4-nightly-20150209/lwjgl_util-2.9.4-nightly-20150209.jar", "sha1": "d51a7c040a721d13efdfbd34f8b257b2df882ad0", "size": 173887, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl_util/2.9.4-nightly-20150209/lwjgl_util-2.9.4-nightly-20150209.jar"}}, "name": "org.lwjgl.lwjgl:lwjgl_util:2.9.4-nightly-20150209", "rules": [{"action": "allow"}, {"action": "disallow", "os": {"name": "osx"}}]}, {"downloads": {"artifact": {"path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209.jar", "sha1": "b04f3ee8f5e43fa3b162981b50bb72fe1acabb33", "size": 22, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209.jar"}, "classifiers": {"natives-linux": {"path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-linux.jar", "sha1": "931074f46c795d2f7b30ed6395df5715cfd7675b", "size": 578680, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-linux.jar"}, "natives-osx": {"path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar", "sha1": "bcab850f8f487c3f4c4dbabde778bb82bd1a40ed", "size": 426822, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar"}, "natives-windows": {"path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-windows.jar", "sha1": "b84d5102b9dbfabfeb5e43c7e2828d98a7fc80e0", "size": 613748, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.4-nightly-20150209/lwjgl-platform-2.9.4-nightly-20150209-natives-windows.jar"}}}, "extract": {"exclude": ["META-INF/"]}, "name": "org.lwjgl.lwjgl:lwjgl-platform:2.9.4-nightly-20150209", "natives": {"linux": "natives-linux", "osx": "natives-osx", "windows": "natives-windows"}, "rules": [{"action": "allow"}, {"action": "disallow", "os": {"name": "osx"}}]}, {"downloads": {"artifact": {"path": "org/lwjgl/lwjgl/lwjgl/2.9.2-nightly-20140822/lwjgl-2.9.2-nightly-20140822.jar", "sha1": "7707204c9ffa5d91662de95f0a224e2f721b22af", "size": 1045632, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl/2.9.2-nightly-20140822/lwjgl-2.9.2-nightly-20140822.jar"}}, "name": "org.lwjgl.lwjgl:lwjgl:2.9.2-nightly-20140822", "rules": [{"action": "allow", "os": {"name": "osx"}}]}, {"downloads": {"artifact": {"path": "org/lwjgl/lwjgl/lwjgl_util/2.9.2-nightly-20140822/lwjgl_util-2.9.2-nightly-20140822.jar", "sha1": "f0e612c840a7639c1f77f68d72a28dae2f0c8490", "size": 173887, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl_util/2.9.2-nightly-20140822/lwjgl_util-2.9.2-nightly-20140822.jar"}}, "name": "org.lwjgl.lwjgl:lwjgl_util:2.9.2-nightly-20140822", "rules": [{"action": "allow", "os": {"name": "osx"}}]}, {"downloads": {"classifiers": {"natives-linux": {"path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.2-nightly-20140822/lwjgl-platform-2.9.2-nightly-20140822-natives-linux.jar", "sha1": "d898a33b5d0a6ef3fed3a4ead506566dce6720a5", "size": 578539, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.2-nightly-20140822/lwjgl-platform-2.9.2-nightly-20140822-natives-linux.jar"}, "natives-osx": {"path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.2-nightly-20140822/lwjgl-platform-2.9.2-nightly-20140822-natives-osx.jar", "sha1": "79f5ce2fea02e77fe47a3c745219167a542121d7", "size": 468116, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.2-nightly-20140822/lwjgl-platform-2.9.2-nightly-20140822-natives-osx.jar"}, "natives-windows": {"path": "org/lwjgl/lwjgl/lwjgl-platform/2.9.2-nightly-20140822/lwjgl-platform-2.9.2-nightly-20140822-natives-windows.jar", "sha1": "78b2a55ce4dc29c6b3ec4df8ca165eba05f9b341", "size": 613680, "url": "https://libraries.minecraft.net/org/lwjgl/lwjgl/lwjgl-platform/2.9.2-nightly-20140822/lwjgl-platform-2.9.2-nightly-20140822-natives-windows.jar"}}}, "extract": {"exclude": ["META-INF/"]}, "name": "org.lwjgl.lwjgl:lwjgl-platform:2.9.2-nightly-20140822", "natives": {"linux": "natives-linux", "osx": "natives-osx", "windows": "natives-windows"}, "rules": [{"action": "allow", "os": {"name": "osx"}}]}, {"downloads": {"classifiers": {"natives-linux": {"path": "net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-linux.jar", "sha1": "7ff832a6eb9ab6a767f1ade2b548092d0fa64795", "size": 10362, "url": "https://libraries.minecraft.net/net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-linux.jar"}, "natives-osx": {"path": "net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-osx.jar", "sha1": "53f9c919f34d2ca9de8c51fc4e1e8282029a9232", "size": 12186, "url": "https://libraries.minecraft.net/net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-osx.jar"}, "natives-windows": {"path": "net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-windows.jar", "sha1": "385ee093e01f587f30ee1c8a2ee7d408fd732e16", "size": 155179, "url": "https://libraries.minecraft.net/net/java/jinput/jinput-platform/2.0.5/jinput-platform-2.0.5-natives-windows.jar"}}}, "extract": {"exclude": ["META-INF/"]}, "name": "net.java.jinput:jinput-platform:2.0.5", "natives": {"linux": "natives-linux", "osx": "natives-osx", "windows": "natives-windows"}}, {"downloads": {"artifact": {"path": "com/mojang/text2speech/1.10.3/text2speech-1.10.3.jar", "sha1": "48fd510879dff266c3815947de66e3d4809f8668", "size": 11055, "url": "https://libraries.minecraft.net/com/mojang/text2speech/1.10.3/text2speech-1.10.3.jar"}}, "name": "com.mojang:text2speech:1.10.3"}, {"downloads": {"artifact": {"path": "com/mojang/text2speech/1.10.3/text2speech-1.10.3.jar", "sha1": "48fd510879dff266c3815947de66e3d4809f8668", "size": 11055, "url": "https://libraries.minecraft.net/com/mojang/text2speech/1.10.3/text2speech-1.10.3.jar"}, "classifiers": {"natives-linux": {"path": "com/mojang/text2speech/1.10.3/text2speech-1.10.3-natives-linux.jar", "sha1": "ab7896aec3b3dd272b06194357f2d98f832c0cfc", "size": 7833, "url": "https://libraries.minecraft.net/com/mojang/text2speech/1.10.3/text2speech-1.10.3-natives-linux.jar"}, "natives-windows": {"path": "com/mojang/text2speech/1.10.3/text2speech-1.10.3-natives-windows.jar", "sha1": "84a4b856389cc4f485275b1f63497a95a857a443", "size": 81217, "url": "https://libraries.minecraft.net/com/mojang/text2speech/1.10.3/text2speech-1.10.3-natives-windows.jar"}}}, "extract": {"exclude": ["META-INF/"]}, "name": "com.mojang:text2speech:1.10.3", "natives": {"linux": "natives-linux", "windows": "natives-windows"}}, {"downloads": {"artifact": {"path": "ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0.jar", "sha1": "6ef160c3133a78de015830860197602ca1c855d3", "size": 40502, "url": "https://libraries.minecraft.net/ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0.jar"}, "classifiers": {"natives-osx": {"path": "ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0-natives-osx.jar", "sha1": "08befab4894d55875f33c3d300f4f71e6e828f64", "size": 5629, "url": "https://libraries.minecraft.net/ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0-natives-osx.jar"}}}, "extract": {"exclude": ["META-INF/"]}, "name": "ca.weblite:java-objc-bridge:1.0.0", "natives": {"osx": "natives-osx"}, "rules": [{"action": "allow", "os": {"name": "osx"}}]}, {"downloads": {"artifact": {"path": "ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0.jar", "sha1": "6ef160c3133a78de015830860197602ca1c855d3", "size": 40502, "url": "https://libraries.minecraft.net/ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0.jar"}}, "name": "ca.weblite:java-objc-bridge:1.0.0", "rules": [{"action": "allow", "os": {"name": "osx"}}]}], "logging": {"client": {"argument": "-Dlog4j.configurationFile=${path}", "file": {"id": "client-1.12.xml", "sha1": "bd65e7d2e3c237be76cfbef4c2405033d7f91521", "size": 888, "url": "https://piston-data.mojang.com/v1/objects/bd65e7d2e3c237be76cfbef4c2405033d7f91521/client-1.12.xml"}, "type": "log4j2-xml"}}, "mainClass": "net.minecraft.client.main.Main", "minecraftArguments": "--username ${auth_player_name} --version ${version_name} --gameDir ${game_directory} --assetsDir ${assets_root} --assetIndex ${assets_index_name} --uuid ${auth_uuid} --accessToken ${auth_access_token} --userType ${user_type} --versionType ${version_type}", "minimumLauncherVersion": 18, "releaseTime": "2017-09-18T08:39:46+00:00", "time": "2017-09-18T08:39:46+00:00", "type": "release"} diff --git a/patches/net/minecraft/block/BlockButton.java.patch b/patches/net/minecraft/block/BlockButton.java.patch index ade8c891..0cc49585 100644 --- a/patches/net/minecraft/block/BlockButton.java.patch +++ b/patches/net/minecraft/block/BlockButton.java.patch @@ -19,13 +19,13 @@ + + // RSMM + @Override -+ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ public boolean rsmm$isActive(World world, BlockPos pos, IBlockState state) { + return state.func_177229_b(field_176584_b); + } + + // RSMM + @Override -+ public int getPowerLevel(World world, BlockPos pos, IBlockState state) { ++ public int rsmm$getPowerLevel(World world, BlockPos pos, IBlockState state) { + return state.func_177229_b(field_176584_b) ? MAX_POWER : MIN_POWER; + } } diff --git a/patches/net/minecraft/block/BlockChest.java.patch b/patches/net/minecraft/block/BlockChest.java.patch index c9c03675..50366fcc 100644 --- a/patches/net/minecraft/block/BlockChest.java.patch +++ b/patches/net/minecraft/block/BlockChest.java.patch @@ -109,31 +109,31 @@ + // RSMM + @Override -+ public boolean isMeterable() { ++ public boolean rsmm$isMeterable() { + return BlockChestHelper.isTrapped(this); + } + + // RSMM + @Override -+ public boolean isPowerSource() { ++ public boolean rsmm$isPowerSource() { + return BlockChestHelper.isTrapped(this); + } + + // RSMM + @Override -+ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ public boolean rsmm$isActive(World world, BlockPos pos, IBlockState state) { + return BlockChestHelper.isTrapped(this) && BlockChestHelper.getPower(world, pos, state) > MIN_POWER; + } + + // RSMM + @Override -+ public boolean logPowerChangeOnStateChange() { ++ public boolean rsmm$logPowerChangeOnStateChange() { + return false; + } + + // RSMM + @Override -+ public int getPowerLevel(World world, BlockPos pos, IBlockState state) { ++ public int rsmm$getPowerLevel(World world, BlockPos pos, IBlockState state) { + return BlockChestHelper.isTrapped(this) ? BlockChestHelper.getPower(world, pos, state) : MIN_POWER; + } + diff --git a/patches/net/minecraft/block/BlockDaylightDetector.java.patch b/patches/net/minecraft/block/BlockDaylightDetector.java.patch index b52fa6a5..53376eff 100644 --- a/patches/net/minecraft/block/BlockDaylightDetector.java.patch +++ b/patches/net/minecraft/block/BlockDaylightDetector.java.patch @@ -19,13 +19,13 @@ + + // RSMM + @Override -+ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ public boolean rsmm$isActive(World world, BlockPos pos, IBlockState state) { + return state.func_177229_b(field_176436_a) > MIN_POWER; + } + + // RSMM + @Override -+ public int getPowerLevel(World world, BlockPos pos, IBlockState state) { ++ public int rsmm$getPowerLevel(World world, BlockPos pos, IBlockState state) { + return state.func_177229_b(field_176436_a); + } } diff --git a/patches/net/minecraft/block/BlockDispenser.java.patch b/patches/net/minecraft/block/BlockDispenser.java.patch index da58eddc..9bc6c58b 100644 --- a/patches/net/minecraft/block/BlockDispenser.java.patch +++ b/patches/net/minecraft/block/BlockDispenser.java.patch @@ -40,7 +40,7 @@ + /* end */ boolean flag1 = ((Boolean)p_189540_1_.func_177229_b(field_176440_b)).booleanValue(); -+ logPowered(p_189540_2_, p_189540_3_, flag); // RSMM ++ rsmm$logPowered(p_189540_2_, p_189540_3_, flag); // RSMM + if (flag && !flag1) { @@ -62,19 +62,19 @@ + + // RSMM + @Override -+ public boolean logPoweredOnBlockUpdate() { ++ public boolean rsmm$logPoweredOnBlockUpdate() { + return false; + } + + // RSMM + @Override -+ public boolean isPowered(World world, BlockPos pos, IBlockState state) { ++ public boolean rsmm$isPowered(World world, BlockPos pos, IBlockState state) { + return world.func_175640_z(pos) || (CarpetSettings.quasiConnectivity && world.func_175640_z(pos.func_177984_a())); + } + + // RSMM + @Override -+ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ public boolean rsmm$isActive(World world, BlockPos pos, IBlockState state) { + return state.func_177229_b(field_176440_b); + } } diff --git a/patches/net/minecraft/block/BlockDoor.java.patch b/patches/net/minecraft/block/BlockDoor.java.patch index 2c5d134b..fb9051af 100644 --- a/patches/net/minecraft/block/BlockDoor.java.patch +++ b/patches/net/minecraft/block/BlockDoor.java.patch @@ -24,8 +24,8 @@ { boolean flag = p_189540_2_.func_175640_z(p_189540_3_) || p_189540_2_.func_175640_z(blockpos1); -+ logPowered(p_189540_2_, p_189540_3_, flag); // RSMM -+ logPowered(p_189540_2_, blockpos1, flag); // RSMM ++ rsmm$logPowered(p_189540_2_, p_189540_3_, flag); // RSMM ++ rsmm$logPowered(p_189540_2_, blockpos1, flag); // RSMM + if (p_189540_4_ != this && (flag || p_189540_4_.func_176223_P().func_185897_m()) && flag != ((Boolean)iblockstate1.func_177229_b(field_176522_N)).booleanValue()) { @@ -36,19 +36,19 @@ + // RSMM + @Override -+ public boolean logPoweredOnBlockUpdate() { ++ public boolean rsmm$logPoweredOnBlockUpdate() { + return false; + } + + // RSMM + @Override -+ public boolean isPowered(World world, BlockPos pos, IBlockState state) { ++ public boolean rsmm$isPowered(World world, BlockPos pos, IBlockState state) { + return world.func_175640_z(pos) || world.func_175640_z(getOtherHalf(pos, state)); + } + + // RSMM + @Override -+ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ public boolean rsmm$isActive(World world, BlockPos pos, IBlockState state) { + return state.func_177229_b(field_176519_b); + } + diff --git a/patches/net/minecraft/block/BlockEndPortalFrame.java.patch b/patches/net/minecraft/block/BlockEndPortalFrame.java.patch index 3a1ab27b..2ca44af4 100644 --- a/patches/net/minecraft/block/BlockEndPortalFrame.java.patch +++ b/patches/net/minecraft/block/BlockEndPortalFrame.java.patch @@ -18,7 +18,7 @@ + + // RSMM + @Override -+ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ public boolean rsmm$isActive(World world, BlockPos pos, IBlockState state) { + return state.func_177229_b(field_176507_b); + } } diff --git a/patches/net/minecraft/block/BlockFenceGate.java.patch b/patches/net/minecraft/block/BlockFenceGate.java.patch index c305d2fc..d23c77e9 100644 --- a/patches/net/minecraft/block/BlockFenceGate.java.patch +++ b/patches/net/minecraft/block/BlockFenceGate.java.patch @@ -28,7 +28,7 @@ { boolean flag = p_189540_2_.func_175640_z(p_189540_3_); -+ logPowered(p_189540_2_, p_189540_3_, flag); // RSMM ++ rsmm$logPowered(p_189540_2_, p_189540_3_, flag); // RSMM + if (((Boolean)p_189540_1_.func_177229_b(field_176465_b)).booleanValue() != flag) { @@ -40,13 +40,13 @@ + + // RSMM + @Override -+ public boolean logPoweredOnBlockUpdate() { ++ public boolean rsmm$logPoweredOnBlockUpdate() { + return false; + } + + // RSMM + @Override -+ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ public boolean rsmm$isActive(World world, BlockPos pos, IBlockState state) { + return state.func_177229_b(field_176466_a); + } } diff --git a/patches/net/minecraft/block/BlockHopper.java.patch b/patches/net/minecraft/block/BlockHopper.java.patch index 32d940a1..2f1dcd12 100644 --- a/patches/net/minecraft/block/BlockHopper.java.patch +++ b/patches/net/minecraft/block/BlockHopper.java.patch @@ -26,25 +26,31 @@ { boolean flag = !p_176427_1_.func_175640_z(p_176427_2_); -+ logPowered(p_176427_1_, p_176427_2_, !flag); // RSMM ++ rsmm$logPowered(p_176427_1_, p_176427_2_, !flag); // RSMM + if (flag != ((Boolean)p_176427_3_.func_177229_b(field_176429_b)).booleanValue()) { p_176427_1_.func_180501_a(p_176427_2_, p_176427_3_.func_177226_a(field_176429_b, Boolean.valueOf(flag)), 4); -@@ -230,4 +238,16 @@ +@@ -230,4 +238,22 @@ { return p_193383_4_ == EnumFacing.UP ? BlockFaceShape.BOWL : BlockFaceShape.UNDEFINED; } + + // RSMM + @Override -+ public boolean logPoweredOnBlockUpdate() { ++ public boolean rsmm$logPoweredOnBlockUpdate() { + return false; + } + + // RSMM + @Override -+ public boolean isActive(World world, BlockPos pos, IBlockState state) { -+ return state.func_177229_b(field_176429_b); ++ public boolean rsmm$isActive(World world, BlockPos pos, IBlockState state) { ++ TileEntity blockEntity = world.func_175625_s(pos); ++ ++ if (blockEntity instanceof TileEntityHopper) { ++ return !((TileEntityHopper)blockEntity).func_145888_j(); ++ } ++ ++ return false; + } } diff --git a/patches/net/minecraft/block/BlockLever.java.patch b/patches/net/minecraft/block/BlockLever.java.patch index 0546e542..7aec7bd7 100644 --- a/patches/net/minecraft/block/BlockLever.java.patch +++ b/patches/net/minecraft/block/BlockLever.java.patch @@ -18,13 +18,13 @@ + // RSMM + @Override -+ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ public boolean rsmm$isActive(World world, BlockPos pos, IBlockState state) { + return state.func_177229_b(field_176359_b); + } + + // RSMM + @Override -+ public int getPowerLevel(World world, BlockPos pos, IBlockState state) { ++ public int rsmm$getPowerLevel(World world, BlockPos pos, IBlockState state) { + return state.func_177229_b(field_176359_b) ? MAX_POWER : MIN_POWER; + } + diff --git a/patches/net/minecraft/block/BlockNote.java.patch b/patches/net/minecraft/block/BlockNote.java.patch index 274f4375..ba72c8c8 100644 --- a/patches/net/minecraft/block/BlockNote.java.patch +++ b/patches/net/minecraft/block/BlockNote.java.patch @@ -21,7 +21,7 @@ boolean flag = p_189540_2_.func_175640_z(p_189540_3_); TileEntity tileentity = p_189540_2_.func_175625_s(p_189540_3_); -+ logPowered(p_189540_2_, p_189540_3_, flag); // RSMM ++ rsmm$logPowered(p_189540_2_, p_189540_3_, flag); // RSMM + if (tileentity instanceof TileEntityNote) { @@ -37,7 +37,7 @@ tileentitynote.field_145880_i = flag; + + // RSMM start -+ if (!p_189540_2_.field_72995_K) { ++ if (CarpetSettings.redstoneMultimeter) { + WorldHelper.getMultimeter().logActive(p_189540_2_, p_189540_3_, flag); + } + // RSMM end @@ -123,13 +123,13 @@ + + // RSMM + @Override -+ public boolean logPoweredOnBlockUpdate() { ++ public boolean rsmm$logPoweredOnBlockUpdate() { + return false; + } + + // RSMM + @Override -+ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ public boolean rsmm$isActive(World world, BlockPos pos, IBlockState state) { + TileEntity blockEntity = world.func_175625_s(pos); + + if (blockEntity instanceof TileEntityNote) { diff --git a/patches/net/minecraft/block/BlockObserver.java.patch b/patches/net/minecraft/block/BlockObserver.java.patch index 580c17c1..653af19c 100644 --- a/patches/net/minecraft/block/BlockObserver.java.patch +++ b/patches/net/minecraft/block/BlockObserver.java.patch @@ -63,13 +63,13 @@ + + // RSMM + @Override -+ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ public boolean rsmm$isActive(World world, BlockPos pos, IBlockState state) { + return state.func_177229_b(field_190963_a); + } + + // RSMM + @Override -+ public int getPowerLevel(World world, BlockPos pos, IBlockState state) { ++ public int rsmm$getPowerLevel(World world, BlockPos pos, IBlockState state) { + return state.func_177229_b(field_190963_a) ? MAX_POWER : MIN_POWER; + } } diff --git a/patches/net/minecraft/block/BlockPistonBase.java.patch b/patches/net/minecraft/block/BlockPistonBase.java.patch index 099d96e2..1986489c 100644 --- a/patches/net/minecraft/block/BlockPistonBase.java.patch +++ b/patches/net/minecraft/block/BlockPistonBase.java.patch @@ -133,11 +133,11 @@ + return 0; + } + -+ // RSMM - wrapped method ++ // RSMM - wrapped method to capture return value + public boolean func_176318_b(World p_176318_1_, BlockPos p_176318_2_, EnumFacing p_176318_3_) { + boolean powered = _shouldBeExtended(p_176318_1_, p_176318_2_, p_176318_3_); -+ logPowered(p_176318_1_, p_176318_2_, powered); // RSMM ++ rsmm$logPowered(p_176318_1_, p_176318_2_, powered); // RSMM + return powered; + } + @@ -257,7 +257,7 @@ + if (CarpetSettings.redstoneMultimeterLegacy) { + PistonPushEventDispatcher.dispatchEvent(p_176319_1_, blockpos3, enumfacing); + } -+ if (CarpetSettings.redstoneMultimeter && !p_176319_1_.field_72995_K) { ++ if (CarpetSettings.redstoneMultimeter) { + Multimeter multimeter = WorldHelper.getMultimeter(); + + multimeter.logMoved(p_176319_1_, blockpos3, enumfacing); @@ -302,19 +302,19 @@ + + // RSMM + @Override -+ public boolean logPoweredOnBlockUpdate() { ++ public boolean rsmm$logPoweredOnBlockUpdate() { + return false; + } + + // RSMM + @Override -+ public boolean isPowered(World world, BlockPos pos, IBlockState state) { ++ public boolean rsmm$isPowered(World world, BlockPos pos, IBlockState state) { + return func_176318_b(world, pos, state.func_177229_b(field_176387_N)); + } + + // RSMM + @Override -+ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ public boolean rsmm$isActive(World world, BlockPos pos, IBlockState state) { + return state.func_177229_b(field_176320_b); + } + diff --git a/patches/net/minecraft/block/BlockPressurePlate.java.patch b/patches/net/minecraft/block/BlockPressurePlate.java.patch index abf1a923..14cb2a5f 100644 --- a/patches/net/minecraft/block/BlockPressurePlate.java.patch +++ b/patches/net/minecraft/block/BlockPressurePlate.java.patch @@ -18,13 +18,13 @@ + // RSMM + @Override -+ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ public boolean rsmm$isActive(World world, BlockPos pos, IBlockState state) { + return state.func_177229_b(field_176580_a); + } + + // RSMM + @Override -+ public int getPowerLevel(World world, BlockPos pos, IBlockState state) { ++ public int rsmm$getPowerLevel(World world, BlockPos pos, IBlockState state) { + return state.func_177229_b(field_176580_a) ? MAX_POWER : MIN_POWER; + } + diff --git a/patches/net/minecraft/block/BlockPressurePlateWeighted.java.patch b/patches/net/minecraft/block/BlockPressurePlateWeighted.java.patch index cbd704b3..8d970967 100644 --- a/patches/net/minecraft/block/BlockPressurePlateWeighted.java.patch +++ b/patches/net/minecraft/block/BlockPressurePlateWeighted.java.patch @@ -19,13 +19,13 @@ + + // RSMM + @Override -+ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ public boolean rsmm$isActive(World world, BlockPos pos, IBlockState state) { + return state.func_177229_b(field_176579_a) > MIN_POWER; + } + + // RSMM + @Override -+ public int getPowerLevel(World world, BlockPos pos, IBlockState state) { ++ public int rsmm$getPowerLevel(World world, BlockPos pos, IBlockState state) { + return state.func_177229_b(field_176579_a); + } } diff --git a/patches/net/minecraft/block/BlockRailDetector.java.patch b/patches/net/minecraft/block/BlockRailDetector.java.patch index e40b9f2c..903a9fd7 100644 --- a/patches/net/minecraft/block/BlockRailDetector.java.patch +++ b/patches/net/minecraft/block/BlockRailDetector.java.patch @@ -34,13 +34,13 @@ + + // RSMM + @Override -+ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ public boolean rsmm$isActive(World world, BlockPos pos, IBlockState state) { + return state.func_177229_b(field_176574_M); + } + + // RSMM + @Override -+ public int getPowerLevel(World world, BlockPos pos, IBlockState state) { ++ public int rsmm$getPowerLevel(World world, BlockPos pos, IBlockState state) { + return state.func_177229_b(field_176574_M) ? MAX_POWER : MIN_POWER; + } } diff --git a/patches/net/minecraft/block/BlockRailPowered.java.patch b/patches/net/minecraft/block/BlockRailPowered.java.patch index 3823d0de..8f11ce59 100644 --- a/patches/net/minecraft/block/BlockRailPowered.java.patch +++ b/patches/net/minecraft/block/BlockRailPowered.java.patch @@ -30,7 +30,7 @@ boolean flag = ((Boolean)p_189541_1_.func_177229_b(field_176569_M)).booleanValue(); boolean flag1 = p_189541_2_.func_175640_z(p_189541_3_) || this.func_176566_a(p_189541_2_, p_189541_3_, p_189541_1_, true, 0) || this.func_176566_a(p_189541_2_, p_189541_3_, p_189541_1_, false, 0); -+ logPowered(p_189541_2_, p_189541_3_, flag1); // RSMM ++ rsmm$logPowered(p_189541_2_, p_189541_3_, flag1); // RSMM + if (flag1 != flag) { @@ -57,19 +57,19 @@ + + // RSMM + @Override -+ public boolean logPoweredOnBlockUpdate() { ++ public boolean rsmm$logPoweredOnBlockUpdate() { + return false; + } + + // RSMM + @Override -+ public boolean isPowered(World world, BlockPos pos, IBlockState state) { ++ public boolean rsmm$isPowered(World world, BlockPos pos, IBlockState state) { + return world.func_175640_z(pos) || func_176566_a(world, pos, state, true, 0) || func_176566_a(world, pos, state, false, 0); + } + + // RSMM + @Override -+ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ public boolean rsmm$isActive(World world, BlockPos pos, IBlockState state) { + return state.func_177229_b(field_176569_M); + } } diff --git a/patches/net/minecraft/block/BlockRedstoneComparator.java.patch b/patches/net/minecraft/block/BlockRedstoneComparator.java.patch index 5900a299..d055f8b4 100644 --- a/patches/net/minecraft/block/BlockRedstoneComparator.java.patch +++ b/patches/net/minecraft/block/BlockRedstoneComparator.java.patch @@ -27,16 +27,21 @@ { return 2; } -@@ -155,6 +159,8 @@ - } - } +@@ -92,9 +96,12 @@ + return tileentity instanceof TileEntityComparator ? ((TileEntityComparator)tileentity).func_145996_a() : 0; + } -+ logPowered(p_176397_1_, p_176397_2_, i > MIN_POWER); // RSMM -+ - return i; ++ // RSMM - capture return value + private int func_176460_j(World p_176460_1_, BlockPos p_176460_2_, IBlockState p_176460_3_) + { +- return p_176460_3_.func_177229_b(field_176463_b) == BlockRedstoneComparator.Mode.SUBTRACT ? Math.max(this.func_176397_f(p_176460_1_, p_176460_2_, p_176460_3_) - this.func_176407_c(p_176460_1_, p_176460_2_, p_176460_3_), 0) : this.func_176397_f(p_176460_1_, p_176460_2_, p_176460_3_); ++ int output = p_176460_3_.func_177229_b(field_176463_b) == BlockRedstoneComparator.Mode.SUBTRACT ? Math.max(this.func_176397_f(p_176460_1_, p_176460_2_, p_176460_3_) - this.func_176407_c(p_176460_1_, p_176460_2_, p_176460_3_), 0) : this.func_176397_f(p_176460_1_, p_176460_2_, p_176460_3_); ++ rsmm$logPowered(p_176460_1_, p_176460_2_, output > MIN_POWER); // RSMM ++ return output; } -@@ -206,8 +212,32 @@ + protected boolean func_176404_e(World p_176404_1_, BlockPos p_176404_2_, IBlockState p_176404_3_) +@@ -206,8 +213,32 @@ { p_176398_1_.func_175654_a(p_176398_2_, this, 2, 0); } @@ -69,7 +74,7 @@ } private void func_176462_k(World p_176462_1_, BlockPos p_176462_2_, IBlockState p_176462_3_) -@@ -249,6 +279,22 @@ +@@ -249,6 +280,22 @@ } this.func_176462_k(p_180650_1_, p_180650_2_, p_180650_3_); @@ -92,25 +97,25 @@ } public void func_176213_c(World p_176213_1_, BlockPos p_176213_2_, IBlockState p_176213_3_) -@@ -319,6 +365,30 @@ +@@ -319,6 +366,30 @@ return this.func_176223_P().func_177226_a(field_185512_D, p_180642_8_.func_174811_aO().func_176734_d()).func_177226_a(field_176464_a, Boolean.valueOf(false)).func_177226_a(field_176463_b, BlockRedstoneComparator.Mode.COMPARE); } + // RSMM + @Override -+ public boolean isActive(World world, BlockPos pos, IBlockState state) { -+ return getPowerLevel(world, pos, state) > MIN_POWER; ++ public boolean rsmm$isActive(World world, BlockPos pos, IBlockState state) { ++ return rsmm$getPowerLevel(world, pos, state) > MIN_POWER; + } + + // RSMM + @Override -+ public boolean logPowerChangeOnStateChange() { ++ public boolean rsmm$logPowerChangeOnStateChange() { + return false; + } + + // RSMM + @Override -+ public int getPowerLevel(World world, BlockPos pos, IBlockState state) { ++ public int rsmm$getPowerLevel(World world, BlockPos pos, IBlockState state) { + TileEntity blockEntity = world.func_175625_s(pos); + + if (blockEntity instanceof TileEntityComparator) { diff --git a/patches/net/minecraft/block/BlockRedstoneDiode.java.patch b/patches/net/minecraft/block/BlockRedstoneDiode.java.patch index 2d4cb5ae..3dc9d445 100644 --- a/patches/net/minecraft/block/BlockRedstoneDiode.java.patch +++ b/patches/net/minecraft/block/BlockRedstoneDiode.java.patch @@ -39,7 +39,7 @@ { - return this.func_176397_f(p_176404_1_, p_176404_2_, p_176404_3_) > 0; + boolean powered = this.func_176397_f(p_176404_1_, p_176404_2_, p_176404_3_) > 0; -+ logPowered(p_176404_1_, p_176404_2_, powered); // RSMM ++ rsmm$logPowered(p_176404_1_, p_176404_2_, powered); // RSMM + return powered; } @@ -67,19 +67,19 @@ + + // RSMM + @Override -+ public boolean logPoweredOnBlockUpdate() { ++ public boolean rsmm$logPoweredOnBlockUpdate() { + return false; + } + + // RSMM + @Override -+ public boolean isPowered(World world, BlockPos pos, IBlockState state) { ++ public boolean rsmm$isPowered(World world, BlockPos pos, IBlockState state) { + return func_176404_e(world, pos, state); + } + + // RSMM + @Override -+ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ public boolean rsmm$isActive(World world, BlockPos pos, IBlockState state) { + return field_149914_a; + } } diff --git a/patches/net/minecraft/block/BlockRedstoneLight.java.patch b/patches/net/minecraft/block/BlockRedstoneLight.java.patch index 570cf672..01e29055 100644 --- a/patches/net/minecraft/block/BlockRedstoneLight.java.patch +++ b/patches/net/minecraft/block/BlockRedstoneLight.java.patch @@ -15,7 +15,7 @@ { if (!p_180650_1_.field_72995_K) { -+ logPowered(p_180650_1_, p_180650_2_, p_180650_3_); // RSMM ++ rsmm$logPowered(p_180650_1_, p_180650_2_, p_180650_3_); // RSMM + if (this.field_150171_a && !p_180650_1_.func_175640_z(p_180650_2_)) { @@ -27,7 +27,7 @@ + + // RSMM + @Override -+ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ public boolean rsmm$isActive(World world, BlockPos pos, IBlockState state) { + return field_150171_a; + } } diff --git a/patches/net/minecraft/block/BlockRedstoneOre.java.patch b/patches/net/minecraft/block/BlockRedstoneOre.java.patch index 7d1cc2d4..8482e251 100644 --- a/patches/net/minecraft/block/BlockRedstoneOre.java.patch +++ b/patches/net/minecraft/block/BlockRedstoneOre.java.patch @@ -18,7 +18,7 @@ + + // RSMM + @Override -+ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ public boolean rsmm$isActive(World world, BlockPos pos, IBlockState state) { + return field_150187_a; + } } diff --git a/patches/net/minecraft/block/BlockRedstoneRepeater.java.patch b/patches/net/minecraft/block/BlockRedstoneRepeater.java.patch index 2ab6249d..ed6a179a 100644 --- a/patches/net/minecraft/block/BlockRedstoneRepeater.java.patch +++ b/patches/net/minecraft/block/BlockRedstoneRepeater.java.patch @@ -45,7 +45,7 @@ + boolean locked = this.func_176407_c(p_176405_1_, p_176405_2_, p_176405_3_) > 0; + // RSMM start + if (locked && p_176405_1_ instanceof WorldServer) { -+ logPowered((WorldServer)p_176405_1_, p_176405_2_, p_176405_3_); ++ rsmm$logPowered((WorldServer)p_176405_1_, p_176405_2_, p_176405_3_); + } + // RSMM end + return locked; @@ -59,7 +59,7 @@ + + // RSMM + @Override -+ public int getPowerLevel(World world, BlockPos pos, IBlockState state) { ++ public int rsmm$getPowerLevel(World world, BlockPos pos, IBlockState state) { + return field_149914_a ? MAX_POWER : MIN_POWER; + } } diff --git a/patches/net/minecraft/block/BlockRedstoneTorch.java.patch b/patches/net/minecraft/block/BlockRedstoneTorch.java.patch index 9ec186d8..1dcf7ef4 100644 --- a/patches/net/minecraft/block/BlockRedstoneTorch.java.patch +++ b/patches/net/minecraft/block/BlockRedstoneTorch.java.patch @@ -24,7 +24,7 @@ EnumFacing enumfacing = ((EnumFacing)p_176597_3_.func_177229_b(field_176596_a)).func_176734_d(); - return p_176597_1_.func_175709_b(p_176597_2_.func_177972_a(enumfacing), enumfacing); + boolean powered = p_176597_1_.func_175709_b(p_176597_2_.func_177972_a(enumfacing), enumfacing); -+ logPowered(p_176597_1_, p_176597_2_, powered); // RSMM ++ rsmm$logPowered(p_176597_1_, p_176597_2_, powered); // RSMM + return powered; } @@ -44,25 +44,25 @@ + // RSMM + @Override -+ public boolean logPoweredOnBlockUpdate() { ++ public boolean rsmm$logPoweredOnBlockUpdate() { + return false; + } + + // RSMM + @Override -+ public boolean isPowered(World world, BlockPos pos, IBlockState state) { ++ public boolean rsmm$isPowered(World world, BlockPos pos, IBlockState state) { + return func_176597_g(world, pos, state); + } + + // RSMM + @Override -+ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ public boolean rsmm$isActive(World world, BlockPos pos, IBlockState state) { + return field_150113_a; + } + + // RSMM + @Override -+ public int getPowerLevel(World world, BlockPos pos, IBlockState state) { ++ public int rsmm$getPowerLevel(World world, BlockPos pos, IBlockState state) { + return field_150113_a ? MAX_POWER : MIN_POWER; + } + diff --git a/patches/net/minecraft/block/BlockRedstoneWire.java.patch b/patches/net/minecraft/block/BlockRedstoneWire.java.patch index 1ffd366f..e2b98743 100644 --- a/patches/net/minecraft/block/BlockRedstoneWire.java.patch +++ b/patches/net/minecraft/block/BlockRedstoneWire.java.patch @@ -162,7 +162,7 @@ - { - j = k; - } -+ logPowered(p_176345_1_, p_176345_2_, j > MIN_POWER); // RSMM ++ rsmm$logPowered(p_176345_1_, p_176345_2_, j > MIN_POWER); // RSMM if (i != j) { @@ -264,7 +264,7 @@ + // RSMM + @Override -+ public boolean logPoweredOnBlockUpdate() { ++ public boolean rsmm$logPoweredOnBlockUpdate() { + return false; + } + @@ -273,19 +273,19 @@ + // returns 'true', so it does not really matter that a potentially + // incorrect value is returned. + @Override -+ public boolean isPowered(World world, BlockPos pos, IBlockState state) { ++ public boolean rsmm$isPowered(World world, BlockPos pos, IBlockState state) { + return state.func_177229_b(field_176351_O) > MIN_POWER; + } + + // RSMM + @Override -+ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ public boolean rsmm$isActive(World world, BlockPos pos, IBlockState state) { + return state.func_177229_b(field_176351_O) > MIN_POWER; + } + + // RSMM + @Override -+ public int getPowerLevel(World world, BlockPos pos, IBlockState state) { ++ public int rsmm$getPowerLevel(World world, BlockPos pos, IBlockState state) { + return state.func_177229_b(field_176351_O); + } + diff --git a/patches/net/minecraft/block/BlockTrapDoor.java.patch b/patches/net/minecraft/block/BlockTrapDoor.java.patch index 99c33c5d..36e82c6d 100644 --- a/patches/net/minecraft/block/BlockTrapDoor.java.patch +++ b/patches/net/minecraft/block/BlockTrapDoor.java.patch @@ -15,7 +15,7 @@ { boolean flag = p_189540_2_.func_175640_z(p_189540_3_); -+ logPowered(p_189540_2_, p_189540_3_, flag); // RSMM ++ rsmm$logPowered(p_189540_2_, p_189540_3_, flag); // RSMM + if (flag || p_189540_4_.func_176223_P().func_185897_m()) { @@ -26,13 +26,13 @@ + // RSMM + @Override -+ public boolean logPoweredOnBlockUpdate() { ++ public boolean rsmm$logPoweredOnBlockUpdate() { + return false; + } + + // RSMM + @Override -+ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ public boolean rsmm$isActive(World world, BlockPos pos, IBlockState state) { + return state.func_177229_b(field_176283_b); + } + diff --git a/patches/net/minecraft/block/BlockTripWire.java.patch b/patches/net/minecraft/block/BlockTripWire.java.patch index d4e1bc8d..bb1d167a 100644 --- a/patches/net/minecraft/block/BlockTripWire.java.patch +++ b/patches/net/minecraft/block/BlockTripWire.java.patch @@ -18,7 +18,7 @@ + + // RSMM + @Override -+ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ public boolean rsmm$isActive(World world, BlockPos pos, IBlockState state) { + return state.func_177229_b(field_176293_a); + } } diff --git a/patches/net/minecraft/block/BlockTripWireHook.java.patch b/patches/net/minecraft/block/BlockTripWireHook.java.patch index eb3ef08e..f96acdac 100644 --- a/patches/net/minecraft/block/BlockTripWireHook.java.patch +++ b/patches/net/minecraft/block/BlockTripWireHook.java.patch @@ -19,13 +19,13 @@ + + // RSMM + @Override -+ public boolean isActive(World world, BlockPos pos, IBlockState state) { ++ public boolean rsmm$isActive(World world, BlockPos pos, IBlockState state) { + return state.func_177229_b(field_176263_b); + } + + // RSMM + @Override -+ public int getPowerLevel(World world, BlockPos pos, IBlockState state) { ++ public int rsmm$getPowerLevel(World world, BlockPos pos, IBlockState state) { + return state.func_177229_b(field_176263_b) ? MAX_POWER : MIN_POWER; + } } diff --git a/patches/net/minecraft/network/NetHandlerPlayServer.java.patch b/patches/net/minecraft/network/NetHandlerPlayServer.java.patch index 589fef07..c8f9f3e1 100644 --- a/patches/net/minecraft/network/NetHandlerPlayServer.java.patch +++ b/patches/net/minecraft/network/NetHandlerPlayServer.java.patch @@ -26,7 +26,7 @@ +import net.minecraft.world.gen.structure.template.Template; +import net.minecraft.server.management.PlayerInteractionManager; + -+import redstone.multimeter.common.network.PacketManager; ++import redstone.multimeter.common.network.Packets; + +import static carpet.commands.CommandGMS.setPlayerToSurvival; + @@ -242,9 +242,9 @@ + PlayerInteractionManager.activateInstantMine = true; + } + // RSMM packet handling -+ else if (PacketManager.getPacketChannelId().equals(s)) ++ else if (Packets.getChannel().equals(s)) { -+ CarpetServer.rsmmServer.getPacketHandler().onPacketReceived(p_147349_1_.func_180760_b(), field_147369_b); ++ CarpetServer.rsmmServer.getPacketHandler().handlePacket(p_147349_1_.func_180760_b(), field_147369_b); + } + else if ("MC|BEdit".equals(s)) + { diff --git a/patches/net/minecraft/server/MinecraftServer.java.patch b/patches/net/minecraft/server/MinecraftServer.java.patch index be240c52..5197bbd9 100644 --- a/patches/net/minecraft/server/MinecraftServer.java.patch +++ b/patches/net/minecraft/server/MinecraftServer.java.patch @@ -51,7 +51,7 @@ } protected void func_71222_d() -@@ -285,25 +304,32 @@ +@@ -285,29 +304,38 @@ int i1 = 0; this.func_71192_d("menu.generatingTerrain"); int j1 = 0; @@ -99,7 +99,13 @@ } } -@@ -341,7 +367,7 @@ + this.func_71243_i(); ++ ++ CarpetServer.rsmmServer.worldLoaded(); // RSMM + } + + protected void func_175584_a(String p_175584_1_, ISaveHandler p_175584_2_) +@@ -341,7 +369,7 @@ public abstract boolean func_183002_r(); @@ -108,7 +114,7 @@ { this.field_71302_d = p_71216_1_; this.field_71303_e = p_71216_2_; -@@ -375,6 +401,7 @@ +@@ -375,6 +403,7 @@ } } } @@ -116,7 +122,7 @@ } protected void func_71260_j() -@@ -389,6 +416,8 @@ +@@ -389,6 +418,8 @@ if (this.field_71318_t != null) { field_147145_h.info("Saving players"); @@ -125,7 +131,7 @@ this.field_71318_t.func_72389_g(); this.field_71318_t.func_72392_r(); } -@@ -450,18 +479,33 @@ +@@ -450,18 +481,33 @@ { this.field_175591_ab = func_130071_aq(); long i = 0L; @@ -161,7 +167,7 @@ j = 2000L; this.field_71299_R = this.field_175591_ab; } -@@ -474,6 +518,7 @@ +@@ -474,6 +520,7 @@ i += j; this.field_175591_ab = k; @@ -169,7 +175,7 @@ if (this.field_71305_c[0].func_73056_e()) { -@@ -482,14 +527,33 @@ +@@ -482,14 +529,33 @@ } else { @@ -206,7 +212,7 @@ this.field_71296_Q = true; } } -@@ -592,8 +656,19 @@ +@@ -592,8 +658,19 @@ protected void func_71217_p() { long i = System.nanoTime(); @@ -227,7 +233,7 @@ if (this.field_71295_T) { this.field_71295_T = false; -@@ -620,13 +695,23 @@ +@@ -620,13 +697,23 @@ this.field_147147_p.func_151318_b().func_151330_a(agameprofile); } @@ -251,7 +257,7 @@ this.field_71304_b.func_76320_a("tallying"); this.field_71311_j[this.field_71315_w % 100] = System.nanoTime() - i; -@@ -645,12 +730,34 @@ +@@ -645,12 +732,34 @@ this.field_71304_b.func_76319_b(); this.field_71304_b.func_76319_b(); @@ -286,7 +292,7 @@ synchronized (this.field_175589_i) { while (!this.field_175589_i.isEmpty()) -@@ -658,8 +765,10 @@ +@@ -658,8 +767,10 @@ Util.func_181617_a(this.field_175589_i.poll(), field_147145_h); } } @@ -297,7 +303,7 @@ for (int j = 0; j < this.field_71305_c.length; ++j) { -@@ -672,6 +781,7 @@ +@@ -672,6 +783,7 @@ { return worldserver.func_72912_H().func_76065_j(); }); @@ -305,7 +311,7 @@ if (this.field_71315_w % 20 == 0) { -@@ -686,27 +796,46 @@ +@@ -686,27 +798,46 @@ { worldserver.func_72835_b(); } @@ -354,7 +360,7 @@ this.field_71304_b.func_76319_b(); this.field_71304_b.func_76319_b(); } -@@ -714,13 +843,19 @@ +@@ -714,13 +845,19 @@ this.field_71312_k[j][this.field_71315_w % 100] = System.nanoTime() - i; } @@ -374,7 +380,7 @@ for (int k = 0; k < this.field_71322_p.size(); ++k) { -@@ -728,6 +863,9 @@ +@@ -728,6 +865,9 @@ } this.field_71304_b.func_76319_b(); @@ -384,7 +390,7 @@ } public boolean func_71255_r() -@@ -939,7 +1077,7 @@ +@@ -939,7 +1079,7 @@ public String getServerModName() { @@ -393,7 +399,7 @@ } public CrashReport func_71230_b(CrashReport p_71230_1_) -@@ -1512,6 +1650,7 @@ +@@ -1512,6 +1652,7 @@ { if (this.func_152345_ab()) { @@ -401,13 +407,3 @@ this.func_184103_al().func_72389_g(); this.field_71305_c[0].func_184146_ak().func_186522_a(); this.func_191949_aK().func_192779_a(); -@@ -1523,4 +1662,9 @@ - this.func_152344_a(this::func_193031_aM); - } - } -+ -+ // RSMM -+ public boolean isPaused() { -+ return false; -+ } - } diff --git a/patches/net/minecraft/server/management/PlayerList.java.patch b/patches/net/minecraft/server/management/PlayerList.java.patch index 8e784bde..0579cfff 100644 --- a/patches/net/minecraft/server/management/PlayerList.java.patch +++ b/patches/net/minecraft/server/management/PlayerList.java.patch @@ -49,16 +49,7 @@ nethandlerplayserver.func_147359_a(new SPacketJoinGame(p_72355_2_.func_145782_y(), p_72355_2_.field_71134_c.func_73081_b(), worldinfo.func_76093_s(), worldserver.field_73011_w.func_186058_p().func_186068_a(), worldserver.func_175659_aa(), this.func_72352_l(), worldinfo.func_76067_t(), worldserver.func_82736_K().func_82766_b("reducedDebugInfo"))); nethandlerplayserver.func_147359_a(new SPacketCustomPayload("MC|Brand", (new PacketBuffer(Unpooled.buffer())).func_180714_a(this.func_72365_p().getServerModName()))); nethandlerplayserver.func_147359_a(new SPacketServerDifficulty(worldinfo.func_176130_y(), worldinfo.func_176123_z())); -@@ -202,6 +207,8 @@ - } - - p_72355_2_.func_71116_b(); -+ -+ CarpetServer.rsmmServer.onPlayerJoin(p_72355_2_); // RSMM - } - - protected void func_96456_a(ServerScoreboard p_96456_1_, EntityPlayerMP p_96456_2_) -@@ -343,6 +350,8 @@ +@@ -343,6 +348,8 @@ worldserver.func_72838_d(p_72377_1_); this.func_72375_a(p_72377_1_, (WorldServer)null); @@ -67,18 +58,18 @@ } public void func_72358_d(EntityPlayerMP p_72358_1_) -@@ -352,6 +361,10 @@ +@@ -352,6 +359,10 @@ public void func_72367_e(EntityPlayerMP p_72367_1_) { -+ CarpetServer.rsmmServer.onPlayerLeave(p_72367_1_); // RSMM ++ CarpetServer.rsmmServer.getPlayerList().remove(p_72367_1_); // RSMM + + //CM player logging off + CarpetServer.playerDisconnected(p_72367_1_); WorldServer worldserver = p_72367_1_.func_71121_q(); p_72367_1_.func_71029_a(StatList.field_75947_j); this.func_72391_b(p_72367_1_); -@@ -452,6 +465,11 @@ +@@ -452,6 +463,11 @@ for (EntityPlayerMP entityplayermp1 : list) { @@ -90,7 +81,7 @@ entityplayermp1.field_71135_a.func_194028_b(new TextComponentTranslation("multiplayer.disconnect.duplicate_login", new Object[0])); } -@@ -474,6 +492,7 @@ +@@ -474,6 +490,7 @@ p_72368_1_.func_71121_q().func_73039_n().func_72787_a(p_72368_1_); p_72368_1_.func_71121_q().func_73039_n().func_72790_b(p_72368_1_); p_72368_1_.func_71121_q().func_184164_w().func_72695_c(p_72368_1_); @@ -98,7 +89,7 @@ this.field_72404_b.remove(p_72368_1_); this.field_72400_f.func_71218_a(p_72368_1_.field_71093_bK).func_72973_f(p_72368_1_); BlockPos blockpos = p_72368_1_.func_180470_cg(); -@@ -496,6 +515,7 @@ +@@ -496,6 +513,7 @@ entityplayermp.func_145769_d(p_72368_1_.func_145782_y()); entityplayermp.func_174817_o(p_72368_1_); entityplayermp.func_184819_a(p_72368_1_.func_184591_cq()); @@ -106,7 +97,15 @@ for (String s : p_72368_1_.func_184216_O()) { -@@ -560,7 +580,11 @@ +@@ -540,6 +558,7 @@ + this.field_177454_f.put(entityplayermp.func_110124_au(), entityplayermp); + entityplayermp.func_71116_b(); + entityplayermp.func_70606_j(entityplayermp.func_110143_aJ()); ++ CarpetServer.rsmmServer.getPlayerList().respawn(entityplayermp); // RSMM + return entityplayermp; + } + +@@ -560,7 +579,11 @@ WorldServer worldserver1 = this.field_72400_f.func_71218_a(p_187242_1_.field_71093_bK); p_187242_1_.field_71135_a.func_147359_a(new SPacketRespawn(p_187242_1_.field_71093_bK, p_187242_1_.field_70170_p.func_175659_aa(), p_187242_1_.field_70170_p.func_72912_H().func_76067_t(), p_187242_1_.field_71134_c.func_73081_b())); this.func_187243_f(p_187242_1_); @@ -119,7 +118,7 @@ p_187242_1_.field_70128_L = false; this.func_82448_a(p_187242_1_, i, worldserver, worldserver1); this.func_72375_a(p_187242_1_, worldserver); -@@ -630,6 +654,12 @@ +@@ -630,6 +653,12 @@ } } @@ -132,7 +131,7 @@ p_82448_3_.field_72984_F.func_76319_b(); if (p_82448_2_ != 1) -@@ -1097,4 +1127,26 @@ +@@ -1097,4 +1126,26 @@ playeradvancements.func_193766_b(); } } diff --git a/patches/net/minecraft/tileentity/TileEntityComparator.java.patch b/patches/net/minecraft/tileentity/TileEntityComparator.java.patch index 284f6685..75bc5f67 100644 --- a/patches/net/minecraft/tileentity/TileEntityComparator.java.patch +++ b/patches/net/minecraft/tileentity/TileEntityComparator.java.patch @@ -24,7 +24,7 @@ public void func_145995_a(int p_145995_1_) { + // RSMM start -+ if (CarpetSettings.redstoneMultimeter && !field_145850_b.field_72995_K) { ++ if (CarpetSettings.redstoneMultimeter) { + WorldHelper.getMultimeter().logPowerChange(field_145850_b, field_174879_c, field_145997_a, p_145995_1_); + } + // RSMM end diff --git a/patches/net/minecraft/tileentity/TileEntityHopper.java.patch b/patches/net/minecraft/tileentity/TileEntityHopper.java.patch index 3d24dcc3..d31e1fc4 100644 --- a/patches/net/minecraft/tileentity/TileEntityHopper.java.patch +++ b/patches/net/minecraft/tileentity/TileEntityHopper.java.patch @@ -10,17 +10,18 @@ import net.minecraft.block.Block; import net.minecraft.block.BlockChest; import net.minecraft.block.BlockHopper; -@@ -28,12 +31,21 @@ +@@ -27,13 +30,22 @@ + import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; - --public class TileEntityHopper extends TileEntityLockableLoot implements IHopper, ITickable ++import redstone.multimeter.helper.WorldHelper; +import net.minecraft.item.EnumDyeColor; +import carpet.helpers.TileEntityOptimizer.ILazyTileEntity; +import carpet.CarpetSettings; +import carpet.helpers.HopperCounter; +import carpet.utils.WoolTool; -+ + +-public class TileEntityHopper extends TileEntityLockableLoot implements IHopper, ITickable +public class TileEntityHopper extends TileEntityLockableLoot implements IHopper, ITickable, ILazyTileEntity { private NonNullList field_145900_a = NonNullList.func_191197_a(5, ItemStack.field_190927_a); @@ -33,7 +34,15 @@ public static void func_189683_a(DataFixer p_189683_0_) { p_189683_0_.func_188258_a(FixTypes.BLOCK_ENTITY, new ItemStackDataLists(TileEntityHopper.class, new String[] {"Items"})); -@@ -132,14 +144,44 @@ +@@ -114,6 +126,7 @@ + if (this.field_145850_b != null && !this.field_145850_b.field_72995_K) + { + --this.field_145901_j; ++ rsmm$logActive(); // RSMM + this.field_190578_g = this.field_145850_b.func_82737_E(); + + if (!this.func_145888_j()) +@@ -132,14 +145,44 @@ { boolean flag = false; @@ -83,7 +92,7 @@ } if (flag) -@@ -191,10 +233,42 @@ +@@ -191,10 +234,42 @@ private boolean func_145883_k() { @@ -126,7 +135,7 @@ return false; } else -@@ -203,6 +277,10 @@ +@@ -203,6 +278,10 @@ if (this.func_174919_a(iinventory, enumfacing)) { @@ -137,7 +146,7 @@ return false; } else -@@ -297,7 +375,10 @@ +@@ -297,7 +376,10 @@ public static boolean func_145891_a(IHopper p_145891_0_) { @@ -148,7 +157,7 @@ if (iinventory != null) { -@@ -305,6 +386,14 @@ +@@ -305,6 +387,14 @@ if (func_174917_b(iinventory, enumfacing)) { @@ -163,7 +172,7 @@ return false; } -@@ -333,6 +422,13 @@ +@@ -333,6 +423,13 @@ } } } @@ -177,7 +186,7 @@ } else { -@@ -352,6 +448,11 @@ +@@ -352,6 +449,11 @@ { ItemStack itemstack = p_174915_1_.func_70301_a(p_174915_2_); @@ -189,7 +198,7 @@ if (!itemstack.func_190926_b() && func_174921_b(p_174915_1_, itemstack, p_174915_2_, p_174915_3_)) { ItemStack itemstack1 = itemstack.func_77946_l(); -@@ -499,6 +600,14 @@ +@@ -499,6 +601,14 @@ return func_145893_b(this.func_145831_w(), this.func_96107_aA() + (double)enumfacing.func_82601_c(), this.func_96109_aB() + (double)enumfacing.func_96559_d(), this.func_96108_aC() + (double)enumfacing.func_82599_e()); } @@ -204,7 +213,7 @@ public static IInventory func_145884_b(IHopper p_145884_0_) { return func_145893_b(p_145884_0_.func_145831_w(), p_145884_0_.func_96107_aA(), p_145884_0_.func_96109_aB() + 1.0D, p_145884_0_.func_96108_aC()); -@@ -546,7 +655,7 @@ +@@ -546,7 +656,7 @@ return iinventory; } @@ -213,7 +222,20 @@ { if (p_145894_0_.func_77973_b() != p_145894_1_.func_77973_b()) { -@@ -611,4 +720,15 @@ +@@ -584,9 +694,11 @@ + private void func_145896_c(int p_145896_1_) + { + this.field_145901_j = p_145896_1_; ++ rsmm$logActive(); // RSMM + } + +- private boolean func_145888_j() ++ // RSMM - change access from private to public ++ public boolean func_145888_j() + { + return this.field_145901_j > 0; + } +@@ -611,4 +723,22 @@ { return this.field_145900_a; } @@ -227,5 +249,12 @@ + public void wakeUp(){ + this.pullSleeping = false; + this.pushSleeping = false; ++ } ++ ++ // RSMM ++ private void rsmm$logActive() { ++ if (CarpetSettings.redstoneMultimeter) { ++ WorldHelper.getMultimeter().logActive(field_145850_b, field_174879_c, !func_145888_j()); ++ } + } } diff --git a/patches/net/minecraft/world/World.java.patch b/patches/net/minecraft/world/World.java.patch index 8cfc805c..57b9beb9 100644 --- a/patches/net/minecraft/world/World.java.patch +++ b/patches/net/minecraft/world/World.java.patch @@ -311,9 +311,11 @@ int i = MathHelper.func_76128_c(p_191504_2_.field_72340_a) - 1; int j = MathHelper.func_76143_f(p_191504_2_.field_72336_d) + 1; int k = MathHelper.func_76128_c(p_191504_2_.field_72338_b) - 1; -@@ -1338,7 +1483,9 @@ +@@ -1337,8 +1482,11 @@ + public void func_72939_s() { this.field_72984_F.func_76320_a("entities"); ++ WorldHelper.startTickTask(TickTask.ENTITIES); // RSMM this.field_72984_F.func_76320_a("global"); + WorldHelper.startTickTask(TickTask.GLOBAL_ENTITIES); // RSMM @@ -321,7 +323,7 @@ for (int i = 0; i < this.field_73007_j.size(); ++i) { Entity entity = this.field_73007_j.get(i); -@@ -1346,6 +1493,7 @@ +@@ -1346,6 +1494,7 @@ try { ++entity.field_70173_aa; @@ -329,7 +331,7 @@ entity.func_70071_h_(); } catch (Throwable throwable2) -@@ -1370,6 +1518,9 @@ +@@ -1370,6 +1519,9 @@ this.field_73007_j.remove(i--); } } @@ -339,7 +341,7 @@ this.field_72984_F.func_76318_c("remove"); this.field_72996_f.removeAll(this.field_72997_g); -@@ -1393,11 +1544,14 @@ +@@ -1393,11 +1545,14 @@ this.field_72997_g.clear(); this.func_184147_l(); @@ -354,7 +356,7 @@ Entity entity3 = entity2.func_184187_bx(); if (entity3 != null) -@@ -1416,7 +1570,10 @@ +@@ -1416,7 +1571,10 @@ { try { @@ -366,7 +368,7 @@ } catch (Throwable throwable1) { -@@ -1437,31 +1594,51 @@ +@@ -1437,31 +1595,51 @@ if (entity2.field_70175_ag && this.func_175680_a(l1, i2, true)) { @@ -420,7 +422,7 @@ if (!tileentity.func_145837_r() && tileentity.func_145830_o()) { -@@ -1471,12 +1648,15 @@ +@@ -1471,12 +1649,15 @@ { try { @@ -442,7 +444,7 @@ } catch (Throwable throwable) { -@@ -1490,16 +1670,26 @@ +@@ -1490,16 +1671,26 @@ if (tileentity.func_145837_r()) { @@ -469,7 +471,7 @@ this.field_147481_N = false; this.field_72984_F.func_76318_c("pendingBlockEntities"); -@@ -1528,9 +1718,12 @@ +@@ -1528,9 +1719,13 @@ this.field_147484_a.clear(); } @@ -477,12 +479,13 @@ + CarpetProfiler.end_current_section(); this.field_72984_F.func_76319_b(); ++ WorldHelper.endTickTask(); // RSMM this.field_72984_F.func_76319_b(); + WorldHelper.endTickTask(); // RSMM } protected void func_184147_l() -@@ -1602,11 +1795,16 @@ +@@ -1602,11 +1797,16 @@ if (p_72866_1_.func_184218_aH()) { @@ -501,7 +504,7 @@ } } -@@ -1648,7 +1846,8 @@ +@@ -1648,7 +1848,8 @@ this.func_72964_e(p_72866_1_.field_70176_ah, p_72866_1_.field_70164_aj).func_76608_a(p_72866_1_, p_72866_1_.field_70162_ai); } @@ -511,7 +514,7 @@ { p_72866_1_.field_70175_ag = false; } -@@ -1670,7 +1869,11 @@ +@@ -1670,7 +1871,11 @@ } else { @@ -524,7 +527,7 @@ } } } -@@ -1689,7 +1892,7 @@ +@@ -1689,7 +1894,7 @@ { Entity entity4 = list.get(j2); @@ -533,7 +536,7 @@ { return false; } -@@ -2153,6 +2356,16 @@ +@@ -2153,6 +2358,16 @@ { this.field_72986_A.func_76090_f(this.field_73012_v.nextInt(168000) + 12000); } @@ -550,7 +553,7 @@ } else { -@@ -2177,6 +2390,16 @@ +@@ -2177,6 +2392,16 @@ { this.field_72986_A.func_76080_g(this.field_73012_v.nextInt(168000) + 12000); } @@ -567,7 +570,7 @@ } else { -@@ -2387,6 +2610,11 @@ +@@ -2387,6 +2612,11 @@ public boolean func_180500_c(EnumSkyBlock p_180500_1_, BlockPos p_180500_2_) { @@ -579,7 +582,7 @@ if (!this.func_175648_a(p_180500_2_, 17, false)) { return false; -@@ -2699,7 +2927,8 @@ +@@ -2699,7 +2929,8 @@ IBlockState iblockstate1 = this.func_180495_p(p_190527_2_); AxisAlignedBB axisalignedbb = p_190527_3_ ? null : p_190527_1_.func_176223_P().func_185890_d(this, p_190527_2_); @@ -589,7 +592,7 @@ { return false; } -@@ -3267,30 +3496,43 @@ +@@ -3267,30 +3498,43 @@ public void func_175666_e(BlockPos p_175666_1_, Block p_175666_2_) { @@ -648,7 +651,7 @@ } public DifficultyInstance func_175649_E(BlockPos p_175649_1_) -@@ -3361,4 +3603,120 @@ +@@ -3361,4 +3605,120 @@ { return null; } diff --git a/patches/net/minecraft/world/WorldServer.java.patch b/patches/net/minecraft/world/WorldServer.java.patch index 5e765253..4a3a2e18 100644 --- a/patches/net/minecraft/world/WorldServer.java.patch +++ b/patches/net/minecraft/world/WorldServer.java.patch @@ -33,14 +33,13 @@ import net.minecraft.village.VillageCollection; import net.minecraft.village.VillageSiege; import net.minecraft.world.biome.Biome; -@@ -77,17 +81,32 @@ +@@ -77,17 +81,31 @@ import net.minecraft.world.storage.WorldInfo; import net.minecraft.world.storage.WorldSavedDataCallableSave; import net.minecraft.world.storage.loot.LootTableManager; + +import redstone.multimeter.common.TickTask; +import redstone.multimeter.helper.WorldHelper; -+import redstone.multimeter.util.DimensionUtils; + import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -69,7 +68,7 @@ private final Map field_175741_N = Maps.newHashMap(); public boolean field_73058_d; private boolean field_73068_P; -@@ -99,6 +118,14 @@ +@@ -99,6 +117,14 @@ private int field_147489_T; private final List field_94579_S = Lists.newArrayList(); @@ -84,15 +83,15 @@ public WorldServer(MinecraftServer p_i45921_1_, ISaveHandler p_i45921_2_, WorldInfo p_i45921_3_, int p_i45921_4_, Profiler p_i45921_5_) { super(p_i45921_2_, p_i45921_3_, DimensionType.func_186069_a(p_i45921_4_).func_186070_d(), p_i45921_5_, false); -@@ -111,6 +138,7 @@ +@@ -111,6 +137,7 @@ this.func_72966_v(); this.func_72947_a(); this.func_175723_af().func_177725_a(p_i45921_1_.func_175580_aG()); -+ this.dimensionName = DimensionUtils.getId(this.field_73011_w.func_186058_p()).toString(); ++ this.dimensionName = this.field_73011_w.func_186058_p().func_186065_b(); } public World func_175643_b() -@@ -159,11 +187,30 @@ +@@ -159,11 +186,30 @@ this.func_175723_af().func_177750_a(this.field_72986_A.func_176137_E()); } @@ -118,12 +117,12 @@ + CarpetServer.limitITTCounter = 0; + } + -+ WorldHelper.startTickTask(TickTask.TICK_WORLD, dimensionName); // RSMM ++ WorldHelper.startTickTask(TickTask.TICK_LEVEL, dimensionName); // RSMM + super.func_72835_b(); if (this.func_72912_H().func_76093_s() && this.func_175659_aa() != EnumDifficulty.HARD) -@@ -184,15 +231,30 @@ +@@ -184,15 +230,30 @@ this.func_73053_d(); } @@ -154,7 +153,7 @@ int j = this.func_72967_a(1.0F); if (j != this.func_175657_ab()) -@@ -200,26 +262,109 @@ +@@ -200,26 +261,109 @@ this.func_175692_b(j); } @@ -172,7 +171,7 @@ + // RSMM start + if (tickTime) { -+ WorldHelper.getMultimeterServer().onOverworldTickTime(); ++ WorldHelper.getMultimeterServer().tickTime(this); + WorldHelper.endTickTask(); + } + // RSMM @@ -266,7 +265,7 @@ } @Nullable -@@ -255,13 +400,22 @@ +@@ -255,13 +399,22 @@ ++j; } } @@ -291,7 +290,7 @@ this.field_73068_P = false; for (EntityPlayer entityplayer : this.field_73010_i.stream().filter(EntityPlayer::func_70608_bn).collect(Collectors.toList())) -@@ -273,6 +427,8 @@ +@@ -273,6 +426,8 @@ { this.func_73051_P(); } @@ -300,7 +299,7 @@ } private void func_73051_P() -@@ -287,6 +443,28 @@ +@@ -287,6 +442,28 @@ { if (this.field_73068_P && !this.field_72995_K) { @@ -329,7 +328,7 @@ for (EntityPlayer entityplayer : this.field_73010_i) { if (!entityplayer.func_175149_v() && !entityplayer.func_71026_bH()) -@@ -303,7 +481,7 @@ +@@ -303,7 +480,7 @@ } } @@ -338,54 +337,71 @@ { return this.func_72863_F().func_73149_a(p_175680_1_, p_175680_2_); } -@@ -344,6 +522,7 @@ +@@ -331,12 +508,14 @@ + + if (this.field_72986_A.func_76067_t() == WorldType.field_180272_g) + { ++ WorldHelper.startTickTask(TickTask.TICK_CHUNKS); // RSMM + Iterator iterator1 = this.field_73063_M.func_187300_b(); + + while (iterator1.hasNext()) + { + ((Chunk)iterator1.next()).func_150804_b(false); + } ++ WorldHelper.endTickTask(); // RSMM + } + else + { +@@ -344,7 +523,9 @@ boolean flag = this.func_72896_J(); boolean flag1 = this.func_72911_I(); this.field_72984_F.func_76320_a("pollingChunks"); + boolean overworldIceOnly = !CarpetSettings.enableStableLCGNetherEnd || field_73011_w.func_186058_p().func_186068_a() == 0; // Rule to disable nether and end ice snow and lightning Carpet-XCOM ++ WorldHelper.startTickTask(TickTask.TICK_CHUNKS); // RSMM for (Iterator iterator = this.field_73063_M.func_187300_b(); iterator.hasNext(); this.field_72984_F.func_76319_b()) { -@@ -354,10 +533,18 @@ + this.field_72984_F.func_76320_a("getChunk"); +@@ -354,10 +535,18 @@ this.field_72984_F.func_76318_c("checkNextLight"); chunk.func_76594_o(); this.field_72984_F.func_76318_c("tickChunk"); -+ WorldHelper.startTickTask(false, TickTask.TICK_CHUNK); // RSMM ++ WorldHelper.startTickTask(TickTask.TICK_CHUNK); // RSMM chunk.func_150804_b(false); + if (!TickSpeed.process_entities) + { // skipping the rest of the block processing + this.field_72984_F.func_76319_b(); -+ WorldHelper.endTickTask(false); // RSMM ++ WorldHelper.endTickTask(); // RSMM + continue; + } this.field_72984_F.func_76318_c("thunder"); -+ WorldHelper.swapTickTask(false, TickTask.THUNDER); // RSMM ++ WorldHelper.swapTickTask(TickTask.THUNDER); // RSMM - if (flag && flag1 && this.field_73012_v.nextInt(100000) == 0) + if (overworldIceOnly && flag && flag1 && this.field_73012_v.nextInt(100000) == 0) { this.field_73005_l = this.field_73005_l * 3 + 1013904223; int l = this.field_73005_l >> 2; -@@ -384,8 +571,9 @@ +@@ -384,8 +573,9 @@ } this.field_72984_F.func_76318_c("iceandsnow"); -+ WorldHelper.swapTickTask(false, TickTask.PRECIPITATION); // RSMM ++ WorldHelper.swapTickTask(TickTask.PRECIPITATION); // RSMM - if (this.field_73012_v.nextInt(16) == 0) + if (overworldIceOnly && this.field_73012_v.nextInt(16) == 0) { this.field_73005_l = this.field_73005_l * 3 + 1013904223; int j2 = this.field_73005_l >> 2; -@@ -409,6 +597,7 @@ +@@ -409,6 +599,7 @@ } this.field_72984_F.func_76318_c("tickBlocks"); -+ WorldHelper.swapTickTask(false, TickTask.RANDOM_TICKS); // RSMM ++ WorldHelper.swapTickTask(TickTask.RANDOM_TICKS); // RSMM if (i > 0) { -@@ -429,7 +618,15 @@ +@@ -429,7 +620,15 @@ if (block.func_149653_t()) { @@ -402,15 +418,16 @@ } this.field_72984_F.func_76319_b(); -@@ -437,13 +634,15 @@ +@@ -437,13 +636,16 @@ } } } + -+ WorldHelper.endTickTask(false); // RSMM ++ WorldHelper.endTickTask(); // RSMM } this.field_72984_F.func_76319_b(); ++ WorldHelper.endTickTask(); // RSMM } } @@ -419,7 +436,7 @@ { BlockPos blockpos = this.func_175725_q(p_175736_1_); AxisAlignedBB axisalignedbb = (new AxisAlignedBB(blockpos, new BlockPos(blockpos.func_177958_n(), this.func_72800_K(), blockpos.func_177952_p()))).func_186662_g(3.0D); -@@ -472,13 +671,25 @@ +@@ -472,13 +674,25 @@ public boolean func_175691_a(BlockPos p_175691_1_, Block p_175691_2_) { @@ -447,7 +464,7 @@ return this.field_73064_N.contains(nextticklistentry); } -@@ -501,17 +712,29 @@ +@@ -501,17 +715,29 @@ if (iblockstate.func_185904_a() != Material.field_151579_a && iblockstate.func_177230_c() == p_175654_2_) { @@ -479,7 +496,14 @@ if (this.func_175667_e(p_175654_1_)) { -@@ -531,7 +754,13 @@ +@@ -525,13 +751,20 @@ + { + this.field_73064_N.add(nextticklistentry); + this.field_73065_O.add(nextticklistentry); ++ WorldHelper.onScheduledTick(this, p_175654_1_, p_175654_4_, true); // RSMM + } + } + } public void func_180497_b(BlockPos p_180497_1_, Block p_180497_2_, int p_180497_3_, int p_180497_4_) { @@ -494,7 +518,13 @@ nextticklistentry.func_82753_a(p_180497_4_); Material material = p_180497_2_.func_176223_P().func_185904_a(); -@@ -549,7 +778,8 @@ +@@ -544,12 +777,14 @@ + { + this.field_73064_N.add(nextticklistentry); + this.field_73065_O.add(nextticklistentry); ++ WorldHelper.onScheduledTick(this, p_180497_1_, p_180497_4_, true); // RSMM + } + } public void func_72939_s() { @@ -504,7 +534,7 @@ { if (this.field_80004_Q++ >= 300) { -@@ -567,6 +797,8 @@ +@@ -567,6 +802,8 @@ protected void func_184147_l() { @@ -513,7 +543,7 @@ super.func_184147_l(); this.field_72984_F.func_76318_c("players"); -@@ -621,6 +853,8 @@ +@@ -621,6 +858,8 @@ this.field_72984_F.func_76319_b(); } @@ -522,7 +552,7 @@ } public void func_82742_i() -@@ -644,9 +878,18 @@ +@@ -644,9 +883,18 @@ } else { @@ -543,7 +573,7 @@ } this.field_72984_F.func_76320_a("cleaning"); -@@ -677,12 +920,15 @@ +@@ -677,12 +925,15 @@ if (this.func_175707_a(nextticklistentry1.field_180282_a.func_177982_a(0, 0, 0), nextticklistentry1.field_180282_a.func_177982_a(0, 0, 0))) { @@ -555,11 +585,11 @@ { try { -+ WorldHelper.onScheduledTick(this, nextticklistentry1); // RSMM ++ WorldHelper.onScheduledTick(this, nextticklistentry1.field_180282_a, nextticklistentry1.field_82754_f, false); // RSMM iblockstate.func_177230_c().func_180650_b(this, nextticklistentry1.field_180282_a, iblockstate, this.field_73012_v); } catch (Throwable throwable) -@@ -699,6 +945,7 @@ +@@ -699,6 +950,7 @@ this.func_175684_a(nextticklistentry1.field_180282_a, nextticklistentry1.func_151351_a(), 0); } } @@ -567,7 +597,7 @@ this.field_72984_F.func_76319_b(); this.field_94579_S.clear(); -@@ -950,11 +1197,18 @@ +@@ -950,11 +1202,18 @@ chunkproviderserver.func_186027_a(p_73044_1_); @@ -587,7 +617,7 @@ } } } -@@ -1033,9 +1287,15 @@ +@@ -1033,9 +1292,15 @@ } else { @@ -603,7 +633,7 @@ return false; } -@@ -1055,6 +1315,7 @@ +@@ -1055,6 +1320,7 @@ this.field_175729_l.func_76038_a(p_72923_1_.func_145782_y(), p_72923_1_); this.field_175741_N.put(p_72923_1_.func_110124_au(), p_72923_1_); Entity[] aentity = p_72923_1_.func_70021_al(); @@ -611,11 +641,12 @@ if (aentity != null) { -@@ -1139,10 +1400,15 @@ +@@ -1139,10 +1405,16 @@ } this.field_147490_S[this.field_147489_T].add(blockeventdata); + if(CarpetSettings.blockEventSerializer) blockEventSerializer.func_76185_a(); ++ WorldHelper.onBlockEvent(this, p_175641_1_, p_175641_3_, true); // RSMM } private void func_147488_Z() @@ -627,7 +658,7 @@ while (!this.field_147490_S[this.field_147489_T].isEmpty()) { int i = this.field_147489_T; -@@ -1150,19 +1416,33 @@ +@@ -1150,19 +1422,33 @@ for (BlockEventData blockeventdata : this.field_147490_S[i]) { @@ -642,7 +673,7 @@ this.field_147490_S[i].clear(); + -+ WorldHelper.currentBlockEventDepth++; ++ WorldHelper.currentBlockEventDepth++; // RSMM } + // [CM] Piston ghost blocks fix + this.blockActionsProcessed = true; @@ -655,13 +686,13 @@ IBlockState iblockstate = this.func_180495_p(p_147485_1_.func_180328_a()); + // RSMM start + if (iblockstate.func_177230_c() == p_147485_1_.func_151337_f()) { -+ WorldHelper.onBlockEvent(this, p_147485_1_); ++ WorldHelper.onBlockEvent(this, p_147485_1_.func_180328_a(), p_147485_1_.func_151339_d(), false); + } + // RSMM end return iblockstate.func_177230_c() == p_147485_1_.func_151337_f() ? iblockstate.func_189547_a(this, p_147485_1_.func_180328_a(), p_147485_1_.func_151339_d(), p_147485_1_.func_151338_e()) : false; } -@@ -1173,6 +1453,8 @@ +@@ -1173,6 +1459,8 @@ protected void func_72979_l() { @@ -670,7 +701,7 @@ boolean flag = this.func_72896_J(); super.func_72979_l(); -@@ -1200,6 +1482,8 @@ +@@ -1200,6 +1488,8 @@ this.field_73061_a.func_184103_al().func_148540_a(new SPacketChangeGameState(7, this.field_73004_o)); this.field_73061_a.func_184103_al().func_148540_a(new SPacketChangeGameState(8, this.field_73017_q)); } @@ -679,7 +710,7 @@ } @Nullable -@@ -1299,4 +1583,19 @@ +@@ -1299,4 +1589,19 @@ { } } From efaa20dbcd1bc6cfc69031059e1666a9b20f156a Mon Sep 17 00:00:00 2001 From: TheBjoel2 <73243230+TheBjoel2@users.noreply.github.com> Date: Fri, 31 May 2024 00:29:03 +0000 Subject: [PATCH 46/46] fix bug where worldedit does block post processing on the wrong coords (#184) --- carpetmodSrc/carpet/worldedit/CarpetWorld.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/carpetmodSrc/carpet/worldedit/CarpetWorld.java b/carpetmodSrc/carpet/worldedit/CarpetWorld.java index afe82abe..2938aeaa 100644 --- a/carpetmodSrc/carpet/worldedit/CarpetWorld.java +++ b/carpetmodSrc/carpet/worldedit/CarpetWorld.java @@ -123,7 +123,7 @@ public boolean setBlock(Vector position, BaseBlock block, boolean notifyAndLight } IBlockState newState = Block.getBlockById(block.getId()).getStateFromMeta(block.getData()); - boolean successful = chunk.setBlockState(new BlockPos(x & 15, y, z & 15), newState) != null; + boolean successful = chunk.setBlockState(new BlockPos(x, y, z), newState) != null; // Create the TileEntity if (successful) { @@ -432,4 +432,4 @@ private WorldReferenceLostException(String message) { } } -} \ No newline at end of file +}