예제 #1
0
        /// <summary>
        ///     Initializes the <see cref="OpenLevel"/> instance, this could include loading the world from a local folder or generating a new world.
        /// </summary>
        /// <param name="openLevel">The <see cref="OpenLevel"/> instance to register and initialize</param>
        public void LoadLevel(OpenLevel openLevel)
        {
            openLevel.Initialize();

            if (Config.GetProperty("CalculateLights", false) && openLevel.WorldProvider is WrappedWorldProvider wawp &&
                wawp.WorldProvider is AnvilWorldProvider anvilWorldProvider)
            {
                anvilWorldProvider.Locked = true;

                SkyLightCalculations.Calculate(openLevel);
                RecalculateBlockLight(openLevel, anvilWorldProvider);

                anvilWorldProvider.Locked = false;
            }

            if (_levels.TryAdd(openLevel.LevelId, openLevel))
            {
                Levels.Add(openLevel);

                LevelInitEvent initEvent = new LevelInitEvent(openLevel);
                Api.EventDispatcher.DispatchEvent(initEvent);

                //OnLevelCreated?.Invoke(openLevel);

                Log.InfoFormat("Level loaded: {0}", openLevel.LevelId);
            }
            else
            {
                Log.Warn($"Failed to add level: {openLevel.LevelId}");
            }
        }
예제 #2
0
        public void Cut(Player player, int leaveId = 0, int leaveData = 0)
        {
            RegionSelector selector = RegionSelector.GetSelector(player);

            Clipboard clipboard = new Clipboard(player.Level);

            clipboard.OriginPosition1 = selector.Position1;
            clipboard.OriginPosition2 = selector.Position2;
            clipboard.SourceMask      = new AnyBlockMask();
            clipboard.SourceFuncion   = coordinates =>
            {
                var block = BlockFactory.GetBlockById((byte)leaveId);
                block.Metadata    = (byte)leaveData;
                block.Coordinates = coordinates;
                EditSession.SetBlock(block);
                return(true);
            };
            clipboard.Origin = (BlockCoordinates)player.KnownPosition;
            clipboard.Fill(selector.GetSelectedBlocks());
            selector.Clipboard = clipboard;

            Task.Run(() =>
            {
                SkyLightCalculations.Calculate(player.Level);
                player.CleanCache();
                player.ForcedSendChunks(() =>
                {
                    player.SendMessage("Calculated skylights and resent chunks.");
                });
            });
        }
예제 #3
0
 public void CalculateSkyLight(Player player)
 {
     Task.Run(() =>
     {
         SkyLightCalculations.Calculate(player.Level);
         player.CleanCache();
         player.ForcedSendChunks(() => { player.SendMessage("Calculated skylights and resent chunks."); });
     });
 }
예제 #4
0
        public virtual Level GetDimension(Level level, Dimension dimension)
        {
            if (dimension == Dimension.Overworld)
            {
                throw new Exception($"Can not get level for '{dimension}' from the LevelManager");
            }
            if (dimension == Dimension.Nether && !level.WorldProvider.HaveNether())
            {
                return(null);
            }
            if (dimension == Dimension.TheEnd && !level.WorldProvider.HaveTheEnd())
            {
                return(null);
            }

            AnvilWorldProvider overworld = level.WorldProvider as AnvilWorldProvider;

            if (overworld == null)
            {
                return(null);
            }

            var worldProvider = new AnvilWorldProvider(overworld.BasePath)
            {
                ReadBlockLight       = overworld.ReadBlockLight,
                ReadSkyLight         = overworld.ReadSkyLight,
                Dimension            = dimension,
                MissingChunkProvider = new AirWorldGenerator(),
            };

            Level newLevel = new Level(level.LevelManager, level.LevelId + "_" + dimension, worldProvider, EntityManager, level.GameMode, level.Difficulty, level.ViewDistance)
            {
                OverworldLevel     = level,
                Dimension          = dimension,
                EnableBlockTicking = level.EnableBlockTicking,
                EnableChunkTicking = level.EnableChunkTicking,
                IsWorldTimeStarted = level.IsWorldTimeStarted
            };

            newLevel.Initialize();

            if (Config.GetProperty("CalculateLights", false))
            {
                SkyLightCalculations.Calculate(newLevel);

                int count = worldProvider.LightSources.Count;
                Log.Debug($"Recalculating block light for {count} light sources.");
                Stopwatch sw = new Stopwatch();
                sw.Start();
                RecalculateBlockLight(newLevel, worldProvider);

                var chunkCount = worldProvider._chunkCache.Where(chunk => chunk.Value != null).ToArray().Length;
                Log.Debug($"Recalc sky and block light for {chunkCount} chunks, {chunkCount*16*16*256} blocks and {count} light sources. Time {sw.ElapsedMilliseconds}ms");
            }

            return(newLevel);
        }
