Skip to content

Commit ae9dd72

Browse files
authored
Merge pull request #6 from cyilcode/v1.0.6
V1.0.6
2 parents dcae393 + 76ca746 commit ae9dd72

28 files changed

+977
-316
lines changed

CHANGELOG.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Changelog for SteamQueryNet v1.0.6
2+
3+
### 1. Enhancements
4+
5+
* ServerInfo model now reduces the `ServerInfo.Bots` from the `ServerInfo.Players` property. So that `ServerInfo.Players` reflects real player count only. This was an issue because some server flag their bots as real players.
6+
7+
* Added a new constructor to `ServerQuery` to allow users to be able to bind their own local IPEndpoint.
8+
9+
* Added a new constructor to `ServerQuery` to allow users to be able to provide hostnames and ports in one single string like
10+
11+
```
12+
string myHostAndPort = "127.0.0.1:27015";
13+
// or
14+
string myHostAndPort = "localhost:27015";
15+
// or
16+
string myHostAndPort = "steam://connect/127.0.0.1:27015";
17+
// or
18+
string myHostAndPort = "steam://connect/localhost:27015";
19+
```
20+
* Implemented new tests for ip, hostname and port validation.
21+
22+
* Added a CHANGELOG. LUL :)
23+
24+
### 2. Bug fixes
25+
26+
* Fixed a bug where player information was not gathered correctly by the `ServerQuery.GetPlayers()` function.
27+
28+
* Fixed a bug where player count was not gathered by the `ServerQuery.GetServerInfo()` function.
29+
30+
### 3. Soft-deprecations (no warnings emitted)
31+
32+
* Removed `sealed` modifiers from all `SteamQueryNet.Models` namespace.
33+
34+
* `IServerQuery` moved into `SteamQueryNet.Interfaces` namespace.
35+
36+
### 4. Hard-deprecations
37+
38+
* `ServerQuery` constructor parameter `int port` now changed to `ushort` to remove all integer range checks since the UDP port is already literally an `ushort`.
39+
40+
* Removed port range tests.
41+
42+
* `IServerQuery` moved into `SteamQueryNet.Interfaces` namespace.

README.md

Lines changed: 79 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,87 @@ SteamQueryNet comes with a single object that gives you access to all API's of t
1616

1717
* Server information (server name, capacity etc).
1818
* Concurrent players.
19-
* Server rules (friendlyfire, roundttime etc). **Warning: currently does not work due to a protocol issue on server source server.**
19+
* Server rules (friendlyfire, roundttime etc). **Warning: currently does not work due to a protocol issue on steam server query API. Use could make use of ServerInfo.tags if the server admins are kind enough to put rules as tags in the field.**
2020

2121
## Creating an instance
22-
To make us of the API's listed above, an instance of `ServerQuery` should be created.
22+
To make use of the API's listed above, an instance of `ServerQuery` should be created.
2323

2424
```csharp
2525
string serverIp = "127.0.0.1";
2626
int serverPort = 27015;
2727
IServerQuery serverQuery = new ServerQuery(serverIp, serverPort);
2828
```
2929

30+
or you can use string resolvers like below:
31+
32+
```csharp
33+
string myHostAndPort = "127.0.0.1:27015";
34+
// or
35+
myHostAndPort = "127.0.0.1,27015";
36+
// or
37+
myHostAndPort = "localhost:27015";
38+
// or
39+
myHostAndPort = "localhost,27015";
40+
// or
41+
myHostAndPort = "steam://connect/127.0.0.1:27015";
42+
// or
43+
myHostAndPort = "steam://connect/localhost:27015";
44+
45+
IServerQuery serverQuery = new ServerQuery(myHostAndPort);
46+
```
47+
48+
Also, it is possible to create `ServerQuery` object without connecting like below:
49+
50+
```csharp
51+
IServerQuery serverQuery = new ServerQuery();
52+
serverQuery.Connect(host, port);
53+
```
54+
55+
*Note*: `Connect` function overloads are similar to `ServerQuery` non-empty constructors.
56+
57+
## Providing Custom UDPClient
58+
59+
You can provide custom UDP clients by implementing `IUdpClient` in `SteamQueryNet.Interfaces` namespace.
60+
61+
See the example below:
62+
```csharp
63+
public class MyAmazingUdpClient : IUdpClient
64+
{
65+
public bool IsConnected { get; }
66+
67+
public void Close()
68+
{
69+
// client implementation
70+
}
71+
72+
public void Connect(IPEndPoint remoteIpEndpoint)
73+
{
74+
// client implementation
75+
}
76+
77+
public void Dispose()
78+
{
79+
// client implementation
80+
}
81+
82+
public Task<UdpReceiveResult> ReceiveAsync()
83+
{
84+
// client implementation
85+
}
86+
87+
public Task<int> SendAsync(byte[] datagram, int bytes)
88+
{
89+
// client implementation
90+
}
91+
}
92+
93+
// Usage
94+
IPEndpoint remoteIpEndpoint = new IPEndPoint(IPAddress.Parse(remoteServerIp), remoteServerPort);
95+
96+
IUdpClient myUdpClient = new MyAmazingUdpClient();
97+
IServerQuery serverQuery = new ServerQuery(myUdpClient, remoteIpEndpoint);
98+
```
99+
30100
once its created functions below returns informations desired,
31101

