public override void Process(int whoAmI, byte[] readBuffer, int length, int num)
        {
            byte doorAction = readBuffer[num++];
            int  x          = BitConverter.ToInt32(readBuffer, num);

            num += 4;
            int y = BitConverter.ToInt32(readBuffer, num);

            num += 4;

            int doorDirection = (int)readBuffer[num];
            int direction     = 0;

            if (doorDirection == 0)
            {
                direction = -1;
            }

            bool state = (doorAction == 0); //if open

            if (state)
            {
                lock (WorldModify.playerEditLock)
                    WorldModify.OpenDoor(null, null, x, y, direction, Main.players[whoAmI]);
            }
            else if (doorAction == 1)
            {
                lock (WorldModify.playerEditLock)
                    WorldModify.CloseDoor(null, null, x, y, false, Main.players[whoAmI]);
            }

            NetMessage.SendData(19, -1, whoAmI, "", (int)doorAction, (float)x, (float)y, (float)doorDirection);
        }
        public static bool SwitchTiles(Func <Int32, Int32, ITile> TileRefs, ISandbox sandbox, Vector2 Position, int Width, int Height, Vector2 oldPosition, ISender Sender)
        {
            if (TileRefs == null)
            {
                TileRefs = TileCollection.ITileAt;
            }

            int num  = (int)(Position.X / 16f) - 1;
            int num2 = (int)((Position.X + (float)Width) / 16f) + 2;
            int num3 = (int)(Position.Y / 16f) - 1;
            int num4 = (int)((Position.Y + (float)Height) / 16f) + 2;

            if (num < 0)
            {
                num = 0;
            }

            if (num2 > Main.maxTilesX)
            {
                num2 = Main.maxTilesX;
            }

            if (num3 < 0)
            {
                num3 = 0;
            }

            if (num4 > Main.maxTilesY)
            {
                num4 = Main.maxTilesY;
            }

            for (int x = num; x < num2; x++)
            {
                for (int y = num3; y < num4; y++)
                {
                    if (TileRefs(x, y).Active&& TileRefs(x, y).Type == 135)
                    {
                        Vector2 vector;
                        vector.X = (float)(x * 16);
                        vector.Y = (float)(y * 16 + 12);
                        if (Position.X + (float)Width > vector.X && Position.X < vector.X + 16f && Position.Y +
                            (float)Height > vector.Y && (double)Position.Y < (double)vector.Y + 4.01 && (oldPosition.X +
                                                                                                         (float)Width <= vector.X || oldPosition.X >= vector.X + 16f || oldPosition.Y +
                                                                                                         (float)Height <= vector.Y || (double)oldPosition.Y >= (double)vector.Y + 16.01))
                        {
                            WorldModify.hitSwitch(TileRefs, sandbox, x, y, Sender);
                            NetMessage.SendData(59, -1, -1, "", x, (float)y, 0f, 0f, 0);
                            return(true);
                        }
                    }
                }
            }
            return(false);
        }
        public override void Process(int whoAmI, byte[] readBuffer, int length, int num)
        {
            int X = BitConverter.ToInt32(readBuffer, num);

            num += 4;
            int Y = BitConverter.ToInt32(readBuffer, num);

            num += 4;

            WorldModify.hitSwitch(X, Y, Main.players[whoAmI]);
            NetMessage.SendData(59, -1, whoAmI, "", X, (float)Y, 0f, 0f, 0);
        }
Пример #4
0
        public override void Process(int whoAmI, byte[] readBuffer, int length, int num)
        {
            int x = BitConverter.ToInt32(readBuffer, num);

            num += 4;
            int y = BitConverter.ToInt32(readBuffer, num);

            if (Main.tile.At(x, y).Type != 21)
            {
                return;
            }

            var player = Main.players[whoAmI];

            var ctx = new HookContext
            {
                Connection = player.Connection,
                Player     = player,
                Sender     = player,
            };

            var args = new HookArgs.ChestBreakReceived
            {
                X = x, Y = y,
            };

            HookPoints.ChestBreakReceived.Invoke(ref ctx, ref args);

            if (ctx.CheckForKick())
            {
                return;
            }

            if (ctx.Result == HookResult.IGNORE)
            {
                return;
            }

            if (ctx.Result == HookResult.RECTIFY)
            {
                NetMessage.SendTileSquare(whoAmI, x, y, 3);
                return;
            }

            WorldModify.KillTile(null, null, x, y);

            if (!Main.tile.At(x, y).Active || Main.tile.At(x, y).Type != 21)
            {
                NetMessage.SendData(17, -1, -1, "", 0, (float)x, (float)y);
            }
        }
        public static void AddWater(Func <Int32, Int32, ITile> TileRefs, ISandbox sandbox, int x, int y)
        {
            if (TileRefs == null)
            {
                TileRefs = TileCollection.ITileAt;
            }

            if (TileRefs(x, y).CheckingLiquid || (x >= Main.maxTilesX - 5 || y >= Main.maxTilesY - 5) || (x < 5 || y < 5) || TileRefs(x, y).Liquid == 0)
            {
                return;
            }

            if (Liquid.numLiquid >= Liquid.maxLiquid - 1)
            {
                LiquidBuffer.AddBuffer(TileRefs, x, y);
                return;
            }

            TileRefs(x, y).SetCheckingLiquid(true);
            Main.liquid[Liquid.numLiquid].kill  = 0;
            Main.liquid[Liquid.numLiquid].x     = x;
            Main.liquid[Liquid.numLiquid].y     = y;
            Main.liquid[Liquid.numLiquid].delay = 0;
            TileRefs(x, y).SetSkipLiquid(false);

            Liquid.numLiquid++;

            if (Liquid.numLiquid < Liquid.maxLiquid / 3)
            {
                NetMessage.SendWater(x, y);
            }
            if (TileRefs(x, y).Active&& (Main.tileWaterDeath[(int)TileRefs(x, y).Type] || (TileRefs(x, y).Lava&& Main.tileLavaDeath[(int)TileRefs(x, y).Type])))
            {
                if (TileRefs(x, y).Type == 4 && TileRefs(x, y).FrameY == 176)
                {
                    return;
                }

                if (WorldModify.gen)
                {
                    TileRefs(x, y).SetActive(false);
                    return;
                }
                WorldModify.KillTile(TileRefs, sandbox, x, y);
                NetMessage.SendData(17, -1, -1, "", 0, (float)x, (float)y);
            }
        }
        public static void HitTiles(Func <Int32, Int32, ITile> TileRefs, ISandbox sandbox, Vector2 Position, Vector2 Velocity, int Width, int Height)
        {
            if (TileRefs == null)
            {
                TileRefs = TileCollection.ITileAt;
            }

            Vector2 nextPos = Position + Velocity;
            int     left    = (int)(Position.X / 16f) - 1;
            int     right   = (int)((Position.X + (float)Width) / 16f) + 2;
            int     top     = (int)(Position.Y / 16f) - 1;
            int     bottom  = (int)((Position.Y + (float)Height) / 16f) + 2;

            if (left < 0)
            {
                left = 0;
            }
            if (right > Main.maxTilesX)
            {
                right = Main.maxTilesX;
            }
            if (top < 0)
            {
                top = 0;
            }
            if (bottom > Main.maxTilesY)
            {
                bottom = Main.maxTilesY;
            }
            for (int i = left; i < right; i++)
            {
                for (int j = top; j < bottom; j++)
                {
                    if (TileRefs(i, j).Active&& (Main.tileSolid[(int)TileRefs(i, j).Type] || (Main.tileSolidTop[(int)TileRefs(i, j).Type] && TileRefs(i, j).FrameY == 0)))
                    {
                        Vector2 vector2;
                        vector2.X = (float)(i * 16);
                        vector2.Y = (float)(j * 16);
                        if (nextPos.X + (float)Width >= vector2.X && nextPos.X <= vector2.X + 16f && nextPos.Y + (float)Height >= vector2.Y && nextPos.Y <= vector2.Y + 16f)
                        {
                            WorldModify.KillTile(TileRefs, sandbox, i, j, true, true);
                        }
                    }
                }
            }
        }
        public static void LavaCheck(Func <Int32, Int32, ITile> TileRefs, ISandbox sandbox, int x, int y)
        {
            if (TileRefs == null)
            {
                TileRefs = TileCollection.ITileAt;
            }

            if ((TileRefs(x - 1, y).Liquid > 0 && !TileRefs(x - 1, y).Lava) || (TileRefs(x + 1, y).Liquid > 0 && !TileRefs(x + 1, y).Lava) || (TileRefs(x, y - 1).Liquid > 0 && !TileRefs(x, y - 1).Lava))
            {
                int liq = 0;
                if (!TileRefs(x - 1, y).Lava)
                {
                    liq += (int)TileRefs(x - 1, y).Liquid;
                    TileRefs(x - 1, y).SetLiquid(0);
                }
                if (!TileRefs(x + 1, y).Lava)
                {
                    liq += (int)TileRefs(x + 1, y).Liquid;
                    TileRefs(x + 1, y).SetLiquid(0);
                }
                if (!TileRefs(x, y - 1).Lava)
                {
                    liq += (int)TileRefs(x, y - 1).Liquid;
                    TileRefs(x, y - 1).SetLiquid(0);
                }
                if (liq >= 32 && !TileRefs(x, y).Active)
                {
                    TileRefs(x, y).SetLiquid(0);
                    TileRefs(x, y).SetLava(false);
                    WorldModify.PlaceTile(TileRefs, sandbox, x, y, 56, true, true, -1, 0);
                    WorldModify.SquareTileFrame(TileRefs, sandbox, x, y, true);

                    NetMessage.SendTileSquare(-1, x - 1, y - 1, 3);
                    return;
                }
            }
            else if (TileRefs(x, y + 1).Liquid > 0 && !TileRefs(x, y + 1).Lava&& !TileRefs(x, y + 1).Active)
            {
                TileRefs(x, y).SetLiquid(0);
                TileRefs(x, y).SetLava(false);
                TileRefs(x, y + 1).SetLiquid(0);
                WorldModify.PlaceTile(TileRefs, sandbox, x, y + 1, 56, true, true, -1, 0);
                WorldModify.SquareTileFrame(TileRefs, sandbox, x, y + 1, true);
                NetMessage.SendTileSquare(-1, x - 1, y, 3);
            }
        }
        public static void AddWater(int x, int y)
        {
            if (Main.tile.At(x, y).CheckingLiquid)
            {
                return;
            }
            if (x >= Main.maxTilesX - 5 || y >= Main.maxTilesY - 5)
            {
                return;
            }
            if (x < 5 || y < 5)
            {
                return;
            }
            if (Main.tile.At(x, y).Liquid == 0)
            {
                return;
            }
            if (Liquid.numLiquid >= Liquid.maxLiquid - 1)
            {
                LiquidBuffer.AddBuffer(x, y);
                return;
            }
            Main.tile.At(x, y).SetCheckingLiquid(true);
            Main.liquid[Liquid.numLiquid].kill  = 0;
            Main.liquid[Liquid.numLiquid].x     = x;
            Main.liquid[Liquid.numLiquid].y     = y;
            Main.liquid[Liquid.numLiquid].delay = 0;
            Main.tile.At(x, y).SetSkipLiquid(false);
            Liquid.numLiquid++;

            NetMessage.SendWater(x, y);

            if (Main.tile.At(x, y).Active&& (Main.tileWaterDeath[(int)Main.tile.At(x, y).Type] || (Main.tile.At(x, y).Lava&& Main.tileLavaDeath[(int)Main.tile.At(x, y).Type])))
            {
                if (WorldModify.gen)
                {
                    Main.tile.At(x, y).SetActive(false);
                    return;
                }
                WorldModify.KillTile(x, y, false, false, false);
                NetMessage.SendData(17, -1, -1, "", 0, (float)x, (float)y);
            }
        }
        public static void LavaCheck(int x, int y)
        {
            if ((Main.tile.At(x - 1, y).Liquid > 0 && !Main.tile.At(x - 1, y).Lava) || (Main.tile.At(x + 1, y).Liquid > 0 && !Main.tile.At(x + 1, y).Lava) || (Main.tile.At(x, y - 1).Liquid > 0 && !Main.tile.At(x, y - 1).Lava))
            {
                int num = 0;

                if (!Main.tile.At(x - 1, y).Lava)
                {
                    num += (int)Main.tile.At(x - 1, y).Liquid;
                    Main.tile.At(x - 1, y).SetLiquid(0);
                }

                if (!Main.tile.At(x + 1, y).Lava)
                {
                    num += (int)Main.tile.At(x + 1, y).Liquid;
                    Main.tile.At(x + 1, y).SetLiquid(0);
                }

                if (!Main.tile.At(x, y - 1).Lava)
                {
                    num += (int)Main.tile.At(x, y - 1).Liquid;
                    Main.tile.At(x, y - 1).SetLiquid(0);
                }

                if (num >= 128 && !Main.tile.At(x, y).Active)
                {
                    ClearLava(x, y);
                    WorldModify.PlaceTile(x, y, 56, true, true, -1, 0);
                    WorldModify.SquareTileFrame(x, y, true);

                    NetMessage.SendTileSquare(-1, x - 1, y - 1, 3);
                    return;
                }
            }
            else if (Main.tile.At(x, y + 1).Liquid > 0 && !Main.tile.At(x, y + 1).Lava&& !Main.tile.At(x, y + 1).Active)
            {
                ClearLava(x, y);
                WorldModify.PlaceTile(x, y + 1, 56, true, true, -1, 0);
                WorldModify.SquareTileFrame(x, y + 1, true);

                NetMessage.SendTileSquare(-1, x - 1, y, 3);
            }
        }
        public static void HitTiles(Vector2 Position, Vector2 Velocity, int Width, int Height)
        {
            Vector2 nextPos = Position + Velocity;
            int     left    = (int)(Position.X / 16f) - 1;
            int     right   = (int)((Position.X + (float)Width) / 16f) + 2;
            int     top     = (int)(Position.Y / 16f) - 1;
            int     bottom  = (int)((Position.Y + (float)Height) / 16f) + 2;

            if (left < 0)
            {
                left = 0;
            }
            if (right > Main.maxTilesX)
            {
                right = Main.maxTilesX;
            }
            if (top < 0)
            {
                top = 0;
            }
            if (bottom > Main.maxTilesY)
            {
                bottom = Main.maxTilesY;
            }
            for (int i = left; i < right; i++)
            {
                for (int j = top; j < bottom; j++)
                {
                    if (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).FrameY == 0)))
                    {
                        Vector2 vector2;
                        vector2.X = (float)(i * 16);
                        vector2.Y = (float)(j * 16);
                        if (nextPos.X + (float)Width >= vector2.X && nextPos.X <= vector2.X + 16f && nextPos.Y + (float)Height >= vector2.Y && nextPos.Y <= vector2.Y + 16f)
                        {
                            WorldModify.KillTile(i, j, true, true, false);
                        }
                    }
                }
            }
        }