예제 #5
0
        public static void RecalculateLight(Level level, AnvilWorldProvider anvilWorldProvider)
        {
            SkyLightCalculations.Calculate(level);

            while (anvilWorldProvider.LightSources.Count > 0)
            {
                var block = anvilWorldProvider.LightSources.Dequeue();
                BlockLightCalculations.Calculate(level, block.Coordinates);
            }
        }
예제 #6
0
 public void NewArena(MapInfo map)
 {
     lock (LevelSync)
     {
         AnvilWorldProvider l;
         if (OnlyRead)
         {
             l = map.ProviderCache;
         }
         else
         {
             l = map.ProviderCache.Clone() as AnvilWorldProvider;
         }
         int id = LevelCount;
         if (LevelPoolId.Count > 0)
         {
             id = LevelPoolId.First();
             LevelPoolId.Remove(id);
         }
         else
         {
             LevelCount++;
             id = LevelCount;
         }
         var level = new xCoreLevel(l, Game.Context.Server.LevelManager.EntityManager, Game, map, id);
         LevelCount++;
         level.Initialize();
         SkyLightCalculations.Calculate(level);
         while (l.LightSources.Count > 0)
         {
             var block = l.LightSources.Dequeue();
             block = level.GetBlock(block.Coordinates);
             BlockLightCalculations.Calculate(level, block);
         }
         Game.Initialization(level);
         Levels.Add(level);
     }
 }
예제 #7
0
        public void ResetMap()
        {
            //if (_worldProvider == null) throw new Exception($"Can not get level from the WorldProvider");
            AnvilWorldProvider worldProvider = WorldProvider as AnvilWorldProvider;
            //worldProvider._chunkCache.Clear();
            //worldProvider = Map.ProviderCache.Clone() as AnvilWorldProvider;
            ConcurrentDictionary <ChunkCoordinates, ChunkColumn> chunkCache = new ConcurrentDictionary <ChunkCoordinates, ChunkColumn>();

            foreach (KeyValuePair <ChunkCoordinates, ChunkColumn> valuePair in Map.ProviderCache._chunkCache)
            {
                chunkCache.TryAdd(valuePair.Key, (ChunkColumn)valuePair.Value?.Clone());
            }
            worldProvider._chunkCache.Clear();
            worldProvider._chunkCache = chunkCache;
            SkyLightCalculations.Calculate(this);
            while (worldProvider.LightSources.Count > 0)
            {
                var block = worldProvider.LightSources.Dequeue();
                block = this.GetBlock(block.Coordinates);
                BlockLightCalculations.Calculate(this, block);
            }
            //WorldProvider. = worldProvider;
        }
