Skip to content

Commit

Permalink
Support Satisfactory Protocol
Browse files Browse the repository at this point in the history
  • Loading branch information
BattlefieldDuck committed Jan 17, 2024
1 parent c57712f commit 0645990
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 0 deletions.
61 changes: 61 additions & 0 deletions OpenGSQ/Protocols/Satisfactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using System;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using OpenGSQ.Responses.Satisfactory;

namespace OpenGSQ.Protocols
{
/// <summary>
/// Satisfactory Protocol
/// </summary>
public class Satisfactory : ProtocolBase
{
/// <inheritdoc/>
public override string FullName => "Satisfactory Protocol";

/// <summary>
/// Initializes a new instance of the Satisfactory class.
/// </summary>
/// <param name="host">The host.</param>
/// <param name="port">The port. Default is 15777.</param>
/// <param name="timeout">The timeout. Default is 5000.</param>
public Satisfactory(string host, int port = 15777, int timeout = 5000) : base(host, port, timeout)
{
}

/// <summary>
/// Gets the status asynchronously.
/// </summary>
/// <returns>A task that represents the asynchronous operation. The task result contains the StatusResponse.</returns>
public async Task<StatusResponse> GetStatus()
{
// https://github.com/dopeghoti/SF-Tools/blob/main/Protocol.md
byte[] request = new byte[] { 0, 0 }.Concat(Encoding.ASCII.GetBytes("opengsq")).ToArray();

using var udpClient = new UdpClient();
byte[] response = await udpClient.CommunicateAsync(this, request);
using var br = new BinaryReader(new MemoryStream(response), Encoding.UTF8);
byte header = br.ReadByte();

if (header != 1)
{
throw new Exception($"Packet header mismatch. Received: {header}. Expected: 1.");
}

br.ReadByte(); // Protocol version
br.ReadBytes(8); // Request data

var result = new StatusResponse
{
State = br.ReadByte(),
Version = br.ReadInt32(),
BeaconPort = br.ReadInt16()
};

return result;
}
}
}
24 changes: 24 additions & 0 deletions OpenGSQ/Responses/Satisfactory/StatusResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
namespace OpenGSQ.Responses.Satisfactory
{
/// <summary>
/// Represents the status response.
/// </summary>
public class StatusResponse
{
/// <summary>
/// Gets or sets the state.
/// </summary>
public byte State { get; set; }

/// <summary>
/// Gets or sets the version.
/// </summary>
public int Version { get; set; }

/// <summary>
/// Gets or sets the beacon port.
/// </summary>
public short BeaconPort { get; set; }
}

}
23 changes: 23 additions & 0 deletions OpenGSQTests/Protocols/SatisfactoryTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenGSQTests;

namespace OpenGSQ.Protocols.Tests
{
[TestClass()]
public class SatisfactoryTests : TestBase
{
public Satisfactory satisfactory = new("79.136.0.124", 15777);

public SatisfactoryTests() : base(nameof(SatisfactoryTests))
{
_EnableSave = !false;
}

[TestMethod()]
public async Task GetStatusTest()
{
SaveResult(nameof(GetStatusTest), await satisfactory.GetStatus());
}
}
}
5 changes: 5 additions & 0 deletions OpenGSQTests/Results/SatisfactoryTests/GetStatusTest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"State": 3,
"Version": 273254,
"BeaconPort": 15000
}

0 comments on commit 0645990

Please sign in to comment.