diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 5603d0964..ee283c7fe 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 e2101f6db..c053f1718 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,19 @@ # Changelog +## [1.18.2 - 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.18.2 - 3.8.1] * fix: issues with loading NBT data of signal box * fix: issues with setting pathway with a overlap nearby diff --git a/contentPackLib b/contentPackLib index e5f59e1df..1c340d02b 160000 --- a/contentPackLib +++ b/contentPackLib @@ -1 +1 @@ -Subproject commit e5f59e1df12e4e949934f6b2b61adfec9f4154e4 +Subproject commit 1c340d02b6cef9ac03881d018a9a409d30b6ac90 diff --git a/guilib b/guilib index a7ab1c632..be7a4a58f 160000 --- a/guilib +++ b/guilib @@ -1 +1 @@ -Subproject commit a7ab1c6326c72c8510cb9aba1b8e7fa4d54f8edb +Subproject commit be7a4a58fb6d10c9f85185d4e54fb511b2dc8f3c diff --git a/src/main/java/com/troblecodings/signals/animation/SignalAnimationHandler.java b/src/main/java/com/troblecodings/signals/animation/SignalAnimationHandler.java index 5938a2241..deb4920d6 100644 --- a/src/main/java/com/troblecodings/signals/animation/SignalAnimationHandler.java +++ b/src/main/java/com/troblecodings/signals/animation/SignalAnimationHandler.java @@ -40,7 +40,8 @@ public SignalAnimationHandler(final SignalTileEntity tile) { this.tile = tile; } - private final Map>> animationPerModel = new HashMap<>(); + private final Map>> animationPerModel = + new HashMap<>(); public void render(final RenderAnimationInfo info) { final BlockState state = tile.getBlockState(); @@ -52,8 +53,8 @@ public void render(final RenderAnimationInfo info) { } final SignalAngel angle = state.getValue(Signal.ANGEL); final ModelBlockRenderer renderer = info.dispatcher.getModelRenderer(); - final VertexConsumer vertex = info.source - .getBuffer(ItemBlockRenderTypes.getRenderType(state, false)); + final VertexConsumer vertex = + info.source.getBuffer(ItemBlockRenderTypes.getRenderType(state, false)); final IModelData data = tile.getModelData(); final float tick = currentTick - this.lastWorldTick; @@ -91,11 +92,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); @@ -146,8 +148,8 @@ public void updateAnimationListFromBlock() { map.forEach((entry, animations) -> { final BakedModel model = SignalCustomModel.getModelFromLocation( new ResourceLocation(OpenSignalsMain.MODID, entry.getKey())); - final ModelTranslation translation = new ModelTranslation(VectorWrapper.ZERO, - Quaternion.ONE); + final ModelTranslation translation = + new ModelTranslation(VectorWrapper.ZERO, Quaternion.ONE); translation.setModelTranslation(entry.getValue().copy()); animationPerModel.put(model, Maps.immutableEntry(translation, animations.stream() .map(animation -> animation.copy()).collect(Collectors.toList()))); diff --git a/src/main/java/com/troblecodings/signals/blocks/Signal.java b/src/main/java/com/troblecodings/signals/blocks/Signal.java index a21480cef..2e2ea37f2 100644 --- a/src/main/java/com/troblecodings/signals/blocks/Signal.java +++ b/src/main/java/com/troblecodings/signals/blocks/Signal.java @@ -68,7 +68,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 +80,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++) { @@ -434,14 +438,10 @@ public void getUpdate(final Level world, final BlockPos pos) { if (sound.duration == 1) { world.playSound(null, pos, sound.state, SoundSource.BLOCKS, 1.0F, 1.0F); - } else { - if (world.getBlockTicks().hasScheduledTick(pos, this)) - return; - else { - if (sound.predicate.test(properties)) { - world.scheduleTick(pos, this, 1); - } - } + } else if (world.getBlockTicks().hasScheduledTick(pos, this)) + return; + else if (sound.predicate.test(properties)) { + world.scheduleTick(pos, this, 1); } }); } diff --git a/src/main/java/com/troblecodings/signals/blocks/SignalBox.java b/src/main/java/com/troblecodings/signals/blocks/SignalBox.java index f9313a15b..b177721d9 100644 --- a/src/main/java/com/troblecodings/signals/blocks/SignalBox.java +++ b/src/main/java/com/troblecodings/signals/blocks/SignalBox.java @@ -61,7 +61,9 @@ public Optional getSupplierWrapperName() { public void playerWillDestroy(final Level world, final BlockPos pos, final BlockState state, final Player 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)); } diff --git a/src/main/java/com/troblecodings/signals/config/ConfigHandler.java b/src/main/java/com/troblecodings/signals/config/ConfigHandler.java index 99fae4fdc..20d8f0797 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 3d269f977..0502fa857 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 9abb1c803..a4ae230e8 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 083ae3ddd..000000000 --- a/src/main/java/com/troblecodings/signals/enums/SignalBoxNetwork.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.troblecodings.signals.enums; - -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; - -} \ 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 b1eb09734..206e8c03b 100644 --- a/src/main/java/com/troblecodings/signals/guis/ContainerPlacementtool.java +++ b/src/main/java/com/troblecodings/signals/guis/ContainerPlacementtool.java @@ -37,26 +37,29 @@ public void sendAllDataToRemote() { } private void sendItemProperties(final Player player) { - // TODO Redo networking final ItemStack stack = player.getMainHandItem(); final Placementtool tool = (Placementtool) stack.getItem(); 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())).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); @@ -94,16 +97,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 5ffa756b0..ab46cc145 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,31 +20,25 @@ 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.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.core.BlockPos; @@ -52,7 +46,6 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Rotation; public class ContainerSignalBox extends ContainerBase implements UIClientSync, IChunkLoadable { @@ -62,16 +55,22 @@ public class ContainerSignalBox extends ContainerBase implements UIClientSync, I protected final Map, PathType> nextPathways = new HashMap<>(); protected final Map> validInConnections = new HashMap<>(); protected SignalBoxGrid grid; + protected SignalBoxTileEntity tile; + 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 Player 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); @@ -84,10 +83,12 @@ public ContainerSignalBox(final GuiInfo info) { @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 +113,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 +163,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,46 +237,64 @@ 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 Level 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 Player playerIn) { super.removed(playerIn); + grid.removeNetwork(); + network.removeNetwork(); if (this.tile != null) { this.tile.remove(this); } @@ -494,30 +313,10 @@ public Map getPositionForTypes() { public boolean stillValid(final Player 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/GuiSignalBox.java b/src/main/java/com/troblecodings/signals/guis/GuiSignalBox.java index 6cca9fc9a..74ceb4b51 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).isEmpty()) 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, @@ -276,11 +271,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())); @@ -290,7 +292,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(); }))); })); @@ -364,7 +366,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); }); @@ -461,7 +463,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); @@ -483,7 +485,6 @@ private void initializePageSettings(final UIEntity entity, private void initializeFieldUsage(final UIEntity entity) { reset(); - sendModeChanges(); page = SignalBoxPage.OPERATION; initializeFieldTemplate(this::tileNormal, false); resetSelection(entity); @@ -520,7 +521,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; @@ -555,10 +558,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(); } @@ -618,304 +621,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()); - rendering.clearTrainNumbers(); - } - - 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) @@ -939,8 +658,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(); @@ -963,18 +682,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 4e3ee557c..5619fd7c0 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,10 +723,11 @@ 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(Quaternion.fromXYZ(0, (float) x * 0.1f, 0)), 1)); + } preview.add(new UIScissor()); preview.add(renderer); @@ -785,8 +785,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(); @@ -933,9 +933,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())); + } }); } } diff --git a/src/main/java/com/troblecodings/signals/guis/ModeDropDownBoxUI.java b/src/main/java/com/troblecodings/signals/guis/ModeDropDownBoxUI.java index 751693a15..086441f89 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()); + .orElseGet(() -> new SignalBoxNode(gui.network)); 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 ebd71b070..9e13b36ae 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; @@ -50,14 +53,14 @@ public class SidePanel { - public static final ResourceLocation COUNTER_TEXTURE = new ResourceLocation( - OpenSignalsMain.MODID, "gui/textures/counter.png"); - public static final ResourceLocation REDSTONE = new ResourceLocation(OpenSignalsMain.MODID, - "gui/textures/redstone.png"); - public static final ResourceLocation SAVE = new ResourceLocation(OpenSignalsMain.MODID, - "gui/textures/save.png"); - public static final ResourceLocation EMERGENCY = new ResourceLocation(OpenSignalsMain.MODID, - "gui/textures/emergency.png"); + public static final ResourceLocation COUNTER_TEXTURE = + new ResourceLocation(OpenSignalsMain.MODID, "gui/textures/counter.png"); + public static final ResourceLocation REDSTONE = + new ResourceLocation(OpenSignalsMain.MODID, "gui/textures/redstone.png"); + public static final ResourceLocation SAVE = + new ResourceLocation(OpenSignalsMain.MODID, "gui/textures/save.png"); + public static final ResourceLocation EMERGENCY = + new ResourceLocation(OpenSignalsMain.MODID, "gui/textures/emergency.png"); private boolean showHelpPage = true; private final UIEntity helpPage = new UIEntity(); @@ -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(); @@ -310,9 +314,9 @@ public void helpUsageMode(final SignalBoxNode node) { manuelButton.setScale(0.95f); helpList.add(manuelButton); - final UIEntity savedPathways = GuiElements.createButton( - " " + I18Wrapper.format("info.usage.savedpathways"), - e -> addSavedPathsToUI()); + final UIEntity savedPathways = + GuiElements.createButton(" " + I18Wrapper.format("info.usage.savedpathways"), + e -> addSavedPathsToUI()); final UIEntity savedPathsEntity = new UIEntity(); savedPathsEntity.setHeight(20); @@ -347,25 +351,25 @@ public void helpUsageMode(final SignalBoxNode node) { final Minecraft mc = Minecraft.getInstance(); final Map subsidiaries = gui.enabledSubsidiaries; - final Map> possibleSubsidiaries = gui.container.possibleSubsidiaries; + final Map> possibleSubsidiaries = + gui.container.possibleSubsidiaries; if (node != null) { final Map modes = node.getModes(); - final List guiModes = modes.keySet().stream().map(mode -> mode.mode) - .collect(Collectors.toList()); + final List guiModes = + modes.keySet().stream().map(mode -> mode.mode).collect(Collectors.toList()); helpList.add(GuiElements.createLabel(I18Wrapper.format("info.usage.node"), new UIEntity().getBasicTextColor(), 0.8f)); if (guiModes.contains(EnumGuiMode.HP)) { - final UIEntity entity = GuiElements - .createBoolElement(BoolIntegerables.of("auto_pathway"), e -> { - gui.setAutoPoint(node.getPoint(), (byte) e); + final UIEntity entity = + GuiElements.createBoolElement(BoolIntegerables.of("auto_pathway"), e -> { node.setAutoPoint(e == 1 ? true : false); }, node.isAutoPoint() ? 1 : 0); entity.setScale(0.95f); helpList.add(entity); } - final UIEntity reset = GuiElements.createButton(I18Wrapper.format("button.reset"), - e -> { + final UIEntity reset = + GuiElements.createButton(I18Wrapper.format("button.reset"), e -> { final UIEntity screen = GuiElements.createScreen(selectionEntity -> { final UIBox hbox = new UIBox(UIBox.VBOX, 3); selectionEntity.add(hbox); @@ -384,10 +388,10 @@ public void helpUsageMode(final SignalBoxNode node) { selectionEntity.add(question); selectionEntity.add(infoEntity); final UIEntity buttons = new UIEntity(); - final UIEntity buttonYes = GuiElements - .createButton(I18Wrapper.format("btn.yes"), e1 -> { + 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()); @@ -422,19 +426,20 @@ public void helpUsageMode(final SignalBoxNode node) { if (!(mode.mode == EnumGuiMode.HP || mode.mode == EnumGuiMode.RS)) { continue; } - final UIEntity entity = GuiElements - .createButton(I18Wrapper.format("btn.subsidiary"), e -> { + final UIEntity entity = + GuiElements.createButton(I18Wrapper.format("btn.subsidiary"), e -> { final UIBox hbox = new UIBox(UIBox.VBOX, 1); final UIEntity list = new UIEntity(); list.setInherits(true); list.add(hbox); list.add(GuiElements.createButton(I18Wrapper.format("btn.return"), a -> gui.pop())); - final List possibleSubsidiaires = possibleSubsidiaries - .getOrDefault(signalPos, SubsidiaryState.ALL_STATES); + final List possibleSubsidiaires = + possibleSubsidiaries.getOrDefault(signalPos, + SubsidiaryState.ALL_STATES); possibleSubsidiaires.forEach(state -> { - final int defaultValue = state - .equals(node.getSubsidiaryState(mode)) ? 0 : 1; + final int defaultValue = + state.equals(node.getSubsidiaryState(mode)) ? 0 : 1; list.add(GuiElements.createEnumElement( new SizeIntegerables<>(state.getName(), 2, i -> i == 1 ? "false" : "true"), @@ -446,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)); }); @@ -485,14 +490,14 @@ public void helpUsageMode(final SignalBoxNode node) { statusEntity.add(currentStatus); final String modeName = I18Wrapper.format("property." + mode.mode.name()); - final String rotationName = I18Wrapper - .format("property." + mode.rotation.name() + ".rotation"); - final UIEntity manuelButtonEntity = GuiElements - .createButton(I18Wrapper.format("info.usage.manuel") + " : " + modeName - + " - " + rotationName, e1 -> { - final EnumPathUsage usage = option - .getEntry(PathEntryType.PATHUSAGE) - .orElse(EnumPathUsage.FREE); + final String rotationName = + I18Wrapper.format("property." + mode.rotation.name() + ".rotation"); + final UIEntity manuelButtonEntity = + GuiElements.createButton(I18Wrapper.format("info.usage.manuel") + " : " + + modeName + " - " + rotationName, e1 -> { + final EnumPathUsage usage = + option.getEntry(PathEntryType.PATHUSAGE) + .orElse(EnumPathUsage.FREE); final UIEntity info = new UIEntity(); info.setInherits(true); info.add(new UIBox(UIBox.VBOX, 5)); @@ -521,8 +526,8 @@ public void helpUsageMode(final SignalBoxNode node) { GuiSignalBox.REDSTONE_OFF_BLOCKED)); } info.add(textureEntity); - final UILabel outputStatus = new UILabel( - ((!usage.equals(EnumPathUsage.FREE)) + final UILabel outputStatus = + new UILabel(((!usage.equals(EnumPathUsage.FREE)) || node.containsManuellOutput(mode)) ? I18Wrapper.format( "info.usage.rs.true") @@ -539,47 +544,49 @@ public void helpUsageMode(final SignalBoxNode node) { if (canBeManuelChanged) { info.add(GuiElements.createButton( I18Wrapper.format("info.usage.change"), i -> { - final boolean turnOff = node - .containsManuellOutput(mode); + final boolean turnOff = + node.containsManuellOutput(mode); textureEntity.clear(); 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(); - final UIEntity screen = GuiElements - .createScreen(e -> e.add(info)); + final UIEntity screen = + GuiElements.createScreen(e -> e.add(info)); gui.push(screen); }); manuelButtonEntity .add(new UIToolTip(I18Wrapper.format("info.usage.manuel.desc"))); manuellOutputs.add(manuelButtonEntity); } - final EnumPathUsage path = option.getEntry(PathEntryType.PATHUSAGE) - .orElse(EnumPathUsage.FREE); + final EnumPathUsage path = + option.getEntry(PathEntryType.PATHUSAGE).orElse(EnumPathUsage.FREE); if (!(path.equals(EnumPathUsage.FREE) || path.equals(EnumPathUsage.PROTECTED))) { isPathBlocked = true; } } if (isPathBlocked) { - final UIEntity trainNumberButton = GuiElements - .createButton(I18Wrapper.format("info.usage.trainnumber"), e -> { + final UIEntity trainNumberButton = + GuiElements.createButton(I18Wrapper.format("info.usage.trainnumber"), e -> { final UIEntity layout = new UIEntity(); layout.add(new UIBox(UIBox.VBOX, 10)); layout.setInherits(true); @@ -599,16 +606,17 @@ public void helpUsageMode(final SignalBoxNode node) { lowerEntity.setInherits(true); lowerEntity.add(new UIBox(UIBox.HBOX, 5)); lowerEntity.add(GuiElements.createSpacerH(7)); - final UIEntity save = GuiElements - .createButton(I18Wrapper.format("btn.save"), e1 -> { - gui.sendTrainNumber(node.getPoint(), input.getText()); + final UIEntity save = + GuiElements.createButton(I18Wrapper.format("btn.save"), e1 -> { + 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"))); @@ -625,8 +633,8 @@ public void helpUsageMode(final SignalBoxNode node) { } if (!manuellOutputs.isEmpty()) { - final UIEntity manuellOutputList = GuiElements - .createButton(I18Wrapper.format("info.usage.manuel"), e -> { + final UIEntity manuellOutputList = + GuiElements.createButton(I18Wrapper.format("info.usage.manuel"), e -> { gui.push(GuiElements.createScreen(screen -> { manuellOutputs.forEach(screen::add); screen.add(new UIClickable(e1 -> gui.pop(), 1)); @@ -637,8 +645,8 @@ public void helpUsageMode(final SignalBoxNode node) { helpList.add(manuellOutputList); } - final UIEntity edit = GuiElements.createButton(I18Wrapper.format("info.usage.edit"), - e -> { + final UIEntity edit = + GuiElements.createButton(I18Wrapper.format("info.usage.edit"), e -> { helpUsageMode(null); gui.initializePageTileConfig(node); }); @@ -657,8 +665,8 @@ public void helpUsageMode(final SignalBoxNode node) { final UIBox hbox = new UIBox(UIBox.VBOX, 3); selectionEntity.add(hbox); final UIEntity question = new UIEntity(); - final UILabel label = new UILabel( - name + " : " + holder.entry.toString().toUpperCase()); + final UILabel label = + new UILabel(name + " : " + holder.entry.toString().toUpperCase()); label.setTextColor(0xFFFFFFFF); question.setScaleX(1.1f); question.setScaleY(1.1f); @@ -672,8 +680,8 @@ public void helpUsageMode(final SignalBoxNode node) { selectionEntity.add(question); selectionEntity.add(infoEntity); final UIEntity buttons = new UIEntity(); - final UIEntity buttonYes = GuiElements - .createButton(I18Wrapper.format("btn.yes"), e1 -> { + final UIEntity buttonYes = + GuiElements.createButton(I18Wrapper.format("btn.yes"), e1 -> { gui.pop(); gui.disableSubsidiary(pos, holder); subsidiaries.remove(pos); @@ -724,8 +732,8 @@ private void addManuellRStoUI() { statusEntity.add(currentStatus); final AtomicBoolean canBeManuelChanged = new AtomicBoolean(true); currentNode.getModes().forEach((mode, entry) -> { - final EnumPathUsage pathUsage = entry.getEntry(PathEntryType.PATHUSAGE) - .orElse(EnumPathUsage.FREE); + final EnumPathUsage pathUsage = + entry.getEntry(PathEntryType.PATHUSAGE).orElse(EnumPathUsage.FREE); if (!pathUsage.equals(EnumPathUsage.FREE)) { currentStatus.setText(I18Wrapper.format("info.usage.status") + " : " + I18Wrapper.format("info.usage.status.blocked")); @@ -761,8 +769,8 @@ private void addManuellRStoUI() { textureEntity.add(new UITexture(GuiSignalBox.REDSTONE_OFF_BLOCKED)); } info.add(textureEntity); - final UILabel outputStatus = new UILabel( - ((!pathUsage.equals(EnumPathUsage.FREE)) + final UILabel outputStatus = + new UILabel(((!pathUsage.equals(EnumPathUsage.FREE)) || currentNode.containsManuellOutput(mode)) ? I18Wrapper.format("info.usage.rs.true") : I18Wrapper.format("info.usage.rs.false")); @@ -782,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))); }); @@ -836,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 062926059..999f7fe9f 100644 --- a/src/main/java/com/troblecodings/signals/handler/ClientNameHandler.java +++ b/src/main/java/com/troblecodings/signals/handler/ClientNameHandler.java @@ -27,18 +27,21 @@ 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 ClientLevel world = mc.level; mc.doRunTask(() -> { + final BlockPos pos = buffer.getBlockPos(); + final ClientLevel world = mc.level; + final StateInfo info = new StateInfo(world, pos); + final boolean removed = buffer.getBoolean(); + if (removed) { + setRemoved(info); + return; + } + final String name = buffer.getString(); + synchronized (CLIENT_NAMES) { + CLIENT_NAMES.put(info, name); + } + if (world == null) + return; final BlockState state = world.getBlockState(pos); if (state == null) return; @@ -47,10 +50,9 @@ public void deserializeClient(final ReadBuffer buffer) { }); } - private static void setRemoved(final BlockPos pos) { - final Minecraft mc = Minecraft.getInstance(); + private static void setRemoved(final StateInfo info) { synchronized (CLIENT_NAMES) { - CLIENT_NAMES.remove(new StateInfo(mc.level, pos)); + CLIENT_NAMES.remove(info); } } diff --git a/src/main/java/com/troblecodings/signals/handler/ClientSignalStateHandler.java b/src/main/java/com/troblecodings/signals/handler/ClientSignalStateHandler.java index da2611b39..ac0ad6ccd 100644 --- a/src/main/java/com/troblecodings/signals/handler/ClientSignalStateHandler.java +++ b/src/main/java/com/troblecodings/signals/handler/ClientSignalStateHandler.java @@ -13,6 +13,8 @@ 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 com.troblecodings.signals.tileentitys.SignalTileEntity; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientLevel; @@ -24,7 +26,8 @@ public class ClientSignalStateHandler implements INetworkSync { - private static final Map> CURRENTLY_LOADED_STATES = new HashMap<>(); + private static final Map> CURRENTLY_LOADED_STATES = + new HashMap<>(); public static final Map getClientStates(final StateInfo info) { synchronized (CURRENTLY_LOADED_STATES) { @@ -38,40 +41,46 @@ public static final Map getClientStates(final StateInfo info @Override public void deserializeClient(final ReadBuffer buffer) { final Minecraft mc = Minecraft.getInstance(); - final ClientLevel 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(() -> { - BlockEntity entity; - while ((entity = level.getBlockEntity(signalPos)) == null) { - final long currentTime = Calendar.getInstance().getTimeInMillis(); - if (currentTime - startTime >= 5000) - return; - continue; + mc.doRunTask(() -> { + final ClientLevel 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())); + synchronized (CURRENTLY_LOADED_STATES) { + final Map 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(() -> { + BlockEntity entity; + while ((entity = level.getBlockEntity(signalPos)) == null) { + final long currentTime = Calendar.getInstance().getTimeInMillis(); + if (currentTime - startTime >= 5000) + return; + continue; + } + if (!(entity instanceof SignalTileEntity)) + return; + final BlockState state = entity.getBlockState(); + mc.level.setBlocksDirty(signalPos, state, state); + entity.requestModelDataUpdate(); + ((SignalTileEntity) entity).updateAnimationState(newProperties, changedState); + mc.levelRenderer.blockChanged(null, signalPos, null, null, 8); + }); }); } diff --git a/src/main/java/com/troblecodings/signals/handler/SignalStateHandler.java b/src/main/java/com/troblecodings/signals/handler/SignalStateHandler.java index 2038e0b43..5eaa8180b 100644 --- a/src/main/java/com/troblecodings/signals/handler/SignalStateHandler.java +++ b/src/main/java/com/troblecodings/signals/handler/SignalStateHandler.java @@ -57,11 +57,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; @@ -111,7 +114,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); }); } @@ -136,10 +139,11 @@ 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<>()); - if (!list.contains(listener)) + final List list = + TASKS_WHEN_LOAD.computeIfAbsent(info, _u -> new ArrayList<>()); + if (!list.contains(listener)) { list.add(listener); + } } } } @@ -148,10 +152,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); + } } } @@ -192,8 +197,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); }); } @@ -204,9 +209,8 @@ private static void createToFile(final SignalStateInfo info, SignalStateFileV2 file; synchronized (ALL_LEVEL_FILES) { file = ALL_LEVEL_FILES.get(info.world); - if (file == null) { + if (file == null) return; - } } SignalStatePosV2 pos = file.find(info.pos); if (pos == null) { @@ -227,8 +231,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); @@ -241,10 +245,11 @@ 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()) + if (!contains.get()) { createToFile(info, changedProperties); + } }); info.world.getServer().execute(() -> info.world.updateNeighborsAt(info.pos, info.signal)); } @@ -257,14 +262,11 @@ public static Map getStates(final SignalStateInfo info) { final Map stateVolitile = CURRENTLY_LOADED_STATES.get(info); states = stateVolitile == null ? null : ImmutableMap.copyOf(stateVolitile); } - if (states != null) { + if (states != null) return states; - } else { - if (info.world.isClientSide) { - return Map.of(); - } - return readAndSerialize(info); - } + if (info.world.isClientSide) + return Map.of(); + return readAndSerialize(info); } private static void migrateWorldFilesToV2(final Level world) { @@ -340,11 +342,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) { @@ -358,8 +359,9 @@ private static Map readAndSerialize(final SignalStateInfo st continue; } final int typeID = Byte.toUnsignedInt(byteArray[i]); - if (typeID <= 0) + if (typeID <= 0) { continue; + } final String value = property.getObjFromID(typeID - 1); map.put(property, value); } @@ -412,10 +414,11 @@ public static void onWorldSave(final WorldEvent.Save save) { synchronized (CURRENTLY_LOADED_STATES) { maps = ImmutableMap.copyOf(CURRENTLY_LOADED_STATES); } - if (writeService != null) + if (writeService != null) { writeService.execute(() -> maps.entrySet().stream() .filter(entry -> entry.getKey().world.equals(world)) .forEach(entry -> createToFile(entry.getKey(), entry.getValue()))); + } } @SubscribeEvent @@ -442,30 +445,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) { + private 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) { - if (properties.size() > 254) { + 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))); @@ -473,28 +475,27 @@ public static ByteBuffer packToByteBuffer(final SignalStateInfo stateInfo, } private static void sendTo(final SignalStateInfo info, final Map properties, - final @Nullable Player player) { + final @Nullable Player 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 Player player) { - if (properties == null || properties.isEmpty()) { + final Map properties, final Player 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) { - if (properties == null || properties.isEmpty()) { + 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)); } @@ -553,27 +554,25 @@ 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; } - if (!holders.contains(info.holder)) + if (!holders.contains(info.holder)) { holders.add(info.holder); + } } 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) { @@ -598,8 +597,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..10b6bb0bf --- /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.core.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 99aa8ea2a..7db300768 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,9 +106,10 @@ 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() @@ -120,9 +121,10 @@ 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() @@ -142,9 +144,10 @@ protected SignalStateInfo getLastSignalInfo() { final Signal nextSignal = SignalBoxHandler .getSignal(new StateInfo(pathwayToBlock.tile.getLevel(), pathwayToBlock.tile.getBlockPos()), otherLastSignal.pos); - if (nextSignal != null) + if (nextSignal != null) { lastSignalInfo = new SignalStateInfo(tile.getLevel(), otherLastSignal.pos, nextSignal); + } } } return super.getLastSignalInfo(); @@ -183,7 +186,6 @@ public boolean tryBlock(final BlockPos position) { .getPathwayByLastPoint(pathwayToBlock.getLastPoint()); pathwayToBlock.setPathStatus(EnumPathUsage.BLOCKED); pathwayToBlock.updateTrainNumber(trainNumber); - otherGrid.updateToNet(pathwayToBlock); }); } return result; @@ -191,17 +193,14 @@ 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 @@ -209,19 +208,20 @@ protected void updateSignalStates() { 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,9 +234,7 @@ protected void updateSignalStates() { toSet = SignalState.OFF; } position.updateSignalState(toSet); - nodes.add(position.node); }); - updateSignalsOnClient(nodes); } public void setOtherPathwayToBlock(final InterSignalBoxPathway pathway) { diff --git a/src/main/java/com/troblecodings/signals/signalbox/PathwayData.java b/src/main/java/com/troblecodings/signals/signalbox/PathwayData.java index 0da63d36f..577fa0407 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,7 @@ protected boolean resetProtectionWay() { if (pw == null) return; pw.directResetOfProtectionWay(); - pw.removeProtectionWay(); - grid.updateToNet(pw); + grid.tryNextPathways(); })); }).start(); return true; @@ -249,10 +254,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 +296,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 +369,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 467df23b0..bda067135 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,38 +239,26 @@ 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(); } private boolean executingTryNextPWs = false; - private void tryNextPathways() { + protected void tryNextPathways() { if (executingTryNextPWs) return; executingTryNextPWs = true; @@ -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); + 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 17c12acab..0d6243ca1 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 35254b17b..7ae31a6db 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 Level world = tile.getLevel(); final StateInfo identifier = new StateInfo(world, tile.getBlockPos()); final MainSignalIdentifier startSignal = data.getStartSignal(); @@ -204,22 +195,17 @@ 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(); + final Map distantSignalPositions = + data.getOtherSignals(); distantSignalPositions.forEach((holder, position) -> { if (holder.shouldTurnSignalOff()) return; final Signal current = SignalBoxHandler.getSignal(identifier, position.pos); if (current == null) return; - final ConfigInfo info = new ConfigInfo( - new SignalStateInfo(world, position.pos, current), lastSignal, data, - position.isRepeater); + final ConfigInfo info = + new ConfigInfo(new SignalStateInfo(world, position.pos, current), lastSignal, + data, position.isRepeater); if (position.guiMode.equals(EnumGuiMode.HP)) { SignalConfig.loadDisable(info); } else { @@ -227,6 +213,7 @@ protected void setSignals(final SignalStateInfo lastSignal) { } }); updateSignalStates(); + isExecutingSignalSet = false; } private void updatePreSignals() { @@ -237,8 +224,8 @@ private void updatePreSignals() { final Signal first = SignalBoxHandler.getSignal(identifier, startSignal.pos); if (first == null) return; - final SignalStateInfo firstInfo = new SignalStateInfo(tile.getLevel(), startSignal.pos, - first); + final SignalStateInfo firstInfo = + new SignalStateInfo(tile.getLevel(), startSignal.pos, first); data.getPreSignals().forEach(posIdent -> { final Signal current = SignalBoxHandler.getSignal(identifier, posIdent.pos); if (current == null) @@ -250,22 +237,18 @@ 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); }); } } - final Map distantSignalPositions = data - .getOtherSignals(); + final Map distantSignalPositions = + data.getOtherSignals(); distantSignalPositions.forEach((holder, position) -> { if (holder.shouldTurnSignalOff()) { position.updateSignalState(SignalState.OFF); @@ -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 Level 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,16 +311,13 @@ 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(); + final Map distantSignalPositions = + data.getOtherSignals(); distantSignalPositions.values().forEach((position) -> { final Signal current = SignalBoxHandler .getSignal(new StateInfo(tile.getLevel(), tile.getBlockPos()), position.pos); @@ -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,10 +349,9 @@ 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)); + final Rotation rotation = + SignalBoxUtil.getRotationFromDelta(node.getPoint().delta(path.point1)); for (final EnumGuiMode mode : Arrays.asList(EnumGuiMode.VP, EnumGuiMode.RS, EnumGuiMode.HP, EnumGuiMode.ZS3)) { node.getOption(new ModeSet(mode, rotation)).ifPresent( @@ -405,8 +360,8 @@ public void compact(final Point point) { new StateInfo(tile.getLevel(), tile.getBlockPos()), position); if (current == null) return; - final Map distantSignalPositions = data - .getOtherSignals(); + final Map distantSignalPositions = + data.getOtherSignals(); final OtherSignalIdentifier identifier = distantSignalPositions .getOrDefault(new BlockPosSignalHolder(position), new OtherSignalIdentifier(point, @@ -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 Level 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); @@ -531,24 +485,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() { @@ -561,7 +507,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 ad1052685..7e4574f65 100644 --- a/src/main/java/com/troblecodings/signals/signalbox/SignalBoxUtil.java +++ b/src/main/java/com/troblecodings/signals/signalbox/SignalBoxUtil.java @@ -244,8 +244,8 @@ private static double getCosts(final ModeSet mode, final SignalBoxNode currentNo private static boolean checkForValidEnd(final PathType type, final SignalBoxNode lastNode, final SignalBoxNode previous) { final Point delta = lastNode.getPoint().delta(previous.getPoint()); - final Rotation rotation = SignalBoxUtil.getRotationFromDelta(delta) - .getRotated(Rotation.CLOCKWISE_180); + final Rotation rotation = + SignalBoxUtil.getRotationFromDelta(delta).getRotated(Rotation.CLOCKWISE_180); for (final EnumGuiMode mode : type.getModes()) { if (!mode.getModeType().isValidEnd()) { continue; @@ -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 Level 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..93d23ca66 --- /dev/null +++ b/src/main/java/com/troblecodings/signals/signalbox/debug/DebugNetworkHandler.java @@ -0,0 +1,101 @@ +package com.troblecodings.signals.signalbox.debug; + +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.core.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(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 95a1bb551..2cd47a85d 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 7cdcdebf2..e4293e291 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 cbd4777fd..315b11c52 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 c3ad385a0..41dece6cc 100644 --- a/src/main/java/com/troblecodings/signals/tileentitys/SignalControllerTileEntity.java +++ b/src/main/java/com/troblecodings/signals/tileentitys/SignalControllerTileEntity.java @@ -199,13 +199,13 @@ public void loadWrapper(final NBTWrapper wrapper) { }); enabledStates.put(direction, map); if (comp.contains(RS_BOOLEAN)) { - currentStates[direction.ordinal()] = comp.getWrapper(RS_BOOLEAN) - .getBoolean(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); @@ -221,9 +221,9 @@ public void loadWrapper(final NBTWrapper wrapper) { 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); } @@ -231,10 +231,19 @@ public void loadWrapper(final NBTWrapper wrapper) { 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 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); + unlink(); + return; + } + 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)); @@ -243,11 +252,11 @@ public void onLoad() { } 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)); } @@ -278,7 +287,8 @@ public boolean link(final BlockPos pos, final CompoundTag tag) { onLoad(); setChanged(); return true; - } else if (block instanceof RedstoneInput) { + } + if (block instanceof RedstoneInput) { linkedRSInput = pos; loadChunkAndGetTile(RedstoneIOTileEntity.class, (ServerLevel) level, pos, (tile, _u) -> tile.linkController(getBlockPos())); @@ -322,8 +332,8 @@ public void redstoneUpdate() { 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))); } @@ -334,8 +344,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/java/com/troblecodings/signals/tileentitys/SignalTileEntity.java b/src/main/java/com/troblecodings/signals/tileentitys/SignalTileEntity.java index 8d5a56551..4afb53dc3 100644 --- a/src/main/java/com/troblecodings/signals/tileentitys/SignalTileEntity.java +++ b/src/main/java/com/troblecodings/signals/tileentitys/SignalTileEntity.java @@ -15,6 +15,7 @@ import com.troblecodings.signals.core.SignalStateListener; import com.troblecodings.signals.core.StateInfo; import com.troblecodings.signals.core.TileEntityInfo; +import com.troblecodings.signals.enums.ChangedState; import com.troblecodings.signals.handler.ClientSignalStateHandler; import com.troblecodings.signals.handler.SignalStateHandler; import com.troblecodings.signals.handler.SignalStateInfo; @@ -101,8 +102,8 @@ public SignalAnimationHandler getAnimationHandler() { @OnlyIn(Dist.CLIENT) @Override public void requestModelDataUpdate() { - final Map newProperties = ClientSignalStateHandler - .getClientStates(new StateInfo(level, worldPosition)); + final Map newProperties = + ClientSignalStateHandler.getClientStates(new StateInfo(level, worldPosition)); final boolean wasEmpty = properties.isEmpty(); handler.updateStates(newProperties, wasEmpty); this.properties.clear(); @@ -110,6 +111,13 @@ public void requestModelDataUpdate() { super.requestModelDataUpdate(); } + @OnlyIn(Dist.CLIENT) + public void updateAnimationState(final Map properties, + final ChangedState state) { + handler.updateStates(properties, state.equals(ChangedState.ADDED_TO_CACHE) + || state.equals(ChangedState.ADDED_TO_FILE)); + } + @Override public void onLoad() { if (!level.isClientSide) { 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/animations/shmech.json b/src/main/resources/assets/opensignals/animations/shmech.json index 3af7bd181..98ca2ddeb 100644 --- a/src/main/resources/assets/opensignals/animations/shmech.json +++ b/src/main/resources/assets/opensignals/animations/shmech.json @@ -18,8 +18,8 @@ { "predicate": "with(SH_MECH.SH1) && hasandisnot(sh_high)", "mode": "ROTATION", - "rotationAxis": "Z", "animationSpeed": 2, + "rotationAxis": "Z", "rotation": -45 }, { 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 ddc725f7e..cadcf82f1 100644 --- a/src/test/java/com/troblecodings/signals/test/NameFileTest.java +++ b/src/test/java/com/troblecodings/signals/test/NameFileTestV2.java @@ -17,13 +17,12 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -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.core.BlockPos; -public class NameFileTest { +public class NameFileTestV2 { private static Path path = null; @@ -56,10 +55,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); @@ -69,7 +68,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); @@ -78,31 +77,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(Map.entry(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..f03832922 --- /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.world.level.block.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(0, 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(0, 101), RANDOM.nextInt(0, 101)); + } + + private ModeSet getRandModeSet() { + return new ModeSet(EnumGuiMode.values()[RANDOM.nextInt(0, EnumGuiMode.values().length)], + Rotation.values()[RANDOM.nextInt(0, 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(0, 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 bb4f5618d..000000000 --- a/src/test/java/com/troblecodings/signals/test/StateFileTest.java +++ /dev/null @@ -1,183 +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 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 org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import com.troblecodings.signals.handler.SignalStateFile; -import com.troblecodings.signals.handler.SignalStatePos; - -import net.minecraft.core.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<>(); - 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 = GIRSyncEntryTests.randomBlockPos(); - final SignalStatePos statePos = file.create(firstcreate); - file.write(statePos, buffer); - listOfPos.add(Map.entry(firstcreate, statePos)); - } - for (int i = 0; i < listOfPos.size() / 1000; i++) { - final Map.Entry entry = listOfPos.get(i); - final SignalStatePos findPos = file.find(entry.getKey()); - assertEquals(buffer, file.read(findPos)); - assertEquals(entry.getValue(), findPos); - } - } - - @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)); - } - - @Test - public void testGetAllEntries() { - 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); - GIRSyncEntryTests.RANDOM.nextBytes(buffer.array()); - final BlockPos firstcreate = GIRSyncEntryTests.randomBlockPos(); - final SignalStatePos statePos = file.create(firstcreate); - file.write(statePos, buffer); - map.put(firstcreate, buffer); - } - final Map readOutEntries = file.getAllEntries(); - assertEquals(map.size(), readOutEntries.size()); - map.forEach((pos, byteBuffer) -> { - assertTrue(readOutEntries.containsKey(pos)); - assertEquals(byteBuffer, readOutEntries.get(pos)); - }); - } -} \ 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 index a21d9e4a7..741f6f238 100644 --- a/src/test/java/com/troblecodings/signals/test/StateFileTestV2.java +++ b/src/test/java/com/troblecodings/signals/test/StateFileTestV2.java @@ -62,7 +62,7 @@ public static void resetAll() throws IOException { private static final Random RANDOM = new Random(); - private static BlockPos getRandomBlockPos() { + public static BlockPos getRandomBlockPos() { return new BlockPos(RANDOM.nextInt(), RANDOM.nextInt(-64, 321), RANDOM.nextInt()); } @@ -122,7 +122,7 @@ public void moreThenPossible() { file.write(statePos, buffer); listOfPos.add(Map.entry(firstcreate, statePos)); } - for (int i = 0; i < listOfPos.size() / 1000; i++) { + 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));