Esempio n. 1
0
        private void ReceivedMessageTcpBytes(PacketHeader header, ConnectionTcp connection, byte[] message)
        {
            HandledTask task = new HandledTask(() =>
            {
                _Clients[connection].ProcessCompressedMessage(ref message);
            });

            task.Start();
        }
Esempio n. 2
0
      /// <summary>
      /// Runs any postprocessing that is needed after server loads new areas.
      /// </summary>
      /// <param name="loadRequest">Load request instance</param>
      /// <param name="areas">New areas</param>
      /// <param name="segments">New segments</param>
      protected override void OnAreasLoaded(LoadRequest loadRequest, List<ServerArea> areas, List<ServerSegment> segments)
      {
         if (loadRequest.MessageId < 0 || loadRequest.Entity == null)
         {
            return;
         }

         // the newly loaded areas/segments aren't usable as they could have been
         // covered by other players' terrain
         areas.Clear();
         segments.Clear();

         // construct player's area keys
         List<int> areaKeys = new List<int>();
         foreach (Tuple<int, int> column in GetEntityColumns(loadRequest.ColumnX, loadRequest.ColumnZ))
         {
            for (int y = 0; y < 256; y += 64)
            {
               areaKeys.Add(Area.GenerateKey(column.Item1, y, column.Item2));
            }
         }

         // retrieve player connection
         Connection connection = ServerManager.Instance.GetPlayerConnection(loadRequest.Entity.ID);
         if (connection == null)
         {
            // no longer online
            return;
         }

         // process terrain response in a synced and handled task
         HandledTask task = new HandledTask(() =>
         {
            // compare the new keys with current ones
            List<int> currentKeys = new List<int>();
            lock (_ClientLock)
            {
               currentKeys = _ClientAreas[loadRequest.Entity.ID];
            }

            lock (CollectionsLock)
            {
               foreach (int key in areaKeys.Where(a => !currentKeys.Contains(a)))
               {
                  areas.Add(Areas[key]);
               }
            }

            lock (_ClientLock)
            {
               _ClientAreas[loadRequest.Entity.ID] = areaKeys;
            }

            if (areas.Count == 0)
            {
               // there is actually nothing to send
               ServerManager.Instance.ServerToClientProvider.TerrainDataResponse(connection, loadRequest.MessageId, new List<ServerArea>(), (byte)0, (byte)0);
            }
            else
            {
               // send the terrain data to the requesting client
               int batchSize = Configuration.Network.MaxTerrainBatchSize;
               byte current = 1;
               byte total = (byte)Math.Ceiling((float)areas.Count / (float)batchSize);
               for (int i = 0; i < areas.Count; i += batchSize)
               {
                  List<ServerArea> partial = areas.Skip(i).Take(batchSize).ToList();
                  ServerManager.Instance.ServerToClientProvider.TerrainDataResponse(connection, loadRequest.MessageId, partial, current, total);
                  current++;
               }
            }
         });
         task.Start();
      }