예제 #8
0
        public virtual Level GetLevel(Player player, string name)
        {
            Level level = Levels.FirstOrDefault(l => l.LevelId.Equals(name, StringComparison.InvariantCultureIgnoreCase));

            if (level == null)
            {
                GameMode   gameMode     = Config.GetProperty("GameMode", GameMode.Survival);
                Difficulty difficulty   = Config.GetProperty("Difficulty", Difficulty.Normal);
                int        viewDistance = Config.GetProperty("ViewDistance", 11);

                IWorldProvider worldProvider = null;

                switch (Config.GetProperty("WorldProvider", "flat").ToLower().Trim())
                {
                case "flat":
                case "flatland":
                    worldProvider = new FlatlandWorldProvider();
                    break;

                case "cool":
                    worldProvider = new CoolWorldProvider();
                    break;

                case "experimental":
                    worldProvider = new ExperimentalWorldProvider();
                    break;

                case "anvil":
                    worldProvider = new AnvilWorldProvider()
                    {
                        MissingChunkProvider = new FlatlandWorldProvider()
                    };
                    break;

                default:
                    worldProvider = new FlatlandWorldProvider();
                    break;
                }

                level = new Level(name, worldProvider, EntityManager, gameMode, difficulty, viewDistance);
                level.Initialize();

                if (Config.GetProperty("CalculateLights", false))
                {
                    {
                        AnvilWorldProvider wp = level._worldProvider as AnvilWorldProvider;
                        if (wp != null)
                        {
                            //wp.PruneAir();
                            //wp.MakeAirChunksAroundWorldToCompensateForBadRendering();

                            SkyLightCalculations.Calculate(level);

                            Stopwatch sw = new Stopwatch();

                            int count = wp.LightSources.Count;
                            sw.Restart();
                            RecalculateLight(level, wp);

                            var chunkCount = wp._chunkCache.Where(chunk => chunk.Value != null).ToArray().Length;
                            Log.Debug($"Recalc light for {chunkCount} chunks, {chunkCount*16*16*256} blocks and {count} light sources. Time {sw.ElapsedMilliseconds}ms");
                        }
                    }

                    {
                        FlatlandWorldProvider wp = level._worldProvider as FlatlandWorldProvider;
                        if (wp != null)
                        {
                            SkyLightCalculations.Calculate(level);
                        }
                    }
                }
                Levels.Add(level);

                OnLevelCreated(new LevelEventArgs(null, level));
            }

            return(level);
        }
