コード例 #1
0
        void NotifyEntities(Server server, int clientid, float dt)
        {
            ClientOnServer c = server.clients[clientid];

            c.notifyEntitiesAccum += dt;
            if (c.notifyEntitiesAccum < (one / EntityPositionUpdatesPerSecond))
            {
                return;
            }
            c.notifyEntitiesAccum = 0;

            // find nearest entities
            int max = SpawnMaxEntities;

            ServerEntityId[] nearestEntities = new ServerEntityId[max];
            FindNearEntities(server, c, max, nearestEntities);

            // update entities
            for (int i = 0; i < max; i++)
            {
                ServerEntityId e = nearestEntities[i];
                if (e == null)
                {
                    continue;
                }
                for (int k = 0; k < server.modEventHandlers.onentityupdate.Count; k++)
                {
                    server.modEventHandlers.onentityupdate[k](e);
                }
            }

            // despawn old entities
            for (int i = 0; i < c.spawnedEntitiesCount; i++)
            {
                ServerEntityId e = c.spawnedEntities[i];
                if (e == null)
                {
                    continue;
                }
                if (!Contains(nearestEntities, max, e))
                {
                    int onClientId = i;
                    c.spawnedEntities[onClientId] = null;
                    server.SendPacket(clientid, ServerPackets.EntityDespawn(64 + onClientId));
                }
            }

            // spawn new entities
            for (int i = 0; i < max; i++)
            {
                ServerEntityId e = nearestEntities[i];
                if (e == null)
                {
                    continue;
                }
                if (!Contains(c.spawnedEntities, max, e))
                {
                    int onClientId = IndexOfNull(c.spawnedEntities, c.spawnedEntitiesCount);
                    c.spawnedEntities[onClientId] = e.Clone();
                    ServerChunk         chunk = server.d_Map.GetChunk(e.chunkx * Server.chunksize, e.chunky * Server.chunksize, e.chunkz * Server.chunksize);
                    ServerEntity        ee    = chunk.Entities[e.id];
                    Packet_ServerEntity ne    = ToNetworkEntity(server.serverPlatform, ee);
                    server.SendPacket(clientid, ServerPackets.EntitySpawn(64 + onClientId, ne));
                }
            }

            for (int i = 0; i < max; i++)
            {
                if (c.updateEntity[i])
                {
                    c.updateEntity[i] = false;
                    ServerEntityId      e     = c.spawnedEntities[i];
                    ServerChunk         chunk = server.d_Map.GetChunk(e.chunkx * Server.chunksize, e.chunky * Server.chunksize, e.chunkz * Server.chunksize);
                    ServerEntity        ee    = chunk.Entities[e.id];
                    Packet_ServerEntity ne    = ToNetworkEntity(server.serverPlatform, ee);
                    server.SendPacket(clientid, ServerPackets.EntitySpawn(64 + i, ne));
                }
            }
        }
