225 lines
6.7 KiB
Java
225 lines
6.7 KiB
Java
package com.simibubi.create.content.logistics.trains;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Collections;
|
|
import java.util.List;
|
|
import java.util.Set;
|
|
import java.util.UUID;
|
|
|
|
import javax.annotation.Nullable;
|
|
|
|
import com.google.common.collect.ImmutableList;
|
|
import com.simibubi.create.Create;
|
|
import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointType;
|
|
import com.simibubi.create.content.logistics.trains.management.edgePoint.signal.EdgeGroupColor;
|
|
import com.simibubi.create.content.logistics.trains.management.edgePoint.signal.SignalEdgeGroupPacket;
|
|
import com.simibubi.create.content.logistics.trains.management.edgePoint.signal.TrackEdgePoint;
|
|
import com.simibubi.create.foundation.networking.AllPackets;
|
|
import com.simibubi.create.foundation.utility.Couple;
|
|
import com.simibubi.create.foundation.utility.Pair;
|
|
|
|
import net.minecraft.server.level.ServerPlayer;
|
|
import net.minecraftforge.network.PacketDistributor;
|
|
|
|
public class TrackGraphSync {
|
|
|
|
List<TrackGraphPacket> queuedPackets = new ArrayList<>();
|
|
int rollCallIn;
|
|
|
|
public void serverTick() {
|
|
flushGraphPacket();
|
|
|
|
if (!queuedPackets.isEmpty()) {
|
|
for (TrackGraphPacket packet : queuedPackets) {
|
|
if (!packet.packetDeletesGraph && !Create.RAILWAYS.trackNetworks.containsKey(packet.graphId))
|
|
continue;
|
|
AllPackets.channel.send(PacketDistributor.ALL.noArg(), packet);
|
|
rollCallIn = 3;
|
|
}
|
|
|
|
queuedPackets.clear();
|
|
}
|
|
|
|
if (rollCallIn <= 0)
|
|
return;
|
|
rollCallIn--;
|
|
if (rollCallIn > 0)
|
|
return;
|
|
|
|
sendRollCall();
|
|
}
|
|
|
|
//
|
|
|
|
public void nodeAdded(TrackGraph graph, TrackNode node) {
|
|
flushGraphPacket(graph);
|
|
currentGraphSyncPacket.addedNodes.put(node.getNetId(), Pair.of(node.getLocation(), node.getNormal()));
|
|
currentPayload++;
|
|
}
|
|
|
|
public void edgeAdded(TrackGraph graph, TrackNode node1, TrackNode node2, TrackEdge edge) {
|
|
flushGraphPacket(graph);
|
|
currentGraphSyncPacket.addedEdges
|
|
.add(Pair.of(Pair.of(Couple.create(node1.getNetId(), node2.getNetId()), edge.getTrackMaterial()), edge.getTurn()));
|
|
currentPayload++;
|
|
}
|
|
|
|
public void pointAdded(TrackGraph graph, TrackEdgePoint point) {
|
|
flushGraphPacket(graph);
|
|
currentGraphSyncPacket.addedEdgePoints.add(point);
|
|
currentPayload++;
|
|
}
|
|
|
|
public void pointRemoved(TrackGraph graph, TrackEdgePoint point) {
|
|
flushGraphPacket(graph);
|
|
currentGraphSyncPacket.removedEdgePoints.add(point.getId());
|
|
currentPayload++;
|
|
}
|
|
|
|
public void nodeRemoved(TrackGraph graph, TrackNode node) {
|
|
flushGraphPacket(graph);
|
|
int nodeId = node.getNetId();
|
|
if (currentGraphSyncPacket.addedNodes.remove(nodeId) == null)
|
|
currentGraphSyncPacket.removedNodes.add(nodeId);
|
|
currentGraphSyncPacket.addedEdges.removeIf(pair -> {
|
|
Couple<Integer> ids = pair.getFirst().getFirst();
|
|
return ids.getFirst()
|
|
.intValue() == nodeId
|
|
|| ids.getSecond()
|
|
.intValue() == nodeId;
|
|
});
|
|
}
|
|
|
|
public void graphSplit(TrackGraph graph, Set<TrackGraph> additional) {
|
|
flushGraphPacket(graph);
|
|
additional.forEach(rg -> currentGraphSyncPacket.splitSubGraphs.put(rg.nodesById.keySet()
|
|
.stream()
|
|
.findFirst()
|
|
.get(), Pair.of(rg.netId, rg.id)));
|
|
}
|
|
|
|
public void graphRemoved(TrackGraph graph) {
|
|
flushGraphPacket(graph);
|
|
currentGraphSyncPacket.packetDeletesGraph = true;
|
|
}
|
|
|
|
//
|
|
|
|
public void sendEdgeGroups(List<UUID> ids, List<EdgeGroupColor> colors, ServerPlayer player) {
|
|
AllPackets.channel.send(PacketDistributor.PLAYER.with(() -> player),
|
|
new SignalEdgeGroupPacket(ids, colors, true));
|
|
}
|
|
|
|
public void edgeGroupCreated(UUID id, EdgeGroupColor color) {
|
|
AllPackets.channel.send(PacketDistributor.ALL.noArg(), new SignalEdgeGroupPacket(id, color));
|
|
}
|
|
|
|
public void edgeGroupRemoved(UUID id) {
|
|
AllPackets.channel.send(PacketDistributor.ALL.noArg(),
|
|
new SignalEdgeGroupPacket(ImmutableList.of(id), Collections.emptyList(), false));
|
|
}
|
|
|
|
//
|
|
|
|
public void edgeDataChanged(TrackGraph graph, TrackNode node1, TrackNode node2, TrackEdge edge) {
|
|
flushGraphPacket(graph);
|
|
currentGraphSyncPacket.syncEdgeData(node1, node2, edge);
|
|
currentPayload++;
|
|
}
|
|
|
|
public void edgeDataChanged(TrackGraph graph, TrackNode node1, TrackNode node2, TrackEdge edge, TrackEdge edge2) {
|
|
flushGraphPacket(graph);
|
|
currentGraphSyncPacket.syncEdgeData(node1, node2, edge);
|
|
currentGraphSyncPacket.syncEdgeData(node2, node1, edge2);
|
|
currentPayload++;
|
|
}
|
|
|
|
public void sendFullGraphTo(TrackGraph graph, ServerPlayer player) {
|
|
TrackGraphSyncPacket packet = new TrackGraphSyncPacket(graph.id, graph.netId);
|
|
packet.fullWipe = true;
|
|
int sent = 0;
|
|
|
|
for (TrackNode node : graph.nodes.values()) {
|
|
TrackGraphSyncPacket currentPacket = packet;
|
|
currentPacket.addedNodes.put(node.getNetId(), Pair.of(node.getLocation(), node.getNormal()));
|
|
if (sent++ < 1000)
|
|
continue;
|
|
|
|
sent = 0;
|
|
packet = flushAndCreateNew(graph, player, packet);
|
|
}
|
|
|
|
for (TrackNode node : graph.nodes.values()) {
|
|
TrackGraphSyncPacket currentPacket = packet;
|
|
if (!graph.connectionsByNode.containsKey(node))
|
|
continue;
|
|
graph.connectionsByNode.get(node)
|
|
.forEach((node2, edge) -> {
|
|
Couple<Integer> key = Couple.create(node.getNetId(), node2.getNetId());
|
|
currentPacket.addedEdges.add(Pair.of(Pair.of(key, edge.getTrackMaterial()), edge.getTurn()));
|
|
currentPacket.syncEdgeData(node, node2, edge);
|
|
});
|
|
|
|
if (sent++ < 1000)
|
|
continue;
|
|
|
|
sent = 0;
|
|
packet = flushAndCreateNew(graph, player, packet);
|
|
}
|
|
|
|
for (EdgePointType<?> type : EdgePointType.TYPES.values()) {
|
|
for (TrackEdgePoint point : graph.getPoints(type)) {
|
|
packet.addedEdgePoints.add(point);
|
|
|
|
if (sent++ < 1000)
|
|
continue;
|
|
|
|
sent = 0;
|
|
packet = flushAndCreateNew(graph, player, packet);
|
|
}
|
|
}
|
|
|
|
if (sent > 0)
|
|
flushAndCreateNew(graph, player, packet);
|
|
}
|
|
|
|
private void sendRollCall() {
|
|
AllPackets.channel.send(PacketDistributor.ALL.noArg(), new TrackGraphRollCallPacket());
|
|
}
|
|
|
|
private TrackGraphSyncPacket flushAndCreateNew(TrackGraph graph, ServerPlayer player, TrackGraphSyncPacket packet) {
|
|
AllPackets.channel.send(PacketDistributor.PLAYER.with(() -> player), packet);
|
|
packet = new TrackGraphSyncPacket(graph.id, graph.netId);
|
|
return packet;
|
|
}
|
|
|
|
//
|
|
|
|
private TrackGraphSyncPacket currentGraphSyncPacket;
|
|
private int currentPayload;
|
|
|
|
private void flushGraphPacket() {
|
|
flushGraphPacket(null, 0);
|
|
}
|
|
|
|
private void flushGraphPacket(TrackGraph graph) {
|
|
flushGraphPacket(graph.id, graph.netId);
|
|
}
|
|
|
|
private void flushGraphPacket(@Nullable UUID graphId, int netId) {
|
|
if (currentGraphSyncPacket != null) {
|
|
if (currentGraphSyncPacket.graphId.equals(graphId) && currentPayload < 1000)
|
|
return;
|
|
queuedPackets.add(currentGraphSyncPacket);
|
|
currentGraphSyncPacket = null;
|
|
currentPayload = 0;
|
|
}
|
|
|
|
if (graphId != null) {
|
|
currentGraphSyncPacket = new TrackGraphSyncPacket(graphId, netId);
|
|
currentPayload = 0;
|
|
}
|
|
}
|
|
|
|
}
|