예제 #9
0
        public LevelPoolGame(xCoreGames core, xCoreInterface game, bool onlyread, bool parse)
        {
            Random rnd     = new Random();
            var    timings = new Stopwatch();

            timings.Start();
            string basepath = Config.GetProperty("PluginDirectory", "Plugins") + "\\" + game.NameGame;

            for (int id = 1; id <= game.ArenaLoaded; id++)
            {
                if (Maps.Count == 0)
                {
                    DirectoryInfo dirInfo = new DirectoryInfo(basepath);
                    foreach (var dir in dirInfo.GetDirectories())
                    {
                        var     provider = new AnvilWorldProvider(basepath + "\\" + dir.Name);
                        var     cfg      = File.ReadAllText(basepath + "\\" + dir.Name + "\\config.json");
                        JObject jobj     = JObject.Parse(cfg);
                        Maps.Add(dir.Name, new MapInfo(dir.Name, jobj));
                        Maps[dir.Name].ProviderCache = provider;
                        Maps[dir.Name].ProviderCache.Initialize();
                        Maps[dir.Name].ProviderCache.PruneAir();
                        Maps[dir.Name].ProviderCache.MakeAirChunksAroundWorldToCompensateForBadRendering();
                    }
                }

                string map = Maps.Keys.ElementAt(rnd.Next(0, Maps.Keys.Count - 1));

                Level levelkey = Levels.FirstOrDefault(l => l.LevelId.Equals(game.NameGame + id, StringComparison.InvariantCultureIgnoreCase));
                if (levelkey == null)
                {
                    AnvilWorldProvider provider;
                    //provider = Maps[map].ProviderCache;
                    //if (!Maps[map].ProviderBool)
                    //{
                    if (onlyread)
                    {
                        provider = Maps[map].ProviderCache;
                    }
                    else
                    {
                        provider = Maps[map].ProviderCache.Clone() as AnvilWorldProvider;
                    }
                    //}
                    var level = new xCoreLevel(provider, game.Context.Server.LevelManager.EntityManager, game, Maps[map], LevelCount);
                    LevelCount++;
                    level.Initialize();
                    SkyLightCalculations.Calculate(level);
                    while (provider.LightSources.Count > 0)
                    {
                        var block = provider.LightSources.Dequeue();
                        block = level.GetBlock(block.Coordinates);
                        BlockLightCalculations.Calculate(level, block);
                    }
                    if (parse)
                    {
                        int X = Maps[map].Center.X;
                        int Z = Maps[map].Center.Z;
                        List <BlockCoordinates> BE = new List <BlockCoordinates>();
                        if (Maps[map].CacheBlockEntites == null)
                        {
                            int startX = Math.Min(X - 256, X + 256);
                            int endX   = Math.Max(X - 256, X + 256);
                            int startY = Math.Min(11, 129);
                            int endY   = Math.Max(11, 129);
                            int startZ = Math.Min(Z - 256, Z + 256);
                            int endZ   = Math.Max(Z - 256, Z + 256);
                            for (int x = startX; x <= endX; ++x)
                            {
                                for (int y = startY; y <= endY; ++y)
                                {
                                    for (int z = startZ; z <= endZ; ++z)
                                    {
                                        var         bc = new BlockCoordinates(x, y, z);
                                        BlockEntity blockentity;
                                        if ((blockentity = level.GetBlockEntity(bc)) != null)
                                        {
                                            if (blockentity is ChestBlockEntity)
                                            {
                                                if (!BE.Contains(blockentity.Coordinates))
                                                {
                                                    BE.Add(blockentity.Coordinates);
                                                }
                                            }
                                            else if (blockentity is Sign)
                                            {
                                                CleanSignText(((Sign)blockentity).GetCompound(), "Text1");
                                                CleanSignText(((Sign)blockentity).GetCompound(), "Text2");
                                                CleanSignText(((Sign)blockentity).GetCompound(), "Text3");
                                                CleanSignText(((Sign)blockentity).GetCompound(), "Text4");
                                                BE.Add(bc);
                                            }
                                        }
                                    }
                                }
                            }
                            for (int x = startX; x <= endX; ++x)
                            {
                                for (int z = startZ; z <= endZ; ++z)
                                {
                                    var bc = new BlockCoordinates(x, 127, z);
                                    MiNET.Blocks.Block b = level.GetBlock(bc);
                                    if (b.Id == 95)
                                    {
                                        level.SetAir(bc, false);
                                    }
                                }
                            }
                        }
                        if (Maps[map].CacheBlockEntites == null)
                        {
                            Maps[map].CacheBlockEntites = BE;
                        }
                    }
                    game.Initialization(level);
                    Levels.Add(level);
                }
            }
            Core     = core;
            Game     = game;
            OnlyRead = onlyread;
            timings.Stop();
            Log.Info("Loaded " + Levels.Count + " arenas . Load time " + timings.ElapsedMilliseconds + " ms");
            _tickerHighPrecisionTimer = new Timer(QueueTimer, null, 0, 1000);
        }
