public Entity(byte itype, double[] ipos, float[] irot) { isMob = true; id = FreeId(); type = itype; pos = ipos; rot = irot; c.Entities.Add(this); CurrentChunk = c; Entities.Add(id, this); }
public byte type = 0; //0 for player #endregion Fields #region Constructors public Entity(double[] ipos, float[] irot, Player pl) { isPlayer = true; id = FreeId(); pos = ipos; rot = irot; p = pl; c.Entities.Add(this); CurrentChunk = c; Entities.Add(id, this); }
public Entity(Items iitem, byte icount, short imeta, double[] ipos, byte[] irot2) { isItem = true; id = FreeId(); itype = iitem; count = icount; meta = imeta; pos = ipos; irot = irot2; if (pos[0] != 0) { c.Entities.Add(this); CurrentChunk = c; } Entities.Add(id, this); }
public void PerlinChunk(Chunk c) { for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { double v = //perlinNoise.Noise(x * 16, z * 16, 0.1); perlinNoise.Noise(x * 16, z * 16, 1); //perlinNoise.Noise(x * 16, z * 16, -0.065); //(perlinNoise.Noise(x * 16, z * 16, -0.5) + 1) / 2 * 0.7 + //(perlinNoise.Noise(x * 16, z * 16, 0) + 1) / 2 * 0.2 + //(perlinNoise.Noise(x * 16, z * 16, +0.5) + 1) / 2 * 0.1; v = Math.Min(1, Math.Max(0, v)); byte y = (byte)(v * 128); c.PlaceBlock(x, y, z, 2); } } return; }
public void FlatChunk(Chunk c) { for (int x = 0; x < 16; x++) { for (int y = 0; y < 128; y++) { for (int z = 0; z < 16; z++) { if (y == 1) c.PlaceBlock(x, y, z, 7); if (y < 64) c.PlaceBlock(x, y, z, 1); else if (y == 64) c.PlaceBlock(x, y, z, 2); else c.PlaceBlock(x, y, z, 0); } } } return; }
public void UpdateChunks(bool force, bool forcesend) { if (c == null || (c == CurrentChunk && !force)) return; try { if (CurrentChunk != null) CurrentChunk.Entities.Remove(this); c.Entities.Add(this); CurrentChunk = c; } catch { Server.Log("Error Updating chunk for " + isPlayer.ToString() + " " + isItem.ToString() + " " + isAI.ToString() + " " + id); } if (isPlayer && p.LoggedIn) { bool locked = false; List<Point> templist = new List<Point>(); int sx = CurrentChunk.point.x - p.viewdistance; //StartX int ex = CurrentChunk.point.x + p.viewdistance; //EndX int sz = CurrentChunk.point.z - p.viewdistance; //StartZ int ez = CurrentChunk.point.z + p.viewdistance; //EndZ Parallel.For(sx, ex + 1, delegate(int x) { Parallel.For(sz, ez + 1, delegate(int z) { Point po = new Point(x, z); while (locked) Thread.Sleep(1); lock (templist) { templist.Add(po); } //templist.Add(po); if ((!p.VisibleChunks.Contains(po) || forcesend) && (Math.Abs(po.x) < p.level.ChunkLimit && Math.Abs(po.z) < p.level.ChunkLimit)) { if (!p.level.chunkData.ContainsKey(po)) { p.level.LoadChunk(po.x, po.z); } p.SendChunk(p.level.chunkData[po]); } }); }); //for (int x = sx; x <= ex; x++) //{ // for (int z = sz; z <= ez; z++) // { // Point po = new Point(x, z); // templist.Add(po); // if (p.VisibleChunks.Contains(po) && !forcesend) // { // continue; //Continue if the player already has this chunk // } // if (!p.level.chunkData.ContainsKey(po)) // { // p.level.GenerateChunk(po.x, po.z); // } // p.SendChunk(p.level.chunkData[po]); // } //} //UNLOAD CHUNKS THE PLAYER CANNOT SEE foreach (Point point in p.VisibleChunks.ToArray()) { if (!templist.Contains(point)) { p.SendPreChunk(p.level.chunkData[point], 0); p.VisibleChunks.Remove(point); bool unloadChunk = true; Player.players.ForEach(delegate(Player pl) { if (pl.VisibleChunks.Contains(point)) { unloadChunk = false; return; } }); if (unloadChunk) p.level.UnloadChunk(point.x, point.z); } } } }
/// <summary> /// /// </summary> /// <param name="w"></param> /// <param name="c"></param> public override void Generate(World w, Chunk c) { random = new Random(w.seed); int cx = c.x << 4, cz = c.z << 4; int waterLevel = 64 + 15 / 2 - 4; if (w.seed == 0) { for (int x = 0; x < 16; ++x) for (int z = 0; z < 16; ++z) { for (int y = 0; y < 1; ++y) c.UNCHECKEDPlaceBlock(x, y, z, 0x07); for (int y = 1; y < 50; ++y) c.UNCHECKEDPlaceBlock(x, y, z, 0x01); for (int y = 50; y < 65; ++y) c.UNCHECKEDPlaceBlock(x, y, z, 0x03); c.UNCHECKEDPlaceBlock(x, 65, z, 0x02); } } else { for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { int v = (int)(64 + voronoi.GetValue(cx + x, 5, cz + z) * 7 + (perlin2.GetValue(cx + x, 7, cz + z) + (perlin.GetValue(cx + x, 10, cz + z))) * 15); // Bedrock int bedrockHeight = random.Next(1, 6); for (int y = 0; y < bedrockHeight; y++) c.UNCHECKEDPlaceBlock(x, y, z, 0x07); // Stone for (int y = bedrockHeight; y < v - 5; y++) c.UNCHECKEDPlaceBlock(x, y, z, 0x01); // Dirt for (int y = v - 5; y < v; y++) c.UNCHECKEDPlaceBlock(x, y, z, (byte)(desertSelector.GetValue(cx + x, y, cz + z) > 0.4 ? 0x0C : 0x03)); if (v <= waterLevel) { c.UNCHECKEDPlaceBlock(x, v, z, 0x0C); // Send } else { c.UNCHECKEDPlaceBlock(x, v, z, (byte)(desertSelector.GetValue(cx + x, v, cz + z) > 0.35 ? 0x0C : 0x02)); } } } for (int x = 0; x < 16; x++) { //for( int y = 0; y < 128; y++ ) { for (int z = 0; z < 16; z++) { var d = 0.0; var prevV = (64 + voronoi.GetValue(cx + x, 5, cz + z) * 7 + (perlin2.GetValue(cx + x, 7, cz + z) + (perlin.GetValue(cx + x, 10, cz + z))) * 15); if (prevV < waterLevel) d = (waterLevel - prevV) * 0.78; var v = (-mountains.GetValue(cx + x, 127, cz + z)); if (v >= d) { var h = (64 + (int)(v * 39)); int lvl = 0; for (int y = h - 1; y >= 0; y--) { var mv = mountains2.GetValue(cx + x, y, cz + z); bool desert = desertSelector.GetValue(cx + x, y, cz + z) > 0.4; //if( mv > 0.4 ) { if (lvl == 0) c.UNCHECKEDPlaceBlock(x, y, z, (byte)(desert ? 0x0C : 0x02)); else if (lvl < 5) c.UNCHECKEDPlaceBlock(x, y, z, (byte)(desert ? 0x0C : 0x03)); else c.UNCHECKEDPlaceBlock(x, y, z, 0x01); ++lvl; //} } } } //} } for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { for (int y = 0; y < 128; y++) { if (caves.GetValue(cx + x, y, cz + z) > (128 - y) * 0.0132) { c.UNCHECKEDPlaceBlock(x, y, z, 0x00); if (c.SGB(x, y - 1, z) == 0x03) c.UNCHECKEDPlaceBlock(x, y - 1, z, 0x02); } if (y <= waterLevel && c.SGB(x, y, z) == 0x00) { c.UNCHECKEDPlaceBlock(x, y, z, 0x08); } } } } } }
/// <summary> /// Prepare the client before sending the chunk /// </summary> /// <param name='c'> /// The chunk to send /// </param> /// <param name='load'> /// Load. Weather to unload or load the chunk (0 is unload otherwise it will load) /// </param> public void SendPreChunk(Chunk c, byte load) { SendPreChunk(c.x, c.z, load); }
public void UpdateChunks(bool force, bool forcesend) { if (c != CurrentChunk || force) { try { if(CurrentChunk != null) CurrentChunk.Entities.Remove(this); c.Entities.Add(this); CurrentChunk = c; } catch { Server.Log("Error Updating chunk for " + isPlayer.ToString() + " " + isItem.ToString() + " " + isAI.ToString() + " " + id); } if (isPlayer && p.LoggedIn) { List<Point> templist = new List<Point>(); int sx = CurrentChunk.point.x - p.viewdistance; //StartX int ex = CurrentChunk.point.x + p.viewdistance; //EndX int sz = CurrentChunk.point.z - p.viewdistance; //StartZ int ez = CurrentChunk.point.z + p.viewdistance; //EndZ for (int x = sx; x <= ex; x++) { for (int z = sz; z <= ez; z++) { Point po = new Point(x, z); templist.Add(po); if (p.VisibleChunks.Contains(po) && !forcesend) { continue; //Continue if the player already has this chunk } if (!p.level.chunkData.ContainsKey(po)) { p.level.GenerateChunk(po.x, po.z); } p.SendChunk(p.level.chunkData[po]); } } //UNLOAD CHUNKS THE PLAYER CANNOT SEE foreach (Point point in p.VisibleChunks.ToArray()) { if (!templist.Contains(point)) { p.SendPreChunk(p.level.chunkData[point], 0); p.VisibleChunks.Remove(point); } } } } }
public static Chunk Load(int x, int z, World w, bool thread = true, bool threadLoad = true, bool generate = true, bool dummy = true) { string file = CreatePath(w, x, z); if (File.Exists(file)) { if (threadLoad) { World.chunker.QueueChunkLoad(x, z, false, w); return null; } try { Chunk ch = new Chunk(x, z); using (MemoryStream ms = new MemoryStream()) { using (FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read)) { byte[] comp; ms.SetLength(fs.Length); fs.Read(ms.GetBuffer(), 0, (int)fs.Length); comp = ms.GetBuffer().Decompress(CompressionType.GZip); ms.Write(comp, 0, comp.Length); } ms.Position = 0; NbtTree nbt = new NbtTree(ms); ch.generated = (nbt.Root["Generated"].ToTagByte().Data > 0); ch.populated = (nbt.Root["Populated"].ToTagByte().Data > 0); Array.Copy(nbt.Root["Blocks"].ToTagByteArray(), ch.blocks, ch.blocks.Length); Array.Copy(nbt.Root["Meta"].ToTagByteArray(), ch.meta, ch.meta.Length); Array.Copy(nbt.Root["BlockLight"].ToTagByteArray(), ch.Light, ch.Light.Length); Array.Copy(nbt.Root["SkyLight"].ToTagByteArray(), ch.SkyL, ch.SkyL.Length); Array.Copy(nbt.Root["HeightMap"].ToTagByteArray(), ch.heightMap, ch.heightMap.Length); Array.Copy(nbt.Root["HeightMapPrec"].ToTagByteArray().Data.ToIntArray(), ch.precipitationHeightMap, ch.precipitationHeightMap.Length); TagNodeCompound nbtCompound; foreach (TagNode tag in nbt.Root["Extra"].ToTagList()) { nbtCompound = tag.ToTagCompound(); ch.extra.Add(nbtCompound["Pos"].ToTagInt(), (ushort)nbtCompound["Value"].ToTagShort()); } TagNodeList nbtList = nbt.Root["Physics"].ToTagList(); int count = nbtList.Count; if (count > 0) { ch.physChecks = new Physics.Check[count]; TagNodeList nbtList2; for (int i = 0; i < count; i++) { nbtCompound = nbtList[i].ToTagCompound(); nbtList2 = nbtCompound["Pos"].ToTagList(); ch.physChecks[i] = new Physics.Check(nbtList2[0].ToTagInt(), nbtList2[1].ToTagInt(), nbtList2[2].ToTagInt(), nbtCompound["Meta"].ToTagByte(), nbtCompound["Time"].ToTagShort()); } } AI ai; McObject obj; Item item; Entity e; TagNodeCompound nbtCompound2; foreach (TagNode tag in nbt.Root["Entities"].ToTagList()) { e = null; nbtCompound = tag.ToTagCompound(); switch ((EntityType)(byte)nbtCompound["Type"].ToTagByte()) { case EntityType.AI: // TODO break; case EntityType.Object: // TODO break; case EntityType.Item: nbtCompound2 = nbtCompound["Data"].ToTagCompound(); item = new Item(true) { id = nbtCompound2["ID"].ToTagShort(), count = nbtCompound2["Count"].ToTagByte(), meta = nbtCompound2["Meta"].ToTagShort() }; item.e = new Entity(w) { isItem = true, I = item }; e = item.e; break; } if (e != null) { nbtList = nbtCompound["Motion"].ToTagList(); e.velocity = new double[] { nbtList[0].ToTagDouble(), nbtList[1].ToTagDouble(), nbtList[2].ToTagDouble() }; nbtList = nbtCompound["Pos"].ToTagList(); e.pos = new Point3(nbtList[0].ToTagDouble(), nbtList[1].ToTagDouble(), nbtList[2].ToTagDouble()); nbtList = nbtCompound["Rotation"].ToTagList(); e.rot = new float[] { nbtList[0].ToTagFloat(), nbtList[1].ToTagFloat() }; e.age = nbtCompound["Age"].ToTagInt(); e.OnGround = (nbtCompound["OnGround"].ToTagByte() > 0); e.health = nbtCompound["Health"].ToTagShort(); ch.entityLoad.Add(e); } } Container c; Point3 point3; foreach (TagNode tag in nbt.Root["Containers"].ToTagList()) { nbtCompound = tag.ToTagCompound(); nbtList = nbtCompound["Pos"].ToTagList(); point3 = new Point3(nbtList[0].ToTagInt(), nbtList[1].ToTagInt(), nbtList[2].ToTagInt()); c = Container.CreateInstance((ContainerType)(byte)nbtCompound["Type"].ToTagByte(), w, point3); c.LoadNBTData(nbtCompound["Items"].ToTagList()); if (!w.containers.ContainsKey(point3)) w.containers.Add(point3, c); } } //Console.WriteLine("LOADED " + x + " " + z); return ch; } catch (Exception ex) { Logger.LogToFile("Error loading chunk at " + x + "," + z + "! A new chunk will be generated in it's place."); Logger.LogErrorToFile(ex); } } //Console.WriteLine("GENERATED " + x + " " + z); if (generate) { if (thread) World.chunker.QueueChunk(x, z, w); else return w.GenerateChunk(x, z); return null; } if (dummy) return new Chunk(x, z); return null; }
/// <summary> /// Generate a chunk at x and z /// </summary> /// <param name="x">The x cord. to generate</param> /// <param name="z">The z cord. to generate</param> /// <returns>Returns the generated chunk</returns> public Chunk GenerateChunk(int x, int z) { Chunk c = null; Point pt = new Point(x, z); if (ChunkGenerating != null) c = ChunkGenerating(this, x, z); if (WorldGeneratingChunk != null) c = WorldGeneratingChunk(this, x, z); if (cancelchunk) { cancelchunk = false; if (c != null) return c; else Logger.Log("[WARNING] Was told to cancel chunk generating but chunk was null, the event will not cancel"); } lock (chunkData) { if (chunkData.ContainsKey(pt)) { c = chunkData[pt]; } else c = new Chunk(x, z); } c.generating = true; if (x >= -1875000 && z >= -1875000 && x < 1875000 && z < 1875000) { generator.Generate(c); c.RecalculateLight(); } c.generated = true; c.PostGenerate(this); c._dirty = true; c.generating = false; if (GeneratedChunk != null) GeneratedChunk(this, c, x, z); if (WorldGeneratedChunk != null) WorldGeneratedChunk(this, c, x, z); return c; }
/// <summary> /// /// </summary> /// <param name="w"></param> /// <param name="c"></param> public abstract void Generate( World w, Chunk c );
public static Chunk Load(int x, int z, World w) { string file = w.name + "/chunks/" + Convert.ToString(x & 0x3f, 16) + "/" + Convert.ToString(z & 0x3f, 16) + "/" + x.ToString() + "." + z.ToString() + ".chunk"; if (File.Exists(file)) { Chunk ch = new Chunk(x, z); using (MemoryStream ms = new MemoryStream()) { using (FileStream fs = new FileStream(file, FileMode.Open)) { byte[] comp; ms.SetLength(fs.Length); fs.Read(ms.GetBuffer(), 0, (int)fs.Length); comp = ms.GetBuffer().Decompress(); ms.Write(comp, 0, comp.Length); } byte[] bytes = ms.ToArray(); Array.Copy(bytes, ch.blocks, 32768); Array.Copy(bytes, 32768, ch.meta, 0, 16384); Array.Copy(bytes, 49152, ch.SkyL, 0, 16384); Array.Copy(bytes, 65536, ch.Light, 0, 16384); int index = 81922; short extraCount = BitConverter.ToInt16(bytes, index - 2); lock (ch.extra) for (int i = 0; i < extraCount; i++) { ch.extra.Add(BitConverter.ToInt32(bytes, index), BitConverter.ToUInt16(bytes, index + 4)); index += 6; } } //Console.WriteLine("LOADED " + x + " " + z); return ch; } //Console.WriteLine("GENERATED " + x + " " + z); return w.GenerateChunk(x, z); }
public void UpdateChunks(bool force, bool forcesend) { if (c == null) level.LoadChunk((int)(pos.x / 16), (int)(pos.z / 16)); if (c == null || (c == CurrentChunk && !force)) return; try { if (CurrentChunk != null) CurrentChunk.Entities.Remove(this); c.Entities.Add(this); CurrentChunk = c; } catch { Server.Log("Error Updating chunk for " + isPlayer.ToString() + " " + isItem.ToString() + " " + isAI.ToString() + " " + id); } if (isPlayer && p.LoggedIn) { //bool locked = false; List<Point> templist = new List<Point>(); int sx = CurrentChunk.point.x - p.viewdistance; //StartX int ex = CurrentChunk.point.x + p.viewdistance; //EndX int sz = CurrentChunk.point.z - p.viewdistance; //StartZ int ez = CurrentChunk.point.z + p.viewdistance; //EndZ // This can cause severe lag! DO NOT USE IT!!! /*Parallel.For(sx, ex + 1, delegate(int x) { Parallel.For(sz, ez + 1, delegate(int z) { Point po = new Point(x, z); while (locked) Thread.Sleep(1); lock (templist) { templist.Add(po); } //templist.Add(po); if ((!p.VisibleChunks.Contains(po) || forcesend) && (Math.Abs(po.x) < p.level.ChunkLimit && Math.Abs(po.z) < p.level.ChunkLimit)) { if (!p.level.chunkData.ContainsKey(po)) p.level.LoadChunk(po.x, po.z); p.SendChunk(p.level.chunkData[po]); } }); });*/ for (int x = sx; x <= ex; x++) { for (int z = sz; z <= ez; z++) { Point po = new Point(x, z); templist.Add(po); if ((!p.VisibleChunks.Contains(po) || forcesend) && (Math.Abs(po.x) < p.level.ChunkLimit && Math.Abs(po.z) < p.level.ChunkLimit)) { if (!p.level.chunkData.ContainsKey(po)) p.level.LoadChunk(po.x, po.z); if (p.level.chunkData.ContainsKey(po)) { try { p.SendChunk(p.level.chunkData[po]); p.level.chunkData[po].Update(p.level, p); } catch { p.SendPreChunk(new Chunk(po.x, po.z, true), 0); } } else World.chunker.QueueChunkSend(po, p); } } } //UNLOAD CHUNKS THE PLAYER CANNOT SEE foreach (Point point in p.VisibleChunks.ToArray()) { if (!templist.Contains(point)) { p.SendPreChunk(new Chunk(point.x, point.z, true), 0); p.VisibleChunks.Remove(point); bool unloadChunk = true; Player.players.ForEach(delegate(Player pl) { if (pl.VisibleChunks.Contains(point)) { unloadChunk = false; return; } }); if (unloadChunk) World.chunker.QueueChunkLoad(point.x, point.z, true, p.level); //p.level.UnloadChunk(point.x, point.z); } } } }
/// <summary> /// Prepare the client before sending the chunk /// </summary> /// <param name='c'> /// C. The chunk to send /// </param> /// <param name='load'> /// Load. Weather to unload or load the chunk (0 is unload otherwise it will load) /// </param> public void SendPreChunk(Chunk c, byte load) { byte[] bytes = new byte[9]; util.EndianBitConverter.Big.GetBytes(c.x).CopyTo(bytes, 0); util.EndianBitConverter.Big.GetBytes(c.z).CopyTo(bytes, 4); bytes[8] = load; SendRaw(0x32, bytes); }
/// <summary> /// /// </summary> /// <param name="w"></param> /// <param name="c"></param> public override void Generate(World w, Chunk c) { //DateTime start = DateTime.Now; //int cx = c.x << 4, cz = c.z << 4; //int waterLevel = 64 + 15 / 2 - 4; if (w.seed == 0) { for (int x = 0; x < 16; ++x) for (int z = 0; z < 16; ++z) { for (int y = 0; y < 1; ++y) c.UNCHECKEDPlaceBlock(x, y, z, 0x07); for (int y = 1; y < 50; ++y) c.UNCHECKEDPlaceBlock(x, y, z, 0x01); for (int y = 50; y < 65; ++y) c.UNCHECKEDPlaceBlock(x, y, z, 0x03); c.UNCHECKEDPlaceBlock(x, 65, z, 0x02); } } else { lock (this.blarg) // We have to do this otherwise shit gets f****d. { random.setSeed((long)c.x * 0x4f9939f508L + (long)c.z * 0x1ef1565bd5L); generateTerrain(c.x, c.z, c.blocks); //biomesForGeneration = worldObj.getWorldChunkManager().loadBlockGeneratorData(biomesForGeneration, i * 16, j * 16, 16, 16); replaceBlocksForBiome(c.x, c.z, c.blocks/*, biomesForGeneration*/); caveGenerator.generate(worldObj, c.x, c.z, c.blocks); if (field_35563_t) { //field_35559_d.generate(this, worldObj, i, j, abyte0); //field_35558_f.generate(this, worldObj, i, j, abyte0); //field_35560_e.generate(this, worldObj, i, j, abyte0); } field_35564_x.generate(worldObj, c.x, c.z, c.blocks); } } //TimeSpan took = DateTime.Now - start; //Console.WriteLine(took.TotalMilliseconds); }
public Chunk GenerateChunk(int x, int z) { Chunk c = new Chunk(x, z); generator.Generate(this, c); //generator.PerlinChunk(c); //generator.RandMap(c, seed); c.RecalculateLight(); //c.SpreadLight(); if (GeneratedChunk != null) GeneratedChunk(this, c, x, z); if (WorldGenerateChunk != null) WorldGenerateChunk(this, c, x, z); /*lock (chunkData) if (!chunkData.ContainsKey(new Point(x, z))) chunkData.Add(new Point(x, z), c);*/ return c; }
public static Chunk Load(int x, int z, World w, bool thread = true) { string file = String.Format("{0}/chunks/{1}/{2}/{3}.{4}.chunk", w.name, Convert.ToString(x & 0x3f, 16), Convert.ToString(z & 0x3f, 16), x.ToString(), z.ToString()); if (File.Exists(file)) { if (thread) { World.chunker.QueueChunkLoad(x, z, false, w); return null; } try { Chunk ch = new Chunk(x, z); using (MemoryStream ms = new MemoryStream()) { using (FileStream fs = new FileStream(file, FileMode.Open)) { byte[] comp; ms.SetLength(fs.Length); fs.Read(ms.GetBuffer(), 0, (int)fs.Length); comp = ms.GetBuffer().Decompress(); ms.Write(comp, 0, comp.Length); } byte[] bytes = ms.ToArray(); Array.Copy(bytes, ch.blocks, 32768); Array.Copy(bytes, 32768, ch.meta, 0, 16384); Array.Copy(bytes, 49152, ch.SkyL, 0, 16384); Array.Copy(bytes, 65536, ch.Light, 0, 16384); int index = 81922; short extraCount = BitConverter.ToInt16(bytes, index - 2); if (extraCount > 0) for (int i = 0; i < extraCount; i++) { ch.extra.Add(BitConverter.ToInt32(bytes, index), BitConverter.ToUInt16(bytes, index + 4)); index += 6; } short physCount = BitConverter.ToInt16(bytes, index); index += 2; if (physCount > 0) { ch.physChecks = new Physics.Check[physCount]; for (int i = 0; i < physCount; i++) { ch.physChecks[i] = new Physics.Check(BitConverter.ToInt32(bytes, index), BitConverter.ToInt32(bytes, index + 4), BitConverter.ToInt32(bytes, index + 8), bytes[index + 14], BitConverter.ToInt16(bytes, index + 12)); index += 15; } } } //Console.WriteLine("LOADED " + x + " " + z); return ch; } catch (Exception ex) { Server.ServerLogger.Log("Error loading chunk at " + x + "," + z + "! A new chunk will be generated in it's place."); Server.ServerLogger.LogError(ex); } } //Console.WriteLine("GENERATED " + x + " " + z); if (thread) World.chunker.QueueChunk(x, z, w); else return w.GenerateChunk(x, z); return null; }
public void UpdateChunks(bool force, bool forcesend) { if (c != CurrentChunk || force) { //if (c == null) { p.Kick("You dumbass >_>"); return; } try { CurrentChunk.Entities.Remove(this); c.Entities.Add(this); CurrentChunk = c; } catch { p.Kick("Error Updating Chunk."); } if (isPlayer || force) { List<Point> templist = new List<Point>(); int sx = CurrentChunk.point.x - 3; //StartX int ex = CurrentChunk.point.x + 3; //EndX int sz = CurrentChunk.point.z - 3; //StartZ int ez = CurrentChunk.point.z + 3; //EndZ for (int x = sx; x <= ex; x++) { for (int z = sz; z <= ez; z++) { Point po = new Point(x, z); templist.Add(po); if (p.VisibleChunks.Contains(po) || forcesend) { continue; //Continue if the player already has this chunk } if (!p.level.chunkData.ContainsKey(po)) { p.level.GenerateChunk(po.x, po.z); } p.SendChunk(p.level.chunkData[po]); } } //UNLOAD CHUNKS THE PLAYER CANNOT SEE foreach (Point point in p.VisibleChunks.ToArray()) { if (!templist.Contains(point)) { p.SendPreChunk(p.level.chunkData[point], 0); p.VisibleChunks.Remove(point); } } } } }
/// <summary> /// Sends a player a Chunk /// </summary> /// <param name='c'> /// C. The chunk to send /// </param> public void SendChunk(Chunk c) { byte[] CompressedData = c.GetCompressedData(); if (CompressedData == null) { SendPreChunk(c, 0); return; } SendPreChunk(c, 1); //Send Chunk Data byte[] bytes = new byte[17 + CompressedData.Length]; util.EndianBitConverter.Big.GetBytes((int)(c.x * 16)).CopyTo(bytes, 0); util.EndianBitConverter.Big.GetBytes((int)0).CopyTo(bytes, 4); util.EndianBitConverter.Big.GetBytes((int)(c.z * 16)).CopyTo(bytes, 6); bytes[10] = 15; bytes[11] = 127; bytes[12] = 15; util.EndianBitConverter.Big.GetBytes(CompressedData.Length).CopyTo(bytes, 13); CompressedData.CopyTo(bytes, 17); SendRaw(0x33, bytes); VisibleChunks.Add(c.point); }
public void UpdateChunks(bool force, bool forcesend, int queue = 0) { if (c == null) level.LoadChunk((int)pos.x >> 4, (int)pos.z >> 4, false, false); if (c == null || (c == CurrentChunk && !force)) return; try { if (CurrentChunk != null) CurrentChunk.RemoveEntity(this); c.AddEntity(this); CurrentChunk = c; } catch { Logger.Log("Error updating chunk: " + this.ToString()); } if (isPlayer && p.LoggedIn) { //p.SendMessage(level.chunkManager.getBiomeGenAt(CurrentChunk.x << 4, CurrentChunk.z << 4).biomeName); // Debug! //bool locked = false; List<Point> templist = new List<Point>(); int sx = CurrentChunk.x - p.viewdistance; //StartX int ex = CurrentChunk.x + p.viewdistance; //EndX int sz = CurrentChunk.z - p.viewdistance; //StartZ int ez = CurrentChunk.z + p.viewdistance; //EndZ // This can cause severe lag! DO NOT USE IT!!! /*Parallel.For(sx, ex + 1, delegate(int x) { Parallel.For(sz, ez + 1, delegate(int z) { Point po = new Point(x, z); while (locked) Thread.Sleep(1); lock (templist) { templist.Add(po); } //templist.Add(po); if ((!p.VisibleChunks.Contains(po) || forcesend) && (Math.Abs(po.x) < p.level.ChunkLimit && Math.Abs(po.z) < p.level.ChunkLimit)) { if (!p.level.chunkData.ContainsKey(po)) p.level.LoadChunk(po.x, po.z); p.SendChunk(p.level.chunkData[po]); } }); });*/ for (int x = sx; x <= ex; x++) { for (int z = sz; z <= ez; z++) { Point po = new Point(x, z); templist.Add(po); if ((!p.VisibleChunks.Contains(po) || forcesend) && (Math.Abs(po.x) < p.level.ChunkLimit && Math.Abs(po.z) < p.level.ChunkLimit)) { if (!p.level.chunkData.ContainsKey(po)) p.level.LoadChunk(po.x, po.z, queue != -1, queue != -1); try { if (p.level.chunkData.ContainsKey(po)) { if (!p.level.chunkData[po].generated) { World.chunker.QueueChunk(po, p.level); if (queue == -1) { while (!p.level.chunkData[po].generated) Thread.Sleep(50); p.SendChunk(p.level.chunkData[po]); } else World.chunker.QueueChunkSend(po, p); } else if (queue == 1) { if (!p.level.chunkData[po].populated) World.chunker.QueueChunk(po, p.level, false); World.chunker.QueueChunkSend(po, p); } else { if (!p.level.chunkData[po].populated) World.chunker.QueueChunk(po, p.level, false); p.SendChunk(p.level.chunkData[po]); //p.level.chunkData[po].Update(p.level, p); } } else { if (queue == -1) { while (!p.level.chunkData.ContainsKey(po)) Thread.Sleep(50); p.SendChunk(p.level.chunkData[po]); } else World.chunker.QueueChunkSend(po, p); } } catch { p.SendPreChunk(po.x, po.z, 0); } } } } //UNLOAD CHUNKS THE PLAYER CANNOT SEE foreach (Point point in p.VisibleChunks.ToArray()) { if (!templist.Contains(point)) { p.SendPreChunk(point.x, point.z, 0); lock (p.VisibleChunks) p.VisibleChunks.Remove(point); bool unloadChunk = true; Player.players.ForEach(delegate(Player pl) { if (pl.VisibleChunks.Contains(point)) { unloadChunk = false; return; } }); if (unloadChunk) World.chunker.QueueChunkLoad(point.x, point.z, true, p.level); //p.level.UnloadChunk(point.x, point.z); } } } }