//We should never default //public static Chunk GetChunk(int x, int z) //{ // return Server.mainlevel.chunkData[new Point(x, z)]; //} public static Chunk GetChunk(int x, int z, World world, bool overRide = false) { Point po = new Point(x, z); if (overRide && !world.chunkData.ContainsKey(po)) { world.LoadChunk(z, z, false, false); } if (world.chunkData.ContainsKey(po)) { return(world.chunkData[po]); } return(null); }
//We should never default //public static Chunk GetChunk(int x, int z) //{ // return Server.mainlevel.chunkData[new Point(x, z)]; //} public static Chunk GetChunk(int x, int z, World world, bool overRide = false) { Point po = new Point(x, z); if (overRide && !world.chunkData.ContainsKey(po)) world.LoadChunk(z, z, false, false); if (world.chunkData.ContainsKey(po)) return world.chunkData[po]; return null; }
public static World LoadLVL(string filename) { //TODO make loading/saving better. //if (WorldLoad != null) // WorldLoad(this); World w = new World() { chunkData = new Dictionary<Point, Chunk>(), name = filename }; Logger.Log("Loading " + w.name + "..."); /*using (MemoryStream ms = new MemoryStream()) { using (FileStream fs = new FileStream(filename + "/" + filename + ".blocks", FileMode.Open)) { byte[] comp; ms.SetLength(fs.Length); fs.Read(ms.GetBuffer(), 0, (int)fs.Length); DecompressData(ms.GetBuffer(), out comp); ms.Write(comp, 0, comp.Length); } byte[] bytes = ms.ToArray(); long chunkcount = ms.Length / 32776; if(!Program.RunningInMono()) //mono doesn't have Parallel.For(long, long, Syatem.Action<long>) implemented { Parallel.For(0, chunkcount, i => { try { int block = (int)i * 32776; int x = BitConverter.ToInt32(bytes, 0 + block); int z = BitConverter.ToInt32(bytes, 4 + block); Chunk c = new Chunk(x, z); Array.Copy(bytes, 8 + block, c.blocks, 0, 32768); c.RecalculateLight(); c.SpreadLight(); lock (w.chunkData) if (!w.chunkData.ContainsKey(new Point(x, z))) w.chunkData.Add(new Point(x, z), c); } catch (Exception ex) { Logger.Log(ex.ToString()); } }); } else{ for (int i = 0; i < chunkcount; i++) { try { int block = (int)i * 32776; int x = BitConverter.ToInt32(bytes, 0 + block); int z = BitConverter.ToInt32(bytes, 4 + block); Chunk c = new Chunk(x, z); Array.Copy(bytes, 8 + block, c.blocks, 0, 32768); c.RecalculateLight(); c.SpreadLight(); lock (w.chunkData) if (!w.chunkData.ContainsKey(new Point(x, z))) w.chunkData.Add(new Point(x, z), c); } catch (Exception ex) { Logger.Log(ex.ToString()); } } } }*/ try { using (StreamReader sw = new StreamReader(filename + "/" + filename + ".ini")) { w.seed = long.Parse(sw.ReadLine()); w.SpawnX = int.Parse(sw.ReadLine()); w.SpawnY = int.Parse(sw.ReadLine()); w.SpawnZ = int.Parse(sw.ReadLine()); w.ChunkLimit = int.Parse(sw.ReadLine()); w.time = long.Parse(sw.ReadLine()); w.dimension = sbyte.Parse(sw.ReadLine()); w.moonPhase = byte.Parse(sw.ReadLine()); } } catch { /*Logger.Log("Error loading world configuration!");*/ } w.physics = new Physics(w); w.generator = new GenStandard(w, true); w.chunkManager = new WorldChunkManager(w); int cursorH = 22 + w.name.Length; float count = 0, total = (Server.ViewDistance * 2 + 1) * (Server.ViewDistance * 2 + 1); Console.SetCursorPosition(cursorH, Console.CursorTop - 1); Console.Write("0%"); object derpLock = new object(); try { Parallel.For(((int)w.SpawnX >> 4) - Server.ViewDistance, ((int)w.SpawnX >> 4) + Server.ViewDistance + 1, x => { Parallel.For(((int)w.SpawnZ >> 4) - Server.ViewDistance, ((int)w.SpawnZ >> 4) + Server.ViewDistance + 1, z => { w.LoadChunk(x, z, false, false); lock (derpLock) { Console.SetCursorPosition(cursorH, Console.CursorTop); count++; Console.Write((int)((count / total) * 100) + "%"); } }); }); } catch (NotImplementedException) { for (int x = ((int)w.SpawnX >> 4) - Server.ViewDistance; x < ((int)w.SpawnX >> 4) + Server.ViewDistance + 1; x++) { for (int z = ((int)w.SpawnZ >> 4) - Server.ViewDistance; z < ((int)w.SpawnZ >> 4) + Server.ViewDistance + 1; z++) { w.LoadChunk(x, z, false, false); Console.SetCursorPosition(cursorH, Console.CursorTop); count++; Console.Write((int)((count / total) * 100) + "%"); } } } Console.WriteLine(); World.worlds.Add(w); Logger.Log(filename + " Loaded."); Logger.Log("Look distance = " + Server.ViewDistance); w.Init(); w.physics.Start(); if (World.WorldLoad != null) World.WorldLoad(w); return w; }
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); } } } } }
public static World LoadLVL(string filename) { //TODO make loading/saving better. //if (WorldLoad != null) // WorldLoad(this); World w = new World() { chunkData = new Dictionary<Point, Chunk>(), name = filename }; Server.Log("Loading..."); /*using (MemoryStream ms = new MemoryStream()) { using (FileStream fs = new FileStream(filename + "/" + filename + ".blocks", FileMode.Open)) { byte[] comp; ms.SetLength(fs.Length); fs.Read(ms.GetBuffer(), 0, (int)fs.Length); DecompressData(ms.GetBuffer(), out comp); ms.Write(comp, 0, comp.Length); } byte[] bytes = ms.ToArray(); long chunkcount = ms.Length / 32776; if(!Program.RunningInMono()) //mono doesn't have Parallel.For(long, long, Syatem.Action<long>) implemented { Parallel.For(0, chunkcount, i => { try { int block = (int)i * 32776; int x = BitConverter.ToInt32(bytes, 0 + block); int z = BitConverter.ToInt32(bytes, 4 + block); Chunk c = new Chunk(x, z); Array.Copy(bytes, 8 + block, c.blocks, 0, 32768); c.RecalculateLight(); c.SpreadLight(); lock (w.chunkData) if (!w.chunkData.ContainsKey(new Point(x, z))) w.chunkData.Add(new Point(x, z), c); } catch (Exception ex) { Server.Log(ex.ToString()); } }); } else{ for (int i = 0; i < chunkcount; i++) { try { int block = (int)i * 32776; int x = BitConverter.ToInt32(bytes, 0 + block); int z = BitConverter.ToInt32(bytes, 4 + block); Chunk c = new Chunk(x, z); Array.Copy(bytes, 8 + block, c.blocks, 0, 32768); c.RecalculateLight(); c.SpreadLight(); lock (w.chunkData) if (!w.chunkData.ContainsKey(new Point(x, z))) w.chunkData.Add(new Point(x, z), c); } catch (Exception ex) { Server.Log(ex.ToString()); } } } }*/ using (StreamReader sw = new StreamReader(filename + "/" + filename + ".ini")) { w.seed = long.Parse(sw.ReadLine()); w.SpawnX = int.Parse(sw.ReadLine()); w.SpawnY = int.Parse(sw.ReadLine()); w.SpawnZ = int.Parse(sw.ReadLine()); w.ChunkLimit = int.Parse(sw.ReadLine()); w.time = long.Parse(sw.ReadLine()); } w.generator = new GenStandard(w, true); w.physics = new Physics(w); try { Parallel.For(-3, 4, x => { Parallel.For(-3, 4, z => { w.LoadChunk(x, z, false); }); }); } catch (NotImplementedException) { for (int x = -3; x < 4; x++) { for (int z = -3; z < 4; z++) { w.LoadChunk(x, z, false); } } } World.worlds.Add(w); Server.Log(filename + " Loaded."); Server.Log("Look distance = 3"); w.timeupdate.Elapsed += delegate { w.time += 20; if (w.time > 24000) w.time = 0; Player.players.ForEach(delegate(Player p) { if (p.MapLoaded && p.level == w) p.SendTime(); }); }; w.timeupdate.Start(); w.blockflush.Elapsed += delegate { w.FlushBlockChanges(); }; w.blockflush.Start(); w.physics.Start(); if (World.WorldLoad != null) World.WorldLoad(w); return w; }