Merge branch 'mc1.15/security-patches' of https://github.com/pau101/Create into mc1.15/security-patches

This commit is contained in:
Snownee 2021-01-31 03:39:42 +08:00
commit 0c5e67e347
7 changed files with 186 additions and 127 deletions

View file

@ -0,0 +1,59 @@
package com.simibubi.create.content.schematics;
import com.mojang.datafixers.Dynamic;
import com.mojang.datafixers.types.DynamicOps;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IWorldReader;
import net.minecraft.world.World;
import net.minecraft.world.gen.feature.template.IStructureProcessorType;
import net.minecraft.world.gen.feature.template.PlacementSettings;
import net.minecraft.world.gen.feature.template.StructureProcessor;
import net.minecraft.world.gen.feature.template.Template;
import javax.annotation.Nullable;
import java.util.Optional;
public class SchematicProcessor extends StructureProcessor {
public static final SchematicProcessor INSTANCE = new SchematicProcessor();
@Nullable
@Override
public Template.BlockInfo process(IWorldReader world, BlockPos pos, Template.BlockInfo rawInfo, Template.BlockInfo info, PlacementSettings settings, @Nullable Template template) {
if (info.nbt != null) {
TileEntity te = info.state.createTileEntity(world);
if (te != null && te.onlyOpsCanSetNbt()) {
return new Template.BlockInfo(info.pos, info.state, null);
}
}
return info;
}
@Nullable
@Override
public Template.EntityInfo processEntity(IWorldReader world, BlockPos pos, Template.EntityInfo rawInfo, Template.EntityInfo info, PlacementSettings settings, Template template) {
return EntityType.readEntityType(info.nbt)
.flatMap(type -> {
if (world instanceof World) {
Entity e = type.create((World) world);
if (e != null && !e.ignoreItemEntityData()) {
return Optional.of(info);
}
}
return Optional.empty();
})
.orElse(null);
}
@Override
protected IStructureProcessorType getType() {
return dynamic -> INSTANCE;
}
@Override
protected <T> Dynamic<T> serialize0(DynamicOps<T> ops) {
return new Dynamic<>(ops, ops.emptyMap());
}
}

View file