Пример #11
0
        public override void Process(int whoAmI, byte[] readBuffer, int length, int num)
        {
            short npcId = BitConverter.ToInt16(readBuffer, num);

            num += 2;
            short homeTileX = BitConverter.ToInt16(readBuffer, num);

            num += 2;
            short homeTileY = BitConverter.ToInt16(readBuffer, num);

            num += 2;
            var homed = readBuffer[num++] == 0;

            if (homed)             //Kick out if they are
            {
                Main.npcs[(int)npcId].homeless = true;
                return;
            }

            WorldModify.MoveRoom((int)homeTileX, (int)homeTileY, (int)npcId);
        }
Пример #12
0
        //static TimeChangedEvent timeEvent = new TimeChangedEvent();
        private static void UpdateTime()
        {
            Main.time += 1.0;

            //Server.PluginManager.processHook(Hooks.TIME_CHANGED, timeEvent);

            if (!Main.dayTime)
            {
                if (WorldModify.spawnEye)
                {
                    if (Main.time > 4860.0)
                    {
                        int count = 0;
                        foreach (Player player in Main.players)
                        {
                            if (player.Active && !player.dead && (double)player.Position.Y < Main.worldSurface * 16.0)
                            {
                                NPC.SpawnOnPlayer(player, count, 4);
                                WorldModify.spawnEye = false;
                                break;
                            }
                            count++;
                        }
                    }
                }

                if (Main.time > 32400.0)
                {
                    if (Main.invasionDelay > 0)
                    {
                        Main.invasionDelay--;
                    }
                    WorldModify.spawnNPC = 0;
                    Main.checkForSpawns  = 0;
                    Main.time            = 0.0;
                    Main.bloodMoon       = false;
                    Main.dayTime         = true;
                    Main.moonPhase++;
                    if (Main.moonPhase >= 8)
                    {
                        Main.moonPhase = 0;
                    }

                    NetMessage.SendData(7);
                    WorldIO.SaveWorldThreaded();

                    if (Main.rand.Next(15) == 0)
                    {
                        Main.StartInvasion();
                    }
                }
                if (Main.time > 16200.0 && WorldModify.spawnMeteor)
                {
                    WorldModify.spawnMeteor = false;
                    WorldModify.dropMeteor();
                }
            }
            else
            {
                if (Main.time > 54000.0)
                {
                    WorldModify.spawnNPC = 0;
                    Main.checkForSpawns  = 0;
                    if (Main.rand.Next(50) == 0 && WorldModify.shadowOrbSmashed)
                    {
                        WorldModify.spawnMeteor = true;
                    }
                    if (!NPC.downedBoss1)
                    {
                        bool flag = false;
                        foreach (Player player in Main.players)
                        {
                            if (player.Active && player.statLifeMax >= 200)
                            {
                                flag = true;
                                break;
                            }
                        }
                        if (flag && Main.rand.Next(3) == 0)
                        {
                            int num = 0;
                            for (int i = 0; i < NPC.MAX_NPCS; i++)
                            {
                                if (Main.npcs[i].Active)
                                {
                                    if (Main.npcs[i].townNPC)
                                    {
                                        num++;
                                    }
                                }
                            }
                            if (num >= 4)
                            {
                                WorldModify.spawnEye = true;

                                NetMessage.SendData(25, -1, -1, "You feel an evil presence watching you...", 255, 50f, 255f, 130f);
                            }
                        }
                    }
                    if (!WorldModify.spawnEye && Main.moonPhase != 4 && Main.rand.Next(7) == 0)
                    {
                        for (int i = 0; i < 255; i++)
                        {
                            if (Main.players[i].Active && Main.players[i].statLifeMax > 100)
                            {
                                Main.bloodMoon = true;
                                break;
                            }
                        }
                        if (Main.bloodMoon)
                        {
                            NetMessage.SendData(25, -1, -1, "The Blood Moon is rising...", 255, 50f, 255f, 130f);
                        }
                    }
                    Main.time    = 0.0;
                    Main.dayTime = false;

                    NetMessage.SendData(7);
                }
                Main.checkForSpawns++;
                if (Main.checkForSpawns >= 7200)
                {
                    int num2 = 0;
                    for (int i = 0; i < 255; i++)
                    {
                        if (Main.players[i].Active)
                        {
                            num2++;
                        }
                    }
                    Main.checkForSpawns  = 0;
                    WorldModify.spawnNPC = 0;
                    int num3  = 0;
                    int num4  = 0;
                    int num5  = 0;
                    int num6  = 0;
                    int num7  = 0;
                    int num8  = 0;
                    int num9  = 0;
                    int num10 = 0;
                    int num11 = 0;
                    for (int i = 0; i < NPC.MAX_NPCS; i++)
                    {
                        if (Main.npcs[i].Active && Main.npcs[i].townNPC)
                        {
                            if (Main.npcs[i].type != NPCType.N37_OLD_MAN && !Main.npcs[i].homeless)
                            {
                                WorldModify.QuickFindHome(i);
                            }
                            else
                            {
                                num8++;
                            }
                            switch (Main.npcs[i].type)
                            {
                            case NPCType.N17_MERCHANT:
                                num3++;
                                break;

                            case NPCType.N18_NURSE:
                                num4++;
                                break;

                            case NPCType.N19_ARMS_DEALER:
                                num6++;
                                break;

                            case NPCType.N20_DRYAD:
                                num5++;
                                break;

                            case NPCType.N22_GUIDE:
                                num7++;
                                break;

                            case NPCType.N38_DEMOLITIONIST:
                                num9++;
                                break;

                            case NPCType.N54_CLOTHIER:
                                num10++;
                                break;
                            }
                            num11++;
                        }
                    }
                    if (WorldModify.spawnNPC == 0)
                    {
                        int  num12 = 0;
                        bool flag2 = false;
                        int  num13 = 0;
                        bool flag3 = false;
                        bool flag4 = false;
                        for (int i = 0; i < 255; i++)
                        {
                            if (Main.players[i].Active)
                            {
                                for (int j = 0; j < 44; j++)
                                {
                                    if (Main.players[i].inventory[j] != null & Main.players[i].inventory[j].Stack > 0)
                                    {
                                        if (Main.players[i].inventory[j].Type == 71)
                                        {
                                            num12 += Main.players[i].inventory[j].Stack;
                                        }
                                        if (Main.players[i].inventory[j].Type == 72)
                                        {
                                            num12 += Main.players[i].inventory[j].Stack * 100;
                                        }
                                        if (Main.players[i].inventory[j].Type == 73)
                                        {
                                            num12 += Main.players[i].inventory[j].Stack * 10000;
                                        }
                                        if (Main.players[i].inventory[j].Type == 74)
                                        {
                                            num12 += Main.players[i].inventory[j].Stack * 1000000;
                                        }
                                        if (Main.players[i].inventory[j].Ammo == ProjectileType.N14_BULLET || Main.players[i].inventory[j].UseAmmo == ProjectileType.N14_BULLET)
                                        {
                                            flag3 = true;
                                        }
                                        if (Main.players[i].inventory[j].Type == 166 || Main.players[i].inventory[j].Type == 167 || Main.players[i].inventory[j].Type == 168 || Main.players[i].inventory[j].Type == 235)
                                        {
                                            flag4 = true;
                                        }
                                    }
                                }
                                int num14 = Main.players[i].statLifeMax / 20;
                                if (num14 > 5)
                                {
                                    flag2 = true;
                                }
                                num13 += num14;
                            }
                        }
                        if (num7 < 1)
                        {
                            WorldModify.spawnNPC = 22;
                        }
                        if ((double)num12 > 5000.0 && num3 < 1)
                        {
                            WorldModify.spawnNPC = 17;
                        }
                        if (flag2 && num4 < 1)
                        {
                            WorldModify.spawnNPC = 18;
                        }
                        if (flag3 && num6 < 1)
                        {
                            WorldModify.spawnNPC = 19;
                        }
                        if ((NPC.downedBoss1 || NPC.downedBoss2 || NPC.downedBoss3) && num5 < 1)
                        {
                            WorldModify.spawnNPC = 20;
                        }
                        if (flag4 && num3 > 0 && num9 < 1)
                        {
                            WorldModify.spawnNPC = 38;
                        }
                        if (NPC.downedBoss3 && num10 < 1)
                        {
                            WorldModify.spawnNPC = 54;
                        }
                        if (num12 > 100000 && num3 < 2 && num2 > 2)
                        {
                            WorldModify.spawnNPC = 17;
                        }
                        if (num13 >= 20 && num4 < 2 && num2 > 2)
                        {
                            WorldModify.spawnNPC = 18;
                        }
                        if (num12 > 5000000 && num3 < 3 && num2 > 4)
                        {
                            WorldModify.spawnNPC = 17;
                        }
                        if (!NPC.downedBoss3 && num8 == 0)
                        {
                            int num15 = NPC.NewNPC(Main.dungeonX * 16 + 8, Main.dungeonY * 16, 37, 0);
                            Main.npcs[num15].homeless  = false;
                            Main.npcs[num15].homeTileX = Main.dungeonX;
                            Main.npcs[num15].homeTileY = Main.dungeonY;
                        }
                    }
                }
            }
        }
        public static void UpdateLiquid(Func <Int32, Int32, ITile> TileRefs, ISandbox sandbox)
        {
            if (TileRefs == null)
            {
                TileRefs = TileCollection.ITileAt;
            }

            //{
            //Liquid.cycles = 30;
            //    Liquid.maxLiquid = 6000;
            //}

            if (!WorldModify.gen)
            {
                if (!Liquid.panicMode)
                {
                    if (Liquid.numLiquid + LiquidBuffer.numLiquidBuffer > 4000)
                    {
                        Liquid.panicCounter++;
                        if (Liquid.panicCounter > 1800 || Liquid.numLiquid + LiquidBuffer.numLiquidBuffer > 13500)
                        {
                            Liquid.StartPanic();
                        }
                    }
                    else
                    {
                        Liquid.panicCounter = 0;
                    }
                }

                if (Liquid.panicMode)
                {
                    int num = 0;
                    while (Liquid.panicY >= 3 && num < 5)
                    {
                        num++;
                        Liquid.QuickWater(TileRefs, sandbox, 0, Liquid.panicY, Liquid.panicY);
                        Liquid.panicY--;
                        if (Liquid.panicY < 3)
                        {
                            ProgramLog.Log(Languages.Water_WaterHasBeenSettled);
                            Liquid.panicCounter = 0;
                            Liquid.panicMode    = false;

                            using (var prog = new ProgressLogger(Main.maxTilesX - 2, Languages.Water_PerformingWaterCheck))
                                WorldModify.WaterCheck(TileRefs, sandbox, prog);

                            for (int i = 0; i < 255; i++)
                            {
                                for (int j = 0; j < Main.maxSectionsX; j++)
                                {
                                    for (int k = 0; k < Main.maxSectionsY; k++)
                                    {
                                        NetPlay.slots[i].tileSection[j, k] = false;
                                    }
                                }
                            }
                        }
                    }
                    return;
                }
            }

            Liquid.quickFall = Liquid.quickSettle || Liquid.numLiquid > 2000;
            Liquid.wetCounter++;

            int num2 = Liquid.maxLiquid / Liquid.cycles;
            int num3 = num2 * (Liquid.wetCounter - 1);
            int num4 = num2 * Liquid.wetCounter;

            if (Liquid.wetCounter == Liquid.cycles)
            {
                num4 = Liquid.numLiquid;
            }

            if (num4 > Liquid.numLiquid)
            {
                num4 = Liquid.numLiquid;
                Liquid.wetCounter = Liquid.cycles;
            }

            if (Liquid.quickFall)
            {
                for (int l = num3; l < num4; l++)
                {
                    Main.liquid[l].delay = 10;
                    Main.liquid[l].Update(TileRefs, sandbox);
                    TileRefs(Main.liquid[l].x, Main.liquid[l].y).SetSkipLiquid(false);
                }
            }
            else
            {
                for (int m = num3; m < num4; m++)
                {
                    if (!TileRefs(Main.liquid[m].x, Main.liquid[m].y).SkipLiquid)
                    {
                        Main.liquid[m].Update(TileRefs, sandbox);
                    }
                    else
                    {
                        TileRefs(Main.liquid[m].x, Main.liquid[m].y).SetSkipLiquid(false);
                    }
                }
            }

            if (Liquid.wetCounter >= Liquid.cycles)
            {
                Liquid.wetCounter = 0;

                for (int n = Liquid.numLiquid - 1; n >= 0; n--)
                {
                    if (Main.liquid[n].kill > 3)
                    {
                        Liquid.DelWater(TileRefs, sandbox, n);
                    }
                }

                int num5 = Liquid.maxLiquid - (Liquid.maxLiquid - Liquid.numLiquid);
                if (num5 > LiquidBuffer.numLiquidBuffer)
                {
                    num5 = LiquidBuffer.numLiquidBuffer;
                }

                for (int num6 = 0; num6 < num5; num6++)
                {
                    TileRefs(Main.liquidBuffer[0].x, Main.liquidBuffer[0].y).SetCheckingLiquid(false);
                    Liquid.AddWater(TileRefs, sandbox, Main.liquidBuffer[0].x, Main.liquidBuffer[0].y);
                    LiquidBuffer.DelBuffer(0);
                }

                if (Liquid.numLiquid > 0 && Liquid.numLiquid > Liquid.stuckAmount - 50 && Liquid.numLiquid < Liquid.stuckAmount + 50)
                {
                    Liquid.stuckCount++;
                    if (Liquid.stuckCount >= 10000)
                    {
                        Liquid.stuck = true;

                        for (int num7 = Liquid.numLiquid - 1; num7 >= 0; num7--)
                        {
                            Liquid.DelWater(TileRefs, sandbox, num7);
                        }

                        Liquid.stuck      = false;
                        Liquid.stuckCount = 0;
                        return;
                    }
                }
                else
                {
                    Liquid.stuckCount  = 0;
                    Liquid.stuckAmount = Liquid.numLiquid;
                }
            }
        }
        public static Vector2 HurtTiles(Func <Int32, Int32, ITile> TileRefs, ISandbox sandbox, Vector2 Position, Vector2 Velocity, int Width, int Height, bool fireImmune = false)
        {
            if (TileRefs == null)
            {
                TileRefs = TileCollection.ITileAt;
            }

            int left   = (int)(Position.X / 16f) - 1;
            int right  = (int)((Position.X + (float)Width) / 16f) + 2;
            int top    = (int)(Position.Y / 16f) - 1;
            int bottom = (int)((Position.Y + (float)Height) / 16f) + 2;

            if (left < 0)
            {
                left = 0;
            }
            if (right > Main.maxTilesX)
            {
                right = Main.maxTilesX;
            }
            if (top < 0)
            {
                top = 0;
            }
            if (bottom > Main.maxTilesY)
            {
                bottom = Main.maxTilesY;
            }
            for (int i = left; i < right; i++)
            {
                for (int j = top; j < bottom; j++)
                {
                    if (TileRefs(i, j).Active&& (TileRefs(i, j).Type == 32 || TileRefs(i, j).Type == 37 || TileRefs(i, j).Type == 48 || TileRefs(i, j).Type == 53 || TileRefs(i, j).Type == 57 || TileRefs(i, j).Type == 58 || TileRefs(i, j).Type == 59 || TileRefs(i, j).Type == 69 || TileRefs(i, j).Type == 76 || TileRefs(i, j).Type == 80))
                    {
                        Vector2 vector2;
                        vector2.X = (float)(i * 16);
                        vector2.Y = (float)(j * 16);
                        int Y    = 0;
                        int type = (int)TileRefs(i, j).Type;
                        if (type == 32 || type == 69 || type == 80)
                        {
                            if (Position.X + (float)Width > vector2.X && Position.X < vector2.X + 16f && Position.Y + (float)Height > vector2.Y && (double)Position.Y < (double)vector2.Y + 16.01)
                            {
                                int directionX = 1;
                                if (Position.X + (float)(Width / 2) < vector2.X + 8f)
                                {
                                    directionX = -1;
                                }

                                Y = 10;
                                if (type == 69)
                                {
                                    Y = 17;
                                }
                                else if (type == 80)
                                {
                                    Y = 6;
                                }
                                if (type == 32 || type == 69)
                                {
                                    WorldModify.KillTile(TileRefs, sandbox, i, j);
                                }

                                return(new Vector2((float)directionX, (float)Y));
                            }
                        }
                        else if (type == 53 || type == 112 || type == 116 || type == 123)
                        {
                            if (Position.X + (float)Width - 2f >= vector2.X && Position.X + 2f <= vector2.X + 16f && Position.Y + (float)Height - 2f >= vector2.Y && Position.Y + 2f <= vector2.Y + 16f)
                            {
                                int directionX = 1;
                                if (Position.X + (float)(Width / 2) < vector2.X + 8f)
                                {
                                    directionX = -1;
                                }

                                Y = 20;
                                return(new Vector2((float)directionX, (float)Y));
                            }
                        }
                        else if (Position.X + (float)Width >= vector2.X && Position.X <= vector2.X + 16f && Position.Y + (float)Height >= vector2.Y && (double)Position.Y <= (double)vector2.Y + 16.01)
                        {
                            int directionX = 1;
                            if (Position.X + (float)(Width / 2) < vector2.X + 8f)
                            {
                                directionX = -1;
                            }

                            if (!fireImmune && (type == 37 || type == 58 || type == 76))
                            {
                                Y = 20;
                            }
                            if (type == 48)
                            {
                                Y = 40;
                            }

                            return(new Vector2((float)directionX, (float)Y));
                        }
                    }
                }
            }
            return(default(Vector2));
        }
        public static void Update(Stopwatch s)
        {
            int count = 0;

            int timeUpdateErrors     = 0;
            int worldUpdateErrors    = 0;
            int invasionUpdateErrors = 0;
            int serverUpdateErrors   = 0;

            var start = s.Elapsed;

            foreach (Player player in players)
            {
                try
                {
                    player.UpdatePlayer(null, null, count);
                }
                catch (Exception e)
                {
                    if (!ignoreErrors)
                    {
                        throw;
                    }

                    ProgramLog.Log(e, String.Format("Player update error, slot={0}, address={1}, name={2}",
                                                    player.whoAmi, player.IPAddress, player.Name != null ? string.Concat('"', player.Name, '"') : "<null>"));

                    player.Kick("Server malfunction, please reconnect.");
                }
                count++;
            }
            LastPlayerUpdateTime = s.Elapsed - start;

            lock (updatingNPCs)
            {
                start = s.Elapsed;

                NPC.SpawnNPC();

                foreach (Player player in players)
                {
                    player.ActiveNPCs = 0;
                    player.TownNPCs   = 0;
                }

                if (WallOfFlesh >= 0)
                {
                    var WoF   = npcs[WallOfFlesh];
                    var isWoF = WoF.type == NPCType.N113_WALL_OF_FLESH || WoF.type == NPCType.N114_WALL_OF_FLESH_EYE;
                    if (!isWoF && WoF.Active || !WoF.Active && isWoF)
                    {
                        WallOfFlesh = -1;
                    }
                }

                for (int i = 0; i < NPC.MAX_NPCS; i++)
                //					if (npcs[i] == null)
                //					{
                //						ProgramLog.Debug.Log ("NPC[{0}] is null", i);
                //						continue;
                //					}
#if CATCHERROR_NPCUPDATES
                { try
                  {
#endif
                { NPC.UpdateNPC(i); }
#if CATCHERROR_NPCUPDATES
            }
            catch (Exception e)
            {
                if (!ignoreErrors)
                {
                    throw;
                }

                var npc = npcs[i];
                ProgramLog.Log(e, String.Format("NPC update error, id={0}, type={1}, name={2}",
                                                i, npc.Type, npc.Name));

                npcs[i]           = Registries.NPC.Default;
                npcs[i].netUpdate = true;
            }
#endif

                LastNPCUpdateTime = s.Elapsed - start;
            }

            lock (updatingProjectiles)
            {
                start = s.Elapsed;

                for (int i = 0; i < 1000; i++)
                {
                    //					if (projectile[i] == null)
                    //					{
                    //						ProgramLog.Debug.Log ("Projectile[{0}] is null", i);
                    //						continue;
                    //					}

                    try
                    {
                        lock (WorldModify.playerEditLock)
                        {
                            var editor  = TileBreakMessage.staticEditor;
                            var sandbox = editor.Sandbox;

                            editor.Sandbox.Initialize();
                            projectile[i].Update(editor.ITileAt, sandbox, i);

                            Player player = null;
                            if (projectile != null && projectile[i].Owner != myPlayer)
                            {
                                player = players[projectile[i].Owner];
                            }

                            editor.Sandbox.Apply(player);
                        }
                    }
                    catch (Exception e)
                    {
                        if (!ignoreErrors)
                        {
                            throw;
                        }

                        var proj = projectile[i];
                        ProgramLog.Log(e, String.Format("Projectile update error, i={0}, id={1}, owner={2}, type={3}",
                                                        i, proj.identity, proj.Owner, proj.Type));
                        //projectile[i] = new Projectile();
                        Projectile.Reset(i);
                    }
                }

                LastProjectileUpdateTime = s.Elapsed - start;
            }

            lock (updatingItems)
            {
                start = s.Elapsed;

                for (int i = 0; i < 200; i++)
                    //					if (item[i] == null)
                    //					{
                    //						ProgramLog.Debug.Log ("Item[{0}] is null", i);
                    //						continue;
                    //					}

                    try
                    {
                        item[i].UpdateItem(null, i);
                    }
                    catch (Exception e)
                    {
                        if (!ignoreErrors)
                        {
                            throw;
                        }

                        var itm = item[i];
                        ProgramLog.Log(e, String.Format("Projectile update error, i={0}, type={1}, owner={2}, stack={3}",
                                                        i, itm.Type, itm.Owner, itm.Stack));
                        item[i] = new Item();
                    } }

                LastItemUpdateTime = s.Elapsed - start;
            }

            start = s.Elapsed;
            try
            {
                UpdateTime();
                timeUpdateErrors = 0;
            }
            catch (Exception e)
            {
                if (++timeUpdateErrors >= 5 || !ignoreErrors)
                {
                    throw;
                }

                ProgramLog.Log(e, "Time update error");
                checkForSpawns = 0;
            }
            LastTimeUpdateTime = s.Elapsed - start;

            start = s.Elapsed;
            try
            {
                WorldModify.UpdateWorld(null, null, World.Sender);
                worldUpdateErrors = 0;
            }
            catch (Exception e)
            {
                if (++worldUpdateErrors >= 5 || !ignoreErrors)
                {
                    throw;
                }

                ProgramLog.Log(e, "World update error");
            }
            LastWorldUpdateTime = s.Elapsed - start;

            start = s.Elapsed;
            try
            {
                UpdateInvasion();
                invasionUpdateErrors = 0;
            }
            catch (Exception e)
            {
                if (++invasionUpdateErrors >= 5 || !ignoreErrors)
                {
                    throw;
                }

                ProgramLog.Log(e, "Invasion update error");
            }
            LastInvasionUpdateTime = s.Elapsed - start;

            start = s.Elapsed;
            try
            {
                UpdateServer();
                serverUpdateErrors = 0;
            }
            catch (Exception e)
            {
                if (++serverUpdateErrors >= 5 || !ignoreErrors)
                {
                    throw;
                }

                ProgramLog.Log(e, "Server update error");
            }
            LastServerUpdateTime = s.Elapsed - start;
        }
        public override void Process(int whoAmI, byte[] readBuffer, int length, int num)
        {
            int x = BitConverter.ToInt32(readBuffer, num);

            num += 4;
            int y = BitConverter.ToInt32(readBuffer, num);

            num += 4;
            byte liquid   = readBuffer[num++];
            byte lavaFlag = readBuffer[num]++;

            var player = Main.players[whoAmI];

            if (NetPlay.spamCheck) // dead code...
            {
                int centerX          = (int)(player.Position.X + (float)(player.Width / 2));
                int centerY          = (int)(player.Position.Y + (float)(player.Height / 2));
                int disperseDistance = 10;
                int left             = centerX - disperseDistance;
                int right            = centerX + disperseDistance;
                int top    = centerY - disperseDistance;
                int bottom = centerY + disperseDistance;
                if (centerX < left || centerX > right || centerY < top || centerY > bottom)
                {
                    NetMessage.BootPlayer(whoAmI, "Cheating attempt detected: Liquid spam");
                    return;
                }
            }

            var ctx = new HookContext
            {
                Connection = player.Connection,
                Player     = player,
                Sender     = player,
            };

            var args = new HookArgs.LiquidFlowReceived
            {
                X      = x, Y = y,
                Amount = liquid,
                Lava   = lavaFlag == 1,
            };

            HookPoints.LiquidFlowReceived.Invoke(ref ctx, ref args);

            if (ctx.CheckForKick())
            {
                return;
            }

            if (ctx.Result == HookResult.IGNORE)
            {
                return;
            }

            if (ctx.Result == HookResult.RECTIFY)
            {
                var msg = NetMessage.PrepareThreadInstance();
                msg.FlowLiquid(x, y);
                msg.Send(whoAmI);
                return;
            }

            TileRef tile = Main.tile.At(x, y);
            {
                tile.SetLiquid(liquid);
                tile.SetLava(lavaFlag == 1);

                WorldModify.SquareTileFrame(null, null, x, y, true);
            }
        }
        public static void UpdateLiquid()
        {
            Liquid.cycles    = 25;
            Liquid.maxLiquid = 5000;

            if (!WorldModify.gen)
            {
                if (!Liquid.panicMode)
                {
                    if (Liquid.numLiquid + LiquidBuffer.numLiquidBuffer > 4000)
                    {
                        Liquid.panicCounter++;
                        if (Liquid.panicCounter > 1800 || Liquid.numLiquid + LiquidBuffer.numLiquidBuffer > 13500)
                        {
                            Liquid.StartPanic();
                        }
                    }
                    else
                    {
                        Liquid.panicCounter = 0;
                    }
                }

                if (Liquid.panicMode)
                {
                    try
                    {
                        Terraria_Server.Networking.LiquidUpdateBuffer.ClearQueue();
                        NetMessage.DisableLiquidUpdates = true;

                        int num = 0;
                        while (Liquid.panicY >= 3 && num < 5)
                        {
                            num++;
                            Liquid.QuickWater(0, Liquid.panicY, Liquid.panicY);
                            Liquid.panicY--;
                            if (Liquid.panicY < 3)
                            {
                                ProgramLog.Log("Water has been settled.");
                                Liquid.panicCounter = 0;
                                Liquid.panicMode    = false;
                                using (var prog = new ProgressLogger(Main.maxTilesX - 2, "Performing water check"))
                                    WorldModify.WaterCheck(prog);
                                for (int i = 0; i < 255; i++)
                                {
                                    for (int j = 0; j < Main.maxSectionsX; j++)
                                    {
                                        for (int k = 0; k < Main.maxSectionsY; k++)
                                        {
                                            NetPlay.slots[i].tileSection[j, k] = false;
                                        }
                                    }
                                }
                            }
                        }
                        return;
                    }
                    finally
                    {
                        NetMessage.DisableLiquidUpdates = false;
                    }
                }
            }

            if (Liquid.quickSettle || Liquid.numLiquid > 2000)
            {
                Liquid.quickFall = true;
            }
            else
            {
                Liquid.quickFall = false;
            }

            Liquid.wetCounter++;

            int num2 = Liquid.maxLiquid / Liquid.cycles;

            int num3 = num2 * (Liquid.wetCounter - 1);

            int num4 = num2 * Liquid.wetCounter;

            if (Liquid.wetCounter == Liquid.cycles)
            {
                num4 = Liquid.numLiquid;
            }

            if (num4 > Liquid.numLiquid)
            {
                num4 = Liquid.numLiquid;
                Liquid.wetCounter = Liquid.cycles;
            }

            if (Liquid.quickFall)
            {
                for (int l = num3; l < num4; l++)
                {
                    Main.liquid[l].delay = 10;
                    Main.liquid[l].Update();
                    Main.tile.At(Main.liquid[l].x, Main.liquid[l].y).SetSkipLiquid(false);
                }
            }
            else
            {
                for (int m = num3; m < num4; m++)
                {
                    if (!Main.tile.At(Main.liquid[m].x, Main.liquid[m].y).SkipLiquid)
                    {
                        Main.liquid[m].Update();
                    }
                    else
                    {
                        Main.tile.At(Main.liquid[m].x, Main.liquid[m].y).SetSkipLiquid(false);
                    }
                }
            }

            if (Liquid.wetCounter >= Liquid.cycles)
            {
                Liquid.wetCounter = 0;
                for (int n = Liquid.numLiquid - 1; n >= 0; n--)
                {
                    if (Main.liquid[n].kill > 3)
                    {
                        Liquid.DelWater(n);
                    }
                }

                int num5 = Liquid.maxLiquid - (Liquid.maxLiquid - Liquid.numLiquid);

                if (num5 > LiquidBuffer.numLiquidBuffer)
                {
                    num5 = LiquidBuffer.numLiquidBuffer;
                }

                for (int num6 = 0; num6 < num5; num6++)
                {
                    Main.tile.At(Main.liquidBuffer[0].x, Main.liquidBuffer[0].y).SetCheckingLiquid(false);
                    Liquid.AddWater(Main.liquidBuffer[0].x, Main.liquidBuffer[0].y);
                    LiquidBuffer.DelBuffer(0);
                }

                if (Liquid.numLiquid > 0 && Liquid.numLiquid > Liquid.stuckAmount - 50 && Liquid.numLiquid < Liquid.stuckAmount + 50)
                {
                    Liquid.stuckCount++;
                    if (Liquid.stuckCount >= 10000)
                    {
                        Liquid.stuck = true;
                        for (int num7 = Liquid.numLiquid - 1; num7 >= 0; num7--)
                        {
                            Liquid.DelWater(num7);
                        }
                        Liquid.stuck      = false;
                        Liquid.stuckCount = 0;
                        return;
                    }
                }
                else
                {
                    Liquid.stuckCount  = 0;
                    Liquid.stuckAmount = Liquid.numLiquid;
                }
            }
        }
        public static void DelWater(Func <Int32, Int32, ITile> TileRefs, ISandbox sandbox, int id)
        {
            if (TileRefs == null)
            {
                TileRefs = TileCollection.ITileAt;
            }

            int x = Main.liquid[id].x;
            int y = Main.liquid[id].y;

            if (TileRefs(x, y).Liquid < 2)
            {
                TileRefs(x, y).SetLiquid(0);

                if (TileRefs(x - 1, y).Liquid < 2)
                {
                    TileRefs(x - 1, y).SetLiquid(0);
                }

                if (TileRefs(x + 1, y).Liquid < 2)
                {
                    TileRefs(x + 1, y).SetLiquid(0);
                }
            }
            else if (TileRefs(x, y).Liquid < 20)
            {
                if ((TileRefs(x - 1, y).Liquid < TileRefs(x, y).Liquid&& (!TileRefs(x - 1, y).Active || !Main.tileSolid[(int)TileRefs(x - 1, y).Type] || Main.tileSolidTop[(int)TileRefs(x - 1, y).Type])) || (TileRefs(x + 1, y).Liquid < TileRefs(x, y).Liquid&& (!TileRefs(x + 1, y).Active || !Main.tileSolid[(int)TileRefs(x + 1, y).Type] || Main.tileSolidTop[(int)TileRefs(x + 1, y).Type])) || (TileRefs(x, y + 1).Liquid < 255 && (!TileRefs(x, y + 1).Active || !Main.tileSolid[(int)TileRefs(x, y + 1).Type] || Main.tileSolidTop[(int)TileRefs(x, y + 1).Type])))
                {
                    TileRefs(x, y).SetLiquid(0);
                }
            }
            else if (TileRefs(x, y + 1).Liquid < 255 && (!TileRefs(x, y + 1).Active || !Main.tileSolid[(int)TileRefs(x, y + 1).Type] || Main.tileSolidTop[(int)TileRefs(x, y + 1).Type]) && !Liquid.stuck)
            {
                Main.liquid[id].kill = 0;
                return;
            }

            if (TileRefs(x, y).Liquid < 250 && TileRefs(x, y - 1).Liquid > 0)
            {
                Liquid.AddWater(TileRefs, sandbox, x, y - 1);
            }

            if (TileRefs(x, y).Liquid == 0)
            {
                TileRefs(x, y).SetLava(false);
            }
            else
            {
                if ((TileRefs(x + 1, y).Liquid > 0 && TileRefs(x + 1, y + 1).Liquid < 250 && !TileRefs(x + 1, y + 1).Active) || (TileRefs(x - 1, y).Liquid > 0 && TileRefs(x - 1, y + 1).Liquid < 250 && !TileRefs(x - 1, y + 1).Active))
                {
                    Liquid.AddWater(TileRefs, sandbox, x - 1, y);
                    Liquid.AddWater(TileRefs, sandbox, x + 1, y);
                }
                if (TileRefs(x, y).Lava)
                {
                    Liquid.LavaCheck(TileRefs, sandbox, x, y);
                    for (int i = x - 1; i <= x + 1; i++)
                    {
                        for (int j = y - 1; j <= y + 1; j++)
                        {
                            if (TileRefs(i, j).Active)
                            {
                                if (TileRefs(i, j).Type == 2 || TileRefs(i, j).Type == 23 || TileRefs(i, j).Type == 109)
                                {
                                    TileRefs(i, j).SetType(0);
                                    WorldModify.SquareTileFrame(TileRefs, sandbox, i, j, true);
                                    NetMessage.SendTileSquare(-1, x, y, 3);
                                }
                                else if (TileRefs(i, j).Type == 60 || TileRefs(i, j).Type == 70)
                                {
                                    TileRefs(i, j).SetType(59);
                                    WorldModify.SquareTileFrame(TileRefs, sandbox, i, j, true);
                                    NetMessage.SendTileSquare(-1, x, y, 3);
                                }
                            }
                        }
                    }
                }
            }

            NetMessage.SendWater(x, y);

            Liquid.numLiquid--;
            TileRefs(Main.liquid[id].x, Main.liquid[id].y).SetCheckingLiquid(false);
            Main.liquid[id].x    = Main.liquid[Liquid.numLiquid].x;
            Main.liquid[id].y    = Main.liquid[Liquid.numLiquid].y;
            Main.liquid[id].kill = Main.liquid[Liquid.numLiquid].kill;

            if (Main.tileAlch[(int)TileRefs(x, y).Type])
            {
                WorldModify.CheckAlch(TileRefs, sandbox, x, y);
            }
        }