32102
[ServerInfo](https://github.com/cyilcode/SteamQueryNet/blob/master/SteamQueryNet/SteamQueryNet/Models/ServerInfo.cs)
@@ -36,18 +106,21 @@ ServerInfo serverInfo = serverQuery.GetServerInfo();
36106

37107
[Players](https://github.com/cyilcode/SteamQueryNet/blob/master/SteamQueryNet/SteamQueryNet/Models/Player.cs)
38108
```csharp
39-
// Concurrent Players
40109
List<Player> players = serverQuery.GetPlayers();
41110
```
42111

43112
[Rules](https://github.com/cyilcode/SteamQueryNet/blob/master/SteamQueryNet/SteamQueryNet/Models/Rule.cs)
44113
```csharp
45-
// Rules
46114
List<Rules> rules = serverQuery.GetRules();
47115
```
48116

49-
and thats it.
117+
While **it is not encouraged**, you can chain `Connect` function or Non-empty Constructors to get information in a single line.
118+
119+
```csharp
120+
ServerInfo serverInfo = new ServerQuery()
121+
.Connect(host, port)
122+
.GetServerInfo();
123+
```
50124

51125
# Todos
52-
* Write MOAR TESTS !
53126
* Enable CI
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
255,255,255,255,68,4,0,62,58,40,32,217,160,32,77,114,46,80,111,103,111,77,111,103,111,70,111,103,111,78,111,103,111,32,48,49,58,51,0,0,0,0,0,86,189,203,70,0,70,117,77,101,32,74,70,0,0,0,0,0,63,18,10,69,0,51,48,83,97,110,99,104,101,122,90,0,0,0,0,0,0,30,255,68,0,107,122,122,45,45,0,0,0,0,0,253,167,52,68
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
using SteamQueryNet.Enums;
2+
using SteamQueryNet.Models;
3+
4+
using System;
5+
using System.Collections.Generic;
6+
using System.IO;
7+
using System.Linq;
8+
9+
namespace SteamQueryNet.Tests.Responses
10+
{
11+
internal sealed class ResponseHelper
12+
{
13+
internal const string ServerInfo = "/Responses/ServerInfoValidResponse.txt";
14+
internal const string GetPlayers = "/Responses/GetPlayersValidResponse.txt";
15+
16+
// Decided to use a response from SurfHeaven servers and cache them. Got administrators approval.
17+
private static readonly Dictionary<string, object> _responses = new Dictionary<string, object>()
18+
{
19+
{
20+
ServerInfo, new ServerInfo
21+
{
22+
Bots = 3,
23+
EDF = 177,
24+
Environment = ServerEnvironment.Linux,
25+
Folder = "csgo",
26+
Game = "Counter-Strike: Global Offensive",
27+
GameID = 730,
28+
ID = 730,
29+
Keywords = "!knife,!ws,64tick,SurfHeaven,autobhop,cs20,knife,rank,skins,stats,surf,surfing,surftimer,timer,ws,secure",
30+
Map = "surf_sinister_evil",
31+
MaxPlayers = 40,
32+
Name = " SurfHeaven #5 Top 250/VIP",
33+
Ping = 0,
34+
Players = 4,
35+
Port = 27015,
36+
Protocol = 17,
37+
ServerType = ServerType.Dedicated,
38+
ShipGameInfo = null,
39+
SourceTVPort = 0,
40+
SourceTVServerName = null,
41+
SteamID = 85568392920053114,
42+
VAC = VAC.Secured,
43+
Version = "1.37.3.6",
44+
Visibility = Visibility.Public
45+
}
46+
},
47+
{
48+
GetPlayers, new List<Player>()
49+
{
50+
new Player
51+
{
52+
Duration = 26078.668f,
53+
Index = 0,
54+
Name = ">:( ٠ Mr.PogoMogoFogoNogo 01:3",
55+
Score = 0
56+
},
57+
new Player
58+
{
59+
Duration = 2209.14038f,
60+
Index = 0,
61+
Name = "FuMe JF",
62+
Score = 0
63+
},
64+
new Player
65+
{
66+
Duration = 2040.9375f,
67+
Index = 0,
68+
Name = "30SanchezZ",
69+
Score = 0
70+
},
71+
new Player
72+
{
73+
Duration = 722.6248f,
74+
Index = 0,
75+
Name = "kzz--",
76+
Score = 0
77+
}
78+
}
79+
}
80+
};
81+
82+
public static (byte[], object) GetValidResponse(string responseType)
83+
{
84+
string validResponseString = File.ReadAllText(Environment.CurrentDirectory + responseType);
85+
if (!_responses.TryGetValue(responseType, out object responseObject))
86+
{
87+
throw new ArgumentException($"Invalid response type received: {responseType}." +
88+
$"Consider registering {responseType} into ResponseHelpers dictionary.", nameof(responseType));
89+
}
90+
91+
return (validResponseString.Split(',').Select(x => byte.Parse(x)).ToArray(), responseObject);
92+
}
93+
}
94+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
255,255,255,255,73,17,32,83,117,114,102,72,101,97,118,101,110,32,35,53,32,84,111,112,32,50,53,48,47,86,73,80,0,115,117,114,102,95,115,105,110,105,115,116,101,114,95,101,118,105,108,0,99,115,103,111,0,67,111,117,110,116,101,114,45,83,116,114,105,107,101,58,32,71,108,111,98,97,108,32,79,102,102,101,110,115,105,118,101,0,218,2,4,40,3,100,108,0,1,49,46,51,55,46,51,46,54,0,177,135,105,122,53,0,0,0,0,48,1,33,107,110,105,102,101,44,33,119,115,44,54,52,116,105,99,107,44,83,117,114,102,72,101,97,118,101,110,44,97,117,116,111,98,104,111,112,44,99,115,50,48,44,107,110,105,102,101,44,114,97,110,107,44,115,107,105,110,115,44,115,116,97,116,115,44,115,117,114,102,44,115,117,114,102,105,110,103,44,115,117,114,102,116,105,109,101,114,44,116,105,109,101,114,44,119,115,44,115,101,99,117,114,101,0,218,2,0,0,0,0,0,0

0 commit comments

Comments
 (0)