Skip to content

Instantly share code, notes, and snippets.

@AlexArchive
Created July 27, 2013 12:03
Show Gist options
  • Save AlexArchive/6094678 to your computer and use it in GitHub Desktop.
Save AlexArchive/6094678 to your computer and use it in GitHub Desktop.
Resolves a Minecraft Server's Information. This includes Message Of the Day (MOTD), Server Version, Player Count, Maximum Players
public sealed class Program
{
private static void Main()
{
Console.Write("Server End Point: ");
var userInput = Console.ReadLine();
if (userInput != null)
{
var endPoint = new IPEndPoint(IPAddress.Parse(userInput), 25565);
var resolver = new ServerInformationResolver();
var serverInfo = resolver.ResolveServerInformation(endPoint);
Console.WriteLine();
Console.WriteLine(serverInfo.ToStringAutomatic());
}
Console.ReadKey();
}
}
public class ServerInformation
{
public Version Version { get; private set; }
public string MessageOfTheDay { get; private set; }
public int PlayersOnline { get; private set; }
public int MaximumPlayers { get; private set; }
public ServerInformation(Version version, string messageOfTheDay, int playersOnline, int maximumPlayers)
{
Version = version;
MessageOfTheDay = messageOfTheDay;
MaximumPlayers = maximumPlayers;
PlayersOnline = playersOnline;
}
}
public class ServerInformationResolver
{
private readonly Socket _socket =
new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
public ServerInformation ResolveServerInformation(EndPoint remoteEndPoint)
{
_socket.Connect(remoteEndPoint);
var pullInformationMessage = BuildPullServerInformationMessage();
_socket.Send(pullInformationMessage, 0, pullInformationMessage.Length, SocketFlags.None);
var pushInformationMessage = new byte[256];
var bytesRead = _socket.Receive(pushInformationMessage, 0, pushInformationMessage.Length, SocketFlags.None);
var rawServerInformation = new byte[bytesRead];
Buffer.BlockCopy(pushInformationMessage, 5, rawServerInformation, 0, rawServerInformation.Length);
var parsedServerInformation =
Encoding.BigEndianUnicode.GetString(rawServerInformation).Split(new[] { '\u0000' });
var serverInformation = BuildServerInformation(parsedServerInformation);
return serverInformation;
}
private static ServerInformation BuildServerInformation(IList<string> parsedServerInformation)
{
var serverVersion = Version.Parse(parsedServerInformation[2]);
var messageOfTheDay = SanetizeMessageOfTheDay(parsedServerInformation[3]);
var playersOnline = int.Parse(parsedServerInformation[4]);
var maximumPlayers = int.Parse(parsedServerInformation[5]);
return new ServerInformation(serverVersion, messageOfTheDay, playersOnline, maximumPlayers);
}
private static byte[] BuildPullServerInformationMessage()
{
const int PacketID = 0xFE;
var serverListPingPacket = new byte[] { PacketID, 1 };
return serverListPingPacket;
}
private static string SanetizeMessageOfTheDay(string messageOfTheDay)
{
//TODO: Sanetize Input
return messageOfTheDay;
}
}
public static class DebuggingExtensions
{
public static string ToStringAutomatic<T>(this T obj)
{
const string Seperator = "\r\n";
const BindingFlags BindingFlags = BindingFlags.Instance | BindingFlags.Public;
var objProperties =
from property in obj.GetType().GetProperties(BindingFlags)
where property.CanRead
select string.Format("{0} : {1}", property.Name, property.GetValue(obj, null));
return string.Join(Seperator, objProperties);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment