diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 1f662f350..87ecbf481 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -30,7 +30,7 @@ jobs: if: endswith(github.ref_name, 'master') && github.ref_protected && github.ref_type == 'branch' runs-on: ubuntu-latest env: - APPVEYOR_BUILD_VERSION: '3.8.1' + APPVEYOR_BUILD_VERSION: '3.8.2' CURSETOKEN: ${{ secrets.CURSETOKEN }} steps: - uses: actions/checkout@v3 diff --git a/changelog.md b/changelog.md index 597e38329..c606fd9dc 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,19 @@ # Changelog +## [1.16.5 - 3.8.2] +* feat: added config option to block shunting path with active redstone input +* feat/fix: pathway can't be set with active subsidiary +* fix: signal name not loaded in signalbox +* fix: semaphore signal animation +* fix: issue with wrong signal data in SignalController +* fix: client signal property (network) loading +* fix: mast_lamps glowing lamps and ks signal mast model +* fix: hl subsidiary config +* fix: minor fixes +* ref/fix: client-server signalsystem mismatch +* ref: new signalbox networking system +* ref: client animation update trigger + ## [1.16.5 - 3.8.1] * fix: issues with loading NBT data of signal box * fix: issues with setting pathway with a overlap nearby diff --git a/src/main/java/com/troblecodings/signals/animation/SignalAnimationHandler.java b/src/main/java/com/troblecodings/signals/animation/SignalAnimationHandler.java index 6b002abf6..85e1743e2 100644 --- a/src/main/java/com/troblecodings/signals/animation/SignalAnimationHandler.java +++ b/src/main/java/com/troblecodings/signals/animation/SignalAnimationHandler.java @@ -94,11 +94,12 @@ private void updateAnimation(final ModelTranslation translation, final float tic translation.setUpNewTranslation(animation.getModelTranslation()); } - public void updateStates(final Map properties, final boolean firstLoad) { + public void updateStates(final Map properties, + final boolean loadToFinalState) { if (properties == null || properties.isEmpty()) return; final ModelInfoWrapper wrapper = new ModelInfoWrapper(properties); - if (firstLoad) { + if (loadToFinalState) { updateToFinalizedAnimations(wrapper); } else { updateAnimations(wrapper); diff --git a/src/main/java/com/troblecodings/signals/blocks/Signal.java b/src/main/java/com/troblecodings/signals/blocks/Signal.java index be3f9dc61..eca8a7c28 100644 --- a/src/main/java/com/troblecodings/signals/blocks/Signal.java +++ b/src/main/java/com/troblecodings/signals/blocks/Signal.java @@ -43,6 +43,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.state.EnumProperty; import net.minecraft.state.StateContainer.Builder; +import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ActionResultType; import net.minecraft.util.Direction; import net.minecraft.util.Hand; @@ -68,7 +69,7 @@ public class Signal extends BasicBlock { }; public static final Map SIGNALS = new HashMap<>(); - public static final List SIGNAL_IDS = new ArrayList<>(); + public static final Map SIGNAL_IDS = new HashMap<>(); public static final EnumProperty ANGEL = EnumProperty.create("angel", SignalAngel.class); public static final SEProperty CUSTOMNAME = new SEProperty("customname", JsonEnum.BOOLEAN, @@ -80,13 +81,17 @@ public class Signal extends BasicBlock { private List signalProperties; private final Map signalPropertiesToInt = new HashMap<>(); - public Signal(final SignalProperties prop) { + public Signal(final SignalProperties prop, final String name) { super(Properties.of(Material.STONE).noOcclusion() .lightLevel(u -> ConfigHandler.GENERAL.lightEmission.get()) .isRedstoneConductor((_u1, _u2, _u3) -> false)); this.prop = prop; - this.id = SIGNAL_IDS.size(); - SIGNAL_IDS.add(this); + this.id = name.hashCode(); + if (SIGNAL_IDS.containsKey(this.id)) { + OpenSignalsMain.exitMinecraftWithMessage("Hash [" + this.id + "] already exists for [" + + name + "]! Need to choose an other name!"); + } + SIGNAL_IDS.put(this.id, this); registerDefaultState(defaultBlockState().setValue(ANGEL, SignalAngel.ANGEL0)); prop.placementtool.addSignal(this); for (int i = 0; i < signalProperties.size(); i++) { @@ -140,14 +145,14 @@ public int getIDFromProperty(final SEProperty property) { @Override public VoxelShape getShape(final BlockState state, final IBlockReader source, final BlockPos pos, final ISelectionContext context) { - final SignalTileEntity te = (SignalTileEntity) source.getBlockEntity(pos); - if (te == null) + final TileEntity te = source.getBlockEntity(pos); + if (te == null || (!te instanceof SignalTileEntity)) return VoxelShapes.block(); final World world = te.getLevel(); final SignalStateInfo info = new SignalStateInfo(world, pos, this); final Map properties = world.isClientSide ? ClientSignalStateHandler.getClientStates(new StateInfo(info.world, info.pos)) - : te.getProperties(); + : ((SignalTileEntity) te).getProperties(); return VoxelShapes .create(VoxelShapes.block().bounds().expandTowards(0, getHeight(properties), 0)); } diff --git a/src/main/java/com/troblecodings/signals/blocks/SignalBox.java b/src/main/java/com/troblecodings/signals/blocks/SignalBox.java index 23f22ddb5..30170d841 100644 --- a/src/main/java/com/troblecodings/signals/blocks/SignalBox.java +++ b/src/main/java/com/troblecodings/signals/blocks/SignalBox.java @@ -60,16 +60,19 @@ public Optional getSupplierWrapperName() { public void playerWillDestroy(final World world, final BlockPos pos, final BlockState state, final PlayerEntity player) { if (!world.isClientSide) { - ((SignalBoxTileEntity) world.getBlockEntity(pos)).unlink(); + final SignalBoxTileEntity tile = (SignalBoxTileEntity) world.getBlockEntity(pos); + tile.unlink(); + tile.getSignalBoxGrid().resetAllPathways(); SignalBoxHandler.removeSignalBox(new StateInfo(world, pos)); SignalBoxHandler.onPosRemove(new StateInfo(world, pos)); } super.playerWillDestroy(world, pos, state, player); } - + @Override public void onPlace(final BlockState state, final World world, final BlockPos pos, final BlockState state2, final boolean bool) { SignalBoxHandler.relinkAllRedstoneIOs(new StateInfo(world, pos)); } + } \ No newline at end of file diff --git a/src/main/java/com/troblecodings/signals/config/ConfigHandler.java b/src/main/java/com/troblecodings/signals/config/ConfigHandler.java index 24ecfa9af..75562cb22 100644 --- a/src/main/java/com/troblecodings/signals/config/ConfigHandler.java +++ b/src/main/java/com/troblecodings/signals/config/ConfigHandler.java @@ -25,6 +25,7 @@ public static class General { public final ConfigValue lightEmission; public final ConfigValue debugMode; public final ConfigValue canAddRSPathToSaver; + public final ConfigValue canInputBlockShuntingPath; public General(final ForgeConfigSpec.Builder builder) { String desc; @@ -38,9 +39,13 @@ public General(final ForgeConfigSpec.Builder builder) { desc = "Toggle debug mode."; debugMode = builder.comment(desc).define("Debug Mode", false); - desc = "ShuntingPaths can be added to PathwaySaver."; + desc = "ShuntingPaths can be added to PathwaySaver. Default: false"; canAddRSPathToSaver = builder.comment(desc).define("canAddRSPathToSaver", false); + desc = "Choose wether a blocking input can prevent setting a shunting path. Default: false"; + canInputBlockShuntingPath = + builder.comment(desc).define("canInputBlockShuntingPath", false); + builder.pop(); } diff --git a/src/main/java/com/troblecodings/signals/contentpacks/SignalSystemParser.java b/src/main/java/com/troblecodings/signals/contentpacks/SignalSystemParser.java index 83a6b4bb7..f7be58ba3 100644 --- a/src/main/java/com/troblecodings/signals/contentpacks/SignalSystemParser.java +++ b/src/main/java/com/troblecodings/signals/contentpacks/SignalSystemParser.java @@ -21,8 +21,8 @@ public class SignalSystemParser { private static final Gson GSON = new Gson(); public static Map getAllSignals() { - final List> systems = OpenSignalsMain.contentPacks - .getFiles("signalsystems"); + final List> systems = + OpenSignalsMain.contentPacks.getFiles("signalsystems"); final Map properties = new HashMap<>(); systems.forEach(entry -> { properties.put(entry.getKey(), @@ -55,6 +55,6 @@ public Signal createSignalSystem(final String fileName) { Signal.nextConsumer = list -> { list.addAll(properties); }; - return new Signal(systemProperties.build(info)); + return new Signal(systemProperties.build(info), name); } } \ No newline at end of file diff --git a/src/main/java/com/troblecodings/signals/core/NetworkBufferWrappers.java b/src/main/java/com/troblecodings/signals/core/NetworkBufferWrappers.java index a7b956f76..2eea73cbf 100644 --- a/src/main/java/com/troblecodings/signals/core/NetworkBufferWrappers.java +++ b/src/main/java/com/troblecodings/signals/core/NetworkBufferWrappers.java @@ -7,6 +7,7 @@ import com.troblecodings.core.WriteBuffer; import com.troblecodings.signals.SEProperty; import com.troblecodings.signals.blocks.Signal; +import com.troblecodings.signals.network.SignalBoxNetworkHandler; import com.troblecodings.signals.signalbox.Point; import com.troblecodings.signals.signalbox.SignalBoxNode; import com.troblecodings.signals.signalbox.entrys.PathEntryType; @@ -33,14 +34,17 @@ public static BiConsumer getSEPropertyConsumer(final Si public static final Function> PATHENTRYTYPE_FUNCTION = buf -> PathEntryType.ALL_ENTRIES .get(buf.getByteToUnsignedInt()); - public static Function getSignalBoxNodeFunc() { + public static Function getSignalBoxNodeFunc( + final SignalBoxNetworkHandler network) { return buffer -> getSignalBoxNodeFunc( - ReadBuffer.getINetworkSaveableFunction(Point.class).apply(buffer)).apply(buffer); + ReadBuffer.getINetworkSaveableFunction(Point.class).apply(buffer), network) + .apply(buffer); } - public static Function getSignalBoxNodeFunc(final Point point) { + public static Function getSignalBoxNodeFunc(final Point point, + final SignalBoxNetworkHandler network) { return buffer -> { - final SignalBoxNode node = new SignalBoxNode(point); + final SignalBoxNode node = new SignalBoxNode(point, network); node.readNetwork(buffer); return node; }; diff --git a/src/main/java/com/troblecodings/signals/enums/PathwayRequestResult.java b/src/main/java/com/troblecodings/signals/enums/PathwayRequestResult.java index bda816030..46108cb0d 100644 --- a/src/main/java/com/troblecodings/signals/enums/PathwayRequestResult.java +++ b/src/main/java/com/troblecodings/signals/enums/PathwayRequestResult.java @@ -9,12 +9,14 @@ public class PathwayRequestResult { - private static final Map MODE_TO_RESULT = new HashMap<>(); + private static final Map MODE_TO_RESULT = + new HashMap<>(); static { for (final PathwayRequestMode mode : PathwayRequestMode.values()) { - if (mode == PathwayRequestMode.PASS) + if (mode == PathwayRequestMode.PASS) { continue; + } MODE_TO_RESULT.put(mode, new PathwayRequestResult(mode)); } } @@ -74,9 +76,7 @@ public int hashCode() { public boolean equals(final Object obj) { if (this == obj) return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) + if ((obj == null) || (getClass() != obj.getClass())) return false; final PathwayRequestResult other = (PathwayRequestResult) obj; return Objects.equals(data, other.data) && mode == other.mode; @@ -87,7 +87,8 @@ public enum PathwayRequestMode { NO_EQUAL_PATH_TYPE("no_equal_path_type"), NOT_IN_GRID("not_in_grid"), ALREADY_USED("already_used"), OVERSTEPPING("overstepping"), INPUT_BLOCKING("input_blocking"), NO_PATH("no_path"), - NO_INTERSIGNALBOX_SELECTED("no_intersignalbox_selected"), PASS("pass"); + NO_INTERSIGNALBOX_SELECTED("no_intersignalbox_selected"), + SUBISIDIARY_ENABLED("subsidiary_enabled"), PASS("pass"); private final String name; diff --git a/src/main/java/com/troblecodings/signals/enums/SignalBoxNetwork.java b/src/main/java/com/troblecodings/signals/enums/SignalBoxNetwork.java deleted file mode 100644 index ec8e3080c..000000000 --- a/src/main/java/com/troblecodings/signals/enums/SignalBoxNetwork.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.troblecodings.signals.enums; - -import com.troblecodings.core.ReadBuffer; - -public enum SignalBoxNetwork { - - SEND_POS_ENTRY, SEND_INT_ENTRY, REMOVE_ENTRY, REQUEST_PW, REMOVE_POS, RESET_PW, SEND_GRID, - SEND_PW_UPDATE, RESET_ALL_PW, SEND_CHANGED_MODES, REQUEST_LINKED_POS, PW_REQUEST_RESPONSE, - REQUEST_SUBSIDIARY, SEND_ZS2_ENTRY, UPDATE_RS_OUTPUT, OUTPUT_UPDATE, RESET_SUBSIDIARY, - SET_AUTO_POINT, SEND_NAME, SEND_BOOL_ENTRY, ADDED_TO_SAVER, REMOVE_SAVEDPW, SEND_POINT_ENTRY, - SET_SIGNAL_STATE, SEND_COUNTER, SEND_TRAIN_NUMBER, RESET_ALL_SIGNALS, SEND_POSIDENT_LIST, - SEND_CONNECTED_TRAINNUMBERS, SEND_ZS6_ENTRY, SEND_DEBUG_POINTS; - - public static SignalBoxNetwork of(final ReadBuffer buffer) { - return values()[buffer.getByteToUnsignedInt()]; - } -} \ No newline at end of file diff --git a/src/main/java/com/troblecodings/signals/guis/ContainerPlacementtool.java b/src/main/java/com/troblecodings/signals/guis/ContainerPlacementtool.java index 7fb778945..078772626 100644 --- a/src/main/java/com/troblecodings/signals/guis/ContainerPlacementtool.java +++ b/src/main/java/com/troblecodings/signals/guis/ContainerPlacementtool.java @@ -4,6 +4,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; import com.troblecodings.core.NBTWrapper; import com.troblecodings.core.ReadBuffer; @@ -42,20 +43,25 @@ private void sendItemProperties(final PlayerEntity player) { final NBTWrapper wrapper = NBTWrapper.getOrCreateWrapper(stack); final int signalID = wrapper.getInteger(Placementtool.BLOCK_TYPE_ID); signal = tool.getObjFromID(signalID); - final List properites = signal.getProperties(); + final List properties = signal.getProperties().stream() + .filter(property -> wrapper.contains(property.getName())) + .collect(Collectors.toList()); + final WriteBuffer buffer = new WriteBuffer(); final List propertiesToSend = new ArrayList<>(); - for (int i = 0; i < properites.size(); i++) { - final SEProperty property = properites.get(i); + for (int i = 0; i < properties.size(); i++) { + final SEProperty property = properties.get(i); if (wrapper.contains(property.getName())) { propertiesToSend.add((byte) i); final String value = wrapper.getString(property.getName()); propertiesToSend.add((byte) property.getParent().getIDFromValue(value)); } } - final WriteBuffer buffer = new WriteBuffer(); buffer.putInt(signalID); - buffer.putByte((byte) propertiesToSend.size()); - propertiesToSend.forEach(buffer::putByte); + buffer.putList(properties, (buf, prop) -> { + buffer.putByte((byte) signal.getIDFromProperty(prop)); + final String value = wrapper.getString(prop.getName()); + buffer.putByte((byte) prop.getParent().getIDFromValue(value)); + }); final String signalName = wrapper.getString(SIGNAL_NAME); buffer.putString(signalName); OpenSignalsMain.network.sendTo(player, buffer); @@ -93,16 +99,16 @@ public void deserializeServer(final ReadBuffer buffer) { @Override public void deserializeClient(final ReadBuffer buffer) { signalID = buffer.getInt(); - final int size = buffer.getByteToUnsignedInt(); final Placementtool tool = (Placementtool) info.player.getMainHandItem().getItem(); final Signal signal = tool.getObjFromID(signalID); final List signalProperties = signal.getProperties(); properties.clear(); - for (int i = 0; i < size / 2; i++) { - final SEProperty property = signalProperties.get(buffer.getByteToUnsignedInt()); - final int value = buffer.getByteToUnsignedInt(); - properties.put(property, value); - } + buffer.getList(buf -> { + final SEProperty prop = signalProperties.get(buf.getByteToUnsignedInt()); + final int value = buf.getByteToUnsignedInt(); + properties.put(prop, value); + return prop; + }); signalName = buffer.getString(); signalProperties.forEach(property -> { if (!properties.containsKey(property)) { diff --git a/src/main/java/com/troblecodings/signals/guis/ContainerSignalBox.java b/src/main/java/com/troblecodings/signals/guis/ContainerSignalBox.java index b4ce1e00c..7e0c420f1 100644 --- a/src/main/java/com/troblecodings/signals/guis/ContainerSignalBox.java +++ b/src/main/java/com/troblecodings/signals/guis/ContainerSignalBox.java @@ -4,8 +4,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.concurrent.atomic.AtomicReference; +import java.util.function.BiConsumer; import java.util.function.Consumer; import com.google.common.collect.Maps; @@ -20,74 +20,77 @@ import com.troblecodings.signals.blocks.Signal; import com.troblecodings.signals.contentpacks.SubsidiarySignalParser; import com.troblecodings.signals.core.ModeIdentifier; -import com.troblecodings.signals.core.PosIdentifier; import com.troblecodings.signals.core.StateInfo; import com.troblecodings.signals.core.SubsidiaryState; -import com.troblecodings.signals.core.TrainNumber; -import com.troblecodings.signals.enums.EnumGuiMode; import com.troblecodings.signals.enums.LinkType; import com.troblecodings.signals.enums.PathType; -import com.troblecodings.signals.enums.PathwayRequestResult; import com.troblecodings.signals.enums.PathwayRequestResult.PathwayRequestMode; -import com.troblecodings.signals.enums.SignalBoxNetwork; import com.troblecodings.signals.handler.ClientSignalStateHandler; import com.troblecodings.signals.handler.SignalBoxHandler; import com.troblecodings.signals.handler.SignalStateInfo; +import com.troblecodings.signals.network.SignalBoxNetworkHandler; import com.troblecodings.signals.properties.PredicatedPropertyBase.ConfigProperty; +import com.troblecodings.signals.signalbox.MainSignalIdentifier; import com.troblecodings.signals.signalbox.MainSignalIdentifier.SignalState; import com.troblecodings.signals.signalbox.ModeSet; import com.troblecodings.signals.signalbox.Point; import com.troblecodings.signals.signalbox.SignalBoxGrid; import com.troblecodings.signals.signalbox.SignalBoxNode; -import com.troblecodings.signals.signalbox.SignalBoxPathway; import com.troblecodings.signals.signalbox.SignalBoxTileEntity; import com.troblecodings.signals.signalbox.config.ResetInfo; import com.troblecodings.signals.signalbox.config.SignalConfig; import com.troblecodings.signals.signalbox.entrys.PathEntryType; -import com.troblecodings.signals.signalbox.entrys.PathOptionEntry; import com.troblecodings.signals.tileentitys.IChunkLoadable; import net.minecraft.block.Block; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.util.Rotation; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.server.ServerWorld; public class ContainerSignalBox extends ContainerBase implements UIClientSync, IChunkLoadable { + public SignalBoxGrid grid; + public SignalBoxTileEntity tile; + protected final Map> greenSignals = new HashMap<>(); protected final Map> possibleSubsidiaries = new HashMap<>(); protected final Map> enabledSubsidiaryTypes = new HashMap<>(); protected final Map, PathType> nextPathways = new HashMap<>(); protected final Map> validInConnections = new HashMap<>(); - protected SignalBoxGrid grid; + private final Map posForType = new HashMap<>(); - private SignalBoxTileEntity tile; - private Consumer infoUpdates; - private Consumer> colorUpdates; - private Runnable counterUpdater; - private Consumer> trainNumberUpdater; - private Consumer> debugPoints; + private SignalBoxNetworkHandler network = new SignalBoxNetworkHandler(); + private PlayerEntity player; protected Consumer updateSignalState = (node) -> { }; + protected Consumer infoUpdates = (label) -> { + }; + protected BiConsumer> nodeUpdate = (node, entry) -> { + }; + protected Runnable counterUpdater = () -> { + }; + protected Consumer> debugPoints = (list) -> { + }; public ContainerSignalBox(final GuiInfo info) { super(info); if (!info.world.isClientSide) { this.tile = info.getTile(); + this.grid = tile.getSignalBoxGrid(); tile.add(this); } } @Override public void sendAllDataToRemote() { - this.grid = tile.getSignalBoxGrid(); - final WriteBuffer buffer = new WriteBuffer(); - buffer.putEnumValue(SignalBoxNetwork.SEND_GRID); - buffer.putBlockPos(info.pos); - grid.writeNetwork(buffer); + initializeNetwork(); + sendInitialisationPacket(); + network.sendAll(); + } + + public void addAdditionalInitialisationData(final WriteBuffer buffer) { final StateInfo identifier = new StateInfo(info.world, tile.getBlockPos()); final Map positions = SignalBoxHandler.getAllLinkedPos(identifier); final Map, PathType> nextPathways = grid.getNextPathways(); @@ -112,104 +115,49 @@ public void sendAllDataToRemote() { }); buffer.putMap(validInConnections, WriteBuffer.BLOCKPOS_CONSUMER, (b, list) -> b.putISaveableList(list)); - OpenSignalsMain.network.sendTo(info.player, buffer); + } + + public void readAdditionalInitialisationData(final ReadBuffer buffer) { + posForType.clear(); + nextPathways.clear(); + validInConnections.clear(); + posForType.putAll(buffer.getMap(ReadBuffer.BLOCKPOS_FUNCTION, + ReadBuffer.getEnumFunction(LinkType.class))); + nextPathways.putAll(buffer.getMap((b -> Maps.immutableEntry(Point.of(b), Point.of(b))), + b -> b.getEnumValue(PathType.class))); + validInConnections.putAll(buffer.getMap(ReadBuffer.BLOCKPOS_FUNCTION, + b -> b.getList(ReadBuffer.getINetworkSaveableFunction(Point.class)))); + grid.getNodes().forEach(node -> { + final Map subsidiares = + new HashMap<>(node.getSubsidiaryStates()); + if (!subsidiares.isEmpty()) { + enabledSubsidiaryTypes.put(node.getPoint(), subsidiares); + } + }); + update(); + loadPossibleSubsidiaires(); + } + + private void sendInitialisationPacket() { + final WriteBuffer buffer = new WriteBuffer(); + buffer.putBlockPos(info.pos); + OpenSignalsMain.network.sendTo(getPlayer(), buffer); + } + + public SignalBoxNetworkHandler getNetwork() { + return network; } @Override public void deserializeClient(final ReadBuffer buffer) { - final SignalBoxNetwork mode = buffer.getEnumValue(SignalBoxNetwork.class); - switch (mode) { - case SEND_GRID: { - final BlockPos pos = buffer.getBlockPos(); - if (this.tile == null) { - this.tile = (SignalBoxTileEntity) info.world.getBlockEntity(pos); - } - grid = tile.getSignalBoxGrid(); - grid.readNetwork(buffer); - posForType.clear(); - nextPathways.clear(); - validInConnections.clear(); - posForType.putAll(buffer.getMap(ReadBuffer.BLOCKPOS_FUNCTION, - ReadBuffer.getEnumFunction(LinkType.class))); - nextPathways - .putAll(buffer.getMap((b -> Maps.immutableEntry(Point.of(b), Point.of(b))), - b -> b.getEnumValue(PathType.class))); - validInConnections.putAll(buffer.getMap(ReadBuffer.BLOCKPOS_FUNCTION, - b -> b.getList(ReadBuffer.getINetworkSaveableFunction(Point.class)))); - grid.getNodes().forEach(node -> { - final Map subsidiares = - new HashMap<>(node.getSubsidiaryStates()); - if (!subsidiares.isEmpty()) { - enabledSubsidiaryTypes.put(node.getPoint(), subsidiares); - } - }); - update(); - loadPossibleSubsidiaires(); - break; - } - case SEND_PW_UPDATE: { - colorUpdates.accept(grid.readUpdateNetwork(buffer, true)); - break; - } - case PW_REQUEST_RESPONSE: { - final PathwayRequestMode result = buffer.getEnumValue(PathwayRequestMode.class); - infoUpdates.accept(I18Wrapper.format("error." + result.getName())); - break; - } - case ADDED_TO_SAVER: { - final PathwayRequestMode result = buffer.getEnumValue(PathwayRequestMode.class); - final Point start = Point.of(buffer); - final Point end = Point.of(buffer); - final PathType type = buffer.getEnumValue(PathType.class); - nextPathways.put(Maps.immutableEntry(start, end), type); - infoUpdates.accept(I18Wrapper.format("error." + result.getName()) + " - " - + I18Wrapper.format("info.pathwaysaver")); - break; - } - case OUTPUT_UPDATE: { - final Point point = Point.of(buffer); - final ModeSet modeSet = ModeSet.of(buffer); - final boolean state = buffer.getBoolean(); - final SignalBoxNode node = grid.getNode(point); - if (state) { - node.addManuellOutput(modeSet); - } else { - node.removeManuellOutput(modeSet); - } - break; - } - case REMOVE_SAVEDPW: { - final Point start = Point.of(buffer); - final Point end = Point.of(buffer); - nextPathways.remove(Maps.immutableEntry(start, end)); - break; - } - case SET_SIGNAL_STATE: { - grid.readUpdateNetwork(buffer, false).forEach(updateSignalState); - break; - } - case SEND_COUNTER: { - grid.setCounter(buffer.getInt()); - counterUpdater.run(); - break; - } - case SEND_TRAIN_NUMBER: { - trainNumberUpdater.accept(buffer.getList(buf -> { - final Point point = Point.of(buffer); - final SignalBoxNode node = grid.getNode(point); - node.readNetwork(buffer); - return node; - })); - break; - } - case SEND_DEBUG_POINTS: { - debugPoints.accept( - buffer.getList(ReadBuffer.getINetworkSaveableFunction(Point.class))); - break; - } - default: - break; + if (tile == null) { + final BlockPos pos = buffer.getBlockPos(); + this.tile = (SignalBoxTileEntity) info.world.getBlockEntity(pos); + this.grid = tile.getSignalBoxGrid(); + initializeNetwork(); + return; } + network.desirializeBuffer(buffer); } @Override @@ -217,195 +165,50 @@ public void deserializeServer(final ReadBuffer buffer) { if (grid == null) { grid = tile.getSignalBoxGrid(); } - final SignalBoxNetwork mode = buffer.getEnumValue(SignalBoxNetwork.class); - switch (mode) { - case SEND_INT_ENTRY: { - deserializeEntry(buffer, buffer.getByteToUnsignedInt()); - break; - } - case REMOVE_ENTRY: { - final Point point = Point.of(buffer); - final EnumGuiMode guiMode = EnumGuiMode.of(buffer); - final Rotation rotation = deserializeRotation(buffer); - final PathEntryType entryType = - PathEntryType.ALL_ENTRIES.get(buffer.getByteToUnsignedInt()); - final ModeSet modeSet = new ModeSet(guiMode, rotation); - grid.getNode(point).getOption(modeSet) - .ifPresent(entry -> entry.removeEntry(entryType)); - break; - } - case SEND_POS_ENTRY: { - deserializeEntry(buffer, buffer.getBlockPos()); - break; - } - case SEND_ZS2_ENTRY: { - deserializeEntry(buffer, buffer.getByte()); - break; - } - case SEND_ZS6_ENTRY: { - deserializeEntry(buffer, buffer.getTcBoolean()); - break; - } - case REMOVE_POS: { - final BlockPos pos = buffer.getBlockPos(); - SignalBoxHandler.unlinkPosFromSignalBox( - new StateInfo(tile.getLevel(), tile.getBlockPos()), pos); - break; - } - case RESET_PW: { - final Point point = Point.of(buffer); - final SignalBoxPathway pw = grid.getPathwayByStartPoint(point); - final boolean isShuntingPath = pw != null ? pw.isShuntingPath() : false; - if (grid.resetPathway(point) && !isShuntingPath) { - grid.count(); - final WriteBuffer sucess = new WriteBuffer(); - sucess.putEnumValue(SignalBoxNetwork.SEND_COUNTER); - sucess.putInt(grid.getCurrentCounter()); - OpenSignalsMain.network.sendTo(info.player, sucess); - } - break; - } - case REQUEST_PW: { - final Point start = Point.of(buffer); - final Point end = Point.of(buffer); - final PathType type = buffer.getEnumValue(PathType.class); - final PathwayRequestResult request = grid.requestWay(start, end, type); - if (!request.wasSuccesfull()) { - final SignalBoxNode endNode = grid.getNode(end); - if (request.canBeAddedToSaver(type) && !endNode.containsOutConnection() - && grid.addNextPathway(start, end, type)) { - final WriteBuffer sucess = new WriteBuffer(); - sucess.putEnumValue(SignalBoxNetwork.ADDED_TO_SAVER); - sucess.putEnumValue(request.getMode()); - start.writeNetwork(sucess); - end.writeNetwork(sucess); - sucess.putEnumValue(type); - OpenSignalsMain.network.sendTo(info.player, sucess); - break; - } - final WriteBuffer error = new WriteBuffer(); - error.putEnumValue(SignalBoxNetwork.PW_REQUEST_RESPONSE); - error.putEnumValue(request.getMode()); - OpenSignalsMain.network.sendTo(info.player, error); - } - break; - } - case RESET_ALL_PW: { - grid.resetAllPathways(); - break; - } - case SEND_CHANGED_MODES: { - grid.readUpdateNetwork(buffer, true); - break; - } - case REQUEST_SUBSIDIARY: { - final SubsidiaryState entry = SubsidiaryState.of(buffer); - final Point point = Point.of(buffer); - final ModeSet modeSet = ModeSet.of(buffer); - final boolean enable = buffer.getBoolean(); - updateServerSubsidiary(point, modeSet, entry, enable); - break; - } - case UPDATE_RS_OUTPUT: { - final Point point = Point.of(buffer); - final ModeSet modeSet = ModeSet.of(buffer); - final boolean state = buffer.getBoolean(); - final BlockPos pos = grid.updateManuellRSOutput(point, modeSet, state); - if (pos != null) { - SignalBoxHandler.updateRedstoneOutput(new StateInfo(info.world, pos), state); - final WriteBuffer sucess = new WriteBuffer(); - sucess.putEnumValue(SignalBoxNetwork.OUTPUT_UPDATE); - point.writeNetwork(sucess); - modeSet.writeNetwork(sucess); - sucess.putBoolean(state); - OpenSignalsMain.network.sendTo(info.player, sucess); - } - break; - } - case SET_AUTO_POINT: { - final Point point = Point.of(buffer); - final boolean state = buffer.getBoolean(); - final SignalBoxNode node = tile.getSignalBoxGrid().getNode(point); - node.setAutoPoint(state); - grid.updatePathwayToAutomatic(point); - break; - } - case SEND_NAME: { - final Point point = Point.of(buffer); - final SignalBoxNode node = tile.getSignalBoxGrid().getNode(point); - node.setCustomText(buffer.getString()); - break; - } - case SEND_BOOL_ENTRY: { - deserializeEntry(buffer, buffer.getBoolean()); - break; - } - case REMOVE_SAVEDPW: { - final Point start = Point.of(buffer); - final Point end = Point.of(buffer); - grid.removeNextPathway(start, end); - break; - } - case SEND_POINT_ENTRY: { - deserializeEntry(buffer, Point.of(buffer)); - break; - } - case SEND_COUNTER: { - grid.setCounter(buffer.getInt()); - break; - } - case SEND_TRAIN_NUMBER: { - final Point point = Point.of(buffer); - final TrainNumber number = TrainNumber.of(buffer); - grid.updateTrainNumber(point, number); - break; - } - case RESET_ALL_SIGNALS: { - grid.resetAllSignals(); - break; - } - case SEND_POSIDENT_LIST: { - deserializeEntry(buffer, buffer - .getList(ReadBuffer.getINetworkSaveableFunction(PosIdentifier.class))); - break; - } - case SEND_CONNECTED_TRAINNUMBERS: { - deserializeEntry(buffer, ModeIdentifier.of(buffer)); - break; - } - case SET_SIGNAL_STATE: { - final Point point = Point.of(buffer); - final EnumGuiMode guiMode = EnumGuiMode.of(buffer); - final Rotation rotation = deserializeRotation(buffer); - final SignalState state = buffer.getEnumValue(SignalState.class); - grid.getNodeChecked(point) - .ifPresent(node -> node.updateState(new ModeSet(guiMode, rotation), state)); - } - default: - break; - } + network.desirializeBuffer(buffer); tile.setChanged(); } - @SuppressWarnings("unchecked") - private void deserializeEntry(final ReadBuffer buffer, final T type) { - final Point point = Point.of(buffer); - final EnumGuiMode guiMode = EnumGuiMode.of(buffer); - final Rotation rotation = deserializeRotation(buffer); - final PathEntryType entryType = - (PathEntryType) PathEntryType.ALL_ENTRIES.get(buffer.getByteToUnsignedInt()); - final SignalBoxNode node = tile.getSignalBoxGrid().getNode(point); - final ModeSet modeSet = new ModeSet(guiMode, rotation); - final Optional option = node.getOption(modeSet); - if (option.isPresent()) { - option.get().setEntry(entryType, type); - } else { - node.addAndSetEntry(modeSet, entryType, type); - } + public void handlePathwayRequestResponse(final PathwayRequestMode result) { + if (!isClientSide()) + return; + infoUpdates.accept(I18Wrapper.format("error." + result.getName())); + } + + public void handleAddSavedPathway(final Point p1, final Point p2, final PathType type, + final PathwayRequestMode result) { + if (!isClientSide()) + return; + nextPathways.put(Maps.immutableEntry(p1, p2), type); + infoUpdates.accept(I18Wrapper.format("error." + result.getName()) + " - " + + I18Wrapper.format("info.pathwaysaver")); + } + + public void handleRemoveSavedPathway(final Point p1, final Point p2) { + nextPathways.remove(Maps.immutableEntry(p1, p2)); + } + + public void handleDebugPoints(final List debugPoints) { + this.debugPoints.accept(debugPoints); } - private static Rotation deserializeRotation(final ReadBuffer buffer) { - return Rotation.values()[buffer.getByteToUnsignedInt()]; + public void handleCounterUpdate() { + counterUpdater.run(); + } + + public void handleNodeUpdate(final SignalBoxNode node, final PathEntryType type) { + nodeUpdate.accept(node, type); + } + + public void handleSignalStateUpdate(final SignalBoxNode node) { + updateSignalState.accept(node); + } + + private void initializeNetwork() { + if (grid == null) + return; + grid.setUpNetwork(this); + this.network.setUpNetwork(this); } private void loadPossibleSubsidiaires() { @@ -436,47 +239,65 @@ private void loadPossibleSubsidiaires() { } - protected void updateClientSubsidiary(final Point point, final ModeSet mode, + protected void updateClientSubsidiary(final SignalBoxNode node, final ModeSet mode, final SubsidiaryState state, final boolean enable) { final Map map = - enabledSubsidiaryTypes.computeIfAbsent(point, (_u) -> new HashMap<>()); + enabledSubsidiaryTypes.computeIfAbsent(node.getPoint(), (_u) -> new HashMap<>()); if (enable) { map.put(mode, state); + node.setSubsidiaryState(mode, state); } else { map.remove(mode); + node.removeSubsidiaryState(mode); if (map.isEmpty()) { - enabledSubsidiaryTypes.remove(point); + enabledSubsidiaryTypes.remove(node.getPoint()); } } } - private void updateServerSubsidiary(final Point point, final ModeSet mode, - final SubsidiaryState state, final boolean enable) { + public void updateServerSubsidiary(final ModeIdentifier ident, final SubsidiaryState state, + final boolean enable) { + if (isClientSide()) + return; final World world = tile.getLevel(); - grid.getNodeChecked(point).ifPresent((node) -> { - node.getOption(mode) + grid.getNodeChecked(ident.point).ifPresent((node) -> { + node.getOption(ident.mode) .ifPresent(entry -> entry.getEntry(PathEntryType.SIGNAL).ifPresent(pos -> { final Signal signal = SignalBoxHandler .getSignal(new StateInfo(world, tile.getBlockPos()), pos); final SignalStateInfo info = new SignalStateInfo(world, pos, signal); if (enable) { SignalConfig.loadSubsidiary(info, state); - node.updateState(mode, + node.setSubsidiaryState(ident.mode, state); + node.updateStateNoNetwork(ident.mode, SignalState.combine(state.getSubsidiaryShowType())); - node.setSubsidiaryState(mode, state); } else { SignalConfig.reset(new ResetInfo(info)); - node.updateState(mode, SignalState.RED); - node.removeSubsidiaryState(mode); + node.removeSubsidiaryState(ident.mode); + node.updateStateNoNetwork(ident.mode, SignalState.RED); } })); }); } + public SignalBoxTileEntity getTile() { + return this.tile; + } + + public SignalBoxGrid getGrid() { + return this.grid; + } + + public boolean isClientSide() { + return this.info.world.isClientSide; + } + @Override public void removed(final PlayerEntity playerIn) { super.removed(playerIn); - if (this.tile != null) { + if (this.grid != null) { + grid.removeNetwork(); + network.removeNetwork(); this.tile.remove(this); } } @@ -494,30 +315,10 @@ public Map getPositionForTypes() { public boolean stillValid(final PlayerEntity playerIn) { if (tile.isBlocked() && !tile.isValid(playerIn)) return false; - if (this.info.player == null) { - this.info.player = playerIn; + if (this.player == null) { + this.player = playerIn; this.tile.add(this); } return true; } - - protected void setInfoConsumer(final Consumer consumer) { - this.infoUpdates = consumer; - } - - protected void setColorUpdater(final Consumer> updater) { - this.colorUpdates = updater; - } - - protected void setConuterUpdater(final Runnable run) { - this.counterUpdater = run; - } - - protected void setTrainNumberUpdater(final Consumer> updater) { - this.trainNumberUpdater = updater; - } - - protected void setDebugPointUpdater(final Consumer> points) { - this.debugPoints = points; - } } \ No newline at end of file diff --git a/src/main/java/com/troblecodings/signals/guis/ContainerSignalController.java b/src/main/java/com/troblecodings/signals/guis/ContainerSignalController.java index 35850596c..0243615ab 100644 --- a/src/main/java/com/troblecodings/signals/guis/ContainerSignalController.java +++ b/src/main/java/com/troblecodings/signals/guis/ContainerSignalController.java @@ -62,6 +62,7 @@ private void sendProperitesToClient() { linkedPos = controllerEntity.getLinkedPosition(); if (linkedPos == null) return; + controllerEntity.validateData(); currentSignal = controllerEntity.getLinkedSignal(); final SignalStateInfo stateInfo = new SignalStateInfo(info.world, linkedPos, getSignal()); final Map properties = SignalStateHandler.getStates(stateInfo); diff --git a/src/main/java/com/troblecodings/signals/guis/GuiSignalBox.java b/src/main/java/com/troblecodings/signals/guis/GuiSignalBox.java index 091580762..6b282d74d 100644 --- a/src/main/java/com/troblecodings/signals/guis/GuiSignalBox.java +++ b/src/main/java/com/troblecodings/signals/guis/GuiSignalBox.java @@ -13,8 +13,6 @@ import java.util.stream.Collectors; import com.troblecodings.core.I18Wrapper; -import com.troblecodings.core.TCBoolean; -import com.troblecodings.core.WriteBuffer; import com.troblecodings.guilib.ecs.DrawUtil.DisableIntegerable; import com.troblecodings.guilib.ecs.DrawUtil.EnumIntegerable; import com.troblecodings.guilib.ecs.DrawUtil.SizeIntegerables; @@ -37,7 +35,6 @@ import com.troblecodings.signals.OpenSignalsMain; import com.troblecodings.signals.config.ConfigHandler; import com.troblecodings.signals.core.ModeIdentifier; -import com.troblecodings.signals.core.PosIdentifier; import com.troblecodings.signals.core.StateInfo; import com.troblecodings.signals.core.SubsidiaryHolder; import com.troblecodings.signals.core.SubsidiaryState; @@ -48,15 +45,14 @@ import com.troblecodings.signals.enums.PathType; import com.troblecodings.signals.enums.PathwayRequestResult.PathwayRequestMode; import com.troblecodings.signals.enums.ShowTypes; -import com.troblecodings.signals.enums.SignalBoxNetwork; import com.troblecodings.signals.enums.SignalBoxPage; import com.troblecodings.signals.guis.UISignalBoxRendering.BoxEntity; import com.troblecodings.signals.guis.UISignalBoxRendering.SelectionType; import com.troblecodings.signals.guis.UISignalBoxRendering.SignalBoxConsumer; import com.troblecodings.signals.handler.ClientNameHandler; +import com.troblecodings.signals.network.SignalBoxNetworkHandler; import com.troblecodings.signals.signalbox.MainSignalIdentifier.SignalState; import com.troblecodings.signals.signalbox.ModeSet; -import com.troblecodings.signals.signalbox.Path; import com.troblecodings.signals.signalbox.Point; import com.troblecodings.signals.signalbox.SignalBoxNode; import com.troblecodings.signals.signalbox.SignalBoxUtil; @@ -89,13 +85,11 @@ public class GuiSignalBox extends GuiBase { private final UIEntity lowerEntity = new UIEntity(); private final UIEntity bottomEntity = new UIEntity(); protected final ContainerSignalBox container; + protected final SignalBoxNetworkHandler network; private SignalBoxPage page = SignalBoxPage.OPERATION; private SignalBoxNode lastTile = null; private UIEntity mainButton; - private final GuiInfo info; - private final Map changedModes = new HashMap<>(); private UIEntity splitter = new UIEntity(); - private boolean allPacketsRecived = false; private SidePanel helpPage; protected UISignalBoxRendering rendering; protected final Map enabledSubsidiaries = new HashMap<>(); @@ -104,19 +98,27 @@ public class GuiSignalBox extends GuiBase { public GuiSignalBox(final GuiInfo info) { super(info); this.container = (ContainerSignalBox) info.base; - container.setInfoConsumer(this::infoUpdate); - container.setColorUpdater(this::applyColorChanges); - container.setConuterUpdater(this::updateCounter); - container.setTrainNumberUpdater(this::updateTrainNumbers); + this.network = container.getNetwork(); + container.infoUpdates = this::infoUpdate; + container.counterUpdater = this::updateCounter; + container.nodeUpdate = this::updateNode; container.updateSignalState = this::updateSignalState; - this.info = info; } public SignalBoxPage getPage() { return page; } - private void updateSignalState(final SignalBoxNode node) { + private void updateNode(final SignalBoxNode node, final PathEntryType type) { + if (type.equals(PathEntryType.PATHUSAGE)) { + updateColor(node); + } + if (type.equals(PathEntryType.TRAINNUMBER)) { + updateTrainNumbers(node); + } + } + + protected void updateSignalState(final SignalBoxNode node) { node.forEach((mode) -> { checkForSubsidiary(node, mode); rendering.updateSignalState(node.getPoint(), mode, node.getState(mode)); @@ -124,36 +126,32 @@ private void updateSignalState(final SignalBoxNode node) { } private void checkForSubsidiary(final SignalBoxNode node, final ModeSet mode) { - final Map subsidiary = - container.enabledSubsidiaryTypes.getOrDefault(node.getPoint(), new HashMap<>()); - final SubsidiaryState state = subsidiary.get(mode); + final SubsidiaryState state = node.getSubsidiaryState(mode); if (state != null) { node.updateState(mode, SignalState.combine(state.getSubsidiaryShowType())); } } - public void infoUpdate(final String errorString) { + protected void infoUpdate(final String errorString) { final UIToolTip tooltip = new UIToolTip(errorString, true); lowerEntity.add(tooltip); executor.schedule(() -> lowerEntity.remove(tooltip), 3, TimeUnit.SECONDS); return; } - private void updateTrainNumbers(final List nodes) { - nodes.forEach(node -> { - node.iterator().forEachRemaining(modeSet -> { - if (!(modeSet.mode == EnumGuiMode.TRAIN_NUMBER)) - return; - node.getOption(modeSet).ifPresent(option -> { - final TrainNumber number = - option.getEntry(PathEntryType.TRAINNUMBER).orElse(TrainNumber.DEFAULT); - final ModeIdentifier modeIdent = new ModeIdentifier(node.getPoint(), modeSet); - if (number.trainNumber.isEmpty()) { - rendering.removeTrainNumber(modeIdent); - } else { - rendering.putTrainNumber(modeIdent, number.trainNumber); - } - }); + private void updateTrainNumbers(final SignalBoxNode node) { + node.iterator().forEachRemaining(modeSet -> { + if (!(modeSet.mode == EnumGuiMode.TRAIN_NUMBER)) + return; + node.getOption(modeSet).ifPresent(option -> { + final TrainNumber number = + option.getEntry(PathEntryType.TRAINNUMBER).orElse(TrainNumber.DEFAULT); + final ModeIdentifier modeIdent = new ModeIdentifier(node.getPoint(), modeSet); + if (number.trainNumber.isEmpty()) { + rendering.removeTrainNumber(modeIdent); + } else { + rendering.putTrainNumber(modeIdent, number.trainNumber); + } }); }); } @@ -186,13 +184,11 @@ protected void selectLink(final UIEntity parent, final SignalBoxNode node, if (!option.getEntry(entryType).isPresent()) return; option.removeEntry(entryType); - removeEntryFromServer(node, mode, rotation, entryType); } else { final Optional pathEntry = option.getEntry(entryType); if (pathEntry.isPresent() && pathEntry.get().equals(setPos)) return; option.setEntry(entryType, setPos); - sendPosEntryToServer(setPos, node, mode, rotation, entryType); } }, option.getEntry(entryType).map(entry -> positions.indexOf(entry)).orElse(-1)); parent.add(blockSelect); @@ -210,12 +206,12 @@ public static String getSignalInfo(final BlockPos signalPos, final LinkType type protected void disableSubsidiary(final BlockPos pos, final SubsidiaryHolder holder) { final SubsidiaryState state = holder.entry; - sendSubsidiaryRequest(state, holder.point, holder.modeSet, false); - container.updateClientSubsidiary(holder.point, holder.modeSet, state, false); + network.sendSubsidiary(new ModeIdentifier(holder.point, holder.modeSet), state, false); enabledSubsidiaries.remove(pos); helpPage.helpUsageMode(null); container.grid.getNodeChecked(holder.point).ifPresent(node -> { + container.updateClientSubsidiary(node, holder.modeSet, state, false); node.removeSubsidiaryState(holder.modeSet); node.updateState(holder.modeSet, SignalState.RED); rendering.updateSignalState(holder.point, holder.modeSet, SignalState.RED); @@ -237,7 +233,6 @@ private void updateTileWithMode(final UIMenu menu, final UISignalBoxRendering re } else { rendering.addMode(point, modeSet); } - this.changedModes.put(point, container.grid.getNode(point)); } private void tileNormal(final UISignalBoxRendering rendering, final Point tile, @@ -278,11 +273,18 @@ private void tileNormal(final UISignalBoxRendering rendering, final Point tile, private void checkForMultiplePathTypes(final SignalBoxNode start, final SignalBoxNode end) { final List possibleTypes = start.getPossibleTypes(end); + for (final ModeSet mode : start.getModes().keySet()) { + if (start.getSubsidiaryState(mode) != null) { + infoUpdate(I18Wrapper + .format("error." + PathwayRequestMode.SUBISIDIARY_ENABLED.getName())); + return; + } + } if (possibleTypes.isEmpty()) { infoUpdate( I18Wrapper.format("error." + PathwayRequestMode.NO_EQUAL_PATH_TYPE.getName())); } else if (possibleTypes.size() == 1) { - sendPWRequest(lastTile.getPoint(), end.getPoint(), possibleTypes.get(0)); + network.sendRequestPathway(start.getPoint(), end.getPoint(), possibleTypes.get(0)); } else if (possibleTypes.size() > 1) { push(GuiElements.createScreen(entity -> { entity.add(GuiElements.createButton(I18Wrapper.format("btn.return"), e -> pop())); @@ -292,7 +294,7 @@ private void checkForMultiplePathTypes(final SignalBoxNode start, final SignalBo entity.add(GuiElements.createSpacerV(10)); possibleTypes .forEach(type -> entity.add(GuiElements.createButton(type.name(), e -> { - sendPWRequest(start.getPoint(), end.getPoint(), type); + network.sendRequestPathway(start.getPoint(), end.getPoint(), type); pop(); }))); })); @@ -366,7 +368,7 @@ private void buildTileConfigList(final SignalBoxNode node, namingInput.setOnTextUpdate(str -> { node.setCustomText(str); - sendName(node.getPoint(), str); + network.sendNodeLabel(node.getPoint(), str); rendering.updateNodeLabeling(node.getPoint(), str); }); @@ -463,7 +465,7 @@ private void initializePageSettings(final UIEntity entity, layout.add(GuiElements.createButton(name)); layout.add(GuiElements.createButton("x", 20, e -> { - removeBlockPos(p); + network.sendRemovePos(p); list.remove(layout); })); list.add(layout); @@ -485,7 +487,6 @@ private void initializePageSettings(final UIEntity entity, private void initializeFieldUsage(final UIEntity entity) { reset(); - sendModeChanges(); page = SignalBoxPage.OPERATION; initializeFieldTemplate(this::tileNormal, false); resetSelection(entity); @@ -522,7 +523,9 @@ private void initializeFieldEdit(final UIEntity entity) { menu.setConsumer( (selection, rotation) -> helpPage.updateNextNode(selection, rotation)); resetSelection(entity); - resetAllPathways(); + network.sendResetAllPathways(); + resetAllSubsidiarySignals(); + resetColors(); helpPage.updateNextNode(menu.getSelection(), menu.getRotation()); this.lastTile = null; @@ -557,10 +560,10 @@ private void initializeFieldTemplate(final SignalBoxConsumer consumer, final List nodes = container.grid.getNodes(); buildColors(nodes); - updateTrainNumbers(nodes); + nodes.forEach(this::updateTrainNumbers); } - public void updateCounter() { + protected void updateCounter() { helpPage.updateCounterButton(); } @@ -620,303 +623,20 @@ private void disableBottomEntity() { bottomEntity.getParent().update(); } - private void sendPWRequest(final Point start, final Point end, final PathType type) { - if (!allPacketsRecived) - return; - final WriteBuffer buffer = new WriteBuffer(); - buffer.putEnumValue(SignalBoxNetwork.REQUEST_PW); - start.writeNetwork(buffer); - end.writeNetwork(buffer); - buffer.putEnumValue(type); - OpenSignalsMain.network.sendTo(info.player, buffer); - } - - protected void resetPathwayOnServer(final SignalBoxNode node) { - if (!allPacketsRecived) - return; - final WriteBuffer buffer = new WriteBuffer(); - buffer.putEnumValue(SignalBoxNetwork.RESET_PW); - node.getPoint().writeNetwork(buffer); - OpenSignalsMain.network.sendTo(info.player, buffer); - } - - private void sendPosEntryToServer(final BlockPos pos, final SignalBoxNode node, - final EnumGuiMode mode, final Rotation rotation, final PathEntryType entry) { - if (!allPacketsRecived) - return; - final WriteBuffer buffer = new WriteBuffer(); - buffer.putEnumValue(SignalBoxNetwork.SEND_POS_ENTRY); - buffer.putBlockPos(pos); - node.getPoint().writeNetwork(buffer); - buffer.putByte((byte) mode.ordinal()); - buffer.putByte((byte) rotation.ordinal()); - buffer.putByte((byte) entry.getID()); - OpenSignalsMain.network.sendTo(info.player, buffer); - } - - protected void sendIntEntryToServer(final int speed, final SignalBoxNode node, - final EnumGuiMode mode, final Rotation rotation, final PathEntryType entry) { - if (speed == 127 || !allPacketsRecived) - return; - final WriteBuffer buffer = new WriteBuffer(); - buffer.putEnumValue(SignalBoxNetwork.SEND_INT_ENTRY); - buffer.putByte((byte) speed); - node.getPoint().writeNetwork(buffer); - buffer.putByte((byte) mode.ordinal()); - buffer.putByte((byte) rotation.ordinal()); - buffer.putByte((byte) entry.getID()); - OpenSignalsMain.network.sendTo(info.player, buffer); - } - - protected void sendZS2Entry(final byte value, final SignalBoxNode node, final EnumGuiMode mode, - final Rotation rotation, final PathEntryType entry) { - if (!allPacketsRecived) - return; - final WriteBuffer buffer = new WriteBuffer(); - buffer.putEnumValue(SignalBoxNetwork.SEND_ZS2_ENTRY); - buffer.putByte(value); - node.getPoint().writeNetwork(buffer); - buffer.putByte((byte) mode.ordinal()); - buffer.putByte((byte) rotation.ordinal()); - buffer.putByte((byte) entry.getID()); - OpenSignalsMain.network.sendTo(info.player, buffer); - } - - protected void sendZS6Entry(final boolean value, final SignalBoxNode node, - final EnumGuiMode mode, final Rotation rotation, final PathEntryType entry) { - if (!allPacketsRecived) - return; - final WriteBuffer buffer = new WriteBuffer(); - buffer.putEnumValue(SignalBoxNetwork.SEND_ZS6_ENTRY); - buffer.putBoolean(value); - node.getPoint().writeNetwork(buffer); - buffer.putByte((byte) mode.ordinal()); - buffer.putByte((byte) rotation.ordinal()); - buffer.putByte((byte) entry.getID()); - OpenSignalsMain.network.sendTo(info.player, buffer); - } - - protected void sendPointEntry(final Point point, final SignalBoxNode node, - final EnumGuiMode mode, final Rotation rotation, final PathEntryType entry) { - if (!allPacketsRecived) - return; - final WriteBuffer buffer = new WriteBuffer(); - buffer.putEnumValue(SignalBoxNetwork.SEND_POINT_ENTRY); - point.writeNetwork(buffer); - node.getPoint().writeNetwork(buffer); - buffer.putByte((byte) mode.ordinal()); - buffer.putByte((byte) rotation.ordinal()); - buffer.putByte((byte) entry.getID()); - OpenSignalsMain.network.sendTo(info.player, buffer); - } - - protected void removeEntryFromServer(final SignalBoxNode node, final EnumGuiMode mode, - final Rotation rotation, final PathEntryType entry) { - if (!allPacketsRecived) - return; - final WriteBuffer buffer = new WriteBuffer(); - buffer.putEnumValue(SignalBoxNetwork.REMOVE_ENTRY); - node.getPoint().writeNetwork(buffer); - buffer.putByte((byte) mode.ordinal()); - buffer.putByte((byte) rotation.ordinal()); - buffer.putByte((byte) entry.getID()); - OpenSignalsMain.network.sendTo(info.player, buffer); - } - - private void resetAllPathways() { - if (!allPacketsRecived) - return; - final WriteBuffer buffer = new WriteBuffer(); - buffer.putEnumValue(SignalBoxNetwork.RESET_ALL_PW); - OpenSignalsMain.network.sendTo(info.player, buffer); - resetColors(container.grid.getNodes()); - } - - private void sendModeChanges() { - if (changedModes.isEmpty() || !allPacketsRecived) - return; - final WriteBuffer buffer = new WriteBuffer(); - buffer.putEnumValue(SignalBoxNetwork.SEND_CHANGED_MODES); - buffer.putINetworkSaveableMap(changedModes); - container.grid.putAllNodes(changedModes); - changedModes.clear(); - OpenSignalsMain.network.sendTo(info.player, buffer); - } - - private void removeBlockPos(final BlockPos pos) { - if (!allPacketsRecived) - return; - final WriteBuffer buffer = new WriteBuffer(); - buffer.putEnumValue(SignalBoxNetwork.REMOVE_POS); - buffer.putBlockPos(pos); - OpenSignalsMain.network.sendTo(info.player, buffer); - } - - protected void sendSubsidiaryRequest(final SubsidiaryState entry, final Point point, - final ModeSet mode, final boolean enable) { - if (!allPacketsRecived) - return; - final WriteBuffer buffer = new WriteBuffer(); - buffer.putEnumValue(SignalBoxNetwork.REQUEST_SUBSIDIARY); - entry.writeNetwork(buffer); - point.writeNetwork(buffer); - mode.writeNetwork(buffer); - buffer.putBoolean(enable); - OpenSignalsMain.network.sendTo(info.player, buffer); - } - - protected void changeRedstoneOutput(final Point point, final ModeSet mode, - final boolean state) { - if (!allPacketsRecived) - return; - final WriteBuffer buffer = new WriteBuffer(); - buffer.putEnumValue(SignalBoxNetwork.UPDATE_RS_OUTPUT); - point.writeNetwork(buffer); - mode.writeNetwork(buffer); - buffer.putBoolean(state); - OpenSignalsMain.network.sendTo(info.player, buffer); - rendering.setColor(point, mode, state ? OUTPUT_COLOR : SignalBoxUtil.FREE_COLOR); - } - - protected void setAutoPoint(final Point point, final byte state) { - if (!allPacketsRecived) - return; - final WriteBuffer buffer = new WriteBuffer(); - buffer.putEnumValue(SignalBoxNetwork.SET_AUTO_POINT); - point.writeNetwork(buffer); - buffer.putBoolean(state == 1); - OpenSignalsMain.network.sendTo(info.player, buffer); - } - - private void sendName(final Point point, final String name) { - if (!allPacketsRecived) - return; - final WriteBuffer buffer = new WriteBuffer(); - buffer.putEnumValue(SignalBoxNetwork.SEND_NAME); - point.writeNetwork(buffer); - buffer.putString(name); - OpenSignalsMain.network.sendTo(info.player, buffer); - } - - protected void sendBoolEntry(final boolean state, final Point point, final ModeSet mode, - final PathEntryType entry) { - if (!allPacketsRecived) - return; - final WriteBuffer buffer = new WriteBuffer(); - buffer.putEnumValue(SignalBoxNetwork.SEND_BOOL_ENTRY); - buffer.putBoolean(state); - point.writeNetwork(buffer); - mode.writeNetwork(buffer); - buffer.putByte((byte) entry.getID()); - OpenSignalsMain.network.sendTo(info.player, buffer); - } - - protected void removeNextPathwayFromServer(final Point start, final Point end) { - if (!allPacketsRecived) - return; - final WriteBuffer buffer = new WriteBuffer(); - buffer.putEnumValue(SignalBoxNetwork.REMOVE_SAVEDPW); - start.writeNetwork(buffer); - end.writeNetwork(buffer); - OpenSignalsMain.network.sendTo(info.player, buffer); - } - - protected void sendCurrentCounterToServer() { - if (!allPacketsRecived) - return; - final WriteBuffer buffer = new WriteBuffer(); - buffer.putEnumValue(SignalBoxNetwork.SEND_COUNTER); - buffer.putInt(container.grid.getCurrentCounter()); - OpenSignalsMain.network.sendTo(info.player, buffer); - } - - protected void sendTrainNumber(final Point point, final String number) { - if (!allPacketsRecived) - return; - final WriteBuffer buffer = new WriteBuffer(); - buffer.putEnumValue(SignalBoxNetwork.SEND_TRAIN_NUMBER); - point.writeNetwork(buffer); - buffer.putString(number); - OpenSignalsMain.network.sendTo(info.player, buffer); - } - - protected void deleteTrainNumber(final Point point) { - if (!allPacketsRecived) - return; - final WriteBuffer buffer = new WriteBuffer(); - buffer.putEnumValue(SignalBoxNetwork.SEND_TRAIN_NUMBER); - point.writeNetwork(buffer); - buffer.putString(TrainNumber.DEFAULT.trainNumber); - OpenSignalsMain.network.sendTo(info.player, buffer); - } - - protected void resetAllSignals() { - if (!allPacketsRecived) - return; - final WriteBuffer buffer = new WriteBuffer(); - buffer.putEnumValue(SignalBoxNetwork.RESET_ALL_SIGNALS); - OpenSignalsMain.network.sendTo(info.player, buffer); - container.grid.resetAllSignals(); - } - - protected void sendPosIdentList(final List list, final SignalBoxNode node, - final EnumGuiMode mode, final Rotation rotation, - final PathEntryType> entry) { - if (!allPacketsRecived) - return; - final WriteBuffer buffer = new WriteBuffer(); - buffer.putEnumValue(SignalBoxNetwork.SEND_POSIDENT_LIST); - buffer.putISaveableList(list); - node.getPoint().writeNetwork(buffer); - buffer.putByte((byte) mode.ordinal()); - buffer.putByte((byte) rotation.ordinal()); - buffer.putByte((byte) entry.getID()); - OpenSignalsMain.network.sendTo(info.player, buffer); - } - - protected void sendConnetedTrainNumbers(final ModeIdentifier ident, final SignalBoxNode node, - final EnumGuiMode mode, final Rotation rotation) { - if (!allPacketsRecived) - return; - final WriteBuffer buffer = new WriteBuffer(); - buffer.putEnumValue(SignalBoxNetwork.SEND_CONNECTED_TRAINNUMBERS); - ident.writeNetwork(buffer); - node.getPoint().writeNetwork(buffer); - buffer.putByte((byte) mode.ordinal()); - buffer.putByte((byte) rotation.ordinal()); - buffer.putByte((byte) PathEntryType.CONNECTED_TRAINNUMBER.getID()); - OpenSignalsMain.network.sendTo(info.player, buffer); - } - - protected void updateSignalStateOnServer(final Point point, final ModeSet mode, - final SignalState state) { - if (!allPacketsRecived) - return; - final WriteBuffer buffer = new WriteBuffer(); - buffer.putEnumValue(SignalBoxNetwork.SET_SIGNAL_STATE); - point.writeNetwork(buffer); - buffer.putByte((byte) mode.mode.ordinal()); - buffer.putByte((byte) mode.rotation.ordinal()); - buffer.putEnumValue(state); - OpenSignalsMain.network.sendTo(info.player, buffer); - } - private void reset() { lowerEntity.clear(); } @Override public void updateFromContainer() { - if (!allPacketsRecived) { - updateEnabledSubsidiaries(); - initializeBasicUI(); - enabledSubsidiaries.values() - .forEach(holder -> updateSignalState(container.grid.getNode(holder.point))); - allPacketsRecived = true; - } + updateAllEnabledSubsidiaries(); + initializeBasicUI(); + enabledSubsidiaries.values() + .forEach(holder -> updateSignalState(container.grid.getNode(holder.point))); } - private void updateEnabledSubsidiaries() { + private void updateAllEnabledSubsidiaries() { + enabledSubsidiaries.clear(); container.enabledSubsidiaryTypes.forEach((point, map) -> map.forEach((modeSet, state) -> { final SignalBoxNode node = container.grid.getNode(point); if (node == null) @@ -940,8 +660,8 @@ private void buildColors(final List nodes) { }); } - private void resetColors(final List nodes) { - nodes.forEach(node -> { + private void resetColors() { + container.grid.getNodes().forEach(node -> { node.forEach(mode -> { final EnumGuiMode guiMode = mode.mode; final PathOptionEntry entry = node.getOption(mode).get(); @@ -964,18 +684,28 @@ private void resetColors(final List nodes) { }); } - private void applyColorChanges(final List listOfNodes) { - for (int i = listOfNodes.size() - 2; i > 0; i--) { - final Point oldPos = listOfNodes.get(i - 1).getPoint(); - final Point newPos = listOfNodes.get(i + 1).getPoint(); - final Path path = new Path(oldPos, newPos); - final SignalBoxNode current = listOfNodes.get(i); - final ModeSet modeSet = current.getMode(path); - current.getOption(modeSet) - .ifPresent(poe -> rendering.setColor(current.getPoint(), modeSet, - poe.getEntry(PathEntryType.PATHUSAGE) - .orElseGet(() -> EnumPathUsage.FREE).getColor())); - } + private void updateColor(final SignalBoxNode node) { + node.toPathIdentifier().forEach(ident -> { + node.getOption(ident.getMode()).ifPresent(poe -> { + rendering.setColor(node.getPoint(), ident.getMode(), + poe.getEntry(PathEntryType.PATHUSAGE).orElseGet(() -> EnumPathUsage.FREE) + .getColor()); + }); + }); + } + + private void resetAllSubsidiarySignals() { + final SubsidiaryState dummy = SubsidiaryState.ALL_STATES.get(0); + container.enabledSubsidiaryTypes.forEach((point, states) -> { + final SignalBoxNode node = container.grid.getNode(point); + states.keySet().forEach(mode -> { + node.updateState(mode, SignalState.RED); + network.sendSubsidiary(new ModeIdentifier(point, mode), dummy, false); + }); + updateSignalState(node); + }); + enabledSubsidiaries.clear(); + container.enabledSubsidiaryTypes.clear(); } } \ No newline at end of file diff --git a/src/main/java/com/troblecodings/signals/guis/GuiSignalBridge.java b/src/main/java/com/troblecodings/signals/guis/GuiSignalBridge.java index d4cefe031..2a238dddd 100644 --- a/src/main/java/com/troblecodings/signals/guis/GuiSignalBridge.java +++ b/src/main/java/com/troblecodings/signals/guis/GuiSignalBridge.java @@ -62,8 +62,8 @@ public class GuiSignalBridge extends GuiBase { private static final UIBorder SELECTED_BORDER = new UIBorder(0xFF00FF00, 1); private static final int TILE_WIDTH = 13; private static final int TILE_COUNT = 15; - private static final UIToolTip COLLISION_TOOLTIP = new UIToolTip( - I18Wrapper.format("gui.signalbridge.collision"), true); + private static final UIToolTip COLLISION_TOOLTIP = + new UIToolTip(I18Wrapper.format("gui.signalbridge.collision"), true); private final UIEntity leftEntity = new UIEntity(); private final UIEntity middleEntity = new UIEntity(); @@ -80,7 +80,7 @@ public class GuiSignalBridge extends GuiBase { private boolean loaded = false; static { - Signal.SIGNAL_IDS.stream().filter(signal -> signal.isForSignalBridge()) + Signal.SIGNAL_IDS.values().stream().filter(signal -> signal.isForSignalBridge()) .forEach(SIGNALS_FOR_BRIDGE::add); } @@ -108,8 +108,8 @@ private void initInternal() { header.add(GuiElements.createLabel(I18Wrapper.format("gui.signalbridge.title"), header.getBasicTextColor(), 1.1f)); header.add(GuiElements.createSpacerH(10)); - final UIEntity editButton = GuiElements - .createButton(I18Wrapper.format("gui.signalbridge.edit"), e -> { + final UIEntity editButton = + GuiElements.createButton(I18Wrapper.format("gui.signalbridge.edit"), e -> { updateAvailableBridgeParts(SignalBridgeType.BASE); buildGrid(); resetSelection(e); @@ -117,8 +117,8 @@ private void initInternal() { editButton.add(new UIToolTip(I18Wrapper.format("gui.signalbridge.edit.desc"))); header.add(editButton); resetSelection(editButton); - final UIEntity preview = GuiElements - .createButton(I18Wrapper.format("gui.signalbridge.preview"), e -> { + final UIEntity preview = + GuiElements.createButton(I18Wrapper.format("gui.signalbridge.preview"), e -> { buildBridgePreview(); buildBridgeList(); resetSelection(e); @@ -153,14 +153,15 @@ private void updateAvailableBridgeParts(final SignalBridgeType type) { list.setInherits(true); list.add(new UIBox(UIBox.VBOX, 1).setPageable(false)); - final List typeBlocks = SignalBridgeBlockParser.SIGNAL_BRIDGE_BLOCKS - .getOrDefault(type, new ArrayList<>()); + final List typeBlocks = + SignalBridgeBlockParser.SIGNAL_BRIDGE_BLOCKS.getOrDefault(type, new ArrayList<>()); typeBlocks.forEach(block -> { final UIEntity blockEntity = createPreviewForBlock(block, 14, -2, 1.9f, 80, 60, true, 0, 0, true, SignalBridgeBuilder.EMPTY_WRAPPER); blockEntity.add(new UIClickable(e -> { - if (currentBlock != null) + if (currentBlock != null) { removeUISelection(currentBlock); + } if (currentBlock == block) { currentBlock = null; return; @@ -214,18 +215,17 @@ private void buildGrid() { row.add(tile); final SignalBridgeBasicBlock savedBlock = container.builder.getBlockOnPoint(point); if (savedBlock != null) { - final UIEntity blockEntity = createPreviewForBlock(savedBlock, 15, -1, 0.7f, - TILE_WIDTH, TILE_WIDTH, false, -9.5f, 1.5f, false, - SignalBridgeBuilder.EMPTY_WRAPPER); + final UIEntity blockEntity = + createPreviewForBlock(savedBlock, 15, -1, 0.7f, TILE_WIDTH, TILE_WIDTH, + false, -9.5f, 1.5f, false, SignalBridgeBuilder.EMPTY_WRAPPER); tile.add(blockEntity); } if (point.equals(container.builder.getStartPoint())) { tile.add(new UIBorder(0xFF0000FF, 2)); } tile.add(new UIClickable(e -> { - if (currentBlock == null) { + if (currentBlock == null) return; - } final SignalBridgeBasicBlock block = container.builder.getBlockOnPoint(point); final UIEntity blockEntity = createPreviewForBlock(currentBlock, 15, -1, 0.7f, TILE_WIDTH, TILE_WIDTH, false, -9.5f, 1.5f, false, @@ -300,9 +300,9 @@ private void buildBridgeList() { scroll.add(list); list.setInherits(true); list.add(new UIBox(UIBox.VBOX, 1).setPageable(false)); - final IIntegerable availableSignals = SizeIntegerables.of( - I18Wrapper.format("gui.signalbridge.signals"), SIGNALS_FOR_BRIDGE.size(), - i -> SIGNALS_FOR_BRIDGE.get(i)); + final IIntegerable availableSignals = + SizeIntegerables.of(I18Wrapper.format("gui.signalbridge.signals"), + SIGNALS_FOR_BRIDGE.size(), i -> SIGNALS_FOR_BRIDGE.get(i)); final UIEntity addButton = GuiElements.createButton("+", e -> { disableMultiRenderer(); push(GuiElements.createScreen(searchPanel -> { @@ -407,9 +407,9 @@ private void buildBridgeList() { addButton.add(new UIToolTip(I18Wrapper.format("gui.signalbridge.plusbutton.desc"))); list.add(addButton); container.allSignals.forEach((name, entry) -> { - final UIEntity blockEntity = createPreviewForBlock(entry.getKey(), 14, -3.5f, 1.9f, 80, - 100, true, 0, 0, true, name, - new ModelInfoWrapper(renderData.getDataForName(name)), 100); + final UIEntity blockEntity = + createPreviewForBlock(entry.getKey(), 14, -3.5f, 1.9f, 80, 100, true, 0, 0, + true, name, new ModelInfoWrapper(renderData.getDataForName(name)), 100); blockEntity.add(new UIClickable(e -> { addUISelection(name); currentSignal = name; @@ -555,12 +555,12 @@ private void buildSystemToAddSignal(final String name, final Signal signal, })); for (final Axis axis : Direction.Axis.values()) { for (final AxisDirection axisDirection : Direction.AxisDirection.values()) { - final String buttonName = axis.getName() - + (axisDirection == AxisDirection.POSITIVE ? "+" : "-"); + final String buttonName = + axis.getName() + (axisDirection == AxisDirection.POSITIVE ? "+" : "-"); final UIEntity button = GuiElements.createButton(buttonName, e -> { final int step = axisDirection == AxisDirection.POSITIVE ? -1 : 1; - final VectorWrapper vector = container.builder.getVecForSignal(entry) - .addOnAxis(axis, step); + final VectorWrapper vector = + container.builder.getVecForSignal(entry).addOnAxis(axis, step); checkCollision(name, vector, signal); container.builder.setNewSignalPos(signal, name, vector); updateMultiRenderer(); @@ -595,8 +595,8 @@ private void disableRightEntity() { private void checkMaxAndMins(final VectorWrapper vector) { for (final Axis axis : Axis.values()) { for (final AxisDirection axisDirection : AxisDirection.values()) { - final String buttonName = axis.getName() - + (axisDirection == AxisDirection.POSITIVE ? "+" : "-"); + final String buttonName = + axis.getName() + (axisDirection == AxisDirection.POSITIVE ? "+" : "-"); final UIEntity button = nameForButton.get(buttonName); switch (axis) { case X: { @@ -623,9 +623,8 @@ private void checkMaxAndMins(final VectorWrapper vector) { private static void checkEnableAndDisable(final AxisDirection axisDirection, final int min, final int max, final float value, final UIEntity button) { - if (value >= max && axisDirection == AxisDirection.POSITIVE) { - disableSelection(button); - } else if (value <= min && axisDirection == AxisDirection.NEGATIVE) { + if ((value >= max && axisDirection == AxisDirection.POSITIVE) + || (value <= min && axisDirection == AxisDirection.NEGATIVE)) { disableSelection(button); } else { enableSelection(button); @@ -662,9 +661,9 @@ private void buildSignalPropertiesSelection(final Signal signal, final String na final Map.Entry> entry = container.allSignals.get(name); previewSidebar.clear(); signal.getProperties().forEach(property -> { - final int value = entry.getValue().containsKey(property) - ? entry.getValue().get(property) - : property.getParent().getIDFromValue(property.getDefault()); + final int value = + entry.getValue().containsKey(property) ? entry.getValue().get(property) + : property.getParent().getIDFromValue(property.getDefault()); of(property, inp -> applyPropertyChanges(name, property, inp), value); }); previewSidebar.update(signal); @@ -706,8 +705,8 @@ private static UIEntity createPreviewForBlock(final BasicBlock block, final floa blockEntity.setHeight(height); blockEntity.add(new UIColor(GuiSignalBox.BACKGROUND_COLOR)); if (showName) { - final UILabel label = new UILabel( - customName.isEmpty() + final UILabel label = + new UILabel(customName.isEmpty() ? I18Wrapper.format("block." + OpenSignalsMain.MODID + "." + block.delegate.name().getPath()) : customName); @@ -724,9 +723,10 @@ private static UIEntity createPreviewForBlock(final BasicBlock block, final floa preview.setY(previewY); preview.add(new UIScale(previewScale, previewScale, previewScale)); - if (enableRotation) + if (enableRotation) { preview.add(new UIDrag((x, y) -> renderer .updateRotation(QuaternionWrapper.fromXYZ(0, (float) x * 0.1f, 0)), 1)); + } preview.add(new UIScissor()); preview.add(renderer); @@ -784,8 +784,8 @@ private void applyPropertyChanges(final String signalName, final SEProperty prop final int valueId) { if (!loaded) return; - final Map.Entry> entry = container.allSignals - .get(signalName); + final Map.Entry> entry = + container.allSignals.get(signalName); final Signal signal = entry.getKey(); final int propertyId = signal.getIDFromProperty(property); final WriteBuffer buffer = new WriteBuffer(); @@ -932,9 +932,10 @@ private void prepareRenderData() { private void fillRenderPropertiesUp(final Signal signal, final Map properties) { signal.getProperties().forEach(property -> { - if (!properties.containsKey(property)) + if (!properties.containsKey(property)) { properties.put(property, property.getParent().getIDFromValue(property.getDefault())); + } }); } } \ No newline at end of file diff --git a/src/main/java/com/troblecodings/signals/guis/ModeDropDownBoxUI.java b/src/main/java/com/troblecodings/signals/guis/ModeDropDownBoxUI.java index 8b5a3b349..c48af6a0e 100644 --- a/src/main/java/com/troblecodings/signals/guis/ModeDropDownBoxUI.java +++ b/src/main/java/com/troblecodings/signals/guis/ModeDropDownBoxUI.java @@ -117,11 +117,9 @@ public void addElements(final UIEntity parent) { final int speed = id > 0 ? id : 127; final Optional opt = option.getEntry(PathEntryType.SPEED); if (speed == 127 && opt.isPresent()) { - gui.removeEntryFromServer(node, mode, rotation, PathEntryType.SPEED); option.removeEntry(PathEntryType.SPEED); } else if ((opt.isPresent() && opt.get() != speed) || (!opt.isPresent() && speed != 127)) { - gui.sendIntEntryToServer(speed, node, mode, rotation, PathEntryType.SPEED); option.setEntry(PathEntryType.SPEED, speed); } }, option.getEntry(PathEntryType.SPEED).filter(n -> n < 16).orElse(127)); @@ -141,10 +139,8 @@ public void addElements(final UIEntity parent) { final UIEntity zs2Entity = GuiElements.createEnumElement(JsonEnumHolder.ZS32, e -> { if (e == 0) { - gui.removeEntryFromServer(node, mode, rotation, PathEntryType.ZS2); option.removeEntry(PathEntryType.ZS2); } else { - gui.sendZS2Entry((byte) e, node, mode, rotation, PathEntryType.ZS2); option.setEntry(PathEntryType.ZS2, (byte) e); } }, option.getEntry(PathEntryType.ZS2).orElse((byte) 0)); @@ -152,8 +148,11 @@ public void addElements(final UIEntity parent) { Optional opt = option.getEntry(PathEntryType.ZS6); parent.add(GuiElements.createBoolElement(BoolIntegerables.of("zs6_state"), e -> { final boolean state = e == 1 ? true : false; - gui.sendZS6Entry(state, node, mode, rotation, PathEntryType.ZS6); - option.setEntry(PathEntryType.ZS6, TCBoolean.valueOf(state)); + if (state) { + option.setEntry(PathEntryType.ZS6, TCBoolean.valueOf(state)); + } else { + option.removeEntry(PathEntryType.ZS6); + } }, opt.isPresent() && opt.get().booleanValue() ? 1 : 0)); } break; @@ -164,9 +163,11 @@ public void addElements(final UIEntity parent) { parent.add( GuiElements.createBoolElement(BoolIntegerables.of("signal_repeater"), e -> { final boolean state = e == 1 ? true : false; - gui.sendBoolEntry(state, node.getPoint(), modeSet, - PathEntryType.SIGNAL_REPEATER); - option.setEntry(PathEntryType.SIGNAL_REPEATER, state); + if (state) { + option.setEntry(PathEntryType.SIGNAL_REPEATER, state); + } else { + option.removeEntry(PathEntryType.SIGNAL_REPEATER); + } }, opt.isPresent() && opt.get() ? 1 : 0)); break; case HP: { @@ -183,7 +184,7 @@ public void addElements(final UIEntity parent) { final BoxEntity boxEntity = UISignalBoxRendering.createSignalBoxEntity( grid, false, (rendering, point, mouseKey) -> { final SignalBoxNode node = grid.getNodeChecked(point) - .orElseGet(() -> new SignalBoxNode()); + .orElse(new SignalBoxNode(grid.getNetwork())); if (mouseKey != MouseEvent.LEFT_MOUSE || node.isEmpty()) return; final AtomicReference vp = @@ -213,13 +214,9 @@ public void addElements(final UIEntity parent) { } if (preSignalsList.isEmpty()) { option.removeEntry(PathEntryType.PRESIGNALS); - gui.removeEntryFromServer(this.node, mode, rotation, - PathEntryType.PRESIGNALS); } else { option.setEntry(PathEntryType.PRESIGNALS, preSignalsList); - gui.sendPosIdentList(preSignalsList, this.node, mode, - rotation, PathEntryType.PRESIGNALS); } }); preSignalsList.forEach(ident -> { @@ -248,7 +245,7 @@ public void addElements(final UIEntity parent) { final BoxEntity boxEntity = UISignalBoxRendering.createSignalBoxEntity( gui.container.grid, false, (rendering, point, mouseKey) -> { final SignalBoxNode node = grid.getNodeChecked(point) - .orElse(new SignalBoxNode()); + .orElse(new SignalBoxNode(grid.getNetwork())); if (mouseKey != MouseEvent.LEFT_MOUSE || node.isEmpty()) return; final Point select = @@ -256,14 +253,10 @@ public void addElements(final UIEntity parent) { .orElse(new Point(-1, -1)); if (point.equals(select)) { rendering.removeSelection(SelectionType.FIRST); - gui.removeEntryFromServer(this.node, mode, rotation, - PathEntryType.PROTECTIONWAY_END); option.removeEntry(PathEntryType.PROTECTIONWAY_END); } else { rendering.addSelection(GuiSignalBox.SELECTION_COLOR, point, SelectionType.FIRST); - gui.sendPointEntry(point, this.node, mode, rotation, - PathEntryType.PROTECTIONWAY_END); option.setEntry(PathEntryType.PROTECTIONWAY_END, point); } }); @@ -290,9 +283,11 @@ public void addElements(final UIEntity parent) { parent.add(GuiElements.createBoolElement(BoolIntegerables.of("can_be_overstepped"), e -> { final boolean state = e == 1 ? true : false; - option.setEntry(PathEntryType.CAN_BE_OVERSTPEPPED, state); - gui.sendBoolEntry(state, node.getPoint(), modeSet, - PathEntryType.CAN_BE_OVERSTPEPPED); + if (state) { + option.setEntry(PathEntryType.CAN_BE_OVERSTPEPPED, state); + } else { + option.removeEntry(PathEntryType.CAN_BE_OVERSTPEPPED); + } }, option.getEntry(PathEntryType.CAN_BE_OVERSTPEPPED).orElse(false) ? 1 : 0)); break; @@ -300,8 +295,11 @@ public void addElements(final UIEntity parent) { case BUE: { parent.add(GuiElements.createEnumElement( new SizeIntegerables<>("delay", 60, get -> String.valueOf(get)), i -> { - option.setEntry(PathEntryType.DELAY, i); - gui.sendIntEntryToServer(i, node, mode, rotation, PathEntryType.DELAY); + if (i == 0) { + option.removeEntry(PathEntryType.DELAY); + } else { + option.setEntry(PathEntryType.DELAY, i); + } }, option.getEntry(PathEntryType.DELAY).orElse(0))); break; } @@ -329,10 +327,8 @@ public void addElements(final UIEntity parent) { final Point point = e >= 0 ? validInConnections.get(e) : null; if (point == null) { option.removeEntry(PathEntryType.POINT); - gui.removeEntryFromServer(node, mode, rotation, PathEntryType.POINT); } else { option.setEntry(PathEntryType.POINT, point); - gui.sendPointEntry(point, node, mode, rotation, PathEntryType.POINT); } }, option.getEntry(PathEntryType.POINT) .map(point -> validInConnections.indexOf(point)).orElse(-1))); @@ -354,21 +350,17 @@ public void addElements(final UIEntity parent) { final BoxEntity boxEntity = UISignalBoxRendering.createSignalBoxEntity( gui.container.grid, false, (rendering, point, mouseKey) -> { final SignalBoxNode node = grid.getNodeChecked(point) - .orElse(new SignalBoxNode()); + .orElse(new SignalBoxNode(grid.getNetwork())); if (mouseKey != MouseEvent.LEFT_MOUSE || !node.isValidEnd()) return; final Point select = option.getEntry(PathEntryType.POINT) .orElse(new Point(-1, -1)); if (point.equals(select)) { rendering.removeSelection(SelectionType.FIRST); - gui.removeEntryFromServer(this.node, mode, rotation, - PathEntryType.POINT); option.removeEntry(PathEntryType.POINT); } else { rendering.addSelection(GuiSignalBox.SELECTION_COLOR, point, SelectionType.FIRST); - gui.sendPointEntry(point, this.node, mode, rotation, - PathEntryType.POINT); option.setEntry(PathEntryType.POINT, point); } }); @@ -405,8 +397,9 @@ public void addElements(final UIEntity parent) { gui.container.grid, false, (rendering, point, mouseKey) -> { if (mouseKey != MouseEvent.LEFT_MOUSE) return; - final SignalBoxNode node = gui.container.grid - .getNodeChecked(point).orElse(new SignalBoxNode()); + final SignalBoxNode node = + gui.container.grid.getNodeChecked(point).orElse( + new SignalBoxNode(grid.getNetwork())); if (node.isEmpty()) return; @@ -530,11 +523,9 @@ private static void connectToEachOther(final ModeIdentifier ident1, final ModeId final SignalBoxGrid grid, final GuiSignalBox gui) { final SignalBoxNode node1 = grid.getNode(ident1.point); node1.getOption(ident1.mode).get().setEntry(PathEntryType.CONNECTED_TRAINNUMBER, ident2); - gui.sendConnetedTrainNumbers(ident2, node1, ident1.mode.mode, ident1.mode.rotation); final SignalBoxNode node2 = grid.getNode(ident2.point); node2.getOption(ident2.mode).get().setEntry(PathEntryType.CONNECTED_TRAINNUMBER, ident1); - gui.sendConnetedTrainNumbers(ident1, node2, ident2.mode.mode, ident2.mode.rotation); } private static void disconnectFromEachOther(final ModeIdentifier ident1, @@ -542,14 +533,10 @@ private static void disconnectFromEachOther(final ModeIdentifier ident1, final SignalBoxNode node1 = grid.getNode(ident1.point); node1.getOption(ident1.mode) .ifPresent(entry -> entry.removeEntry(PathEntryType.CONNECTED_TRAINNUMBER)); - gui.removeEntryFromServer(node1, ident1.mode.mode, ident1.mode.rotation, - PathEntryType.CONNECTED_TRAINNUMBER); final SignalBoxNode node2 = grid.getNode(ident2.point); node2.getOption(ident2.mode) .ifPresent(entry -> entry.removeEntry(PathEntryType.CONNECTED_TRAINNUMBER)); - gui.removeEntryFromServer(node2, ident2.mode.mode, ident2.mode.rotation, - PathEntryType.CONNECTED_TRAINNUMBER); } private void changeShowState() { @@ -598,10 +585,8 @@ private UIEntity getTextFieldEntityforType(final EnumGuiMode mode, final Rotatio } if (i != defaultValue) { option.setEntry(type, i); - gui.sendIntEntryToServer(i, node, mode, rotation, type); } else { option.removeEntry(type); - gui.removeEntryFromServer(node, mode, rotation, type); } }); textInputEntity.add(input); diff --git a/src/main/java/com/troblecodings/signals/guis/SidePanel.java b/src/main/java/com/troblecodings/signals/guis/SidePanel.java index c1fad9c3f..d0c667195 100644 --- a/src/main/java/com/troblecodings/signals/guis/SidePanel.java +++ b/src/main/java/com/troblecodings/signals/guis/SidePanel.java @@ -30,9 +30,11 @@ import com.troblecodings.guilib.ecs.entitys.transform.UIRotate; import com.troblecodings.guilib.ecs.entitys.transform.UIScale; import com.troblecodings.signals.OpenSignalsMain; +import com.troblecodings.signals.core.ModeIdentifier; import com.troblecodings.signals.core.StateInfo; import com.troblecodings.signals.core.SubsidiaryHolder; import com.troblecodings.signals.core.SubsidiaryState; +import com.troblecodings.signals.core.TrainNumber; import com.troblecodings.signals.enums.EnumGuiMode; import com.troblecodings.signals.enums.EnumPathUsage; import com.troblecodings.signals.enums.SignalBoxPage; @@ -41,6 +43,7 @@ import com.troblecodings.signals.signalbox.ModeSet; import com.troblecodings.signals.signalbox.Point; import com.troblecodings.signals.signalbox.SignalBoxNode; +import com.troblecodings.signals.signalbox.SignalBoxUtil; import com.troblecodings.signals.signalbox.entrys.PathEntryType; import com.troblecodings.signals.signalbox.entrys.PathOptionEntry; @@ -152,7 +155,7 @@ private UIEntity getIcons() { emergencyEntity.setHeight(20); emergencyEntity.setWidth(20); emergencyEntity.add(new UITexture(EMERGENCY)); - emergencyEntity.add(new UIClickable(e -> gui.resetAllSignals())); + emergencyEntity.add(new UIClickable(e -> gui.network.sendResetAllSignals())); emergencyEntity.add(new UIToolTip(I18Wrapper.format("info.usage.emergency.desc"))); list.add(emergencyEntity); @@ -284,8 +287,9 @@ public void helpUsageMode(final SignalBoxNode node) { helpList.add(getSpacerLine()); - final UIEntity shButton = GuiElements.createButton( - " " + I18Wrapper.format("info.usage.emergency"), e -> gui.resetAllSignals()); + final UIEntity shButton = + GuiElements.createButton(" " + I18Wrapper.format("info.usage.emergency"), + e -> gui.network.sendResetAllSignals()); shButton.add(new UIToolTip(I18Wrapper.format("info.usage.emergency.desc"))); final UIEntity emergencyEntity = new UIEntity(); @@ -358,7 +362,6 @@ public void helpUsageMode(final SignalBoxNode node) { if (guiModes.contains(EnumGuiMode.HP)) { final UIEntity entity = GuiElements.createBoolElement(BoolIntegerables.of("auto_pathway"), e -> { - gui.setAutoPoint(node.getPoint(), (byte) e); node.setAutoPoint(e == 1 ? true : false); }, node.isAutoPoint() ? 1 : 0); entity.setScale(0.95f); @@ -388,7 +391,7 @@ public void helpUsageMode(final SignalBoxNode node) { final UIEntity buttonYes = GuiElements.createButton(I18Wrapper.format("btn.yes"), e1 -> { gui.pop(); - gui.resetPathwayOnServer(node); + gui.network.sendResetPathway(node.getPoint()); }); final UIEntity buttonNo = GuiElements .createButton(I18Wrapper.format("btn.no"), e2 -> gui.pop()); @@ -448,21 +451,21 @@ public void helpUsageMode(final SignalBoxNode node) { node.getPoint(), mode)); node.setSubsidiaryState(mode, state); } else { - node.updateState(mode, SignalState.RED); node.removeSubsidiaryState(mode); + node.updateState(mode, SignalState.RED); subsidiaries.remove(signalPos); } - gui.sendSubsidiaryRequest(state, node.getPoint(), - mode, enable); - gui.container.updateClientSubsidiary( - node.getPoint(), mode, state, enable); - gui.container.updateSignalState.accept(node); + gui.network.sendSubsidiary( + new ModeIdentifier(node.getPoint(), mode), + state, enable); + gui.container.updateClientSubsidiary(node, mode, + state, enable); + gui.updateSignalState(node); gui.pop(); helpUsageMode(node); if (state.isCountable() && enable) { gui.container.grid.count(); gui.updateCounter(); - gui.sendCurrentCounterToServer(); } }, defaultValue)); }); @@ -547,20 +550,22 @@ public void helpUsageMode(final SignalBoxNode node) { textureEntity.add(new UIToolTip(I18Wrapper .format("info.usage.rs.desc"))); if (turnOff) { - gui.changeRedstoneOutput( - node.getPoint(), mode, false); + node.removeManuellOutput(mode); outputStatus.setText(I18Wrapper .format("info.usage.rs.false")); textureEntity.add(new UITexture( GuiSignalBox.REDSTONE_OFF)); } else { - gui.changeRedstoneOutput( - node.getPoint(), mode, true); + node.addManuellOutput(mode); outputStatus.setText(I18Wrapper .format("info.usage.rs.true")); textureEntity.add(new UITexture( GuiSignalBox.REDSTONE_ON)); } + gui.rendering.setColor(node.getPoint(), + mode, + !turnOff ? GuiSignalBox.OUTPUT_COLOR + : SignalBoxUtil.FREE_COLOR); })); } gui.pop(); @@ -603,14 +608,15 @@ public void helpUsageMode(final SignalBoxNode node) { lowerEntity.add(GuiElements.createSpacerH(7)); final UIEntity save = GuiElements.createButton(I18Wrapper.format("btn.save"), e1 -> { - gui.sendTrainNumber(node.getPoint(), input.getText()); + gui.network.updateTrainNumber(node.getPoint(), + new TrainNumber(input.getText())); input.setText(""); gui.pop(); }); save.add(new UIToolTip(I18Wrapper.format("sb.trainnumber.save"))); lowerEntity.add(save); final UIEntity remove = GuiElements.createButton("x", e1 -> { - gui.deleteTrainNumber(node.getPoint()); + gui.network.updateTrainNumber(node.getPoint(), TrainNumber.DEFAULT); gui.pop(); }); remove.add(new UIToolTip(I18Wrapper.format("sb.trainnumber.remove"))); @@ -784,14 +790,16 @@ private void addManuellRStoUI() { textureEntity.clear(); textureEntity.add(new UIToolTip(I18Wrapper.format("info.usage.rs.desc"))); if (turnOff) { - gui.changeRedstoneOutput(currentNode.getPoint(), mode, false); + currentNode.removeManuellOutput(mode); outputStatus.setText(I18Wrapper.format("info.usage.rs.false")); textureEntity.add(new UITexture(GuiSignalBox.REDSTONE_OFF)); } else { - gui.changeRedstoneOutput(currentNode.getPoint(), mode, true); + currentNode.addManuellOutput(mode); outputStatus.setText(I18Wrapper.format("info.usage.rs.true")); textureEntity.add(new UITexture(GuiSignalBox.REDSTONE_ON)); } + gui.rendering.setColor(currentNode.getPoint(), mode, + !turnOff ? GuiSignalBox.OUTPUT_COLOR : SignalBoxUtil.FREE_COLOR); })); gui.push(GuiElements.createScreen(entity -> entity.add(info))); }); @@ -838,7 +846,7 @@ private void addSavedPathsToUI() { layout.add(GuiElements.createButton("x", 20, _u -> { gui.container.nextPathways.remove(entry); list.remove(layout); - gui.removeNextPathwayFromServer(entry.getKey(), entry.getValue()); + gui.network.sendRemoveSavedPathway(entry.getKey(), entry.getValue()); gui.pop(); })); list.add(layout); diff --git a/src/main/java/com/troblecodings/signals/handler/ClientNameHandler.java b/src/main/java/com/troblecodings/signals/handler/ClientNameHandler.java index a9bf1e4b3..6250b2aa6 100644 --- a/src/main/java/com/troblecodings/signals/handler/ClientNameHandler.java +++ b/src/main/java/com/troblecodings/signals/handler/ClientNameHandler.java @@ -9,8 +9,8 @@ import net.minecraft.block.BlockState; import net.minecraft.client.Minecraft; -import net.minecraft.client.world.ClientWorld; import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.network.NetworkEvent.ServerCustomPayloadEvent; @@ -27,23 +27,23 @@ public static String getClientName(final StateInfo info) { @Override public void deserializeClient(final ReadBuffer buffer) { final Minecraft mc = Minecraft.getInstance(); - final BlockPos pos = buffer.getBlockPos(); - final boolean removed = buffer.getBoolean(); - if (removed) { - setRemoved(pos); - return; - } - final String name = buffer.getString(); - synchronized (CLIENT_NAMES) { - CLIENT_NAMES.put(new StateInfo(mc.level, pos), name); - } - final ClientWorld world = mc.level; mc.submit(() -> { - final BlockState state = world.getBlockState(pos); + final BlockPos pos = buffer.getBlockPos(); + final boolean removed = buffer.getBoolean(); + if (removed) { + setRemoved(pos); + return; + } + final String name = buffer.getString(); + final World level = mc.level; + synchronized (CLIENT_NAMES) { + CLIENT_NAMES.put(new StateInfo(level, pos), name); + } + final BlockState state = level.getBlockState(pos); if (state == null) return; - world.setBlocksDirty(pos, state, state); - world.setBlockAndUpdate(pos, state); + level.setBlocksDirty(pos, state, state); + level.setBlockAndUpdate(pos, state); }); } diff --git a/src/main/java/com/troblecodings/signals/handler/ClientSignalStateHandler.java b/src/main/java/com/troblecodings/signals/handler/ClientSignalStateHandler.java index c871f0f8c..66ca93519 100644 --- a/src/main/java/com/troblecodings/signals/handler/ClientSignalStateHandler.java +++ b/src/main/java/com/troblecodings/signals/handler/ClientSignalStateHandler.java @@ -13,12 +13,13 @@ import com.troblecodings.signals.blocks.Signal; import com.troblecodings.signals.core.NetworkBufferWrappers; import com.troblecodings.signals.core.StateInfo; +import com.troblecodings.signals.enums.ChangedState; import net.minecraft.block.BlockState; import net.minecraft.client.Minecraft; -import net.minecraft.client.world.ClientWorld; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.network.NetworkEvent.ServerCustomPayloadEvent; @@ -39,40 +40,44 @@ public static final Map getClientStates(final StateInfo info @Override public void deserializeClient(final ReadBuffer buffer) { final Minecraft mc = Minecraft.getInstance(); - final ClientWorld level = mc.level; - final BlockPos signalPos = buffer.getBlockPos(); - final StateInfo stateInfo = new StateInfo(level, signalPos); - final int signalID = buffer.getInt(); - final boolean remove = buffer.getBoolean(); - if (remove) { - setRemoved(stateInfo); - return; - } - final Signal signal = Signal.getSignalByID(signalID); - final Map newProperties = - buffer.getMapWithCombinedValueFunc(NetworkBufferWrappers.getSEPropertyFunc(signal), - (buf, prop) -> prop.getObjFromID(buf.getByteToUnsignedInt())); - synchronized (CURRENTLY_LOADED_STATES) { - final Map properties = - CURRENTLY_LOADED_STATES.computeIfAbsent(stateInfo, _u -> new HashMap<>()); - properties.putAll(newProperties); - CURRENTLY_LOADED_STATES.put(stateInfo, properties); - } - if (level == null) - return; - final long startTime = Calendar.getInstance().getTimeInMillis(); - SERVICE.execute(() -> { - TileEntity entity; - while ((entity = level.getBlockEntity(signalPos)) == null) { - final long currentTime = Calendar.getInstance().getTimeInMillis(); - if (currentTime - startTime >= 5000) - return; - continue; + mc.submit(() -> { + final World level = mc.level; + final BlockPos signalPos = buffer.getBlockPos(); + final StateInfo stateInfo = new StateInfo(level, signalPos); + final int signalID = buffer.getInt(); + final ChangedState changedState = buffer.getEnumValue(ChangedState.class); + if (changedState.equals(ChangedState.REMOVED_FROM_CACHE) + || changedState.equals(ChangedState.REMOVED_FROM_FILE)) { + setRemoved(stateInfo); + return; + } + final Signal signal = Signal.getSignalByID(signalID); + final Map newProperties = buffer.getMapWithCombinedValueFunc( + NetworkBufferWrappers.getSEPropertyFunc(signal), + (buf, prop) -> prop.getObjFromID(buf.getByteToUnsignedInt())); + final Map properties; + synchronized (CURRENTLY_LOADED_STATES) { + properties = + CURRENTLY_LOADED_STATES.computeIfAbsent(stateInfo, _u -> new HashMap<>()); + properties.putAll(newProperties); + CURRENTLY_LOADED_STATES.put(stateInfo, properties); } - final BlockState state = entity.getBlockState(); - mc.level.setBlocksDirty(signalPos, state, state); - entity.requestModelDataUpdate(); - mc.levelRenderer.blockChanged(null, signalPos, null, null, 8); + if (level == null) + return; + final long startTime = Calendar.getInstance().getTimeInMillis(); + SERVICE.execute(() -> { + TileEntity entity; + while ((entity = level.getBlockEntity(signalPos)) == null) { + final long currentTime = Calendar.getInstance().getTimeInMillis(); + if (currentTime - startTime >= 5000) + return; + continue; + } + final BlockState state = entity.getBlockState(); + mc.level.setBlocksDirty(signalPos, state, state); + entity.requestModelDataUpdate(); + mc.levelRenderer.blockChanged(null, signalPos, null, null, 8); + }); }); } diff --git a/src/main/java/com/troblecodings/signals/handler/NameHandler.java b/src/main/java/com/troblecodings/signals/handler/NameHandler.java index cbf736536..dac955478 100644 --- a/src/main/java/com/troblecodings/signals/handler/NameHandler.java +++ b/src/main/java/com/troblecodings/signals/handler/NameHandler.java @@ -42,6 +42,7 @@ import net.minecraft.world.World; import net.minecraft.world.chunk.IChunk; import net.minecraft.world.server.ServerWorld; +import net.minecraftforge.event.entity.player.PlayerEvent; import net.minecraftforge.event.world.ChunkWatchEvent; import net.minecraftforge.event.world.WorldEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; @@ -166,8 +167,8 @@ public static void runTaskWhenNameLoaded(final StateInfo info, listener.update(info, name, ChangedState.UPDATED); } else { synchronized (TASKS_WHEN_LOAD) { - final List list = TASKS_WHEN_LOAD.computeIfAbsent(info, - _u -> new ArrayList<>()); + final List list = + TASKS_WHEN_LOAD.computeIfAbsent(info, _u -> new ArrayList<>()); if (!list.contains(listener)) { list.add(listener); } @@ -253,10 +254,11 @@ public static void onWorldSave(final WorldEvent.Save event) { synchronized (ALL_NAMES) { map = ImmutableMap.copyOf(ALL_NAMES); } - if (writeService != null) + if (writeService != null) { writeService.execute(() -> map.entrySet().stream() .filter(entry -> entry.getKey().world.equals(world)) .forEach(entry -> createToFile(entry.getKey(), entry.getValue()))); + } } @SubscribeEvent @@ -268,6 +270,16 @@ public static void onWorldUnload(final WorldEvent.Unload unload) { } } + @SubscribeEvent + public static void onPlayerJoin(final PlayerEvent.PlayerLoggedInEvent event) { + final PlayerEntity player = event.getPlayer(); + Map map; + synchronized (ALL_NAMES) { + map = ImmutableMap.copyOf(ALL_NAMES); + } + map.forEach((state, name) -> sendTo(player, packToBuffer(state.pos, name))); + } + private static void createToFile(final StateInfo info, final String name) { NameHandlerFileV2 file; synchronized (ALL_LEVEL_FILES) { @@ -341,13 +353,14 @@ public static void loadNames(final List infos, infos.forEach(info -> { boolean isLoaded = false; synchronized (LOAD_COUNTER) { - final List> holders = LOAD_COUNTER.computeIfAbsent(info.info, - _u -> new ArrayList<>()); + final List> holders = + LOAD_COUNTER.computeIfAbsent(info.info, _u -> new ArrayList<>()); if (holders.size() > 0) { isLoaded = true; } - if (!holders.contains(info.holder)) + if (!holders.contains(info.holder)) { holders.add(info.holder); + } } if (isLoaded) { if (player == null) @@ -395,8 +408,8 @@ public static void unloadNames(final List infos) { writeService.execute(() -> { infos.forEach(info -> { synchronized (LOAD_COUNTER) { - final List> holders = LOAD_COUNTER.getOrDefault(info.info, - new ArrayList<>()); + final List> holders = + LOAD_COUNTER.getOrDefault(info.info, new ArrayList<>()); holders.remove(info.holder); if (!holders.isEmpty()) return; diff --git a/src/main/java/com/troblecodings/signals/handler/SignalStateHandler.java b/src/main/java/com/troblecodings/signals/handler/SignalStateHandler.java index f4f8a6569..6a8409d3e 100644 --- a/src/main/java/com/troblecodings/signals/handler/SignalStateHandler.java +++ b/src/main/java/com/troblecodings/signals/handler/SignalStateHandler.java @@ -35,6 +35,7 @@ import io.netty.buffer.Unpooled; import net.minecraft.block.Block; import net.minecraft.client.Minecraft; +import net.minecraft.entity.Entity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.ServerPlayerEntity; import net.minecraft.network.PacketBuffer; @@ -45,6 +46,7 @@ import net.minecraft.world.chunk.IChunk; import net.minecraft.world.server.ServerWorld; import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.entity.EntityJoinWorldEvent; import net.minecraftforge.event.entity.player.PlayerEvent; import net.minecraftforge.event.world.ChunkWatchEvent; import net.minecraftforge.event.world.WorldEvent; @@ -58,11 +60,14 @@ public final class SignalStateHandler implements INetworkSync { private static ExecutorService writeService = Executors.newFixedThreadPool(5); private static final ExecutorService THREAD_SERVICE = Executors.newCachedThreadPool(); - private static final Map> CURRENTLY_LOADED_STATES = new HashMap<>(); + private static final Map> CURRENTLY_LOADED_STATES = + new HashMap<>(); private static final Map ALL_LEVEL_FILES = new HashMap<>(); private static final Map>> SIGNAL_COUNTER = new HashMap<>(); - private static final Map> ALL_LISTENERS = new HashMap<>(); - private static final Map> TASKS_WHEN_LOAD = new HashMap<>(); + private static final Map> ALL_LISTENERS = + new HashMap<>(); + private static final Map> TASKS_WHEN_LOAD = + new HashMap<>(); private static EventNetworkChannel channel; private static ResourceLocation channelName; @@ -112,7 +117,7 @@ public static void createStates(final SignalStateInfo info, synchronized (SIGNAL_COUNTER) { SIGNAL_COUNTER.put(info, list); } - sendToAll(info, states); + sendToAll(info, states, ChangedState.UPDATED); createToFile(info, states); }); } @@ -137,8 +142,8 @@ public static void runTaskWhenSignalLoaded(final SignalStateInfo info, listener.update(info, properties, ChangedState.UPDATED); } else { synchronized (TASKS_WHEN_LOAD) { - final List list = TASKS_WHEN_LOAD.computeIfAbsent(info, - _u -> new ArrayList<>()); + final List list = + TASKS_WHEN_LOAD.computeIfAbsent(info, _u -> new ArrayList<>()); if (!list.contains(listener)) { list.add(listener); } @@ -150,10 +155,11 @@ public static void addListener(final SignalStateInfo info, final SignalStateList if (!info.isValid() || info.isWorldNullOrClientSide()) return; synchronized (ALL_LISTENERS) { - final List listeners = ALL_LISTENERS.computeIfAbsent(info, - _u -> new ArrayList<>()); - if (!listeners.contains(listener)) + final List listeners = + ALL_LISTENERS.computeIfAbsent(info, _u -> new ArrayList<>()); + if (!listeners.contains(listener)) { listeners.add(listener); + } } } @@ -194,8 +200,8 @@ private static void statesToBuffer(final Signal signal, final Map { if (property.equals(Signal.CUSTOMNAME)) return; - readData[signal.getIDFromProperty( - property)] = (byte) (property.getParent().getIDFromValue(string) + 1); + readData[signal.getIDFromProperty(property)] = + (byte) (property.getParent().getIDFromValue(string) + 1); }); } @@ -228,8 +234,8 @@ public static void setStates(final SignalStateInfo info, final Map oldStates = new HashMap<>( - CURRENTLY_LOADED_STATES.get(info)); + final Map oldStates = + new HashMap<>(CURRENTLY_LOADED_STATES.get(info)); states.entrySet().stream().filter(entry -> { final String oldState = oldStates.get(entry.getKey()); return !entry.getValue().equals(oldState); @@ -242,7 +248,7 @@ public static void setStates(final SignalStateInfo info, final Map { - sendToAll(info, changedProperties); + sendToAll(info, changedProperties, ChangedState.UPDATED); info.signal.getUpdate(info.world, info.pos); if (!contains.get()) { createToFile(info, changedProperties); @@ -261,11 +267,9 @@ public static Map getStates(final SignalStateInfo info) { } if (states != null) return states; - else { - if (info.world.isClientSide) - return new HashMap<>(); - return readAndSerialize(info); - } + if (info.world.isClientSide) + return new HashMap<>(); + return readAndSerialize(info); } private static void migrateWorldFilesToV2(final World world) { @@ -337,11 +341,10 @@ private static Map readAndSerialize(final SignalStateInfo st OpenSignalsMain.getLogger() .warn("Position [" + stateInfo + "] not found on client!"); return map; - } else { - OpenSignalsMain.getLogger() - .warn("Position [" + stateInfo + "] not found in file, recovering!"); - pos = file.create(stateInfo.pos); } + OpenSignalsMain.getLogger() + .warn("Position [" + stateInfo + "] not found in file, recovering!"); + pos = file.create(stateInfo.pos); } ByteBuffer buffer; synchronized (file) { @@ -440,29 +443,29 @@ public static void setRemoved(final SignalStateInfo info) { synchronized (SIGNAL_COUNTER) { SIGNAL_COUNTER.remove(info); } - sendRemoved(info); + sendRemoved(info, ChangedState.REMOVED_FROM_FILE); updateListeners(info, removedProperties, ChangedState.REMOVED_FROM_FILE); synchronized (ALL_LISTENERS) { ALL_LISTENERS.remove(info); } } - private static void sendRemoved(final SignalStateInfo info) { + public static void sendRemoved(final SignalStateInfo info, final ChangedState state) { final WriteBuffer buffer = new WriteBuffer(); buffer.putBlockPos(info.pos); buffer.putInt(info.signal.getID()); - buffer.putBoolean(true); + buffer.putEnumValue(state); info.world.players().forEach(player -> sendTo(player, buffer.getBuildedBuffer())); } public static ByteBuffer packToByteBuffer(final SignalStateInfo stateInfo, - final Map properties) { + final Map properties, final ChangedState state) { if (properties.size() > 254) throw new IllegalStateException("Too many SEProperties!"); final WriteBuffer buffer = new WriteBuffer(); buffer.putBlockPos(stateInfo.pos); buffer.putInt(stateInfo.signal.getID()); - buffer.putBoolean(false); + buffer.putEnumValue(state); buffer.putMapWithCombinedValueConsumer(properties, NetworkBufferWrappers.getSEPropertyConsumer(stateInfo.signal), (buf, prop, value) -> buf.putByte((byte) prop.getParent().getIDFromValue(value))); @@ -470,29 +473,43 @@ public static ByteBuffer packToByteBuffer(final SignalStateInfo stateInfo, } private static void sendTo(final SignalStateInfo info, final Map properties, - final @Nullable PlayerEntity player) { + final @Nullable PlayerEntity player, final ChangedState state) { if (player == null) { - sendToAll(info, properties); + sendToAll(info, properties, state); } else { - sendToPlayer(info, properties, player); + sendToPlayer(info, properties, player, state); } } private static void sendToPlayer(final SignalStateInfo stateInfo, - final Map properties, final PlayerEntity player) { + final Map properties, final PlayerEntity player, + final ChangedState state) { if (properties == null || properties.isEmpty()) return; - sendTo(player, packToByteBuffer(stateInfo, properties)); + sendTo(player, packToByteBuffer(stateInfo, properties, state)); } private static void sendToAll(final SignalStateInfo stateInfo, - final Map properties) { + final Map properties, final ChangedState state) { if (properties == null || properties.isEmpty()) return; - final ByteBuffer buffer = packToByteBuffer(stateInfo, properties); + final ByteBuffer buffer = packToByteBuffer(stateInfo, properties, state); stateInfo.world.players().forEach(playerEntity -> sendTo(playerEntity, buffer)); } + @SubscribeEvent + public static void onEntityJoinWorldEvent(final EntityJoinWorldEvent event) { + final Entity entity = event.getEntity(); + if (!(entity instanceof PlayerEntity)) + return; + final Map> properties; + synchronized (CURRENTLY_LOADED_STATES) { + properties = ImmutableMap.copyOf(CURRENTLY_LOADED_STATES); + } + properties.forEach( + (info, map) -> sendTo(info, map, (PlayerEntity) entity, ChangedState.UPDATED)); + } + @SubscribeEvent public static void onChunkWatch(final ChunkWatchEvent.Watch event) { final ServerWorld world = event.getWorld(); @@ -535,7 +552,8 @@ public static void onPlayerJoin(final PlayerEvent.PlayerLoggedInEvent event) { synchronized (CURRENTLY_LOADED_STATES) { map = ImmutableMap.copyOf(CURRENTLY_LOADED_STATES); } - map.forEach((state, properties) -> sendToPlayer(state, properties, player)); + map.forEach((state, properties) -> sendToPlayer(state, properties, player, + ChangedState.ADDED_TO_CACHE)); } public static void loadSignal(final SignalStateLoadHoler info) { @@ -559,8 +577,8 @@ public static void loadSignals(final List signals, signals.forEach(info -> { boolean isLoaded = false; synchronized (SIGNAL_COUNTER) { - final List> holders = SIGNAL_COUNTER.computeIfAbsent(info.info, - _u -> new ArrayList<>()); + final List> holders = + SIGNAL_COUNTER.computeIfAbsent(info.info, _u -> new ArrayList<>()); if (holders.size() > 0) { isLoaded = true; } @@ -569,18 +587,15 @@ public static void loadSignals(final List signals, } } if (isLoaded) { - Map sendProperties; - synchronized (CURRENTLY_LOADED_STATES) { - sendProperties = CURRENTLY_LOADED_STATES.get(info.info); - } - sendTo(info.info, sendProperties, player); + runTaskWhenSignalLoaded(info.info, (stateInfo, props, _u) -> sendTo(stateInfo, + props, player, ChangedState.ADDED_TO_CACHE)); return; } final Map properties = readAndSerialize(info.info); synchronized (CURRENTLY_LOADED_STATES) { CURRENTLY_LOADED_STATES.put(info.info, properties); } - sendTo(info.info, properties, player); + sendTo(info.info, properties, player, ChangedState.ADDED_TO_CACHE); updateListeners(info.info, properties, ChangedState.ADDED_TO_CACHE); final List tasks; synchronized (TASKS_WHEN_LOAD) { @@ -604,8 +619,8 @@ public static void unloadSignals(final List signals) { writeService.execute(() -> { signals.forEach(info -> { synchronized (SIGNAL_COUNTER) { - final List> holders = SIGNAL_COUNTER.getOrDefault(info.info, - new ArrayList<>()); + final List> holders = + SIGNAL_COUNTER.getOrDefault(info.info, new ArrayList<>()); holders.remove(info.holder); if (!holders.isEmpty()) return; diff --git a/src/main/java/com/troblecodings/signals/network/PathOptionEntryNetwork.java b/src/main/java/com/troblecodings/signals/network/PathOptionEntryNetwork.java new file mode 100644 index 000000000..08f8c1d5a --- /dev/null +++ b/src/main/java/com/troblecodings/signals/network/PathOptionEntryNetwork.java @@ -0,0 +1,50 @@ +package com.troblecodings.signals.network; + +import java.util.Objects; + +import com.troblecodings.signals.core.ModeIdentifier; +import com.troblecodings.signals.signalbox.entrys.IPathEntry; +import com.troblecodings.signals.signalbox.entrys.PathEntryType; + +public class PathOptionEntryNetwork { + + private SignalBoxNetworkHandler network; + private ModeIdentifier ident; + + public void sendEntryAdd(final PathEntryType type, final IPathEntry entry) { + if (network == null) + throw new IllegalArgumentException( + "Tried to send entry without network beeing connected!"); + network.sendEntryAdd(ident, type, entry); + } + + public void sendEntryRemove(final PathEntryType type) { + if (network == null) + throw new IllegalArgumentException( + "Tried to send entry without network beeing connected!"); + network.sendEntryRemove(ident, type); + } + + public PathOptionEntryNetwork setUpNetwork(final SignalBoxNetworkHandler network, + final ModeIdentifier ident) { + this.network = network; + this.ident = ident; + return this; + } + + @Override + public int hashCode() { + return Objects.hash(ident, network); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if ((obj == null) || (getClass() != obj.getClass())) + return false; + final PathOptionEntryNetwork other = (PathOptionEntryNetwork) obj; + return Objects.equals(ident, other.ident) && Objects.equals(network, other.network); + } + +} \ No newline at end of file diff --git a/src/main/java/com/troblecodings/signals/network/SignalBoxNetworkHandler.java b/src/main/java/com/troblecodings/signals/network/SignalBoxNetworkHandler.java new file mode 100644 index 000000000..cd7b53e2e --- /dev/null +++ b/src/main/java/com/troblecodings/signals/network/SignalBoxNetworkHandler.java @@ -0,0 +1,478 @@ +package com.troblecodings.signals.network; + +import java.util.List; +import java.util.Objects; + +import com.troblecodings.core.ReadBuffer; +import com.troblecodings.core.WriteBuffer; +import com.troblecodings.signals.OpenSignalsMain; +import com.troblecodings.signals.core.ModeIdentifier; +import com.troblecodings.signals.core.StateInfo; +import com.troblecodings.signals.core.SubsidiaryState; +import com.troblecodings.signals.core.TrainNumber; +import com.troblecodings.signals.enums.PathType; +import com.troblecodings.signals.enums.PathwayRequestResult; +import com.troblecodings.signals.enums.PathwayRequestResult.PathwayRequestMode; +import com.troblecodings.signals.guis.ContainerSignalBox; +import com.troblecodings.signals.handler.SignalBoxHandler; +import com.troblecodings.signals.signalbox.ModeSet; +import com.troblecodings.signals.signalbox.Point; +import com.troblecodings.signals.signalbox.SignalBoxGrid; +import com.troblecodings.signals.signalbox.SignalBoxNode; +import com.troblecodings.signals.signalbox.SignalBoxPathway; +import com.troblecodings.signals.signalbox.entrys.IPathEntry; +import com.troblecodings.signals.signalbox.entrys.PathEntryType; +import com.troblecodings.signals.signalbox.entrys.PathOptionEntry; + +import net.minecraft.util.math.BlockPos; + +public class SignalBoxNetworkHandler { + + private static final byte REMOVE = 0; + private static final byte ADD = 1; + + protected static final SignalBoxNetworkMode GRID = + new SignalBoxNetworkMode((b, n) -> n.readForGrid(b)); + + protected static final SignalBoxNetworkMode ENTRY = + new SignalBoxNetworkMode((b, n) -> n.readEntry(b)); + + protected static final SignalBoxNetworkMode NODE_SPECIAL_ENTRIES = + new SignalBoxNetworkMode((b, n) -> n.readNodeSpecialEntries(b)); + + protected static final SignalBoxNetworkMode PATHWAY = + new SignalBoxNetworkMode((b, n) -> n.readPathwayAction(b)); + + protected static final SignalBoxNetworkMode PATHWAY_SAVER = + new SignalBoxNetworkMode((b, n) -> n.readSavedPathway(b)); + + protected static final SignalBoxNetworkMode SUBSIDIARY = + new SignalBoxNetworkMode((b, n) -> n.readSubsidiary(b)); + + protected static final SignalBoxNetworkMode TRAINNUMBER = + new SignalBoxNetworkMode((b, n) -> n.readUpdateTrainNumber(b)); + + protected static final SignalBoxNetworkMode DEBUG_POINTS = + new SignalBoxNetworkMode((b, n) -> n.readDebugPoints(b)); + + protected ContainerSignalBox container = null; + + public void setUpNetwork(final ContainerSignalBox container) { + this.container = container; + } + + public void removeNetwork() { + this.container = null; + } + + protected boolean containerConnected() { + return container != null; + } + + public ContainerSignalBox getContainer() { + return container; + } + + public void sendModeAdd(final ModeIdentifier ident) { + if (!containerConnected()) + return; + sendBuffer(getEntryBuffer(ident, EntryNetworkMode.MODE_ADD)); + } + + public void sendModeRemove(final ModeIdentifier ident) { + if (!containerConnected()) + return; + sendBuffer(getEntryBuffer(ident, EntryNetworkMode.MODE_REMOVE)); + } + + public void sendEntryAdd(final ModeIdentifier ident, final PathEntryType entryType, + final IPathEntry entry) { + if (!containerConnected()) + return; + final WriteBuffer buffer = getEntryBuffer(ident, EntryNetworkMode.ENTRY_ADD); + buffer.putInt(entryType.getID()); + entry.writeNetwork(buffer); + sendBuffer(buffer); + } + + public void sendEntryRemove(final ModeIdentifier ident, final PathEntryType type) { + if (!containerConnected()) + return; + final WriteBuffer buffer = getEntryBuffer(ident, EntryNetworkMode.ENTRY_REMOVE); + buffer.putInt(type.getID()); + sendBuffer(buffer); + } + + public void sendAll() { + if (!containerConnected()) + return; + final WriteBuffer buffer = getGridBuffer(GridNetworkMode.SEND_ALL); + getGrid().writeNetwork(buffer); + container.addAdditionalInitialisationData(buffer); + sendBuffer(buffer); + } + + public void sendCounter() { + if (!containerConnected()) + return; + final WriteBuffer buffer = getGridBuffer(GridNetworkMode.COUNTER); + buffer.putInt(getGrid().getCurrentCounter()); + sendBuffer(buffer); + } + + public void sendNodeLabel(final Point point, final String label) { + if (!containerConnected()) + return; + final WriteBuffer buffer = getNodeBuffer(point, NodeNetworkMode.LABEL); + buffer.putString(label); + sendBuffer(buffer); + } + + public void sendAutoPoint(final Point point, final boolean autoPoint) { + if (!containerConnected()) + return; + final WriteBuffer buffer = getNodeBuffer(point, NodeNetworkMode.AUTO_POINT); + buffer.putBoolean(autoPoint); + sendBuffer(buffer); + } + + public void sendRequestPathway(final Point p1, final Point p2, final PathType type) { + if (!containerConnected()) + return; + final WriteBuffer buffer = getPathwayBuffer(PathwayNetworkMode.REQUEST); + p1.writeNetwork(buffer); + p2.writeNetwork(buffer); + buffer.putEnumValue(type); + sendBuffer(buffer); + } + + public void sendResetPathway(final Point p1) { + if (!containerConnected()) + return; + final WriteBuffer buffer = getPathwayBuffer(PathwayNetworkMode.RESET); + p1.writeNetwork(buffer); + sendBuffer(buffer); + } + + public void sendRequestResponse(final PathwayRequestResult result) { + if (!containerConnected()) + return; + final WriteBuffer buffer = getPathwayBuffer(PathwayNetworkMode.RESPONSE); + buffer.putEnumValue(result.getMode()); + sendBuffer(buffer); + } + + public void sendResetAllPathways() { + if (!containerConnected()) + return; + sendBuffer(getPathwayBuffer(PathwayNetworkMode.RESET_ALL_PATHWAYS)); + } + + public void sendResetAllSignals() { + if (!containerConnected()) + return; + sendBuffer(getPathwayBuffer(PathwayNetworkMode.RESET_ALL_SIGNALS)); + } + + public void sendAddSavedPathway(final Point start, final Point end, final PathType type, + final PathwayRequestResult result) { + if (!containerConnected()) + return; + final WriteBuffer buffer = getSavedPathwayBuffer(start, end); + buffer.putByte(ADD); + buffer.putEnumValue(type); + buffer.putEnumValue(result.getMode()); + sendBuffer(buffer); + } + + public void sendRemoveSavedPathway(final Point start, final Point end) { + if (!containerConnected()) + return; + final WriteBuffer buffer = getSavedPathwayBuffer(start, end); + buffer.putByte(REMOVE); + sendBuffer(buffer); + } + + public void sendRemovePos(final BlockPos pos) { + if (!containerConnected()) + return; + final WriteBuffer buffer = getGridBuffer(GridNetworkMode.REMOVE_POS); + buffer.putBlockPos(pos); + sendBuffer(buffer); + } + + public void sendSubsidiary(final ModeIdentifier ident, final SubsidiaryState entry, + final boolean enable) { + if (!containerConnected()) + return; + final WriteBuffer buffer = SUBSIDIARY.getBuffer(); + ident.writeNetwork(buffer); + entry.writeNetwork(buffer); + buffer.putBoolean(enable); + sendBuffer(buffer); + } + + public void sendManuellOutputAdd(final Point point, final ModeSet mode) { + sendManuellOutput(point, mode, NodeNetworkMode.MANUELL_OUTPUT_ADD); + } + + public void sendManuellOutputRemove(final Point point, final ModeSet mode) { + sendManuellOutput(point, mode, NodeNetworkMode.MANUELL_OUTPUT_REMOVE); + } + + private void sendManuellOutput(final Point point, final ModeSet mode, + final NodeNetworkMode network) { + final WriteBuffer buffer = getNodeBuffer(point, network); + mode.writeNetwork(buffer); + sendBuffer(buffer); + } + + public void updateTrainNumber(final Point point, final TrainNumber number) { + if (!containerConnected()) + return; + final WriteBuffer buffer = TRAINNUMBER.getBuffer(); + point.writeNetwork(buffer); + number.writeNetwork(buffer); + sendBuffer(buffer); + } + + public void sendDebugPoints(final List points) { + if (!containerConnected()) + return; + final WriteBuffer buffer = DEBUG_POINTS.getBuffer(); + buffer.putISaveableList(points); + sendBuffer(buffer); + } + + public void sendUpdateSignalStates(final SignalBoxNode node) { + if (!containerConnected()) + return; + final WriteBuffer buffer = getNodeBuffer(node.getPoint(), NodeNetworkMode.SIGNAL_STATE); + node.writeSignalStates(buffer); + sendBuffer(buffer); + } + + protected void readEntry(final ReadBuffer buffer) { + final EntryNetworkMode mode = buffer.getEnumValue(EntryNetworkMode.class); + final ModeIdentifier ident = ModeIdentifier.of(buffer); + final SignalBoxNode node = getGrid().getOrCreateNode(ident.point); + if (mode.equals(EntryNetworkMode.MODE_ADD) || mode.equals(EntryNetworkMode.MODE_REMOVE)) { + node.applyModeNetworkChanges(ident.mode); + node.post(); + return; + } + final PathEntryType entryType = PathEntryType.ALL_ENTRIES.get(buffer.getInt()); + final PathOptionEntry optionEntry = node.getOrCreateOption(ident.mode); + if (mode.equals(EntryNetworkMode.ENTRY_REMOVE)) { + optionEntry.removeEntryNoNetwork(entryType); + container.handleNodeUpdate(node, entryType); + return; + } + final IPathEntry entry = entryType.newValue(); + entry.readNetwork(buffer); + optionEntry.addEntry(entryType, entry); + container.handleNodeUpdate(node, entryType); + } + + protected void readForGrid(final ReadBuffer buffer) { + final SignalBoxGrid grid = getGrid(); + final GridNetworkMode mode = buffer.getEnumValue(GridNetworkMode.class); + if (mode.equals(GridNetworkMode.SEND_ALL)) { + grid.readNetwork(buffer); + container.readAdditionalInitialisationData(buffer); + } else if (mode.equals(GridNetworkMode.COUNTER)) { + grid.setCounterFromNetwork(buffer.getInt()); + container.handleCounterUpdate(); + } else { + final BlockPos pos = buffer.getBlockPos(); + SignalBoxHandler.unlinkPosFromSignalBox(new StateInfo(container.getTile().getLevel(), + container.getTile().getBlockPos()), pos); + } + } + + protected void readNodeSpecialEntries(final ReadBuffer buffer) { + final NodeNetworkMode mode = buffer.getEnumValue(NodeNetworkMode.class); + final Point point = Point.of(buffer); + final SignalBoxGrid grid = getGrid(); + final SignalBoxNode node = grid.getNode(point); + if (mode.equals(NodeNetworkMode.LABEL)) { + node.setCustomText(buffer.getString()); + } + if (mode.equals(NodeNetworkMode.AUTO_POINT)) { + node.setAutoPointFromNetwork(buffer.getBoolean()); + grid.updatePathwayToAutomatic(point); + } + if (mode.equals(NodeNetworkMode.MANUELL_OUTPUT_ADD) + || mode.equals(NodeNetworkMode.MANUELL_OUTPUT_REMOVE)) { + handleManuellOutput(node, buffer.getINetworkSaveable(ModeSet.class), mode); + } + if (mode.equals(NodeNetworkMode.SIGNAL_STATE)) { + node.readSignalStates(buffer); + container.handleSignalStateUpdate(node); + } + } + + protected void handleManuellOutput(final SignalBoxNode node, final ModeSet mode, + final NodeNetworkMode network) { + final boolean state = network.equals(NodeNetworkMode.MANUELL_OUTPUT_ADD) ? true : false; + if (container.isClientSide()) { + node.handleManuellEnabledOutputUpdate(mode, state); + } else { + getGrid().updateManuellRSOutput(node.getPoint(), mode, state); + } + } + + protected void readPathwayAction(final ReadBuffer buffer) { + final SignalBoxGrid grid = getGrid(); + final PathwayNetworkMode mode = buffer.getEnumValue(PathwayNetworkMode.class); + if (mode.equals(PathwayNetworkMode.RESPONSE)) { + container.handlePathwayRequestResponse(buffer.getEnumValue(PathwayRequestMode.class)); + return; + } + if (mode.equals(PathwayNetworkMode.RESET_ALL_PATHWAYS)) { + grid.resetAllPathways(); + return; + } + if (mode.equals(PathwayNetworkMode.RESET_ALL_SIGNALS)) { + grid.resetAllSignals(); + return; + } + final Point p1 = Point.of(buffer); + if (mode.equals(PathwayNetworkMode.RESET)) { + resetPathway(p1); + return; + } + final Point p2 = Point.of(buffer); + final PathType type = buffer.getEnumValue(PathType.class); + final PathwayRequestResult request = grid.requestWay(p1, p2, type); + if (!request.wasSuccesfull()) { + final SignalBoxNode endNode = grid.getNode(p2); + if (request.canBeAddedToSaver(type) && !endNode.containsOutConnection() + && grid.addNextPathway(p1, p2, type)) { + sendAddSavedPathway(p1, p2, type, request); + return; + } + sendRequestResponse(request); + } + } + + protected void resetPathway(final Point p1) { + final SignalBoxGrid grid = getGrid(); + final SignalBoxPathway pw = grid.getPathwayByStartPoint(p1); + final boolean isShuntingPath = pw != null ? pw.isShuntingPath() : false; + if (grid.resetPathway(p1) && !isShuntingPath) { + grid.count(); + } + } + + protected void readSavedPathway(final ReadBuffer buffer) { + final Point p1 = Point.of(buffer); + final Point p2 = Point.of(buffer); + final byte state = buffer.getByte(); + if (state == REMOVE) { + getGrid().removeNextPathway(p1, p2); + container.handleRemoveSavedPathway(p1, p2); + return; + } + final PathType type = buffer.getEnumValue(PathType.class); + final PathwayRequestMode result = buffer.getEnumValue(PathwayRequestMode.class); + container.handleAddSavedPathway(p1, p2, type, result); + } + + protected void readSubsidiary(final ReadBuffer buffer) { + final ModeIdentifier ident = ModeIdentifier.of(buffer); + final SubsidiaryState entry = SubsidiaryState.of(buffer); + final boolean state = buffer.getBoolean(); + container.updateServerSubsidiary(ident, entry, state); + } + + protected void readUpdateTrainNumber(final ReadBuffer buffer) { + final Point point = Point.of(buffer); + final TrainNumber number = TrainNumber.of(buffer); + getGrid().updateTrainNumber(point, number); + } + + protected void readDebugPoints(final ReadBuffer buffer) { + container.handleDebugPoints( + buffer.getList(ReadBuffer.getINetworkSaveableFunction(Point.class))); + } + + protected WriteBuffer getSavedPathwayBuffer(final Point p1, final Point p2) { + final WriteBuffer buffer = PATHWAY_SAVER.getBuffer(); + p1.writeNetwork(buffer); + p2.writeNetwork(buffer); + return buffer; + } + + protected WriteBuffer getNodeBuffer(final Point point, final NodeNetworkMode mode) { + final WriteBuffer buffer = NODE_SPECIAL_ENTRIES.getBuffer(); + buffer.putEnumValue(mode); + point.writeNetwork(buffer); + return buffer; + } + + protected WriteBuffer getGridBuffer(final GridNetworkMode mode) { + final WriteBuffer buffer = GRID.getBuffer(); + buffer.putEnumValue(mode); + return buffer; + } + + protected WriteBuffer getPathwayBuffer(final PathwayNetworkMode mode) { + final WriteBuffer buffer = PATHWAY.getBuffer(); + buffer.putEnumValue(mode); + return buffer; + } + + protected WriteBuffer getEntryBuffer(final ModeIdentifier ident, final EntryNetworkMode mode) { + final WriteBuffer buffer = ENTRY.getBuffer(); + buffer.putEnumValue(mode); + ident.writeNetwork(buffer); + return buffer; + } + + protected SignalBoxGrid getGrid() { + return container.getGrid(); + } + + public void desirializeBuffer(final ReadBuffer buffer) { + final SignalBoxNetworkMode mode = SignalBoxNetworkMode.getModeFromBuffer(buffer); + mode.executeRead(buffer, this); + } + + protected void sendBuffer(final WriteBuffer buffer) { + if (!containerConnected()) + return; + OpenSignalsMain.network.sendTo(container.getPlayer(), buffer); + } + + @Override + public int hashCode() { + return Objects.hash(container); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if ((obj == null) || (getClass() != obj.getClass())) + return false; + SignalBoxNetworkHandler other = (SignalBoxNetworkHandler) obj; + return Objects.equals(container, other.container); + } + + protected static enum PathwayNetworkMode { + REQUEST, RESET, RESPONSE, RESET_ALL_PATHWAYS, RESET_ALL_SIGNALS; + } + + protected static enum NodeNetworkMode { + LABEL, AUTO_POINT, MANUELL_OUTPUT_ADD, MANUELL_OUTPUT_REMOVE, SIGNAL_STATE; + } + + protected static enum GridNetworkMode { + SEND_ALL, COUNTER, REMOVE_POS; + } + + protected static enum EntryNetworkMode { + MODE_ADD, MODE_REMOVE, ENTRY_ADD, ENTRY_REMOVE; + } +} \ No newline at end of file diff --git a/src/main/java/com/troblecodings/signals/network/SignalBoxNetworkMode.java b/src/main/java/com/troblecodings/signals/network/SignalBoxNetworkMode.java new file mode 100644 index 000000000..b5d8e7c63 --- /dev/null +++ b/src/main/java/com/troblecodings/signals/network/SignalBoxNetworkMode.java @@ -0,0 +1,53 @@ +package com.troblecodings.signals.network; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.function.BiConsumer; + +import com.troblecodings.core.ReadBuffer; +import com.troblecodings.core.WriteBuffer; + +public class SignalBoxNetworkMode { + + private static final List NETWORK_ENTRIES = new ArrayList<>(); + + private int id; + private final BiConsumer read; + + public SignalBoxNetworkMode(final BiConsumer read) { + this.read = read; + this.id = NETWORK_ENTRIES.size(); + NETWORK_ENTRIES.add(this); + } + + public static SignalBoxNetworkMode getModeFromBuffer(final ReadBuffer buffer) { + return NETWORK_ENTRIES.get(buffer.getInt()); + } + + public void executeRead(final ReadBuffer buffer, final SignalBoxNetworkHandler network) { + read.accept(buffer, network); + } + + public WriteBuffer getBuffer() { + final WriteBuffer buffer = new WriteBuffer(); + buffer.putInt(id); + return buffer; + } + + @Override + public int hashCode() { + return Objects.hash(id, read); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if ((obj == null) || (getClass() != obj.getClass())) + return false; + final SignalBoxNetworkMode other = (SignalBoxNetworkMode) obj; + return id == other.id && Objects.equals(read, other.read); + } + +} \ No newline at end of file diff --git a/src/main/java/com/troblecodings/signals/signalbox/InterSignalBoxPathway.java b/src/main/java/com/troblecodings/signals/signalbox/InterSignalBoxPathway.java index f88e7dd0e..831feba9b 100644 --- a/src/main/java/com/troblecodings/signals/signalbox/InterSignalBoxPathway.java +++ b/src/main/java/com/troblecodings/signals/signalbox/InterSignalBoxPathway.java @@ -1,7 +1,5 @@ package com.troblecodings.signals.signalbox; -import java.util.ArrayList; -import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicReference; @@ -70,8 +68,9 @@ public void postRead(final NBTWrapper tag) { } else { final AtomicReference otherGrid = new AtomicReference<>(); otherGrid.set(SignalBoxHandler.getGrid(new StateInfo(world, otherPos))); - if (otherGrid.get() == null) + if (otherGrid.get() == null) { loadTileAndExecute(otherPos, tile -> otherGrid.set(tile.getSignalBoxGrid())); + } final SignalBoxPathway otherPathway = otherGrid.get().getPathwayByLastPoint(end); pathwayToBlock = (InterSignalBoxPathway) otherPathway; @@ -88,8 +87,9 @@ public void postRead(final NBTWrapper tag) { } else { final AtomicReference otherGrid = new AtomicReference<>(); otherGrid.set(SignalBoxHandler.getGrid(new StateInfo(world, otherPos))); - if (otherGrid.get() == null) + if (otherGrid.get() == null) { loadTileAndExecute(otherPos, tile -> otherGrid.set(tile.getSignalBoxGrid())); + } final SignalBoxPathway otherPathway = otherGrid.get().getPathwayByLastPoint(end); pathwayToReset = (InterSignalBoxPathway) otherPathway; @@ -106,13 +106,16 @@ public void onLoad() { if (blockPW != null) { final AtomicReference otherGrid = new AtomicReference<>(); otherGrid.set(SignalBoxHandler.getGrid(new StateInfo(world, blockPW.getKey()))); - if (otherGrid.get() == null) + if (otherGrid.get() == null) { loadTileAndExecute(blockPW.getKey(), tile -> otherGrid.set(tile.getSignalBoxGrid())); + } if (otherGrid.get() != null) { - final SignalBoxPathway otherPathway = otherGrid.get() - .getPathwayByLastPoint(blockPW.getValue()); + final SignalBoxPathway otherPathway = + otherGrid.get().getPathwayByLastPoint(blockPW.getValue()); + if (!(otherPathway instanceof InterSignalBoxPathway)) + return; pathwayToBlock = (InterSignalBoxPathway) otherPathway; blockPW = null; } @@ -120,13 +123,16 @@ public void onLoad() { if (resetPW != null) { final AtomicReference otherGrid = new AtomicReference<>(); otherGrid.set(SignalBoxHandler.getGrid(new StateInfo(world, resetPW.getKey()))); - if (otherGrid.get() == null) + if (otherGrid.get() == null) { loadTileAndExecute(resetPW.getKey(), tile -> otherGrid.set(tile.getSignalBoxGrid())); + } if (otherGrid.get() != null) { - final SignalBoxPathway otherPathway = otherGrid.get() - .getPathwayByLastPoint(resetPW.getValue()); + final SignalBoxPathway otherPathway = + otherGrid.get().getPathwayByLastPoint(resetPW.getValue()); + if (!(otherPathway instanceof InterSignalBoxPathway)) + return; pathwayToReset = (InterSignalBoxPathway) otherPathway; resetPW = null; } @@ -139,12 +145,13 @@ protected SignalStateInfo getLastSignalInfo() { if (pathwayToBlock != null) { final MainSignalIdentifier otherLastSignal = pathwayToBlock.data.getEndSignal(); if (otherLastSignal != null) { - final Signal nextSignal = SignalBoxHandler - .getSignal(new StateInfo(pathwayToBlock.tile.getLevel(), + final Signal nextSignal = + SignalBoxHandler.getSignal(new StateInfo(pathwayToBlock.tile.getLevel(), pathwayToBlock.tile.getBlockPos()), otherLastSignal.pos); - if (nextSignal != null) - lastSignalInfo = new SignalStateInfo(tile.getLevel(), otherLastSignal.pos, - nextSignal); + if (nextSignal != null) { + lastSignalInfo = + new SignalStateInfo(tile.getLevel(), otherLastSignal.pos, nextSignal); + } } } return super.getLastSignalInfo(); @@ -183,7 +190,6 @@ public boolean tryBlock(final BlockPos position) { .getPathwayByLastPoint(pathwayToBlock.getLastPoint()); pathwayToBlock.setPathStatus(EnumPathUsage.BLOCKED); pathwayToBlock.updateTrainNumber(trainNumber); - otherGrid.updateToNet(pathwayToBlock); }); } return result; @@ -191,37 +197,35 @@ public boolean tryBlock(final BlockPos position) { @Override protected void updateSignalStates() { - final List nodes = new ArrayList<>(); final MainSignalIdentifier startSignal = data.getStartSignal(); final MainSignalIdentifier lastSignal = data.getEndSignal(); if (startSignal != null) { if (isBlocked) return; startSignal.updateSignalState(SignalState.GREEN); - nodes.add(startSignal.node); data.getPreSignals().forEach(signalIdent -> { signalIdent.updateSignalState(SignalState.GREEN); - nodes.add(signalIdent.node); }); } - final Map distantSignalPositions = data - .getOtherSignals(); + final Map distantSignalPositions = + data.getOtherSignals(); distantSignalPositions.forEach((holder, position) -> { if (holder.shouldTurnSignalOff()) { position.updateSignalState(SignalState.OFF); - nodes.add(position.node); return; } final SignalBoxPathway next = getNextPathway(); SignalState toSet = SignalState.RED; if (lastSignal != null && next != null && !next.isEmptyOrBroken()) { - if (!next.isExecutingSignalSet) + if (!next.isExecutingSignalSet) { toSet = SignalState.GREEN; + } } else if (pathwayToBlock != null) { final SignalBoxPathway otherNext = pathwayToBlock.getNextPathway(); if (otherNext != null && !otherNext.isEmptyOrBroken()) { - if (!otherNext.isExecutingSignalSet) + if (!otherNext.isExecutingSignalSet) { toSet = SignalState.GREEN; + } } else { toSet = SignalState.RED; } @@ -234,16 +238,18 @@ protected void updateSignalStates() { toSet = SignalState.OFF; } position.updateSignalState(toSet); - nodes.add(position.node); }); - updateSignalsOnClient(nodes); } public void setOtherPathwayToBlock(final InterSignalBoxPathway pathway) { + if (!(pathway instanceof InterSignalBoxPathway)) + return; this.pathwayToBlock = pathway; } public void setOtherPathwayToReset(final InterSignalBoxPathway pathway) { + if (!(pathway instanceof InterSignalBoxPathway)) + return; this.pathwayToReset = pathway; } diff --git a/src/main/java/com/troblecodings/signals/signalbox/PathwayData.java b/src/main/java/com/troblecodings/signals/signalbox/PathwayData.java index 456085d2d..dd1715f91 100644 --- a/src/main/java/com/troblecodings/signals/signalbox/PathwayData.java +++ b/src/main/java/com/troblecodings/signals/signalbox/PathwayData.java @@ -23,6 +23,7 @@ import com.google.common.collect.ImmutableMap; import com.troblecodings.core.NBTWrapper; import com.troblecodings.signals.OpenSignalsMain; +import com.troblecodings.signals.config.ConfigHandler; import com.troblecodings.signals.core.BlockPosSignalHolder; import com.troblecodings.signals.core.JsonEnumHolder; import com.troblecodings.signals.core.ModeIdentifier; @@ -51,6 +52,8 @@ public class PathwayData { private static final String PATH_TYPE = "pathType"; private static final String LIST_OF_PROTECTIONWAY_NODES = "listOfProtectionWayNodes"; private static final String IS_INTERSIGNALBOX_PATHWAY = "isInterSignalBoxPathway"; + private static final boolean CAN_INPUT_BLOCK_SHUNTING_PATH = + ConfigHandler.GENERAL.canInputBlockShuntingPath.get(); protected SignalBoxGrid grid = null; private final Map mapOfResetPositions = new HashMap<>(); @@ -161,7 +164,9 @@ private boolean checkForShuntingPath() { this.initalize(); break; } - if (current.isUsedInDirection(oldPos, EnumPathUsage.PROTECTED)) + if (current.isUsedInDirection(oldPos, EnumPathUsage.PROTECTED) + || (CAN_INPUT_BLOCK_SHUNTING_PATH + && SignalBoxUtil.isPathBlocked(grid, current, path))) return false; } return true; @@ -173,7 +178,8 @@ private boolean checkForProtectionWay() { final MainSignalIdentifier signalIdent = endSignal.get(); final PathOptionEntry option = grid.getNode(signalIdent.getPoint()) .getOption(signalIdent.getModeSet()).orElse(null); - if ((option == null) || grid.startsToPath.containsKey(lastPoint)) + final SignalBoxPathway next = grid.getPathwayByStartPoint(lastPoint); + if ((option == null) || next != null && !next.isBlocked) return true; final Point protectionWayEnd = option.getEntry(PathEntryType.PROTECTIONWAY_END).orElse(lastPoint); @@ -228,8 +234,6 @@ protected boolean resetProtectionWay() { if (pw == null) return; pw.directResetOfProtectionWay(); - pw.removeProtectionWay(); - grid.updateToNet(pw); })); }).start(); return true; @@ -249,10 +253,11 @@ protected boolean directResetOfProtectionWay() { .updateRedstoneOutput(new StateInfo(pathway.tile.getLevel(), pos), false)); option.removeEntry(PathEntryType.PATHUSAGE); }); + removeProtectionWay(); return true; } - protected void removeProtectionWay() { + private void removeProtectionWay() { this.protectionWayNodes = ImmutableList.of(); } @@ -290,7 +295,7 @@ private void initalize() { .ifPresent(value -> zs6State.set(value.booleanValue())); optionEntry.getEntry(PathEntryType.CONNECTED_TRAINNUMBER).ifPresent(ident -> { final Optional entry = grid.getNodeChecked(ident.point) - .orElse(new SignalBoxNode()).getOption(ident.mode); + .orElse(new SignalBoxNode(grid.getNetwork())).getOption(ident.mode); if (entry.isPresent()) { trainNumberDisplays.add(ident); } else { @@ -363,8 +368,9 @@ private void initalize() { entry.getEntry(PathEntryType.PRESIGNALS).orElse(new ArrayList<>()); posIdents.removeIf(ident -> !grid.getNode(ident.getPoint()).has(ident.getModeSet())); this.preSignals = ImmutableList.copyOf(posIdents.stream().map(ident -> { - final PathOptionEntry vpEntry = grid.getNode(ident.getPoint()) - .getOption(ident.getModeSet()).orElse(new PathOptionEntry()); + final PathOptionEntry vpEntry = + grid.getNode(ident.getPoint()).getOption(ident.getModeSet()) + .orElse(SignalBoxFactory.getFactory().getEntry()); return new OtherSignalIdentifier(ident.getPoint(), ident.getModeSet(), ident.pos, vpEntry.getEntry(PathEntryType.SIGNAL_REPEATER).orElse(false), EnumGuiMode.VP, grid); diff --git a/src/main/java/com/troblecodings/signals/signalbox/SignalBoxGrid.java b/src/main/java/com/troblecodings/signals/signalbox/SignalBoxGrid.java index 07180f36c..14da8d175 100644 --- a/src/main/java/com/troblecodings/signals/signalbox/SignalBoxGrid.java +++ b/src/main/java/com/troblecodings/signals/signalbox/SignalBoxGrid.java @@ -1,6 +1,5 @@ package com.troblecodings.signals.signalbox; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -21,13 +20,16 @@ import com.troblecodings.signals.blocks.CombinedRedstoneInput; import com.troblecodings.signals.core.NetworkBufferWrappers; import com.troblecodings.signals.core.RedstoneUpdatePacket; +import com.troblecodings.signals.core.StateInfo; import com.troblecodings.signals.core.SubsidiaryState; import com.troblecodings.signals.core.TrainNumber; import com.troblecodings.signals.enums.EnumPathUsage; import com.troblecodings.signals.enums.PathType; import com.troblecodings.signals.enums.PathwayRequestResult; import com.troblecodings.signals.enums.PathwayRequestResult.PathwayRequestMode; -import com.troblecodings.signals.enums.SignalBoxNetwork; +import com.troblecodings.signals.guis.ContainerSignalBox; +import com.troblecodings.signals.handler.SignalBoxHandler; +import com.troblecodings.signals.network.SignalBoxNetworkHandler; import com.troblecodings.signals.signalbox.debug.SignalBoxFactory; import com.troblecodings.signals.signalbox.entrys.PathEntryType; import com.troblecodings.signals.signalbox.entrys.PathOptionEntry; @@ -54,9 +56,14 @@ public class SignalBoxGrid implements INetworkSaveable, ISaveable { protected final SignalBoxFactory factory; protected SignalBoxTileEntity tile; private int counter; + private final SignalBoxNetworkHandler network = new SignalBoxNetworkHandler(); public SignalBoxGrid() { - this.factory = SignalBoxFactory.getFactory(); + this(SignalBoxFactory.getFactory()); + } + + public SignalBoxGrid(final SignalBoxFactory factory) { + this.factory = factory; } public void setTile(final SignalBoxTileEntity tile) { @@ -96,7 +103,6 @@ public boolean resetPathway(final Point p1) { return false; } resetPathway(pathway); - updateToNet(pathway); tryNextPathways(); return true; } @@ -105,12 +111,7 @@ private boolean checkManuellResetOfProtectionWay(final Point p1) { final SignalBoxPathway pathway = endsToPath.get(p1); if (pathway == null) return false; - final boolean isReset = pathway.directResetOfProtectionWay(); - if (isReset) { - updateToNet(pathway); - pathway.removeProtectionWay(); - } - return isReset; + return pathway.directResetOfProtectionWay(); } protected void resetPathway(final SignalBoxPathway pathway) { @@ -122,48 +123,42 @@ protected void resetPathway(final SignalBoxPathway pathway) { } public void updateMode(final Point point, final ModeSet mode) { - final SignalBoxNode node = this.modeGrid.computeIfAbsent(point, SignalBoxNode::new); + final SignalBoxNode node = + this.modeGrid.computeIfAbsent(point, p -> new SignalBoxNode(p, network)); if (!node.has(mode)) { node.add(mode); } else { node.remove(mode); } + node.post(); } - protected void updateToNet(final SignalBoxPathway pathway) { - if (tile == null || !tile.isBlocked()) - return; - final List allNodes = new ArrayList<>(); - allNodes.addAll(pathway.getListOfNodes()); - allNodes.addAll(pathway.getProtectionWayNodes()); - final WriteBuffer buffer = new WriteBuffer(); - buffer.putEnumValue(SignalBoxNetwork.SEND_PW_UPDATE); - buffer.putList(allNodes, NetworkBufferWrappers.POINT_SIGNALBOXNODE_CONSUMER); - OpenSignalsMain.network.sendTo(tile.get(0).getPlayer(), buffer); + public void setUpNetwork(final ContainerSignalBox container) { + network.setUpNetwork(container); + } + + public void removeNetwork() { + network.removeNetwork(); + } + + public SignalBoxNetworkHandler getNetwork() { + return network; } public PathwayRequestResult requestWay(final Point p1, final Point p2, final PathType type) { - try { - final PathwayRequestResult result = SignalBoxUtil.requestPathway(this, p1, p2, type); - if (!result.wasSuccesfull()) { - if (result.getMode().equals(PathwayRequestMode.PASS)) - return PathwayRequestResult.getByMode(PathwayRequestMode.NO_PATH); - return result; - } - final PathwayData data = result.getPathwayData(); - if (checkPathwayData(data)) - return PathwayRequestResult.getByMode(PathwayRequestMode.ALREADY_USED); - if (data.isEmpty()) + final PathwayRequestResult result = SignalBoxUtil.requestPathway(this, p1, p2, type); + if (!result.wasSuccesfull()) { + if (result.getMode().equals(PathwayRequestMode.PASS)) return PathwayRequestResult.getByMode(PathwayRequestMode.NO_PATH); - addPathway(data); return result; - } catch (final Exception e) { - OpenSignalsMain.getLogger().error("There was an issue with creating a pathway from " - + p1 + " to " + p2 + "! Resetting!"); - e.printStackTrace(); - resetPathway(p1); } - return PathwayRequestResult.getByMode(PathwayRequestMode.NO_PATH); + final PathwayData data = result.getPathwayData(); + if (checkPathwayData(data)) + return PathwayRequestResult.getByMode(PathwayRequestMode.ALREADY_USED); + if (data.isEmpty()) + return PathwayRequestResult.getByMode(PathwayRequestMode.NO_PATH); + addPathway(data); + return result; } private boolean checkPathwayData(final PathwayData data) { @@ -179,7 +174,6 @@ protected void addPathway(final PathwayData data) { way.setUpPathwayStatus(); way.updatePathwaySignals(); onWayAdd(way); - updateToNet(way); } protected void updatePrevious(final SignalBoxPathway pathway) { @@ -202,7 +196,6 @@ protected void updatePrevious(final SignalBoxPathway pathway) { public void resetAllPathways() { ImmutableSet.copyOf(this.startsToPath.values()).forEach(this::resetPathway); clearPaths(); - modeGrid.values().forEach(SignalBoxNode::resetEnumPathUsage); } public void resetAllSignals() { @@ -237,18 +230,8 @@ public void updateInput(final RedstoneUpdatePacket update) { private void tryBlock(final List pathways, final BlockPos pos) { pathways.forEach(pathway -> { - try { - if (pathway.tryBlock(pos)) { - updatePrevious(pathway); - updateToNet(pathway); - } - } catch (final Exception e) { - OpenSignalsMain.getLogger().error( - "There was an issue while trying to block " + pathway + "! Resetting!"); - e.printStackTrace(); - resetPathway(pathway); - updateToNet(pathway); - tryNextPathways(); + if (pathway.tryBlock(pos)) { + updatePrevious(pathway); } }); @@ -256,31 +239,19 @@ private void tryBlock(final List pathways, final BlockPos pos) private void tryReset(final List pathways, final BlockPos pos) { pathways.forEach(pathway -> { - try { - final Point first = pathway.getFirstPoint(); - final Optional optPoint = pathway.tryReset(pos); - if (optPoint.isPresent()) { - if (pathway.isEmptyOrBroken()) { - resetPathway(pathway); - updateToNet(pathway); - pathway.checkReRequest(); - } else { - updateToNet(pathway); - pathway.compact(optPoint.get()); - this.startsToPath.remove(first); - this.startsToPath.put(pathway.getFirstPoint(), pathway); - } - } - if (pathway.checkResetOfProtectionWay(pos)) { - updateToNet(pathway); + final Point first = pathway.getFirstPoint(); + final Optional optPoint = pathway.tryReset(pos); + if (optPoint.isPresent()) { + if (pathway.isEmptyOrBroken()) { + resetPathway(pathway); + pathway.checkReRequest(); + } else { + pathway.compact(optPoint.get()); + this.startsToPath.remove(first); + this.startsToPath.put(pathway.getFirstPoint(), pathway); } - } catch (final Exception e) { - OpenSignalsMain.getLogger().error( - "There was an issue while trying to reset " + pathway + "! Resetting!"); - e.printStackTrace(); - resetPathway(pathway); - updateToNet(pathway); } + pathway.checkResetOfProtectionWay(pos); }); tryNextPathways(); } @@ -296,13 +267,7 @@ private void tryNextPathways() { requestWay(pointEntry.getKey(), pointEntry.getValue(), type); if (request.wasSuccesfull()) { nextPathways.remove(pointEntry); - if (tile != null && tile.isBlocked()) { - final WriteBuffer buffer = new WriteBuffer(); - buffer.putEnumValue(SignalBoxNetwork.REMOVE_SAVEDPW); - pointEntry.getKey().writeNetwork(buffer); - pointEntry.getValue().writeNetwork(buffer); - OpenSignalsMain.network.sendTo(tile.get(0).getPlayer(), buffer); - } + network.sendRemoveSavedPathway(pointEntry.getKey(), pointEntry.getValue()); } }); executingTryNextPWs = false; @@ -333,7 +298,8 @@ public SignalBoxPathway getPathwayByLastPoint(final Point end) { } public void updateTrainNumber(final Point point, final TrainNumber number) { - final SignalBoxNode node = modeGrid.computeIfAbsent(point, p -> new SignalBoxNode(p)); + final SignalBoxNode node = + modeGrid.computeIfAbsent(point, p -> new SignalBoxNode(p, network)); startsToPath.values().forEach(pathway -> pathway.checkTrainNumberUpdate(number, node)); tile.setChanged(); } @@ -381,7 +347,7 @@ public void writePathways(final NBTWrapper tag) { public void read(final NBTWrapper tag) { modeGrid.clear(); tag.getList(NODE_LIST).forEach(comp -> { - final SignalBoxNode node = new SignalBoxNode(); + final SignalBoxNode node = new SignalBoxNode(network); node.read(comp); modeGrid.put(node.getPoint(), node); final List subsidiaryTags = comp.getList(SUBSIDIARY_LIST); @@ -456,6 +422,10 @@ public SignalBoxNode getNode(final Point point) { return modeGrid.get(point); } + public SignalBoxNode getOrCreateNode(final Point point) { + return modeGrid.computeIfAbsent(point, p -> new SignalBoxNode(p, network)); + } + public Optional getNodeChecked(final Point point) { return Optional.ofNullable(getNode(point)); } @@ -474,6 +444,11 @@ public void count() { public void setCounter(final int counter) { this.counter = (counter < MAX_COUNTS ? counter : 0); + network.sendCounter(); + } + + public void setCounterFromNetwork(final int counter) { + this.counter = counter; } protected Map getModeGrid() { @@ -489,7 +464,7 @@ public void readNetwork(final ReadBuffer buffer) { modeGrid.clear(); modeGrid.putAll(buffer.getMapWithCombinedValueFunc( ReadBuffer.getINetworkSaveableFunction(Point.class), - (b, point) -> NetworkBufferWrappers.getSignalBoxNodeFunc(point).apply(b))); + (b, point) -> NetworkBufferWrappers.getSignalBoxNodeFunc(point, network).apply(b))); counter = buffer.getInt(); } @@ -499,38 +474,19 @@ public void writeNetwork(final WriteBuffer buffer) { buffer.putInt(counter); } - public List readUpdateNetwork(final ReadBuffer buffer, final boolean override) { - return buffer.getList((buf) -> { - final Point point = Point.of(buf); - SignalBoxNode node; - if (override) { - node = new SignalBoxNode(point); - } else { - node = modeGrid.computeIfAbsent(point, _u -> new SignalBoxNode(point)); - } - node.readNetwork(buf); - modeGrid.put(point, node); - return node; - }); - } - - public BlockPos updateManuellRSOutput(final Point point, final ModeSet mode, - final boolean state) { + public void updateManuellRSOutput(final Point point, final ModeSet mode, final boolean state) { final SignalBoxNode node = modeGrid.get(point); if (node == null) - return null; + return; final PathOptionEntry entry = node.getOption(mode).get(); final Optional outputPos = entry.getEntry(PathEntryType.OUTPUT); final EnumPathUsage usage = entry.getEntry(PathEntryType.PATHUSAGE).orElse(EnumPathUsage.FREE); if (!outputPos.isPresent() || !usage.equals(EnumPathUsage.FREE)) - return null; - if (state) { - node.addManuellOutput(mode); - } else { - node.removeManuellOutput(mode); - } - return outputPos.get(); + return; + node.handleManuellEnabledOutputUpdate(mode, state); + SignalBoxHandler.updateRedstoneOutput(new StateInfo(tile.getLevel(), outputPos.get()), + state); } public List getAllPoints() { @@ -538,11 +494,6 @@ public List getAllPoints() { } public void sendDebugPointUpdates(final List points) { - if (tile == null || !tile.isBlocked()) - return; - final WriteBuffer buffer = new WriteBuffer(); - buffer.putEnumValue(SignalBoxNetwork.SEND_DEBUG_POINTS); - buffer.putISaveableList(points); - OpenSignalsMain.network.sendTo(tile.get(0).getPlayer(), buffer); + network.sendDebugPoints(points); } } \ No newline at end of file diff --git a/src/main/java/com/troblecodings/signals/signalbox/SignalBoxNode.java b/src/main/java/com/troblecodings/signals/signalbox/SignalBoxNode.java index 64e787583..d3c144c42 100644 --- a/src/main/java/com/troblecodings/signals/signalbox/SignalBoxNode.java +++ b/src/main/java/com/troblecodings/signals/signalbox/SignalBoxNode.java @@ -13,18 +13,20 @@ import javax.annotation.Nullable; -import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.troblecodings.core.NBTWrapper; import com.troblecodings.core.ReadBuffer; import com.troblecodings.core.WriteBuffer; import com.troblecodings.core.interfaces.INetworkSaveable; import com.troblecodings.core.interfaces.ISaveable; +import com.troblecodings.signals.core.ModeIdentifier; import com.troblecodings.signals.core.SubsidiaryState; import com.troblecodings.signals.enums.EnumGuiMode; import com.troblecodings.signals.enums.EnumPathUsage; import com.troblecodings.signals.enums.PathType; import com.troblecodings.signals.enums.PathwayRequestResult.PathwayRequestMode; +import com.troblecodings.signals.network.PathOptionEntryNetwork; +import com.troblecodings.signals.network.SignalBoxNetworkHandler; import com.troblecodings.signals.signalbox.MainSignalIdentifier.SignalState; import com.troblecodings.signals.signalbox.SignalBoxUtil.PathIdentifier; import com.troblecodings.signals.signalbox.debug.SignalBoxFactory; @@ -42,32 +44,57 @@ public class SignalBoxNode implements INetworkSaveable, ISaveable, Iterable enabledSubsidiaryStates = new HashMap<>(); private final List manuellEnabledOutputs = new ArrayList<>(); private final Point point; + private final SignalBoxNetworkHandler network; + private final SignalBoxFactory factory = SignalBoxFactory.getFactory(); private boolean isAutoPoint = false; private String customText = ""; - public SignalBoxNode() { - this(new Point()); + public SignalBoxNode(final SignalBoxNetworkHandler network) { + this(new Point(), network); } - public SignalBoxNode(final Point point) { + public SignalBoxNode(final Point point, final SignalBoxNetworkHandler network) { this.point = Objects.requireNonNull(point); + this.network = Objects.requireNonNull(network); } public void add(final ModeSet modeSet) { - possibleModes.put(modeSet, SignalBoxFactory.getFactory().getEntry()); + final ModeIdentifier ident = new ModeIdentifier(point, modeSet); + final PathOptionEntry entry = factory.getEntry(); + entry.setUpNetwork(new PathOptionEntryNetwork().setUpNetwork(network, ident)); + possibleModes.put(modeSet, entry); + network.sendModeAdd(ident); + } + + public boolean has(final ModeSet modeSet) { + return possibleModes.containsKey(modeSet); + } + + public void remove(final ModeSet modeSet) { + possibleModes.remove(modeSet); + network.sendModeRemove(new ModeIdentifier(point, modeSet)); } public void addAndSetEntry(final ModeSet mode, final PathEntryType entry, final T type) { - final PathOptionEntry optionEntry = possibleModes.computeIfAbsent(mode, - _u -> SignalBoxFactory.getFactory().getEntry()); + final PathOptionEntry optionEntry = + possibleModes.computeIfAbsent(mode, _u -> factory.getEntry()); + optionEntry.setUpNetwork(new PathOptionEntryNetwork().setUpNetwork(network, + new ModeIdentifier(point, mode))); optionEntry.setEntry(entry, type); } public void updateState(final ModeSet modeSet, final SignalState state) { - if (state == SignalState.RED) + updateStateNoNetwork(modeSet, state); + network.sendUpdateSignalStates(this); + } + + public void updateStateNoNetwork(final ModeSet modeSet, final SignalState state) { + if (state == SignalState.RED) { this.signalStates.remove(modeSet); - else + this.enabledSubsidiaryStates.remove(modeSet); + } else { this.signalStates.put(modeSet, state); + } } public SignalState getState(final ModeSet modeSet) { @@ -90,38 +117,35 @@ public Map getSubsidiaryStates() { return ImmutableMap.copyOf(enabledSubsidiaryStates); } - public boolean has(final ModeSet modeSet) { - return possibleModes.containsKey(modeSet); - } - public void addManuellOutput(final ModeSet mode) { if (!manuellEnabledOutputs.contains(mode)) { manuellEnabledOutputs.add(mode); + network.sendManuellOutputAdd(point, mode); } } public void removeManuellOutput(final ModeSet mode) { manuellEnabledOutputs.remove(mode); + network.sendManuellOutputRemove(point, mode); } public List clearAllManuellOutputs() { final List returnList = new ArrayList<>(); - manuellEnabledOutputs.forEach(mode -> returnList - .add(possibleModes.get(mode).getEntry(PathEntryType.OUTPUT).get())); + manuellEnabledOutputs.forEach(mode -> { + network.sendManuellOutputRemove(point, mode); + returnList.add(possibleModes.get(mode).getEntry(PathEntryType.OUTPUT).get()); + }); manuellEnabledOutputs.clear(); return returnList; } - public List getManuellEnabledOutputs() { - return ImmutableList.copyOf(manuellEnabledOutputs); - } - - public void remove(final ModeSet modeSet) { - possibleModes.remove(modeSet); + public void setAutoPointFromNetwork(final boolean isAutoPoint) { + this.isAutoPoint = isAutoPoint; } public void setAutoPoint(final boolean isAutoPoint) { this.isAutoPoint = isAutoPoint; + network.sendAutoPoint(point, isAutoPoint); } public boolean isAutoPoint() { @@ -236,8 +260,6 @@ public void write(final NBTWrapper compound) { entry.getValue().write(wrapper); if (manuellEnabledOutputs.contains(entry.getKey())) { wrapper.putBoolean(ENABLED_OUTPUTS, true); - } else { - wrapper.putBoolean(ENABLED_OUTPUTS, false); } final SignalState state = signalStates.getOrDefault(entry.getKey(), SignalState.RED); if (!state.equals(SignalState.RED)) { @@ -262,12 +284,13 @@ public void write(final NBTWrapper compound) { @Override public void read(final NBTWrapper compound) { - final SignalBoxFactory factory = SignalBoxFactory.getFactory(); final boolean oldOutputSystem = compound.contains(ENABLED_OUTPUTS); compound.getList(POINT_LIST).forEach(tag -> { + final ModeSet mode = new ModeSet(tag); final PathOptionEntry entry = factory.getEntry(); + entry.setUpNetwork(new PathOptionEntryNetwork().setUpNetwork(network, + new ModeIdentifier(point, mode))); entry.read(tag); - final ModeSet mode = new ModeSet(tag); possibleModes.put(mode, entry); if (!oldOutputSystem) if (tag.getBoolean(ENABLED_OUTPUTS)) { @@ -278,8 +301,9 @@ public void read(final NBTWrapper compound) { final String stateName = tag.getString(SIGNAL_STATE); if (stateName != null && !stateName.isEmpty()) { final SignalState state = SignalState.valueOf(stateName); - if (!state.equals(SignalState.RED)) + if (!state.equals(SignalState.RED)) { signalStates.put(mode, state); + } } if (tag.contains(SUBSIDIARY_ENTRY)) { final NBTWrapper subsidiaryWrapper = tag.getWrapper(SUBSIDIARY_ENTRY); @@ -312,6 +336,13 @@ public ModeSet getMode(final Path path) { return possibleConnections.get(path); } + public PathOptionEntry getOrCreateOption(final ModeSet mode) { + final PathOptionEntry entry = possibleModes.computeIfAbsent(mode, _u -> factory.getEntry()); + entry.setUpNetwork(new PathOptionEntryNetwork().setUpNetwork(network, + new ModeIdentifier(point, mode))); + return entry; + } + public Optional getOption(final ModeSet mode) { return Optional.ofNullable(possibleModes.get(mode)); } @@ -330,10 +361,10 @@ public List getPossibleTypes(final SignalBoxNode other) { final Set otherMode = other.possibleModes.keySet().stream() .map(mode -> mode.mode).collect(Collectors.toSet()); for (final PathType type : PathType.values()) { - final boolean thisContains = Arrays.stream(type.getModes()) - .anyMatch(thisMode::contains); - final boolean otherContains = Arrays.stream(type.getModes()) - .anyMatch(otherMode::contains); + final boolean thisContains = + Arrays.stream(type.getModes()).anyMatch(thisMode::contains); + final boolean otherContains = + Arrays.stream(type.getModes()).anyMatch(otherMode::contains); if (thisContains && otherContains) { possibleTypes.add(type); } @@ -379,7 +410,7 @@ public boolean isUsedInDirection(final Point point, @Nullable final EnumPathUsag if (mode == null) { continue; } - final EnumPathUsage usage = getOption(mode).orElse(new PathOptionEntry()) + final EnumPathUsage usage = getOption(mode).orElse(factory.getEntry()) .getEntry(PathEntryType.PATHUSAGE).orElse(EnumPathUsage.FREE); if (!(usage.equals(exclude) || usage.equals(EnumPathUsage.FREE))) return true; @@ -470,12 +501,14 @@ public Iterator iterator() { public void readNetwork(final ReadBuffer buffer) { possibleModes.clear(); manuellEnabledOutputs.clear(); - final SignalBoxFactory factory = SignalBoxFactory.getFactory(); - buffer.getMap(ReadBuffer.getINetworkSaveableFunction(ModeSet.class), (buf) -> { - final PathOptionEntry entry = factory.getEntry(); - entry.readNetwork(buf); - return entry; - }).forEach((mode, entry) -> possibleModes.put(mode, entry)); + buffer.getMapWithCombinedValueFunc(ReadBuffer.getINetworkSaveableFunction(ModeSet.class), + (buf, mode) -> { + final PathOptionEntry entry = factory.getEntry(); + entry.setUpNetwork(new PathOptionEntryNetwork().setUpNetwork(network, + new ModeIdentifier(point, mode))); + entry.readNetwork(buf); + return entry; + }).forEach((mode, entry) -> possibleModes.put(mode, entry)); buffer.getList(ReadBuffer.getINetworkSaveableFunction(ModeSet.class)).forEach(mode -> { if (!manuellEnabledOutputs.contains(mode)) { manuellEnabledOutputs.add(mode); @@ -507,6 +540,44 @@ public void writeNetwork(final WriteBuffer buffer) { (buf, entry) -> entry.writeNetwork(buf)); } + public void applyModeNetworkChanges(final ModeSet mode) { + if (!has(mode)) { + final PathOptionEntry entry = factory.getEntry(); + entry.setUpNetwork(new PathOptionEntryNetwork().setUpNetwork(network, + new ModeIdentifier(point, mode))); + possibleModes.put(mode, entry); + } else { + possibleModes.remove(mode); + } + } + + public void writeSignalStates(final WriteBuffer buffer) { + buffer.putMap(signalStates, WriteBuffer.getINetworkSaveableConsumer(), + WriteBuffer.getEnumConsumer()); + buffer.putMap(enabledSubsidiaryStates, WriteBuffer.getINetworkSaveableConsumer(), + (buf, state) -> state.writeNetwork(buf)); + } + + public void handleManuellEnabledOutputUpdate(final ModeSet mode, final boolean state) { + if (state) { + if (!manuellEnabledOutputs.contains(mode)) { + manuellEnabledOutputs.add(mode); + } + } else { + manuellEnabledOutputs.remove(mode); + } + } + + public void readSignalStates(final ReadBuffer buffer) { + signalStates.clear(); + enabledSubsidiaryStates.clear(); + signalStates.putAll(buffer.getMap(ReadBuffer.getINetworkSaveableFunction(ModeSet.class), + ReadBuffer.getEnumFunction(SignalState.class))); + enabledSubsidiaryStates + .putAll(buffer.getMap(ReadBuffer.getINetworkSaveableFunction(ModeSet.class), + buf -> SubsidiaryState.of(buf))); + } + public String getCustomText() { return customText; } @@ -519,8 +590,4 @@ public Map getModes() { return ImmutableMap.copyOf(possibleModes); } - public void resetEnumPathUsage() { - possibleModes.values().forEach(entry -> entry.removeEntry(PathEntryType.PATHUSAGE)); - } - } \ No newline at end of file diff --git a/src/main/java/com/troblecodings/signals/signalbox/SignalBoxPathway.java b/src/main/java/com/troblecodings/signals/signalbox/SignalBoxPathway.java index af94c5834..d57bf607d 100644 --- a/src/main/java/com/troblecodings/signals/signalbox/SignalBoxPathway.java +++ b/src/main/java/com/troblecodings/signals/signalbox/SignalBoxPathway.java @@ -1,6 +1,5 @@ package com.troblecodings.signals.signalbox; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; @@ -12,25 +11,22 @@ import javax.annotation.Nullable; import com.troblecodings.core.NBTWrapper; -import com.troblecodings.core.WriteBuffer; -import com.troblecodings.signals.OpenSignalsMain; import com.troblecodings.signals.blocks.RedstoneIO; import com.troblecodings.signals.blocks.Signal; import com.troblecodings.signals.core.BlockPosSignalHolder; import com.troblecodings.signals.core.ModeIdentifier; -import com.troblecodings.signals.core.NetworkBufferWrappers; import com.troblecodings.signals.core.StateInfo; import com.troblecodings.signals.core.TrainNumber; import com.troblecodings.signals.enums.EnumGuiMode; import com.troblecodings.signals.enums.EnumPathUsage; import com.troblecodings.signals.enums.PathType; -import com.troblecodings.signals.enums.SignalBoxNetwork; import com.troblecodings.signals.handler.SignalBoxHandler; import com.troblecodings.signals.handler.SignalStateInfo; import com.troblecodings.signals.signalbox.MainSignalIdentifier.SignalState; import com.troblecodings.signals.signalbox.config.ConfigInfo; import com.troblecodings.signals.signalbox.config.ResetInfo; import com.troblecodings.signals.signalbox.config.SignalConfig; +import com.troblecodings.signals.signalbox.debug.SignalBoxFactory; import com.troblecodings.signals.signalbox.entrys.PathEntryType; import com.troblecodings.signals.signalbox.entrys.PathOptionEntry; import com.troblecodings.signals.tileentitys.IChunkLoadable; @@ -53,6 +49,8 @@ public class SignalBoxPathway implements IChunkLoadable { protected TrainNumber trainNumber; protected boolean isExecutingSignalSet = false; + protected final SignalBoxFactory factory = SignalBoxFactory.getFactory(); + public void setTile(final SignalBoxTileEntity tile) { this.tile = tile; } @@ -122,24 +120,16 @@ private void setProtectionWay() { }); } - public boolean checkResetOfProtectionWay(final BlockPos position) { + public void checkResetOfProtectionWay(final BlockPos position) { if (!data.canResetProtectionWay(position)) - return false; - return resetProtectionWay(); - } - - public boolean resetProtectionWay() { - return data.resetProtectionWay(); + return; + data.resetProtectionWay(); } public boolean directResetOfProtectionWay() { return data.directResetOfProtectionWay(); } - public void removeProtectionWay() { - data.removeProtectionWay(); - } - public void setUpPathwayStatus() { setPathStatus(EnumPathUsage.SELECTED); } @@ -191,6 +181,7 @@ protected void setSignals() { protected void setSignals(final SignalStateInfo lastSignal) { if (isExecutingSignalSet || tile == null) return; + isExecutingSignalSet = true; final World world = tile.getLevel(); final StateInfo identifier = new StateInfo(world, tile.getBlockPos()); final MainSignalIdentifier startSignal = data.getStartSignal(); @@ -204,11 +195,6 @@ protected void setSignals(final SignalStateInfo lastSignal) { SignalConfig.change(new ConfigInfo(firstInfo, lastSignal, data)); updatePreSignals(); } - final SignalBoxPathway next = getNextPathway(); - if (next != null && (next.isEmptyOrBroken() || next.isBlocked)) { - updateSignalStates(); - return; - } final Map distantSignalPositions = data.getOtherSignals(); distantSignalPositions.forEach((holder, position) -> { @@ -227,6 +213,7 @@ protected void setSignals(final SignalStateInfo lastSignal) { } }); updateSignalStates(); + isExecutingSignalSet = false; } private void updatePreSignals() { @@ -250,17 +237,13 @@ private void updatePreSignals() { } protected void updateSignalStates() { - // TODO Just workaround until the new networking comes - final List nodesToUpdate = new ArrayList<>(); final MainSignalIdentifier startSignal = data.getStartSignal(); final MainSignalIdentifier endSignal = data.getEndSignal(); if (startSignal != null) { if (!isBlocked) { startSignal.updateSignalState(SignalState.GREEN); - nodesToUpdate.add(startSignal.node); data.getPreSignals().forEach(signalIdent -> { signalIdent.updateSignalState(SignalState.GREEN); - nodesToUpdate.add(signalIdent.node); }); } } @@ -289,36 +272,17 @@ protected void updateSignalStates() { stateToSet = SignalState.OFF; } position.updateSignalState(stateToSet); - nodesToUpdate.add(position.node); }); - updateSignalsOnClient(nodesToUpdate); } protected void updatePathwayOnGrid() { grid.updatePrevious(this); - grid.updateToNet(this); } protected void setSignalBoxGrid(final SignalBoxGrid grid) { this.grid = grid; } - protected void updateSignalsOnClient(final List nodes) { - if (nodes.isEmpty()) - return; - final World world = tile.getLevel(); - if (world == null || world.isClientSide) - return; - world.getServer().execute(() -> { - if (tile == null || !tile.isBlocked()) - return; - final WriteBuffer buffer = new WriteBuffer(); - buffer.putEnumValue(SignalBoxNetwork.SET_SIGNAL_STATE); - buffer.putList(nodes, NetworkBufferWrappers.POINT_SIGNALBOXNODE_CONSUMER); - OpenSignalsMain.network.sendTo(tile.get(0).getPlayer(), buffer); - }); - } - public void resetPathway() { resetPathway(null); } @@ -333,14 +297,12 @@ private void resetFirstSignal() { final MainSignalIdentifier startSignal = data.getStartSignal(); if (startSignal != null) { final StateInfo stateInfo = new StateInfo(tile.getLevel(), tile.getBlockPos()); - final List nodes = new ArrayList<>(); final Signal current = SignalBoxHandler.getSignal(stateInfo, startSignal.pos); if (current == null) return; SignalConfig.reset( new ResetInfo(new SignalStateInfo(tile.getLevel(), startSignal.pos, current))); startSignal.updateSignalState(SignalState.RED); - nodes.add(startSignal.node); data.getPreSignals().forEach(ident -> { final Signal currentPreSignal = SignalBoxHandler.getSignal(stateInfo, ident.pos); if (currentPreSignal == null) @@ -349,14 +311,11 @@ private void resetFirstSignal() { new SignalStateInfo(tile.getLevel(), ident.pos, currentPreSignal), ident.isRepeater)); ident.updateSignalState(SignalState.RED); - nodes.add(ident.node); }); - updateSignalsOnClient(nodes); } } private void resetOther() { - final List nodes = new ArrayList<>(); final Map distantSignalPositions = data.getOtherSignals(); distantSignalPositions.values().forEach((position) -> { @@ -368,9 +327,7 @@ private void resetOther() { new ResetInfo(new SignalStateInfo(tile.getLevel(), position.pos, current), position.isRepeater)); position.updateSignalState(SignalState.RED); - nodes.add(position.node); }); - updateSignalsOnClient(nodes); } public void resetPathway(final @Nullable Point point) { @@ -379,7 +336,6 @@ public void resetPathway(final @Nullable Point point) { if (data.totalPathwayReset(point)) { resetOther(); resetAllTrainNumbers(); - sendTrainNumberUpdates(); directResetOfProtectionWay(); } } @@ -393,7 +349,6 @@ public void postReset() { } public void compact(final Point point) { - final List nodes = new ArrayList<>(); data.foreachPath((path, node) -> { final Rotation rotation = SignalBoxUtil.getRotationFromDelta(node.getPoint().delta(path.point1)); @@ -416,20 +371,16 @@ public void compact(final Point point) { new SignalStateInfo(tile.getLevel(), position, current), identifier.isRepeater)); identifier.updateSignalState(SignalState.RED); - nodes.add(identifier.node); final OtherSignalIdentifier otherIdent = distantSignalPositions .get(new BlockPosSignalHolder(position, true)); if (otherIdent != null) { otherIdent.updateSignalState(SignalState.RED); - nodes.add(otherIdent.node); } })); } }, point); resetAllTrainNumbers(data.getTrainNumberDisplays()); - sendTrainNumberUpdates(); data.compact(point); - updateSignalsOnClient(nodes); updateTrainNumber(trainNumber); updateSignalStates(); } @@ -492,7 +443,10 @@ private boolean tryReversReset(final BlockPos pos, final SignalBoxNode node, } private boolean isPowerd(final BlockPos pos) { - final BlockState state = tile.getLevel().getBlockState(pos); + final World world = tile.getLevel(); + if (world == null) + return false; + final BlockState state = world.getBlockState(pos); if (state == null || !(state.getBlock() instanceof RedstoneIO)) return false; return state.getValue(RedstoneIO.POWER); @@ -528,24 +482,16 @@ protected void updateTrainNumber(final TrainNumber number) { final List trainNumberDisplays = data.getTrainNumberDisplays(); if (trainNumberDisplays == null || number == null) return; - trainNumberDisplays.forEach(ident -> grid.getNode(ident.point).getOption(ident.mode) - .orElse(new PathOptionEntry()).setEntry(PathEntryType.TRAINNUMBER, number)); - this.trainNumber = number; - sendTrainNumberUpdates(); - } - - private void sendTrainNumberUpdates() { - if (!this.tile.isBlocked()) - return; - final List trainNumberDisplays = data.getTrainNumberDisplays(); - final WriteBuffer buffer = new WriteBuffer(); - buffer.putEnumValue(SignalBoxNetwork.SEND_TRAIN_NUMBER); - buffer.putList(trainNumberDisplays, (buf, ident) -> { - final SignalBoxNode node = grid.getNode(ident.point); - node.getPoint().writeNetwork(buffer); - node.writeNetwork(buffer); + trainNumberDisplays.forEach(ident -> { + final PathOptionEntry entry = + grid.getNode(ident.point).getOption(ident.mode).orElse(factory.getEntry()); + if (number.equals(TrainNumber.DEFAULT)) { + entry.removeEntry(PathEntryType.TRAINNUMBER); + } else { + entry.setEntry(PathEntryType.TRAINNUMBER, number); + } }); - OpenSignalsMain.network.sendTo(tile.get(0).getPlayer(), buffer); + this.trainNumber = number; } private void resetAllTrainNumbers() { @@ -558,7 +504,7 @@ private void resetAllTrainNumbers(final List trainNumberDisplays final SignalBoxNode node = grid.getNode(ident.point); if (node == null) return; - node.getOption(ident.mode).orElse(new PathOptionEntry()) + node.getOption(ident.mode).orElse(factory.getEntry()) .removeEntry(PathEntryType.TRAINNUMBER); }); } diff --git a/src/main/java/com/troblecodings/signals/signalbox/SignalBoxUtil.java b/src/main/java/com/troblecodings/signals/signalbox/SignalBoxUtil.java index 9d381ad1c..48d72f6d6 100644 --- a/src/main/java/com/troblecodings/signals/signalbox/SignalBoxUtil.java +++ b/src/main/java/com/troblecodings/signals/signalbox/SignalBoxUtil.java @@ -286,6 +286,8 @@ public static boolean isPathBlocked(final SignalBoxGrid grid, final SignalBoxNod } private static boolean isPowerd(final SignalBoxTileEntity tile, final BlockPos pos) { + if (tile == null) + return false; final World world = tile.getLevel(); if (world == null) { OpenSignalsMain.getLogger() diff --git a/src/main/java/com/troblecodings/signals/signalbox/debug/DebugNetworkHandler.java b/src/main/java/com/troblecodings/signals/signalbox/debug/DebugNetworkHandler.java new file mode 100644 index 000000000..02915774c --- /dev/null +++ b/src/main/java/com/troblecodings/signals/signalbox/debug/DebugNetworkHandler.java @@ -0,0 +1,103 @@ +package com.troblecodings.signals.signalbox.debug; + +import java.nio.ByteBuffer; + +import com.troblecodings.core.ReadBuffer; +import com.troblecodings.core.WriteBuffer; +import com.troblecodings.signals.core.ModeIdentifier; +import com.troblecodings.signals.core.StateInfo; +import com.troblecodings.signals.handler.SignalBoxHandler; +import com.troblecodings.signals.network.SignalBoxNetworkHandler; +import com.troblecodings.signals.signalbox.ModeSet; +import com.troblecodings.signals.signalbox.Point; +import com.troblecodings.signals.signalbox.SignalBoxGrid; +import com.troblecodings.signals.signalbox.SignalBoxNode; +import com.troblecodings.signals.signalbox.entrys.IPathEntry; +import com.troblecodings.signals.signalbox.entrys.PathEntryType; +import com.troblecodings.signals.signalbox.entrys.PathOptionEntry; + +import io.netty.buffer.Unpooled; +import net.minecraft.util.math.BlockPos; + +public class DebugNetworkHandler extends SignalBoxNetworkHandler { + + private final SignalBoxGrid grid; + + public DebugNetworkHandler(final SignalBoxGrid grid) { + this.grid = grid; + } + + @Override + protected boolean containerConnected() { + return true; + } + + @Override + protected SignalBoxGrid getGrid() { + return grid; + } + + @Override + protected void sendBuffer(final WriteBuffer buffer) { + desirializeBuffer(new ReadBuffer(Unpooled + .copiedBuffer((ByteBuffer) buffer.getBuildedBuffer().position(0)).nioBuffer())); + } + + @Override + protected void readNodeSpecialEntries(final ReadBuffer buffer) { + final NodeNetworkMode mode = buffer.getEnumValue(NodeNetworkMode.class); + final Point point = Point.of(buffer); + final SignalBoxGrid grid = getGrid(); + final SignalBoxNode node = grid.getNode(point); + if (mode.equals(NodeNetworkMode.LABEL)) { + node.setCustomText(buffer.getString()); + } + if (mode.equals(NodeNetworkMode.AUTO_POINT)) { + node.setAutoPointFromNetwork(buffer.getBoolean()); + } + if (mode.equals(NodeNetworkMode.MANUELL_OUTPUT_ADD) + || mode.equals(NodeNetworkMode.MANUELL_OUTPUT_REMOVE)) { + node.handleManuellEnabledOutputUpdate(buffer.getINetworkSaveable(ModeSet.class), + mode.equals(NodeNetworkMode.MANUELL_OUTPUT_ADD) ? true : false); + } + if (mode.equals(NodeNetworkMode.SIGNAL_STATE)) { + node.readSignalStates(buffer); + } + } + + @Override + protected void readForGrid(final ReadBuffer buffer) { + final SignalBoxGrid grid = getGrid(); + final GridNetworkMode mode = buffer.getEnumValue(GridNetworkMode.class); + if (mode.equals(GridNetworkMode.SEND_ALL)) { + grid.readNetwork(buffer); + } else if (mode.equals(GridNetworkMode.COUNTER)) { + grid.setCounterFromNetwork(buffer.getInt()); + } else { + final BlockPos pos = buffer.getBlockPos(); + SignalBoxHandler.unlinkPosFromSignalBox(new StateInfo(container.getTile().getLevel(), + container.getTile().getBlockPos()), pos); + } + } + + @Override + protected void readEntry(final ReadBuffer buffer) { + final EntryNetworkMode mode = buffer.getEnumValue(EntryNetworkMode.class); + final ModeIdentifier ident = ModeIdentifier.of(buffer); + final SignalBoxNode node = getGrid().getOrCreateNode(ident.point); + if (mode.equals(EntryNetworkMode.MODE_ADD) || mode.equals(EntryNetworkMode.MODE_REMOVE)) { + node.applyModeNetworkChanges(ident.mode); + return; + } + final PathEntryType entryType = PathEntryType.ALL_ENTRIES.get(buffer.getInt()); + final PathOptionEntry optionEntry = node.getOrCreateOption(ident.mode); + if (mode.equals(EntryNetworkMode.ENTRY_REMOVE)) { + optionEntry.removeEntryNoNetwork(entryType); + return; + } + final IPathEntry entry = entryType.newValue(); + entry.readNetwork(buffer); + optionEntry.addEntry(entryType, entry); + } + +} \ No newline at end of file diff --git a/src/main/java/com/troblecodings/signals/signalbox/debug/DebugOptionEntry.java b/src/main/java/com/troblecodings/signals/signalbox/debug/DebugOptionEntry.java index 64a566b95..3d3e94f53 100644 --- a/src/main/java/com/troblecodings/signals/signalbox/debug/DebugOptionEntry.java +++ b/src/main/java/com/troblecodings/signals/signalbox/debug/DebugOptionEntry.java @@ -21,7 +21,6 @@ public void setEntry(final PathEntryType type, final T value) { public Optional getEntry(final PathEntryType type) { final Optional entry = super.getEntry(type); if (entry.filter(n -> n.equals(EnumPathUsage.SELECTED)).isPresent()) { - return entry; } return entry; } diff --git a/src/main/java/com/troblecodings/signals/signalbox/debug/SignalBoxFactory.java b/src/main/java/com/troblecodings/signals/signalbox/debug/SignalBoxFactory.java index 11ca93575..e3998f648 100644 --- a/src/main/java/com/troblecodings/signals/signalbox/debug/SignalBoxFactory.java +++ b/src/main/java/com/troblecodings/signals/signalbox/debug/SignalBoxFactory.java @@ -23,6 +23,10 @@ public static final SignalBoxFactory getFactory() { return factory; } + public static void setUpFactoryForTests() { + factory = new DebugFactory(); + } + public ConnectionChecker getConnectionCheckerNormal() { return new ConnectionCheckerNormal(); } diff --git a/src/main/java/com/troblecodings/signals/signalbox/entrys/BlockposEntry.java b/src/main/java/com/troblecodings/signals/signalbox/entrys/BlockposEntry.java index 67540ad1c..401e4daf2 100644 --- a/src/main/java/com/troblecodings/signals/signalbox/entrys/BlockposEntry.java +++ b/src/main/java/com/troblecodings/signals/signalbox/entrys/BlockposEntry.java @@ -42,6 +42,11 @@ public void setValue(final BlockPos pPosition) { this.position = pPosition; } + @Override + public BlockPos getDefaultValue() { + return BlockPos.ZERO; + } + @Override public void readNetwork(final ReadBuffer buffer) { this.position = buffer.getBlockPos(); diff --git a/src/main/java/com/troblecodings/signals/signalbox/entrys/BoolEntry.java b/src/main/java/com/troblecodings/signals/signalbox/entrys/BoolEntry.java index 3a1affb26..e04276858 100644 --- a/src/main/java/com/troblecodings/signals/signalbox/entrys/BoolEntry.java +++ b/src/main/java/com/troblecodings/signals/signalbox/entrys/BoolEntry.java @@ -58,6 +58,11 @@ public void accept(final int value) { this.setValue(getObjFromID(value)); } + @Override + public Boolean getDefaultValue() { + return false; + } + @Override public void readNetwork(final ReadBuffer buffer) { value = buffer.getBoolean(); diff --git a/src/main/java/com/troblecodings/signals/signalbox/entrys/ByteEntry.java b/src/main/java/com/troblecodings/signals/signalbox/entrys/ByteEntry.java index bba6014a2..ec0a7f81c 100644 --- a/src/main/java/com/troblecodings/signals/signalbox/entrys/ByteEntry.java +++ b/src/main/java/com/troblecodings/signals/signalbox/entrys/ByteEntry.java @@ -33,6 +33,11 @@ public Byte getValue() { return (byte) value; } + @Override + public Byte getDefaultValue() { + return 0; + } + @Override public void setValue(final Byte value) { this.value = value; diff --git a/src/main/java/com/troblecodings/signals/signalbox/entrys/EnumEntry.java b/src/main/java/com/troblecodings/signals/signalbox/entrys/EnumEntry.java index 458949c73..a48180453 100644 --- a/src/main/java/com/troblecodings/signals/signalbox/entrys/EnumEntry.java +++ b/src/main/java/com/troblecodings/signals/signalbox/entrys/EnumEntry.java @@ -64,6 +64,11 @@ public void accept(final int value) { setValue(getObjFromID(value)); } + @Override + public T getDefaultValue() { + return enumClass.getEnumConstants()[0]; + } + @Override public void readNetwork(final ReadBuffer buffer) { this.enumValue = buffer.getEnumValue(enumClass); diff --git a/src/main/java/com/troblecodings/signals/signalbox/entrys/IPathEntry.java b/src/main/java/com/troblecodings/signals/signalbox/entrys/IPathEntry.java index 2fd8f87c9..4433e2e20 100644 --- a/src/main/java/com/troblecodings/signals/signalbox/entrys/IPathEntry.java +++ b/src/main/java/com/troblecodings/signals/signalbox/entrys/IPathEntry.java @@ -37,6 +37,8 @@ public void setName(final String name) { */ public abstract void setValue(T value); + public abstract T getDefaultValue(); + @Override public int hashCode() { return Objects.hash(name, this.getValue()); diff --git a/src/main/java/com/troblecodings/signals/signalbox/entrys/IntegerEntry.java b/src/main/java/com/troblecodings/signals/signalbox/entrys/IntegerEntry.java index c049fd6cd..f0f34349a 100644 --- a/src/main/java/com/troblecodings/signals/signalbox/entrys/IntegerEntry.java +++ b/src/main/java/com/troblecodings/signals/signalbox/entrys/IntegerEntry.java @@ -35,6 +35,11 @@ public void accept(final int value) { this.setValue(value); } + @Override + public Integer getDefaultValue() { + return 0; + } + @Override public void readNetwork(final ReadBuffer buffer) { this.value = buffer.getInt(); diff --git a/src/main/java/com/troblecodings/signals/signalbox/entrys/ListBlockPosEntry.java b/src/main/java/com/troblecodings/signals/signalbox/entrys/ListBlockPosEntry.java index 4154a96f7..3f53d6207 100644 --- a/src/main/java/com/troblecodings/signals/signalbox/entrys/ListBlockPosEntry.java +++ b/src/main/java/com/troblecodings/signals/signalbox/entrys/ListBlockPosEntry.java @@ -49,6 +49,11 @@ public void setValue(final List value) { this.list = new ArrayList<>(value); } + @Override + public List getDefaultValue() { + return new ArrayList<>(); + } + public void add(final PosIdentifier pos) { list.add(pos); } diff --git a/src/main/java/com/troblecodings/signals/signalbox/entrys/ModeIdentifierEntry.java b/src/main/java/com/troblecodings/signals/signalbox/entrys/ModeIdentifierEntry.java index 1bbd80ea4..361952561 100644 --- a/src/main/java/com/troblecodings/signals/signalbox/entrys/ModeIdentifierEntry.java +++ b/src/main/java/com/troblecodings/signals/signalbox/entrys/ModeIdentifierEntry.java @@ -34,6 +34,11 @@ public ModeIdentifier getValue() { return identifier; } + @Override + public ModeIdentifier getDefaultValue() { + return new ModeIdentifier(null, null); + } + @Override public void setValue(final ModeIdentifier value) { identifier = value; diff --git a/src/main/java/com/troblecodings/signals/signalbox/entrys/PathOptionEntry.java b/src/main/java/com/troblecodings/signals/signalbox/entrys/PathOptionEntry.java index 941f0d900..16e9f66b9 100644 --- a/src/main/java/com/troblecodings/signals/signalbox/entrys/PathOptionEntry.java +++ b/src/main/java/com/troblecodings/signals/signalbox/entrys/PathOptionEntry.java @@ -13,9 +13,11 @@ import com.troblecodings.core.interfaces.INetworkSaveable; import com.troblecodings.core.interfaces.ISaveable; import com.troblecodings.signals.core.NetworkBufferWrappers; +import com.troblecodings.signals.network.PathOptionEntryNetwork; public class PathOptionEntry implements INetworkSaveable, ISaveable { + private PathOptionEntryNetwork network = new PathOptionEntryNetwork(); private final Map, IPathEntry> pathEntrys = new HashMap<>(); @SuppressWarnings("unchecked") @@ -31,19 +33,40 @@ public void setEntry(final PathEntryType type, final T value) { pathEntrys.remove(type); return; } - final IPathEntry pathEntry = (IPathEntry) pathEntrys.computeIfAbsent(type, - pType -> pType.newValue()); + final IPathEntry pathEntry = + (IPathEntry) pathEntrys.computeIfAbsent(type, pType -> pType.newValue()); + final T oldValue = pathEntry.getValue(); pathEntry.setValue(value); + if (!value.equals(oldValue)) { + network.sendEntryAdd(type, pathEntry); + } + } + + public void addEntry(final PathEntryType entryType, final IPathEntry entry) { + if (entry == null) { + pathEntrys.remove(entryType); + return; + } + pathEntrys.put(entryType, entry); + } + + public void removeEntryNoNetwork(final PathEntryType type) { + pathEntrys.remove(type); } public void removeEntry(final PathEntryType type) { pathEntrys.remove(type); + network.sendEntryRemove(type); } public boolean containsEntry(final PathEntryType type) { return pathEntrys.containsKey(type); } + public void setUpNetwork(final PathOptionEntryNetwork network) { + this.network = network; + } + @Override public int hashCode() { return Objects.hash(pathEntrys); @@ -66,17 +89,19 @@ public String toString() { @Override public void write(final NBTWrapper tag) { - pathEntrys.forEach((type, option) -> { - final NBTWrapper entry = new NBTWrapper(); - option.write(entry); - tag.putWrapper(type.getName(), entry); - }); + pathEntrys.entrySet().stream().filter( + entry -> !entry.getValue().getDefaultValue().equals(entry.getValue().getValue())) + .forEach(entry -> { + final NBTWrapper entryWrapper = new NBTWrapper(); + entry.getValue().write(entryWrapper); + tag.putWrapper(entry.getKey().getName(), entryWrapper); + }); } @Override public void read(final NBTWrapper tag) { - final List> tagSet = tag.keySet().stream().map(PathEntryType::getType) - .collect(Collectors.toList()); + final List> tagSet = + tag.keySet().stream().map(PathEntryType::getType).collect(Collectors.toList()); tagSet.forEach(entry -> { if (entry != null) { if (tag.contains(entry.getName())) { @@ -94,8 +119,8 @@ public void read(final NBTWrapper tag) { public void readNetwork(final ReadBuffer buffer) { pathEntrys.putAll(buffer.getMapWithCombinedValueFunc( NetworkBufferWrappers.PATHENTRYTYPE_FUNCTION, (buf, type) -> { - final IPathEntry entry = pathEntrys.computeIfAbsent(type, - _u -> type.newValue()); + final IPathEntry entry = + pathEntrys.computeIfAbsent(type, _u -> type.newValue()); entry.readNetwork(buffer); return entry; })); diff --git a/src/main/java/com/troblecodings/signals/signalbox/entrys/PointEntry.java b/src/main/java/com/troblecodings/signals/signalbox/entrys/PointEntry.java index 1593c7fdc..ae4a67062 100644 --- a/src/main/java/com/troblecodings/signals/signalbox/entrys/PointEntry.java +++ b/src/main/java/com/troblecodings/signals/signalbox/entrys/PointEntry.java @@ -35,6 +35,11 @@ public Point getValue() { return point; } + @Override + public Point getDefaultValue() { + return new Point(-1, -1); + } + @Override public void setValue(final Point value) { this.point = value; diff --git a/src/main/java/com/troblecodings/signals/signalbox/entrys/TCBoolEntry.java b/src/main/java/com/troblecodings/signals/signalbox/entrys/TCBoolEntry.java index 111242c86..9b5c481e6 100644 --- a/src/main/java/com/troblecodings/signals/signalbox/entrys/TCBoolEntry.java +++ b/src/main/java/com/troblecodings/signals/signalbox/entrys/TCBoolEntry.java @@ -60,6 +60,11 @@ public void accept(final int value) { this.setValue(getObjFromID(value)); } + @Override + public TCBoolean getDefaultValue() { + return TCBoolean.FALSE; + } + @Override public void readNetwork(final ReadBuffer buffer) { value = buffer.getBoolean(); diff --git a/src/main/java/com/troblecodings/signals/signalbox/entrys/TrainNumberEntry.java b/src/main/java/com/troblecodings/signals/signalbox/entrys/TrainNumberEntry.java index c439f438b..8c3e24a0b 100644 --- a/src/main/java/com/troblecodings/signals/signalbox/entrys/TrainNumberEntry.java +++ b/src/main/java/com/troblecodings/signals/signalbox/entrys/TrainNumberEntry.java @@ -34,6 +34,11 @@ public TrainNumber getValue() { return number; } + @Override + public TrainNumber getDefaultValue() { + return TrainNumber.DEFAULT; + } + @Override public void setValue(final TrainNumber value) { number = value; diff --git a/src/main/java/com/troblecodings/signals/tileentitys/SignalControllerTileEntity.java b/src/main/java/com/troblecodings/signals/tileentitys/SignalControllerTileEntity.java index ecc74ca4f..371eba928 100644 --- a/src/main/java/com/troblecodings/signals/tileentitys/SignalControllerTileEntity.java +++ b/src/main/java/com/troblecodings/signals/tileentitys/SignalControllerTileEntity.java @@ -93,14 +93,16 @@ public void setProfile(final int profile) { public void removePropertyFromProfile(final Byte profile, final SEProperty property) { final Map properties = allStates.get(profile); - if (properties != null) + if (properties != null) { properties.remove(property); + } } public void removeProfileFromDirection(final Direction direction, final EnumState state) { final Map properties = enabledStates.get(direction); - if (properties != null) + if (properties != null) { properties.remove(state); + } } public void updateRedstoneProfile(final Byte profile, final SEProperty property, @@ -144,11 +146,13 @@ public void saveWrapper(final NBTWrapper wrapper) { wrapper.putBlockPos(BLOCK_POS_ID, linkedSignalPosition); wrapper.putString(SIGNAL_NAME, linkedSignal.getSignalTypeName()); wrapper.putInteger(LAST_PROFILE, lastProfile); - if (lastState != null) + if (lastState != null) { wrapper.putInteger(ENUM_MODE, lastState.ordinal()); + } for (final Direction direction : Direction.values()) { - if (!enabledStates.containsKey(direction)) + if (!enabledStates.containsKey(direction)) { continue; + } final NBTWrapper comp = new NBTWrapper(); enabledStates.get(direction) @@ -183,8 +187,9 @@ public void loadWrapper(final NBTWrapper wrapper) { lastProfile = wrapper.getInteger(LAST_PROFILE); lastState = EnumMode.values()[wrapper.getInteger(ENUM_MODE)]; for (final Direction direction : Direction.values()) { - if (!wrapper.contains(direction.getName())) + if (!wrapper.contains(direction.getName())) { continue; + } final NBTWrapper comp = wrapper.getWrapper(direction.getName()); final Map map = new HashMap<>(); comp.keySet().stream().forEach(str -> { @@ -194,13 +199,14 @@ public void loadWrapper(final NBTWrapper wrapper) { map.put(state, (byte) comp.getInteger(state.getNameWrapper())); }); enabledStates.put(direction, map); - if (comp.contains(RS_BOOLEAN)) - currentStates[direction.ordinal()] = comp.getWrapper(RS_BOOLEAN) - .getBoolean(RS_BOOLEAN); + if (comp.contains(RS_BOOLEAN)) { + currentStates[direction.ordinal()] = + comp.getWrapper(RS_BOOLEAN).getBoolean(RS_BOOLEAN); + } } final List list = wrapper.getList(ALLSTATES); - final List properites = linkedSignal == null ? new ArrayList<>() - : linkedSignal.getProperties(); + final List properites = + linkedSignal == null ? new ArrayList<>() : linkedSignal.getProperties(); list.forEach(compund -> { final int profile = compund.getInteger(PROFILE); final NBTWrapper comp = compund.getWrapper(PROPERITES); @@ -213,21 +219,22 @@ public void loadWrapper(final NBTWrapper wrapper) { }); allStates.put((byte) profile, properties); }); - if (wrapper.contains(LINKED_RS_INPUT)) + if (wrapper.contains(LINKED_RS_INPUT)) { linkedRSInput = wrapper.getBlockPos(LINKED_RS_INPUT); - profileRSInput = (byte) (wrapper.contains(RS_INPUT_PROFILE) - ? wrapper.getInteger(RS_INPUT_PROFILE) - : -1); + } + profileRSInput = + (byte) (wrapper.contains(RS_INPUT_PROFILE) ? wrapper.getInteger(RS_INPUT_PROFILE) + : -1); } @Override public void onLoad() { if (!level.isClientSide) { if (linkedSignalPosition != null && linkedSignal != null) { - final SignalStateInfo info = new SignalStateInfo(level, linkedSignalPosition, - linkedSignal); - final LoadHolder holder = new LoadHolder<>( - new StateInfo(level, worldPosition)); + final SignalStateInfo info = + new SignalStateInfo(level, linkedSignalPosition, linkedSignal); + final LoadHolder holder = + new LoadHolder<>(new StateInfo(level, worldPosition)); SignalStateHandler.loadSignal(new SignalStateLoadHoler(info, holder)); SignalStateHandler.addListener(info, listener); NameHandler.loadName(new StateLoadHolder(info.toStateInfo(), holder)); @@ -235,12 +242,24 @@ public void onLoad() { } } + public void validateData() { + final Block thisBlock = level.getBlockState(this.getLinkedPosition()).getBlock(); + if (!thisBlock.equals(linkedSignal)) { + OpenSignalsMain.getLogger() + .error("Unlinked wrong signal data for [" + getBlockPos() + "]! Linked Pos=" + + getLinkedPos() + ", Saved block=" + linkedSignal + ", Real block=" + + thisBlock); + unloadSignal(); + unlink(); + } + } + public void unloadSignal() { - if (linkedSignalPosition != null & linkedSignal != null) { - final SignalStateInfo info = new SignalStateInfo(level, linkedSignalPosition, - linkedSignal); - final LoadHolder holder = new LoadHolder<>( - new StateInfo(level, worldPosition)); + if (linkedSignalPosition != null && linkedSignal != null) { + final SignalStateInfo info = + new SignalStateInfo(level, linkedSignalPosition, linkedSignal); + final LoadHolder holder = + new LoadHolder<>(new StateInfo(level, worldPosition)); SignalStateHandler.unloadSignal(new SignalStateLoadHoler(info, holder)); NameHandler.unloadName(new StateLoadHolder(info.toStateInfo(), holder)); } @@ -270,7 +289,8 @@ public boolean link(final BlockPos pos, final CompoundNBT tag) { linkedSignal = (Signal) block; onLoad(); return true; - } else if (block instanceof RedstoneInput) { + } + if (block instanceof RedstoneInput) { linkedRSInput = pos; loadChunkAndGetTile(RedstoneIOTileEntity.class, (ServerWorld) level, pos, (tile, _u) -> tile.linkController(getBlockPos())); @@ -294,20 +314,22 @@ public void redstoneUpdate() { if (level.isClientSide || linkedSignalPosition == null) return; for (final Direction face : Direction.values()) { - if (!this.enabledStates.containsKey(face)) + if (!this.enabledStates.containsKey(face)) { continue; + } final boolean state = this.level.hasSignal(worldPosition.relative(face), face); final boolean old = this.currentStates[face.ordinal()]; - if (state == old) + if (state == old) { continue; + } this.currentStates[face.ordinal()] = state; final EnumState currenState = state ? EnumState.ONSTATE : EnumState.OFFSTATE; final Byte profile = this.enabledStates.get(face).get(currenState); if (profile == null || !allStates.containsKey(profile)) { continue; } - final SignalStateInfo info = new SignalStateInfo(level, linkedSignalPosition, - linkedSignal); + final SignalStateInfo info = + new SignalStateInfo(level, linkedSignalPosition, linkedSignal); SignalStateHandler.runTaskWhenSignalLoaded(info, (stateInfo, _u1, _u2) -> SignalStateHandler.setStates(info, allStates.get(profile))); } @@ -318,8 +340,8 @@ public void updateFromRSInput() { return; final Map properties = allStates.get(profileRSInput); if (properties != null) { - final SignalStateInfo info = new SignalStateInfo(level, linkedSignalPosition, - linkedSignal); + final SignalStateInfo info = + new SignalStateInfo(level, linkedSignalPosition, linkedSignal); SignalStateHandler.runTaskWhenSignalLoaded(info, (stateInfo, _u1, _u2) -> SignalStateHandler.setStates(info, properties)); } diff --git a/src/main/resources/assets/opensignals/animations/semaphoresignal.json b/src/main/resources/assets/opensignals/animations/semaphoresignal.json index 9ba77f465..59941396c 100644 --- a/src/main/resources/assets/opensignals/animations/semaphoresignal.json +++ b/src/main/resources/assets/opensignals/animations/semaphoresignal.json @@ -55,13 +55,13 @@ "pivotZ": 0, "animationConfigs": [ { - "predicate": "with(WING2.FALSE) && with(SEMATYPE.MAIN)", + "predicate": "with(WING2.FALSE) && with(SEMATYPE.MAIN) && hasandis(HP2)", "mode": "ROTATION", "rotationAxis": "Z", "rotation": 0 }, { - "predicate": "with(WING2.TRUE) && with(SEMATYPE.MAIN)", + "predicate": "with(WING2.TRUE) && with(SEMATYPE.MAIN) && hasandis(HP2)", "mode": "ROTATION", "rotationAxis": "Z", "rotation": 45 @@ -77,14 +77,14 @@ "pivotZ": 0, "animationConfigs": [ { - "predicate": "with(WING2.FALSE) && with(SEMATYPE.MAIN)", + "predicate": "with(WING2.FALSE) && with(SEMATYPE.MAIN) && hasandis(HP2)", "mode": "ROTATION", "rotationAxis": "Z", "animationSpeed": 0.5, "rotation": 0 }, { - "predicate": "with(WING2.TRUE) && with(SEMATYPE.MAIN)", + "predicate": "with(WING2.TRUE) && with(SEMATYPE.MAIN) && hasandis(HP2)", "mode": "ROTATION", "rotationAxis": "Z", "animationSpeed": 0.5, @@ -147,13 +147,13 @@ "pivotZ": 0, "animationConfigs": [ { - "predicate": "!hasandis(WING2) && with(SEMATYPE.MAIN_SMALL)", + "predicate": "!hasandis(WING2) && with(SEMATYPE.MAIN_SMALL) && hasandis(HP2)", "mode": "ROTATION", "rotationAxis": "Z", "rotation": 0 }, { - "predicate": "hasandis(WING2) && with(SEMATYPE.MAIN_SMALL)", + "predicate": "hasandis(WING2) && with(SEMATYPE.MAIN_SMALL) && hasandis(HP2)", "mode": "ROTATION", "rotationAxis": "Z", "rotation": 45 @@ -169,14 +169,14 @@ "pivotZ": 0, "animationConfigs": [ { - "predicate": "!hasandis(WING2) && with(SEMATYPE.MAIN_SMALL)", + "predicate": "!hasandis(WING2) && with(SEMATYPE.MAIN_SMALL) && hasandis(HP2)", "mode": "ROTATION", "rotationAxis": "Z", "animationSpeed": 0.5, "rotation": 0 }, { - "predicate": "hasandis(WING2) && with(SEMATYPE.MAIN_SMALL)", + "predicate": "hasandis(WING2) && with(SEMATYPE.MAIN_SMALL) && hasandis(HP2)", "mode": "ROTATION", "rotationAxis": "Z", "animationSpeed": 0.5, diff --git a/src/main/resources/assets/opensignals/lang/de_de.json b/src/main/resources/assets/opensignals/lang/de_de.json index afb4b8cef..5faf555e6 100644 --- a/src/main/resources/assets/opensignals/lang/de_de.json +++ b/src/main/resources/assets/opensignals/lang/de_de.json @@ -176,6 +176,7 @@ "error.no_path": "Kein Fahrstraße möglich", "error.no_intersignalbox_selected": "Kein Stellwerk verbunden", "error.input_blocking": "aktiver Input blockiert", + "error.subsidiary_enabled": "Eingeschaltetes ZS Signal", "error.pass": "Erfolg", "__SignalboxLinkingPage": "", diff --git a/src/main/resources/assets/opensignals/lang/en_us.json b/src/main/resources/assets/opensignals/lang/en_us.json index 9086f7019..79add9e44 100644 --- a/src/main/resources/assets/opensignals/lang/en_us.json +++ b/src/main/resources/assets/opensignals/lang/en_us.json @@ -176,6 +176,7 @@ "error.no_path": "No path available", "error.no_intersignalbox_selected": "No signalbox connected", "error.input_blocking": "active Input is blocking", + "error.subsidiary_enabled": "Activated Subsidiary", "error.pass": "Pass", "__SignalboxLinkingPage": "", diff --git a/src/main/resources/assets/opensignals/models/block/ks/ks_mast1.json b/src/main/resources/assets/opensignals/models/block/ks/ks_mast1.json index 7ecbb565f..cc9ce0063 100644 --- a/src/main/resources/assets/opensignals/models/block/ks/ks_mast1.json +++ b/src/main/resources/assets/opensignals/models/block/ks/ks_mast1.json @@ -1 +1,31 @@ -{"credit": "Made with Blockbench by Mc_Jeronimo", "texture_size": [32, 32], "textures": {"0": "opensignals:blocks/default/mast", "particle": "opensignals:blocks/default/mast"}, "elements": [{"name": "mast4", "from": [7, 0, 10], "to": [9, 16, 13], "faces": {"north": {"uv": [0, 0, 1, 8], "texture": "#0"}, "east": {"uv": [0, 0, 0.5, 8], "texture": "#0"}, "south": {"uv": [0, 0, 1, 8], "texture": "#0"}, "west": {"uv": [0, 0, 0.5, 8], "texture": "#0"}, "down": {"uv": [0, 0, 1, 0.5], "texture": "#0"}}}], "groups": [{"name": "mast2", "origin": [-8, 32, -27], "children": [0]}]} \ No newline at end of file +{ + "credit": "Made with Blockbench by Mc_Jeronimo", + "texture_size": [32, 32], + "textures": { + "0": "opensignals:blocks/default/mast", + "particle": "opensignals:blocks/default/mast" + }, + "elements": [ + { + "name": "mast4", + "from": [7, 0, 10], + "to": [9, 16, 13], + "faces": { + "north": {"uv": [0, 0, 1, 8], "texture": "#0"}, + "east": {"uv": [0, 0, 0.5, 8], "texture": "#0"}, + "south": {"uv": [0, 0, 1, 8], "texture": "#0"}, + "west": {"uv": [0, 0, 0.5, 8], "texture": "#0"}, + "up": {"uv": [0, 0, 0, 0], "texture": "#0"}, + "down": {"uv": [0, 0, 1, 0.5], "texture": "#0"} + } + } + ], + "groups": [ + { + "name": "mast2", + "origin": [-8, 32, -27], + "color": 0, + "children": [0] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/opensignals/models/block/ks/ks_mast2.json b/src/main/resources/assets/opensignals/models/block/ks/ks_mast2.json index 048c02e53..1da12c2ba 100644 --- a/src/main/resources/assets/opensignals/models/block/ks/ks_mast2.json +++ b/src/main/resources/assets/opensignals/models/block/ks/ks_mast2.json @@ -1 +1,31 @@ -{"credit": "Made with Blockbench by Mc_Jeronimo", "texture_size": [32, 32], "textures": {"0": "opensignals:blocks/default/mast", "particle": "opensignals:blocks/default/mast"}, "elements": [{"name": "mast5", "from": [7, 0, 10], "to": [9, 16, 13], "faces": {"north": {"uv": [0, 0, 1, 8], "texture": "#0"}, "east": {"uv": [0, 0, 0.5, 8], "texture": "#0"}, "south": {"uv": [0, 0, 1, 8], "texture": "#0"}, "west": {"uv": [0, 0, 0.5, 8], "texture": "#0"}, "down": {"uv": [0, 0, 1, 0.5], "texture": "#0"}}}], "groups": [{"name": "mast3", "origin": [-8, 48, -27], "children": [0]}]} \ No newline at end of file +{ + "credit": "Made with Blockbench by Mc_Jeronimo", + "texture_size": [32, 32], + "textures": { + "0": "opensignals:blocks/default/mast", + "particle": "opensignals:blocks/default/mast" + }, + "elements": [ + { + "name": "mast5", + "from": [7, 0, 10], + "to": [9, 16, 13], + "faces": { + "north": {"uv": [0, 0, 1, 8], "texture": "#0"}, + "east": {"uv": [0, 0, 0.5, 8], "texture": "#0"}, + "south": {"uv": [0, 0, 1, 8], "texture": "#0"}, + "west": {"uv": [0, 0, 0.5, 8], "texture": "#0"}, + "up": {"uv": [0, 0, 0, 0], "texture": "#0"}, + "down": {"uv": [0, 0, 1, 0.5], "texture": "#0"} + } + } + ], + "groups": [ + { + "name": "mast3", + "origin": [-8, 48, -27], + "color": 0, + "children": [0] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/opensignals/models/block/ks/ks_mast3.json b/src/main/resources/assets/opensignals/models/block/ks/ks_mast3.json index c6b53ed98..23451eccb 100644 --- a/src/main/resources/assets/opensignals/models/block/ks/ks_mast3.json +++ b/src/main/resources/assets/opensignals/models/block/ks/ks_mast3.json @@ -1 +1,31 @@ -{"credit": "Made with Blockbench by Mc_Jeronimo", "texture_size": [32, 32], "textures": {"0": "opensignals:blocks/default/mast", "particle": "opensignals:blocks/default/mast"}, "elements": [{"name": "mast6", "from": [7, 0, 10], "to": [9, 16, 13], "faces": {"north": {"uv": [0, 0, 1, 8], "texture": "#0"}, "east": {"uv": [0, 0, 0.5, 8], "texture": "#0"}, "south": {"uv": [0, 0, 1, 8], "texture": "#0"}, "west": {"uv": [0, 0, 0.5, 8], "texture": "#0"}, "down": {"uv": [0, 0, 1, 0.5], "texture": "#0"}}}], "groups": [{"name": "mast4", "origin": [-8, 64, -27], "children": [0]}]} \ No newline at end of file +{ + "credit": "Made with Blockbench by Mc_Jeronimo", + "texture_size": [32, 32], + "textures": { + "0": "opensignals:blocks/default/mast", + "particle": "opensignals:blocks/default/mast" + }, + "elements": [ + { + "name": "mast6", + "from": [7, 0, 10], + "to": [9, 16, 13], + "faces": { + "north": {"uv": [0, 0, 1, 8], "texture": "#0"}, + "east": {"uv": [0, 0, 0.5, 8], "texture": "#0"}, + "south": {"uv": [0, 0, 1, 8], "texture": "#0"}, + "west": {"uv": [0, 0, 0.5, 8], "texture": "#0"}, + "up": {"uv": [0, 0, 0, 0], "texture": "#0"}, + "down": {"uv": [0, 0, 1, 0.5], "texture": "#0"} + } + } + ], + "groups": [ + { + "name": "mast4", + "origin": [-8, 64, -27], + "color": 0, + "children": [0] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/opensignals/models/block/ks/ks_mast4.json b/src/main/resources/assets/opensignals/models/block/ks/ks_mast4.json index 498000656..85a5f37d1 100644 --- a/src/main/resources/assets/opensignals/models/block/ks/ks_mast4.json +++ b/src/main/resources/assets/opensignals/models/block/ks/ks_mast4.json @@ -1 +1,32 @@ -{"credit": "Made with Blockbench by Mc_Jeronimo", "texture_size": [32, 32], "textures": {"0": "opensignals:blocks/default/mast", "particle": "opensignals:blocks/default/mast"}, "elements": [{"name": "mast7", "from": [7, 0, 10], "to": [9, 16, 13], "faces": {"north": {"uv": [0, 0, 1, 8], "texture": "#0"}, "east": {"uv": [0, 0, 0.5, 8], "texture": "#0"}, "south": {"uv": [0, 0, 1, 8], "texture": "#0"}, "west": {"uv": [0, 0, 0.5, 8], "texture": "#0"}, "down": {"uv": [0, 0, 1, 0.5], "texture": "#0"}}}], "groups": [{"name": "mast5", "origin": [-8, 80, -27], "children": [0]}]} \ No newline at end of file +{ + "format_version": "1.21.11", + "credit": "Made with Blockbench by Mc_Jeronimo", + "texture_size": [32, 32], + "textures": { + "0": "opensignals:blocks/default/mast", + "particle": "opensignals:blocks/default/mast" + }, + "elements": [ + { + "name": "mast7", + "from": [7, 0, 10], + "to": [9, 16, 13], + "faces": { + "north": {"uv": [0, 0, 1, 8], "texture": "#0"}, + "east": {"uv": [0, 0, 0.5, 8], "texture": "#0"}, + "south": {"uv": [0, 0, 1, 8], "texture": "#0"}, + "west": {"uv": [0, 0, 0.5, 8], "texture": "#0"}, + "up": {"uv": [0, 0, 0, 0], "texture": "#0"}, + "down": {"uv": [0, 0, 1, 0.5], "texture": "#0"} + } + } + ], + "groups": [ + { + "name": "mast5", + "origin": [-8, 80, -27], + "color": 0, + "children": [0] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/opensignals/models/block/mast_lamps.json b/src/main/resources/assets/opensignals/models/block/mast_lamps.json index aab5cfba8..e2fa0fe5f 100644 --- a/src/main/resources/assets/opensignals/models/block/mast_lamps.json +++ b/src/main/resources/assets/opensignals/models/block/mast_lamps.json @@ -1 +1,114 @@ -{"credit": "Made with Blockbench by Mc_Jeronimo", "textures": {"1": "opensignals:blocks/default/yellow", "2": "opensignals:blocks/default/orange", "particle": "opensignals:blocks/default/yellow"}, "elements": [{"name": "lamp body", "from": [9, 10, 7], "to": [12, 12, 9], "faces": {"north": {"uv": [0, 0, 3, 2], "texture": "#1"}, "east": {"uv": [0, 0, 2, 2], "texture": "#1"}, "south": {"uv": [0, 0, 3, 2], "texture": "#1"}, "west": {"uv": [0, 0, 2, 2], "texture": "#1"}, "up": {"uv": [0, 0, 3, 2], "texture": "#1"}, "down": {"uv": [0, 0, 3, 2], "texture": "#1"}}}, {"name": "lamp", "from": [10, 12, 7.5], "to": [11, 12.5, 8.5], "faces": {"north": {"uv": [0, 0, 2, 2], "texture": "#2"}, "east": {"uv": [0, 0, 2, 2], "texture": "#2"}, "south": {"uv": [0, 0, 2, 2], "texture": "#2"}, "west": {"uv": [0, 0, 2, 2], "texture": "#2"}, "up": {"uv": [0, 0, 2, 2], "texture": "#2"}, "down": {"uv": [0, 0, 2, 2], "texture": "#2"}}}, {"name": "lamp", "from": [10, 13.5, 7.5], "to": [11, 14, 8.5], "faces": {"north": {"uv": [0, 0, 2, 2], "texture": "#2"}, "east": {"uv": [0, 0, 2, 2], "texture": "#2"}, "south": {"uv": [0, 0, 2, 2], "texture": "#2"}, "west": {"uv": [0, 0, 2, 2], "texture": "#2"}, "up": {"uv": [0, 0, 2, 2], "texture": "#2"}, "down": {"uv": [0, 0, 2, 2], "texture": "#2"}}}, {"name": "lamp", "from": [9.5, 12.5, 7.5], "to": [11.5, 13.5, 8.5], "faces": {"north": {"uv": [0, 0, 2, 2], "texture": "#2"}, "east": {"uv": [0, 0, 2, 2], "texture": "#2"}, "south": {"uv": [0, 0, 2, 2], "texture": "#2"}, "west": {"uv": [0, 0, 2, 2], "texture": "#2"}, "up": {"uv": [0, 0, 2, 2], "texture": "#2"}, "down": {"uv": [0, 0, 2, 2], "texture": "#2"}}}, {"name": "lamp body", "from": [4, 4, 7], "to": [7, 6, 9], "faces": {"north": {"uv": [0, 0, 3, 2], "texture": "#1"}, "east": {"uv": [0, 0, 2, 2], "texture": "#1"}, "south": {"uv": [0, 0, 3, 2], "texture": "#1"}, "west": {"uv": [0, 0, 2, 2], "texture": "#1"}, "up": {"uv": [0, 0, 3, 2], "texture": "#1"}, "down": {"uv": [0, 0, 3, 2], "texture": "#1"}}}, {"name": "lamp", "from": [5, 6, 7.5], "to": [6, 6.5, 8.5], "faces": {"north": {"uv": [0, 0, 2, 2], "texture": "#2"}, "east": {"uv": [0, 0, 2, 2], "texture": "#2"}, "south": {"uv": [0, 0, 2, 2], "texture": "#2"}, "west": {"uv": [0, 0, 2, 2], "texture": "#2"}, "up": {"uv": [0, 0, 2, 2], "texture": "#2"}, "down": {"uv": [0, 0, 2, 2], "texture": "#2"}}}, {"name": "lamp", "from": [4.5, 6.5, 7.5], "to": [6.5, 7.5, 8.5], "faces": {"north": {"uv": [0, 0, 2, 2], "texture": "#2"}, "east": {"uv": [0, 0, 2, 2], "texture": "#2"}, "south": {"uv": [0, 0, 2, 2], "texture": "#2"}, "west": {"uv": [0, 0, 2, 2], "texture": "#2"}, "up": {"uv": [0, 0, 2, 2], "texture": "#2"}, "down": {"uv": [0, 0, 2, 2], "texture": "#2"}}}, {"name": "lamp", "from": [5, 7.5, 7.5], "to": [6, 8, 8.5], "faces": {"north": {"uv": [0, 0, 2, 2], "texture": "#2"}, "east": {"uv": [0, 0, 2, 2], "texture": "#2"}, "south": {"uv": [0, 0, 2, 2], "texture": "#2"}, "west": {"uv": [0, 0, 2, 2], "texture": "#2"}, "up": {"uv": [0, 0, 2, 2], "texture": "#2"}, "down": {"uv": [0, 0, 2, 2], "texture": "#2"}}}]} \ No newline at end of file +{ + "credit": "Made with Blockbench by Mc_Jeronimo modded by SkywalkerValle", + "textures": { + "1": "opensignals:blocks/default/yellow", + "3": "opensignals:blocks/lamps/lamp_yellow", + "particle": "opensignals:blocks/default/yellow" + }, + "elements": [ + { + "name": "lamp body", + "from": [9, 10, 7], + "to": [12, 12, 9], + "faces": { + "north": {"uv": [0, 0, 3, 2], "texture": "#1"}, + "east": {"uv": [0, 0, 2, 2], "texture": "#1"}, + "south": {"uv": [0, 0, 3, 2], "texture": "#1"}, + "west": {"uv": [0, 0, 2, 2], "texture": "#1"}, + "up": {"uv": [0, 0, 3, 2], "texture": "#1"}, + "down": {"uv": [0, 0, 3, 2], "texture": "#1"} + } + }, + { + "name": "lamp", + "from": [10, 12, 7.5], + "to": [11, 12.5, 8.5], + "faces": { + "north": {"uv": [1, 1, 3, 3], "texture": "#3"}, + "east": {"uv": [1, 1, 3, 3], "texture": "#3"}, + "south": {"uv": [1, 1, 3, 3], "texture": "#3"}, + "west": {"uv": [1, 1, 3, 3], "texture": "#3"}, + "up": {"uv": [1, 1, 3, 3], "texture": "#3"}, + "down": {"uv": [1, 1, 3, 3], "texture": "#3"} + } + }, + { + "name": "lamp", + "from": [10, 13.5, 7.5], + "to": [11, 14, 8.5], + "faces": { + "north": {"uv": [1, 1, 3, 3], "texture": "#3"}, + "east": {"uv": [1, 1, 3, 3], "texture": "#3"}, + "south": {"uv": [1, 1, 3, 3], "texture": "#3"}, + "west": {"uv": [1, 1, 3, 3], "texture": "#3"}, + "up": {"uv": [1, 1, 3, 3], "texture": "#3"}, + "down": {"uv": [1, 1, 3, 3], "texture": "#3"} + } + }, + { + "name": "lamp", + "from": [9.5, 12.5, 7.5], + "to": [11.5, 13.5, 8.5], + "faces": { + "north": {"uv": [1, 1, 3, 3], "texture": "#3"}, + "east": {"uv": [1, 1, 3, 3], "texture": "#3"}, + "south": {"uv": [1, 1, 3, 3], "texture": "#3"}, + "west": {"uv": [1, 1, 3, 3], "texture": "#3"}, + "up": {"uv": [1, 1, 3, 3], "texture": "#3"}, + "down": {"uv": [1, 1, 3, 3], "texture": "#3"} + } + }, + { + "name": "lamp body", + "from": [4, 4, 7], + "to": [7, 6, 9], + "faces": { + "north": {"uv": [0, 0, 3, 2], "texture": "#1"}, + "east": {"uv": [0, 0, 2, 2], "texture": "#1"}, + "south": {"uv": [0, 0, 3, 2], "texture": "#1"}, + "west": {"uv": [0, 0, 2, 2], "texture": "#1"}, + "up": {"uv": [0, 0, 3, 2], "texture": "#1"}, + "down": {"uv": [0, 0, 3, 2], "texture": "#1"} + } + }, + { + "name": "lamp", + "from": [5, 6, 7.5], + "to": [6, 6.5, 8.5], + "faces": { + "north": {"uv": [1, 1, 3, 3], "texture": "#3"}, + "east": {"uv": [1, 1, 3, 3], "texture": "#3"}, + "south": {"uv": [1, 1, 3, 3], "texture": "#3"}, + "west": {"uv": [1, 1, 3, 3], "texture": "#3"}, + "up": {"uv": [1, 1, 3, 3], "texture": "#3"}, + "down": {"uv": [1, 1, 3, 3], "texture": "#3"} + } + }, + { + "name": "lamp", + "from": [4.5, 6.5, 7.5], + "to": [6.5, 7.5, 8.5], + "faces": { + "north": {"uv": [1, 1, 3, 3], "texture": "#3"}, + "east": {"uv": [1, 1, 3, 3], "texture": "#3"}, + "south": {"uv": [1, 1, 3, 3], "texture": "#3"}, + "west": {"uv": [1, 1, 3, 3], "texture": "#3"}, + "up": {"uv": [1, 1, 3, 3], "texture": "#3"}, + "down": {"uv": [1, 1, 3, 3], "texture": "#3"} + } + }, + { + "name": "lamp", + "from": [5, 7.5, 7.5], + "to": [6, 8, 8.5], + "faces": { + "north": {"uv": [1, 1, 3, 3], "texture": "#3"}, + "east": {"uv": [1, 1, 3, 3], "texture": "#3"}, + "south": {"uv": [1, 1, 3, 3], "texture": "#3"}, + "west": {"uv": [1, 1, 3, 3], "texture": "#3"}, + "up": {"uv": [1, 1, 3, 3], "texture": "#3"}, + "down": {"uv": [1, 1, 3, 3], "texture": "#3"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/opensignals/signalconfigs/subsidiary/hl.json b/src/main/resources/assets/opensignals/signalconfigs/subsidiary/hl.json index 77fcf364d..d1e4f02b3 100644 --- a/src/main/resources/assets/opensignals/signalconfigs/subsidiary/hl.json +++ b/src/main/resources/assets/opensignals/signalconfigs/subsidiary/hl.json @@ -13,7 +13,6 @@ "ZS8": [ "zs2.ZS8", "mainlightsignallightbar.OFF", - "zs2.OFF", "zs2v.OFF" ], "ZP9": [ diff --git a/src/main/resources/assets/opensignals/signalconfigs/subsidiary/hlbridge.json b/src/main/resources/assets/opensignals/signalconfigs/subsidiary/hlbridge.json index 5f3b41996..0fd059837 100644 --- a/src/main/resources/assets/opensignals/signalconfigs/subsidiary/hlbridge.json +++ b/src/main/resources/assets/opensignals/signalconfigs/subsidiary/hlbridge.json @@ -13,7 +13,6 @@ "ZS8": [ "zs2.ZS8", "mainlightsignallightbar.OFF", - "zs2.OFF", "zs2v.OFF" ], "ZP9": [ diff --git a/src/test/java/com/troblecodings/signals/test/NameFileTest.java b/src/test/java/com/troblecodings/signals/test/NameFileTestV2.java similarity index 69% rename from src/test/java/com/troblecodings/signals/test/NameFileTest.java rename to src/test/java/com/troblecodings/signals/test/NameFileTestV2.java index 845f27962..151217ab6 100644 --- a/src/test/java/com/troblecodings/signals/test/NameFileTest.java +++ b/src/test/java/com/troblecodings/signals/test/NameFileTestV2.java @@ -18,13 +18,12 @@ import org.junit.jupiter.api.Test; import com.google.common.collect.Maps; -import com.troblecodings.signals.handler.NameHandlerFile; -import com.troblecodings.signals.handler.SignalStateFile; -import com.troblecodings.signals.handler.SignalStatePos; +import com.troblecodings.signals.handler.NameHandlerFileV2; +import com.troblecodings.signals.handler.SignalStatePosV2; import net.minecraft.util.math.BlockPos; -public class NameFileTest { +public class NameFileTestV2 { private static Path path = null; @@ -57,10 +56,10 @@ public static void resetAll() throws IOException { @Test public void testWriteAndRead() { - final BlockPos pos = GIRSyncEntryTests.randomBlockPos(); + final BlockPos pos = StateFileTestV2.getRandomBlockPos(); final String name = "wdasdfdgsddfwadsdf"; - final NameHandlerFile file = new NameHandlerFile(path); - final SignalStatePos statePos = file.createState(pos, name); + final NameHandlerFileV2 file = new NameHandlerFileV2(path); + final SignalStatePosV2 statePos = file.createState(pos, name); final String nameInFile = file.getString(statePos); assertEquals(name, nameInFile); @@ -70,7 +69,7 @@ public void testWriteAndRead() { file.deleteIndex(pos); assertNull(file.find(pos)); - final SignalStatePos statePos2 = file.createState(pos, name); + final SignalStatePosV2 statePos2 = file.createState(pos, name); final String nameInFile2 = file.getString(statePos2); assertEquals(name, nameInFile2); @@ -79,31 +78,31 @@ public void testWriteAndRead() { @Test public void testException() { - final NameHandlerFile file = new NameHandlerFile(path); + final NameHandlerFileV2 file = new NameHandlerFileV2(path); String str = ""; for (int i = 0; i < 129; i++) { str += "A"; } final String s = str; assertThrowsExactly(IllegalArgumentException.class, - () -> file.createState(GIRSyncEntryTests.randomBlockPos(), s)); + () -> file.createState(StateFileTestV2.getRandomBlockPos(), s)); } @Test public void moreThanPossible() { - final NameHandlerFile file = new NameHandlerFile(path); + final NameHandlerFileV2 file = new NameHandlerFileV2(path); final Map allNames = new HashMap<>(); - final List> listOfPos = new ArrayList<>(); + final List> listOfPos = new ArrayList<>(); String testString = ""; - for (int i = 0; i < SignalStateFile.MAX_ELEMENTS_PER_FILE + 10; i++) { + for (int i = 0; i < 5000; i++) { testString = "test_" + String.valueOf(i); - final BlockPos firstcreate = GIRSyncEntryTests.randomBlockPos(); - final SignalStatePos pos = file.createState(firstcreate, testString); + final BlockPos firstcreate = StateFileTestV2.getRandomBlockPos(); + final SignalStatePosV2 pos = file.createState(firstcreate, testString); listOfPos.add(Maps.immutableEntry(firstcreate, pos)); allNames.put(firstcreate, testString); } - for (int i = 0; i < listOfPos.size() / 1000; i++) { - final Map.Entry entry = listOfPos.get(i); + for (int i = 0; i < listOfPos.size(); i++) { + final Map.Entry entry = listOfPos.get(i); assertEquals(entry.getValue(), file.find(entry.getKey())); assertEquals(allNames.get(entry.getKey()), file.getString(entry.getValue())); } diff --git a/src/test/java/com/troblecodings/signals/test/SignalBoxNetworkTest.java b/src/test/java/com/troblecodings/signals/test/SignalBoxNetworkTest.java new file mode 100644 index 000000000..78eef571f --- /dev/null +++ b/src/test/java/com/troblecodings/signals/test/SignalBoxNetworkTest.java @@ -0,0 +1,180 @@ +package com.troblecodings.signals.test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.stream.Collectors; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.troblecodings.signals.core.ModeIdentifier; +import com.troblecodings.signals.enums.EnumGuiMode; +import com.troblecodings.signals.signalbox.ModeSet; +import com.troblecodings.signals.signalbox.Point; +import com.troblecodings.signals.signalbox.SignalBoxGrid; +import com.troblecodings.signals.signalbox.debug.DebugNetworkHandler; +import com.troblecodings.signals.signalbox.debug.SignalBoxFactory; +import com.troblecodings.signals.signalbox.entrys.IPathEntry; +import com.troblecodings.signals.signalbox.entrys.ModeIdentifierEntry; +import com.troblecodings.signals.signalbox.entrys.PathEntryType; +import com.troblecodings.signals.signalbox.entrys.PathOptionEntry; +import com.troblecodings.signals.signalbox.entrys.PointEntry; + +import net.minecraft.util.Rotation; + +public class SignalBoxNetworkTest { + + private static final Random RANDOM = new Random(); + + private SignalBoxGrid grid = new SignalBoxGrid(null); + private DebugNetworkHandler handler = new DebugNetworkHandler(grid); + + @BeforeAll + public static void setUpFactory() { + SignalBoxFactory.setUpFactoryForTests(); + } + + @BeforeEach + public void initializeNewGridAndNetwork() { + grid = new SignalBoxGrid(null); + handler = new DebugNetworkHandler(grid); + } + + @Test + public void testAddAndRemoveMode() { + final Map modes = new HashMap<>(); + for (int i = 0; i < 500; i++) { + Point point = getRandPoint(); + while (modes.containsKey(point)) { + point = getRandPoint(); + } + final ModeSet mode = getRandModeSet(); + handler.sendModeAdd(new ModeIdentifier(point, mode)); + modes.put(point, mode); + } + modes.forEach((point, mode) -> { + assertTrue(grid.getNode(point).getModes().keySet().contains(mode)); + handler.sendModeRemove(new ModeIdentifier(point, mode)); + assertTrue(!grid.getNode(point).getModes().keySet().contains(mode)); + }); + } + + @Test + public void testCounter() { + final int counter = RANDOM.nextInt(1000); + grid.setCounter(counter); + handler.sendCounter(); + assertEquals(counter, grid.getCurrentCounter()); + } + + @SuppressWarnings("unchecked") + @Test + public void testAddAndRemoveEntry() { + final Map>> entries = + new HashMap<>(); + for (int i = 0; i < 500; i++) { + final ModeSet mode = getRandModeSet(); + ModeIdentifier modeIdent = new ModeIdentifier(getRandPoint(), mode); + while (entries.containsKey(modeIdent)) { + modeIdent = new ModeIdentifier(getRandPoint(), mode); + } + final PathOptionEntry entry = new PathOptionEntry(); + final PathEntryType entryType = (PathEntryType) getRandEntryType(); + final IPathEntry iPathEntry = entryType.newValue(); + iPathEntry.setValue(iPathEntry.getDefaultValue()); + entry.addEntry(entryType, iPathEntry); + handler.sendEntryAdd(modeIdent, entryType, iPathEntry); + entries.put(modeIdent, Maps.immutableEntry(entry, entryType)); + } + entries.forEach((modeIdent, entry) -> { + assertTrue(grid.getNode(modeIdent.point).getOption(modeIdent.mode).get() + .equals(entry.getKey())); + handler.sendEntryRemove(modeIdent, entry.getValue()); + assertTrue(!grid.getNode(modeIdent.point).getOption(modeIdent.mode).get() + .equals(entry.getKey())); + }); + } + + @Test + public void testNodeLabel() { + final Map labels = new HashMap<>(); + for (int i = 0; i < 500; i++) { + Point point = getRandPoint(); + while (labels.containsKey(point)) { + point = getRandPoint(); + } + final ModeSet mode = getRandModeSet(); + handler.sendModeAdd(new ModeIdentifier(point, mode)); + handler.sendNodeLabel(point, "Test"); + labels.put(point, "Test"); + } + labels.forEach( + (point, label) -> assertTrue(grid.getNode(point).getCustomText().equals(label))); + } + + @Test + public void testAutoPoint() { + final List points = new ArrayList<>(); + for (int i = 0; i < 500; i++) { + Point point = getRandPoint(); + while (points.contains(point)) { + point = getRandPoint(); + } + final ModeSet mode = getRandModeSet(); + handler.sendModeAdd(new ModeIdentifier(point, mode)); + handler.sendAutoPoint(point, true); + points.add(point); + } + points.forEach(point -> assertTrue(grid.getNode(point).isAutoPoint())); + } + + @Test + public void testManuellOutput() { + final List points = new ArrayList<>(); + for (int i = 0; i < 500; i++) { + Point point = getRandPoint(); + final ModeSet mode = getRandModeSet(); + final ModeIdentifier ident = new ModeIdentifier(point, mode); + while (points.contains(ident)) { + point = getRandPoint(); + } + handler.sendModeAdd(ident); + handler.sendManuellOutputAdd(point, mode); + points.add(ident); + } + points.forEach(ident -> { + assertTrue(grid.getNode(ident.point).containsManuellOutput(ident.mode)); + handler.sendManuellOutputRemove(ident.point, ident.mode); + assertTrue(!grid.getNode(ident.point).containsManuellOutput(ident.mode)); + }); + } + + private Point getRandPoint() { + return new Point(RANDOM.nextInt(101), RANDOM.nextInt(101)); + } + + private ModeSet getRandModeSet() { + return new ModeSet(EnumGuiMode.values()[RANDOM.nextInt(EnumGuiMode.values().length)], + Rotation.values()[RANDOM.nextInt(Rotation.values().length)]); + } + + private static final List> PATHENTRY_TYPES = + Lists.newArrayList(PathEntryType.ALL_ENTRIES).stream() + .filter(entry -> !(entry.getEntryClass().equals(ModeIdentifierEntry.class) + || entry.getEntryClass().equals(PointEntry.class))) + .collect(Collectors.toList()); + + private PathEntryType getRandEntryType() { + return PATHENTRY_TYPES.get(RANDOM.nextInt(PATHENTRY_TYPES.size())); + } + +} diff --git a/src/test/java/com/troblecodings/signals/test/StateFileTest.java b/src/test/java/com/troblecodings/signals/test/StateFileTest.java deleted file mode 100644 index 63fffb38c..000000000 --- a/src/test/java/com/troblecodings/signals/test/StateFileTest.java +++ /dev/null @@ -1,155 +0,0 @@ -package com.troblecodings.signals.test; - -import static org.junit.jupiter.api.Assertions.assertArrayEquals; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import com.google.common.collect.Maps; -import com.troblecodings.signals.handler.SignalStateFile; -import com.troblecodings.signals.handler.SignalStatePos; - -import net.minecraft.util.math.BlockPos; - -public class StateFileTest { - - private static Path path = null; - - @BeforeEach - public void reset() throws IOException { - path = Paths.get("test/statefiles"); - if (Files.exists(path)) { - Files.list(path).forEach(t -> { - try { - Files.deleteIfExists(t); - } catch (final IOException e) { - e.printStackTrace(); - } - }); - } - } - - @AfterAll - public static void resetAll() throws IOException { - if (Files.exists(path)) { - Files.list(path).forEach(t -> { - try { - Files.deleteIfExists(t); - } catch (final IOException e) { - e.printStackTrace(); - } - }); - } - } - - @Test - public void creationAndAddition() { - final SignalStateFile file = new SignalStateFile(path); - final BlockPos firstcreate = GIRSyncEntryTests.randomBlockPos(); - final SignalStatePos createPos = file.create(firstcreate); - assertFalse(createPos.offset < SignalStateFile.MAX_OFFSET_OF_INDEX); - assertNotNull(createPos); - - final SignalStatePos position = file.find(firstcreate); - assertNotNull(position); - assertEquals(position, createPos); - - final SignalStateFile file2 = new SignalStateFile(path); - final SignalStatePos position2 = file2.find(firstcreate); - assertNotNull(position2); - assertEquals(position2, createPos); - } - - @Test - public void readAndWrite() { - final SignalStateFile file = new SignalStateFile(path); - - final BlockPos firstcreate = GIRSyncEntryTests.randomBlockPos(); - final SignalStatePos positionInFile = file.create(firstcreate); - final ByteBuffer buffer = ByteBuffer.allocate(SignalStateFile.STATE_BLOCK_SIZE); - GIRSyncEntryTests.RANDOM.nextBytes(buffer.array()); - file.write(positionInFile, buffer); - - final ByteBuffer outbuffer = file.read(positionInFile); - - assertArrayEquals(buffer.array(), outbuffer.array()); - } - - @Test - public void moreThenPossible() { - final SignalStateFile file = new SignalStateFile(path); - final List> listOfPos = new ArrayList<>(); - for (int i = 0; i < SignalStateFile.MAX_ELEMENTS_PER_FILE + 10; i++) { - final BlockPos firstcreate = GIRSyncEntryTests.randomBlockPos(); - listOfPos.add(Maps.immutableEntry(firstcreate, file.create(firstcreate))); - } - for (int i = 0; i < listOfPos.size() / 1000; i++) { - final Map.Entry entry = listOfPos.get(i); - assertEquals(entry.getValue(), file.find(entry.getKey())); - } - } - - @Test - public void readAndWriteCritical() { - final SignalStateFile file = new SignalStateFile(path); - - final BlockPos firstcreate = GIRSyncEntryTests.randomBlockPos(); - final SignalStatePos positionInFile = file.create(firstcreate); - - final ByteBuffer buffer = ByteBuffer.allocate(SignalStateFile.STATE_BLOCK_SIZE); - buffer.array()[0] = (byte) 0xFF; - buffer.array()[255] = (byte) 0x0F; - file.write(positionInFile, buffer); - - final BlockPos secondCreate = GIRSyncEntryTests.randomBlockPos(); - final SignalStatePos secondpositionInFile = file.create(secondCreate); - file.write(secondpositionInFile, buffer); - - final ByteBuffer outbuffer = file.read(positionInFile); - assertArrayEquals(buffer.array(), outbuffer.array()); - - final ByteBuffer outbuffer2 = file.read(secondpositionInFile); - assertArrayEquals(buffer.array(), outbuffer2.array()); - } - - @Test - public void testDelete() { - final SignalStateFile file = new SignalStateFile(path); - final BlockPos first = GIRSyncEntryTests.randomBlockPos(); - final SignalStatePos posInFile = file.create(first); - - final ByteBuffer buffer = ByteBuffer.allocate(SignalStateFile.STATE_BLOCK_SIZE); - buffer.array()[0] = (byte) 0xFF; - buffer.array()[255] = (byte) 0x0F; - file.write(posInFile, buffer); - - final SignalStatePos posToFind = file.find(first); - - assertEquals(posInFile, posToFind); - file.deleteIndex(first); - assertNull(file.find(first)); - - final SignalStatePos secondPos = file.create(first); - file.write(secondPos, buffer); - - final SignalStatePos secondPosToFind = file.find(first); - - assertEquals(secondPos, secondPosToFind); - file.deleteIndex(first); - assertNull(file.find(first)); - } -} \ No newline at end of file diff --git a/src/test/java/com/troblecodings/signals/test/StateFileTestV2.java b/src/test/java/com/troblecodings/signals/test/StateFileTestV2.java new file mode 100644 index 000000000..45f080687 --- /dev/null +++ b/src/test/java/com/troblecodings/signals/test/StateFileTestV2.java @@ -0,0 +1,227 @@ +package com.troblecodings.signals.test; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import com.google.common.collect.Maps; +import com.troblecodings.signals.handler.SignalStateFile; +import com.troblecodings.signals.handler.SignalStateFileV2; +import com.troblecodings.signals.handler.SignalStatePos; +import com.troblecodings.signals.handler.SignalStatePosV2; + +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.ChunkPos; + +public class StateFileTestV2 { + + private static Path path = null; + + @BeforeEach + public void reset() throws IOException { + path = Paths.get("test/statefiles"); + if (Files.exists(path)) { + Files.list(path).forEach(t -> { + try { + Files.deleteIfExists(t); + } catch (final IOException e) { + e.printStackTrace(); + } + }); + } + } + + @AfterAll + public static void resetAll() throws IOException { + if (Files.exists(path)) { + Files.list(path).forEach(t -> { + try { + Files.deleteIfExists(t); + } catch (final IOException e) { + e.printStackTrace(); + } + }); + } + } + + private static final Random RANDOM = new Random(); + + public static BlockPos getRandomBlockPos() { + return new BlockPos(RANDOM.nextInt(), RANDOM.nextInt(321), RANDOM.nextInt()); + } + + @Test + public void serializeAndDeserializePos() { + for (int i = 0; i < 1000; i++) { + final BlockPos pos = getRandomBlockPos(); + final ChunkPos chunk = new ChunkPos(pos); + final byte[] array = SignalStateFileV2.getChunkPosFromPos(chunk, pos); + assertEquals(pos, SignalStateFileV2.getPosFromChunkPos(chunk, array)); + } + } + + @Test + public void creationAndAddition() { + final SignalStateFileV2 file = new SignalStateFileV2(path); + final BlockPos firstcreate = getRandomBlockPos(); + final SignalStatePosV2 createPos = file.create(firstcreate); + assertNotNull(createPos); + + final SignalStatePosV2 position = file.find(firstcreate); + assertNotNull(position); + assertEquals(position, createPos); + + final SignalStateFileV2 file2 = new SignalStateFileV2(path); + file2.create(firstcreate); + final SignalStatePosV2 position2 = file2.find(firstcreate); + assertNotNull(position2); + assertEquals(position2, createPos); + } + + @Test + public void readAndWrite() { + final SignalStateFileV2 file = new SignalStateFileV2(path); + + final BlockPos firstcreate = GIRSyncEntryTests.randomBlockPos(); + final SignalStatePosV2 positionInFile = file.create(firstcreate); + final ByteBuffer buffer = ByteBuffer.allocate(SignalStateFile.STATE_BLOCK_SIZE); + RANDOM.nextBytes(buffer.array()); + file.write(positionInFile, buffer); + + final ByteBuffer outbuffer = file.read(positionInFile); + + assertArrayEquals(buffer.array(), outbuffer.array()); + } + + @Test + public void moreThenPossible() { + final SignalStateFileV2 file = new SignalStateFileV2(path); + final List> listOfPos = new ArrayList<>(); + final ByteBuffer buffer = ByteBuffer.allocate(SignalStateFile.STATE_BLOCK_SIZE); + buffer.array()[0] = (byte) 0xFF; + buffer.array()[255] = (byte) 0x0F; + for (int i = 0; i < 5000; i++) { + final BlockPos firstcreate = getRandomBlockPos(); + final SignalStatePosV2 statePos = file.create(firstcreate); + file.write(statePos, buffer); + listOfPos.add(Maps.immutableEntry(firstcreate, statePos)); + } + for (int i = 0; i < listOfPos.size(); i++) { + final Map.Entry entry = listOfPos.get(i); + final SignalStatePosV2 findPos = file.find(entry.getKey()); + assertEquals(buffer, file.read(findPos)); + assertEquals(entry.getValue(), findPos); + } + } + + @Test + public void readAndWriteCritical() { + final SignalStateFileV2 file = new SignalStateFileV2(path); + + final BlockPos firstcreate = getRandomBlockPos(); + final SignalStatePosV2 positionInFile = file.create(firstcreate); + + final ByteBuffer buffer = ByteBuffer.allocate(SignalStateFileV2.STATE_BLOCK_SIZE); + buffer.array()[0] = (byte) 0xFF; + buffer.array()[255] = (byte) 0x0F; + file.write(positionInFile, buffer); + + final BlockPos secondCreate = getRandomBlockPos(); + final SignalStatePosV2 secondpositionInFile = file.create(secondCreate); + file.write(secondpositionInFile, buffer); + + final ByteBuffer outbuffer = file.read(positionInFile); + assertArrayEquals(buffer.array(), outbuffer.array()); + + final ByteBuffer outbuffer2 = file.read(secondpositionInFile); + assertArrayEquals(buffer.array(), outbuffer2.array()); + } + + @Test + public void testDelete() { + final SignalStateFileV2 file = new SignalStateFileV2(path); + final BlockPos first = getRandomBlockPos(); + final SignalStatePosV2 posInFile = file.create(first); + + final ByteBuffer buffer = ByteBuffer.allocate(SignalStateFileV2.STATE_BLOCK_SIZE); + buffer.array()[0] = (byte) 0xFF; + buffer.array()[255] = (byte) 0x0F; + file.write(posInFile, buffer); + + final SignalStatePosV2 posToFind = file.find(first); + + assertEquals(posInFile, posToFind); + file.deleteIndex(first); + assertNull(file.find(first)); + + final SignalStatePosV2 secondPos = file.create(first); + file.write(secondPos, buffer); + + final SignalStatePosV2 secondPosToFind = file.find(first); + + assertEquals(secondPos, secondPosToFind); + file.deleteIndex(first); + assertNull(file.find(first)); + } + + @Test + public void testSpeedOfFind() { + final SignalStateFileV2 file = new SignalStateFileV2(path); + assertNull(file.find(getRandomBlockPos())); + } + + @Test + public void testMigration() { + final SignalStateFile file = new SignalStateFile(path); + final Map map = new HashMap<>(); + for (int i = 0; i < SignalStateFile.MAX_ELEMENTS_PER_FILE + 100; i++) { + final ByteBuffer buffer = ByteBuffer.allocate(SignalStateFile.STATE_BLOCK_SIZE); + RANDOM.nextBytes(buffer.array()); + final BlockPos firstcreate = getRandomBlockPos(); + final SignalStatePos statePos = file.create(firstcreate); + file.write(statePos, buffer); + map.put(firstcreate, buffer); + } + final Map contentMap = file.getAllEntries(); + final SignalStateFileV2 fileV2 = new SignalStateFileV2(path); + assertEquals(map.size(), contentMap.size()); + contentMap.forEach((pos, buffer) -> { + final SignalStatePosV2 statePos = fileV2.create(pos); + fileV2.write(statePos, buffer); + }); + contentMap.forEach((pos, buffer) -> { + final SignalStatePos posOldFile = file.find(pos); + final SignalStatePosV2 posInNewFile = fileV2.find(pos); + assertTrue(posOldFile != null); + assertTrue(posInNewFile != null); + assertEquals(file.read(posOldFile), fileV2.read(posInNewFile)); + }); + } + + @Test + public void testHash() { + final BlockPos pos = new BlockPos(-50, 82, -6156); + final ChunkPos chunk = new ChunkPos(pos); + System.out.println(SignalStateFileV2.hash(pos, chunk)); + final byte[] array = SignalStateFileV2.getChunkPosFromPos(chunk, pos); + assertEquals(pos, SignalStateFileV2.getPosFromChunkPos(chunk, array)); + + } +} \ No newline at end of file