Пример #19
0
        public static void Update(Stopwatch s)
        {
            int count = 0;

            int timeUpdateErrors     = 0;
            int worldUpdateErrors    = 0;
            int invasionUpdateErrors = 0;
            int serverUpdateErrors   = 0;

            var start = s.Elapsed;

            foreach (Player player in Main.players)
            {
                try
                {
                    player.UpdatePlayer(count);
                }
                catch (Exception e)
                {
                    if (!Main.ignoreErrors)
                    {
                        throw;
                    }

                    ProgramLog.Log(e, String.Format("Player update error, slot={0}, address={1}, name={2}",
                                                    player.whoAmi, player.IPAddress, player.Name != null ? string.Concat('"', player.Name, '"') : "<null>"));

                    player.Kick("Server malfunction, please reconnect.");
                }
                count++;
            }
            LastPlayerUpdateTime = s.Elapsed - start;

            lock (updatingNPCs)
            {
                start = s.Elapsed;

                NPC.SpawnNPC();

                foreach (Player player in Main.players)
                {
                    player.activeNPCs = 0;
                    player.townNPCs   = 0;
                }

                if (Main.WallOfFlesh >= 0 && !Main.npcs[Main.WallOfFlesh].Active)
                {
                    Main.WallOfFlesh = -1;
                }

                for (int i = 0; i < NPC.MAX_NPCS; i++)
                {
//					if (Main.npcs[i] == null)
//					{
//						ProgramLog.Debug.Log ("NPC[{0}] is null", i);
//						continue;
//					}

                    try
                    {
                        NPC.UpdateNPC(i);
                    }
                    catch (Exception e)
                    {
                        if (!Main.ignoreErrors)
                        {
                            throw;
                        }

                        var npc = Main.npcs[i];
                        ProgramLog.Log(e, String.Format("NPC update error, id={0}, type={1}, name={2}",
                                                        i, npc.Type, npc.Name));

                        Main.npcs[i]           = Registries.NPC.Default;
                        Main.npcs[i].netUpdate = true;
                    }
                }

                LastNPCUpdateTime = s.Elapsed - start;
            }

            lock (updatingProjectiles)
            {
                start = s.Elapsed;

                for (int i = 0; i < 1000; i++)
                {
//					if (Main.projectile[i] == null)
//					{
//						ProgramLog.Debug.Log ("Projectile[{0}] is null", i);
//						continue;
//					}

                    try
                    {
                        Main.projectile[i].Update(i);
                    }
                    catch (Exception e)
                    {
                        if (!Main.ignoreErrors)
                        {
                            throw;
                        }

                        var proj = Main.projectile[i];
                        ProgramLog.Log(e, String.Format("Projectile update error, i={0}, id={1}, owner={2}, type={3}",
                                                        i, proj.identity, proj.Owner, proj.Type));
                        //Main.projectile[i] = new Projectile();
                        Projectile.Reset(i);
                    }
                }

                LastProjectileUpdateTime = s.Elapsed - start;
            }

            lock (updatingItems)
            {
                start = s.Elapsed;

                for (int i = 0; i < 200; i++)
                {
//					if (Main.item[i] == null)
//					{
//						ProgramLog.Debug.Log ("Item[{0}] is null", i);
//						continue;
//					}

                    try
                    {
                        Main.item[i].UpdateItem(i);
                    }
                    catch (Exception e)
                    {
                        if (!Main.ignoreErrors)
                        {
                            throw;
                        }

                        var item = Main.item[i];
                        ProgramLog.Log(e, String.Format("Projectile update error, i={0}, type={1}, owner={2}, stack={3}",
                                                        i, item.Type, item.Owner, item.Stack));
                        Main.item[i] = new Item();
                    }
                }

                LastItemUpdateTime = s.Elapsed - start;
            }

            start = s.Elapsed;
            try
            {
                Main.UpdateTime();
                timeUpdateErrors = 0;
            }
            catch (Exception e)
            {
                if (++timeUpdateErrors >= 5 || !Main.ignoreErrors)
                {
                    throw;
                }

                ProgramLog.Log(e, "Time update error");
                Main.checkForSpawns = 0;
            }
            LastTimeUpdateTime = s.Elapsed - start;

            start = s.Elapsed;
            try
            {
                WorldModify.UpdateWorld(World.Sender);
                worldUpdateErrors = 0;
            }
            catch (Exception e)
            {
                if (++worldUpdateErrors >= 5 || !Main.ignoreErrors)
                {
                    throw;
                }

                ProgramLog.Log(e, "World update error");
            }
            LastWorldUpdateTime = s.Elapsed - start;

            start = s.Elapsed;
            try
            {
                Main.UpdateInvasion();
                invasionUpdateErrors = 0;
            }
            catch (Exception e)
            {
                if (++invasionUpdateErrors >= 5 || !Main.ignoreErrors)
                {
                    throw;
                }

                ProgramLog.Log(e, "Invasion update error");
            }
            LastInvasionUpdateTime = s.Elapsed - start;

            start = s.Elapsed;
            try
            {
                Main.UpdateServer();
                serverUpdateErrors = 0;
            }
            catch (Exception e)
            {
                if (++serverUpdateErrors >= 5 || !Main.ignoreErrors)
                {
                    throw;
                }

                ProgramLog.Log(e, "Server update error");
            }
            LastServerUpdateTime = s.Elapsed - start;
        }
        public static void DelWater(int liquidIndex)
        {
            int x = Main.liquid[liquidIndex].x;
            int y = Main.liquid[liquidIndex].y;

            if (Main.tile.At(x, y).Liquid < 2)
            {
                Main.tile.At(x, y).SetLiquid(0);
            }
            else if (Main.tile.At(x, y).Liquid < 20)
            {
                if ((Main.tile.At(x - 1, y).Liquid < Main.tile.At(x, y).Liquid&& (!Main.tile.At(x - 1, y).Active || !Main.tileSolid[(int)Main.tile.At(x - 1, y).Type] || Main.tileSolidTop[(int)Main.tile.At(x - 1, y).Type])) || (Main.tile.At(x + 1, y).Liquid < Main.tile.At(x, y).Liquid&& (!Main.tile.At(x + 1, y).Active || !Main.tileSolid[(int)Main.tile.At(x + 1, y).Type] || Main.tileSolidTop[(int)Main.tile.At(x + 1, y).Type])) || (Main.tile.At(x, y + 1).Liquid < 255 && (!Main.tile.At(x, y + 1).Active || !Main.tileSolid[(int)Main.tile.At(x, y + 1).Type] || Main.tileSolidTop[(int)Main.tile.At(x, y + 1).Type])))
                {
                    Main.tile.At(x, y).SetLiquid(0);
                }
            }
            else if (Main.tile.At(x, y + 1).Liquid < 255 && (!Main.tile.At(x, y + 1).Active || !Main.tileSolid[(int)Main.tile.At(x, y + 1).Type] || Main.tileSolidTop[(int)Main.tile.At(x, y + 1).Type]) && !Liquid.stuck)
            {
                Main.liquid[liquidIndex].kill = 0;
                return;
            }
            if (Main.tile.At(x, y).Liquid < 250 && Main.tile.At(x, y - 1).Liquid > 0)
            {
                Liquid.AddWater(x, y - 1);
            }
            if (Main.tile.At(x, y).Liquid == 0)
            {
                Main.tile.At(x, y).SetLava(false);
            }
            else
            {
                if (Main.tile.At(x + 1, y).Liquid > 0 && Main.tile.At(x + 1, y + 1).Liquid < 250 && !Main.tile.At(x + 1, y + 1).Active)
                {
                    Liquid.AddWater(x + 1, y);
                }
                if (Main.tile.At(x - 1, y).Liquid > 0 && Main.tile.At(x - 1, y + 1).Liquid < 250 && !Main.tile.At(x - 1, y + 1).Active)
                {
                    Liquid.AddWater(x - 1, y);
                }
                if (Main.tile.At(x, y).Lava)
                {
                    Liquid.LavaCheck(x, y);
                    for (int i = x - 1; i <= x + 1; i++)
                    {
                        for (int j = y - 1; j <= y + 1; j++)
                        {
                            if (Main.tile.At(i, j).Active)
                            {
                                if (Main.tile.At(i, j).Type == 2 || Main.tile.At(i, j).Type == 23)
                                {
                                    Main.tile.At(i, j).SetType(0);
                                    WorldModify.SquareTileFrame(i, j, true);

                                    NetMessage.SendTileSquare(-1, x, y, 3);
                                }
                                else if (Main.tile.At(i, j).Type == 60 || Main.tile.At(i, j).Type == 70)
                                {
                                    Main.tile.At(i, j).SetType(59);
                                    WorldModify.SquareTileFrame(i, j, true);

                                    NetMessage.SendTileSquare(-1, x, y, 3);
                                }
                            }
                        }
                    }
                }
            }


            NetMessage.SendWater(x, y);

            Liquid.numLiquid--;
            Main.tile.At(Main.liquid[liquidIndex].x, Main.liquid[liquidIndex].y).SetCheckingLiquid(false);
            Main.liquid[liquidIndex].x    = Main.liquid[Liquid.numLiquid].x;
            Main.liquid[liquidIndex].y    = Main.liquid[Liquid.numLiquid].y;
            Main.liquid[liquidIndex].kill = Main.liquid[Liquid.numLiquid].kill;
            if (Main.tileAlch[(int)Main.tile.At(x, y).Type])
            {
                WorldModify.CheckAlch(x, y);
            }
        }
        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);
        }
