Skip to content

Commit

Permalink
work on clean up
Browse files Browse the repository at this point in the history
  • Loading branch information
HandyS11 committed May 27, 2024
1 parent d99de37 commit ee97d9f
Show file tree
Hide file tree
Showing 8 changed files with 436 additions and 477 deletions.
5 changes: 1 addition & 4 deletions RustPlusApi/Examples/Fcm/FcmListener/Program.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using RustPlusApi.Fcm;
using RustPlusApi.Fcm.Data;
using Newtonsoft.Json;

var credentials = new Credentials
{
Expand Down Expand Up @@ -28,9 +27,7 @@

listener.NotificationReceived += (_, message) =>
{
var rustPlusMessage = JsonConvert.DeserializeObject<RustPlusMessage>(message);
var formattedMessage = JsonConvert.SerializeObject(rustPlusMessage, Formatting.Indented);
Console.WriteLine(formattedMessage);
Console.WriteLine(message);
};

await listener.ConnectAsync();
18 changes: 1 addition & 17 deletions RustPlusApi/RustPlusApi.Fcm/Data/Credentials.cs
Original file line number Diff line number Diff line change
@@ -1,46 +1,30 @@
using Newtonsoft.Json;

namespace RustPlusApi.Fcm.Data
namespace RustPlusApi.Fcm.Data
{
public sealed class Credentials
{
[JsonProperty(PropertyName = "keys")]
public Keys Keys { get; set; } = null!;
[JsonProperty(PropertyName = "fcm")]
public FcmCredentials Fcm { get; set; } = null!;
[JsonProperty(PropertyName = "gcm")]
public GcmCredentials Gcm { get; set; } = null!;
}

public sealed class Keys
{
[JsonProperty(PropertyName = "privateKey")]
public string PrivateKey { get; set; } = null!;

[JsonProperty(PropertyName = "publicKey")]
public string PublicKey { get; set; } = null!;

[JsonProperty(PropertyName = "authSecret")]
public string AuthSecret { get; set; } = null!;
}

public sealed class FcmCredentials
{
[JsonProperty(PropertyName = "token")]
public string Token { get; set; } = null!;
[JsonProperty(PropertyName = "pushSet")]
public string PushSet { get; set; } = null!;
}

public sealed class GcmCredentials
{
[JsonProperty(PropertyName = "token")]
public string Token { get; set; } = null!;
[JsonProperty(PropertyName = "androidId")]
public ulong AndroidId { get; set; }
[JsonProperty(PropertyName = "securityToken")]
public ulong SecurityToken { get; set; }
[JsonProperty(PropertyName = "appId")]
public string AppId { get; set; } = null!;
}
}
76 changes: 36 additions & 40 deletions RustPlusApi/RustPlusApi.Fcm/FcmListener.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

using McsProto;

using Newtonsoft.Json;

using ProtoBuf;

using RustPlusApi.Fcm.Data;
Expand All @@ -13,7 +15,6 @@
using static RustPlusApi.Fcm.Data.Constants;
using static System.GC;


namespace RustPlusApi.Fcm
{
public class FcmListener(Credentials credentials, ICollection<string> persistentIds) : IDisposable
Expand Down Expand Up @@ -59,10 +60,10 @@ public async Task ConnectAsync()
UseRmq2 = true,
Settings = { new Setting() { Name = "new_vc", Value = "1" } },
ClientEvents = { new ClientEvent() },
ReceivedPersistentIds = { },
};

if (persistentIds != null)
loginRequest.ReceivedPersistentIds.AddRange(persistentIds);
if (persistentIds != null) loginRequest.ReceivedPersistentIds.AddRange(persistentIds);

SendPacket(loginRequest);

Expand All @@ -72,7 +73,7 @@ public async Task ConnectAsync()
Connected?.Invoke(this, EventArgs.Empty);

StatusCheck();
await ReceiveMessagesAsync();
ReceiveMessages();
}
catch (Exception ex)
{
Expand All @@ -91,9 +92,9 @@ public void Dispose()
SuppressFinalize(this);
}

