diff --git a/src/gg.regression.unity.bots/Runtime/Resources/RegressionGames.exe b/src/gg.regression.unity.bots/Runtime/Resources/RegressionGames.exe
index 72f8e6c5..cde23b71 100644
Binary files a/src/gg.regression.unity.bots/Runtime/Resources/RegressionGames.exe and b/src/gg.regression.unity.bots/Runtime/Resources/RegressionGames.exe differ
diff --git a/src/gg.regression.unity.bots/Runtime/Scripts/ClientDashboard/RGTcpManager.cs b/src/gg.regression.unity.bots/Runtime/Scripts/ClientDashboard/RGTcpManager.cs
index 5d3b9ff9..ece03aaf 100644
--- a/src/gg.regression.unity.bots/Runtime/Scripts/ClientDashboard/RGTcpManager.cs
+++ b/src/gg.regression.unity.bots/Runtime/Scripts/ClientDashboard/RGTcpManager.cs
@@ -17,7 +17,6 @@
namespace RegressionGames.ClientDashboard
{
-
///
/// Starts and stops RGTcpServer, handles and sends messages to and from connected clients
///
@@ -26,10 +25,16 @@ public class RGTcpManager : MonoBehaviour
{
// the last active sequence that was sent to the client
private static BotSegmentsPlaybackController m_botSegmentsPlaybackController;
- private static BotSequence m_startPlayingSequence = null;
- private static ActiveSequence m_activeSequence = null;
private static ReplayToolbarManager m_replayToolbarManager;
+
private static List m_availableBotSequences = new ();
+ private static List m_availableBotSegments = new();
+
+ private static ActiveSequence m_activeSequence = null;
+ private static BotSequence m_startPlayingSequence = null;
+ private static BotSegmentList m_startPlayingSegment = null;
+ private static bool m_shouldStopReplay = false;
+
public void Start()
{
@@ -52,6 +57,7 @@ public void Start()
RGTcpServer.ProcessClientMessage += ProcessClientMessage;
RGTcpServer.Start();
StartCoroutine(RGSequenceManager.ResolveSequenceFiles(ProcessAndSendSequences));
+ ProcessAndSendSegments();
}
///
@@ -73,17 +79,43 @@ private void Update()
SendActiveSequence();
}
- // check if we need to start playing a sequence
+ // check if we need to start playing a sequence or segment
if (m_startPlayingSequence != null)
{
- var botManager = RGBotManager.GetInstance();
- if (botManager != null)
+ if (activeSequence == null)
+ {
+ var botManager = RGBotManager.GetInstance();
+ if (botManager != null)
+ {
+ botManager.OnBeginPlaying();
+ }
+ m_replayToolbarManager.selectedReplayFilePath = null;
+ m_startPlayingSequence.Play();
+ }
+ m_startPlayingSequence = null;
+ m_startPlayingSegment = null;
+ m_shouldStopReplay = false;
+ }
+ else if (m_startPlayingSegment != null)
+ {
+ if (activeSequence == null)
{
- botManager.OnBeginPlaying();
+ var botManager = RGBotManager.GetInstance();
+ if (botManager != null)
+ {
+ botManager.OnBeginPlaying();
+ }
+ m_botSegmentsPlaybackController.SetDataContainer(new BotSegmentsPlaybackContainer(m_startPlayingSegment.segments));
+ m_botSegmentsPlaybackController.Play();
}
- m_replayToolbarManager.selectedReplayFilePath = null;
- m_startPlayingSequence.Play();
m_startPlayingSequence = null;
+ m_startPlayingSegment = null;
+ m_shouldStopReplay = false;
+ }
+ else if (m_shouldStopReplay)
+ {
+ m_replayToolbarManager.StopReplay();
+ m_shouldStopReplay = false;
}
}
@@ -120,6 +152,7 @@ private static void DidReloadScripts()
var it = RGSequenceManager.ResolveSequenceFiles(ProcessAndSendSequences);
while(it.MoveNext()){}
+ ProcessAndSendSegments();
}
///
@@ -170,6 +203,7 @@ private static void OnClientHandshake(TcpClient client)
{
SendActiveSequence();
SendAvailableSequences();
+ SendAvailableSegments();
}
///
@@ -185,11 +219,23 @@ private static void ProcessClientMessage(TcpClient client, TcpMessage message)
}
case TcpMessageType.PlaySequence:
{
- var playSequenceData = (PlaySequenceTcpMessageData) message.payload;
+ var playSequenceData = (PlayResourceTcpMessageData) message.payload;
var botSequence = BotSequence.LoadSequenceJsonFromPath(playSequenceData.resourcePath);
m_startPlayingSequence = botSequence.Item3;
break;
}
+ case TcpMessageType.PlaySegment:
+ {
+ var playSegmentData = (PlayResourceTcpMessageData) message.payload;
+ var segmentList = BotSequence.CreateBotSegmentListForPath(playSegmentData.resourcePath, out var sessId);
+ m_startPlayingSegment = segmentList;
+ break;
+ }
+ case TcpMessageType.StopReplay:
+ {
+ m_shouldStopReplay = true;
+ break;
+ }
}
}
@@ -207,6 +253,12 @@ private static void ProcessAndSendSequences(IDictionary seg.Item2).ToList();
+ SendAvailableSegments();
+ }
+
///
/// Returns the active bot sequence, if there is one
///
@@ -261,6 +313,19 @@ private static void SendAvailableSequences([CanBeNull] TcpClient client = null)
RGTcpServer.QueueMessage(message, client);
}
+ private static void SendAvailableSegments([CanBeNull] TcpClient client = null)
+ {
+ var message = new TcpMessage
+ {
+ type = TcpMessageType.AvailableSegments,
+ payload = new AvailableSegmentsTcpMessageData
+ {
+ availableSegments = m_availableBotSegments
+ }
+ };
+ RGTcpServer.QueueMessage(message, client);
+ }
+
private static void SendActiveSequence([CanBeNull] TcpClient client = null)
{
var message = new TcpMessage
diff --git a/src/gg.regression.unity.bots/Runtime/Scripts/ClientDashboard/TcpMessage.cs b/src/gg.regression.unity.bots/Runtime/Scripts/ClientDashboard/TcpMessage.cs
index 29bd18cd..8bc7cfc7 100644
--- a/src/gg.regression.unity.bots/Runtime/Scripts/ClientDashboard/TcpMessage.cs
+++ b/src/gg.regression.unity.bots/Runtime/Scripts/ClientDashboard/TcpMessage.cs
@@ -5,6 +5,7 @@
using RegressionGames.RemoteOrchestration.Models;
using RegressionGames.RemoteOrchestration.Types;
using RegressionGames.StateRecorder;
+using RegressionGames.StateRecorder.BotSegments.Models;
using RegressionGames.StateRecorder.JsonConverters;
namespace RegressionGames.ClientDashboard
@@ -17,8 +18,12 @@ public enum TcpMessageType
Ping,
- // client requests to play a sequence with the given resourcePath
+ // client requests to play a resource with the given resourcePath
PlaySequence,
+ PlaySegment,
+
+ // stops any currently-running sequence/segments
+ StopReplay,
// =====================
// server -> client
@@ -26,8 +31,9 @@ public enum TcpMessageType
Pong,
- // info about the available sequences for this game instance
+ // info about the available file-based resources for this game instance
AvailableSequences,
+ AvailableSegments,
// info about the currently-running sequence (or segment)
ActiveSequence,
@@ -124,7 +130,53 @@ public override string ToString()
}
[Serializable]
- public class PlaySequenceTcpMessageData : ITcpMessageData
+ public class AvailableSegmentsTcpMessageData : ITcpMessageData
+ {
+ public List availableSegments;
+
+ public void WriteToStringBuilder(StringBuilder stringBuilder)
+ {
+ stringBuilder.Append("{\"availableSegments\":[");
+ var availableSegmentsCount = availableSegments.Count;
+ for (var i = 0; i < availableSegmentsCount; i++)
+ {
+ // a lot of the fields on BotSequenceEntry are not written to string builder
+ // so pick what we need for the dashboard here...
+ var currentSegment = availableSegments[i];
+
+ stringBuilder.Append("{\"apiVersion\":");
+ IntJsonConverter.WriteToStringBuilder(stringBuilder, currentSegment.apiVersion);
+
+ // not normally serialized
+ stringBuilder.Append(",\"resourcePath\":");
+ StringJsonConverter.WriteToStringBuilder(stringBuilder, currentSegment.resourcePath);
+ stringBuilder.Append(",\"type\":");
+ StringJsonConverter.WriteToStringBuilder(stringBuilder, currentSegment.type.ToString());
+ stringBuilder.Append(",\"name\":");
+ StringJsonConverter.WriteToStringBuilder(stringBuilder, currentSegment.name);
+ stringBuilder.Append(",\"description\":");
+ StringJsonConverter.WriteToStringBuilder(stringBuilder, currentSegment.description);
+
+ stringBuilder.Append("}");
+
+ if (i + 1 < availableSegmentsCount)
+ {
+ stringBuilder.Append(",");
+ }
+ }
+ stringBuilder.Append("]}");
+ }
+
+ public override string ToString()
+ {
+ StringBuilder sb = new StringBuilder(1000);
+ WriteToStringBuilder(sb);
+ return sb.ToString();
+ }
+ }
+
+ [Serializable]
+ public class PlayResourceTcpMessageData : ITcpMessageData
{
public string resourcePath;
@@ -142,4 +194,5 @@ public override string ToString()
return sb.ToString();
}
}
+
}
\ No newline at end of file
diff --git a/src/gg.regression.unity.bots/Runtime/Scripts/ClientDashboard/TcpMessageDataJsonConverter.cs b/src/gg.regression.unity.bots/Runtime/Scripts/ClientDashboard/TcpMessageDataJsonConverter.cs
index b1f32f7a..9d737ae1 100644
--- a/src/gg.regression.unity.bots/Runtime/Scripts/ClientDashboard/TcpMessageDataJsonConverter.cs
+++ b/src/gg.regression.unity.bots/Runtime/Scripts/ClientDashboard/TcpMessageDataJsonConverter.cs
@@ -22,6 +22,7 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist
{
case TcpMessageType.Ping:
case TcpMessageType.Pong:
+ case TcpMessageType.StopReplay:
case TcpMessageType.CloseConnection:
// these messages have no payload
break;
@@ -31,8 +32,12 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist
case TcpMessageType.AvailableSequences:
payload = jObject["payload"].ToObject(serializer);
break;
+ case TcpMessageType.AvailableSegments:
+ payload = jObject["payload"].ToObject(serializer);
+ break;
case TcpMessageType.PlaySequence:
- payload = jObject["payload"].ToObject(serializer);
+ case TcpMessageType.PlaySegment:
+ payload = jObject["payload"].ToObject(serializer);
break;
default:
throw new JsonSerializationException($"Unsupported TcpMessage type: '{message.type}'");