diff --git a/CriticalPathAnalyzer/CriticalPathAnalyzer/FancyInput/ContextMetadata.jecs b/CriticalPathAnalyzer/CriticalPathAnalyzer/FancyInput/ContextMetadata.jecs
index 0544baa..1f57727 100644
--- a/CriticalPathAnalyzer/CriticalPathAnalyzer/FancyInput/ContextMetadata.jecs
+++ b/CriticalPathAnalyzer/CriticalPathAnalyzer/FancyInput/ContextMetadata.jecs
@@ -1,4 +1,6 @@
+# Define two contexts - one for keybindings used during the building state and one for the tool's state
CriticalPathAnalyzer.CriticalPathAnalyzerBuilding:
+ # This keybinding is used during the game's standard building state - need to inject into the build actions
InjectTriggersInto:
- MHG.BuildActions
Triggers:
diff --git a/CriticalPathAnalyzer/CriticalPathAnalyzer/FancyInput/TriggerMetadata.jecs b/CriticalPathAnalyzer/CriticalPathAnalyzer/FancyInput/TriggerMetadata.jecs
index 77de273..8de3166 100644
--- a/CriticalPathAnalyzer/CriticalPathAnalyzer/FancyInput/TriggerMetadata.jecs
+++ b/CriticalPathAnalyzer/CriticalPathAnalyzer/FancyInput/TriggerMetadata.jecs
@@ -1,3 +1,4 @@
+# Define all available keybindings of the mod
CriticalPathAnalyzer.OpenPathAnalyzer:
Heading: "CriticalPathAnalyzer"
DefaultBinding:
diff --git a/CriticalPathAnalyzer/CriticalPathAnalyzer/src/client/CriticalPathAnalyzerClient.cs b/CriticalPathAnalyzer/CriticalPathAnalyzer/src/client/CriticalPathAnalyzerClient.cs
index 81db8fe..51c7c2b 100644
--- a/CriticalPathAnalyzer/CriticalPathAnalyzer/src/client/CriticalPathAnalyzerClient.cs
+++ b/CriticalPathAnalyzer/CriticalPathAnalyzer/src/client/CriticalPathAnalyzerClient.cs
@@ -24,14 +24,18 @@ namespace CriticalPathAnalyzer.Client {
// Inject a hook into the game code to check for our keybindings
KeybindingsInjector.Inject();
-
+
// Inject packet handlers
- RawPacketHandlerInjector.addPacketHandler(new AnnounceModPacketHandler(Manifest.Version));
- RawPacketHandlerInjector.addPacketHandler(new AnalyzePathResponseHandler());
+ RawPacketHandlerInjector.addPacketHandler(new AnnounceModPacketHandler(Manifest.Version));
+ RawPacketHandlerInjector.addPacketHandler(new AnalyzePathResponseHandler());
Logger.Info("CriticalPathAnalyzer mod loaded");
}
+ ///
+ /// Handler method for the server's analysis response.
+ /// Gets called from the AnalyzePathResponseHandler packet handler class
+ ///
public static void OnAnalyzePathResponse(AnalyzePathResponse response) {
LoggerInstance.Info($"Got response from server");
CriticalPathAnalyzerTool.HandleResponse(response);
diff --git a/CriticalPathAnalyzer/CriticalPathAnalyzer/src/client/CriticalPathAnalyzerGameState.cs b/CriticalPathAnalyzer/CriticalPathAnalyzer/src/client/CriticalPathAnalyzerGameState.cs
index 68e5c70..d731641 100644
--- a/CriticalPathAnalyzer/CriticalPathAnalyzer/src/client/CriticalPathAnalyzerGameState.cs
+++ b/CriticalPathAnalyzer/CriticalPathAnalyzer/src/client/CriticalPathAnalyzerGameState.cs
@@ -9,9 +9,17 @@ namespace CriticalPathAnalyzer.Client {
public class CriticalPathAnalyzerGameState : GameState {
public const string Id = "CriticalPathAnalyzerTool";
- public override bool MouseLocked => true;
public override string TextID => Id;
+ ///
+ /// Locked mouse means you look around when you move it.
+ /// False would display the cursor to be able to click on UI elements.
+ ///
+ public override bool MouseLocked => true;
+
+ ///
+ /// This list gets printed on the game's top left UI panel which displays the currently available keybindings
+ ///
public override IEnumerable HelpScreenTriggers => new InputTrigger[] {
UITrigger.Back,
CriticalPathAnalyzerTrigger.AnalyzePathStart,
@@ -19,10 +27,16 @@ namespace CriticalPathAnalyzer.Client {
CriticalPathAnalyzerTrigger.DisplayLoop,
};
+ ///
+ /// Called when the game transitions into this game state i.e. after pressing the configured keybinding
+ ///
public override void OnEnter() {
CriticalPathAnalyzerClient.LoggerInstance.Info("CPA enter");
}
+ ///
+ /// Ran every frame when inside this game state
+ ///
public override void OnRun() {
if (CustomInput.DownThisFrame(UITrigger.Back)) {
GameStateManager.TransitionBackToBuildingState();
@@ -35,6 +49,9 @@ namespace CriticalPathAnalyzer.Client {
}
}
+ ///
+ /// Called when the game transitions away from this game state i.e. after pressing the back keybinding
+ ///
public override void OnExit() {
CriticalPathAnalyzerClient.LoggerInstance.Info("CPA exit");
CriticalPathAnalyzerTool.Clear();
diff --git a/CriticalPathAnalyzer/CriticalPathAnalyzer/src/client/keybindings/CriticalPathAnalyzerContext.cs b/CriticalPathAnalyzer/CriticalPathAnalyzer/src/client/keybindings/CriticalPathAnalyzerContext.cs
index 4e149e7..5e1472b 100644
--- a/CriticalPathAnalyzer/CriticalPathAnalyzer/src/client/keybindings/CriticalPathAnalyzerContext.cs
+++ b/CriticalPathAnalyzer/CriticalPathAnalyzer/src/client/keybindings/CriticalPathAnalyzerContext.cs
@@ -1,4 +1,5 @@
namespace CriticalPathAnalyzer.Client.Keybindings {
+ // Define two contexts - one for keybindings used during the building state and one for the tool's state
public enum CriticalPathAnalyzerContext {
CriticalPathAnalyzerBuilding,
CriticalPathAnalyzerTool,
diff --git a/CriticalPathAnalyzer/CriticalPathAnalyzer/src/client/keybindings/CriticalPathAnalyzerTrigger.cs b/CriticalPathAnalyzer/CriticalPathAnalyzer/src/client/keybindings/CriticalPathAnalyzerTrigger.cs
index 9d1094f..ac63061 100644
--- a/CriticalPathAnalyzer/CriticalPathAnalyzer/src/client/keybindings/CriticalPathAnalyzerTrigger.cs
+++ b/CriticalPathAnalyzer/CriticalPathAnalyzer/src/client/keybindings/CriticalPathAnalyzerTrigger.cs
@@ -1,4 +1,5 @@
namespace CriticalPathAnalyzer.Client.Keybindings {
+ // Define all available keybindings of the mod
public enum CriticalPathAnalyzerTrigger {
None,
OpenPathAnalyzer,
diff --git a/CriticalPathAnalyzer/CriticalPathAnalyzer/src/client/network/AnalyzePathResponseHandler.cs b/CriticalPathAnalyzer/CriticalPathAnalyzer/src/client/network/AnalyzePathResponseHandler.cs
index 9204ebf..bfb4068 100644
--- a/CriticalPathAnalyzer/CriticalPathAnalyzer/src/client/network/AnalyzePathResponseHandler.cs
+++ b/CriticalPathAnalyzer/CriticalPathAnalyzer/src/client/network/AnalyzePathResponseHandler.cs
@@ -4,6 +4,7 @@ using LogicWorld.SharedCode.Networking;
namespace CriticalPathAnalyzer.Client.Network {
public class AnalyzePathResponseHandler : PacketHandler {
public override void Handle(AnalyzePathResponse packet, HandlerContext context) {
+ // Pass the packet to the client mod
CriticalPathAnalyzerClient.OnAnalyzePathResponse(packet);
}
}
diff --git a/CriticalPathAnalyzer/CriticalPathAnalyzer/src/client/tool/CriticalPathAnalyzerTool.cs b/CriticalPathAnalyzer/CriticalPathAnalyzer/src/client/tool/CriticalPathAnalyzerTool.cs
index e09e463..96ab410 100644
--- a/CriticalPathAnalyzer/CriticalPathAnalyzer/src/client/tool/CriticalPathAnalyzerTool.cs
+++ b/CriticalPathAnalyzer/CriticalPathAnalyzer/src/client/tool/CriticalPathAnalyzerTool.cs
@@ -26,6 +26,9 @@ namespace CriticalPathAnalyzer.Client.Tool {
_logger = logger;
}
+ ///
+ /// Remove all highlights
+ ///
public static void Clear() {
PathHighlighter.RemoveHighlighting();
Outliner.RemoveOutline(_startPegAddress);
@@ -34,6 +37,10 @@ namespace CriticalPathAnalyzer.Client.Tool {
_endPegAddress = PegAddress.Empty;
}
+ ///
+ /// Cast a ray from the player's camera to find a peg or a wire the player is looking at.
+ ///
+ /// The peg's address or peg address of an input in case of a wire
private static PegAddress RayCastPeg() {
// Ray-cast into the world to find what the player is looking at
HitInfo hitInfo = PlayerCaster.CameraCast(Masks.Environment | Masks.Structure | Masks.Peg | Masks.Wire);
@@ -58,6 +65,9 @@ namespace CriticalPathAnalyzer.Client.Tool {
return PegAddress.Empty;
}
+ ///
+ /// Try to select the start of the path.
+ ///
public static void SelectPathStart() {
_logger.Info("Analyze Path Start");
PegAddress pegAddress = RayCastPeg();
@@ -71,6 +81,9 @@ namespace CriticalPathAnalyzer.Client.Tool {
}
}
+ ///
+ /// Try to select the end of the path.
+ ///
public static void SelectPathEnd() {
_logger.Info("Analyze Path End");
PegAddress pegAddress = RayCastPeg();
@@ -84,6 +97,9 @@ namespace CriticalPathAnalyzer.Client.Tool {
}
}
+ ///
+ /// Remove standard highlighting and only highlight clusters that form a loop.
+ ///
public static void DisplayLoop() {
if (_response == null) {
_logger.Error("Got no response - cannot display loop");
@@ -94,6 +110,9 @@ namespace CriticalPathAnalyzer.Client.Tool {
PathHighlighter.HighlightWires(_response.LoopingClusters);
}
+ ///
+ /// Send a request to the server to analyze the path between the selected start and end pegs.
+ ///
private static void CalculateCriticalPath() {
if (_startPegAddress.IsEmpty() || _endPegAddress.IsEmpty()) {
_logger.Error("Invalid pegs");
@@ -108,6 +127,11 @@ namespace CriticalPathAnalyzer.Client.Tool {
});
}
+ ///
+ /// Handle incoming response packet from the server.
+ /// Highlight pegs and wires involved in the circuit with their color based on their delay from the start.
+ ///
+ /// The server's response packet
public static void HandleResponse(AnalyzePathResponse response) {
if (_currentRequestGuid != response.RequestGuid) {
// Not matching Guid, old or wrong request, discard.
diff --git a/CriticalPathAnalyzer/CriticalPathAnalyzer/src/client/tool/PathHighlighter.cs b/CriticalPathAnalyzer/CriticalPathAnalyzer/src/client/tool/PathHighlighter.cs
index e2c8014..965ef4c 100644
--- a/CriticalPathAnalyzer/CriticalPathAnalyzer/src/client/tool/PathHighlighter.cs
+++ b/CriticalPathAnalyzer/CriticalPathAnalyzer/src/client/tool/PathHighlighter.cs
@@ -36,6 +36,9 @@ namespace CriticalPathAnalyzer.Client.Tool {
// }
}
+ ///
+ /// Highlight all pegs and wires of the given cluster.
+ ///
private static void HighlightCluster(ClusterDetails cluster) {
IWorldData world = Instances.MainWorld.Data;
diff --git a/CriticalPathAnalyzer/CriticalPathAnalyzer/src/server/CriticalPathAnalyzerServer.cs b/CriticalPathAnalyzer/CriticalPathAnalyzer/src/server/CriticalPathAnalyzerServer.cs
index efed7aa..e400c2c 100644
--- a/CriticalPathAnalyzer/CriticalPathAnalyzer/src/server/CriticalPathAnalyzerServer.cs
+++ b/CriticalPathAnalyzer/CriticalPathAnalyzer/src/server/CriticalPathAnalyzerServer.cs
@@ -34,13 +34,17 @@ namespace CriticalPathAnalyzer.Server {
throw new Exception("Could not get Service 'NetworkServer'.");
}
- // Inject verifier:
+ // Inject client verifier:
RawJoinVerifierInjector.addVerifier(this);
PacketHandlerManager.getCustomPacketHandler()
.addHandlerToEnd(new ClientJoinedPacketHandler(this));
RawPacketHandlerInjector.addPacketHandler(new CriticalPathAnalyzerRequestHandler(this));
}
+ ///
+ /// Gets called before a player (client) joins the server.
+ /// Used to check if the player has this mod installed
+ ///
public void Verify(VerificationContext ctx) {
bool hasMod = ctx.ApprovalPacket.ClientMods.Contains(Manifest.ID);
string playerName = ctx.PlayerID.Name;
@@ -48,6 +52,10 @@ namespace CriticalPathAnalyzer.Server {
LoggerInstance.Info($"Verifying player {playerName}: hasMod={hasMod}");
}
+ ///
+ /// 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.
+ ///
public void PlayerJoined(PlayerData playerData, HandlerContext context) {
_playerHasWireTracer.TryGetValue(playerData.Name, out bool hasWireTracer);
if (hasWireTracer) {
@@ -57,6 +65,10 @@ namespace CriticalPathAnalyzer.Server {
}
}
+ ///
+ /// Gets called from the AnalyzePathRequestHandler.
+ /// Use the tool to trace the path and send back a response.
+ ///
public void AnalyzePath(Connection sender, Guid requestGuid, PegAddress start, PegAddress end) {
LoggerInstance.Info("Got AnalyzePath request");
if (!ServerPathTracer.TracePath(requestGuid, start, end, out AnalyzePathResponse response)) {
diff --git a/CriticalPathAnalyzer/CriticalPathAnalyzer/src/server/tool/ServerPathTracer.cs b/CriticalPathAnalyzer/CriticalPathAnalyzer/src/server/tool/ServerPathTracer.cs
index df7f69c..cd949e9 100644
--- a/CriticalPathAnalyzer/CriticalPathAnalyzer/src/server/tool/ServerPathTracer.cs
+++ b/CriticalPathAnalyzer/CriticalPathAnalyzer/src/server/tool/ServerPathTracer.cs
@@ -192,6 +192,11 @@ namespace CriticalPathAnalyzer.Server.Tool {
}
+ ///
+ /// Check if the peg exists in the world
+ ///
+ /// Address of the peg
+ /// True if it exists, false if it doesn't
private static bool PegExists(PegAddress address) {
IComponentInWorld component = World.Lookup(address.ComponentAddress);
if (component == null) {
@@ -224,6 +229,12 @@ namespace CriticalPathAnalyzer.Server.Tool {
return linker != null;
}
+ ///
+ /// An output peg can be connected to multiple clusters. Collect all of them.
+ ///
+ /// Address of the peg
+ /// Found clusters get added into this hash set
+ /// A wire of the peg is not in the world
private static void CollectMainClusters(PegAddress pegAddress, HashSet primaryClusters) {
if (pegAddress.IsInputAddress(out InputAddress inputAddress)) {
primaryClusters.Add(GetClusterAt(inputAddress));
diff --git a/CriticalPathAnalyzer/CriticalPathAnalyzer/src/shared/packets/s2c/AnalyzePathResponse.cs b/CriticalPathAnalyzer/CriticalPathAnalyzer/src/shared/packets/s2c/AnalyzePathResponse.cs
index 7f771b7..473f20d 100644
--- a/CriticalPathAnalyzer/CriticalPathAnalyzer/src/shared/packets/s2c/AnalyzePathResponse.cs
+++ b/CriticalPathAnalyzer/CriticalPathAnalyzer/src/shared/packets/s2c/AnalyzePathResponse.cs
@@ -11,6 +11,7 @@ namespace CriticalPathAnalyzer.Shared.Packets.S2C {
[Key(1)] public List Clusters;
[Key(2)] public int CriticalPathLength;
+
[Key(3)] public List LoopingClusters;
// [Key(4)] public List PerimeterComponents;
// [Key(5)] public List NextClusters;
@@ -18,9 +19,21 @@ namespace CriticalPathAnalyzer.Shared.Packets.S2C {
[MessagePackObject]
public sealed class ClusterDetails {
+ ///
+ /// List of all pegs inside the cluster
+ ///
[Key(0)] public List Pegs;
- [Key(1)] public List ConnectingComponents; // Sockets
- [Key(2)] public List LinkingComponents; // Relays, fast buffers
+
+ ///
+ /// Sockets
+ ///
+ [Key(1)] public List ConnectingComponents;
+
+ ///
+ /// Relays and fast buffers
+ ///
+ [Key(2)] public List LinkingComponents;
+
[Key(3)] public int Color;
}
}
\ No newline at end of file