private async Task ReceiveMessagesAsync()
private void ReceiveMessages()
{
var parser = new Parser(this);
var parser = new Parser();
parser.MessageReceived += (_, e) => OnMessage(e);

// First receival (LoginResponse)
Expand All @@ -105,10 +106,10 @@ private async Task ReceiveMessagesAsync()
throw new InvalidOperationException($"Protocol version {version} unsupported");

int size = ReadVarint32();
Debug.WriteLine($"Got message size: {size}bytes");
Debug.WriteLine($"Got message size: {size} bytes");

byte[] payload = Read(size);
Debug.WriteLine($"Successfully read {payload.Length}bytes");
Debug.WriteLine($"Successfully read: {payload.Length} bytes");

Type type = Parser.BuildProtobufFromTag(((McsProtoTag)tag));
Debug.WriteLine($"RECEIVED PROTO OF TYPE {type.Name}");
Expand All @@ -123,7 +124,7 @@ private async Task ReceiveMessagesAsync()
Debug.WriteLine("Starting receiver loop.");
while (true)
{
tag = _sslStream.ReadByte();
tag = _sslStream!.ReadByte();
size = ReadVarint32();
payload = Read(size);
type = Parser.BuildProtobufFromTag((McsProtoTag)tag);
Expand All @@ -139,7 +140,7 @@ internal byte[] Read(int size)
int bytesRead = 0;
while (bytesRead < size)
{
bytesRead += _sslStream.Read(buffer, bytesRead, size - bytesRead);
bytesRead += _sslStream!.Read(buffer, bytesRead, size - bytesRead);
}
return buffer;
}
Expand All @@ -150,41 +151,37 @@ internal int ReadVarint32()
int shift = 0;
while (true)
{
byte b = (byte)_sslStream.ReadByte();
byte b = (byte)_sslStream!.ReadByte();
result |= (b & 0x7F) << shift;
if ((b & 0x80) == 0)
break;
if ((b & 0x80) == 0) break;
shift += 7;
}
return result;
}

internal byte[] EncodeVarint32(int value)
internal static byte[] EncodeVarint32(int value)
{
List<byte> result = new List<byte>();
List<byte> result = [];
while (value != 0)
{
byte b = (byte)(value & 0x7F);
value >>= 7;
if (value != 0)
b |= 0x80;
if (value != 0) b |= 0x80;
result.Add(b);
}
return result.ToArray();
return [.. result];
}

internal void SendPacket(object packet)
private void SendPacket(object packet)
{
var tagEnum = Parser.GetTagFromProtobufType(packet.GetType());
var header = new byte[] { KMcsVersion, (byte)(int)tagEnum };

using (var ms = new MemoryStream())
{
Serializer.Serialize(ms, packet);
using var ms = new MemoryStream();
Serializer.Serialize(ms, packet);

byte[] payload = ms.ToArray();
_sslStream.Write([.. header, .. EncodeVarint32(payload.Length), .. payload]);
}
byte[] payload = ms.ToArray();
_sslStream!.Write([.. header, .. EncodeVarint32(payload.Length), .. payload]);
}

private void HandlePing(HeartbeatPing? ping)
Expand All @@ -202,7 +199,7 @@ private void HandlePing(HeartbeatPing? ping)
SendPacket(pingResponse);
}

internal void Reset(bool noWait = false)
private void Reset(bool noWait = false)
{
if (!noWait)
{
Expand All @@ -218,28 +215,21 @@ internal void Reset(bool noWait = false)
Thread.Sleep(waitTime);
}
}

_lastReset = DateTime.Now;

Debug.WriteLine("Resetting listener.");
Dispose();