コード例 #2
0
        void FindNearEntities(Server server, ClientOnServer c, int maxCount, ServerEntityId[] ret)
        {
            List <ServerEntityId> list = new List <ServerEntityId>();
            int playerx = c.PositionMul32GlX / 32;
            int playery = c.PositionMul32GlZ / 32;
            int playerz = c.PositionMul32GlY / 32;

            // Find all entities in 3x3x3 chunks around player.
            for (int xx = -1; xx < 2; xx++)
            {
                for (int yy = -1; yy < 2; yy++)
                {
                    for (int zz = -1; zz < 2; zz++)
                    {
                        int chunkx = playerx / Server.chunksize + xx;
                        int chunky = playery / Server.chunksize + yy;
                        int chunkz = playerz / Server.chunksize + zz;
                        if (!MapUtil.IsValidChunkPos(server.d_Map, chunkx, chunky, chunkz, Server.chunksize))
                        {
                            continue;
                        }
                        ServerChunk chunk = server.d_Map.GetChunk(chunkx * Server.chunksize, chunky * Server.chunksize, chunkz * Server.chunksize);
                        if (chunk == null)
                        {
                            continue;
                        }
                        if (chunk.Entities == null)
                        {
                            continue;
                        }
                        for (int i = 0; i < chunk.EntitiesCount; i++)
                        {
                            if (chunk.Entities[i] == null)
                            {
                                continue;
                            }
                            if (chunk.Entities[i].position == null)
                            {
                                continue;
                            }
                            ServerEntityId id = new ServerEntityId(chunkx, chunky, chunkz, i);
                            list.Add(id);
                        }
                    }
                }
            }
            // Return maxCount of entities nearest to player.

            list.Sort((a, b) =>
            {
                var entityA = server.d_Map.GetChunk(a.chunkx * Server.chunksize, a.chunky * Server.chunksize, a.chunkz * Server.chunksize).Entities[a.id];
                var entityB = server.d_Map.GetChunk(b.chunkx * Server.chunksize, b.chunky * Server.chunksize, b.chunkz * Server.chunksize).Entities[b.id];

                Vector3i posA      = new Vector3i((int)entityA.position.x, (int)entityA.position.y, (int)entityA.position.z);
                Vector3i posB      = new Vector3i((int)entityB.position.x, (int)entityB.position.y, (int)entityB.position.z);
                Vector3i posPlayer = new Vector3i(c.PositionMul32GlX / 32, c.PositionMul32GlY / 32, c.PositionMul32GlZ / 32);
                return(server.DistanceSquared(posA, posPlayer).CompareTo(server.DistanceSquared(posB, posPlayer)));
            }
                      );

            int retCount = maxCount;

            if (list.Count < maxCount)
            {
                retCount = list.Count;
            }
            for (int i = 0; i < retCount; i++)
            {
                ret[i] = list[i];
            }
        }
コード例 #3
0
        public void SendChunk(Server server, int clientid, Vector3i globalpos, Vector3i chunkpos)
        {
            ClientOnServer c     = server.clients[clientid];
            ServerChunk    chunk = server.d_Map.GetChunk(globalpos.x, globalpos.y, globalpos.z);

            server.ClientSeenChunkSet(clientid, chunkpos.x, chunkpos.y, chunkpos.z, (int)server.simulationcurrentframe);
            //sent++;
            byte[] compressedchunk;
            if (MapUtil.IsSolidChunk(chunk.data) && chunk.data[0] == 0)
            {
                //don't send empty chunk.
                compressedchunk = null;
            }
            else
            {
                compressedchunk = server.CompressChunkNetwork(chunk.data);
                //TODO: commented because it was being sent too early, before full column was generated.
                //if (!c.heightmapchunksseen.ContainsKey(new Vector2i(v.x, v.y)))
                {
                    byte[] heightmapchunk           = Misc.UshortArrayToByteArray(server.d_Map.GetHeightmapChunk(globalpos.x, globalpos.y));
                    byte[] compressedHeightmapChunk = server.d_NetworkCompression.Compress(heightmapchunk);
                    Packet_ServerHeightmapChunk p1  = new Packet_ServerHeightmapChunk()
                    {
                        X     = globalpos.x,
                        Y     = globalpos.y,
                        SizeX = Server.chunksize,
                        SizeY = Server.chunksize,
                        CompressedHeightmap = compressedHeightmapChunk,
                    };
                    server.SendPacket(clientid, server.Serialize(new Packet_Server()
                    {
                        Id             = Packet_ServerIdEnum.HeightmapChunk,
                        HeightmapChunk = p1
                    }));
                    c.heightmapchunksseen[new Vector2i(globalpos.x, globalpos.y)] = (int)server.simulationcurrentframe;
                }
            }
            if (compressedchunk != null)
            {
                foreach (byte[] part in Server.Parts(compressedchunk, 1024))
                {
                    Packet_ServerChunkPart p1 = new Packet_ServerChunkPart()
                    {
                        CompressedChunkPart = part,
                    };
                    server.SendPacket(clientid, server.Serialize(new Packet_Server()
                    {
                        Id        = Packet_ServerIdEnum.ChunkPart,
                        ChunkPart = p1
                    }));
                }
            }
            Packet_ServerChunk p = new Packet_ServerChunk()
            {
                X     = globalpos.x,
                Y     = globalpos.y,
                Z     = globalpos.z,
                SizeX = Server.chunksize,
                SizeY = Server.chunksize,
                SizeZ = Server.chunksize,
            };

            server.SendPacket(clientid, server.Serialize(new Packet_Server()
            {
                Id     = Packet_ServerIdEnum.Chunk_,
                Chunk_ = p
            }));
        }