From 4f4ad95ac40263d2d4128632e9b0df9f8e7eb74d Mon Sep 17 00:00:00 2001
From: actually akac <38866219+actually-akac@users.noreply.github.com>
Date: Wed, 7 Sep 2022 19:48:50 +0200
Subject: [PATCH] Version 1.1.4 - Added a documentation XML file - Updated some
variable and method names - The constructor of YachtsClient had its identity
and cache period arguments switched - Bumped Discord.net for the example
project from 3.7.2 to 3.8.0 - Minor general code changes
---
Example/Example.csproj | 2 +-
Example/Program.cs | 16 ++--
README.md | 117 +++++++++++++++++------------
SinkingYachts/Connection.cs | 50 +++++++++---
SinkingYachts/README_NuGet.md | 88 +++++++++++++++-------
SinkingYachts/SinkingYachts.cs | 55 +++++++++-----
SinkingYachts/SinkingYachts.csproj | 7 +-
7 files changed, 217 insertions(+), 118 deletions(-)
diff --git a/Example/Example.csproj b/Example/Example.csproj
index 7af21f2..5488089 100644
--- a/Example/Example.csproj
+++ b/Example/Example.csproj
@@ -6,7 +6,7 @@
-
+
diff --git a/Example/Program.cs b/Example/Program.cs
index df4368f..7c19cad 100644
--- a/Example/Program.cs
+++ b/Example/Program.cs
@@ -16,7 +16,7 @@ public static class Program
public static readonly StorageMode Mode = StorageMode.LocalWS;
- private static readonly YachtsClient Yachts = new(Mode, 3, "Example Bot");
+ private static readonly YachtsClient Yachts = new(Mode, "Example Bot", 3);
private static readonly string Token = Environment.GetEnvironmentVariable("BOT_TOKEN");
@@ -61,9 +61,9 @@ public static async Task Main()
public static async Task Ready()
{
- await Logger.Log("Bot", $"Bot is ready to protect your server from {await Yachts.DatabaseSize()} phishing domains", LogSeverity.Info);
+ await Logger.Log("Bot", $"Ready to protect your server from {await Yachts.GetDatabaseSize()} phishing domains", LogSeverity.Info);
- Change[] changes = await Yachts.Recent(TimeSpan.FromDays(1));
+ Change[] changes = await Yachts.GetRecent(TimeSpan.FromDays(1));
int added = changes.Count(x => x.Type == ChangeType.Add);
int deleted = changes.Count(x => x.Type == ChangeType.Delete);
@@ -78,11 +78,11 @@ public static async Task OnMessageReceived(SocketMessage msg)
if (msg.Channel is not SocketTextChannel) return;
if (msg.Author.IsBot) return;
- if (await Yachts.IsPhishing(msg.Content))
- {
- await msg.DeleteAsync();
- await msg.Channel.SendMessageAsync("Phishing links are not allowed.");
- }
+ bool isPhishing = await Yachts.IsPhishing(msg.Content);
+ if (!isPhishing) return;
+
+ await msg.DeleteAsync();
+ await msg.Channel.SendMessageAsync($"{msg.Author.Mention}, phishing links are not allowed.");
}
}
}
\ No newline at end of file
diff --git a/README.md b/README.md
index 3db9419..8ccdf34 100644
--- a/README.md
+++ b/README.md
@@ -9,76 +9,97 @@
## Usage
-This library can be downloaded as the package `SinkingYachts`. The main class is called `YachtsClient`.
+Available on NuGet as `SinkingYachts`, methods are available under the public class `YachtsClient`.
https://www.nuget.org/packages/SinkingYachts
## Features
+- Made with **.NET 6**
- Fully async
-- Access to a Discord-related phishing database of over `13 300` confirmed malicious domains
+- Access to a Discord-related phishing database of over `15 500` confirmed malicious domains
- Regex matching of domains and automatic phishing detection
- Different modes for storing and loading phishing domains
- Instant updates through **WebSocket events**
-- Domain whitelisting to prevent false positives
-- Customizable caching to decrease load
+- Domain whitelisting to decrease false positives
+- Customizable caching to decrease load
+
+## Example Project
+Under the `Example` directory you can find a working demo Discord bot that implements this library.
+```rust
+07.09. 19:13:59 [Discord] Discord.Net v3.8.0 (API v9)
+07.09. 19:13:59 [Gateway] Connecting
+07.09. 19:14:01 [Gateway] Connected
+07.09. 19:14:02 [Bot] Ready to protect your server from 15601 phishing domains
+07.09. 19:14:02 [Bot] Domains added within the past day: 8
+07.09. 19:14:02 [Bot] Domains deleted within the past day: 0
+07.09. 19:14:02 [Gateway] Ready
+```
+
+## Code Samples
+
+### Check message content
+```csharp
+bool isPhishing = await Yachts.IsPhishing("hello https://hypesquadacademy-apply.ml");
+//👉 True
+```
+
+### Check a domain
+```csharp
+bool isPhishing = await Yachts.IsPhishingDomain("warning-selectioneventhype.gq");
+//👉 True
+```
+
+### Get the latest domains
+```csharp
+string[] domains = (await Yachts.GetRecent(TimeSpan.FromDays(1))).Where(x => x.Type == ChangeType.Add).SelectMany(x => x.Domains).ToArray();
+//👉 steamcommunitysiv.top, wvwww-roblox.com, discord-download.win, steamcoumunity.eu, streamcummonity.com, streamcommunity.org, join-event-hypesquad.com, steamcommunityzowe.top
+```
+
+### Get the database size
+```csharp
+int size = await Yachts.GetDatabaseSize();
+//👉 15601
+```
## Available methods
-- Task `Recent`(TimeSpan time)
-- Task `Recent`(int seconds)
-- Task `IsPhishing`(string content)
-- Task `IsPhishingDomain`(string domain)
-- Task `DatabaseSize`()
-- Task `GetPhishingDomains`()
+- Task GetRecent(TimeSpan time)
+- Task GetRecent(int seconds)
+- Task IsPhishing(string content)
+- Task IsPhishingDomain(string domain)
+- Task GetDatabaseSize()
+- Task GetPhishingDomains()
## Available events (requires `StorageMode.LocalWS`)
-- EventHandler\ `DomainAdded`
-- EventHandler\ `DomainDeleted`
+- EventHandler\ DomainAdded
+- EventHandler\ DomainDeleted
## Statistics from the past week
| Date | New domains found |
| :---: | :---: |
-| 0.0.0 | + `0` |
-| 0.0.0 | + `0` |
-| 0.0.0 | + `0` |
-| 0.0.0 | + `0` |
-| 0.0.0 | + `0` |
-| 23.06.2022 | + `33` |
-| 24.06.2022 | + `24` |
+| 31.08.2022 | + `23` |
+| 01.09.2022 | + `10` |
+| 02.09.2022 | + `23` |
+| 03.09.2022 | + `25` |
+| 04.09.2022 | + `3` |
+| 05.09.2022 | + `18` |
+| 06.09.2022 | + `5` |
## Recently flagged domains
```ruby
-steamcommunityzivc.top
-www-robloxa.com
-wwzw-robloxs.com
-www-roblox.com.ru
-discoradnitro.xyz
-hype-squad-vote.gq
-www.discordpolicy.repl.co
-wmw-roblox.com
-hype-events-badges.gq
-wwu-roblox.com
-discrod-egift.com
+steamcommunityzowe.top
+sleamtlade-ofler.xyz
+vww-roblox.ga
+wwwwv-roblox.com
+roblox-profiles.gq
```
-## Example
-Under the `Example` folder you can find a demo Discord bot that implements this library.
-```rust
-18.06. 20:09:38 [Discord] Discord.Net v3.6.0 (API v9)
-18.06. 20:09:38 [Gateway] Connecting
-18.06. 20:09:40 [Gateway] Connected
-18.06. 20:09:40 [Bot] Bot is ready to protect your server from 13326 phishing domains
-18.06. 20:09:40 [Bot] Domains added within the past day: 111
-18.06. 20:09:40 [Bot] Domains deleted within the past day: 0
-18.06. 20:09:40 [Gateway] Ready
-```
-
-## Unknown domains
-Found a Discord/Steam phishing domain that isn't yet present in the database? Send it into the `#domain-reports` channel on our Discord server or open an **issue**.
+## Missing domains
+Found a Discord/Steam phishing domain that isn't yet present in the database? Send it into the `#domain-reports` channel on our Discord server or open an **issue** in this repository.
-## Links
-Need help, want to discuss phishing or have a suggestion? Feel free to join our Discord server: https://discord.gg/cT6eQjWW8H
+## Resources
+Need help, want to discuss phishing or have a suggestion? Feel free to join our Discord server: https://discord.gg/d63pvY28HU (temporarily closed)
Official website: https://sinking.yachts
-Email: sinkingyachts@gmail.com
+Email: admin@fishfish.gg, sinkingyachts@gmail.com
GitHub: https://github.com/SinkingYachts
-Blog: https://sinking.yachts/blog/
+Blog: https://sinking.yachts/blog/
\ No newline at end of file
diff --git a/SinkingYachts/Connection.cs b/SinkingYachts/Connection.cs
index 214295b..aeb7921 100644
--- a/SinkingYachts/Connection.cs
+++ b/SinkingYachts/Connection.cs
@@ -8,42 +8,69 @@
namespace SinkingYachts
{
+ ///
+ /// The class for connecting and receiving messages from the real-time WebSocket server.
+ ///
public class Connection
{
- public const string URL = "wss://phish.sinking.yachts/feed";
- public const int ReconnectionInterval = 10000;
+ ///
+ /// The WebSocket URI to connect to.
+ ///
+ public static readonly Uri Feed = new("wss://phish.sinking.yachts/feed");
+
+ ///
+ /// How long to wait before reconnecting after a connection is lost.
+ ///
+ public const int ReconnectionDelay = 10000;
private ClientWebSocket WS;
private readonly CancellationTokenSource Source = new();
+ ///
+ /// Whether there is currently a connection to the phishing feed.
+ ///
public bool Connected = false;
+ ///
+ /// Executes whenever a phishing domain is added into the database.
+ ///
public EventHandler DomainAdded;
+
+ ///
+ /// Executes whenever a phishing domain is removed from the database.
+ ///
public EventHandler DomainDeleted;
- private readonly string _identity;
+ private readonly string Identity;
+ ///
+ /// Default constructor for the connection class.
+ ///
+ ///
public Connection(string identity)
{
- _identity = identity;
+ Identity = identity;
Connect();
}
+ ///
+ /// Connects to the remote WebSocket server to start receiving updates.
+ ///
public async void Connect()
{
Connected = false;
WS = new ClientWebSocket();
- WS.Options.SetRequestHeader("X-Identity", _identity);
+ WS.Options.SetRequestHeader("X-Identity", Identity);
try
{
- await WS.ConnectAsync(new Uri(URL), Source.Token);
+ await WS.ConnectAsync(Feed, Source.Token);
}
catch
{
Connected = false;
- await Task.Delay(ReconnectionInterval);
+ await Task.Delay(ReconnectionDelay);
Connect();
return;
}
@@ -62,8 +89,8 @@ public async void Connect()
WebSocketReceiveResult result = await WS.ReceiveAsync(bytesReceived, Source.Token);
offset += result.Count;
- if (result.EndOfMessage)
- break;
+
+ if (result.EndOfMessage) break;
}
catch { break; };
}
@@ -72,10 +99,13 @@ public async void Connect()
}
Connected = false;
- await Task.Delay(ReconnectionInterval);
+ await Task.Delay(ReconnectionDelay);
Connect();
}
+ ///
+ /// Called when a WebSocket message is received.
+ ///
public void OnMessage(string msg)
{
Change data;
diff --git a/SinkingYachts/README_NuGet.md b/SinkingYachts/README_NuGet.md
index 6f41ec0..015f0b4 100644
--- a/SinkingYachts/README_NuGet.md
+++ b/SinkingYachts/README_NuGet.md
@@ -4,49 +4,79 @@
A C# library for detecting Discord/Steam phishing links using the Sinking Yachts API.
+
## Usage
-Everything is located within the `SinkingYachts` NuGet package, the main class is called `YachtsClient`.
+Available on NuGet as `SinkingYachts`, methods are available under the public class `YachtsClient`.
+
+https://www.nuget.org/packages/SinkingYachts
## Features
+- Made with **.NET 6**
- Fully async
-- Access to a Discord-related phishing database of over `13 300` confirmed malicious domains
+- Access to a Discord-related phishing database of over `15 500` confirmed malicious domains
- Regex matching of domains and automatic phishing detection
- Different modes for storing and loading phishing domains
- Instant updates through **WebSocket events**
-- Domain whitelisting to prevent false positives
-- Customizable caching to decrease load
+- Domain whitelisting to decrease false positives
+- Customizable caching to decrease load
+
+## Example Project
+Under the `Example` directory you can find a working demo Discord bot that implements this library.
+```rust
+07.09. 19:13:59 [Discord] Discord.Net v3.8.0 (API v9)
+07.09. 19:13:59 [Gateway] Connecting
+07.09. 19:14:01 [Gateway] Connected
+07.09. 19:14:02 [Bot] Ready to protect your server from 15601 phishing domains
+07.09. 19:14:02 [Bot] Domains added within the past day: 8
+07.09. 19:14:02 [Bot] Domains deleted within the past day: 0
+07.09. 19:14:02 [Gateway] Ready
+```
+
+## Code Samples
+
+### Check message content
+```csharp
+bool isPhishing = await Yachts.IsPhishing("hello https://hypesquadacademy-apply.ml");
+//👉 True
+```
+
+### Check a domain
+```csharp
+bool isPhishing = await Yachts.IsPhishingDomain("warning-selectioneventhype.gq");
+//👉 True
+```
+
+### Get the latest domains
+```csharp
+string[] domains = (await Yachts.GetRecent(TimeSpan.FromDays(1))).Where(x => x.Type == ChangeType.Add).SelectMany(x => x.Domains).ToArray();
+//👉 steamcommunitysiv.top, wvwww-roblox.com, discord-download.win, steamcoumunity.eu, streamcummonity.com, streamcommunity.org, join-event-hypesquad.com, steamcommunityzowe.top
+```
+
+### Get the database size
+```csharp
+int size = await Yachts.GetDatabaseSize();
+//👉 15601
+```
## Available methods
-- Task `Recent`(TimeSpan time)
-- Task `Recent`(int seconds)
-- Task `IsPhishing`(string content)
-- Task `IsPhishingDomain`(string domain)
-- Task `DatabaseSize`()
-- Task `GetPhishingDomains`()
+- Task GetRecent(TimeSpan time)
+- Task GetRecent(int seconds)
+- Task IsPhishing(string content)
+- Task IsPhishingDomain(string domain)
+- Task GetDatabaseSize()
+- Task GetPhishingDomains()
## Available events (requires `StorageMode.LocalWS`)
-- EventHandler\ `DomainAdded`
-- EventHandler\ `DomainDeleted`
+- EventHandler\ DomainAdded
+- EventHandler\ DomainDeleted
-## Example
-Under the `Example` folder you can find a demo Discord bot that implements this library.
-```rust
-18.06. 20:09:38 [Discord] Discord.Net v3.6.0 (API v9)
-18.06. 20:09:38 [Gateway] Connecting
-18.06. 20:09:40 [Gateway] Connected
-18.06. 20:09:40 [Bot] Bot is ready to protect your server from 13326 phishing domains
-18.06. 20:09:40 [Bot] Domains added within the past day: 111
-18.06. 20:09:40 [Bot] Domains deleted within the past day: 0
-18.06. 20:09:40 [Gateway] Ready
-```
-
-## Unknown domains
-Found a Discord/Steam phishing domain that isn't yet present in the database? Send it into the `#domain-reports` channel on our Discord server or open an **issue**.
+## Missing domains
+Found a Discord/Steam phishing domain that isn't yet present in the database? Send it into the `#domain-reports` channel on our Discord server or open an **issue** in this repository.
-## Links
-Need help, want to discuss phishing or have a suggestion? Feel free to join our Discord server: https://discord.gg/cT6eQjWW8H
+## Resources
+Need help, want to discuss phishing or have a suggestion? Feel free to join our Discord server: https://discord.gg/d63pvY28HU (temporarily closed)
* Official website: https://sinking.yachts
-* Email: sinkingyachts@gmail.com
+* Email: admin@fishfish.gg, sinkingyachts@gmail.com
* GitHub: https://github.com/SinkingYachts
* Blog: https://sinking.yachts/blog/
\ No newline at end of file
diff --git a/SinkingYachts/SinkingYachts.cs b/SinkingYachts/SinkingYachts.cs
index 86d228e..4ccf19d 100644
--- a/SinkingYachts/SinkingYachts.cs
+++ b/SinkingYachts/SinkingYachts.cs
@@ -39,9 +39,15 @@ public enum StorageMode
///
public enum ChangeType
{
+ ///
+ /// Domain add event.
+ ///
[JsonPropertyName("add")]
Add,
+ ///
+ /// Domain delete event.
+ ///
[JsonPropertyName("delete")]
Delete
}
@@ -106,11 +112,18 @@ public class YachtsClient
private static Connection Con;
- private readonly string _identity;
- private readonly TimeSpan _cachePeriod;
- private readonly StorageMode _mode;
+ private readonly string Identity;
+ private readonly TimeSpan CachePeriod;
+ private readonly StorageMode Mode;
+ ///
+ /// Executes whenever a phishing domain is added into the database.
+ ///
public EventHandler DomainAdded;
+
+ ///
+ /// Executes whenever a phishing domain is deleted from the database.
+ ///
public EventHandler DomainDeleted;
///
@@ -119,23 +132,25 @@ public class YachtsClient
/// The domain storage mode to use.
/// A short string identifying your bot application. By default this is the name of your project.
/// How long in hours should be API responses cached for.
- public YachtsClient(StorageMode mode, int cachePeriodHours = 3, string identity = null)
+ public YachtsClient(StorageMode mode, string identity = null, int cachePeriodHours = 3)
{
- _mode = mode;
- _identity = $"https://github.com/actually-akac/SinkingYachts | {identity ?? Assembly.GetEntryAssembly().GetName().Name}";
- _cachePeriod = TimeSpan.FromHours(cachePeriodHours);
+ Mode = mode;
+ Identity = $"https://github.com/actually-akac/SinkingYachts | {identity ?? Assembly.GetEntryAssembly().GetName().Name}";
+ CachePeriod = TimeSpan.FromHours(cachePeriodHours);
Client = new();
- Client.DefaultRequestHeaders.Add("X-Identity", _identity);
+ Client.DefaultRequestHeaders.Add("X-Identity", Identity);
- switch (_mode)
+ switch (Mode)
{
case StorageMode.Local:
{
UpdateCache();
- Refresher = new();
- Refresher.Interval = RefreshInterval;
+ Refresher = new()
+ {
+ Interval = RefreshInterval
+ };
Refresher.Elapsed += (o, e) => UpdateCache();
Refresher.Start();
@@ -145,12 +160,14 @@ public YachtsClient(StorageMode mode, int cachePeriodHours = 3, string identity
{
UpdateCache();
- Refresher = new();
- Refresher.Interval = RefreshInterval;
+ Refresher = new()
+ {
+ Interval = RefreshInterval
+ };
Refresher.Elapsed += (o, e) => UpdateCache();
Refresher.Start();
- Con = new Connection(_identity);
+ Con = new Connection(Identity);
Con.DomainAdded += (sender, domain) => Cache[domain] = true;
Con.DomainAdded += (sender, domain) => DomainAdded(sender, domain);
@@ -224,7 +241,7 @@ public async Task IsPhishingDomain(string domain)
output = bool.Parse(content);
Cache[domain] = output;
- Task remover = Task.Delay(_cachePeriod).ContinueWith(x =>
+ Task remover = Task.Delay(CachePeriod).ContinueWith(x =>
{
Cache.Remove(domain);
});
@@ -249,7 +266,7 @@ public async Task GetPhishingDomains()
///
/// Fetches the total amount of flagged domains in the database.
///
- public async Task DatabaseSize()
+ public async Task GetDatabaseSize()
{
HttpResponseMessage res = await Client.GetAsync($"{Api}/v{Version}/dbsize");
string content = await res.Content.ReadAsStringAsync();
@@ -267,7 +284,7 @@ public async Task DatabaseSize()
///
/// Fetches the domains added or deleted within the last X seconds.
///
- public async Task Recent(int seconds)
+ public async Task GetRecent(int seconds)
{
if (seconds > 604800) throw new ArgumentException("Maximum value is 604800 seconds (7 days).", nameof(seconds));
if (seconds <= 0) throw new ArgumentException("Argument has to be positive.", nameof(seconds));
@@ -293,9 +310,9 @@ public async Task Recent(int seconds)
///
/// Fetches the domains added or deleted within the provided TimeSpan.
///
- public async Task Recent(TimeSpan time)
+ public async Task GetRecent(TimeSpan time)
{
- return await Recent((int)time.TotalSeconds);
+ return await GetRecent((int)time.TotalSeconds);
}
}
}
\ No newline at end of file
diff --git a/SinkingYachts/SinkingYachts.csproj b/SinkingYachts/SinkingYachts.csproj
index e4e8028..30254f6 100644
--- a/SinkingYachts/SinkingYachts.csproj
+++ b/SinkingYachts/SinkingYachts.csproj
@@ -3,7 +3,9 @@
net6.0
SinkingYachts
- 1.0.4
+ 1.1.4
+ 1.1.4
+ 1.1.4
akac
akac
SinkingYachts
@@ -15,10 +17,9 @@
https://github.com/actually-akac/SinkingYachts
git
phishing; phish; scam; anti-phishing; anti-scam; discord; steam; sinking-yachts
- 1.0.4
- 1.0.4
en
MIT
+ true