@ -91,10 +91,8 @@ public class ServerSchematicLoader {
} }
public void handleNewUpload(ServerPlayerEntity player, String schematic, long size, BlockPos pos) { public void handleNewUpload(ServerPlayerEntity player, String schematic, long size, BlockPos pos) {
String playerPath = getSchematicPath() + "/" + player.getName() String playerPath = getSchematicPath() + "/" + player.getGameProfile().getName();
.getFormattedText(); String playerSchematicId = player.getGameProfile().getName() + "/" + schematic;
String playerSchematicId = player.getName()
.getFormattedText() + "/" + schematic;
FilesHelper.createFolderIfMissing(playerPath); FilesHelper.createFolderIfMissing(playerPath);
// Unsupported Format // Unsupported Format
@ -103,6 +101,14 @@ public class ServerSchematicLoader {
return; return;
} }
Path playerSchematicsPath = Paths.get(getSchematicPath(), player.getGameProfile().getName()).toAbsolutePath();
Path uploadPath = playerSchematicsPath.resolve(schematic).normalize();
if (!uploadPath.startsWith(playerSchematicsPath)) {
Create.logger.warn("Attempted Schematic Upload with directory escape: {}", playerSchematicId);
return;
}
// Too big // Too big
if (!validateSchematicSizeOnServer(player, size)) if (!validateSchematicSizeOnServer(player, size))
return; return;
@ -118,11 +124,15 @@ public class ServerSchematicLoader {
return; return;
// Delete schematic with same name // Delete schematic with same name
Files.deleteIfExists(Paths.get(getSchematicPath(), playerSchematicId)); Files.deleteIfExists(uploadPath);
// Too many Schematics // Too many Schematics
Stream<Path> list = Files.list(Paths.get(playerPath)); long count;
if (list.count() >= getConfig().maxSchematics.get()) { try (Stream<Path> list = Files.list(Paths.get(playerPath))) {
count = list.count();
}
if (count >= getConfig().maxSchematics.get()) {
Stream<Path> list2 = Files.list(Paths.get(playerPath)); Stream<Path> list2 = Files.list(Paths.get(playerPath));
Optional<Path> lastFilePath = list2.filter(f -> !Files.isDirectory(f)) Optional<Path> lastFilePath = list2.filter(f -> !Files.isDirectory(f))
.min(Comparator.comparingLong(f -> f.toFile() .min(Comparator.comparingLong(f -> f.toFile()
@ -132,11 +142,9 @@ public class ServerSchematicLoader {
Files.deleteIfExists(lastFilePath.get()); Files.deleteIfExists(lastFilePath.get());
} }
} }
list.close();
// Open Stream // Open Stream
OutputStream writer = OutputStream writer = Files.newOutputStream(uploadPath);
Files.newOutputStream(Paths.get(getSchematicPath(), playerSchematicId), StandardOpenOption.CREATE_NEW);
activeUploads.put(playerSchematicId, new SchematicUploadEntry(writer, size, player.getServerWorld(), pos)); activeUploads.put(playerSchematicId, new SchematicUploadEntry(writer, size, player.getServerWorld(), pos));
// Notify Tile Entity // Notify Tile Entity
@ -165,8 +173,7 @@ public class ServerSchematicLoader {
} }
public void handleWriteRequest(ServerPlayerEntity player, String schematic, byte[] data) { public void handleWriteRequest(ServerPlayerEntity player, String schematic, byte[] data) {
String playerSchematicId = player.getName() String playerSchematicId = player.getGameProfile().getName() + "/" + schematic;
.getFormattedText() + "/" + schematic;
if (activeUploads.containsKey(playerSchematicId)) { if (activeUploads.containsKey(playerSchematicId)) {
SchematicUploadEntry entry = activeUploads.get(playerSchematicId); SchematicUploadEntry entry = activeUploads.get(playerSchematicId);
@ -236,8 +243,7 @@ public class ServerSchematicLoader {
} }
public void handleFinishedUpload(ServerPlayerEntity player, String schematic) { public void handleFinishedUpload(ServerPlayerEntity player, String schematic) {
String playerSchematicId = player.getName() String playerSchematicId = player.getGameProfile().getName() + "/" + schematic;
.getFormattedText() + "/" + schematic;
if (activeUploads.containsKey(playerSchematicId)) { if (activeUploads.containsKey(playerSchematicId)) {
try { try {
@ -258,8 +264,7 @@ public class ServerSchematicLoader {
if (table == null) if (table == null)
return; return;
table.finishUpload(); table.finishUpload();
table.inventory.setStackInSlot(1, SchematicItem.create(schematic, player.getName() table.inventory.setStackInSlot(1, SchematicItem.create(schematic, player.getGameProfile().getName()));
.getFormattedText()));
} catch (IOException e) { } catch (IOException e) {
Create.logger.error("Exception Thrown when finishing Upload: " + playerSchematicId); Create.logger.error("Exception Thrown when finishing Upload: " + playerSchematicId);
@ -270,15 +275,21 @@ public class ServerSchematicLoader {
public void handleInstantSchematic(ServerPlayerEntity player, String schematic, World world, BlockPos pos, public void handleInstantSchematic(ServerPlayerEntity player, String schematic, World world, BlockPos pos,
BlockPos bounds) { BlockPos bounds) {
String playerPath = getSchematicPath() + "/" + player.getName() String playerPath = getSchematicPath() + "/" + player.getGameProfile().getName();
.getFormattedText(); String playerSchematicId = player.getGameProfile().getName() + "/" + schematic;
String playerSchematicId = player.getName()
.getFormattedText() + "/" + schematic;
FilesHelper.createFolderIfMissing(playerPath); FilesHelper.createFolderIfMissing(playerPath);
// Unsupported Format // Unsupported Format
if (!schematic.endsWith(".nbt")) { if (!schematic.endsWith(".nbt")) {
Create.logger.warn("Attempted Schematic Upload with non-supported Format: " + playerSchematicId); Create.logger.warn("Attempted Schematic Upload with non-supported Format: {}", playerSchematicId);
return;
}
Path schematicPath = Paths.get(getSchematicPath()).toAbsolutePath();
Path path = schematicPath.resolve(playerSchematicId).normalize();
if (!path.startsWith(schematicPath)) {
Create.logger.warn("Attempted Schematic Upload with directory escape: {}", playerSchematicId);
return; return;
} }
@ -288,38 +299,34 @@ public class ServerSchematicLoader {
try { try {
// Delete schematic with same name // Delete schematic with same name
Path path = Paths.get(getSchematicPath(), playerSchematicId);
Files.deleteIfExists(path); Files.deleteIfExists(path);
// Too many Schematics // Too many Schematics
Stream<Path> list = Files.list(Paths.get(playerPath)); long count;
if (list.count() >= getConfig().maxSchematics.get()) { try (Stream<Path> list = Files.list(Paths.get(playerPath))) {
count = list.count();
}
if (count >= getConfig().maxSchematics.get()) {
Stream<Path> list2 = Files.list(Paths.get(playerPath)); Stream<Path> list2 = Files.list(Paths.get(playerPath));
Optional<Path> lastFilePath = list2.filter(f -> !Files.isDirectory(f)) Optional<Path> lastFilePath = list2.filter(f -> !Files.isDirectory(f))
.min(Comparator.comparingLong(f -> f.toFile() .min(Comparator.comparingLong(f -> f.toFile()
.lastModified())); .lastModified()));
list2.close(); list2.close();
if (lastFilePath.isPresent()) if (lastFilePath.isPresent())
Files.deleteIfExists(lastFilePath.get()); Files.deleteIfExists(lastFilePath.get());
} }
list.close();
Template t = new Template(); Template t = new Template();
t.takeBlocksFromWorld(world, pos, bounds, true, Blocks.AIR); t.takeBlocksFromWorld(world, pos, bounds, true, Blocks.AIR);
OutputStream outputStream = null; try (OutputStream outputStream = Files.newOutputStream(path)) {
try {
outputStream = Files.newOutputStream(path, StandardOpenOption.CREATE);
CompoundNBT nbttagcompound = t.writeToNBT(new CompoundNBT()); CompoundNBT nbttagcompound = t.writeToNBT(new CompoundNBT());
CompressedStreamTools.writeCompressed(nbttagcompound, outputStream); CompressedStreamTools.writeCompressed(nbttagcompound, outputStream);
player.setHeldItem(Hand.MAIN_HAND, SchematicItem.create(schematic, player.getName() player.setHeldItem(Hand.MAIN_HAND, SchematicItem.create(schematic, player.getGameProfile().getName()));
.getFormattedText()));
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} finally {
if (outputStream != null)
IOUtils.closeQuietly(outputStream);
} }
} catch (IOException e) { } catch (IOException e) {
Create.logger.error("Exception Thrown in direct Schematic Upload: " + playerSchematicId); Create.logger.error("Exception Thrown in direct Schematic Upload: " + playerSchematicId);

View file

@ -422,8 +422,7 @@ public class SchematicannonScreen extends AbstractSimiContainerScreen<Schematica
} }
protected void sendOptionUpdate(Option option, boolean set) { protected void sendOptionUpdate(Option option, boolean set) {
AllPackets.channel.sendToServer(ConfigureSchematicannonPacket.setOption(container.getTileEntity() AllPackets.channel.sendToServer(new ConfigureSchematicannonPacket(option, set));
.getPos(), option, set));
} }
} }

View file

@ -1,17 +1,22 @@
package com.simibubi.create.content.schematics.item; package com.simibubi.create.content.schematics.item;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.nio.file.StandardOpenOption; import java.nio.file.StandardOpenOption;
import java.util.List; import java.util.List;
import java.util.zip.GZIPInputStream;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import org.apache.commons.io.IOUtils; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.simibubi.create.AllItems; import com.simibubi.create.AllItems;
import com.simibubi.create.content.schematics.SchematicProcessor;
import com.simibubi.create.content.schematics.client.SchematicEditScreen; import com.simibubi.create.content.schematics.client.SchematicEditScreen;
import com.simibubi.create.foundation.gui.ScreenOpener; import com.simibubi.create.foundation.gui.ScreenOpener;
import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.Lang;
@ -24,6 +29,7 @@ import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUseContext; import net.minecraft.item.ItemUseContext;
import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.CompressedStreamTools; import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTSizeTracker;
import net.minecraft.nbt.NBTUtil; import net.minecraft.nbt.NBTUtil;
import net.minecraft.util.ActionResult; import net.minecraft.util.ActionResult;
import net.minecraft.util.ActionResultType; import net.minecraft.util.ActionResultType;
@ -45,6 +51,8 @@ import net.minecraftforge.fml.common.thread.SidedThreadGroups;
public class SchematicItem extends Item { public class SchematicItem extends Item {
private static final Logger LOGGER = LogManager.getLogger();
public SchematicItem(Properties properties) { public SchematicItem(Properties properties) {
super(properties.maxStackSize(1)); super(properties.maxStackSize(1));
} }
@ -94,6 +102,7 @@ public class SchematicItem extends Item {
PlacementSettings settings = new PlacementSettings(); PlacementSettings settings = new PlacementSettings();
settings.setRotation(Rotation.valueOf(tag.getString("Rotation"))); settings.setRotation(Rotation.valueOf(tag.getString("Rotation")));
settings.setMirror(Mirror.valueOf(tag.getString("Mirror"))); settings.setMirror(Mirror.valueOf(tag.getString("Mirror")));
settings.addProcessor(SchematicProcessor.INSTANCE);
return settings; return settings;
} }
@ -104,25 +113,30 @@ public class SchematicItem extends Item {
String schematic = blueprint.getTag() String schematic = blueprint.getTag()
.getString("File"); .getString("File");
String filepath = ""; if (!schematic.endsWith(".nbt"))
return t;
if (Thread.currentThread() Path dir;
.getThreadGroup() == SidedThreadGroups.SERVER) Path file;
filepath = "schematics/uploaded/" + owner + "/" + schematic;
else
filepath = "schematics/" + schematic;
InputStream stream = null; if (Thread.currentThread().getThreadGroup() == SidedThreadGroups.SERVER) {
try { dir = Paths.get("schematics", "uploaded").toAbsolutePath();
stream = Files.newInputStream(Paths.get(filepath), StandardOpenOption.READ); file = Paths.get(owner, schematic);
CompoundNBT nbt = CompressedStreamTools.readCompressed(stream); } else {
dir = Paths.get("schematics").toAbsolutePath();
file = Paths.get(schematic);
}
Path path = dir.resolve(file).normalize();
if (!path.startsWith(dir))
return t;
try (DataInputStream stream = new DataInputStream(new BufferedInputStream(
new GZIPInputStream(Files.newInputStream(path, StandardOpenOption.READ))))) {
CompoundNBT nbt = CompressedStreamTools.read(stream, new NBTSizeTracker(0x20000000L));
t.read(nbt); t.read(nbt);
} catch (IOException e) { } catch (IOException e) {
// Player/Server doesnt have schematic saved LOGGER.warn("Failed to read schematic", e);
} finally {
if (stream != null)
IOUtils.closeQuietly(stream);
} }
return t; return t;

View file

@ -2,15 +2,13 @@ package com.simibubi.create.content.schematics.packet;
import java.util.function.Supplier; import java.util.function.Supplier;
import com.simibubi.create.content.schematics.block.SchematicannonContainer;
import com.simibubi.create.content.schematics.block.SchematicannonTileEntity; import com.simibubi.create.content.schematics.block.SchematicannonTileEntity;
import com.simibubi.create.content.schematics.block.SchematicannonTileEntity.State; import com.simibubi.create.content.schematics.block.SchematicannonTileEntity.State;
import com.simibubi.create.foundation.networking.SimplePacketBase; import com.simibubi.create.foundation.networking.SimplePacketBase;
import net.minecraft.entity.player.ServerPlayerEntity; import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.network.PacketBuffer; import net.minecraft.network.PacketBuffer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fml.network.NetworkEvent.Context; import net.minecraftforge.fml.network.NetworkEvent.Context;
public class ConfigureSchematicannonPacket extends SimplePacketBase { public class ConfigureSchematicannonPacket extends SimplePacketBase {
@ -21,45 +19,28 @@ public class ConfigureSchematicannonPacket extends SimplePacketBase {
private Option option; private Option option;
private boolean set; private boolean set;
private BlockPos pos;
public static ConfigureSchematicannonPacket setOption(BlockPos pos, Option option, boolean set) { public ConfigureSchematicannonPacket(Option option, boolean set) {
ConfigureSchematicannonPacket packet = new ConfigureSchematicannonPacket(pos); this.option = option;
packet.option = option; this.set = set;
packet.set = set;
return packet;
}
public ConfigureSchematicannonPacket(BlockPos pos) {
this.pos = pos;
} }
public ConfigureSchematicannonPacket(PacketBuffer buffer) { public ConfigureSchematicannonPacket(PacketBuffer buffer) {
pos = buffer.readBlockPos(); this(buffer.readEnumValue(Option.class), buffer.readBoolean());
option = Option.values()[buffer.readInt()];
set = buffer.readBoolean();
} }
public void write(PacketBuffer buffer) { public void write(PacketBuffer buffer) {
buffer.writeBlockPos(pos); buffer.writeEnumValue(option);
buffer.writeInt(option.ordinal());
buffer.writeBoolean(set); buffer.writeBoolean(set);
} }
public void handle(Supplier<Context> context) { public void handle(Supplier<Context> context) {
context.get().enqueueWork(() -> { context.get().enqueueWork(() -> {
ServerPlayerEntity player = context.get().getSender(); ServerPlayerEntity player = context.get().getSender();
if (player == null) if (player == null || !(player.openContainer instanceof SchematicannonContainer))
return;
World world = player.world;
if (world == null || !world.isBlockPresent(pos))
return; return;
TileEntity tileEntity = world.getTileEntity(pos); SchematicannonTileEntity te = ((SchematicannonContainer) player.openContainer).getTileEntity();
if (!(tileEntity instanceof SchematicannonTileEntity))
return;
SchematicannonTileEntity te = (SchematicannonTileEntity) tileEntity;
switch (option) { switch (option) {
case DONT_REPLACE: case DONT_REPLACE:
case REPLACE_ANY: case REPLACE_ANY:

View file

@ -38,47 +38,51 @@ import net.minecraft.network.PacketBuffer;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.fml.network.NetworkDirection;
import net.minecraftforge.fml.network.NetworkEvent.Context; import net.minecraftforge.fml.network.NetworkEvent.Context;
import net.minecraftforge.fml.network.NetworkRegistry; import net.minecraftforge.fml.network.NetworkRegistry;
import net.minecraftforge.fml.network.PacketDistributor; import net.minecraftforge.fml.network.PacketDistributor;
import net.minecraftforge.fml.network.PacketDistributor.TargetPoint; import net.minecraftforge.fml.network.PacketDistributor.TargetPoint;
import net.minecraftforge.fml.network.simple.SimpleChannel; import net.minecraftforge.fml.network.simple.SimpleChannel;
import static net.minecraftforge.fml.network.NetworkDirection.PLAY_TO_SERVER;
import static net.minecraftforge.fml.network.NetworkDirection.PLAY_TO_CLIENT;
public enum AllPackets { public enum AllPackets {
// Client to Server // Client to Server
NBT(NbtPacket.class, NbtPacket::new), NBT(NbtPacket.class, NbtPacket::new, PLAY_TO_SERVER),
CONFIGURE_SCHEMATICANNON(ConfigureSchematicannonPacket.class, ConfigureSchematicannonPacket::new), CONFIGURE_SCHEMATICANNON(ConfigureSchematicannonPacket.class, ConfigureSchematicannonPacket::new, PLAY_TO_SERVER),
CONFIGURE_FLEXCRATE(ConfigureFlexcratePacket.class, ConfigureFlexcratePacket::new), CONFIGURE_FLEXCRATE(ConfigureFlexcratePacket.class, ConfigureFlexcratePacket::new, PLAY_TO_SERVER),
CONFIGURE_STOCKSWITCH(ConfigureStockswitchPacket.class, ConfigureStockswitchPacket::new), CONFIGURE_STOCKSWITCH(ConfigureStockswitchPacket.class, ConfigureStockswitchPacket::new, PLAY_TO_SERVER),
CONFIGURE_SEQUENCER(ConfigureSequencedGearshiftPacket.class, ConfigureSequencedGearshiftPacket::new), CONFIGURE_SEQUENCER(ConfigureSequencedGearshiftPacket.class, ConfigureSequencedGearshiftPacket::new, PLAY_TO_SERVER),
PLACE_SCHEMATIC(SchematicPlacePacket.class, SchematicPlacePacket::new), PLACE_SCHEMATIC(SchematicPlacePacket.class, SchematicPlacePacket::new, PLAY_TO_SERVER),
UPLOAD_SCHEMATIC(SchematicUploadPacket.class, SchematicUploadPacket::new), UPLOAD_SCHEMATIC(SchematicUploadPacket.class, SchematicUploadPacket::new, PLAY_TO_SERVER),
CONFIGURE_FILTER(FilterScreenPacket.class, FilterScreenPacket::new), CONFIGURE_FILTER(FilterScreenPacket.class, FilterScreenPacket::new, PLAY_TO_SERVER),
CONFIGURE_FILTERING_AMOUNT(FilteringCountUpdatePacket.class, FilteringCountUpdatePacket::new), CONFIGURE_FILTERING_AMOUNT(FilteringCountUpdatePacket.class, FilteringCountUpdatePacket::new, PLAY_TO_SERVER),
CONFIGURE_SCROLLABLE(ScrollValueUpdatePacket.class, ScrollValueUpdatePacket::new), CONFIGURE_SCROLLABLE(ScrollValueUpdatePacket.class, ScrollValueUpdatePacket::new, PLAY_TO_SERVER),
EXTENDO_INTERACT(ExtendoGripInteractionPacket.class, ExtendoGripInteractionPacket::new), EXTENDO_INTERACT(ExtendoGripInteractionPacket.class, ExtendoGripInteractionPacket::new, PLAY_TO_SERVER),
CONTRAPTION_INTERACT(ContraptionInteractionPacket.class, ContraptionInteractionPacket::new), CONTRAPTION_INTERACT(ContraptionInteractionPacket.class, ContraptionInteractionPacket::new, PLAY_TO_SERVER),
CLIENT_MOTION(ClientMotionPacket.class, ClientMotionPacket::new), CLIENT_MOTION(ClientMotionPacket.class, ClientMotionPacket::new, PLAY_TO_SERVER),
PLACE_ARM(ArmPlacementPacket.class, ArmPlacementPacket::new), PLACE_ARM(ArmPlacementPacket.class, ArmPlacementPacket::new, PLAY_TO_SERVER),
MINECART_COUPLING_CREATION(CouplingCreationPacket.class, CouplingCreationPacket::new), MINECART_COUPLING_CREATION(CouplingCreationPacket.class, CouplingCreationPacket::new, PLAY_TO_SERVER),
INSTANT_SCHEMATIC(InstantSchematicPacket.class, InstantSchematicPacket::new), INSTANT_SCHEMATIC(InstantSchematicPacket.class, InstantSchematicPacket::new, PLAY_TO_SERVER),
SYNC_SCHEMATIC(SchematicSyncPacket.class, SchematicSyncPacket::new), SYNC_SCHEMATIC(SchematicSyncPacket.class, SchematicSyncPacket::new, PLAY_TO_SERVER),
LEFT_CLICK(LeftClickPacket.class, LeftClickPacket::new), LEFT_CLICK(LeftClickPacket.class, LeftClickPacket::new, PLAY_TO_SERVER),
// Server to Client // Server to Client
SYMMETRY_EFFECT(SymmetryEffectPacket.class, SymmetryEffectPacket::new), SYMMETRY_EFFECT(SymmetryEffectPacket.class, SymmetryEffectPacket::new, PLAY_TO_CLIENT),
SERVER_SPEED(ServerSpeedProvider.Packet.class, ServerSpeedProvider.Packet::new), SERVER_SPEED(ServerSpeedProvider.Packet.class, ServerSpeedProvider.Packet::new, PLAY_TO_CLIENT),
BEAM_EFFECT(ZapperBeamPacket.class, ZapperBeamPacket::new), BEAM_EFFECT(ZapperBeamPacket.class, ZapperBeamPacket::new, PLAY_TO_CLIENT),
CONFIGURE_CONFIG(ConfigureConfigPacket.class, ConfigureConfigPacket::new), CONFIGURE_CONFIG(ConfigureConfigPacket.class, ConfigureConfigPacket::new, PLAY_TO_CLIENT),
CONTRAPTION_STALL(ContraptionStallPacket.class, ContraptionStallPacket::new), CONTRAPTION_STALL(ContraptionStallPacket.class, ContraptionStallPacket::new, PLAY_TO_CLIENT),
CONTRAPTION_DISASSEMBLE(ContraptionDisassemblyPacket.class, ContraptionDisassemblyPacket::new), CONTRAPTION_DISASSEMBLE(ContraptionDisassemblyPacket.class, ContraptionDisassemblyPacket::new, PLAY_TO_CLIENT),
GLUE_EFFECT(GlueEffectPacket.class, GlueEffectPacket::new), GLUE_EFFECT(GlueEffectPacket.class, GlueEffectPacket::new, PLAY_TO_CLIENT),
CONTRAPTION_SEAT_MAPPING(ContraptionSeatMappingPacket.class, ContraptionSeatMappingPacket::new), CONTRAPTION_SEAT_MAPPING(ContraptionSeatMappingPacket.class, ContraptionSeatMappingPacket::new, PLAY_TO_CLIENT),
LIMBSWING_UPDATE(LimbSwingUpdatePacket.class, LimbSwingUpdatePacket::new), LIMBSWING_UPDATE(LimbSwingUpdatePacket.class, LimbSwingUpdatePacket::new, PLAY_TO_CLIENT),
MINECART_CONTROLLER(MinecartControllerUpdatePacket.class, MinecartControllerUpdatePacket::new), MINECART_CONTROLLER(MinecartControllerUpdatePacket.class, MinecartControllerUpdatePacket::new, PLAY_TO_CLIENT),
FLUID_SPLASH(FluidSplashPacket.class, FluidSplashPacket::new), FLUID_SPLASH(FluidSplashPacket.class, FluidSplashPacket::new, PLAY_TO_CLIENT),
CONTRAPTION_FLUID(ContraptionFluidPacket.class, ContraptionFluidPacket::new), CONTRAPTION_FLUID(ContraptionFluidPacket.class, ContraptionFluidPacket::new, PLAY_TO_CLIENT),
; ;
@ -88,14 +92,14 @@ public enum AllPackets {
private LoadedPacket<?> packet; private LoadedPacket<?> packet;
private <T extends SimplePacketBase> AllPackets(Class<T> type, Function<PacketBuffer, T> factory) { private <T extends SimplePacketBase> AllPackets(Class<T> type, Function<PacketBuffer, T> factory, NetworkDirection direction) {
packet = new LoadedPacket<>(type, factory); packet = new LoadedPacket<>(type, factory, direction);
} }
public static void registerPackets() { public static void registerPackets() {
channel = NetworkRegistry.ChannelBuilder.named(CHANNEL_NAME) channel = NetworkRegistry.ChannelBuilder.named(CHANNEL_NAME)
.serverAcceptedVersions(s -> true) .serverAcceptedVersions(NETWORK_VERSION::equals)
.clientAcceptedVersions(s -> true) .clientAcceptedVersions(NETWORK_VERSION::equals)
.networkProtocolVersion(() -> NETWORK_VERSION) .networkProtocolVersion(() -> NETWORK_VERSION)
.simpleChannel(); .simpleChannel();
for (AllPackets packet : values()) for (AllPackets packet : values())
@ -115,16 +119,18 @@ public enum AllPackets {
Function<PacketBuffer, T> decoder; Function<PacketBuffer, T> decoder;
BiConsumer<T, Supplier<Context>> handler; BiConsumer<T, Supplier<Context>> handler;
Class<T> type; Class<T> type;
NetworkDirection direction;
private LoadedPacket(Class<T> type, Function<PacketBuffer, T> factory) { private LoadedPacket(Class<T> type, Function<PacketBuffer, T> factory, NetworkDirection direction) {
encoder = T::write; encoder = T::write;
decoder = factory; decoder = factory;
handler = T::handle; handler = T::handle;
this.type = type; this.type = type;
this.direction = direction;
} }
private void register() { private void register() {
channel.messageBuilder(type, index++) channel.messageBuilder(type, index++, direction)
.encoder(encoder) .encoder(encoder)
.decoder(decoder) .decoder(decoder)
.consumer(handler) .consumer(handler)

View file

@ -21,17 +21,10 @@ import net.minecraft.nbt.CompoundNBT;
public class FilesHelper { public class FilesHelper {
public static void createFolderIfMissing(String name) { public static void createFolderIfMissing(String name) {
Path path = Paths.get(name); try {
if (path.getParent() != null) Files.createDirectories(Paths.get(name));
createFolderIfMissing(path.getParent() } catch (IOException e) {
.toString()); Create.logger.warn("Could not create Folder: {}", name);
if (!Files.isDirectory(path)) {
try {
Files.createDirectory(path);
} catch (IOException e) {
Create.logger.warn("Could not create Folder: " + name);
}
} }
} }