public static void ReceiveClientSettings(Player player, GameStream stream) { string locale = stream.ReadString(); byte viewDistance = stream.ReadByte(); ChatMode chatMode = (ChatMode)(int)stream.ReadVarInt().Value; bool colors = stream.ReadBoolean(); byte skinParts = stream.ReadByte(); VarInt mainHand = stream.ReadVarInt(); player.Locale = locale; player.ViewDistance = viewDistance; player.ChatMode = chatMode; player.ColorsEnabled = colors; foreach (SkinPart part in SkinParts) { if (skinParts.IsBitSet(part)) { player.DisplayedSkinParts.Add(part); } } player.MainHand.Value = mainHand; SendPlayerSlot(player, stream, player.Slot); // TODO - Declare Recipes // TODO - Set Tags // TODO - Set Entity Statuses }
public void Receive(ref MinecraftClient client, GameStream stream) { VarInt secretLength = stream.ReadVarInt(); byte[] sharedSecret = stream.ReadByteArray((int)secretLength.Value); VarInt tokenLength = stream.ReadVarInt(); byte[] verifyToken = stream.ReadByteArray((int)tokenLength.Value); var decryptedToken = Protocol.CryptoProvider.Decrypt(verifyToken, false); for (int i = 0; i < decryptedToken.Length; i++) { if (decryptedToken[i] != client.VerifyToken[i]) { client.Disconnect("Unable to authenticate"); return; } } client.SharedToken = Protocol.CryptoProvider.Decrypt(sharedSecret, false); AsnKeyBuilder.AsnMessage encodedKey = AsnKeyBuilder.PublicKeyToX509(Protocol.Key); byte[] shaData = Encoding.UTF8.GetBytes(Protocol.ServerID) .Concat(client.SharedToken) .Concat(encodedKey.GetBytes()).ToArray(); string hash = Cryptography.JavaHexDigest(shaData); WebClient webClient = new(); StreamReader webReader = new(webClient.OpenRead( new Uri(string.Format(SessionChecker, client.Player.Username, hash)) )); string response = webReader.ReadToEnd(); webReader.Close(); JToken json = JToken.Parse(response); if (string.IsNullOrEmpty(response)) { client.Disconnect("Failed to verify username"); return; } client.Stream = new(new AesStream(client.Stream.BaseStream, client.SharedToken)); string?uuid = json["id"] !.Value <string>(); if (uuid != client.Player.UniqueId.toString().Remove('-')) { client.Disconnect("Failed to verify UniqueID"); return; } client.EncryptionPassed = true; new LoginSuccess(true).Send(ref client, client.Stream); }
public static void ReceiveEncryptionResponse(Player player, GameStream stream) { VarInt secretLength = stream.ReadVarInt(); byte[] sharedSecret = stream.ReadByteArray((int)secretLength.Value); VarInt tokenLength = stream.ReadVarInt(); byte[] verifyToken = stream.ReadByteArray((int)tokenLength.Value); var decryptedToken = Server.CryptoServerProvider.Decrypt(verifyToken, false); for (int i = 0; i < decryptedToken.Length; i++) { if (decryptedToken[i] != player.Stream.VerifyToken[i]) { Disconnect(player, stream, "Unable to authenticate"); } } player.SharedToken = Server.CryptoServerProvider.Decrypt(sharedSecret, false); AsnKeyBuilder.AsnMessage encodedKey = AsnKeyBuilder.PublicKeyToX509(Server.ServerKey); byte[] shaData = Encoding.UTF8.GetBytes(Server.ID) .Concat(player.SharedToken) .Concat(encodedKey.GetBytes()).ToArray(); string hash = Cryptography.JavaHexDigest(shaData); WebClient webCLient = new WebClient(); StreamReader webReader = new StreamReader(webCLient.OpenRead( new Uri(string.Format(SessionChecker, player.Username, hash)) )); string response = webReader.ReadToEnd(); webReader.Close(); JToken json = JToken.Parse(response); if (string.IsNullOrEmpty(response)) { Disconnect(player, stream, "Failed to verify username"); } player.Stream = new GameStream(new AesStream(player.Stream.BaseStream, player.SharedToken)); player.UUID = json["id"].Value <string>(); player.EncryptionEnabled = true; SendSuccess(player, player.Stream); }
public void Receive(ref MinecraftClient client, GameStream stream) { VarInt protocolVersion = stream.ReadVarInt(); string serverAddress = stream.ReadString(); ushort port = stream.ReadShort(); VarInt nextState = stream.ReadVarInt(); if (nextState == 1) { client.State = ConnectionState.Status; } else if (nextState == 2) { client.State = ConnectionState.Login; } else { throw new Exception("Invalid Next State - Handshake"); } }
private static void Run() { IPAddress ip = IPAddress.Parse("0.0.0.0"); int port = 25565; TcpListener server = new TcpListener(ip, port); Logger.Write("Starting the server on " + ip + ":" + port); try { server.Start(); Logger.Write("Now accepting connections."); while (true) { if (!server.Pending()) { continue; } Thread tmpThread = new Thread(() => { Player client = new Player(server.AcceptTcpClient()); using (NetworkStream ns = client.Client.GetStream()) { GameStream stream = new GameStream(ns) { State = SessionState.Handshaking }; using (StreamReader sr = new StreamReader(stream)) { while (true) { // Read packets here and transport them to their appropiate places VarInt length = stream.ReadVarInt(); MemoryStream ms = new MemoryStream(stream.ReadByteArray((int)length.Value)); Protocol.Receive(client, new GameStream(ms)); } } } }); tmpThread.Start(); } } catch (Exception e) { Logger.Write("Error!"); Logger.Write(e.ToString()); } }
public static void ReceiveHandshake(Player client, GameStream stream) { VarInt protocolVersion = stream.ReadVarInt(); string serverAddress = stream.ReadString(); ushort port = stream.ReadShort(); VarInt next = stream.ReadVarInt(); if (!CheckHandshakeInfo(protocolVersion, serverAddress, port, next)) { return; } switch ((int)next.Value) { case 1: // Status client.State = SessionState.Status; StatusPackets.SendStatus(client, stream); break; case 2: // Login client.State = SessionState.Login; break; } }