Compare commits

...

2 Commits

@ -3,6 +3,7 @@ using CriticalPathAnalyzer.Client.Network;
using CriticalPathAnalyzer.Client.Tool;
using CriticalPathAnalyzer.Shared.Packets.S2C;
using EccsLogicWorldAPI.Client.Injectors;
using EccsLogicWorldAPI.Client.PacketIndexOrdering;
using FancyInput;
using LogicAPI.Client;
using LogicLog;
@ -33,9 +34,11 @@ namespace CriticalPathAnalyzer.Client {
}
);
// Inject packet handlers
RawPacketHandlerInjector.addPacketHandler(new AnnounceModPacketHandler(Manifest.Version));
// Register a handler for the server response packet
RawPacketHandlerInjector.addPacketHandler(new AnalyzePathResponseHandler());
// Mark it as optional so that the game works even if the mod is not present on one end
PacketIndexOrdering.markModAsOptional(GetType().Assembly);
Logger.Info("CriticalPathAnalyzer mod loaded");
}

@ -1,21 +0,0 @@
using System;
using CriticalPathAnalyzer.Shared.Packets.S2C;
using LogicWorld.SharedCode.Networking;
namespace CriticalPathAnalyzer.Client.Network {
public class AnnounceModPacketHandler : PacketHandler<AnnounceModPresence> {
private readonly Version _version;
public AnnounceModPacketHandler(Version version) {
_version = version;
}
public override void Handle(AnnounceModPresence packet, HandlerContext context) {
if (packet.Version == _version) {
CriticalPathAnalyzerClient.LoggerInstance.Info($"Mod is supported on the server: version={packet.Version}");
} else {
CriticalPathAnalyzerClient.LoggerInstance.Error($"Mod version mismatch: client={_version}, server={packet.Version}");
}
}
}
}