_tcpClient.Close();
_sslStream.Close();
Disconnected?.Invoke(this, EventArgs.Empty);
ConnectAsync().GetAwaiter().GetResult();
}

public void Reset()
{
Reset(true);
}

private void StatusCheck(object? state = null)
{
TimeSpan timeSinceLastMessage = DateTime.UtcNow - _timeLastMessageReceived;
if (timeSinceLastMessage > TimeSpan.FromSeconds(MaxSilentIntervalSecs))
{
Debug.WriteLine($"No communications received in {timeSinceLastMessage.TotalSeconds}s. Resetting connection.");
Reset();
Reset(true);
}
else
{
Expand All @@ -265,7 +255,7 @@ private void OnMessage(MessageEventArgs e)
HandlePing(e.Object as HeartbeatPing);
break;
case McsProtoTag.KCloseTag:
Reset();
Reset(true);
break;
case McsProtoTag.KIqStanzaTag:
break; // I'm not sure about what this message does, and it arrives partially empty, so I will just leave it like this for now
Expand All @@ -290,12 +280,18 @@ private void OnDataMessage(DataMessageStanza? dataMessage)
ex.Message.Contains("salt is missing"))
{
Debug.WriteLine($"Message dropped as it could not be decrypted: {ex.Message}");
persistentIds?.Add(dataMessage!.PersistentId);
return;
}
}
persistentIds?.Add(dataMessage!.PersistentId);
NotificationReceived?.Invoke(this, message);
finally
{
persistentIds?.Add(dataMessage!.PersistentId);
}

var rustPlusMessage = JsonConvert.DeserializeObject<RustPlusMessage>(message);
var formattedMessage = JsonConvert.SerializeObject(rustPlusMessage, Formatting.Indented);

NotificationReceived?.Invoke(this, formattedMessage);
}
}
}
2 changes: 1 addition & 1 deletion RustPlusApi/RustPlusApi.Fcm/RustPlusApi.Fcm.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="BouncyCastle.Cryptography" Version="2.3.1" />
<PackageReference Include="BouncyCastle.Cryptography" Version="2.4.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="protobuf-net" Version="3.2.30" />
</ItemGroup>
Expand Down
28 changes: 14 additions & 14 deletions RustPlusApi/RustPlusApi.Fcm/Tools/GcmTools.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
using System.Diagnostics;
using System.Net.Http.Headers;

using AndroidCheckinProto;

using CheckinProto;
using McsProto;

using ProtoBuf;

using RustPlusApi.Fcm.Data;
Expand Down Expand Up @@ -34,25 +36,23 @@ public static async Task<AndroidCheckinResponse> CheckInAsync(ulong? androidId =

var request = new HttpRequestMessage(HttpMethod.Post, CheckInUrl);

using (var ms = new MemoryStream())
{
Serializer.Serialize(ms, requestBody);
using var ms = new MemoryStream();
Serializer.Serialize(ms, requestBody);

var content = new ByteArrayContent(ms.ToArray());
content.Headers.ContentType = new MediaTypeHeaderValue("application/x-protobuf");
var content = new ByteArrayContent(ms.ToArray());
content.Headers.ContentType = new MediaTypeHeaderValue("application/x-protobuf");

request.Content = content;
request.Content = content;

var response = await HttpClient.SendAsync(request);
response.EnsureSuccessStatusCode();
var response = await HttpClient.SendAsync(request);
response.EnsureSuccessStatusCode();

var data = await response.Content.ReadAsByteArrayAsync();
var data = await response.Content.ReadAsByteArrayAsync();

using var stream = new MemoryStream(data);
var message = Serializer.Deserialize<AndroidCheckinResponse>(stream);
using var stream = new MemoryStream(data);
var message = Serializer.Deserialize<AndroidCheckinResponse>(stream);

return message;
}
return message;
}
catch (Exception ex)
{
Expand Down
Loading

0 comments on commit ee97d9f

Please sign in to comment.