Example #1
0
        private void InitiateVariables()
        {
            Console.Title = Globals.ProtocolName;

            Globals.LevelManager = new LevelManager(LoadLevel());
            Globals.LevelManager.AddLevel("nether", new NetherLevel("nether"));
            Globals.ChatManager    = new ChatManager();
            Globals.ServerKey      = PacketCryptography.GenerateKeyPair();
            Globals.ClientManager  = new ClientManager();
            Globals.MessageFactory = new MessageFactory();
            Globals.ServerListener = new ClientListener();
        }
Example #2
0
        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();
        }
Example #3
0
        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();
        }
Example #4
0
        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();
            }
        }