private void InitiateVariables() { Globals.Rand = new Random(); Console.Title = Globals.ProtocolName; ServerSettings.Debug = Config.GetProperty("debug", false); ServerSettings.DisplayPacketErrors = Config.GetProperty("ShowNetworkErrors", false); #if DEBUG ServerSettings.Debug = true; #endif ServerSettings.MaxPlayers = Config.GetProperty("MaxPlayers", 10); ServerSettings.Seed = Config.GetProperty("Seed", "SharpMC"); ServerSettings.Motd = Config.GetProperty("motd", "A SharpMC Powered Server"); Globals.LevelManager = new LevelManager(LoadLevel()); Globals.LevelManager.AddLevel("nether", new NetherLevel("nether")); ServerSettings.OnlineMode = Config.GetProperty("Online-mode", false); Globals.ChatHandler = new Synchronized <ChatHandler>(new ChatHandler()); Globals.ServerKey = PacketCryptography.GenerateKeyPair(); Globals.ClientManager = new ClientManager(); Globals.ConsolePlayer = new Player(Globals.LevelManager.MainLevel) { Username = "******", Wrapper = new ClientWrapper(null), Uuid = Guid.NewGuid().ToString(), Gamemode = Gamemode.Spectator, }; Globals.ConsolePlayer.Wrapper.Player = Globals.ConsolePlayer; Globals.ConsolePlayer.IsOperator = true; Globals.MessageFactory = new MessageFactory(); Globals.PluginManager = new PluginManager(); Globals.ServerListener = new BasicListener(); OperatorLoader.LoadOperators(); }
private void HandleLogin(int protocol) { if (Buffer != null) { var usernameRaw = Buffer.ReadString(); var username = new string(usernameRaw.Where(c => char.IsLetter(c) || char.IsPunctuation(c) || char.IsDigit(c)).ToArray()); //username = Regex.Replace(username, @"[^\u0000-\u007F]", string.Empty); var uuid = getUUID(username); if (!Globals.Offlinemode) { if (Globals.EncryptionEnabled) { Client.PacketMode = PacketMode.Login; Client.Username = username; new EncryptionRequest(Client) { PublicKey = PacketCryptography.PublicKeyToAsn1(Globals.ServerKey), VerificationToken = PacketCryptography.GetRandomToken() }.Write(); return; } if (!Client.Player.IsAuthenticated()) { new LoginSucces(Client) { Username = username, UUID = uuid }.Write(); new Disconnect(Client) { Reason = "§4SharpMC\n§fAuthentication failed!" }.Write(); return; } } new LoginSucces(Client) { Username = username, UUID = uuid }.Write(); if (Encoding.UTF8.GetBytes(username).Length == 0) { new Disconnect(Client) { Reason = "§4SharpMC\n§fSomething went wrong while decoding your username!" }.Write(); return; } //Protocol check! if (protocol < Globals.ProtocolVersion) //Protocol to old? { new Disconnect(Client) { Reason = "§4SharpMC\n§fYour Minecraft version is to old!\nPlease update in order to play!" } .Write(); return; } if (protocol > Globals.ProtocolVersion) //Protocol to new? { new Disconnect(Client) { Reason = "§4SharpMC\n§fThis server is not yet updated for your version of Minecraft!\nIn order to play you have to use " + Globals.MCProtocolName }.Write(); return; } Client.Player = new Player(Globals.LevelManager.MainLevel) { Uuid = uuid, Username = username, Wrapper = Client, Gamemode = Globals.LevelManager.MainLevel.DefaultGamemode }; Client.PacketMode = PacketMode.Play; new SetCompression(Client).Write(); new JoinGame(Client) { Player = Client.Player }.Write(); new SpawnPosition(Client).Write(); Client.StartKeepAliveTimer(); Client.Player.InitializePlayer(); } }
public override void Read() { if (Buffer == null) { return; } var usernameRaw = Buffer.ReadString(); var username = new string(usernameRaw.Where(c => char.IsLetter(c) || char.IsPunctuation(c) || char.IsDigit(c)).ToArray()); var uuid = GetUuid(username); if (Core.Server.ServerSettings.OnlineMode) { if (Core.Server.ServerSettings.EncryptionEnabled) { Client.PacketMode = PacketMode.Login; Client.Username = username; new EncryptionRequest(Client) { PublicKey = PacketCryptography.PublicKeyToAsn1(Globals.ServerKey), VerificationToken = PacketCryptography.GetRandomToken() }.Write(); return; } if (!Client.Player.IsAuthenticated()) { new Disconnect(Client) { Reason = new ChatText("Authentication failed!", TextColor.Reset) }.Write(); return; } } if (Encoding.UTF8.GetBytes(username).Length == 0) { new Disconnect(Client) { Reason = new ChatText("Something went wrong while decoding your username!", TextColor.Reset) }.Write(); return; } //Protocol check! if (Client.Protocol < Globals.ProtocolVersion) //Protocol to old? { new Disconnect(Client) { Reason = new ChatText("Your Minecraft version is too old!\nPlease update in order to play!", TextColor.Reset) } .Write(); return; } if (Client.Protocol > Globals.ProtocolVersion) //Protocol to new? { new Disconnect(Client) { Reason = new ChatText("This server is not yet updated for your version of Minecraft!\nIn order to play you have to use " + Globals.OfficialProtocolName, TextColor.Reset) }.Write(); return; } new LoginSucces(Client) { Username = username, Uuid = uuid }.Write(); Client.Player = new Player(Globals.LevelManager.MainLevel) { Uuid = uuid, Username = username, Wrapper = Client, Gamemode = Globals.LevelManager.MainLevel.DefaultGamemode }; Client.PacketMode = PacketMode.Play; new SetCompression(Client) { CompressionLevel = Core.Server.ServerSettings.UseCompression ? Core.Server.ServerSettings.CompressionThreshold : -1 }.Write(); new JoinGame(Client) { Player = Client.Player }.Write(); new SpawnPosition(Client).Write(); Client.Player.InitializePlayer(); }
public override void Read() { if (Buffer != null) { var length = Buffer.ReadVarInt(); var sharedsecret = Buffer.Read(length); length = Buffer.ReadVarInt(); var verifytoken = Buffer.Read(length); Client.SharedKey = PacketCryptography.Decrypt(sharedsecret); var recv = PacketCryptography.GenerateAES((byte[])Client.SharedKey.Clone()); var send = PacketCryptography.GenerateAES((byte[])Client.SharedKey.Clone()); var packetToken = PacketCryptography.Decrypt(verifytoken); if (!packetToken.SequenceEqual(PacketCryptography.VerifyToken)) { //Wrong token! :( ConsoleFunctions.WriteWarningLine("Wrong token!"); return; } Client.Decrypter = recv.CreateDecryptor(); Client.Encrypter = send.CreateEncryptor(); Client.EncryptionEnabled = true; Client.Player = new Player(Globals.LevelManager.MainLevel) { Uuid = getUUID(Client.Username), Username = Client.Username, Wrapper = Client, Gamemode = Globals.LevelManager.MainLevel.DefaultGamemode }; if (Client.Player.IsAuthenticated()) { new LoginSucces(Client) { Username = Client.Username, UUID = Client.Player.Uuid }.Write(); Client.PacketMode = PacketMode.Play; new SetCompression(Client).Write(); new JoinGame(Client) { Player = Client.Player }.Write(); new SpawnPosition(Client).Write(); Client.StartKeepAliveTimer(); Client.Player.SendChunksFromPosition(); } else { new LoginSucces(Client) { Username = Client.Username, UUID = Client.Player.Uuid }.Write(); new Disconnect(Client) { Reason = "Authentication failed! Try restarting your client." }.Write(); } } }
public override void Initialize(int length, Stream stream) { base.Initialize(length, stream); VerifyToken = PacketCryptography.GetRandomToken(); PublicKey = PacketCryptography.PublicKeyToAsn1(Utils.ServerKey); }
public static void Main(string[] args) { var currentDomain = AppDomain.CurrentDomain; currentDomain.UnhandledException += UnhandledException; Console.Title = Globals.ProtocolName; Config.ConfigFile = "server.properties"; Config.InitialValue = new[] { "#DO NOT REMOVE THIS LINE - SharpMC Config", "Port=25565", "MaxPlayers=10", "LevelType=standard", "WorldName=world", "Debug=false", "Seed=", "Motd=" }; Config.Check(); Console.CancelKeyPress += delegate { ConsoleFunctions.WriteInfoLine("Shutting down..."); Disconnect.Broadcast("§fServer shutting down..."); ConsoleFunctions.WriteInfoLine("Disabling plugins..."); Globals.PluginManager.DisablePlugins(); ConsoleFunctions.WriteInfoLine("Saving chunks..."); Globals.LevelManager.MainLevel.SaveChunks(); }; ConsoleFunctions.WriteInfoLine("Loading config file..."); Globals.MaxPlayers = Config.GetProperty("MaxPlayers", 10); var lvltype = Config.GetProperty("LevelType", "Experimental"); Level lvl; switch (lvltype.ToLower()) { case "flatland": lvl = new FlatLandLevel(Config.GetProperty("WorldName", "world")); break; case "standard": lvl = new StandardLevel(Config.GetProperty("WorldName", "world")); //lvl = new BetterLevel(Config.GetProperty("worldname", "world")); break; case "anvil": lvl = new AnvilLevel(Config.GetProperty("WorldName", "world")); break; default: lvl = new StandardLevel(Config.GetProperty("WorldName", "world")); break; } Globals.LevelManager = new LevelManager(lvl); Globals.LevelManager.AddLevel("nether", new NetherLevel("nether")); //Initiate the 'nether' Globals.Seed = Config.GetProperty("Seed", "SharpieCraft"); Globals.Motd = Config.GetProperty("motd", ""); Globals.Debug = Config.GetProperty("debug", false); ConsoleFunctions.WriteInfoLine("Checking files..."); if (!Directory.Exists(Globals.LevelManager.MainLevel.LvlName)) { Directory.CreateDirectory(Globals.LevelManager.MainLevel.LvlName); } ConsoleFunctions.WriteInfoLine("Setting up some variables..."); Globals.ServerKey = PacketCryptography.GenerateKeyPair(); Globals.Rand = new Random(); #if DEBUG Globals.Debug = true; #else Globals.Debug = false; #endif ConsoleFunctions.WriteInfoLine("Loading plugins..."); Globals.PluginManager = new PluginManager(); Globals.PluginManager.LoadPlugins(); ConsoleFunctions.WriteInfoLine("Enabling plugins..."); Globals.PluginManager.EnablePlugins(Globals.LevelManager); new Thread(() => new BasicListener().ListenForClients()).Start(); }
public async Task StartConnectionAsync() { while (!Cancellation.IsCancellationRequested && this.Tcp.Connected) { Packet packet = this.Compressed ? await this.GetNextCompressedPacketAsync() : await this.GetNextPacketAsync(); Packet returnPacket; if (this.State == ClientState.Play && packet.PacketData.Length < 1) { this.Disconnect(); } switch (this.State) { case ClientState.Status: //server ping/list switch (packet.PacketId) { case 0x00: var status = new ServerStatus(OriginServer); await PacketHandler.CreateAsync(new RequestResponse(status), this.MinecraftStream); break; case 0x01: await PacketHandler.CreateAsync(new PingPong(packet.PacketData), this.MinecraftStream); this.Disconnect(); break; } break; case ClientState.Handshaking: if (packet.PacketId == 0x00) { if (packet == null) { throw new InvalidOperationException(); } var handshake = await PacketHandler.CreateAsync(new Handshake(packet.PacketData)); var nextState = handshake.NextState; if (nextState != ClientState.Status && nextState != ClientState.Login) { this.Logger.LogDebug($"Client sent unexpected state ({(int)nextState}), forcing it to disconnect"); await this.DisconnectAsync(Chat.ChatMessage.Simple("you seem suspicious")); } this.State = nextState; this.Logger.LogMessage($"Handshaking with client (protocol: {handshake.Version}, server: {handshake.ServerAddress}:{handshake.ServerPort})"); } else { //Handle legacy ping stuff } break; case ClientState.Login: switch (packet.PacketId) { default: this.Logger.LogError("Client in state Login tried to send an unimplemented packet. Forcing it to disconnect."); await this.DisconnectAsync(ChatMessage.Simple("Unknown Packet Id.")); break; case 0x00: var loginStart = await PacketHandler.CreateAsync(new LoginStart(packet.PacketData)); string username = loginStart.Username; if (Config.MulitplayerDebugMode) { username = $"Player{new Random().Next(1, 999)}"; this.Logger.LogDebug($"Overriding username from {loginStart.Username} to {username}"); } this.Logger.LogDebug($"Received login request from user {loginStart.Username}"); if (this.OriginServer.CheckPlayerOnline(username)) { await this.OriginServer.Clients.FirstOrDefault(c => c.Player.Username == username).DisconnectAsync(Chat.ChatMessage.Simple("Logged in from another location")); } if (this.Config.OnlineMode) { var users = await MinecraftAPI.GetUsersAsync(new string[] { loginStart.Username }); var uid = users.FirstOrDefault(); var uuid = Guid.Parse(uid.Id); this.Player = new Player(uuid, loginStart.Username, this); PacketCryptography.GenerateKeyPair(); var pubKey = PacketCryptography.PublicKeyToAsn(); this.Token = PacketCryptography.GetRandomToken(); returnPacket = await PacketHandler.CreateAsync(new EncryptionRequest(pubKey, this.Token), this.MinecraftStream); break; } this.Player = new Player(Guid.NewGuid(), username, this); await ConnectAsync(this.Player.Uuid); break; case 0x01: var encryptionResponse = await PacketHandler.CreateAsync(new EncryptionResponse(packet.PacketData)); JoinedResponse response; this.SharedKey = PacketCryptography.Decrypt(encryptionResponse.SharedSecret); var dec2 = PacketCryptography.Decrypt(encryptionResponse.VerifyToken); var dec2Base64 = Convert.ToBase64String(dec2); var tokenBase64 = Convert.ToBase64String(this.Token); if (!dec2Base64.Equals(tokenBase64)) { await this.DisconnectAsync(Chat.ChatMessage.Simple("Invalid token..")); break; } var encodedKey = PacketCryptography.PublicKeyToAsn(); var serverId = PacketCryptography.MinecraftShaDigest(SharedKey.Concat(encodedKey).ToArray()); response = await MinecraftAPI.HasJoined(this.Player.Username, serverId); if (response is null) { this.Logger.LogWarning($"Failed to auth {this.Player.Username}"); await this.DisconnectAsync(Chat.ChatMessage.Simple("Unable to authenticate..")); break; } this.EncryptionEnabled = true; this.MinecraftStream = new AesStream(this.Tcp.GetStream(), this.SharedKey); await ConnectAsync(new Guid(response.Id)); break; case 0x02: // Login Plugin Response break; } break; case ClientState.Play: ///this.Logger.LogDebugAsync($"Received Play packet with Packet ID 0x{packet.PacketId.ToString("X")}"); await PacketHandler.HandlePlayPackets(packet, this); break; } } Logger.LogMessage($"Disconnected client"); if (this.IsPlaying) { await this.OriginServer.Events.InvokePlayerLeave(new PlayerLeaveEventArgs(this)); } this.OriginServer.Broadcast(string.Format(this.Config.LeaveMessage, this.Player.Username)); this.Player = null; if (Tcp.Connected) { this.Tcp.Close(); } }