コード例 #1
0
ファイル: MinecraftServer.cs プロジェクト: Zynx87/Craft.Net
 /// <summary>
 /// Adds a worldBlockChangedr's list of worlds.
 /// </summary>
 public void AddLevel(Level level)
 {
     level.World.BlockChanged += HandleOnBlockChanged;
     level.World.SpawnEntity  += (sender, args) =>
                                 EntityManager.SpawnEntity(sender as World, args.Entity);
     level.World.DestroyEntity += (sender, args) =>
                                  EntityManager.DespawnEntity(sender as World, args.Entity);
     WeatherManagers.Add(new WeatherManager(level.World, this));
     Levels.Add(level);
 }
コード例 #2
0
ファイル: MinecraftServer.cs プロジェクト: Zynx87/Craft.Net
        private void NetworkWorker()
        {
            while (true) // TODO: Consider refactoring
            {
                lock (NetworkLock)
                {
                    for (int i = 0; i < Clients.Count; i++)
                    {
                        var client = Clients[i];
                        if (client.IsLoggedIn)
                        {
                            DoClientUpdates(client);
                        }
                        bool disconnect = false;
                        while (client.SendQueue.Count != 0)
                        {
                            IPacket packet;
                            if (client.SendQueue.TryDequeue(out packet))
                            {
                                try
                                {
                                    packet.WritePacket(client.Stream);
#if DEBUG
                                    LogProvider.Log(packet, false);
#endif
                                    client.Stream.Flush();
                                }
                                catch
                                {
                                    // TODO: Consider more detail
                                    disconnect = true;
                                    break;
                                }
                                if (packet is DisconnectPacket)
                                {
                                    disconnect = true;
                                    break;
                                }
                                if (packet is EncryptionKeyResponsePacket)
                                {
                                    // Set up crypto stream
#if DEBUG
                                    LogProvider.Log("Encryption enabled with " + client.Username, LogImportance.Low);
#endif
                                    client.Stream            = new MinecraftStream(new BufferedStream(new AesStream(client.NetworkStream, client.SharedKey)));
                                    client.EncryptionEnabled = true;
                                }
                            }
                        }
                        if (disconnect)
                        {
                            Clients.Remove(client);
                            i--;
                            EntityManager.DespawnEntity(client.Entity);
                            if (client.IsLoggedIn)
                            {
                                OnPlayerLoggedOut(new PlayerLogInEventArgs(client));
                            }
                            continue;
                        }
                        // Each client has a maximum of 10 milliseconds per iteration for reads
                        DateTime readTimeout = DateTime.Now.AddMilliseconds(10);
                        while (client.NetworkStream.DataAvailable && DateTime.Now < readTimeout)
                        {
                            try
                            {
                                var packet = PacketReader.ReadPacket(client.Stream);
#if DEBUG
                                LogProvider.Log(packet, true);
#endif
                                if (packet is DisconnectPacket) // TODO: Should we have a disconnect packet handler?
                                {
                                    Clients.Remove(client);
                                    i--;
                                    EntityManager.DespawnEntity(client.Entity);
                                    if (client.IsLoggedIn)
                                    {
                                        OnPlayerLoggedOut(new PlayerLogInEventArgs(client));
                                    }
                                    continue;
                                }
                                HandlePacket(client, packet);
                                if (client.DisconnectPending)
                                {
                                    break;
                                }
                            }
                            catch (InvalidOperationException e)
                            {
                                new DisconnectPacket(e.Message).WritePacket(client.Stream);
                                client.Stream.Flush();
                                Clients.Remove(client);
                                i--;
                                EntityManager.DespawnEntity(client.Entity);
                                if (client.IsLoggedIn)
                                {
                                    OnPlayerLoggedOut(new PlayerLogInEventArgs(client));
                                }
                            }
                            catch (SocketException e)
                            {
                                Clients.Remove(client);
                                i--;
                                EntityManager.DespawnEntity(client.Entity);
                                if (client.IsLoggedIn)
                                {
                                    OnPlayerLoggedOut(new PlayerLogInEventArgs(client));
                                }
                            }
                            catch (Exception e)
                            {
                                new DisconnectPacket("A network exception occured: " + e.GetType().Name).WritePacket(client.Stream);
                                client.Stream.Flush();
                                Clients.Remove(client);
                                i--;
                                EntityManager.DespawnEntity(client.Entity);
                                if (client.IsLoggedIn)
                                {
                                    OnPlayerLoggedOut(new PlayerLogInEventArgs(client));
                                }
                            }
                        }
                    }
                }
                if (DefaultLevel.Time % 5 == 0)
                {
                    foreach (var level in Levels)
                    {
                        level.World.DoScheduledUpdates();
                    }
                }
                Thread.Sleep(1);
            }
        }