예제 #10
0
        public virtual Level GetLevel(Player player, string name)
        {
            Level level = Levels.FirstOrDefault(l => l.LevelId.Equals(name, StringComparison.InvariantCultureIgnoreCase));

            if (level == null)
            {
                GameMode   gameMode           = Config.GetProperty("GameMode", GameMode.Survival);
                Difficulty difficulty         = Config.GetProperty("Difficulty", Difficulty.Normal);
                int        viewDistance       = Config.GetProperty("ViewDistance", 11);
                bool       enableBlockTicking = Config.GetProperty("EnableBlockTicking", false);
                bool       enableChunkTicking = Config.GetProperty("EnableChunkTicking", false);
                bool       isWorldTimeStarted = Config.GetProperty("IsWorldTimeStarted", false);

                IWorldProvider worldProvider = null;

                switch (Config.GetProperty("WorldProvider", "flat").ToLower().Trim())
                {
                case "cool":
                    worldProvider = new CoolWorldProvider();
                    break;

                case "experimental":
                    worldProvider = new ExperimentalWorldProvider();
                    break;

                case "anvil":
                case "flat":
                case "flatland":
                default:
                    worldProvider = new AnvilWorldProvider
                    {
                        MissingChunkProvider = new FlatlandWorldProvider(),
                        ReadSkyLight         = !Config.GetProperty("CalculateLights", false),
                        ReadBlockLight       = !Config.GetProperty("CalculateLights", false),
                    };
                    break;
                }

                level = new Level(this, name, worldProvider, EntityManager, gameMode, difficulty, viewDistance)
                {
                    EnableBlockTicking = enableBlockTicking,
                    EnableChunkTicking = enableChunkTicking,
                    IsWorldTimeStarted = isWorldTimeStarted
                };
                level.Initialize();

                if (Config.GetProperty("CalculateLights", false))
                {
                    {
                        AnvilWorldProvider wp = level.WorldProvider as AnvilWorldProvider;
                        if (wp != null)
                        {
                            wp.Locked = true;
                            Stopwatch sw = new Stopwatch();

                            var chunkCount = 0;
                            sw.Restart();
                            SkyLightCalculations.Calculate(level);
                            sw.Stop();
                            chunkCount = wp._chunkCache.Where(chunk => chunk.Value != null).ToArray().Length;
                            Log.Debug($"Recalculated sky light for {chunkCount} chunks, {chunkCount * 16 * 16 * 256} blocks. Time {sw.ElapsedMilliseconds}ms");

                            int count = wp.LightSources.Count;
                            sw.Restart();
                            RecalculateBlockLight(level, wp);

                            chunkCount = wp._chunkCache.Where(chunk => chunk.Value != null).ToArray().Length;
                            Log.Debug($"Recalculated sky and block light for {chunkCount} chunks, {chunkCount * 16 * 16 * 256} blocks and {count} light sources. Time {sw.ElapsedMilliseconds}ms. Touched {BlockLightCalculations.touches}");

                            wp.Locked = false;
                        }
                    }
                }

                Levels.Add(level);

                OnLevelCreated(new LevelEventArgs(null, level));
            }

            return(level);
        }
예제 #11
0
        public void Paste(Player player, bool skipAir = false, bool selectAfter = true, bool pastAtOrigin = false)
        {
            try
            {
                RegionSelector selector = RegionSelector.GetSelector(player);

                Clipboard clipboard = selector.Clipboard;
                if (clipboard == null)
                {
                    player.SendMessage("Nothing in clipboard");
                    return;
                }

                Vector3 to = pastAtOrigin ? clipboard.Origin : (BlockCoordinates)player.KnownPosition;

                var rotateY = clipboard.Transform;

                var clipOffset = clipboard.GetMin() - clipboard.Origin;
                var realTo     = to + Vector3.Transform(clipOffset, rotateY);
                var max        = realTo + Vector3.Transform(clipboard.GetMax() - clipboard.GetMin(), rotateY);

                var blocks = clipboard.GetBuffer();
                foreach (Block block in blocks)
                {
                    if (skipAir && block is Air)
                    {
                        continue;
                    }

                    if (rotateY != Matrix4x4.Identity)
                    {
                        Vector3 vec = Vector3.Transform(block.Coordinates - clipboard.Origin, rotateY);
                        block.Coordinates = vec + to;
                    }
                    else
                    {
                        //Vector3 vec = (block.Coordinates - clipboard.Origin);
                        Vector3 vec = new Vector3(
                            block.Coordinates.X - clipboard.Origin.X + to.X,
                            block.Coordinates.Y - clipboard.Origin.Y + to.Y,
                            block.Coordinates.Z - clipboard.Origin.Z + to.Z);

                        block.Coordinates = vec;
                    }

                    EditSession.SetBlock(block);
                }

                if (selectAfter)
                {
                    selector.Select(realTo, max);
                }

                Task.Run(() =>
                {
                    SkyLightCalculations.Calculate(player.Level);
                    player.CleanCache();
                    player.ForcedSendChunks(() =>
                    {
                        player.SendMessage("Calculated skylights and resent chunks.");
                    });
                });
            }
            catch (Exception e)
            {
                Log.Error("Paste", e);
            }
        }