@ -1,6 +1,7 @@
using System;
using CriticalPathAnalyzer.Shared.Packets.C2S;
using CriticalPathAnalyzer.Shared.Packets.S2C;
using EccsLogicWorldAPI.Client.PacketIndexOrdering;
using JimmysUnityUtilities;
using LogicAPI.Data;
using LogicLog;
@ -20,8 +21,8 @@ namespace CriticalPathAnalyzer.Client.Tool {
private static AnalyzePathResponse _response;
private static Node _selectedNode;
private static readonly OutlineData StartOutline = new OutlineData(new Color24(0x00ff00));
private static readonly OutlineData EndOutline = new OutlineData(new Color24(0x00aaff));
private static readonly OutlineData startOutline = new OutlineData(new Color24(0x00ff00));
private static readonly OutlineData endOutline = new OutlineData(new Color24(0x00aaff));
public static void Init(ILogicLogger logger) {
_logger = logger;
@ -75,7 +76,7 @@ namespace CriticalPathAnalyzer.Client.Tool {
PegAddress pegAddress = RayCastPeg();
if (!pegAddress.IsEmpty()) {
Outliner.RemoveOutline(_startPegAddress);
Outliner.Outline(pegAddress, StartOutline);
Outliner.Outline(pegAddress, startOutline);
_startPegAddress = pegAddress;
if (!_startPegAddress.IsEmpty() && !_endPegAddress.IsEmpty()) {
CalculateCriticalPath();
@ -120,7 +121,7 @@ namespace CriticalPathAnalyzer.Client.Tool {
PegAddress pegAddress = RayCastPeg();
if (!pegAddress.IsEmpty()) {
Outliner.RemoveOutline(_endPegAddress);
Outliner.Outline(pegAddress, EndOutline);
Outliner.Outline(pegAddress, endOutline);
_endPegAddress = pegAddress;
if (!_startPegAddress.IsEmpty() && !_endPegAddress.IsEmpty()) {
CalculateCriticalPath();
@ -136,6 +137,11 @@ namespace CriticalPathAnalyzer.Client.Tool {
_logger.Error("Invalid pegs");
return;
}
if (!PacketIndexOrdering.doesServerSupportPacket(typeof(AnalyzePathRequest))) {
_logger.Error("Server doesn't support this mod");
return;
}
_currentRequestGuid = Guid.NewGuid();
Instances.SendData.Send(new AnalyzePathRequest {

@ -1,26 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using CriticalPathAnalyzer.Server.Network;
using CriticalPathAnalyzer.Server.Tool;
using CriticalPathAnalyzer.Shared.Packets.S2C;
using EccsLogicWorldAPI.Server;
using EccsLogicWorldAPI.Server.Injectors;
using EccsLogicWorldAPI.Shared.PacketWrapper;
using EccsLogicWorldAPI.Server.PacketIndexOrdering;
using LogicAPI.Data;
using LogicAPI.Networking;
using LogicAPI.Networking.Packets.Initialization;
using LogicAPI.Server;
using LogicAPI.Server.Networking;
using LogicAPI.Server.Networking.ClientVerification;
using LogicLog;
using LogicWorld.SharedCode.Networking;
namespace CriticalPathAnalyzer.Server {
// ReSharper disable once ClassNeverInstantiated.Global
public class CriticalPathAnalyzerServer : ServerMod, IClientVerifier {
public class CriticalPathAnalyzerServer : ServerMod {
private NetworkServer _networkServer;
private readonly Dictionary<string, bool> _playerHasWireTracer = new Dictionary<string, bool>();
public static ILogicLogger LoggerInstance;
@ -33,35 +27,11 @@ namespace CriticalPathAnalyzer.Server {
throw new Exception("Could not get Service 'NetworkServer'.");
}
// Inject client verifier:
RawJoinVerifierInjector.addVerifier(this);
PacketHandlerManager.getCustomPacketHandler<ClientLoadedWorldPacket>()
.addHandlerToEnd(new ClientJoinedPacketHandler(this));
// Register a handler for the client request packet
RawPacketHandlerInjector.addPacketHandler(new CriticalPathAnalyzerRequestHandler(this));
}
/// <summary>
/// Gets called before a player (client) joins the server.
/// Used to check if the player has this mod installed
/// </summary>
public void Verify(VerificationContext ctx) {
bool hasMod = ctx.ApprovalPacket.ClientMods.Contains((Manifest.ID, Manifest.Version));
string playerName = ctx.PlayerID.Name;
_playerHasWireTracer[playerName] = hasMod;
LoggerInstance.Info($"Verifying player {playerName}: hasMod={hasMod}");
}
/// <summary>
/// Gets called after verifying a connecting player.
/// If the player has this mod installed, send a packet informing about the mod's presence on the server.
/// </summary>
public void PlayerJoined(PlayerData playerData, HandlerContext context) {
_playerHasWireTracer.TryGetValue(playerData.Name, out bool hasWireTracer);
if (hasWireTracer) {
_networkServer.Send(context.Sender, new AnnounceModPresence() {
Version = Manifest.Version
});
}
// Mark it as optional so that the game works even if the mod is not present on one end
PacketIndexOrdering.markModAsOptional(GetType().Assembly);
}
/// <summary>

@ -1,16 +0,0 @@
using EccsLogicWorldAPI.Shared.PacketWrapper;
using LogicAPI.Networking.Packets.Initialization;
using LogicWorld.SharedCode.Networking;
namespace CriticalPathAnalyzer.Server.Network {
public class ClientJoinedPacketHandler : CustomPacketHandler<ClientLoadedWorldPacket> {
private readonly CriticalPathAnalyzerServer _criticalPathAnalyzerServer;
public ClientJoinedPacketHandler(CriticalPathAnalyzerServer criticalPathAnalyzerServer) {
_criticalPathAnalyzerServer = criticalPathAnalyzerServer;
}
public override void handle(ref bool isCancelled, ref ClientLoadedWorldPacket packet, HandlerContext context) {
_criticalPathAnalyzerServer.PlayerJoined(packet.PlayerData, context);
}
}
}

@ -14,19 +14,19 @@ using LogicWorld.Server.Circuitry;
namespace CriticalPathAnalyzer.Server.Tool {
public class ServerPathTracer {
// Reflection/Delegate access helpers:
private static readonly Func<InputPeg, Cluster> GetCluster;
private static readonly Func<InputPeg, Cluster> getCluster;
// Services needed to lookup wires/pegs:
private static readonly ICircuitryManager Circuits;
private static readonly IWorldData World;
private static readonly ICircuitryManager circuits;
private static readonly IWorldData world;
static ServerPathTracer() {
GetCluster = Delegator.createPropertyGetter<InputPeg, Cluster>(
getCluster = Delegator.createPropertyGetter<InputPeg, Cluster>(
Properties.getPrivate(typeof(InputPeg), "Cluster")
);
Circuits = ServiceGetter.getService<ICircuitryManager>();
World = ServiceGetter.getService<IWorldData>();
circuits = ServiceGetter.getService<ICircuitryManager>();
world = ServiceGetter.getService<IWorldData>();
}
public static bool TracePath(
@ -342,7 +342,7 @@ namespace CriticalPathAnalyzer.Server.Tool {
/// <param name="address">Address of the peg</param>
/// <returns>True if it exists, false if it doesn't</returns>
private static bool PegExists(PegAddress address) {
IComponentInWorld component = World.Lookup(address.ComponentAddress);
IComponentInWorld component = world.Lookup(address.ComponentAddress);
if (component == null) {
return false; // Component of the peg does not exist in world.
}
@ -353,13 +353,13 @@ namespace CriticalPathAnalyzer.Server.Tool {
}
private static Cluster GetClusterAt(InputAddress peg) {
InputPeg originPeg = Circuits.LookupInput(peg);
InputPeg originPeg = circuits.LookupInput(peg);
if (originPeg == null) {
throw new Exception(
"Tried to lookup cluster on input peg, but the peg was not present in the circuit model! This should never happen, as the peg is present in the world.");
}
Cluster cluster = GetCluster(originPeg);
Cluster cluster = getCluster(originPeg);
if (cluster == null) {
throw new Exception(
"Tried to lookup cluster on input peg, but the cluster was 'null', this should never happen! As the peg is present in the world.");
@ -378,13 +378,13 @@ namespace CriticalPathAnalyzer.Server.Tool {
if (pegAddress.IsInputAddress(out InputAddress inputAddress)) {
primaryClusters.Add(GetClusterAt(inputAddress));
} else {
HashSet<WireAddress> wires = World.LookupPegWires(pegAddress);
HashSet<WireAddress> wires = world.LookupPegWires(pegAddress);
if (wires == null) {
return;
}
foreach (WireAddress wireAddress in wires) {
Wire wire = World.Lookup(wireAddress);
Wire wire = world.Lookup(wireAddress);
if (wire == null) {
throw new Exception(
"Tried to lookup wire given its address, but the world did not contain it. World must be corrupted.");

@ -1,10 +0,0 @@
using System;
using LogicAPI.Networking.Packets;
using MessagePack;
namespace CriticalPathAnalyzer.Shared.Packets.S2C {
[MessagePackObject]
public class AnnounceModPresence : Packet {
[Key(0)] public Version Version;
}
}
Loading…
Cancel
Save