diff --git a/README.md b/README.md index 9fd5725..0929fc5 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ ## 📊 Features +### RustPlusApi + This is a list of the features that the Rust+ API provides: - `GetEntityInfo` Get current state of a Smart Device @@ -16,6 +18,10 @@ This is a list of the features that the Rust+ API provides: Feel free to **explore** the `./RustPlusApi/Examples/` folder to see how to **use** the API. +### RustPlusApi.Fcm + + + ## 🖊️ Versions ![skills](https://skillicons.dev/icons?i=cs,dotnet) @@ -24,14 +30,20 @@ Feel free to **explore** the `./RustPlusApi/Examples/` folder to see how to **us ## 📍 NuGet -Simply use this nuget by running the following command: +Simply use this library in your project by running the following commands: ```dotnet dotnet add package RustPlusApi ``` +```dotnet +dotnet add package RustPlusApi.Fcm +``` + ## ⚙️ Usage +### RustPlusApi + First, instantiate the `RustPlus` class with the necessary parameters: ```csharp @@ -43,9 +55,11 @@ Parameters: - `server`: The IP address of the Rust+ server. - `port`: The port dedicated for the Rust+ companion app (not the one used to connect in-game). - `playerId`: Your Steam ID. -- `playerToken`: Your player token acquired with FCM. +- `playerToken`\*: Your player token acquired with FCM. - `useFacepunchProxy`: Specifies whether to use the Facepunch proxy. Default is false. +\* To aquired the player token, you can use the `FcmListener` and received at least one notification. Go to the next section to see how to use it. + Then, connect to the Rust+ server: ```csharp @@ -68,8 +82,59 @@ Remember to dispose the `RustPlus` instance when you're done: rustPlusApi.Dispose(); ``` +--- + +### RustPlusApi.Fcm + +First, instantiate the `FcmListener` class with the necessary parameters: + +```csharp +var fcmListener = new FcmListener(credentials, persistentIds); +``` + +Parameters: + +- `credentials`: The `Credentials`\* object containing the FCM & GCM credentials + the keys to decrypt the notification. +- `persistentIds`: A list of notification IDs that should be ignored. Default is null. + +\* Go to the [Credentials](#credentials) section to know how to get it. + +Then, connect to the FCM socket: + +```csharp +await fcmListener.ConnectAsync(); +``` + +You can subscribe to events to handle connection, disconnection, errors, and received messages: + +```csharp +fcmListener.Connecting += (sender, e) => { /* handle connecting event */ }; +fcmListener.Connected += (sender, e) => { /* handle connected event */ }; +fcmListener.Disconnected += (sender, e) => { /* handle disconnected event */ }; +fcmListener.ErrorOccurred += (sender, e) => { /* handle error event */ }; +fcmListener.MessageReceived += (sender, e) => { /* handle received message event */ }; +``` + +Remember to dispose the `FcmListener` instance when you're done: + +```csharp +fcmListener.Dispose(); +``` + +### Credentials + +Currenlty, there is not simple way to get the FCM & GCM credentials using **.NET**. +I've planned to implement a solution but it's not ready yet. + +To use this library, you need to get the FCM & GCM credentials manually. +To do so I recommand you to use [this project](https://github.com/liamcottle/rustplus.js) to get the credentials. + +I'm sorry for the inconvenience but since the API is not fully complete it's the easiest way. + ## 🖼️ Credits -This project is grandly inspired by [liamcottle/rustplus.js](https://github.com/liamcottle/rustplus.js). +*This project is grandly inspired by [liamcottle/rustplus.js](https://github.com/liamcottle/rustplus.js).* + +Special thanks to [**Versette**](https://github.com/Versette) for his work on the `RustPlusApi.Fcm` socket. * Author: [**HandyS11**](https://github.com/HandyS11) \ No newline at end of file diff --git a/RustPlusApi/Examples/Fcm/FcmListener/Program.cs b/RustPlusApi/Examples/Fcm/FcmListener/Program.cs index 3ff84b8..65b2880 100644 --- a/RustPlusApi/Examples/Fcm/FcmListener/Program.cs +++ b/RustPlusApi/Examples/Fcm/FcmListener/Program.cs @@ -1,33 +1,40 @@ -using RustPlusApi.Fcm; +using Newtonsoft.Json; + +using RustPlusApi.Fcm; using RustPlusApi.Fcm.Data; var credentials = new Credentials { Keys = new Keys { - PrivateKey = "", - PublicKey = "", - AuthSecret = "", + PrivateKey = "PNo-juMIoy8nh45ap7CcOjmvCcXG71zxo1Kf6sG75yI", + PublicKey = "BMLRwfGJ3poc2ih6eIQpf-7xwkP9z98K8vh-bWzxypDERTUIyAqpulccHR6WBVP8jgoecNtYePTYvSc-sHGhWcY", + AuthSecret = "3_stBv0R105hCQJgJ_Oqag", }, Fcm = new FcmCredentials { - Token = "", - PushSet = "", + Token = "de0gThSZW5A:APA91bEpz3S-tIVNV4uoKKNc_UCA_8tcg5lxEWiXkx-zFb0-H6FG5ltQvkGYzfxcfm3GxNihFgfRvH7Ps0_IdvRpOvjVREsm8uJwhkt8ztaoOZ886osG-bvGGVfV2jt1rPDG1_22NoMm", + PushSet = "dEhc-sLR9LY", }, Gcm = new GcmCredentials { - Token = "", - AndroidId = 0, - SecurityToken = 0, - AppId = "", + Token = "ctMfS0V2BB0:APA91bG5LKmV_pe27v7Drm4OBYMkZS8eItKHUX-wG5eUw1WmKFTSkwYr4hw43AQmP7oBwHzeKbMRDEmaml0lh2CBvh0s3pXxrDSng6au3t-iE1FkEhpBOwaDh74Hk2z6Y8GcFTcaPsA2", + AndroidId = 5198350057269518718, + SecurityToken = 726893779159876265, + AppId = "wp:receiver.push.com#46616054-1728-4be7-9dc6-740f3e76d9f4", } }; -var listener = new FcmListener(credentials, []); +var listener = new FcmListener(credentials); listener.NotificationReceived += (_, message) => { - Console.WriteLine(message); + Console.WriteLine($"{DateTime.Now}:\n{message}"); +}; + +listener.ErrorOccurred += (_, error) => +{ + Console.WriteLine($"[ERROR]: {error}"); }; await listener.ConnectAsync(); \ No newline at end of file diff --git a/RustPlusApi/Examples/Fcm/FcmRegister/Program.cs b/RustPlusApi/Examples/Fcm/FcmRegister/Program.cs index f9a93aa..8266013 100644 --- a/RustPlusApi/Examples/Fcm/FcmRegister/Program.cs +++ b/RustPlusApi/Examples/Fcm/FcmRegister/Program.cs @@ -1,7 +1,10 @@ using RustPlusApi.Fcm; using Newtonsoft.Json; -var senderId = "976529667804"; +// NOT WORKING, NEEDS TO BE FIXED +return; + +/* var senderId = "976529667804"; var credentials = await FcmRegister.RegisterAsync(senderId); -Console.WriteLine(JsonConvert.SerializeObject(credentials, Formatting.Indented)); \ No newline at end of file +Console.WriteLine(JsonConvert.SerializeObject(credentials, Formatting.Indented));*/ \ No newline at end of file diff --git a/RustPlusApi/RustPlusApi.Fcm/Data/RustPlusMessage.cs b/RustPlusApi/RustPlusApi.Fcm/Data/FcmMessage.cs similarity index 97% rename from RustPlusApi/RustPlusApi.Fcm/Data/RustPlusMessage.cs rename to RustPlusApi/RustPlusApi.Fcm/Data/FcmMessage.cs index fe3ca86..77d0447 100644 --- a/RustPlusApi/RustPlusApi.Fcm/Data/RustPlusMessage.cs +++ b/RustPlusApi/RustPlusApi.Fcm/Data/FcmMessage.cs @@ -4,7 +4,7 @@ namespace RustPlusApi.Fcm.Data { - public class RustPlusMessage + public class FcmMessage { public Data Data { get; set; } = null!; public string From { get; set; } = null!; diff --git a/RustPlusApi/RustPlusApi.Fcm/FcmListener.cs b/RustPlusApi/RustPlusApi.Fcm/FcmListener.cs index 334917a..07ea1f0 100644 --- a/RustPlusApi/RustPlusApi.Fcm/FcmListener.cs +++ b/RustPlusApi/RustPlusApi.Fcm/FcmListener.cs @@ -17,7 +17,7 @@ namespace RustPlusApi.Fcm { - public class FcmListener(Credentials credentials, ICollection persistentIds) : IDisposable + public class FcmListener(Credentials credentials, ICollection? persistentIds = null) : IDisposable { private const string Host = "mtalk.google.com"; private const int Port = 5228; @@ -264,9 +264,12 @@ private void OnMessage(MessageEventArgs e) } } - private void OnDataMessage(DataMessageStanza? dataMessage) + protected void OnDataMessage(DataMessageStanza? dataMessage) { - if (dataMessage?.PersistentId != null && persistentIds != null && persistentIds!.Contains(dataMessage?.PersistentId!)) return; + if (dataMessage?.PersistentId != null + && persistentIds != null + && persistentIds!.Contains(dataMessage?.PersistentId!)) + return; var message = string.Empty; try @@ -288,10 +291,10 @@ private void OnDataMessage(DataMessageStanza? dataMessage) persistentIds?.Add(dataMessage!.PersistentId); } - var rustPlusMessage = JsonConvert.DeserializeObject(message); - var formattedMessage = JsonConvert.SerializeObject(rustPlusMessage, Formatting.Indented); + var fcmMessage = JsonConvert.DeserializeObject(message); + var betterMessage = JsonConvert.SerializeObject(fcmMessage, Formatting.Indented); - NotificationReceived?.Invoke(this, formattedMessage); + NotificationReceived?.Invoke(this, betterMessage); } } } diff --git a/RustPlusApi/RustPlusApi.Fcm/FcmRegister.cs b/RustPlusApi/RustPlusApi.Fcm/FcmRegister.cs index 7a88ed3..7209aed 100644 --- a/RustPlusApi/RustPlusApi.Fcm/FcmRegister.cs +++ b/RustPlusApi/RustPlusApi.Fcm/FcmRegister.cs @@ -3,7 +3,7 @@ namespace RustPlusApi.Fcm { - public class FcmRegister + /*public class FcmRegister { public static async Task RegisterAsync(string senderId) { @@ -19,5 +19,5 @@ public static async Task RegisterAsync(string senderId) Fcm = fcmRegistration.Item2, }; } - } + }*/ } diff --git a/RustPlusApi/RustPlusApi.Fcm/README.md b/RustPlusApi/RustPlusApi.Fcm/README.md new file mode 100644 index 0000000..c00d795 --- /dev/null +++ b/RustPlusApi/RustPlusApi.Fcm/README.md @@ -0,0 +1,54 @@ +# RustPlusApi.Fcm + +This is a C# client for the Rust+ websocket. It allows you to receive notification via FCM. + +## Prerequisites + +- **.NET 8** or later + +## Usage + +First, instantiate the `FcmListener` class with the necessary parameters: + +```csharp +var fcmListener = new FcmListener(credentials, persistentIds); +``` + +Parameters: + +- `credentials`: The `Credentials`* object containing the FCM & GCM credentials + the keys to decrypt the notification. +- `persistentIds`: A list of notification IDs that should be ignored. Default is null. + +\* Go to the next section to see how to create a `Credentials` object. + +Then, connect to the FCM socket: + +```csharp +await fcmListener.ConnectAsync(); +``` + +You can subscribe to events to handle connection, disconnection, errors, and received messages: + +```csharp +fcmListener.Connecting += (sender, e) => { /* handle connecting event */ }; +fcmListener.Connected += (sender, e) => { /* handle connected event */ }; +fcmListener.Disconnected += (sender, e) => { /* handle disconnected event */ }; +fcmListener.ErrorOccurred += (sender, e) => { /* handle error event */ }; +fcmListener.MessageReceived += (sender, e) => { /* handle received message event */ }; +``` + +Remember to dispose the `FcmListener` instance when you're done: + +```csharp +fcmListener.Dispose(); +``` + +## Credentials + +Currenlty, there is not simple way to get the FCM & GCM credentials using .NET. +I've planned to implement a solution but it's not ready yet. + +To use this library, you need to get the FCM & GCM credentials manually. +To do so I recommand you to use [this project](https://github.com/liamcottle/rustplus.js) to get the credentials. + +I'm sorry for the inconvenience but since the API is not fully complete it's the easiest way. \ No newline at end of file diff --git a/RustPlusApi/RustPlusApi.Fcm/RustPlusApi.Fcm.csproj b/RustPlusApi/RustPlusApi.Fcm/RustPlusApi.Fcm.csproj index 61fd5ea..9fa298f 100644 --- a/RustPlusApi/RustPlusApi.Fcm/RustPlusApi.Fcm.csproj +++ b/RustPlusApi/RustPlusApi.Fcm/RustPlusApi.Fcm.csproj @@ -4,6 +4,19 @@ net8.0 enable enable + RustPlusApi.Fcm + 1.0.2 + HandyS11 + HandyS11 + A Rust+ API websocket made in C#. + This is a C# client for the Rust+ websocket. It allows you to receive notification via FCM. + rust rustplus rustplusapi + MIT + https://github.com/HandyS11/RustPlusApi/blob/main/LICENSE + true + https://github.com/HandyS11/RustPlusApi + git + README.md @@ -12,4 +25,8 @@ + + + + diff --git a/RustPlusApi/RustPlusApi.Fcm/Tools/FcmTools.cs b/RustPlusApi/RustPlusApi.Fcm/Tools/FcmTools.cs index d64d4ab..cbee472 100644 --- a/RustPlusApi/RustPlusApi.Fcm/Tools/FcmTools.cs +++ b/RustPlusApi/RustPlusApi.Fcm/Tools/FcmTools.cs @@ -5,14 +5,14 @@ namespace RustPlusApi.Fcm.Tools { - public static class FcmTools + internal static class FcmTools { private const string FcmSubscribeUrl = "https://fcm.googleapis.com/fcm/connect/subscribe"; private const string FcmEndpoint = "https://fcm.googleapis.com/fcm/send"; private static readonly HttpClient HttpClient = new(); - public static async Task> RegisterFcmAsync(string senderId, string token) + internal static async Task> RegisterFcmAsync(string senderId, string token) { var keys = CreateKeys(); var response = await HttpClient.PostAsync(FcmSubscribeUrl, new FormUrlEncodedContent(new Dictionary diff --git a/RustPlusApi/RustPlusApi.Fcm/Tools/GcmTools.cs b/RustPlusApi/RustPlusApi.Fcm/Tools/GcmTools.cs index b3ff763..048d5cd 100644 --- a/RustPlusApi/RustPlusApi.Fcm/Tools/GcmTools.cs +++ b/RustPlusApi/RustPlusApi.Fcm/Tools/GcmTools.cs @@ -11,7 +11,7 @@ namespace RustPlusApi.Fcm.Tools { - public static class GcmTools + internal static class GcmTools { private static readonly HttpClient HttpClient = new(); @@ -27,7 +27,7 @@ public static async Task RegisterAsync(string appId) return credentials; } - public static async Task CheckInAsync(ulong? androidId = null, ulong? securityToken = null) + internal static async Task CheckInAsync(ulong? androidId = null, ulong? securityToken = null) { try { diff --git a/RustPlusApi/RustPlusApi/README.md b/RustPlusApi/RustPlusApi/README.md index 3fd6263..68222a0 100644 --- a/RustPlusApi/RustPlusApi/README.md +++ b/RustPlusApi/RustPlusApi/README.md @@ -38,4 +38,8 @@ rustPlusApi.ErrorOccurred += (sender, e) => { /* handle error event */ }; rustPlusApi.MessageReceived += (sender, e) => { /* handle received message event */ }; ``` -Remember to dispose the `RustPlus` instance when you're done: \ No newline at end of file +Remember to dispose the `RustPlus` instance when you're done: + +```csharp +rustPlusApi.Dispose(); +``` \ No newline at end of file