-
-
Save glombek/5494697 to your computer and use it in GitHub Desktop.
A class to ping a Minecraft server for its description, player count and maximum player count. Based on barneygale's PHP code.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Net.Sockets; | |
using System.Text; | |
using System.Text.RegularExpressions; | |
namespace Minecraft | |
{ | |
public class MinecraftServerInfo | |
{ | |
const string NonNumericRegex = "[^.0-9]"; | |
/// <summary> | |
/// A class to ping a Minecraft server for its description, player count and maximum player count. | |
/// </summary> | |
/// <param name="host">Address of server to ping.</param> | |
/// <param name="port">Port on which the Minecraft server sits.</param> | |
/// <param name="sendTimeout">How long to wait when sending the ping (in milliseconds).</param> | |
/// <param name="recieveTimeout">How long to wait when reciving the ping response (in milliseconds).</param> | |
public MinecraftServerInfo(string host, int port = 25565, int sendTimeout = 0, int recieveTimeout = 30000) | |
{ | |
HostName = host; | |
Port = port; | |
SendTimeout = sendTimeout; | |
RecieveTimeout = recieveTimeout; | |
Refresh(); | |
} | |
/// <summary> | |
/// Refresh the data about this server. | |
/// </summary> | |
public void Refresh() | |
{ | |
//Set up our TCP Client | |
TcpClient tcpClient = new TcpClient(); | |
//Set the timeouts | |
tcpClient.SendTimeout = SendTimeout; | |
tcpClient.ReceiveTimeout = RecieveTimeout; | |
//Reset values | |
Online = false; | |
PlayerCount = 0; | |
try | |
{ | |
tcpClient.Connect(HostName, Port); | |
NetworkStream stream = tcpClient.GetStream(); | |
//Send server list ping | |
stream.Write(new byte[] { 0xFE }, 0, 1); | |
//Read data into buffer | |
byte[] buffer = new byte[256]; | |
while (tcpClient.Connected) | |
{ | |
int readBytes = stream.Read(buffer, 0, 256); | |
if (readBytes == 0) | |
break; | |
} | |
//Check we've got a 0xFF Disconnect | |
if (buffer[0] != 255) | |
{ | |
Online = false; | |
} | |
else | |
{ | |
//Server is online | |
Online = true; | |
//Remove the packet ident (0xFF) and the short containing the length of the string | |
buffer = buffer.Skip(3).ToArray(); | |
//Decode UCS-2 string | |
string str = System.Text.Encoding.BigEndianUnicode.GetString(buffer); | |
//Split into array | |
string[] parts = str.Split('§'); | |
//Set values | |
Description = parts[0].Trim(); | |
PlayerCount = int.Parse(Regex.Replace(parts[1], "[^.0-9]", "")); | |
MaxPlayerCount = int.Parse(Regex.Replace(parts[2], "[^.0-9]", "")); | |
} | |
} | |
catch { | |
//Online is already set to false. | |
//We assume the server is offline if any errors occur. | |
} | |
finally | |
{ | |
//close the client | |
tcpClient.Close(); | |
} | |
} | |
/// <summary> | |
/// The port being pinged. | |
/// </summary> | |
public int Port { get; set; } | |
/// <summary> | |
/// The hostname being tested. | |
/// </summary> | |
public string HostName { get; set; } | |
public int RecieveTimeout { get; set; } | |
public int SendTimeout { get; set; } | |
/// <summary> | |
/// Whether we can reach the server or not. | |
/// </summary> | |
public bool Online { get; set; } | |
/// <summary> | |
/// The server's MOTD. | |
/// This will always be null if Online has never been true. This information is kept after a Refresh. | |
/// </summary> | |
public string Description { get; set; } | |
/// <summary> | |
/// Number of online players. | |
/// This will always be 0 if Online is false. | |
/// </summary> | |
public int PlayerCount { get; set; } | |
/// <summary> | |
/// Maximum number of players for this server. | |
/// This will always be 0 if Online has never been true. This information is kept after a Refresh. | |
/// </summary> | |
public int MaxPlayerCount { get; set; } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment