Esempio n. 1
0
        //pre-blends colors when loading plugin so making the image is faster
        public void initBList()
        {
            //adds all the colors for walls/tiles/global
            UInt32 waterColor = 0x093DBF;
            UInt32 lavaColor = 0xFD2003;
            //blends water and lava with UInt32Defs
            using (var blendprog = new ProgressLogger(Main.maxTilesX - 1, "[map] Blending colors"))
                for (int y = 0; y <= Main.maxTilesY + 331; y++)
                {
                    if (UInt32Defs.ContainsKey(y))
                    {
                        UInt32 c = UInt32Defs[y];

                        //initialize DimColorDefs and DimUInt32Defs first
                        UInt32 dimblend = dimI(c);
                        Color dimresult = dimC(c);
                        DimUInt32Defs[y] = dimblend;
                        DimColorDefs[y] = dimresult;

                        UInt32 d = DimUInt32Defs[y];
                        blendprog.Value = y;

                        doBlendResult(c, waterColor, lavaColor, "regular");
                        doBlendResult(d, waterColor, lavaColor, "dim");
                    }
                }
        }
        public static void EveryTileFrame()
        {
            using (var prog = new ProgressLogger (Main.maxTilesX, "Finding tile frames"))
            {
                WorldModify.noLiquidCheck = true;
                WorldModify.noTileActions = true;
                for (int i = 0; i < Main.maxTilesX; i++)
                {
                    prog.Value = i;

                    for (int j = 0; j < Main.maxTilesY; j++)
                    {
                        WorldModify.TileFrame(i, j, true, false);
                    }
                }
                WorldModify.noLiquidCheck = false;
                WorldModify.noTileActions = false;
            }
        }
 public static void AddProgressLogger(ProgressLogger prog)
 {
     Write (new LogEntry (prog, null));
 }
        public static void clearWorld()
        {
            Main.trashItem = new Item();
            WorldModify.spawnEye = false;
            WorldModify.spawnNPC = 0;
            WorldModify.shadowOrbCount = 0;
            Main.helpText = 0;
            Main.dungeonX = 0;
            Main.dungeonY = 0;
            NPC.downedBoss1 = false;
            NPC.downedBoss2 = false;
            NPC.downedBoss3 = false;
            WorldModify.shadowOrbSmashed = false;
            WorldModify.spawnMeteor = false;
            WorldModify.stopDrops = false;
            Main.invasionDelay = 0;
            Main.invasionType = 0;
            Main.invasionSize = 0;
            Main.invasionWarn = 0;
            Main.invasionX = 0.0;
            WorldModify.noLiquidCheck = false;
            Liquid.numLiquid = 0;
            LiquidBuffer.numLiquidBuffer = 0;

            if (WorldModify.lastMaxTilesX > Main.maxTilesX || WorldModify.lastMaxTilesY > Main.maxTilesY)
            {
                using (var prog = new ProgressLogger(WorldModify.lastMaxTilesX - 1, "Freeing unused resources"))
                    for (int i = 0; i < WorldModify.lastMaxTilesX; i++)
                    {
                        prog.Value = i;
                        for (int j = 0; j < WorldModify.lastMaxTilesY; j++)
                        {
                            Main.tile.CreateTileAt(i, j);
                        }
                    }
            }
            WorldModify.lastMaxTilesX = Main.maxTilesX;
            WorldModify.lastMaxTilesY = Main.maxTilesY;

            Server.tile = new TileCollection(Main.maxTilesX, Main.maxTilesY);

            using (var prog = new ProgressLogger(Main.maxTilesX - 1, "Resetting game objects"))
                for (int k = 0; k < Main.maxTilesX; k++)
                {
                    prog.Value = k;
                    for (int l = 0; l < Main.maxTilesY; l++)
                    {
                        Main.tile.CreateTileAt(k, l);
                    }
                }

            for (int num3 = 0; num3 < 200; num3++)
            {
                Main.item[num3] = new Item();
            }
            for (int num4 = 0; num4 < 1000; num4++)
            {
                Main.npcs[num4] = new NPC();
            }
            for (int num5 = 0; num5 < 1000; num5++)
            {
                Main.projectile[num5] = new Projectile();
            }
            for (int num6 = 0; num6 < 1000; num6++)
            {
                Main.chest[num6] = null;
            }
            for (int num7 = 0; num7 < 1000; num7++)
            {
                Main.sign[num7] = null;
            }
            for (int num8 = 0; num8 < Liquid.resLiquid; num8++)
            {
                Main.liquid[num8] = new Liquid();
            }
            for (int num9 = 0; num9 < 10000; num9++)
            {
                Main.liquidBuffer[num9] = new LiquidBuffer();
            }
            setWorldSize();
            worldCleared = true;
        }
        public static void Main(string[] args)
		{
			Thread.CurrentThread.Name = "Main";
            try
            {
                string MODInfo = "Terraria's Dedicated Server Mod. (" + VERSION_NUMBER + " {" + Statics.CURRENT_TERRARIA_RELEASE + "}) #"
					+ Statics.BUILD;
				try
				{
					Console.Title = MODInfo;
				}
				catch
				{

				}

				var lis = new Logging.LogTraceListener ();
				System.Diagnostics.Trace.Listeners.Clear ();
				System.Diagnostics.Trace.Listeners.Add (lis);
				System.Diagnostics.Debug.Listeners.Clear ();
				System.Diagnostics.Debug.Listeners.Add (lis);

				ProgramLog.Log ("Initializing " + MODInfo);

				ProgramLog.Log ("Setting up Paths.");
				if (!SetupPaths())
				{
					return;
				}
				
				Platform.InitPlatform();

				ProgramLog.Log ("Setting up Properties.");
				bool propertiesExist = File.Exists("server.properties");
				SetupProperties();

				if (!propertiesExist)
				{
					ProgramLog.Console.Print ("New properties file created. Would you like to exit for editing? [Y/n]: ");
					if (Console.ReadLine().ToLower() == "y")
					{
						ProgramLog.Console.Print ("Complete, Press any Key to Exit...");
						Console.ReadKey(true);
						return;
					}
				}
				
				var logFile = Statics.DataPath + Path.DirectorySeparatorChar + "server.log";
				ProgramLog.OpenLogFile (logFile);

                string PIDFile = properties.PIDFile.Trim();
				if (PIDFile.Length > 0)
				{
                    string ProcessUID = Process.GetCurrentProcess().Id.ToString();
					bool Issue = false;
					if (File.Exists(PIDFile))
					{
						try
						{
							File.Delete(PIDFile);
						}
						catch (Exception)
						{
							ProgramLog.Console.Print ("Issue deleting PID file, Continue? [Y/n]: ");
							if (Console.ReadLine().ToLower() == "n")
							{
								ProgramLog.Console.Print ("Press any Key to Exit...");
								Console.ReadKey(true);
								return;
							}
							Issue = true;
						}
					}
					if (!Issue)
					{
						try
						{
							File.WriteAllText(PIDFile, ProcessUID);
						}
						catch (Exception)
						{
							ProgramLog.Console.Print ("Issue creating PID file, Continue? [Y/n]: ");
							if (Console.ReadLine().ToLower() == "n")
							{
								ProgramLog.Console.Print ("Press any Key to Exit...");
								Console.ReadKey(true);
								return;
							}
						}
						ProgramLog.Log ("PID File Created, Process ID: " + ProcessUID);
					}
				}

				ParseArgs(args);

				try
				{
					if (UpdateManager.performProcess())
					{
						ProgramLog.Log ("Restarting into new update!");
						return;
					}
				}
				catch (UpdateCompleted)
				{
					throw;
				}
				catch (Exception e)
				{
					ProgramLog.Log (e, "Error updating");
				}
				
				LoadMonitor.Start ();
				
				ProgramLog.Log ("Starting remote console server");
				RemoteConsole.RConServer.Start ("rcon_logins.properties");

				ProgramLog.Log("Starting permissions manager");
				permissionManager = new PermissionManager();
				
				ProgramLog.Log ("Preparing Server Data...");
				
				using (var prog = new ProgressLogger (1, "Loading item definitions"))
					Collections.Registries.Item.Load ();
				using (var prog = new ProgressLogger (1, "Loading NPC definitions"))
					Collections.Registries.NPC.Load (Collections.Registries.NPC_FILE);
				using (var prog = new ProgressLogger (1, "Loading projectile definitions"))
					Collections.Registries.Projectile.Load (Collections.Registries.PROJECTILE_FILE);
                                
                commandParser = new CommandParser();
                commandParser.ReadPermissionNodes();
				
				ProgramLog.Log("Loading plugins...");
                Terraria_Server.Plugins.PluginManager.Initialize(Statics.PluginPath, Statics.LibrariesPath);

                var ctx = new HookContext()
                {
                    Sender = new ConsoleSender()
                };

                var eArgs = new HookArgs.ServerStateChange()
                {
                    ServerChangeState = ServerState.INITIALIZING
                };

                HookPoints.ServerStateChange.Invoke(ref ctx, ref eArgs);
				PluginManager.LoadPlugins ();
				ProgramLog.Log("Plugins loaded: " + PluginManager.PluginCount);
				
                string worldFile = properties.WorldPath;
				FileInfo file = new FileInfo(worldFile);

				if (!file.Exists)
				{
					try
					{
						file.Directory.Create();
					}
					catch (Exception exception)
					{
						ProgramLog.Log (exception);
						ProgramLog.Console.Print ("Press any key to continue...");
						Console.ReadKey(true);
						return;
					}

                    ctx = new HookContext
                    {
                        Sender = new WorldSender(),
                    };

                    eArgs = new HookArgs.ServerStateChange
                    {
                        ServerChangeState = ServerState.GENERATING
                    };

                    HookPoints.ServerStateChange.Invoke(ref ctx, ref eArgs);

					ProgramLog.Log ("Generating world '{0}'", worldFile);

                    string seed = properties.Seed;
					if (seed == "-1")
					{
						seed = new Random().Next(100).ToString();
						ProgramLog.Log ("Generated seed: {0}", seed);
					}

					int worldX = properties.GetMapSizes()[0];
					int worldY = properties.GetMapSizes()[1];
					if (properties.UseCustomTiles)
					{
						int X = properties.MaxTilesX;
						int Y = properties.MaxTilesY;
						if (X > 0 && Y > 0)
						{
							worldX = X;
							worldY = Y;
						}

						if (worldX < (int)World.MAP_SIZE.SMALL_X || worldY < (int)World.MAP_SIZE.SMALL_Y)
						{
							ProgramLog.Log ("World dimensions need to be equal to or larger than {0} by {1}; using built-in 'small'", (int)World.MAP_SIZE.SMALL_X, (int)World.MAP_SIZE.SMALL_Y);
							worldX = (int)((int)World.MAP_SIZE.SMALL_Y * 3.5);
							worldY = (int)World.MAP_SIZE.SMALL_Y;
						}

						ProgramLog.Log ("Generating world with custom map size: {0}x{1}", worldX, worldY);
					}

                    Terraria_Server.Main.maxTilesX = worldX;
                    Terraria_Server.Main.maxTilesY = worldY;

					WorldIO.clearWorld();
                    Terraria_Server.Main.Initialize();
					if (properties.UseCustomGenOpts)
					{
						WorldGen.numDungeons = properties.DungeonAmount;
						WorldModify.ficount = properties.FloatingIslandAmount;
					}
					else
					{
						WorldGen.numDungeons = 1;
                        WorldModify.ficount = (int)((double)Terraria_Server.Main.maxTilesX * 0.0008); //The Statics one was generating with default values, We want it to use the actual tileX for the world
					}
                    WorldGen.GenerateWorld(seed);
					WorldIO.saveWorld(worldFile, true);
				}
                
                ctx = new HookContext
                {
                    Sender = new WorldSender(),
                };

                eArgs = new HookArgs.ServerStateChange
                {
                    ServerChangeState = ServerState.LOADING
                };

                HookPoints.ServerStateChange.Invoke(ref ctx, ref eArgs);
				
				// TODO: read map size from world file instead of config
				int worldXtiles = properties.GetMapSizes()[0];
				int worldYtiles = properties.GetMapSizes()[1];

				if (properties.UseCustomTiles)
				{
					int X = properties.MaxTilesX;
					int Y = properties.MaxTilesY;
					if (X > 0 && Y > 0)
					{
						worldXtiles = X;
						worldYtiles = Y;
					}

					if (worldXtiles < (int)World.MAP_SIZE.SMALL_X || worldYtiles < (int)World.MAP_SIZE.SMALL_Y)
					{
						ProgramLog.Log ("World dimensions need to be equal to or larger than {0} by {1}; using built-in 'small'", (int)World.MAP_SIZE.SMALL_X, (int)World.MAP_SIZE.SMALL_Y);
						worldXtiles = (int)((int)World.MAP_SIZE.SMALL_Y * 3.5);
						worldYtiles = (int)World.MAP_SIZE.SMALL_Y;
					}

					ProgramLog.Log ("Using world with custom map size: {0}x{1}", worldXtiles, worldYtiles);
				}

				World world = new World(worldXtiles, worldYtiles);
				world.SavePath = worldFile;

				Server.InitializeData(world, properties.MaxPlayers,
					Statics.DataPath + Path.DirectorySeparatorChar + "whitelist.txt",
					Statics.DataPath + Path.DirectorySeparatorChar + "banlist.txt",
					Statics.DataPath + Path.DirectorySeparatorChar + "oplist.txt");
				NetPlay.password = properties.Password;
                NetPlay.serverPort = properties.Port;
                NetPlay.serverSIP = properties.ServerIP;
				Terraria_Server.Main.Initialize();
				
				Terraria_Server.Main.maxTilesX = worldXtiles;
				Terraria_Server.Main.maxTilesY = worldYtiles;
                Terraria_Server.Main.maxSectionsX = worldXtiles / 200;
				Terraria_Server.Main.maxSectionsY = worldYtiles / 150;

                WorldIO.LoadWorld(Server.World.SavePath);
                
                ctx = new HookContext
                {
                    Sender = new WorldSender(),
                };

                eArgs = new HookArgs.ServerStateChange
                {
                    ServerChangeState = ServerState.LOADED
                };

                HookPoints.ServerStateChange.Invoke(ref ctx, ref eArgs);

				updateThread = new ProgramThread ("Updt", Program.UpdateLoop);

				ProgramLog.Log ("Starting the Server");
				NetPlay.StartServer();
				
				while (!NetPlay.ServerUp) { }

				ProgramLog.Console.Print ("You can now insert Commands.");

                while (!Statics.Exit)
				{
					try
					{
                        string line = Console.ReadLine();
						if (line.Length > 0)
						{
							commandParser.ParseConsoleCommand(line);
						}
                    }
                    catch (ExitException e)
                    {
                        ProgramLog.Log(e.Message);
                        break;
                    }
					catch (Exception e)
					{
						ProgramLog.Log (e, "Issue parsing console command");
					}
				}

                while(WorldModify.saveLock || NetPlay.ServerUp)
                    Thread.Sleep(100);

                ProgramLog.Log("Exiting...");
                Thread.Sleep(1000);
            }
            catch (UpdateCompleted)
            {
            }
            catch (Exception e)
            {
                try
                {
                    using (StreamWriter streamWriter = new StreamWriter(Statics.DataPath + Path.DirectorySeparatorChar + "crashlog.txt", true))
                    {
                        streamWriter.WriteLine(DateTime.Now);
                        streamWriter.WriteLine("Crash Log Generated by TDSM #" + Statics.BUILD + " for " + //+ " r" + Statics.revision + " for " +
                            VERSION_NUMBER + " {" + Statics.CURRENT_TERRARIA_RELEASE + "}");
                        streamWriter.WriteLine(e);
                        streamWriter.WriteLine("");
                    }
                    ProgramLog.Log(e, "Program crash");
                    ProgramLog.Log("Please send crashlog.txt to http://tdsm.org/");
                }
                catch
                {
                }
            }

            if (File.Exists(properties.PIDFile.Trim()))
            {
                File.Delete(properties.PIDFile.Trim());
            }

			Thread.Sleep (500);
			ProgramLog.Log ("Log end.");
			ProgramLog.Close();
			
			RemoteConsole.RConServer.Stop ();
		}
        public static void EveryTileFrame(Func<Int32, Int32, ITile> TileRefs, ISandbox sandbox)
        {
            if (TileRefs == null)
                TileRefs = TileCollection.ITileAt;

            using (var prog = new ProgressLogger(Main.maxTilesX, "Finding tile frames"))
            {
                noLiquidCheck = true;
                noTileActions = true;
                for (int i = 0; i < Main.maxTilesX; i++)
                {
                    prog.Value = i;

                    for (int j = 0; j < Main.maxTilesY; j++)
                    {
                        if (TileRefs(i, j).Active)
                        {
                            TileFrame(TileRefs, sandbox, i, j, true, false);
                        }
                        if (TileRefs(i, j).Wall > 0)
                        {
                            WallFrame(TileRefs, i, j, true);
                        }
                    }
                }
                noLiquidCheck = false;
                noTileActions = false;
            }
        }
        public static void clearWorld()
        {
            Statics.WorldLoaded = false;

            Main.trashItem = new Item();
            WorldModify.spawnEye = false;
            WorldModify.spawnNPC = 0;
            WorldModify.shadowOrbCount = 0;
            Main.helpText = 0;
            Main.dungeonX = 0;
            Main.dungeonY = 0;
            NPC.downedBoss1 = false;
            NPC.downedBoss2 = false;
            NPC.downedBoss3 = false;
            WorldModify.shadowOrbSmashed = false;
            WorldModify.spawnMeteor = false;
            WorldModify.stopDrops = false;
            Main.invasionDelay = 0;
            Main.invasionType = 0;
            Main.invasionSize = 0;
            Main.invasionWarn = 0;
            Main.invasionX = 0.0;
            WorldModify.noLiquidCheck = false;
            Liquid.numLiquid = 0;
            LiquidBuffer.numLiquidBuffer = 0;

            //			if (WorldModify.lastMaxTilesX > Main.maxTilesX || WorldModify.lastMaxTilesY > Main.maxTilesY)
            //			{
            //				using (var prog = new ProgressLogger(WorldModify.lastMaxTilesX - 1, "Freeing unused resources"))
            //					for (int i = 0; i < WorldModify.lastMaxTilesX; i++)
            //					{
            //						prog.Value = i;
            //						for (int j = 0; j < WorldModify.lastMaxTilesY; j++)
            //						{
            //							Main.tile.CreateTileAt(i, j);
            //						}
            //					}
            //			}
            WorldModify.lastMaxTilesX = Main.maxTilesX;
            WorldModify.lastMaxTilesY = Main.maxTilesY;

            if (Main.tile == null || Main.tile.SizeX != Main.maxTilesX || Main.tile.SizeY != Main.maxTilesY)
            {
                Main.tile = null;
                GC.Collect ();
                Main.tile = new TileCollection(Main.maxTilesX, Main.maxTilesY);
            }
            else
            {
                using (var prog = new ProgressLogger(Main.maxTilesX - 1, "Clearing world tiles"))
                    for (int k = 0; k < Main.maxTilesX; k++)
                    {
                        prog.Value = k;
                        for (int l = 0; l < Main.maxTilesY; l++)
                        {
                            Main.tile.CreateTileAt(k, l);
            // for testing
            //							if ((l == 25 || l == 26) && k > 4000 && k < 5000)
            //							{
            //								Main.tile.At(k, l).SetLiquid (250);
            //								Liquid.AddWater (k, l);
            //							}
                        }
                    }
            }

            using (var prog = new ProgressLogger(12212 + Liquid.resLiquid - 1, "Resetting game objects"))
            {
                for (int num3 = 0; num3 < 200; num3++)
                {
                    Main.item[num3] = null;
                }
                prog.Value++;

                for (int num4 = 0; num4 < 1000; num4++)
                {
                    Main.npcs[num4] = null;
                    Main.projectile[num4] = null;
                    Main.chest[num4] = null;
                    Main.sign[num4] = null;
                }
                prog.Value++;

            //				for (int num8 = 0; num8 < Liquid.resLiquid; num8++)
            //				{
            //					Main.liquid[num8] = null;
            //				}
            //				prog.Value++;

            //				for (int num9 = 0; num9 < 10000; num9++)
            //				{
            //					Main.liquidBuffer[num9] = null;
            //				}
            //				prog.Value += 10;

                GC.Collect ();
                prog.Value += 10;

                for (int num3 = 0; num3 < 200; num3++)
                {
                    Main.item[num3] = new Item();
                    prog.Value++;
                }
                for (int num4 = 0; num4 < 1000; num4++)
                {
                    Main.npcs[num4] = new NPC();
                    prog.Value++;
                }
            //				for (int num5 = 0; num5 < 1000; num5++)
            //				{
            //					Main.projectile[num5] = new Projectile();
            //					prog.Value++;
            //				}
                Projectile.ResetProjectiles ();
                prog.Value += 1000;
                for (int num8 = 0; num8 < Liquid.resLiquid; num8++)
                {
                    Main.liquid[num8] = new Liquid();
                    prog.Value++;
                }
                for (int num9 = 0; num9 < 10000; num9++)
                {
                    Main.liquidBuffer[num9] = new LiquidBuffer();
                    prog.Value++;
                }
            }
            setWorldSize();

            LiquidUpdateBuffer.Initialize (Main.maxSectionsX, Main.maxSectionsY);

            worldCleared = true;
        }
        public static void LoadWorld(Func<Int32, Int32, ITile> TileRefs, ISandbox sandbox, string LoadPath)
        {
            if (TileRefs == null)
                TileRefs = TileCollection.ITileAt;

            Main.checkXmas();

            using (FileStream fileStream = new FileStream(LoadPath, FileMode.Open))
            {
                using (BinaryReader binaryReader = new BinaryReader(fileStream))
                {
                    try
                    {
                        WorldModify.loadFailed = false;
                        WorldModify.loadSuccess = false;
                        int Terraria_Release = binaryReader.ReadInt32();
                        if (Terraria_Release > Statics.CURRENT_TERRARIA_RELEASE)
                        {
                            WorldModify.loadFailed = true;
                            WorldModify.loadSuccess = false;
                            try
                            {
                                binaryReader.Close();
                                fileStream.Close();
                            }
                            catch
                            {
                            }
                        }
                        else
                        {
                            Main.worldName = binaryReader.ReadString();
                            Main.worldID = binaryReader.ReadInt32();
                            Main.leftWorld = (float)binaryReader.ReadInt32();
                            Main.rightWorld = (float)binaryReader.ReadInt32();
                            Main.topWorld = (float)binaryReader.ReadInt32();
                            Main.bottomWorld = (float)binaryReader.ReadInt32();
                            Main.maxTilesY = binaryReader.ReadInt32();
                            Main.maxTilesX = binaryReader.ReadInt32();
                            Main.maxSectionsX = Main.maxTilesX / 200;
                            Main.maxSectionsY = Main.maxTilesY / 150;
                            ClearWorld();
                            Main.spawnTileX = binaryReader.ReadInt32();
                            Main.spawnTileY = binaryReader.ReadInt32();
                            Main.worldSurface = binaryReader.ReadDouble();
                            Main.rockLayer = binaryReader.ReadDouble();
                            tempTime = binaryReader.ReadDouble();
                            tempDayTime = binaryReader.ReadBoolean();
                            tempMoonPhase = binaryReader.ReadInt32();
                            tempBloodMoon = binaryReader.ReadBoolean();
                            Main.dungeonX = binaryReader.ReadInt32();
                            Main.dungeonY = binaryReader.ReadInt32();
                            NPC.downedBoss1 = binaryReader.ReadBoolean();
                            NPC.downedBoss2 = binaryReader.ReadBoolean();
                            NPC.downedBoss3 = binaryReader.ReadBoolean();
                            if (Terraria_Release >= 29)
                            {
                                NPC.savedGoblin = binaryReader.ReadBoolean();
                                NPC.savedWizard = binaryReader.ReadBoolean();
                                if (Terraria_Release >= 34)
                                {
                                    NPC.savedMech = binaryReader.ReadBoolean();
                                }
                                NPC.downedGoblins = binaryReader.ReadBoolean();
                            }
                            if (Terraria_Release >= 32)
                            {
                                NPC.downedClown = binaryReader.ReadBoolean();
                            }
                            if (Terraria_Release >= 37)
                            {
                                NPC.downedFrost = binaryReader.ReadBoolean();
                            }
                            WorldModify.shadowOrbSmashed = binaryReader.ReadBoolean();
                            WorldModify.spawnMeteor = binaryReader.ReadBoolean();
                            WorldModify.shadowOrbCount = (int)binaryReader.ReadByte();
                            if (Terraria_Release >= 23)
                            {
                                WorldModify.altarCount = binaryReader.ReadInt32();
                                Main.hardMode = binaryReader.ReadBoolean();
                            }
                            Main.invasionDelay = binaryReader.ReadInt32();
                            Main.invasionSize = binaryReader.ReadInt32();
                            Main.invasionType = (InvasionType)binaryReader.ReadInt32();
                            Main.invasionX = binaryReader.ReadDouble();

                            using (var prog = new ProgressLogger(Main.maxTilesX - 1, Languages.LoadingWorldTiles))
                            {
                                for (int j = 0; j < Main.maxTilesX; j++)
                                {
                                    prog.Value = j;

                                    for (int k = 0; k < Main.maxTilesY; k++)
                                    {
                                        Main.tile.At(j, k).SetActive(binaryReader.ReadBoolean());
                                        if (Main.tile.At(j, k).Active)
                                        {
                                            Main.tile.At(j, k).SetType(binaryReader.ReadByte());

                                            if (Main.tile.At(j, k).Type == 127)
                                                Main.tile.At(j, k).SetActive(false);

                                            if (Main.tileFrameImportant[(int)Main.tile.At(j, k).Type])
                                            {
                                                if (Terraria_Release < 28 && Main.tile.At(j, k).Type == 4)
                                                {
                                                    Main.tile.At(j, k).SetFrameX(0);
                                                    Main.tile.At(j, k).SetFrameY(0);
                                                }
                                                else
                                                {
                                                    Main.tile.At(j, k).SetFrameX(binaryReader.ReadInt16());
                                                    Main.tile.At(j, k).SetFrameY(binaryReader.ReadInt16());
                                                    if (Main.tile.At(j, k).Type == 144)
                                                    {
                                                        Main.tile.At(j, k).SetFrameY(0);
                                                    }
                                                }
                                            }
                                            else
                                            {
                                                Main.tile.At(j, k).SetFrameX(-1);
                                                Main.tile.At(j, k).SetFrameY(-1);
                                            }
                                        }
                                        if (Terraria_Release <= 25)
                                        {
                                            /*Main.tile.At(j, k).SetLighted(*/
                                            binaryReader.ReadBoolean();
                                            /*);*/
                                        }
                                        if (binaryReader.ReadBoolean())
                                        {
                                            Main.tile.At(j, k).SetWall(binaryReader.ReadByte());
                                            //											if (Main.tile.At(j, k).Wall == 7)
                                            //												Main.tile.At(j, k).SetWall (17);
                                        }
                                        if (binaryReader.ReadBoolean())
                                        {
                                            Main.tile.At(j, k).SetLiquid(binaryReader.ReadByte());
                                            Main.tile.At(j, k).SetLava(binaryReader.ReadBoolean());
                                        }
                                        if (Terraria_Release >= 33)
                                        {
                                            Main.tile.At(j, k).SetWire(binaryReader.ReadBoolean());
                                        }
                                        if (Terraria_Release >= 25)
                                        {
                                            int num3 = (int)binaryReader.ReadInt16();
                                            if (num3 > 0)
                                            {
                                                for (int l = k + 1; l < k + num3 + 1; l++)
                                                {
                                                    Main.tile.At(j, l).SetActive(Main.tile.At(j, k).Active);
                                                    Main.tile.At(j, l).SetType(Main.tile.At(j, k).Type);
                                                    Main.tile.At(j, l).SetWall(Main.tile.At(j, k).Wall);
                                                    Main.tile.At(j, l).SetFrameX(Main.tile.At(j, k).FrameX);
                                                    Main.tile.At(j, l).SetFrameY(Main.tile.At(j, k).FrameY);
                                                    Main.tile.At(j, l).SetLiquid(Main.tile.At(j, k).Liquid);
                                                    Main.tile.At(j, l).SetLava(Main.tile.At(j, k).Lava);
                                                    Main.tile.At(j, l).SetWire(Main.tile.At(j, k).Wire);
                                                }
                                                k += num3;
                                            }
                                        }
                                    }
                                }
                            }

                            for (int l = 0; l < Main.MAX_CHESTS; l++)
                            {
                                if (binaryReader.ReadBoolean())
                                {
                                    var x = binaryReader.ReadInt32();
                                    var y = binaryReader.ReadInt32();
                                    Main.chest[l] = Chest.InitializeChest(x, y);
                                    for (int m = 0; m < Chest.MAX_ITEMS; m++)
                                    {
                                        //Main.chest[l].contents[m] = new Item();
                                        int stack = binaryReader.ReadByte();
                                        if (stack > 0)
                                        {
                                            if (Terraria_Release >= 38)
                                            {
                                                Main.chest[l].contents[m] = Item.netDefaults(binaryReader.ReadInt32());
                                                Main.chest[l].contents[m].Stack = stack;
                                            }
                                            else
                                            {
                                                string defaults = Item.VersionName(binaryReader.ReadString(), Terraria_Release);
                                                Main.chest[l].contents[m] = Registries.Item.Create(defaults, stack);
                                            }

                                            if (Terraria_Release >= 36)
                                                Main.chest[l].contents[m].SetPrefix((int)binaryReader.ReadByte());
                                        }
                                    }
                                }
                            }
                            for (int n = 0; n < Main.MAX_SIGNS; n++)
                            {
                                if (binaryReader.ReadBoolean())
                                {
                                    string text = binaryReader.ReadString();
                                    int x = binaryReader.ReadInt32();
                                    int y = binaryReader.ReadInt32();
                                    if (Main.tile.At(x, y).Active && (Main.tile.At(x, y).Type == 55 || Main.tile.At(x, y).Type == 85))
                                    {
                                        Main.sign[n] = new Sign();
                                        Main.sign[n].x = x;
                                        Main.sign[n].y = y;
                                        Main.sign[n].text = text;
                                    }
                                }
                            }
                            bool flag = binaryReader.ReadBoolean();
                            int num5 = 0;
                            while (flag)
                            {
                                string NPCName = binaryReader.ReadString();
                                Main.npcs[num5] = Registries.NPC.Create(NPCName);
                                Main.npcs[num5].Position.X = binaryReader.ReadSingle();
                                Main.npcs[num5].Position.Y = binaryReader.ReadSingle();
                                Main.npcs[num5].homeless = binaryReader.ReadBoolean();
                                Main.npcs[num5].homeTileX = binaryReader.ReadInt32();
                                Main.npcs[num5].homeTileY = binaryReader.ReadInt32();
                                flag = binaryReader.ReadBoolean();
                                num5++;
                            }
                            if (Terraria_Release >= 31)
                            {
                                Main.chrName[17] = binaryReader.ReadString();
                                Main.chrName[18] = binaryReader.ReadString();
                                Main.chrName[19] = binaryReader.ReadString();
                                Main.chrName[20] = binaryReader.ReadString();
                                Main.chrName[22] = binaryReader.ReadString();
                                Main.chrName[54] = binaryReader.ReadString();
                                Main.chrName[38] = binaryReader.ReadString();
                                Main.chrName[107] = binaryReader.ReadString();
                                Main.chrName[108] = binaryReader.ReadString();
                                if (Terraria_Release >= 35)
                                {
                                    Main.chrName[124] = binaryReader.ReadString();
                                }
                            }
                            if (Terraria_Release >= 7)
                            {
                                bool flag2 = binaryReader.ReadBoolean();
                                string worldName = binaryReader.ReadString();
                                int num6 = binaryReader.ReadInt32();
                                if (!flag2 || !(worldName == Main.worldName) || num6 != Main.worldID)
                                {
                                    WorldModify.loadSuccess = false;
                                    WorldModify.loadFailed = true;
                                    binaryReader.Close();
                                    fileStream.Close();
                                    return;
                                }
                                WorldModify.loadSuccess = true;
                            }
                            else
                            {
                                WorldModify.loadSuccess = true;
                            }
                            binaryReader.Close();
                            fileStream.Close();

                            if (!WorldModify.loadFailed && WorldModify.loadSuccess)
                            {
                                WorldModify.gen = true;
                                using (var prog = new ProgressLogger(Main.maxTilesX, Languages.CheckingTileAlignment))
                                {
                                    for (int num9 = 0; num9 < Main.maxTilesX; num9++)
                                    {
                                        float num10 = (float)num9 / (float)Main.maxTilesX;
                                        //WorldModify.statusText = "Checking tile alignment: " + (int)(num10 * 100f + 1f) + "%";
                                        WorldModify.CountTiles(TileRefs, num9);
                                        prog.Value++;
                                    }
                                }

                                //ProgramLog.Log("Loading NPC Names...");
                                //NPC.SetNames();

                                ProgramLog.Log(Languages.Water_PreparingLiquids);
                                WorldModify.waterLine = Main.maxTilesY;
                                Liquid.QuickWater(TileRefs, sandbox, 2, -1, -1);
                                WorldModify.WaterCheck(TileRefs, sandbox);

                                int num11 = 0;
                                Liquid.quickSettle = true;
                                int num12 = Liquid.numLiquid + LiquidBuffer.numLiquidBuffer;
                                float num13 = 0f;

                                var pres = Liquid.numLiquid;
                                using (var prog = new ProgressLogger(Liquid.maxLiquid, Languages.Generation_SettlingLiquids))
                                {
                                    while (Liquid.numLiquid > 0 && num11 < 100000)
                                    {
                                        num11++;
                                        float num14 = (float)(num12 - (Liquid.numLiquid + LiquidBuffer.numLiquidBuffer)) / (float)num12;
                                        if (Liquid.numLiquid + LiquidBuffer.numLiquidBuffer > num12)
                                        {
                                            num12 = Liquid.numLiquid + LiquidBuffer.numLiquidBuffer;
                                        }
                                        if (num14 > num13)
                                        {
                                            num13 = num14;
                                        }
                                        else
                                        {
                                            num14 = num13;
                                        }

                                        prog.Value = Liquid.numLiquid;

                                        Liquid.UpdateLiquid(TileRefs, sandbox);
                                    }
                                }

                                Liquid.quickSettle = false;

                                ProgramLog.Log(Languages.Water_PerformingWaterCheck);
                                WorldModify.WaterCheck(TileRefs, sandbox);
                                WorldModify.gen = false;
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        WorldModify.loadFailed = true;
                        WorldModify.loadSuccess = false;
                        try
                        {
                            binaryReader.Close();
                            fileStream.Close();
                        }
                        catch { }

                        ProgramLog.Error.Log(
                            String.Format("Error Loading world:\n{0}\nStack Trace: {1}", e, e.StackTrace)
                        );

                        return;
                    }
                }
            }

            if (String.IsNullOrEmpty(Main.worldName))
                Main.worldName = System.IO.Path.GetFileNameWithoutExtension(LoadPath);

            Statics.WorldLoaded = true;

            PluginManager.NotifyWorldLoaded();

            var ctx = new HookContext
            {
            };

            var args = new HookArgs.WorldLoaded
            {
                Height = Main.maxTilesY,
                Width = Main.maxTilesX,
            };

            HookPoints.WorldLoaded.Invoke(ref ctx, ref args);
        }
        public static void AddClay(Func<Int32, Int32, ITile> TileRefs)
        {
            if (TileRefs == null)
                TileRefs = TileCollection.ITileAt;

            var Max = (int)((double)(Main.maxTilesX * Main.maxTilesY) * 2E-05);
            var Max2 = (int)((double)(Main.maxTilesX * Main.maxTilesY) * 5E-05);
            var Max3 = (int)((double)(Main.maxTilesX * Main.maxTilesY) * 2E-05);
            var Max4 = Main.maxTilesX - 5;
            using (var clayProg = new ProgressLogger(Max + Max2 + Max3 + Max4, Languages.Generation_AddingClay))
            {
                for (int i = 0; i < Max; i++)
                {
                    TileRunner(TileRefs, WorldModify.genRand.Next(0, Main.maxTilesX), WorldModify.genRand.Next(0, (int)terrarainMaxY), (double)WorldModify.genRand.Next(4, 14), WorldModify.genRand.Next(10, 50), 40, false, 0f, 0f, false, true);
                    clayProg.Value++;
                }
                for (int i = 0; i < Max2; i++)
                {
                    TileRunner(TileRefs, WorldModify.genRand.Next(0, Main.maxTilesX), WorldModify.genRand.Next((int)terrarainMaxY, (int)worldSurface + 1), (double)WorldModify.genRand.Next(8, 14), WorldModify.genRand.Next(15, 45), 40, false, 0f, 0f, false, true);
                    clayProg.Value++;
                }
                for (int i = 0; i < Max3; i++)
                {
                    TileRunner(TileRefs, WorldModify.genRand.Next(0, Main.maxTilesX), WorldModify.genRand.Next((int)worldSurface, (int)rockLayer + 1), (double)WorldModify.genRand.Next(8, 15), WorldModify.genRand.Next(5, 50), 40, false, 0f, 0f, false, true);
                    clayProg.Value++;
                }
                for (int posX = 5; posX < Max4; posX++)
                {
                    int startY = 1;
                    while ((double)startY < Main.worldSurface - 1.0)
                    {
                        if (TileRefs(posX, startY).Active)
                        {
                            for (int posY = startY; posY < startY + 5; posY++)
                            {
                                if (TileRefs(posX, posY).Type == 40)
                                {
                                    TileRefs(posX, posY).SetType(0);
                                }
                            }
                            break;
                        }
                        startY++;
                    }
                    clayProg.Value++;
                }
            }
        }
        public static void PlaceAltars(Func<Int32, Int32, ITile> TileRefs)
        {
            if (TileRefs == null)
                TileRefs = TileCollection.ITileAt;

            var MaxAltar = (int)((double)(Main.maxTilesX * Main.maxTilesY) * 2E-05);
            using (var prog = new ProgressLogger(MaxAltar - 1, Languages.Generation_PlacingAltars))
            {
                for (int i = 0; i < MaxAltar; i++)
                {
                    prog.Value = i;

                    //bool flag11 = false;
                    int maxAltar = 0;
                    while (true)
                    {
                        int tileX = WorldModify.genRand.Next(1, Main.maxTilesX);
                        int tileY = (int)(worldSurface + 20.0);
                        WorldModify.Place3x2(TileRefs, tileX, tileY, 26);
                        if (TileRefs(tileX, tileY).Type == 26)
                        {
                            //flag11 = true;
                            break;
                        }
                        else
                        {
                            maxAltar++;
                            if (maxAltar >= 10000)
                            {
                                //flag11 = true;
                                break;
                            }
                        }
                    }
                }
            }
        }
        public static void MakeWorldEvil(Func<Int32, Int32, ITile> TileRefs)
        {
            if (TileRefs == null)
                TileRefs = TileCollection.ITileAt;

            int evilSegment = 0;

            using (var prog = new ProgressLogger(100, Languages.Generation_MakingTheWorldEvil))
            {
                while ((double)evilSegment < (double)Main.maxTilesX * 0.00045)
                {
                    float num145 = (float)((double)evilSegment / ((double)Main.maxTilesX * 0.00045));

                    prog.Value = (int)(num145 * 100f);

                    bool flag8 = false;
                    int chasmX = 0;
                    int chasmStartX = 0;
                    int chasmEndX = 0;
                    while (!flag8)
                    {
                        int jungleLength = 0;
                        flag8 = true;
                        int MaxTileX_d2 = Main.maxTilesX / 2;
                        int cOutlier = 200;
                        chasmX = WorldModify.genRand.Next(320, Main.maxTilesX - 320);
                        chasmStartX = chasmX - WorldModify.genRand.Next(200) - 100;
                        chasmEndX = chasmX + WorldModify.genRand.Next(200) + 100;
                        if (chasmStartX < 285)
                        {
                            chasmStartX = 285;
                        }
                        if (chasmEndX > Main.maxTilesX - 285)
                        {
                            chasmEndX = Main.maxTilesX - 285;
                        }
                        if (chasmX > MaxTileX_d2 - cOutlier && chasmX < MaxTileX_d2 + cOutlier)
                        {
                            flag8 = false;
                        }
                        if (chasmStartX > MaxTileX_d2 - cOutlier && chasmStartX < MaxTileX_d2 + cOutlier)
                        {
                            flag8 = false;
                        }
                        if (chasmEndX > MaxTileX_d2 - cOutlier && chasmEndX < MaxTileX_d2 + cOutlier)
                        {
                            flag8 = false;
                        }
                        for (int tileX = chasmStartX; tileX < chasmEndX; tileX++)
                        {
                            for (int tileY = 0; tileY < (int)Main.worldSurface; tileY += 5)
                            {
                                if (TileRefs(tileX, tileY).Active && Main.tileDungeon[(int)TileRefs(tileX, tileY).Type])
                                {
                                    flag8 = false;
                                    break;
                                }
                                if (!flag8)
                                {
                                    break;
                                }
                            }
                        }
                        if (jungleLength < 200 && JungleX > chasmStartX && JungleX < chasmEndX)
                        {
                            jungleLength++;
                            flag8 = false;
                        }
                    }
                    int tilePass = 0;
                    for (int tileX = chasmStartX; tileX < chasmEndX; tileX++)
                    {
                        if (tilePass > 0)
                        {
                            tilePass--;
                        }
                        if (tileX == chasmX || tilePass == 0)
                        {
                            int tileY = (int)terrarainMaxY;
                            while ((double)tileY < Main.worldSurface - 1.0)
                            {
                                if (TileRefs(tileX, tileY).Active || TileRefs(tileX, tileY).Wall > 0)
                                {
                                    if (tileX == chasmX)
                                    {
                                        tilePass = 20;
                                        ChasmRunner(TileRefs, tileX, tileY, WorldModify.genRand.Next(150) + 150, true);
                                    }
                                    if (WorldModify.genRand.Next(35) == 0 && tilePass == 0)
                                    {
                                        tilePass = 30;
                                        ChasmRunner(TileRefs, tileX, tileY, WorldModify.genRand.Next(50) + 50, true);
                                    }
                                    break;
                                }
                                else
                                {
                                    tileY++;
                                }
                            }
                        }
                        int tileYCheck = (int)terrarainMaxY;
                        while ((double)tileYCheck < Main.worldSurface - 1.0)
                        {
                            if (TileRefs(tileX, tileYCheck).Active)
                            {
                                int resetY = tileYCheck + WorldModify.genRand.Next(10, 14);
                                for (int tileY = tileYCheck; tileY < resetY; tileY++)
                                {
                                    if ((TileRefs(tileX, tileY).Type == 59 || TileRefs(tileX, tileY).Type == 60) && tileX >= chasmStartX + WorldModify.genRand.Next(5) && tileX < chasmEndX - WorldModify.genRand.Next(5))
                                    {
                                        TileRefs(tileX, tileY).SetType(0);
                                    }
                                }
                                break;
                            }
                            tileYCheck++;
                        }
                    }
                    double chasmTop = Main.worldSurface + 40.0;
                    for (int chasmCycle = chasmStartX; chasmCycle < chasmEndX; chasmCycle++)
                    {
                        chasmTop += (double)WorldModify.genRand.Next(-2, 3);
                        if (chasmTop < Main.worldSurface + 30.0)
                        {
                            chasmTop = Main.worldSurface + 30.0;
                        }
                        if (chasmTop > Main.worldSurface + 50.0)
                        {
                            chasmTop = Main.worldSurface + 50.0;
                        }
                        int tileX = chasmCycle;
                        bool flag9 = false;
                        int tileY = (int)terrarainMaxY;
                        while ((double)tileY < chasmTop)
                        {
                            if (TileRefs(tileX, tileY).Active)
                            {
                                if (TileRefs(tileX, tileY).Type == 53 && tileX >= chasmStartX + WorldModify.genRand.Next(5) && tileX <= chasmEndX - WorldModify.genRand.Next(5))
                                {
                                    TileRefs(tileX, tileY).SetType(0);
                                }
                                if (TileRefs(tileX, tileY).Type == 0 && (double)tileY < Main.worldSurface - 1.0 && !flag9)
                                {
                                    WorldModify.SpreadGrass(TileRefs, tileX, tileY, 0, 23, true);
                                }
                                flag9 = true;
                                if (TileRefs(tileX, tileY).Type == 1 && tileX >= chasmStartX + WorldModify.genRand.Next(5) && tileX <= chasmEndX - WorldModify.genRand.Next(5))
                                {
                                    TileRefs(tileX, tileY).SetType(25);
                                }
                                if (TileRefs(tileX, tileY).Type == 2)
                                {
                                    TileRefs(tileX, tileY).SetType(23);
                                }
                            }
                            tileY++;
                        }
                    }
                    for (int secondChasmCycle = chasmStartX; secondChasmCycle < chasmEndX; secondChasmCycle++)
                    {
                        for (int cycleBeforeWater = 0; cycleBeforeWater < Main.maxTilesY - 50; cycleBeforeWater++)
                        {
                            if (TileRefs(secondChasmCycle, cycleBeforeWater).Active && TileRefs(secondChasmCycle, cycleBeforeWater).Type == 31)
                            {
                                int sectionStartX = secondChasmCycle - 13;
                                int sectionEndX = secondChasmCycle + 13;
                                //Terrain minus water?
                                int tMwStartX = cycleBeforeWater - 13;
                                int tMwEndX = cycleBeforeWater + 13;
                                for (int tileX = sectionStartX; tileX < sectionEndX; tileX++)
                                {
                                    if (tileX > 10 && tileX < Main.maxTilesX - 10)
                                    {
                                        for (int tileY = tMwStartX; tileY < tMwEndX; tileY++)
                                        {
                                            if (Math.Abs(tileX - secondChasmCycle) + Math.Abs(tileY - cycleBeforeWater) < 9 + WorldModify.genRand.Next(11) && WorldModify.genRand.Next(3) != 0 && TileRefs(tileX, tileY).Type != 31)
                                            {
                                                TileRefs(tileX, tileY).SetActive(true);
                                                TileRefs(tileX, tileY).SetType(25);
                                                if (Math.Abs(tileX - secondChasmCycle) <= 1 && Math.Abs(tileY - cycleBeforeWater) <= 1)
                                                {
                                                    TileRefs(tileX, tileY).SetActive(false);
                                                }
                                            }
                                            if (TileRefs(tileX, tileY).Type != 31 && Math.Abs(tileX - secondChasmCycle) <= 2 + WorldModify.genRand.Next(3) && Math.Abs(tileY - cycleBeforeWater) <= 2 + WorldModify.genRand.Next(3))
                                            {
                                                TileRefs(tileX, tileY).SetActive(false);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    evilSegment++;
                }
            }
        }
        public static void MakeRandomHoles(Func<Int32, Int32, ITile> TileRefs)
        {
            if (TileRefs == null)
                TileRefs = TileCollection.ITileAt;

            var MaxRandomHoles = (int)((double)(Main.maxTilesX * Main.maxTilesY) * 0.0015);

            using (var prog = new ProgressLogger(MaxRandomHoles - 1, Languages.Generation_MakingRandomHoles))
            {
                for (int i = 0; i < MaxRandomHoles; i++)
                {
                    prog.Value = i;

                    int type = -1;
                    if (WorldModify.genRand.Next(5) == 0)
                    {
                        type = -2;
                    }
                    TileRunner(TileRefs, WorldModify.genRand.Next(0, Main.maxTilesX), WorldModify.genRand.Next((int)worldSurface, Main.maxTilesY), (double)WorldModify.genRand.Next(2, 5), WorldModify.genRand.Next(2, 20), type, false, 0f, 0f, false, true);
                    TileRunner(TileRefs, WorldModify.genRand.Next(0, Main.maxTilesX), WorldModify.genRand.Next((int)worldSurface, Main.maxTilesY), (double)WorldModify.genRand.Next(8, 15), WorldModify.genRand.Next(7, 30), type, false, 0f, 0f, false, true);
                }
            }
        }
        public static void MakeDungeon(Func<Int32, Int32, ITile> TileRefs, int x, int y, int tileType = 41, int wallType = 7)
        {
            if (TileRefs == null)
                TileRefs = TileCollection.ITileAt;

            using (var prog = new ProgressLogger(100, Languages.Generation_CreatingDungeons))
            {
                int num = WorldModify.genRand.Next(3);
                int num2 = WorldModify.genRand.Next(3);
                if (num == 1)
                {
                    tileType = 43;
                }
                else if (num == 2)
                {
                    tileType = 44;
                }
                if (num2 == 1)
                {
                    wallType = 8;
                }
                else if (num2 == 2)
                {
                    wallType = 9;
                }
                numDDoors = 0;
                numDPlats = 0;
                numDRooms = 0;
                dungeonX = x;
                dungeonY = y;
                dMinX = x;
                dMaxX = x;
                dMinY = y;
                dMaxY = y;
                dxStrength1 = (double)WorldModify.genRand.Next(25, 30);
                dyStrength1 = (double)WorldModify.genRand.Next(20, 25);
                dxStrength2 = (double)WorldModify.genRand.Next(35, 50);
                dyStrength2 = (double)WorldModify.genRand.Next(10, 15);
                float num3 = (float)(Main.maxTilesX / 60);
                num3 += (float)WorldModify.genRand.Next(0, (int)(num3 / 3f));
                float num4 = num3;
                int num5 = 5;
                DungeonRoom(TileRefs, dungeonX, dungeonY, tileType, wallType);
                while (num3 > 0f)
                {
                    if (dungeonX < dMinX)
                    {
                        dMinX = dungeonX;
                    }
                    if (dungeonX > dMaxX)
                    {
                        dMaxX = dungeonX;
                    }
                    if (dungeonY > dMaxY)
                    {
                        dMaxY = dungeonY;
                    }
                    num3 -= 1f;

                    prog.Value = (int)((num4 - num3) / num4 * 60f);

                    if (num5 > 0)
                    {
                        num5--;
                    }
                    if (num5 == 0 & WorldModify.genRand.Next(3) == 0)
                    {
                        num5 = 5;
                        if (WorldModify.genRand.Next(2) == 0)
                        {
                            int num6 = dungeonX;
                            int num7 = dungeonY;
                            DungeonHalls(TileRefs, dungeonX, dungeonY, tileType, wallType, false);
                            if (WorldModify.genRand.Next(2) == 0)
                            {
                                DungeonHalls(TileRefs, dungeonX, dungeonY, tileType, wallType, false);
                            }
                            DungeonRoom(TileRefs, dungeonX, dungeonY, tileType, wallType);
                            dungeonX = num6;
                            dungeonY = num7;
                        }
                        else
                        {
                            DungeonRoom(TileRefs, dungeonX, dungeonY, tileType, wallType);
                        }
                    }
                    else
                    {
                        DungeonHalls(TileRefs, dungeonX, dungeonY, tileType, wallType, false);
                    }
                }
                DungeonRoom(TileRefs, dungeonX, dungeonY, tileType, wallType);
                int num8 = dRoomX[0];
                int num9 = dRoomY[0];
                for (int i = 0; i < numDRooms; i++)
                {
                    if (dRoomY[i] < num9)
                    {
                        num8 = dRoomX[i];
                        num9 = dRoomY[i];
                    }
                }
                dungeonX = num8;
                dungeonY = num9;
                dEntranceX = num8;
                dSurface = false;
                num5 = 5;
                while (!dSurface)
                {
                    if (num5 > 0)
                    {
                        num5--;
                    }
                    if ((num5 == 0 & WorldModify.genRand.Next(5) == 0) && (double)dungeonY > Main.worldSurface + 50.0)
                    {
                        num5 = 10;
                        int num10 = dungeonX;
                        int num11 = dungeonY;
                        DungeonHalls(TileRefs, dungeonX, dungeonY, tileType, wallType, true);
                        DungeonRoom(TileRefs, dungeonX, dungeonY, tileType, wallType);
                        dungeonX = num10;
                        dungeonY = num11;
                    }
                    DungeonStairs(TileRefs, dungeonX, dungeonY, tileType, wallType);
                }
                DungeonEnt(TileRefs, null, dungeonX, dungeonY, tileType, wallType);

                prog.Value = 65;

                for (int j = 0; j < numDRooms; j++)
                {
                    for (int k = dRoomL[j]; k <= dRoomR[j]; k++)
                    {
                        if (!TileRefs(k, dRoomT[j] - 1).Active)
                        {
                            DPlatX[numDPlats] = k;
                            DPlatY[numDPlats] = dRoomT[j] - 1;
                            numDPlats++;
                            break;
                        }
                    }
                    for (int l = dRoomL[j]; l <= dRoomR[j]; l++)
                    {
                        if (!TileRefs(l, dRoomB[j] + 1).Active)
                        {
                            DPlatX[numDPlats] = l;
                            DPlatY[numDPlats] = dRoomB[j] + 1;
                            numDPlats++;
                            break;
                        }
                    }
                    for (int m = dRoomT[j]; m <= dRoomB[j]; m++)
                    {
                        if (!TileRefs(dRoomL[j] - 1, m).Active)
                        {
                            DDoorX[numDDoors] = dRoomL[j] - 1;
                            DDoorY[numDDoors] = m;
                            DDoorPos[numDDoors] = -1;
                            numDDoors++;
                            break;
                        }
                    }
                    for (int n = dRoomT[j]; n <= dRoomB[j]; n++)
                    {
                        if (!TileRefs(dRoomR[j] + 1, n).Active)
                        {
                            if (numDDoors <= DDoorX.Length)
                            {
                                DDoorX[numDDoors] = dRoomR[j] + 1;
                                DDoorY[numDDoors] = n;
                                DDoorPos[numDDoors] = 1;
                                numDDoors++;
                            }
                            break;
                        }
                    }
                }

                prog.Value = 70;

                int num12 = 0;
                int num13 = 1000;
                int num14 = 0;
                while (num14 < Main.maxTilesX / 100)
                {
                    num12++;
                    int num15 = WorldModify.genRand.Next(dMinX, dMaxX);
                    int num16 = WorldModify.genRand.Next((int)Main.worldSurface + 25, dMaxY);
                    int num17 = num15;
                    if ((int)TileRefs(num15, num16).Wall == wallType && !TileRefs(num15, num16).Active)
                    {
                        int num18 = 1;
                        if (WorldModify.genRand.Next(2) == 0)
                        {
                            num18 = -1;
                        }
                        while (!TileRefs(num15, num16).Active)
                        {
                            num16 += num18;
                        }
                        if (TileRefs(num15 - 1, num16).Active && TileRefs(num15 + 1, num16).Active && !TileRefs(num15 - 1, num16 - num18).Active && !TileRefs(num15 + 1, num16 - num18).Active)
                        {
                            num14++;
                            int num19 = WorldModify.genRand.Next(5, 13);
                            while (TileRefs(num15 - 1, num16).Active && TileRefs(num15, num16 + num18).Active && TileRefs(num15, num16).Active && !TileRefs(num15, num16 - num18).Active && num19 > 0)
                            {
                                TileRefs(num15, num16).SetType(48);
                                if (!TileRefs(num15 - 1, num16 - num18).Active && !TileRefs(num15 + 1, num16 - num18).Active)
                                {
                                    TileRefs(num15, num16 - num18).SetType(48);
                                    TileRefs(num15, num16 - num18).SetActive(true);
                                }
                                num15--;
                                num19--;
                            }
                            num19 = WorldModify.genRand.Next(5, 13);
                            num15 = num17 + 1;
                            while (TileRefs(num15 + 1, num16).Active && TileRefs(num15, num16 + num18).Active && TileRefs(num15, num16).Active && !TileRefs(num15, num16 - num18).Active && num19 > 0)
                            {
                                TileRefs(num15, num16).SetType(48);
                                if (!TileRefs(num15 - 1, num16 - num18).Active && !TileRefs(num15 + 1, num16 - num18).Active)
                                {
                                    TileRefs(num15, num16 - num18).SetType(48);
                                    TileRefs(num15, num16 - num18).SetActive(true);
                                }
                                num15++;
                                num19--;
                            }
                        }
                    }
                    if (num12 > num13)
                    {
                        num12 = 0;
                        num14++;
                    }
                }
                num12 = 0;
                num13 = 1000;
                num14 = 0;

                prog.Value = 75;

                while (num14 < Main.maxTilesX / 100)
                {
                    num12++;
                    int num20 = WorldModify.genRand.Next(dMinX, dMaxX);
                    int num21 = WorldModify.genRand.Next((int)Main.worldSurface + 25, dMaxY);
                    int num22 = num21;
                    if ((int)TileRefs(num20, num21).Wall == wallType && !TileRefs(num20, num21).Active)
                    {
                        int num23 = 1;
                        if (WorldModify.genRand.Next(2) == 0)
                        {
                            num23 = -1;
                        }
                        while (num20 > 5 && num20 < Main.maxTilesX - 5 && !TileRefs(num20, num21).Active)
                        {
                            num20 += num23;
                        }
                        if (TileRefs(num20, num21 - 1).Active && TileRefs(num20, num21 + 1).Active && !TileRefs(num20 - num23, num21 - 1).Active && !TileRefs(num20 - num23, num21 + 1).Active)
                        {
                            num14++;
                            int num24 = WorldModify.genRand.Next(5, 13);
                            while (TileRefs(num20, num21 - 1).Active && TileRefs(num20 + num23, num21).Active && TileRefs(num20, num21).Active && !TileRefs(num20 - num23, num21).Active && num24 > 0)
                            {
                                TileRefs(num20, num21).SetType(48);
                                if (!TileRefs(num20 - num23, num21 - 1).Active && !TileRefs(num20 - num23, num21 + 1).Active)
                                {
                                    TileRefs(num20 - num23, num21).SetType(48);
                                    TileRefs(num20 - num23, num21).SetActive(true);
                                }
                                num21--;
                                num24--;
                            }
                            num24 = WorldModify.genRand.Next(5, 13);
                            num21 = num22 + 1;
                            while (TileRefs(num20, num21 + 1).Active && TileRefs(num20 + num23, num21).Active && TileRefs(num20, num21).Active && !TileRefs(num20 - num23, num21).Active && num24 > 0)
                            {
                                TileRefs(num20, num21).SetType(48);
                                if (!TileRefs(num20 - num23, num21 - 1).Active && !TileRefs(num20 - num23, num21 + 1).Active)
                                {
                                    TileRefs(num20 - num23, num21).SetType(48);
                                    TileRefs(num20 - num23, num21).SetActive(true);
                                }
                                num21++;
                                num24--;
                            }
                        }
                    }
                    if (num12 > num13)
                    {
                        num12 = 0;
                        num14++;
                    }
                }

                prog.Value = 80;

                for (int num25 = 0; num25 < numDDoors; num25++)
                {
                    int num26 = DDoorX[num25] - 10;
                    int num27 = DDoorX[num25] + 10;
                    int num28 = 100;
                    int num29 = 0;
                    for (int num30 = num26; num30 < num27; num30++)
                    {
                        bool flag = true;
                        int num31 = DDoorY[num25];
                        while (!TileRefs(num30, num31).Active)
                        {
                            num31--;
                        }
                        if (!Main.tileDungeon[(int)TileRefs(num30, num31).Type])
                        {
                            flag = false;
                        }
                        int num32 = num31;
                        num31 = DDoorY[num25];
                        while (!TileRefs(num30, num31).Active)
                        {
                            num31++;
                        }
                        if (!Main.tileDungeon[(int)TileRefs(num30, num31).Type])
                        {
                            flag = false;
                        }
                        int num33 = num31;
                        if (num33 - num32 >= 3)
                        {
                            int num34 = num30 - 20;
                            int num35 = num30 + 20;
                            int num36 = num33 - 10;
                            int num37 = num33 + 10;
                            for (int num38 = num34; num38 < num35; num38++)
                            {
                                for (int num39 = num36; num39 < num37; num39++)
                                {
                                    if (TileRefs(num38, num39).Active && TileRefs(num38, num39).Type == 10)
                                    {
                                        flag = false;
                                        break;
                                    }
                                }
                            }
                            if (flag)
                            {
                                for (int num40 = num33 - 3; num40 < num33; num40++)
                                {
                                    for (int num41 = num30 - 3; num41 <= num30 + 3; num41++)
                                    {
                                        if (TileRefs(num41, num40).Active)
                                        {
                                            flag = false;
                                            break;
                                        }
                                    }
                                }
                            }
                            if (flag && num33 - num32 < 20)
                            {
                                bool flag2 = false;
                                if (DDoorPos[num25] == 0 && num33 - num32 < num28)
                                {
                                    flag2 = true;
                                }
                                if (DDoorPos[num25] == -1 && num30 > num29)
                                {
                                    flag2 = true;
                                }
                                if (DDoorPos[num25] == 1 && (num30 < num29 || num29 == 0))
                                {
                                    flag2 = true;
                                }
                                if (flag2)
                                {
                                    num29 = num30;
                                    num28 = num33 - num32;
                                }
                            }
                        }
                    }
                    if (num28 < 20)
                    {
                        int num42 = num29;
                        int num43 = DDoorY[num25];
                        int num44 = num43;
                        while (!TileRefs(num42, num43).Active)
                        {
                            TileRefs(num42, num43).SetActive(false);
                            num43++;
                        }
                        while (!TileRefs(num42, num44).Active)
                        {
                            num44--;
                        }
                        num43--;
                        num44++;
                        for (int num45 = num44; num45 < num43 - 2; num45++)
                        {
                            TileRefs(num42, num45).SetActive(true);
                            TileRefs(num42, num45).SetType((byte)tileType);
                        }
                        WorldModify.PlaceTile(TileRefs, null, num42, num43, 10, true, false, -1, 0);
                        num42--;
                        int num46 = num43 - 3;
                        while (!TileRefs(num42, num46).Active)
                        {
                            num46--;
                        }
                        if (num43 - num46 < num43 - num44 + 5 && Main.tileDungeon[(int)TileRefs(num42, num46).Type])
                        {
                            for (int num47 = num43 - 4 - WorldModify.genRand.Next(3); num47 > num46; num47--)
                            {
                                TileRefs(num42, num47).SetActive(true);
                                TileRefs(num42, num47).SetType((byte)tileType);
                            }
                        }
                        num42 += 2;
                        num46 = num43 - 3;
                        while (!TileRefs(num42, num46).Active)
                        {
                            num46--;
                        }
                        if (num43 - num46 < num43 - num44 + 5 && Main.tileDungeon[(int)TileRefs(num42, num46).Type])
                        {
                            for (int num48 = num43 - 4 - WorldModify.genRand.Next(3); num48 > num46; num48--)
                            {
                                TileRefs(num42, num48).SetActive(true);
                                TileRefs(num42, num48).SetType((byte)tileType);
                            }
                        }
                        num43++;
                        num42--;
                        TileRefs(num42 - 1, num43).SetActive(true);
                        TileRefs(num42 - 1, num43).SetType((byte)tileType);
                        TileRefs(num42 + 1, num43).SetActive(true);
                        TileRefs(num42 + 1, num43).SetType((byte)tileType);
                    }
                }

                prog.Value = 85;

                for (int num49 = 0; num49 < numDPlats; num49++)
                {
                    int num50 = DPlatX[num49];
                    int num51 = DPlatY[num49];
                    int num52 = Main.maxTilesX;
                    int num53 = 10;
                    for (int num54 = num51 - 5; num54 <= num51 + 5; num54++)
                    {
                        int num55 = num50;
                        int num56 = num50;
                        bool flag3 = false;
                        if (TileRefs(num55, num54).Active)
                        {
                            flag3 = true;
                        }
                        else
                        {
                            while (!TileRefs(num55, num54).Active)
                            {
                                num55--;
                                if (!Main.tileDungeon[(int)TileRefs(num55, num54).Type])
                                {
                                    flag3 = true;
                                }
                            }
                            while (!TileRefs(num56, num54).Active)
                            {
                                num56++;
                                if (!Main.tileDungeon[(int)TileRefs(num56, num54).Type])
                                {
                                    flag3 = true;
                                }
                            }
                        }
                        if (!flag3 && num56 - num55 <= num53)
                        {
                            bool flag4 = true;
                            int num57 = num50 - num53 / 2 - 2;
                            int num58 = num50 + num53 / 2 + 2;
                            int num59 = num54 - 5;
                            int num60 = num54 + 5;
                            for (int num61 = num57; num61 <= num58; num61++)
                            {
                                for (int num62 = num59; num62 <= num60; num62++)
                                {
                                    if (TileRefs(num61, num62).Active && TileRefs(num61, num62).Type == 19)
                                    {
                                        flag4 = false;
                                        break;
                                    }
                                }
                            }
                            for (int num63 = num54 + 3; num63 >= num54 - 5; num63--)
                            {
                                if (TileRefs(num50, num63).Active)
                                {
                                    flag4 = false;
                                    break;
                                }
                            }
                            if (flag4)
                            {
                                num52 = num54;
                                break;
                            }
                        }
                    }
                    if (num52 > num51 - 10 && num52 < num51 + 10)
                    {
                        int num64 = num50;
                        int num65 = num52;
                        int num66 = num50 + 1;
                        while (!TileRefs(num64, num65).Active)
                        {
                            TileRefs(num64, num65).SetActive(true);
                            TileRefs(num64, num65).SetType(19);
                            num64--;
                        }
                        while (!TileRefs(num66, num65).Active)
                        {
                            TileRefs(num66, num65).SetActive(true);
                            TileRefs(num66, num65).SetType(19);
                            num66++;
                        }
                    }
                }

                prog.Value = 90;

                num12 = 0;
                num13 = 1000;
                num14 = 0;
                while (num14 < Main.maxTilesX / 20)
                {
                    num12++;
                    int num67 = WorldModify.genRand.Next(dMinX, dMaxX);
                    int num68 = WorldModify.genRand.Next(dMinY, dMaxY);
                    bool flag5 = true;
                    if ((int)TileRefs(num67, num68).Wall == wallType && !TileRefs(num67, num68).Active)
                    {
                        int num69 = 1;
                        if (WorldModify.genRand.Next(2) == 0)
                        {
                            num69 = -1;
                        }
                        while (flag5 && !TileRefs(num67, num68).Active)
                        {
                            num67 -= num69;
                            if (num67 < 5 || num67 > Main.maxTilesX - 5)
                            {
                                flag5 = false;
                            }
                            else if (TileRefs(num67, num68).Active && !Main.tileDungeon[(int)TileRefs(num67, num68).Type])
                            {
                                flag5 = false;
                            }
                        }
                        if (flag5 && TileRefs(num67, num68).Active && Main.tileDungeon[(int)TileRefs(num67, num68).Type] && TileRefs(num67, num68 - 1).Active && Main.tileDungeon[(int)TileRefs(num67, num68 - 1).Type] && TileRefs(num67, num68 + 1).Active && Main.tileDungeon[(int)TileRefs(num67, num68 + 1).Type])
                        {
                            num67 += num69;
                            for (int num70 = num67 - 3; num70 <= num67 + 3; num70++)
                            {
                                for (int num71 = num68 - 3; num71 <= num68 + 3; num71++)
                                {
                                    if (TileRefs(num70, num71).Active && TileRefs(num70, num71).Type == 19)
                                    {
                                        flag5 = false;
                                        break;
                                    }
                                }
                            }
                            if (flag5 && (!TileRefs(num67, num68 - 1).Active & !TileRefs(num67, num68 - 2).Active & !TileRefs(num67, num68 - 3).Active))
                            {
                                int num72 = num67;
                                int num73 = num67;
                                while (num72 > dMinX && num72 < dMaxX && !TileRefs(num72, num68).Active && !TileRefs(num72, num68 - 1).Active && !TileRefs(num72, num68 + 1).Active)
                                {
                                    num72 += num69;
                                }
                                num72 = Math.Abs(num67 - num72);
                                bool flag6 = false;
                                if (WorldModify.genRand.Next(2) == 0)
                                {
                                    flag6 = true;
                                }
                                if (num72 > 5)
                                {
                                    for (int num74 = WorldModify.genRand.Next(1, 4); num74 > 0; num74--)
                                    {
                                        TileRefs(num67, num68).SetActive(true);
                                        TileRefs(num67, num68).SetType(19);
                                        if (flag6)
                                        {
                                            WorldModify.PlaceTile(TileRefs, null, num67, num68 - 1, 50, true, false, -1, 0);
                                            if (WorldModify.genRand.Next(50) == 0 && TileRefs(num67, num68 - 1).Type == 50)
                                            {
                                                TileRefs(num67, num68 - 1).SetFrameX(90);
                                            }
                                        }
                                        num67 += num69;
                                    }
                                    num12 = 0;
                                    num14++;
                                    if (!flag6 && WorldModify.genRand.Next(2) == 0)
                                    {
                                        num67 = num73;
                                        num68--;
                                        int num75 = WorldModify.genRand.Next(2);
                                        if (num75 == 0)
                                        {
                                            num75 = 13;
                                        }
                                        else if (num75 == 1)
                                        {
                                            num75 = 49;
                                        }
                                        WorldModify.PlaceTile(TileRefs, null, num67, num68, num75, true, false, -1, 0);
                                        if (TileRefs(num67, num68).Type == 13)
                                        {
                                            if (WorldModify.genRand.Next(2) == 0)
                                            {
                                                TileRefs(num67, num68).SetFrameX(18);
                                            }
                                            else
                                            {
                                                TileRefs(num67, num68).SetFrameX(36);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    if (num12 > num13)
                    {
                        num12 = 0;
                        num14++;
                    }
                }

                prog.Value = 95;

                int num76 = 0;
                for (int num77 = 0; num77 < numDRooms; num77++)
                {
                    int num78 = 0;
                    while (num78 < 1000)
                    {
                        int num79 = (int)((double)dRoomSize[num77] * 0.4);
                        int i2 = dRoomX[num77] + WorldModify.genRand.Next(-num79, num79 + 1);
                        int num80 = dRoomY[num77] + WorldModify.genRand.Next(-num79, num79 + 1);
                        int num81 = 0;
                        num76++;
                        int style = 2;
                        switch (num76)
                        {
                            case 1:
                                num81 = 329;
                                break;
                            case 2:
                                num81 = 155;
                                break;
                            case 3:
                                num81 = 156;
                                break;
                            case 4:
                                num81 = 157;
                                break;
                            case 5:
                                num81 = 163;
                                break;
                            case 6:
                                num81 = 113;
                                break;
                            case 7:
                                num81 = 327;
                                style = 0;
                                break;
                            default:
                                num81 = 164;
                                num76 = 0;
                                break;
                        }
                        if ((double)num80 < Main.worldSurface + 50.0)
                        {
                            num81 = 327;
                            style = 0;
                        }
                        if (num81 == 0 && WorldModify.genRand.Next(2) == 0)
                        {
                            num78 = 1000;
                        }
                        else
                        {
                            if (AddBuriedChest(TileRefs, i2, num80, num81, false, style))
                            {
                                num78 += 1000;
                            }
                            num78++;
                        }
                    }
                }
                dMinX -= 25;
                dMaxX += 25;
                dMinY -= 25;
                dMaxY += 25;
                if (dMinX < 0)
                {
                    dMinX = 0;
                }
                if (dMaxX > Main.maxTilesX)
                {
                    dMaxX = Main.maxTilesX;
                }
                if (dMinY < 0)
                {
                    dMinY = 0;
                }
                if (dMaxY > Main.maxTilesY)
                {
                    dMaxY = Main.maxTilesY;
                }
                num12 = 0;
                num13 = 1000;
                num14 = 0;
                while (num14 < Main.maxTilesX / 150)
                {
                    num12++;
                    int num81 = WorldModify.genRand.Next(dMinX, dMaxX);
                    int num82 = WorldModify.genRand.Next(dMinY, dMaxY);
                    if ((int)TileRefs(num81, num82).Wall == wallType)
                    {
                        int num83 = num82;
                        while (num83 > dMinY)
                        {
                            if (TileRefs(num81, num83 - 1).Active && (int)TileRefs(num81, num83 - 1).Type == tileType)
                            {
                                bool flag7 = false;
                                for (int num84 = num81 - 15; num84 < num81 + 15; num84++)
                                {
                                    for (int num85 = num83 - 15; num85 < num83 + 15; num85++)
                                    {
                                        if (num84 > 0 && num84 < Main.maxTilesX && num85 > 0 && num85 < Main.maxTilesY && TileRefs(num84, num85).Type == 42)
                                        {
                                            flag7 = true;
                                            break;
                                        }
                                    }
                                }
                                if (TileRefs(num81 - 1, num83).Active || TileRefs(num81 + 1, num83).Active || TileRefs(num81 - 1, num83 + 1).Active || TileRefs(num81 + 1, num83 + 1).Active || TileRefs(num81, num83 + 2).Active)
                                {
                                    flag7 = true;
                                }
                                if (flag7)
                                {
                                    break;
                                }
                                WorldModify.Place1x2Top(TileRefs, num81, num83, 42);
                                if (TileRefs(num81, num83).Type == 42)
                                {
                                    num12 = 0;
                                    num14++;
                                    break;
                                }
                                break;
                            }
                            else
                            {
                                num83--;
                            }
                        }
                    }
                    if (num12 > num13)
                    {
                        num14++;
                        num12 = 0;
                    }
                }
                num12 = 0;
                num13 = 1000;
                num14 = 0;
                while (num14 < Main.maxTilesX / 500)
                {
                    num12++;
                    int num90 = WorldModify.genRand.Next(dMinX, dMaxX);
                    int num91 = WorldModify.genRand.Next(dMinY, dMaxY);

                    if ((int)TileRefs(num90, num91).Wall == wallType && WorldModify.placeTrap(TileRefs, null, num90, num91, 0))
                        num12 = num13;

                    if (num12 > num13)
                    {
                        num14++;
                        num12 = 0;
                    }
                }
            }
        }
        public static void HideWaterTreasure(Func<Int32, Int32, ITile> TileRefs)
        {
            if (TileRefs == null)
                TileRefs = TileCollection.ITileAt;

            //Water Treasure
            float num235 = (float)(Main.maxTilesX / 4200);
            int num236 = 0;
            int num237 = 0;
            using (var prog = new ProgressLogger(100, Languages.Generation_HidingWaterTreasure))
            {
                while ((float)num237 < 10f * num235)
                {
                    int contain2 = 0;
                    num236++;
                    if (num236 == 1)
                    {
                        contain2 = 186;
                    }
                    else if (num236 == 2)
                    {
                        contain2 = 277;
                    }
                    else
                    {
                        contain2 = 187;
                        num236 = 0;
                    }
                    bool flag16 = false;
                    while (!flag16)
                    {
                        int num238 = WorldModify.genRand.Next(1, Main.maxTilesX);
                        int num239 = WorldModify.genRand.Next(1, Main.maxTilesY - 200);
                        while (TileRefs(num238, num239).Liquid < 200 || TileRefs(num238, num239).Lava)
                        {
                            num238 = WorldModify.genRand.Next(1, Main.maxTilesX);
                            num239 = WorldModify.genRand.Next(1, Main.maxTilesY - 200);
                        }
                        flag16 = AddBuriedChest(TileRefs, num238, num239, contain2, true);
                    }
                    num237++;
                }
            }
        }
        public static void PlaceBreakables(Func<Int32, Int32, ITile> TileRefs)
        {
            if (TileRefs == null)
                TileRefs = TileCollection.ITileAt;

            var num241max = (int)((double)(Main.maxTilesX * Main.maxTilesY) * 0.0008);
            using (var prog = new ProgressLogger(num241max - 1, Languages.Generation_PlacingBreakables))
            {
                for (int num241 = 0; num241 < num241max; num241++)
                {
                    float num242 = (float)((double)num241 / ((double)(Main.maxTilesX * Main.maxTilesY) * 0.0008));

                    prog.Value = num241;

                    bool flag17 = false;
                    int num243 = 0;
                    while (!flag17)
                    {
                        int num244 = WorldModify.genRand.Next((int)worldSurface, Main.maxTilesY - 10);
                        if ((double)num242 > 0.93)
                        {
                            num244 = Main.maxTilesY - 150;
                        }
                        else if ((double)num242 > 0.75)
                        {
                            num244 = (int)terrarainMaxY;
                        }
                        int num245 = WorldModify.genRand.Next(1, Main.maxTilesX);
                        bool flag18 = false;
                        for (int num246 = num244; num246 < Main.maxTilesY; num246++)
                        {
                            if (!flag18)
                            {
                                if (TileRefs(num245, num246).Active && Main.tileSolid[(int)TileRefs(num245, num246).Type] && !TileRefs(num245, num246 - 1).Lava)
                                {
                                    flag18 = true;
                                }
                            }
                            else
                            {
                                if (WorldModify.PlacePot(TileRefs, num245, num246, 28))
                                {
                                    flag17 = true;
                                    break;
                                }
                                num243++;
                                if (num243 >= 10000)
                                {
                                    flag17 = true;
                                    break;
                                }
                            }
                        }
                    }
                }
            } // end breakables
        }
        public static void AddGems(Func<Int32, Int32, ITile> TileRefs)
        {
            if (TileRefs == null)
                TileRefs = TileCollection.ITileAt;

            using (var genProg = new ProgressLogger(68, Languages.Generation_AddingGems))
            {
                for (int Type = 63; Type <= 68; Type++)
                {
                    float gemAmount = 0f;
                    if (Type == 67)
                    {
                        gemAmount = (float)Main.maxTilesX * 0.5f;
                    }
                    else if (Type == 66)
                    {
                        gemAmount = (float)Main.maxTilesX * 0.45f;
                    }
                    else if (Type == 63)
                    {
                        gemAmount = (float)Main.maxTilesX * 0.3f;
                    }
                    else if (Type == 65)
                    {
                        gemAmount = (float)Main.maxTilesX * 0.25f;
                    }
                    else if (Type == 64)
                    {
                        gemAmount = (float)Main.maxTilesX * 0.1f;
                    }
                    else if (Type == 68)
                    {
                        gemAmount = (float)Main.maxTilesX * 0.05f;
                    }
                    gemAmount *= 0.2f;
                    int num193 = 0;
                    while ((float)num193 < gemAmount)
                    {
                        int tileX = WorldModify.genRand.Next(0, Main.maxTilesX);
                        int tileY = WorldModify.genRand.Next((int)Main.worldSurface, Main.maxTilesY);
                        while (TileRefs(tileX, tileY).Type != 1)
                        {
                            tileX = WorldModify.genRand.Next(0, Main.maxTilesX);
                            tileY = WorldModify.genRand.Next((int)Main.worldSurface, Main.maxTilesY);
                        }
                        TileRunner(TileRefs, tileX, tileY, (double)WorldModify.genRand.Next(2, 6), WorldModify.genRand.Next(3, 7),
                            Type, false, 0f, 0f, false, true);
                        num193++;
                    }
                } // end gems
            }
        }
        public static void PlaceHellforges(Func<Int32, Int32, ITile> TileRefs)
        {
            if (TileRefs == null)
                TileRefs = TileCollection.ITileAt;

            var max = Main.maxTilesX / 200;
            using (var prog = new ProgressLogger(max - 1, Languages.Generation_PlacingHellForges))
            {
                for (int num294 = 0; num294 < Main.maxTilesX / 200; num294++)
                {
                    float num295 = (float)(num294 / (Main.maxTilesX / 200));
                    bool flag21 = false;
                    int num296 = 0;
                    while (!flag21)
                    {
                        int num297 = WorldModify.genRand.Next(1, Main.maxTilesX);
                        int num298 = WorldModify.genRand.Next(Main.maxTilesY - 250, Main.maxTilesY - 5);
                        try
                        {
                            if (TileRefs(num297, num298).Wall != 13 && TileRefs(num297, num298).Wall != 14)
                                continue;

                            while (!TileRefs(num297, num298).Active)
                                num298++;

                            num298--;
                            WorldModify.PlaceTile(TileRefs, null, num297, num298, 77, false, false, -1, 0);
                            if (TileRefs(num297, num298).Type == 77)
                                flag21 = true;
                            else
                            {
                                num296++;
                                if (num296 >= 10000)
                                    flag21 = true;
                            }
                        }
                        catch
                        { }
                    }
                }
                prog.Value++;
            }
        }
        public static bool SaveWorld(string savePath, bool resetTime = false)
        {
            bool success = true;

            if (savePath == null || WorldModify.saveLock)
                return false;

            try
            {
                WorldModify.saveLock = true;
                //while (WorldIO.hardLock)
                //{
                //    WorldModify.statusText = "Setting hard mode...";
                //    Thread.Sleep(100);
                //}
                lock (padlock)
                {
                    bool value = Main.dayTime;
                    tempTime = Main.Time;
                    tempMoonPhase = Main.moonPhase;
                    tempBloodMoon = Main.bloodMoon;

                    if (resetTime)
                    {
                        value = true;
                        tempTime = 13500.0;
                        tempMoonPhase = 0;
                        tempBloodMoon = false;
                    }

                    Stopwatch stopwatch = new Stopwatch();
                    stopwatch.Start();
                    string tempPath = savePath + ".sav";
                    using (FileStream fileStream = new FileStream(tempPath, FileMode.Create))
                    {
                        using (BinaryWriter binaryWriter = new BinaryWriter(fileStream))
                        {
                            binaryWriter.Write(Statics.CURRENT_TERRARIA_RELEASE);
                            binaryWriter.Write(Main.worldName);
                            binaryWriter.Write(Main.worldID);
                            binaryWriter.Write((int)Main.leftWorld);
                            binaryWriter.Write((int)Main.rightWorld);
                            binaryWriter.Write((int)Main.topWorld);
                            binaryWriter.Write((int)Main.bottomWorld);
                            binaryWriter.Write(Main.maxTilesY);
                            binaryWriter.Write(Main.maxTilesX);
                            binaryWriter.Write(Main.spawnTileX);
                            binaryWriter.Write(Main.spawnTileY);
                            binaryWriter.Write(Main.worldSurface);
                            binaryWriter.Write(Main.rockLayer);
                            binaryWriter.Write(tempTime);
                            binaryWriter.Write(value);
                            binaryWriter.Write(tempMoonPhase);
                            binaryWriter.Write(tempBloodMoon);
                            binaryWriter.Write(Main.dungeonX);
                            binaryWriter.Write(Main.dungeonY);
                            binaryWriter.Write(NPC.downedBoss1);
                            binaryWriter.Write(NPC.downedBoss2);
                            binaryWriter.Write(NPC.downedBoss3);
                            binaryWriter.Write(NPC.savedGoblin);
                            binaryWriter.Write(NPC.savedWizard);
                            binaryWriter.Write(NPC.savedMech);
                            binaryWriter.Write(NPC.downedGoblins);
                            binaryWriter.Write(NPC.downedClown);
                            binaryWriter.Write(NPC.downedFrost);
                            binaryWriter.Write(WorldModify.shadowOrbSmashed);
                            binaryWriter.Write(WorldModify.spawnMeteor);
                            binaryWriter.Write((byte)WorldModify.shadowOrbCount);
                            binaryWriter.Write(WorldModify.altarCount);
                            binaryWriter.Write(Main.hardMode);
                            binaryWriter.Write(Main.invasionDelay);
                            binaryWriter.Write(Main.invasionSize);
                            binaryWriter.Write((int)Main.invasionType);
                            binaryWriter.Write(Main.invasionX);

                            using (var prog = new ProgressLogger(Main.maxTilesX - 1, "Saving world data"))
                            {
                                for (int x = 0; x < Main.maxTilesX; x++)
                                {
                                    prog.Value = x;

                                    for (int y = 0; y < Main.maxTilesY; y++)
                                    {
                                        if (Main.tile.At(x, y).Type == 127 && Main.tile.At(x, y).Active)
                                        {
                                            WorldModify.KillTile(null, null, x, y);
                                            WorldModify.KillTile(null, null, x, y);
                                            if (!Main.tile.At(x, y).Active)
                                                NetMessage.SendData(17, -1, -1, String.Empty, 0, (float)x, (float)y);
                                        }

                                        var tile = Main.tile.At(x, y); //.FieldwiseClone();
                                        binaryWriter.Write(tile.Active);
                                        if (tile.Active)
                                        {
                                            binaryWriter.Write(tile.Type);
                                            if (Main.tileFrameImportant[(int)tile.Type])
                                            {
                                                binaryWriter.Write(tile.FrameX);
                                                binaryWriter.Write(tile.FrameY);
                                            }
                                        }

                                        //binaryWriter.Write(tile.Lighted);
                                        if (Main.tile.At(x, y).Wall > 0)
                                        {
                                            binaryWriter.Write(true);
                                            binaryWriter.Write(tile.Wall);
                                        }
                                        else
                                        {
                                            binaryWriter.Write(false);
                                        }

                                        if (tile.Liquid > 0)
                                        {
                                            binaryWriter.Write(true);
                                            binaryWriter.Write(tile.Liquid);
                                            binaryWriter.Write(tile.Lava);
                                        }
                                        else
                                        {
                                            binaryWriter.Write(false);
                                        }
                                        binaryWriter.Write(tile.Wire);
                                        int num2 = 1;

                                        while (y + num2 < Main.maxTilesY && World.IsTileTheSame(tile, Main.tile.At(x, y + num2)))
                                            num2++;

                                        num2--;
                                        binaryWriter.Write((short)num2);
                                        y += num2;
                                    }
                                }
                            }

                            Chest chest;
                            for (int i = 0; i < Main.MAX_CHESTS; i++)
                            {
                                chest = Main.chest[i];
                                if (chest == default(Chest))
                                {
                                    binaryWriter.Write(false);
                                }
                                else
                                {
                                    binaryWriter.Write(true);
                                    binaryWriter.Write(chest.x);
                                    binaryWriter.Write(chest.y);
                                    for (int l = 0; l < Chest.MAX_ITEMS; l++)
                                    {
                                        if (chest.contents[l].Type == 0)
                                        {
                                            chest.contents[l].Stack = 0;
                                        }
                                        binaryWriter.Write((byte)chest.contents[l].Stack);
                                        if (chest.contents[l].Stack > 0)
                                        {
                                            binaryWriter.Write(chest.contents[l].NetID);
                                            binaryWriter.Write(chest.contents[l].Prefix);
                                        }
                                    }
                                }
                            }

                            Sign sign;
                            for (int i = 0; i < Main.MAX_SIGNS; i++)
                            {
                                sign = Main.sign[i];
                                if (sign == default(Sign) || sign.text == null)
                                {
                                    binaryWriter.Write(false);
                                }
                                else
                                {
                                    binaryWriter.Write(true);
                                    binaryWriter.Write(sign.text);
                                    binaryWriter.Write(sign.x);
                                    binaryWriter.Write(sign.y);
                                }
                            }

                            NPC npc;
                            for (int i = 0; i < NPC.MAX_NPCS; i++)
                            {
                                npc = (NPC)Main.npcs[i].Clone();
                                if (npc.Active && npc.townNPC)
                                {
                                    binaryWriter.Write(true);
                                    binaryWriter.Write(npc.Name);
                                    binaryWriter.Write(npc.Position.X);
                                    binaryWriter.Write(npc.Position.Y);
                                    binaryWriter.Write(npc.homeless);
                                    binaryWriter.Write(npc.homeTileX);
                                    binaryWriter.Write(npc.homeTileY);
                                }
                            }

                            binaryWriter.Write(false);
                            binaryWriter.Write(Main.chrName[17]);
                            binaryWriter.Write(Main.chrName[18]);
                            binaryWriter.Write(Main.chrName[19]);
                            binaryWriter.Write(Main.chrName[20]);
                            binaryWriter.Write(Main.chrName[22]);
                            binaryWriter.Write(Main.chrName[54]);
                            binaryWriter.Write(Main.chrName[38]);
                            binaryWriter.Write(Main.chrName[107]);
                            binaryWriter.Write(Main.chrName[108]);
                            binaryWriter.Write(Main.chrName[124]);
                            binaryWriter.Write(true);
                            binaryWriter.Write(Main.worldName);
                            binaryWriter.Write(Main.worldID);

                            binaryWriter.Close();
                            fileStream.Close();

                            if (File.Exists(savePath))
                            {
                                ProgramLog.Log("Backing up world file...");
                                string destFileName = savePath + ".bak";
                                File.Copy(savePath, destFileName, true);
                                try
                                {
                                    File.Delete(destFileName);
                                }
                                catch (Exception e)
                                {
                                    ProgramLog.Log(e, "Exception removing " + destFileName);
                                }
                                File.Move(savePath, destFileName);
                            }
                        }

                        try
                        {
                            File.Move(tempPath, savePath);
                        }
                        catch (Exception e)
                        {
                            ProgramLog.Log(e, "Exception moving " + tempPath);
                        }

                        try
                        {
                            File.Delete(tempPath);
                        }
                        catch (Exception e)
                        {
                            ProgramLog.Log(e, "Exception removing " + tempPath);
                        }
                    }
                    stopwatch.Stop();
                    ProgramLog.Log("Save duration: " + stopwatch.Elapsed.Seconds + " Second(s)");
                }
            }
            catch (Exception e)
            {
                ProgramLog.Log(e, "Exception saving the world");
                success = false;
            }
            finally
            {
                WorldModify.saveLock = false;
            }

            return success;
        }
        public static void PlaceLifeCrystals(Func<Int32, Int32, ITile> TileRefs)
        {
            if (TileRefs == null)
                TileRefs = TileCollection.ITileAt;

            var num218max = (int)((double)(Main.maxTilesX * Main.maxTilesY) * 2.2E-05);
            using (var prog = new ProgressLogger(num218max - 1, Languages.Generation_PlacingLifeCrystals))
            {
                for (int num218 = 0; num218 < num218max; num218++)
                {
                    prog.Value = num218;
                    bool flag12 = false;
                    int num220 = 0;
                    while (!flag12)
                    {
                        if (AddLifeCrystal(TileRefs, WorldModify.genRand.Next(1, Main.maxTilesX), WorldModify.genRand.Next((int)(worldSurface + 20.0), Main.maxTilesY)))
                        {
                            flag12 = true;
                        }
                        else
                        {
                            num220++;
                            if (num220 >= 10000)
                            {
                                flag12 = true;
                            }
                        }
                    }
                }
            }
        }
        public static void WaterCheck(Func<Int32, Int32, ITile> TileRefs, ISandbox sandbox, ProgressLogger prog = null)
        {
            if (TileRefs == null)
                TileRefs = TileCollection.ITileAt;

            Liquid.numLiquid = 0;
            LiquidBuffer.numLiquidBuffer = 0;
            for (int i = 1; i < Main.maxTilesX - 1; i++)
            {
                for (int j = Main.maxTilesY - 2; j > 0; j--)
                {
                    TileRefs(i, j).SetCheckingLiquid(false);
                    if (TileRefs(i, j).Liquid > 0 && TileRefs(i, j).Active && Main.tileSolid[(int)TileRefs(i, j).Type] && !Main.tileSolidTop[(int)TileRefs(i, j).Type])
                    {
                        TileRefs(i, j).SetLiquid(0);
                    }
                    else if (TileRefs(i, j).Liquid > 0)
                    {
                        if (TileRefs(i, j).Active)
                        {
                            if (Main.tileWaterDeath[(int)TileRefs(i, j).Type] && (TileRefs(i, j).Type != 4 || TileRefs(i, j).FrameY != 176))
                            {
                                KillTile(TileRefs, sandbox, i, j, false, false, false);
                            }
                            if (TileRefs(i, j).Lava && Main.tileLavaDeath[(int)TileRefs(i, j).Type])
                            {
                                KillTile(TileRefs, sandbox, i, j, false, false, false);
                            }
                        }
                        if ((!TileRefs(i, j + 1).Active || !Main.tileSolid[(int)TileRefs(i, j + 1).Type] || Main.tileSolidTop[(int)TileRefs(i, j + 1).Type]) && TileRefs(i, j + 1).Liquid < 255)
                        {
                            if (TileRefs(i, j + 1).Liquid > 250)
                            {
                                TileRefs(i, j + 1).SetLiquid(255);
                            }
                            else
                            {
                                Liquid.AddWater(TileRefs, sandbox, i, j);
                            }
                        }
                        if ((!TileRefs(i - 1, j).Active || !Main.tileSolid[(int)TileRefs(i - 1, j).Type] || Main.tileSolidTop[(int)TileRefs(i - 1, j).Type]) && TileRefs(i - 1, j).Liquid != TileRefs(i, j).Liquid)
                        {
                            Liquid.AddWater(TileRefs, sandbox, i, j);
                        }
                        else if ((!TileRefs(i + 1, j).Active || !Main.tileSolid[(int)TileRefs(i + 1, j).Type] || Main.tileSolidTop[(int)TileRefs(i + 1, j).Type]) && TileRefs(i + 1, j).Liquid != TileRefs(i, j).Liquid)
                        {
                            Liquid.AddWater(TileRefs, sandbox, i, j);
                        }

                        if (TileRefs(i, j).Lava)
                        {
                            if (TileRefs(i - 1, j).Liquid > 0 && !TileRefs(i - 1, j).Lava)
                            {
                                Liquid.AddWater(TileRefs, sandbox, i, j);
                            }
                            else if (TileRefs(i + 1, j).Liquid > 0 && !TileRefs(i + 1, j).Lava)
                            {
                                Liquid.AddWater(TileRefs, sandbox, i, j);
                            }
                            else if (TileRefs(i, j - 1).Liquid > 0 && !TileRefs(i, j - 1).Lava)
                            {
                                Liquid.AddWater(TileRefs, sandbox, i, j);
                            }
                            else if (TileRefs(i, j + 1).Liquid > 0 && !TileRefs(i, j + 1).Lava)
                            {
                                Liquid.AddWater(TileRefs, sandbox, i, j);
                            }
                        }
                    }
                }
            }

            if (prog != null)
                prog.Value++;
        }
        public static void PlaceMudInDirt(Func<Int32, Int32, ITile> TileRefs, double num7)
        {
            if (TileRefs == null)
                TileRefs = TileCollection.ITileAt;

            var Max = (int)((double)(Main.maxTilesX * Main.maxTilesY) * 0.001);
            using (var mudProg = new ProgressLogger(Max, Languages.Generation_PlacingMudInDirt))
            {
                for (int i = 0; i < Max; i++)
                {
                    TileRunner(TileRefs, WorldModify.genRand.Next(0, Main.maxTilesX), WorldModify.genRand.Next((int)num7, Main.maxTilesY), (double)WorldModify.genRand.Next(2, 6), WorldModify.genRand.Next(2, 40), 59, false, 0f, 0f, false, true);
                    mudProg.Value++;
                }
            }
        }
        public static void Main(string[] args)
        {
            Thread.CurrentThread.Name = "Main";

            //Title: Terraria's Dedicated Server Mod. (1.1.2 #36) ~ Build: 37 [CodeName]
            string codeName = Statics.CODENAME.Length > 0 ? String.Format(" [{0}]", Statics.CODENAME) : String.Empty;

            try
            {
                try
                {
                    Console.Title = String.Format(
                        "Terraria's Dedicated Server Mod. ({0} #{1}) ~ Build: {2}{3}",
                        Statics.VERSION_NUMBER,
                        Statics.CURRENT_TERRARIA_RELEASE,
                        Statics.BUILD,
                        codeName
                    );
                }
                catch { }

                var lis = new Logging.LogTraceListener();
                System.Diagnostics.Trace.Listeners.Clear();
                System.Diagnostics.Trace.Listeners.Add(lis);
                System.Diagnostics.Debug.Listeners.Clear();
                System.Diagnostics.Debug.Listeners.Add(lis);

                using (var prog = new ProgressLogger(1, "Loading language definitions"))
                    Languages.LoadClass(Collections.Registries.LANGUAGE_FILE);

                if (Languages.Startup_Initializing == null)
                {
                    ProgramLog.Error.Log("Please update the language file, either by deleting or finding another online.");
                    Console.ReadKey(true);
                    return;
                }

                ProgramLog.Log("{0} Terraria's Dedicated Server Mod.", Languages.Startup_Initializing);
                ProgramLog.Log("Build: {0}{1} for Terraria {2} & release #{3}.",
                        Statics.BUILD,
                        codeName,
                        Statics.VERSION_NUMBER,
                        Statics.CURRENT_TERRARIA_RELEASE
                );

                ProgramLog.Log(Languages.Startup_SettingUpPaths);
                if (!SetupPaths())
                    return;

                Platform.InitPlatform();

                ProgramLog.Log(Languages.Startup_SettingUpProperties);
                bool propertiesExist = File.Exists("server.properties");
                SetupProperties();

                if (!propertiesExist)
                {
                    ProgramLog.Console.Print(Languages.Startup_NoPropertiesFileFound);
                    if (Console.ReadLine().ToLower() == "y")
                    {
                        //ProgramLog.Console.Print(Languages.Startup_PropertiesCreationComplete);
                        ProgramLog.Log(Languages.ExitRequestCommand);
                        //Console.ReadKey(true);
                        return;
                    }
                }

                var logFile = Statics.DataPath + Path.DirectorySeparatorChar + "server.log";
                ProgramLog.OpenLogFile(logFile);

                string PIDFile = properties.PIDFile.Trim();
                if (PIDFile.Length > 0)
                {
                    string ProcessUID = Process.GetCurrentProcess().Id.ToString();
                    bool Issue = false;
                    if (File.Exists(PIDFile))
                    {
                        try
                        {
                            File.Delete(PIDFile);
                        }
                        catch (Exception)
                        {
                            ProgramLog.Console.Print(Languages.Startup_IssueDeletingPID);
                            if (Console.ReadLine().ToLower() == "n")
                            {
                                ProgramLog.Console.Print(Languages.Startup_PressAnyKeyToExit);
                                Console.ReadKey(true);
                                return;
                            }
                            Issue = true;
                        }
                    }
                    if (!Issue)
                    {
                        try
                        {
                            File.WriteAllText(PIDFile, ProcessUID);
                        }
                        catch (Exception)
                        {
                            ProgramLog.Console.Print(Languages.Startup_IssueCreatingPID);
                            if (Console.ReadLine().ToLower() == "n")
                            {
                                ProgramLog.Console.Print(Languages.Startup_PressAnyKeyToExit);
                                Console.ReadKey(true);
                                return;
                            }
                        }
                        ProgramLog.Log(Languages.Startup_PIDCreated + ProcessUID);
                    }
                }

                ParseArgs(args);

                try
                {
                    if (UpdateManager.PerformProcess())
                    {
                        ProgramLog.Log(Languages.Startup_RestartingIntoNewUpdate);
                        return;
                    }
                }
                catch (UpdateCompleted)
                {
                    throw;
                }
                catch (Exception e)
                {
                    ProgramLog.Log(e, Languages.Startup_ErrorUpdating);
                }

                LoadMonitor.Start();

                ProgramLog.Log(Languages.Startup_StartingRCON);
                RemoteConsole.RConServer.Start("rcon_logins.properties");

                ProgramLog.Log(Languages.Startup_StartingPermissions);
                permissionManager = new PermissionManager();

                ProgramLog.Log(Languages.Startup_PreparingServerData);

                using (var prog = new ProgressLogger(1, Languages.Startup_LoadingItemDefinitions))
                    Collections.Registries.Item.Load();
                using (var prog = new ProgressLogger(1, Languages.Startup_LoadingNPCDefinitions))
                    Collections.Registries.NPC.Load(Collections.Registries.NPC_FILE);
                using (var prog = new ProgressLogger(1, Languages.Startup_LoadingProjectileDefinitions))
                    Collections.Registries.Projectile.Load(Collections.Registries.PROJECTILE_FILE);

                //if (Languages.IsOutOfDate())
                //    ProgramLog.Error.Log(
                //        String.Format("{0}\n{1}",
                //        Languages.Startup_LanguageFileOOD, Languages.Startup_LanguageFileUpdate)
                //        , true);

                commandParser = new CommandParser();
                commandParser.ReadPermissionNodes();

                LoadPlugins();

                /* Save access languages - once only */
                Languages.Save(Collections.Registries.LANGUAGE_FILE);

                HookContext ctx;
                HookArgs.ServerStateChange eArgs;

                string worldFile = properties.WorldPath;
                FileInfo file = new FileInfo(worldFile);

                if (!file.Exists)
                {
                    try
                    {
                        file.Directory.Create();
                    }
                    catch (Exception exception)
                    {
                        ProgramLog.Log(exception);
                        ProgramLog.Console.Print(Languages.Startup_PressAnyKeyToExit);
                        Console.ReadKey(true);
                        return;
                    }

                    ctx = new HookContext
                    {
                        Sender = World.Sender,
                    };

                    eArgs = new HookArgs.ServerStateChange
                    {
                        ServerChangeState = ServerState.GENERATING
                    };

                    HookPoints.ServerStateChange.Invoke(ref ctx, ref eArgs);

                    ProgramLog.Log("{0} '{1}'", Languages.Startup_GeneratingWorld, worldFile);

                    string seed = properties.Seed;
                    if (seed == "-1")
                    {
                        seed = WorldModify.genRand.Next(Int32.MaxValue).ToString();
                        ProgramLog.Log("{0} {1}", Languages.Startup_GeneratedSeed, seed);
                    }

                    int worldX = properties.GetMapSizes()[0];
                    int worldY = properties.GetMapSizes()[1];
                    if (properties.UseCustomTiles)
                    {
                        int X = properties.MaxTilesX;
                        int Y = properties.MaxTilesY;
                        if (X > 0 && Y > 0)
                        {
                            worldX = X;
                            worldY = Y;
                        }

                        if (worldX < (int)World.MAP_SIZE.SMALL_X || worldY < (int)World.MAP_SIZE.SMALL_Y)
                        {
                            ProgramLog.Log("{0} {1}x{2}", Languages.Startup_WorldSizingError, (int)World.MAP_SIZE.SMALL_X, (int)World.MAP_SIZE.SMALL_Y);
                            worldX = (int)((int)World.MAP_SIZE.SMALL_Y * 3.5);
                            worldY = (int)World.MAP_SIZE.SMALL_Y;
                        }

                        ProgramLog.Log("{0} {1}x{2}", Languages.Startup_GeneratingWithCustomSize, worldX, worldY);
                    }

                    Terraria_Server.Main.maxTilesX = worldX;
                    Terraria_Server.Main.maxTilesY = worldY;

                    WorldIO.ClearWorld();
                    Terraria_Server.Main.Initialize();
                    if (properties.UseCustomGenOpts)
                    {
                        WorldGen.numDungeons = properties.DungeonAmount;
                        WorldModify.ficount = properties.FloatingIslandAmount;
                    }
                    else
                    {
                        WorldGen.numDungeons = 1;
                        WorldModify.ficount = (int)((double)Terraria_Server.Main.maxTilesX * 0.0008); //The Statics one was generating with default values, We want it to use the actual tileX for the world
                    }
                    WorldGen.GenerateWorld(null, seed);
                    WorldIO.SaveWorld(worldFile, true);
                }

                ctx = new HookContext
                {
                    Sender = World.Sender,
                };

                eArgs = new HookArgs.ServerStateChange
                {
                    ServerChangeState = ServerState.LOADING
                };

                HookPoints.ServerStateChange.Invoke(ref ctx, ref eArgs);

                // TODO: read map size from world file instead of config
                int worldXtiles = properties.GetMapSizes()[0];
                int worldYtiles = properties.GetMapSizes()[1];

                if (properties.UseCustomTiles)
                {
                    int X = properties.MaxTilesX;
                    int Y = properties.MaxTilesY;
                    if (X > 0 && Y > 0)
                    {
                        worldXtiles = X;
                        worldYtiles = Y;
                    }

                    if (worldXtiles < (int)World.MAP_SIZE.SMALL_X || worldYtiles < (int)World.MAP_SIZE.SMALL_Y)
                    {
                        ProgramLog.Log("{0} {1}x{2}", Languages.Startup_WorldSizingError, (int)World.MAP_SIZE.SMALL_X, (int)World.MAP_SIZE.SMALL_Y);
                        worldXtiles = (int)((int)World.MAP_SIZE.SMALL_Y * 3.5);
                        worldYtiles = (int)World.MAP_SIZE.SMALL_Y;
                    }

                    ProgramLog.Log("{0} {1}x{2}", Languages.Startup_GeneratingWithCustomSize, worldXtiles, worldXtiles);
                }

                World.SavePath = worldFile;

                Server.InitializeData(properties.MaxPlayers,
                    Statics.DataPath + Path.DirectorySeparatorChar + "whitelist.txt",
                    Statics.DataPath + Path.DirectorySeparatorChar + "banlist.txt",
                    Statics.DataPath + Path.DirectorySeparatorChar + "oplist.txt");
                NetPlay.password = properties.Password;
                NetPlay.serverPort = properties.Port;
                NetPlay.serverSIP = properties.ServerIP;
                Terraria_Server.Main.Initialize();

                Terraria_Server.Main.maxTilesX = worldXtiles;
                Terraria_Server.Main.maxTilesY = worldYtiles;
                Terraria_Server.Main.maxSectionsX = worldXtiles / 200;
                Terraria_Server.Main.maxSectionsY = worldYtiles / 150;

                WorldIO.LoadWorld(null, null, World.SavePath);

                ctx = new HookContext
                {
                    Sender = World.Sender,
                };

                eArgs = new HookArgs.ServerStateChange
                {
                    ServerChangeState = ServerState.LOADED
                };

                HookPoints.ServerStateChange.Invoke(ref ctx, ref eArgs);

                updateThread = new ProgramThread("Updt", Program.UpdateLoop);

                ProgramLog.Log(Languages.Startup_StartingTheServer);
                NetPlay.StartServer();

                while (!NetPlay.ServerUp) { }

                ThreadPool.QueueUserWorkItem(CommandThread);
                ProgramLog.Console.Print(Languages.Startup_YouCanNowInsertCommands);

                while (WorldModify.saveLock || NetPlay.ServerUp || Restarting)
                    Thread.Sleep(100);

                ProgramLog.Log(Languages.Startup_Exiting);
                Thread.Sleep(1000);
            }
            catch (UpdateCompleted) { }
            catch (Exception e)
            {
                try
                {
                    using (StreamWriter streamWriter = new StreamWriter(Statics.DataPath + Path.DirectorySeparatorChar + "crashlog.txt", true))
                    {
                        streamWriter.WriteLine(DateTime.Now);
                        streamWriter.WriteLine(String.Format("{0} {1}", Languages.Startup_CrashlogGeneratedBy, Console.Title));
                        streamWriter.WriteLine(e);
                        streamWriter.WriteLine();
                    }
                    ProgramLog.Log(e, Languages.Startup_ProgramCrash);
                    ProgramLog.Log("{0} crashlog.txt -> http://tdsm.org/", Languages.Startup_PleaseSend);
                }
                catch { }
            }

            if (properties != null && File.Exists(properties.PIDFile.Trim()))
                File.Delete(properties.PIDFile.Trim());

            Thread.Sleep(500);
            ProgramLog.Log(Languages.Startup_LogEnd);
            ProgramLog.Close();

            RemoteConsole.RConServer.Stop();
        }
        public static void PlaceRocksWithinDirt(Func<Int32, Int32, ITile> TileRefs)
        {
            if (TileRefs == null)
                TileRefs = TileCollection.ITileAt;

            var Max = (int)((double)(Main.maxTilesX * Main.maxTilesY) * 0.0002);
            var Max2 = (int)((double)(Main.maxTilesX * Main.maxTilesY) * 0.0045);
            using (var rockProg = new ProgressLogger((Max * 2) + Max2, Languages.Generation_PlacingRocks))
            {
                for (int i = 0; i < (int)((double)(Main.maxTilesX * Main.maxTilesY) * 0.0002); i++)
                {
                    TileRunner(TileRefs, WorldModify.genRand.Next(0, Main.maxTilesX), WorldModify.genRand.Next(0, (int)terrarainMaxY + 1), (double)WorldModify.genRand.Next(4, 15), WorldModify.genRand.Next(5, 40), 1, false, 0f, 0f, false, true);
                    rockProg.Value++;
                }
                for (int i = 0; i < (int)((double)(Main.maxTilesX * Main.maxTilesY) * 0.0002); i++)
                {
                    TileRunner(TileRefs, WorldModify.genRand.Next(0, Main.maxTilesX), WorldModify.genRand.Next((int)terrarainMaxY, (int)worldSurface + 1), (double)WorldModify.genRand.Next(4, 10), WorldModify.genRand.Next(5, 30), 1, false, 0f, 0f, false, true);
                    rockProg.Value++;
                }
                for (int i = 0; i < (int)((double)(Main.maxTilesX * Main.maxTilesY) * 0.0045); i++)
                {
                    TileRunner(TileRefs, WorldModify.genRand.Next(0, Main.maxTilesX), WorldModify.genRand.Next((int)worldSurface, (int)rockLayer + 1), (double)WorldModify.genRand.Next(2, 7), WorldModify.genRand.Next(2, 23), 1, false, 0f, 0f, false, true);
                    rockProg.Value++;
                }
            }
        }
        public static void loadWorld()
        {
            if (WorldModify.genRand == null)
            {
                WorldModify.genRand = new Random((int)DateTime.Now.Ticks);
            }
            using (FileStream fileStream = new FileStream(Program.server.World.SavePath, FileMode.Open))
            {
                using (BinaryReader binaryReader = new BinaryReader(fileStream))
                {
                    try
                    {
                        WorldModify.loadFailed = false;
                        WorldModify.loadSuccess = false;
                        int Terraria_Release = binaryReader.ReadInt32();
                        if (Terraria_Release > Statics.CURRENT_TERRARIA_RELEASE)
                        {
                            WorldModify.loadFailed = true;
                            WorldModify.loadSuccess = false;
                            try
                            {
                                binaryReader.Close();
                                fileStream.Close();
                            }
                            catch
                            {
                            }
                        }
                        else
                        {
                            Main.worldName = binaryReader.ReadString();
                            Main.worldID = binaryReader.ReadInt32();
                            Main.leftWorld = (float)binaryReader.ReadInt32();
                            Main.rightWorld = (float)binaryReader.ReadInt32();
                            Main.topWorld = (float)binaryReader.ReadInt32();
                            Main.bottomWorld = (float)binaryReader.ReadInt32();
                            Main.maxTilesY = binaryReader.ReadInt32();
                            Main.maxTilesX = binaryReader.ReadInt32();
                            Main.maxSectionsX = Main.maxTilesX / 200;
                            Main.maxSectionsY = Main.maxTilesY / 150;
                            clearWorld();
                            Main.spawnTileX = binaryReader.ReadInt32();
                            Main.spawnTileY = binaryReader.ReadInt32();
                            Main.worldSurface = binaryReader.ReadDouble();
                            Main.rockLayer = binaryReader.ReadDouble();
                            tempTime = binaryReader.ReadDouble();
                            tempDayTime = binaryReader.ReadBoolean();
                            tempMoonPhase = binaryReader.ReadInt32();
                            tempBloodMoon = binaryReader.ReadBoolean();
                            Main.dungeonX = binaryReader.ReadInt32();
                            Main.dungeonY = binaryReader.ReadInt32();
                            NPC.downedBoss1 = binaryReader.ReadBoolean();
                            NPC.downedBoss2 = binaryReader.ReadBoolean();
                            NPC.downedBoss3 = binaryReader.ReadBoolean();
                            WorldModify.shadowOrbSmashed = binaryReader.ReadBoolean();
                            WorldModify.spawnMeteor = binaryReader.ReadBoolean();
                            WorldModify.shadowOrbCount = (int)binaryReader.ReadByte();
                            Main.invasionDelay = binaryReader.ReadInt32();
                            Main.invasionSize = binaryReader.ReadInt32();
                            Main.invasionType = binaryReader.ReadInt32();
                            Main.invasionX = binaryReader.ReadDouble();

                            using (var prog = new ProgressLogger(Main.maxTilesX - 1, "Loading world tiles"))
                            {
                                for (int j = 0; j < Main.maxTilesX; j++)
                                {
                                    prog.Value = j;

                                    for (int k = 0; k < Main.maxTilesY; k++)
                                    {
                                        Main.tile.At(j, k).SetActive(binaryReader.ReadBoolean());
                                        if (Main.tile.At(j, k).Active)
                                        {
                                            Main.tile.At(j, k).SetType(binaryReader.ReadByte());
                                            if (Main.tileFrameImportant[(int)Main.tile.At(j, k).Type])
                                            {
                                                Main.tile.At(j, k).SetFrameX(binaryReader.ReadInt16());
                                                Main.tile.At(j, k).SetFrameY(binaryReader.ReadInt16());
                                            }
                                            else
                                            {
                                                Main.tile.At(j, k).SetFrameX(-1);
                                                Main.tile.At(j, k).SetFrameY(-1);
                                            }
                                        }
                                        Main.tile.At(j, k).SetLighted(binaryReader.ReadBoolean());
                                        if (binaryReader.ReadBoolean())
                                        {
                                            Main.tile.At(j, k).SetWall(binaryReader.ReadByte());
                                        }
                                        if (binaryReader.ReadBoolean())
                                        {
                                            Main.tile.At(j, k).SetLiquid(binaryReader.ReadByte());
                                            Main.tile.At(j, k).SetLava(binaryReader.ReadBoolean());
                                        }
                                    }
                                }
                            }

                            for (int l = 0; l < 1000; l++)
                            {
                                if (binaryReader.ReadBoolean())
                                {
                                    Main.chest[l] = new Chest();
                                    Main.chest[l].x = binaryReader.ReadInt32();
                                    Main.chest[l].y = binaryReader.ReadInt32();
                                    for (int m = 0; m < Chest.MAX_ITEMS; m++)
                                    {
                                        Main.chest[l].contents[m] = new Item();
                                        int stack = binaryReader.ReadByte();
                                        if (stack > 0)
                                        {
                                            String defaults = Item.VersionName(binaryReader.ReadString(), Terraria_Release);
                                            Main.chest[l].contents[m] = Registries.Item.Create(defaults, stack);
                                        }
                                    }
                                }
                            }
                            for (int n = 0; n < 1000; n++)
                            {
                                if (binaryReader.ReadBoolean())
                                {
                                    String text = binaryReader.ReadString();
                                    int num3 = binaryReader.ReadInt32();
                                    int num4 = binaryReader.ReadInt32();
                                    if (Main.tile.At(num3, num4).Active && (Main.tile.At(num3, num4).Type == 55 || Main.tile.At(num3, num4).Type == 85))
                                    {
                                        Main.sign[n] = new Sign();
                                        Main.sign[n].x = num3;
                                        Main.sign[n].y = num4;
                                        Main.sign[n].text = text;
                                    }
                                }
                            }
                            bool flag = binaryReader.ReadBoolean();
                            int num5 = 0;
                            while (flag)
                            {
                                String NPCName = binaryReader.ReadString();
                                Main.npcs[num5] = Registries.NPC.Create(NPCName);
                                Main.npcs[num5].Position.X = binaryReader.ReadSingle();
                                Main.npcs[num5].Position.Y = binaryReader.ReadSingle();
                                Main.npcs[num5].homeless = binaryReader.ReadBoolean();
                                Main.npcs[num5].homeTileX = binaryReader.ReadInt32();
                                Main.npcs[num5].homeTileY = binaryReader.ReadInt32();
                                flag = binaryReader.ReadBoolean();
                                num5++;
                            }
                            if (Terraria_Release >= 7)
                            {
                                bool flag2 = binaryReader.ReadBoolean();
                                String a = binaryReader.ReadString();
                                int num6 = binaryReader.ReadInt32();
                                if (!flag2 || !(a == Main.worldName) || num6 != Main.worldID)
                                {
                                    WorldModify.loadSuccess = false;
                                    WorldModify.loadFailed = true;
                                    binaryReader.Close();
                                    fileStream.Close();
                                    return;
                                }
                                WorldModify.loadSuccess = true;
                            }
                            else
                            {
                                WorldModify.loadSuccess = true;
                            }
                            binaryReader.Close();
                            fileStream.Close();

                            if (!WorldModify.loadFailed && WorldModify.loadSuccess)
                            {
                                WorldModify.gen = true;
                                WorldModify.waterLine = Main.maxTilesY;
                                Liquid.QuickWater(2, -1, -1);
                                WorldModify.WaterCheck();
                                int num7 = 0;
                                Liquid.quickSettle = true;
                                int num8 = Liquid.numLiquid + LiquidBuffer.numLiquidBuffer;
                                float num9 = 0f;

                                using (var prog = new ProgressLogger(100, "Settling liquids"))
                                    while (Liquid.numLiquid > 0 && num7 < 100000)
                                    {
                                        num7++;
                                        float num10 = (float)(num8 - (Liquid.numLiquid + LiquidBuffer.numLiquidBuffer)) / (float)num8;
                                        if (Liquid.numLiquid + LiquidBuffer.numLiquidBuffer > num8)
                                        {
                                            num8 = Liquid.numLiquid + LiquidBuffer.numLiquidBuffer;
                                        }
                                        if (num10 > num9)
                                        {
                                            num9 = num10;
                                        }
                                        else
                                        {
                                            num10 = num9;
                                        }

                                        prog.Value = (int)(num10 * 50f + 50f);

                                        Liquid.UpdateLiquid();
                                    }
                                Liquid.quickSettle = false;

                                ProgramLog.Log("Performing Water Check");
                                WorldModify.WaterCheck();
                                WorldModify.gen = false;
                            }
                        }
                    }
                    catch
                    {
                        WorldModify.loadFailed = true;
                        WorldModify.loadSuccess = false;
                        try
                        {
                            binaryReader.Close();
                            fileStream.Close();
                        }
                        catch
                        {
                        }
                    }
                }
            }

            if (Main.worldName == null || Main.worldName == "")
            {
                Main.worldName = System.IO.Path.GetFileNameWithoutExtension (Program.server.World.SavePath);
            }
        }
        public static void PlaceTraps(Func<Int32, Int32, ITile> TileRefs)
        {
            if (TileRefs == null)
                TileRefs = TileCollection.ITileAt;

            var maxTraps = (int)((double)Main.maxTilesX * 0.05);

            using (var logger = new ProgressLogger(maxTraps, Languages.Generation_PlacingTraps))
            {
                for (int num273 = 0; num273 < maxTraps; num273++)
                {
                    float num274 = (float)((double)num273 / ((double)Main.maxTilesX * 0.05));
                    //Main.statusText = "Placing traps: " + (int)(num274 * 100f + 1f) + "%";
                    for (int num275 = 0; num275 < MAX_TRAPS; num275++)
                    {
                        int X = Main.rand.Next(200, Main.maxTilesX - 200);
                        int Y = Main.rand.Next((int)Main.worldSurface, Main.maxTilesY - 300);
                        if (TileRefs(X, Y).Wall == 0 && WorldModify.placeTrap(TileRefs, null, X, Y, -1))
                        {
                            break;
                        }
                    }
                }
            }
        }
        public static Boolean saveWorld(String savePath, bool resetTime = false)
        {
            Boolean success = true;

            if (savePath == null)
            {
                return false;
            }

            if (WorldModify.saveLock)
            {
                return false;
            }

            try
            {
                WorldModify.saveLock = true;
                lock (padlock)
                {
                    bool value = Main.dayTime;
                    tempTime = Main.time;
                    tempMoonPhase = Main.moonPhase;
                    tempBloodMoon = Main.bloodMoon;

                    if (resetTime)
                    {
                        value = true;
                        tempTime = 13500.0;
                        tempMoonPhase = 0;
                        tempBloodMoon = false;
                    }

                    Stopwatch stopwatch = new Stopwatch();
                    stopwatch.Start();
                    String tempPath = savePath + ".sav";
                    using (FileStream fileStream = new FileStream(tempPath, FileMode.Create))
                    {
                        using (BinaryWriter binaryWriter = new BinaryWriter(fileStream))
                        {
                            binaryWriter.Write(Statics.CURRENT_TERRARIA_RELEASE);
                            binaryWriter.Write(Main.worldName);
                            binaryWriter.Write(Main.worldID);
                            binaryWriter.Write((int)Main.leftWorld);
                            binaryWriter.Write((int)Main.rightWorld);
                            binaryWriter.Write((int)Main.topWorld);
                            binaryWriter.Write((int)Main.bottomWorld);
                            binaryWriter.Write(Main.maxTilesY);
                            binaryWriter.Write(Main.maxTilesX);
                            binaryWriter.Write(Main.spawnTileX);
                            binaryWriter.Write(Main.spawnTileY);
                            binaryWriter.Write(Main.worldSurface);
                            binaryWriter.Write(Main.rockLayer);
                            binaryWriter.Write(tempTime);
                            binaryWriter.Write(value);
                            binaryWriter.Write(tempMoonPhase);
                            binaryWriter.Write(tempBloodMoon);
                            binaryWriter.Write(Main.dungeonX);
                            binaryWriter.Write(Main.dungeonY);
                            binaryWriter.Write(NPC.downedBoss1);
                            binaryWriter.Write(NPC.downedBoss2);
                            binaryWriter.Write(NPC.downedBoss3);
                            binaryWriter.Write(WorldModify.shadowOrbSmashed);
                            binaryWriter.Write(WorldModify.spawnMeteor);
                            binaryWriter.Write((byte)WorldModify.shadowOrbCount);
                            binaryWriter.Write(Main.invasionDelay);
                            binaryWriter.Write(Main.invasionSize);
                            binaryWriter.Write(Main.invasionType);
                            binaryWriter.Write(Main.invasionX);

                            using (var prog = new ProgressLogger(Main.maxTilesX - 1, "Saving world data"))
                            {
                                for (int x = 0; x < Main.maxTilesX; x++)
                                {
                                    prog.Value = x;

                                    for (int y = 0; y < Main.maxTilesY; y++)
                                    {
                                        TileRef tile = Main.tile.At(x, y);
                                        binaryWriter.Write(tile.Active);
                                        if (tile.Active)
                                        {
                                            binaryWriter.Write(tile.Type);
                                            if (Main.tileFrameImportant[(int)tile.Type])
                                            {
                                                binaryWriter.Write(tile.FrameX);
                                                binaryWriter.Write(tile.FrameY);
                                            }
                                        }

                                        binaryWriter.Write(tile.Lighted);
                                        if (Main.tile.At(x, y).Wall > 0)
                                        {
                                            binaryWriter.Write(true);
                                            binaryWriter.Write(tile.Wall);
                                        }
                                        else
                                        {
                                            binaryWriter.Write(false);
                                        }

                                        if (tile.Liquid > 0)
                                        {
                                            binaryWriter.Write(true);
                                            binaryWriter.Write(tile.Liquid);
                                            binaryWriter.Write(tile.Lava);
                                        }
                                        else
                                        {
                                            binaryWriter.Write(false);
                                        }
                                    }
                                }
                            }

                            Chest chest;
                            for (int i = 0; i < 1000; i++)
                            {
                                chest = Main.chest[i];
                                if (chest == null)
                                {
                                    binaryWriter.Write(false);
                                }
                                else
                                {
                                    binaryWriter.Write(true);
                                    binaryWriter.Write(chest.x);
                                    binaryWriter.Write(chest.y);
                                    for (int l = 0; l < Chest.MAX_ITEMS; l++)
                                    {
                                        if (chest.contents[l].Type == 0)
                                        {
                                            chest.contents[l].Stack = 0;
                                        }
                                        binaryWriter.Write((byte)chest.contents[l].Stack);
                                        if (chest.contents[l].Stack > 0)
                                        {
                                            binaryWriter.Write(chest.contents[l].Name);
                                        }
                                    }
                                }
                            }

                            Sign sign;
                            for (int i = 0; i < 1000; i++)
                            {
                                sign = Main.sign[i];
                                if (sign == null || sign.text == null)
                                {
                                    binaryWriter.Write(false);
                                }
                                else
                                {
                                    binaryWriter.Write(true);
                                    binaryWriter.Write(sign.text);
                                    binaryWriter.Write(sign.x);
                                    binaryWriter.Write(sign.y);
                                }
                            }

                            NPC npc;
                            for (int i = 0; i < 1000; i++)
                            {
                                npc = Main.npcs[i];
                                if (npc.Active && npc.townNPC)
                                {
                                    binaryWriter.Write(true);
                                    binaryWriter.Write(npc.Name);
                                    binaryWriter.Write(npc.Position.X);
                                    binaryWriter.Write(npc.Position.Y);
                                    binaryWriter.Write(npc.homeless);
                                    binaryWriter.Write(npc.homeTileX);
                                    binaryWriter.Write(npc.homeTileY);
                                }
                            }

                            binaryWriter.Write(false);
                            binaryWriter.Write(true);
                            binaryWriter.Write(Main.worldName);
                            binaryWriter.Write(Main.worldID);
                            binaryWriter.Close();
                            fileStream.Close();

                            if (File.Exists(savePath))
                            {
                                ProgramLog.Log("Backing up world file...");
                                String destFileName = savePath + ".bak";
                                File.Copy(savePath, destFileName, true);
                                try
                                {
                                    File.Delete(destFileName);
                                }
                                catch (Exception e)
                                {
                                    ProgramLog.Log(e, "Exception removing " + destFileName);
                                }
                                File.Move(savePath, destFileName);
                            }
                        }

                        try
                        {
                            File.Move(tempPath, savePath);
                        }
                        catch (Exception e)
                        {
                            ProgramLog.Log(e, "Exception moving " + tempPath);
                        }

                        try
                        {
                            File.Delete(tempPath);
                        }
                        catch (Exception e)
                        {
                            ProgramLog.Log(e, "Exception removing " + tempPath);
                        }
                    }
                    stopwatch.Stop();
                    ProgramLog.Log("Save duration: " + stopwatch.Elapsed.Seconds + " Second(s)");
                }
            }
            catch (Exception e)
            {
                ProgramLog.Log(e, "Exception saving the world");
                success = false;
            }
            finally
            {
                WorldModify.saveLock = false;
            }

            return success;
        }
        public static void PutDirtBehindDirt(Func<Int32, Int32, ITile> TileRefs)
        {
            if (TileRefs == null)
                TileRefs = TileCollection.ITileAt;

            int outlier = 0;

            using (var prog = new ProgressLogger(Main.maxTilesX - 3, Languages.Generation_PuttingDirtBehindDirt))
            {
                for (int posX = 1; posX < Main.maxTilesX - 1; posX++)
                {
                    prog.Value = posX - 1;

                    bool flag3 = false;
                    outlier += WorldModify.genRand.Next(-1, 2);
                    if (outlier < 0)
                    {
                        outlier = 0;
                    }
                    if (outlier > 10)
                    {
                        outlier = 10;
                    }
                    int posY = 0;
                    while ((double)posY < Main.worldSurface + 10.0 && (double)posY <= Main.worldSurface + (double)outlier)
                    {
                        if (flag3)
                        {
                            TileRefs(posX, posY).SetWall(2);
                        }
                        if (TileRefs(posX, posY).Active && TileRefs(posX - 1, posY).Active && TileRefs(posX + 1, posY).Active && TileRefs(posX, posY + 1).Active && TileRefs(posX - 1, posY + 1).Active && TileRefs(posX + 1, posY + 1).Active)
                        {
                            flag3 = true;
                        }
                        posY++;
                    }
                }
            }
        }
 public static void WaterCheck(ProgressLogger prog = null)
 {
     Liquid.numLiquid = 0;
     LiquidBuffer.numLiquidBuffer = 0;
     for (int i = 1; i < Main.maxTilesX - 1; i++)
     {
         for (int j = Main.maxTilesY - 2; j > 0; j--)
         {
             Main.tile.At(i, j).SetCheckingLiquid (false);
             if (Main.tile.At(i, j).Liquid > 0 && Main.tile.At(i, j).Active && Main.tileSolid[(int)Main.tile.At(i, j).Type] && !Main.tileSolidTop[(int)Main.tile.At(i, j).Type])
             {
                 Main.tile.At(i, j).SetLiquid (0);
             }
             else if (Main.tile.At(i, j).Liquid > 0)
             {
                 if (Main.tile.At(i, j).Active)
                 {
                     if (Main.tileWaterDeath[(int)Main.tile.At(i, j).Type])
                     {
                         WorldModify.KillTile(i, j, false, false, false);
                     }
                     if (Main.tile.At(i, j).Lava && Main.tileLavaDeath[(int)Main.tile.At(i, j).Type])
                     {
                         WorldModify.KillTile(i, j, false, false, false);
                     }
                 }
                 if ((!Main.tile.At(i, j + 1).Active || !Main.tileSolid[(int)Main.tile.At(i, j + 1).Type] || Main.tileSolidTop[(int)Main.tile.At(i, j + 1).Type]) && Main.tile.At(i, j + 1).Liquid < 255)
                 {
                     if (Main.tile.At(i, j + 1).Liquid > 250)
                     {
                         Main.tile.At(i, j + 1).SetLiquid (255);
                     }
                     else
                     {
                         Liquid.AddWater(i, j);
                     }
                 }
                 if ((!Main.tile.At(i - 1, j).Active || !Main.tileSolid[(int)Main.tile.At(i - 1, j).Type] || Main.tileSolidTop[(int)Main.tile.At(i - 1, j).Type]) && Main.tile.At(i - 1, j).Liquid != Main.tile.At(i, j).Liquid)
                 {
                     Liquid.AddWater(i, j);
                 }
                 else if ((!Main.tile.At(i + 1, j).Active || !Main.tileSolid[(int)Main.tile.At(i + 1, j).Type] || Main.tileSolidTop[(int)Main.tile.At(i + 1, j).Type]) && Main.tile.At(i + 1, j).Liquid != Main.tile.At(i, j).Liquid)
                 {
                     Liquid.AddWater(i, j);
                 }
                 if (Main.tile.At(i, j).Lava)
                 {
                     if (Main.tile.At(i - 1, j).Liquid > 0 && !Main.tile.At(i - 1, j).Lava)
                     {
                         Liquid.AddWater(i, j);
                     }
                     else if (Main.tile.At(i + 1, j).Liquid > 0 && !Main.tile.At(i + 1, j).Lava)
                     {
                         Liquid.AddWater(i, j);
                     }
                     else if (Main.tile.At(i, j - 1).Liquid > 0 && !Main.tile.At(i, j - 1).Lava)
                     {
                         Liquid.AddWater(i, j);
                     }
                     else if (Main.tile.At(i, j + 1).Liquid > 0 && !Main.tile.At(i, j + 1).Lava)
                     {
                         Liquid.AddWater(i, j);
                     }
                 }
             }
         }
         if (prog != null)
             prog.Value++;
     }
 }
        public static void SettleLiquids(Func<Int32, Int32, ITile> TileRefs, ISandbox sandbox)
        {
            if (TileRefs == null)
                TileRefs = TileCollection.ITileAt;

            var Max = Main.maxTilesX - 400;
            var Max2 = (Main.maxTilesX - 1) * 2;
            var Max3 = (int)((100 + Main.maxTilesX + Max + Max2 + (int)(Main.maxTilesX * 2.85)) * 1.65);
            var Max4 = (int)(Max3 * 0.573);
            using (var prog = new ProgressLogger(Max4 + Max3, Languages.Generation_SettlingLiquids))
            {
                for (int tilePosX = 0; tilePosX < Main.maxTilesX; tilePosX++)
                {
                    int tileX = tilePosX;
                    int tileY = (int)terrarainMaxY;
                    while ((double)tileY < Main.worldSurface - 1.0)
                    {
                        if (TileRefs(tileX, tileY).Active)
                        {
                            if (TileRefs(tileX, tileY).Type == 60)
                            {
                                TileRefs(tileX, tileY - 1).SetLiquid(255);
                                TileRefs(tileX, tileY - 2).SetLiquid(255);
                                break;
                            }
                            break;
                        }
                        else
                        {
                            tileY++;
                        }
                    }
                    prog.Value++;
                }
                for (int tilePosX = 400; tilePosX < Max; tilePosX++)
                {
                    int tileX = tilePosX;
                    int tileY = (int)terrarainMaxY;
                    while ((double)tileY < Main.worldSurface - 1.0)
                    {
                        if (TileRefs(tileX, tileY).Active)
                        {
                            if (TileRefs(tileX, tileY).Type == 53)
                            {
                                int fTileY = tileY;
                                while ((double)fTileY > terrarainMaxY)
                                {
                                    fTileY--;
                                    TileRefs(tileX, fTileY).SetLiquid(0);
                                }
                                break;
                            }
                            break;
                        }
                        else
                        {
                            tileY++;
                        }
                    }
                    prog.Value++;
                }

                Liquid.QuickWater(TileRefs, sandbox, 3, -1, -1, prog);
                WorldModify.WaterCheck(TileRefs, sandbox, prog);

                int liquidLeft = 0;
                Liquid.quickSettle = true;
                while (liquidLeft < 10)
                {
                    int liquidAmount = Liquid.numLiquid + LiquidBuffer.numLiquidBuffer;
                    liquidLeft++;
                    float preserver = 0f;
                    while (Liquid.numLiquid > 0)
                    {
                        float liquidLeftO = (float)(liquidAmount - (Liquid.numLiquid + LiquidBuffer.numLiquidBuffer)) / (float)liquidAmount;
                        if (Liquid.numLiquid + LiquidBuffer.numLiquidBuffer > liquidAmount)
                        {
                            liquidAmount = Liquid.numLiquid + LiquidBuffer.numLiquidBuffer;
                        }
                        if (liquidLeftO > preserver)
                        {
                            preserver = liquidLeftO;
                        }
                        else
                        {
                            liquidLeftO = preserver;
                        }
                        if (liquidLeft == 1)
                        {
                            prog.Value = (int)(liquidLeftO * 100f / 3f + 33f);
                        }
                        if (liquidLeft <= 10)
                        {
                            Liquid.UpdateLiquid(TileRefs, sandbox);
                        }
                    }
                    WorldModify.WaterCheck(TileRefs, sandbox, prog);

                    prog.Value = (int)((float)liquidLeft * 10f / 3f + 66f);
                }
                Liquid.quickSettle = false;
            } // end settling
        }
Esempio n. 30
0
        public void mapWorld()
        {
            Stopwatch stopwatch = new Stopwatch ();
            Server.notifyOps("Saving Image...", true);
            stopwatch.Start ();
            bmp = new Bitmap (Main.maxTilesX, Main.maxTilesY, PixelFormat.Format32bppArgb);
            Graphics graphicsHandle = Graphics.FromImage ((Image)bmp);
            graphicsHandle.FillRectangle (new SolidBrush (Constants.MoreTerra_Color.SKY), 0, 0, bmp.Width, bmp.Height);

            using (var prog = new ProgressLogger(Main.maxTilesX - 1, "Saving image data"))
                for (int i = 0; i < Main.maxTilesX; i++) {
                    prog.Value = i;
                    for (int j = 0; j < Main.maxTilesY; j++) {

                    //TODO: find a more understandable way on these if statements
                        if (Main.tile.At (i, j).Wall == 0) {
                            if (Main.tile.At (i, j).Active) {
                                bmp.SetPixel (i, j, tileTypeDefs [Main.tile.At (i, j).Type]);
                            } else {

                                if (j > Main.worldSurface) {
                                    bmp.SetPixel (i, j, Constants.MoreTerra_Color.WALL_BACKGROUND);
                                }
                                if (Main.tile.At (i, j).Liquid > 0) {
                                    if (Main.tile.At (i, j).Lava) {
                                        bmp.SetPixel (i, j, Constants.MoreTerra_Color.LAVA);
                                    } else {
                                        bmp.SetPixel (i, j, Constants.MoreTerra_Color.WATER);
                                    }
                                }
                            }
                        } else {
                            if (Main.tile.At (i, j).Active) {
                                bmp.SetPixel (i, j, tileTypeDefs [Main.tile.At (i, j).Type]);
                            } else {
                                bmp.SetPixel (i, j, tileTypeDefs [Main.tile.At (i, j).Wall + 267]);
                            }
                        }

                    }
                }
                Server.notifyOps("Saving Data...", true);
                bmp.Save (string.Concat (p, Path.DirectorySeparatorChar, filename));
                stopwatch.Stop ();
                ProgramLog.Log ("Save duration: " + stopwatch.Elapsed.Seconds + " Second(s)");
                Server.notifyOps("Saving Complete.", true);
                bmp = null;
                isMapping = false;
        }
 public static void RemoveProgressLogger(ProgressLogger prog)
 {
     Write(new LogEntry(prog, null));
 }