public async Task DispatchPacket(LoginStart packet) { if (_useAuthentication) { throw new NotImplementedException(); } else { var user = await GrainFactory.GetGrain <INonAuthenticatedUser>(packet.Name).GetUser(); if (await user.GetProtocolVersion() > MineCase.Protocol.Protocol.Version) { await SendLoginDisconnect("{\"text\":\"Outdated server!I'm still on 1.12\"}"); } else if (await user.GetProtocolVersion() < MineCase.Protocol.Protocol.Version) { await SendLoginDisconnect("{\"text\":\"Outdated client!Please use 1.12\"}"); } else { var uuid = user.GetPrimaryKey(); await SendLoginSuccess(packet.Name, uuid); await user.SetClientPacketSink(GrainFactory.GetGrain <IClientboundPacketSink>(this.GetPrimaryKey())); await GrainFactory.GetGrain <IPacketRouter>(this.GetPrimaryKey()).BindToUser(user); var world = await user.GetWorld(); var game = GrainFactory.GetGrain <IGameSession>(world.GetPrimaryKeyString()); await game.JoinGame(user); } } }
private Task DispatchLoginPackets(UncompressedPacket packet) { var br = new SpanReader(packet.Data); Task task; switch (packet.PacketId) { // Login Start case 0x00: task = DispatchPacket(LoginStart.Deserialize(ref br)); break; // Encryption Response case 0x01: task = DispatchPacket(EncryptionResponse.Deserialize(ref br)); break; default: throw new InvalidDataException($"Unrecognizable packet id: 0x{packet.PacketId:X2}."); } if (!br.IsCosumed) { throw new InvalidDataException($"Packet data is not fully consumed."); } return(task); }
private async Task DispatchPacket(LoginStart packet) { _userName = packet.Name; var user = GrainFactory.GetGrain <INonAuthenticatedUser>(packet.Name); await user.SetProtocolVersion(_protocolVersion); var requestGrain = GrainFactory.GetGrain <ILoginFlow>(this.GetPrimaryKey()); requestGrain.DispatchPacket(packet).Ignore(); }
public static void Invoke(ClientConnection client) { client.RegisterPacketHandler(typeof(StatusResponse), (connection, packet) => { Debug.Log("Handler"); var login = new LoginStart(connection.Session.SelectedProfile.Name); connection.SendPacket(login); }); client.RegisterPacketHandler(typeof(KeepAlive), (connection, packet) => { if (packet is KeepAlive sender) { Debug.Log("Bip bop"); connection.SendPacket(sender); } }); }
public void Connect(string address, int port) { Connection = new TcpClient(); Connection.Connect(address, port); NetworkStream = Connection.GetStream(); NetworkManager = new NetworkManager(NetworkStream); NetworkingReset = new ManualResetEvent(true); NetworkWorkerThread = new Thread(NetworkWorker); NetworkWorkerThread.Start(); var handshake = new Handshaking(NetworkManager.Protocol, address, (ushort)port, NetworkState.Login); SendPacket(handshake); //var queue = new StatusRequest(); //SendPacket(queue); var login = new LoginStart(Session.SelectedProfile.Name); SendPacket(login); Debug.Log("Hello"); }
private object DeserializeLoginPacket(UncompressedPacket packet) { var br = new SpanReader(packet.Data); object innerPacket; switch (packet.PacketId) { // Login Start case 0x00: innerPacket = LoginStart.Deserialize(ref br); break; default: throw new InvalidDataException($"Unrecognizable packet id: 0x{packet.PacketId:X2}."); } if (!br.IsCosumed) { throw new InvalidDataException($"Packet data is not fully consumed."); } return(innerPacket); }
private object DeserializeLoginPacket(ref UncompressedPacket packet) { using (var br = new BinaryReader(new MemoryStream(packet.Data))) { object innerPacket; switch (packet.PacketId) { // Login Start case 0x00: innerPacket = LoginStart.Deserialize(br); break; default: throw new InvalidDataException($"Unrecognizable packet id: 0x{packet.PacketId:X}."); } if (br.BaseStream.Position != br.BaseStream.Length) { throw new InvalidDataException($"Packet data is not fully consumed."); } return(innerPacket); } }
public async Task DispatchPacket(LoginStart packet) { var settingsGrain = GrainFactory.GetGrain <IServerSettings>(0); var settings = await settingsGrain.GetSettings(); if (settings.OnlineMode) { // TODO auth and compression var user = GrainFactory.GetGrain <INonAuthenticatedUser>(packet.Name); if (await user.GetProtocolVersion() > MineCase.Protocol.Protocol.Version) { await SendLoginDisconnect($"{{\"text\":\"Outdated server!I'm still on {Protocol.Protocol.VersionName}\"}}"); } else if (await user.GetProtocolVersion() < MineCase.Protocol.Protocol.Version) { await SendLoginDisconnect($"{{\"text\":\"Outdated client!Please use {Protocol.Protocol.VersionName}\"}}"); } else { RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); Random verifyRandom = new Random(); Byte[] verifyToken = new byte[64]; verifyRandom.NextBytes(verifyToken); var keys = rsa.ExportParameters(false); await SendEncryptionRequest("", keys.Exponent, verifyToken); } } else { var nonAuthenticatedUser = GrainFactory.GetGrain <INonAuthenticatedUser>(packet.Name); if (await nonAuthenticatedUser.GetProtocolVersion() > MineCase.Protocol.Protocol.Version) { await SendLoginDisconnect($"{{\"text\":\"Outdated server!I'm still on {Protocol.Protocol.VersionName}\"}}"); } else if (await nonAuthenticatedUser.GetProtocolVersion() < MineCase.Protocol.Protocol.Version) { await SendLoginDisconnect($"{{\"text\":\"Outdated client!Please use {Protocol.Protocol.VersionName}\"}}"); } else { // TODO refuse him if server is full var user = await nonAuthenticatedUser.GetUser(); var world = await user.GetWorld(); var gameSession = GrainFactory.GetGrain <IGameSession>(world.GetPrimaryKeyString()); await SendSetCompression(); var uuid = user.GetPrimaryKey(); await SendLoginSuccess(packet.Name, uuid); await user.SetClientPacketSink(GrainFactory.GetGrain <IClientboundPacketSink>(this.GetPrimaryKey())); var packetRouter = GrainFactory.GetGrain <IPacketRouter>(this.GetPrimaryKey()); await user.SetPacketRouter(packetRouter); await packetRouter.BindToUser(user); var game = GrainFactory.GetGrain <IGameSession>(world.GetPrimaryKeyString()); await game.JoinGame(user); } } }
/// <summary> /// Return false if disconnect/finished /// </summary> void RunClientHandshake() { clientThread.WatchdogTick = DateTime.Now; //Read Handshake var hs = PacketReader.ReadFirstPackage(clientStream); if (hs == null) { //Old status packet LegacyStatus.SendStatus(clientStream); Phase = Phases.FinalClose; return; } var h = new Handshake(hs); Debug.FromClient(this, h); clientThread.State = "Handshake Received " + h; ClientVersion = h.Version; if (h.State == HandshakeState.Status) { RunStatusPing(h); return; } if (h.State == HandshakeState.None) { Close("Invalid handshake state: " + h.State); return; } if (h.State != HandshakeState.Login) { Close("Invalid handshake state: " + h.State); return; } #if DEBUG if (h.Version >= ProtocolVersion.next) { throw new InvalidDataException("new version: " + h.Version); } #endif if (h.Version > MinecraftServer.BackendVersion) { clientThread.State = "Handshake too high version"; Close("We are still running " + MinecraftServer.BackendVersion.ToText() + " we are so very sorry about that"); return; } if (h.Version < MinecraftServer.FrontendVersion) { clientThread.State = "Handshake too low version"; Close("Upgrade your client to " + MinecraftServer.FrontendVersion.ToText()); return; } //Login var l = new LoginStart(PacketReader.ReadHandshake(clientStream)); clientThread.State = "LoginStart Received " + l.Name; unverifiedUsername = l.Name; #if DEBUGx var names = new string[] { "travelcraft2012", "nuxas", "drjanitor" }; unverifiedUsername = names[logincount++ % names.Length]; #endif if (unverifiedUsername.Length == 0 || unverifiedUsername.Length > 16) { clientThread.State = "Handshake wrong username length"; Close("Bad username"); Console.WriteLine("Wrong username length: " + unverifiedUsername.Length); return; } //Set Compression var compression = new SetCompression(); SendToClientInternal(compression); maxUncompressed = compression.MaxSize; //Send encryption request clientThread.State = "Handshake: Sending encryption request"; //Initiate ID var r = new Random(); ID = new byte[8]; r.NextBytes(ID); SendToClientInternal(new EncryptionRequest(Authentication.McHex(ID), MinecraftServer.RsaBytes)); clientThread.State = "Handshake: Sent encryption request, reading response"; //Read enc response int erSize; var erBuffer = PacketReader.Read(clientStream, out erSize); if (erSize != 0) { erBuffer = Compression.Decompress(erBuffer, erSize); } var er = new EncryptionResponse(erBuffer); clientThread.State = "Handshake: Got enc resp"; CryptoMC cryptoStream = new CryptoMC(clientStream, er); //Verify user clientThread.WatchdogTick = DateTime.Now; clientThread.State = "Handshake: loading proxy data"; Settings = LoadProxyPlayer(unverifiedUsername); if (IPAddress.IsLoopback(RemoteEndPoint.Address)) { MinecraftUsername = unverifiedUsername; Log.WritePlayer(this, "Succesful login from (local) " + RemoteEndPoint); } else { clientThread.State = "Handshake: Verifying login credentials"; string error = Authentication.VerifyUserLogin(unverifiedUsername, cryptoStream.SharedKey, ID); if (error != null) { //Unauthorized Log.WriteAuthFail(unverifiedUsername, RemoteEndPoint, error); Close("Mojang says " + error); return; } else { MinecraftUsername = unverifiedUsername; Log.WritePlayer(this, "Login from " + RemoteEndPoint + " " + Country); } } clientThread.State = "Handshake: Logged in"; //Get UUID try { Settings.UUID = UsernameUUID.GetUUID(MinecraftUsername); //Saved further down Debug.WriteLine("Real UUID for " + MinecraftUsername + " is " + Settings.UUID); } catch (Exception) { Debug.WriteLine("Failed to get UUID for MinecraftName " + MinecraftUsername); } clientThread.WatchdogTick = DateTime.Now; MineProxy.Inbox.Status(this); //start encryption clientStream = cryptoStream; SendToClientInternal(new LoginSuccess(Settings.UUID, MinecraftUsername)); clientThread.User = MinecraftUsername; clientThread.State = "Logged in"; EntityID = freeEID; //Math.Abs(unverifiedUsername.GetHashCode()); freeEID += 5000; //Login reply to client JoinGame lr = new JoinGame(); lr.ClientVersion = 0; lr.Difficulty = 0; lr.Dimension = 0; lr.EntityID = EntityID; lr.MaxPlayers = (byte)MinecraftServer.PlayerListSlots; lr.GameMode = 0; SendToClient(lr); Phase = Phases.Gaming; Queue = new SendQueue(this); PlayerList.LoginPlayer(this); SaveProxyPlayer(); string name = h.Host.ToLowerInvariant().Split('.')[0]; if (name == "con") { SetWorld(World.Construct); } else { SetWorld(World.Main); } //Handshake complete }
private void btnLogin_Click(object sender, EventArgs e) { LoginStart?.Invoke(sender, e); }
/// <summary> /// Return false if disconnect/finished /// </summary> void RunClientHandshake() { clientThread.WatchdogTick = DateTime.Now; //Read Handshake var hs = PacketReader.ReadFirstPackage(clientStream); if (hs == null) { //Old status packet LegacyStatus.SendStatus(clientStream); Phase = Phases.FinalClose; return; } var h = new Handshake(hs); Debug.FromClient(this, h); clientThread.State = "Handshake Received " + h; ClientVersion = h.Version; if (h.State == HandshakeState.Status) { RunStatusPing(h); return; } if (h.State == HandshakeState.None) { Close("Invalid handshake state: " + h.State); return; } if (h.State != HandshakeState.Login) { Close("Invalid handshake state: " + h.State); return; } #if DEBUG if (h.Version >= ProtocolVersion.next) { throw new InvalidDataException("new version: " + h.Version); } #endif if (h.Version > MinecraftServer.BackendVersion) { clientThread.State = "Handshake too high version"; Close("We are still running " + MinecraftServer.BackendVersion.ToText() + " we are so very sorry about that"); return; } if (h.Version < MinecraftServer.FrontendVersion) { clientThread.State = "Handshake too low version"; Close("Upgrade your client to " + MinecraftServer.FrontendVersion.ToText()); return; } clientThread.WatchdogTick = DateTime.Now; //Login var l = new LoginStart(PacketReader.ReadHandshake(clientStream)); Debug.FromClient(this, l); clientThread.State = "LoginStart Received " + l.Name; unverifiedUsername = l.Name; if (unverifiedUsername.Length == 0 || unverifiedUsername.Length > 16) { clientThread.State = "Handshake wrong username length"; Close("Bad username"); Console.WriteLine("Wrong username length: " + unverifiedUsername.Length); return; } //Set Compression var compression = new SetCompression(); SendToClientInternal(compression); maxUncompressed = compression.MaxSize; //Send encryption request clientThread.State = "Handshake: Sending encryption request"; //Initiate ID var r = new Random(); ID = new byte[8]; r.NextBytes(ID); SendToClientInternal(new EncryptionRequest(Authentication.McHex(ID), MinecraftServer.RsaBytes)); clientThread.State = "Handshake: Sent encryption request, reading response"; //Read enc response int erSize; var erBuffer = PacketReader.Read(clientStream, out erSize); if (erSize != 0) { erBuffer = Compression.Decompress(erBuffer, erSize); } var er = new EncryptionResponse(erBuffer); Debug.FromClient(this, er); clientThread.State = "Handshake: Got enc resp"; CryptoMC cryptoStream = new CryptoMC(clientStream, er); //Verify user clientThread.State = "Handshake: loading proxy data"; Settings = LoadProxyPlayer(unverifiedUsername); clientThread.State = "Handshake: Verifying login credentials"; var auth = Authentication.VerifyUserLogin(unverifiedUsername, cryptoStream.SharedKey, ID); #warning From here we now need to take care of the id in the response. if (auth == null) { //Unauthorized Log.WriteAuthFail(unverifiedUsername, RemoteEndPoint, ""); Close("Mojang says no"); return; } else { MinecraftUsername = unverifiedUsername; Log.WritePlayer(this, "Login from " + RemoteEndPoint + " " + Country); } clientThread.State = "Handshake: Logged in"; //Get UUID Settings.UUID = auth.id; clientThread.WatchdogTick = DateTime.Now; MineProxy.Inbox.Status(this); //start encryption clientStream = cryptoStream; SendToClientInternal(new LoginSuccess(Settings.UUID, MinecraftUsername)); clientThread.User = MinecraftUsername; clientThread.State = "Logged in"; EntityID = freeEID; //Math.Abs(unverifiedUsername.GetHashCode()); freeEID += 5000; //Login reply to client //No longer, send the vanilla server Login reply instead. Phase = Phases.Gaming; Queue = new SendQueue(this); PlayerList.LoginPlayer(this); SaveProxyPlayer(); string name = h.Host.ToLowerInvariant().Split('.')[0]; if (World.VanillaWorlds.ContainsKey(name)) { SetWorld(World.VanillaWorlds[name]); } else { SetWorld(World.Main); } //Handshake complete }
public virtual void OnLoginStart(LoginStart packet) { }
private void InvokeLoginStart(LoginStart packet) { packetListener.OnLoginStart(packet); }