Пример #22
0
        public static void LoadWorld(string LoadPath)
        {
            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();
                            }
                            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  = 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);
                                            }
                                        }
                                        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 < 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);
                                            Main.chest[m].contents[m].Stack = (int)stack;
                                            if (Terraria_Release >= 36)
                                            {
                                                Main.chest[m].contents[m].SetPrefix((int)binaryReader.ReadByte());
                                            }
                                        }
                                    }
                                }
                            }
                            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 >= 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 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;
                                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(num9);
                                }
                                WorldModify.waterLine = Main.maxTilesY;
                                NPC.SetNames();
                                Liquid.QuickWater(2, -1, -1);
                                WorldModify.WaterCheck();
                                int num11 = 0;
                                Liquid.quickSettle = true;
                                int   num12 = Liquid.numLiquid + LiquidBuffer.numLiquidBuffer;
                                float num13 = 0f;

                                using (var prog = new ProgressLogger(100, "Settling liquids"))
                                    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 = (int)(num14 * 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
                        {
                        }
                        return;
                    }
                }
            }

            if (Main.worldName == null || 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);
        }
//        static long sameTiles = 0;
//        static long diffTiles = 0;

        public override void Process(int whoAmI, byte[] readBuffer, int length, int num)
        {
            short size = BitConverter.ToInt16(readBuffer, num);
            int   left = BitConverter.ToInt32(readBuffer, num + 2);
            int   top  = BitConverter.ToInt32(readBuffer, num + 6);

            num += 10;
            var slot = NetPlay.slots[whoAmI];

            var start = num;

            var setting = Program.properties.TileSquareMessages;

            if (setting == "rectify")
            {
                if (size > 7)
                {
                    Logging.ProgramLog.Debug.Log("{0}: Ignoring tile square of size {1}", whoAmI, size);
                    return;
                }

                //Logging.ProgramLog.Debug.Log ("{0}: TILE_SQUARE at {1}, {2}", whoAmI, left, top);

                bool different = false;
                for (int x = left; x < left + (int)size; x++)
                {
                    for (int y = top; y < top + (int)size; y++)
                    {
                        TileData tile = Main.tile.At(x, y).Data;

                        byte b9 = readBuffer[num++];

                        bool wasActive = tile.Active;

                        tile.Active = ((b9 & 1) == 1);
                        different  |= tile.Active != wasActive;

                        if ((b9 & 2) == 2)
                        {
                            different   |= tile.Lighted == false;
                            tile.Lighted = true;
                        }

                        if (tile.Active)
                        {
                            int wasType = (int)tile.Type;
                            tile.Type = readBuffer[num++];

                            different |= tile.Type != wasType;

                            short framex = tile.FrameX;
                            short framey = tile.FrameY;

                            if (tile.Type >= Main.MAX_TILE_SETS)
                            {
                                slot.Kick("Invalid tile received from client.");
                                return;
                            }

                            if (Main.tileFrameImportant[(int)tile.Type])
                            {
                                framex = BitConverter.ToInt16(readBuffer, num);
                                num   += 2;
                                framey = BitConverter.ToInt16(readBuffer, num);
                                num   += 2;
                            }
                            else if (!wasActive || (int)tile.Type != wasType)
                            {
                                framex = -1;
                                framey = -1;
                            }

                            different |= (framex != tile.FrameX) || (framey != tile.FrameY);
                        }

                        if ((b9 & 4) == 4)
                        {
                            different |= tile.Wall == 0;
                            different |= tile.Wall != readBuffer[num++];
                        }

                        if ((b9 & 8) == 8)
                        {
                            // TODO: emit a liquid event
                            different |= tile.Liquid != readBuffer[num++];
                            different |= (tile.Lava ? 1 : 0) != readBuffer[num++];
                        }

                        tile.Wire = (b9 & 16) == 16;

                        if (different)
                        {
                            break;
                        }
                    }
                }

                //Logging.ProgramLog.Debug.Log ("TileSquare({0}): {1}", size, different);
//				if (different)
//				{
//					System.Threading.Interlocked.Add (ref diffTiles, size);
//					if (size != 3)
//						Logging.ProgramLog.Debug.Log ("{0}: TileSquare({1}): {2:0.0} ({3})", whoAmI, size, diffTiles * 100.0 / (sameTiles + diffTiles), diffTiles);
//				}
//				else
//				{
//					System.Threading.Interlocked.Add (ref sameTiles, size);
//					//Logging.ProgramLog.Debug.Log ("{0}: same TileSquare({1}): {2:0.0} ({3})", whoAmI, size, diffTiles * 100.0 / (sameTiles + diffTiles), diffTiles);
//				}

                if (different)
                {
                    NetMessage.SendTileSquare(whoAmI, left, top, size, false);
                }
                return;
            }
            else if (setting == "ignore")
            {
                //if (size == 1) Logging.ProgramLog.Debug.Log ("{0}: TileSquare({1}) from {2}", whoAmI, size, Main.players[whoAmI].Name);
                return;
            }

            var player = Main.players[whoAmI];

            var ctx = new HookContext
            {
                Sender     = player,
                Player     = player,
                Connection = player.Connection
            };

            var args = new HookArgs.TileSquareReceived
            {
                X          = left, Y = top, Size = size,
                readBuffer = readBuffer,
                start      = start,
            };

            HookPoints.TileSquareReceived.Invoke(ref ctx, ref args);

            if (args.applied > 0)
            {
                WorldModify.RangeFrame(null, null, left, top, left + (int)size, top + (int)size);
                NetMessage.SendData(Packet.TILE_SQUARE, -1, whoAmI, "", (int)size, (float)left, (float)top);
            }

            if (ctx.CheckForKick() || ctx.Result == HookResult.IGNORE)
            {
                return;
            }

            args.ForEach(player, this.EachTile);
        }
        private static void UpdateTime()
        {
            Time += 1.0;

            if (!dayTime)
            {
                if (WorldModify.spawnEye && Time > 4860.0)
                {
                    foreach (Player player in players)
                    {
                        if (player.Active && !player.dead && (double)player.Position.Y < worldSurface * 16.0)
                        {
                            NPC.SpawnOnPlayer(player.whoAmi, 4);
                            WorldModify.spawnEye = false;
                            break;
                        }
                    }
                }

                if (Time > 32400.0)
                {
                    checkXmas();

                    if (invasionDelay > 0)
                    {
                        invasionDelay--;
                    }

                    WorldModify.spawnNPC = 0;
                    checkForSpawns       = 0;
                    Time      = 0.0;
                    bloodMoon = false;
                    dayTime   = true;
                    moonPhase++;
                    if (moonPhase >= 8)
                    {
                        moonPhase = 0;
                    }

                    NetMessage.SendData(7);
                    WorldIO.SaveWorldThreaded();

                    if (WorldModify.shadowOrbSmashed)
                    {
                        var startInvasion = !NPC.downedGoblins ? rand.Next(3) == 0 : rand.Next(15) == 0;
                        if (startInvasion)
                        {
                            StartInvasion();
                        }
                    }
                }
                if (Time > 16200.0 && WorldModify.spawnMeteor)
                {
                    WorldModify.spawnMeteor = false;
                    WorldModify.dropMeteor(null, null);
                    return;
                }
            }
            else
            {
                bloodMoon = false;
                if (Time > 54000.0)
                {
                    WorldModify.spawnNPC = 0;
                    checkForSpawns       = 0;
                    if (rand.Next(50) == 0 && WorldModify.shadowOrbSmashed)
                    {
                        WorldModify.spawnMeteor = true;
                    }

                    if (!NPC.downedBoss1)
                    {
                        bool flag = false;
                        foreach (Player player in players)
                        {
                            if (player.Active && player.statLifeMax >= 200 && player.statDefense > 10)
                            {
                                flag = true;
                                break;
                            }
                        }
                        if (flag && rand.Next(3) == 0)
                        {
                            int num = 0;
                            for (int i = 0; i < NPC.MAX_NPCS; i++)
                            {
                                if (npcs[i].Active && npcs[i].townNPC)
                                {
                                    num++;
                                }
                            }

                            if (num >= 4)
                            {
                                WorldModify.spawnEye = true;

                                NetMessage.SendData(25, -1, -1, "You feel an evil presence watching you...", 255, 50f, 255f, 130f);
                            }
                        }
                    }
                    if (!WorldModify.spawnEye && moonPhase != 4 && rand.Next(9) == 0)
                    {
                        for (int i = 0; i < 255; i++)
                        {
                            if (players[i].Active && players[i].statLifeMax > 100)
                            {
                                bloodMoon = true;
                                break;
                            }
                        }

                        if (bloodMoon)
                        {
                            NetMessage.SendData(25, -1, -1, "The Blood Moon is rising...", 255, 50f, 255f, 130f);
                        }
                    }
                    Time    = 0.0;
                    dayTime = false;

                    NetMessage.SendData(7);
                }

                //checkForSpawns++;
                if (++checkForSpawns >= 7200)
                {
                    int num2 = 0;
                    for (int i = 0; i < 255; i++)
                    {
                        if (players[i].Active)
                        {
                            num2++;
                        }
                    }

                    checkForSpawns       = 0;
                    WorldModify.spawnNPC = 0;
                    int num3  = 0;
                    int num4  = 0;
                    int num5  = 0;
                    int num6  = 0;
                    int num7  = 0;
                    int num8  = 0;
                    int num9  = 0;
                    int num10 = 0;
                    int num11 = 0;

                    int goblin = 0, wizard = 0, mechanic = 0, santa = 0;

                    for (int i = 0; i < NPC.MAX_NPCS; i++)
                    {
                        if (npcs[i].Active && npcs[i].townNPC)
                        {
                            if (npcs[i].type != NPCType.N37_OLD_MAN && !npcs[i].homeless)
                            {
                                WorldModify.QuickFindHome(null, i);
                            }

                            switch (npcs[i].type)
                            {
                            case NPCType.N37_OLD_MAN:
                                num8++;
                                break;

                            case NPCType.N17_MERCHANT:
                                num3++;
                                break;

                            case NPCType.N18_NURSE:
                                num4++;
                                break;

                            case NPCType.N19_ARMS_DEALER:
                                num6++;
                                break;

                            case NPCType.N20_DRYAD:
                                num5++;
                                break;

                            case NPCType.N22_GUIDE:
                                num7++;
                                break;

                            case NPCType.N38_DEMOLITIONIST:
                                num9++;
                                break;

                            case NPCType.N54_CLOTHIER:
                                num10++;
                                break;

                            case NPCType.N107_GOBLIN_TINKERER:
                                goblin++;
                                break;

                            case NPCType.N108_WIZARD:
                                wizard++;
                                break;

                            case NPCType.N124_MECHANIC:
                                mechanic++;
                                break;

                            case NPCType.N142_SANTA_CLAUS:
                                santa++;
                                break;
                            }
                            num11++;
                        }
                    }
                    if (WorldModify.spawnNPC == 0)
                    {
                        int  num12 = 0;
                        bool flag2 = false;
                        int  num13 = 0;
                        bool flag3 = false;
                        bool flag4 = false;
                        for (int i = 0; i < 255; i++)
                        {
                            if (players[i].Active)
                            {
                                for (int j = 0; j < 44; j++)
                                {
                                    if (players[i].inventory[j] != null & players[i].inventory[j].Stack > 0)
                                    {
                                        if (players[i].inventory[j].Type == 71)
                                        {
                                            num12 += players[i].inventory[j].Stack;
                                        }
                                        if (players[i].inventory[j].Type == 72)
                                        {
                                            num12 += players[i].inventory[j].Stack * 100;
                                        }
                                        if (players[i].inventory[j].Type == 73)
                                        {
                                            num12 += players[i].inventory[j].Stack * 10000;
                                        }
                                        if (players[i].inventory[j].Type == 74)
                                        {
                                            num12 += players[i].inventory[j].Stack * 1000000;
                                        }
                                        if (players[i].inventory[j].Ammo == ProjectileType.N14_BULLET || players[i].inventory[j].UseAmmo == ProjectileType.N14_BULLET)
                                        {
                                            flag3 = true;
                                        }
                                        if (players[i].inventory[j].Type == 166 || players[i].inventory[j].Type == 167 || players[i].inventory[j].Type == 168 || players[i].inventory[j].Type == 235)
                                        {
                                            flag4 = true;
                                        }
                                    }
                                }
                                int num14 = players[i].statLifeMax / 20;
                                if (num14 > 5)
                                {
                                    flag2 = true;
                                }
                                num13 += num14;
                            }
                        }

                        if (!NPC.downedBoss3 && num8 == 0)
                        {
                            int num15 = NPC.NewNPC(dungeonX * 16 + 8, dungeonY * 16, 37, 0);
                            npcs[num15].homeless  = false;
                            npcs[num15].homeTileX = dungeonX;
                            npcs[num15].homeTileY = dungeonY;
                        }

                        if (WorldModify.spawnNPC == 0 && num7 < 1)
                        {
                            WorldModify.spawnNPC = 22;
                        }
                        if (WorldModify.spawnNPC == 0 && (double)num12 > 5000.0 && num3 < 1)
                        {
                            WorldModify.spawnNPC = 17;
                        }
                        if (WorldModify.spawnNPC == 0 && flag2 && num4 < 1)
                        {
                            WorldModify.spawnNPC = 18;
                        }
                        if (WorldModify.spawnNPC == 0 && flag3 && num6 < 1)
                        {
                            WorldModify.spawnNPC = 19;
                        }
                        if (WorldModify.spawnNPC == 0 && (NPC.downedBoss1 || NPC.downedBoss2 || NPC.downedBoss3) && num5 < 1)
                        {
                            WorldModify.spawnNPC = 20;
                        }
                        if (WorldModify.spawnNPC == 0 && flag4 && num3 > 0 && num9 < 1)
                        {
                            WorldModify.spawnNPC = 38;
                        }
                        if (WorldModify.spawnNPC == 0 && NPC.downedBoss3 && num10 < 1)
                        {
                            WorldModify.spawnNPC = 54;
                        }
                        if (WorldModify.spawnNPC == 0 && NPC.savedGoblin && goblin < 1)
                        {
                            WorldModify.spawnNPC = 107;
                        }
                        if (WorldModify.spawnNPC == 0 && NPC.savedWizard && wizard < 1)
                        {
                            WorldModify.spawnNPC = 108;
                        }
                        if (WorldModify.spawnNPC == 0 && NPC.savedMech && mechanic < 1)
                        {
                            WorldModify.spawnNPC = 124;
                        }
                        if (WorldModify.spawnNPC == 0 && NPC.downedFrost && santa < 1 && Xmas)
                        {
                            WorldModify.spawnNPC = 142;
                        }
                    }
                }
            }
        }
        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);
        }