Exemple #1
0
        /// <summary>
        /// Finds instances of the long form alias on the command line
        /// and replaces it with a standard property specification.
        /// </summary>
        /// <param name="context">The context that has access to the command line args and the target property.</param>
        public override void BeforeParse(HookContext context)
        {
            this.target = context.Property;

            List<string> newCommandLine = new List<string>();
            foreach (var arg in context.CmdLineArgs)
            {
                if (arg.StartsWith("--"))
                {
                    var argumentName = arg.Substring(2);
                    if (argumentName.Contains("="))
                    {
                        if (argumentName.IndexOf('=') != argumentName.LastIndexOf('='))
                        {
                            throw new ArgumentException("The '=' character can only appear once in a long form argument");
                        }

                        var explicitValue = argumentName.Split('=')[1];
                        argumentName = argumentName.Split('=')[0];

                        TryReplaceArg(context, newCommandLine, arg, argumentName, explicitValue);
                    }
                    else
                    {
                        TryReplaceArg(context, newCommandLine, arg, argumentName, null);
                    }
                }
                else
                {
                    newCommandLine.Add(arg);
                }
            }

            context.CmdLineArgs = newCommandLine.ToArray();
        }
Exemple #2
0
 /// <summary>
 /// This gets called after the target property is populated.  It cancels processing.
 /// </summary>
 /// <param name="context">Context passed by the parser</param>
 public override void AfterPopulateProperty(HookContext context)
 {
     base.AfterPopulateProperty(context);
     if (context.CurrentArgument.RevivedValue is bool &&
         ((bool)context.CurrentArgument.RevivedValue) == true)
     {
         context.CancelAllProcessing();
     }
 }
Exemple #3
0
        /// <summary>
        /// After PowerArgs does most of its work this hook looks for string properties on the parsed object called Skip, Take, 
        /// Where, OrderBy, and OrderByDescending.  These properties are used to construct a linq query that is dynamically compiled
        /// and executed against the provided data source.
        /// </summary>
        /// <param name="context">The context used to detect the query parameters.</param>
        public override void AfterPopulateProperties(HookContext context)
        {
            var dataSource = Activator.CreateInstance(DataSourceType);
            //TODO P0 - I should not need to read from an obsolete property
            var dataSourceCollectionProperty = DataSourceType.GetProperty(context.Property.Name);
            IEnumerable dataSourceCollection = (IEnumerable)dataSourceCollectionProperty.GetValue(dataSource, null);

            QueryArgs queryArgs = new QueryArgs()
            {
                ReturnType = dataSourceCollectionProperty.PropertyType.GetGenericArguments()[0].FullName,
            };

            var argObject = context.Args;
            var argType = context.Property.DeclaringType;

            if (argType.GetProperty("Skip") != null)
            {
                queryArgs.Skip = (int)argType.GetProperty("Skip").GetValue(argObject, null);
            }

            if (argType.GetProperty("Take") != null)
            {
                var take = (int)argType.GetProperty("Take").GetValue(argObject, null);
                if (take > 0) queryArgs.Take = take;
            }

            if (argType.GetProperty("Where") != null)
            {
                queryArgs.Where = argType.GetProperty("Where").GetValue(argObject, null) as string;
            }

            if (argType.GetProperty("OrderBy") != null)
            {
                var orderProp = argType.GetProperty("OrderBy").GetValue(argObject, null) as string;
                if (string.IsNullOrWhiteSpace(orderProp) == false)
                {
                    queryArgs.OrderBy = "item => " + orderProp;
                }
            }

            if (argType.GetProperty("OrderByDescending") != null)
            {
                var orderProp = argType.GetProperty("OrderByDescending").GetValue(argObject, null) as string;
                if (string.IsNullOrWhiteSpace(orderProp) == false)
                {
                    queryArgs.OrderByDescending = "item => " + orderProp;
                }
            }

            if (referencedAssemblies != null)
            {
                queryArgs.ReferencedAssemblies.AddRange(referencedAssemblies);
            }
            var results = queryArgs.RunQuery(dataSourceCollection);
            context.Property.SetValue(context.Args, results, null);
        }
Exemple #4
0
    /// <summary>
    /// If the given property has a non null value then that value is persisted for the next use.
    /// </summary>
    /// <param name="Context">Used to see if the property was specified.</param>
    public override void AfterPopulateProperty(HookContext Context)
    {
        if (Context.ArgumentValue != null)
            {
                if (userSpecifiedPersistenceProvider == null && Context.Definition.Metadata.HasMeta<StickyArgPersistence>())
                {
                    userSpecifiedPersistenceProvider = Context.Definition.Metadata.Meta<StickyArgPersistence>().PersistenceProvider;
                }

                SetStickyArg(Context.CurrentArgument.DefaultAlias, Context.ArgumentValue);
            }
    }
 public virtual void BeforePopulateProperty(HookContext context)
 {
 }
 public virtual void AfterPopulateProperty(HookContext context)
 {
 }
 public override void AfterInvoke(HookContext context)
 {
     hook(context);
 }
Exemple #8
0
 /// <summary>
 /// Calls the underlying hook if it was specified in the constructor
 /// </summary>
 /// <param name="context">The processing context</param>
 public override void BeforePopulateProperty(HookContext context)
 {
     DoHook("BeforePopulateProperty", context);
 }
 /// <summary>
 /// This hook is called before the parser ever looks at the command line.  You can do some preprocessing of the
 /// raw string arguments here.
 /// </summary>
 /// <param name="context">An object that has useful context.  See the documentation of each property for information about when those properties are populated.</param>
 public virtual void BeforeParse(HookContext context)
 {
 }
        public override void Process(int whoAmI, byte[] readBuffer, int length, int num)
        {
            //TODO [ProjectileReceived]

            var identity  = (int)ReadInt16(readBuffer);
            var position  = ReadVector2(readBuffer);
            var velocity  = ReadVector2(readBuffer);
            var knockBack = ReadSingle(readBuffer);
            var damage    = (int)ReadInt16(readBuffer);

            /*var targetOwner =*/
            ReadByte(readBuffer);
            var type  = (int)ReadInt16(readBuffer);
            var flags = (BitsByte)ReadByte(readBuffer);
            var ai    = new float[Projectile.maxAI];

            for (var i = 0; i < Projectile.maxAI; i++)
            {
                if (flags[i])
                {
                    ai[i] = ReadSingle(readBuffer);
                }
                else
                {
                    ai[i] = 0f;
                }
            }

            if (Main.projHostile[type])
            {
                return;
            }

            var index = 1000;

            //Attempt to find the existing projectile.
            for (var i = 0; i < 1000; i++)
            {
                if (Main.projectile[i].owner == whoAmI && Main.projectile[i].identity == identity && Main.projectile[i].active)
                {
                    index = i;
                    break;
                }
            }

            if (index == 1000)
            {
                //Find the next slot since there was no existing projectile.
                for (var i = 0; i < 1000; i++)
                {
                    if (!Main.projectile[i].active)
                    {
                        index = i;
                        break;
                    }
                }
            }

            var player = Main.player[whoAmI];
            var ctx    = new HookContext
            {
                Connection = player.Connection,
                Player     = player,
                Sender     = player,
            };

            var args = new HookArgs.ProjectileReceived
            {
                Position      = position,
                Velocity      = velocity,
                Id            = identity,
                Owner         = whoAmI,
                Knockback     = knockBack,
                Damage        = damage,
                Type          = type,
                AI            = ai,
                ExistingIndex = index < 1000 ? index : -1
            };

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

            if (ctx.Result == HookResult.DEFAULT)
            {
                if (index > -1 && index < 1000)
                {
                    var projectile = Main.projectile[index];
                    if (!projectile.active || projectile.type != type)
                    {
                        projectile.SetDefaults(type);
                        Terraria.Netplay.Clients[whoAmI].SpamProjectile += 1f;
                    }

                    projectile.identity  = identity;
                    projectile.position  = position;
                    projectile.velocity  = velocity;
                    projectile.type      = type;
                    projectile.damage    = damage;
                    projectile.knockBack = knockBack;
                    projectile.owner     = whoAmI;

                    for (var i = 0; i < Projectile.maxAI; i++)
                    {
                        projectile.ai[i] = ai[i];
                    }

                    NewNetMessage.SendData(Packet.PROJECTILE, -1, whoAmI, String.Empty, index);
                }
            }
        }
Exemple #11
0
 public override void AfterPopulateProperty(HookContext context)
 {
     ArgVal = context.CmdLineArgs.Where(a => a.ToLower() == "-v" || a.ToLower() == "-vv").Single();
 }
Exemple #12
0
//        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++];
                        }

                        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(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);
        }
        public static int SendData(int packetId, int remoteClient = -1, int ignoreClient = -1, string text = "", int number = 0, float number2 = 0f, float number3 = 0f, float number4 = 0f, int number5 = 0)
        {
            if (!NetPlay.anyClients)
            {
                return(0);
            }

            try
            {
                var msg = PrepareThreadInstance();

                switch (packetId)
                {
                case (int)Packet.CONNECTION_REQUEST:
                    msg.ConnectionRequest(Statics.CURRENT_TERRARIA_RELEASE_STR);
                    break;

                case (int)Packet.DISCONNECT:
                    msg.Disconnect(text);
                    break;

                case (int)Packet.CONNECTION_RESPONSE:
                    msg.ConnectionResponse(remoteClient);
                    break;

                case (int)Packet.PLAYER_DATA:
                    msg.PlayerData(number);
                    break;

                case (int)Packet.INVENTORY_DATA:
                    msg.InventoryData(number, (byte)number2, (int)number3);
                    break;

                case (int)Packet.WORLD_REQUEST:
                    msg.WorldRequest();
                    break;

                case (int)Packet.WORLD_DATA:
                    msg.WorldData();
                    break;

                case (int)Packet.REQUEST_TILE_BLOCK:
                    msg.RequestTileBlock();
                    break;

                case (int)Packet.SEND_TILE_LOADING:
                    msg.SendTileLoading(number, text);
                    break;

                case (int)Packet.SEND_TILE_ROW:
                    msg.SendTileRow(number, (int)number2, (int)number3);
                    break;

                case (int)Packet.SEND_TILE_CONFIRM:
                    msg.SendTileConfirm(number, (int)number2, (int)number3, (int)number4);
                    break;

                case (int)Packet.RECEIVING_PLAYER_JOINED:
                    msg.ReceivingPlayerJoined(number);
                    break;

                case (int)Packet.PLAYER_STATE_UPDATE:
                    msg.PlayerStateUpdate(number);
                    break;

                case (int)Packet.SYNCH_BEGIN:
                    msg.SynchBegin(number, (int)number2);
                    break;

                case (int)Packet.UPDATE_PLAYERS:
                    msg.UpdatePlayers();
                    break;

                case (int)Packet.PLAYER_HEALTH_UPDATE:
                    msg.PlayerHealthUpdate(number);
                    break;

                case (int)Packet.TILE_BREAK:
                    msg.TileBreak(number, (int)number2, (int)number3, (int)number4, (int)number5);
                    break;

                case (int)Packet.TIME_SUN_MOON_UPDATE:
                    msg.TimeSunMoonUpdate();
                    break;

                case (int)Packet.DOOR_UPDATE:
                    msg.DoorUpdate(number, (int)number2, (int)number3, (int)number4);
                    break;

                case (int)Packet.TILE_SQUARE:
                    msg.TileSquare(number, (int)number2, (int)number3);
                    break;

                case (int)Packet.ITEM_INFO:
                    msg.ItemInfo(number);
                    break;

                case (int)Packet.ITEM_OWNER_INFO:
                    msg.ItemOwnerInfo(number);
                    break;

                case (int)Packet.NPC_INFO:
                    msg.NPCInfo(number);
                    break;

                case (int)Packet.STRIKE_NPC:
                    msg.StrikeNPC(number, (int)number2);
                    break;

                case (int)Packet.PLAYER_CHAT:
                    msg.PlayerChat(number, text, (byte)number2, (byte)number3, (byte)number4);
                    break;

                case (int)Packet.STRIKE_PLAYER:
                    msg.StrikePlayer(number, text, (int)number2, (int)number3, (int)number4);
                    break;

                case (int)Packet.PROJECTILE:
                    msg.Projectile(Main.projectile[number]);
                    break;

                case (int)Packet.DAMAGE_NPC:
                    msg.DamageNPC(number, (int)number2, number3, (int)number4);
                    break;

                case (int)Packet.KILL_PROJECTILE:
                    msg.KillProjectile(number, (int)number2);
                    break;

                case (int)Packet.PLAYER_PVP_CHANGE:
                    msg.PlayerPVPChange(number);
                    break;

                case (int)Packet.OPEN_CHEST:
                    msg.OpenChest();
                    break;

                case (int)Packet.CHEST_ITEM:
                    msg.ChestItem(number, (int)number2);
                    break;

                case (int)Packet.PLAYER_CHEST_UPDATE:
                    msg.PlayerChestUpdate(number);
                    break;

                case (int)Packet.KILL_TILE:
                    msg.KillTile();
                    break;

                case (int)Packet.HEAL_PLAYER:
                    msg.HealPlayer(number, (int)number2);
                    break;

                case (int)Packet.ENTER_ZONE:
                    msg.EnterZone(number);
                    break;

                case (int)Packet.PASSWORD_REQUEST:
                    msg.PasswordRequest();
                    break;

                case (int)Packet.PASSWORD_RESPONSE:
                    msg.PasswordResponse();
                    break;

                case (int)Packet.ITEM_OWNER_UPDATE:
                    msg.ItemOwnerUpdate(number);
                    break;

                case (int)Packet.NPC_TALK:
                    msg.NPCTalk(number);
                    break;

                case (int)Packet.PLAYER_BALLSWING:
                    msg.PlayerBallswing(number);
                    break;

                case (int)Packet.PLAYER_MANA_UPDATE:
                    msg.PlayerManaUpdate(number);
                    break;

                case (int)Packet.PLAYER_USE_MANA_UPDATE:
                    msg.PlayerUseManaUpdate(number, (int)number2);
                    break;

                case (int)Packet.KILL_PLAYER_PVP:
                    msg.KillPlayerPVP(number, text, (int)number2, (int)number3, (int)number4);
                    break;

                case (int)Packet.PLAYER_JOIN_PARTY:
                    msg.PlayerJoinParty(number);
                    break;

                case (int)Packet.READ_SIGN:
                    msg.ReadSign(number, (int)number2);
                    break;

                case (int)Packet.WRITE_SIGN:
                    msg.WriteSign(number);
                    break;

                case (int)Packet.FLOW_LIQUID:
                    msg.FlowLiquid(number, (int)number2);
                    break;

                case (int)Packet.SEND_SPAWN:
                    msg.SendSpawn();
                    break;

                case (int)Packet.PLAYER_BUFFS:
                    msg.PlayerBuffs(number);
                    break;

                case (int)Packet.SUMMON_SKELETRON:
                    msg.SummonSkeletron((byte)number, (byte)number2);
                    break;

                case (int)Packet.CHEST_UNLOCK:
                    msg.ChestUnlock(number, (int)number2, (int)number3, (int)number4);
                    break;

                case (int)Packet.NPC_ADD_BUFF:
                    msg.NPCAddBuff(number, (int)number2, (int)number3);
                    break;

                case (int)Packet.NPC_BUFFS:
                    msg.NPCBuffs(number);
                    break;

                case (int)Packet.PLAYER_ADD_BUFF:
                    msg.PlayerAddBuff(number, (int)number2, (int)number3);
                    break;

                case (int)Packet.CLIENT_MOD:
                    msg.ClientMod(remoteClient);
                    break;

                case (int)Packet.CLIENT_MOD_SPAWN_NPC:
                    msg.RpgNPCSpawned(number);
                    break;

                case (int)Packet.NPC_NAME:
                    msg.NPCName(number, Main.chrName[number]);
                    break;

                case (int)Packet.WORLD_BALANCE:
                    msg.WorldBalance(WorldModify.tGood, WorldModify.tEvil);
                    break;

                case (int)Packet.SPAWN_NPCS:
                    msg.SpawnNPC(number, (int)number2);
                    break;

                case (int)Packet.NPC_HOME:
                    msg.NPCHome(number, (int)number2, (int)number3, number4 == 1);
                    break;

                default:
                {
                    //Unknown packet :3
                    var ctx = new HookContext()
                    {
                    };

                    var args = new HookArgs.UnkownSendPacket()
                    {
                        Message      = msg,
                        PacketId     = packetId,
                        RemoteClient = remoteClient,
                        IgnoreClient = ignoreClient,
                        Text         = text,
                        Number       = number,
                        Number2      = number2,
                        Number3      = number3,
                        Number4      = number4,
                        Number5      = number5
                    };

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

                    /* Update Locals */
                    msg          = args.Message;
                    remoteClient = args.RemoteClient;
                    ignoreClient = args.IgnoreClient;

                    if (ctx.Result != HookResult.IGNORE)
                    {
                        return(0);
                    }
                    else
                    {
                        break;
                    }
                }
                }

                //var bytes = msg.Output;
                if (remoteClient == -1)
                {
                    msg.BroadcastExcept(ignoreClient);
                    //					for (int num11 = 0; num11 < 256; num11++)
                    //					{
                    //						if (num11 != ignoreClient && Netplay.slots[num11].state >= SlotState.PLAYING && Netplay.slots[num11].Connected)
                    //						{
                    //							NetMessage.buffer[num11].spamCount++;
                    //							Netplay.slots[num11].Send (bytes);
                    //						}
                    //					}
                }
                else if (NetPlay.slots[remoteClient].Connected)
                {
                    msg.Send(remoteClient);
                    //NetMessage.buffer[remoteClient].spamCount++;
                    //Netplay.slots[remoteClient].Send (bytes);
                }
                return(msg.Written);
            }
            catch (Exception e)
            {
                ProgramLog.Log(e, "SendData error");
            }
            return(0);
        }
        public static void OnPlayerJoined(int plr)
        {
            var player = Main.players[plr];

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

            var args = new HookArgs.PlayerEnteringGame
            {
                Slot = plr,
            };

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

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

            var msg = NetMessage.PrepareThreadInstance();

            var motd = Program.properties.Greeting.Split('@');

            for (int i = 0; i < motd.Length; i++)
            {
                if (motd[i] != null && motd[i].Trim().Length > 0)
                {
                    msg.PlayerChat(255, motd[i], 0, 0, 255);
                }
            }

            string list = "";

            for (int i = 0; i < 255; i++)
            {
                if (Main.players[i].Active)
                {
                    if (list == "")
                    {
                        list += Main.players[i].Name;
                    }
                    else
                    {
                        list = list + ", " + Main.players[i].Name;
                    }
                }
            }

            msg.PlayerChat(255, "Current players: " + list + ".", 255, 240, 20);
            msg.Send(plr);             // send these before the login event, so messages from plugins come after

            var slot = NetPlay.slots[plr];

            slot.announced = true;

            // to player
            msg.Clear();
            msg.SyncAllNPCHomes();
            msg.SendSyncOthersForPlayer(plr);

            ProgramLog.Users.Log("{0} @ {1}: ENTER {2}", slot.remoteAddress, plr, player.Name);

            if (player.HasHackedData())
            {
                player.Kick("No Hacked Health or Mana is allowed.");
                return;
            }

            // to other players
            msg.Clear();
            msg.PlayerChat(255, player.Name + " has joined.", 255, 240, 20);
            msg.ReceivingPlayerJoined(plr);
            msg.SendSyncPlayerForOthers(plr);             // broadcasts the preceding message too

            var args2 = new HookArgs.PlayerEnteredGame
            {
                Slot = plr,
            };

            ctx.SetResult(HookResult.DEFAULT, false);
            HookPoints.PlayerEnteredGame.Invoke(ref ctx, ref args2);

            if (ctx.CheckForKick())
            {
                return;
            }
        }
        internal void Apply(Player player = null)
        {
            foreach (var kv in changedTiles)
            {
                var k = kv.Key;
                var x = k >> 16;
                var y = k & 0xffff;
                var t = kv.Value;

                if (t >= 0)
                {
                    Main.tile.data[x, y] = tiles[t];
                }
            }

            foreach (var eff in sideEffects)
            {
                if (eff == null || eff.Cancel)
                {
                    continue;
                }

                switch (eff.EffectType)
                {
                case SideEffectType.ADD_WATER:
                {
                    Liquid.AddWater(eff.X, eff.Y);
                    break;
                }

                case SideEffectType.SMASH_SHADOW_ORB:
                {
                    WorldModify.shadowOrbSmashed = true;
                    WorldModify.shadowOrbCount++;

                    if (WorldModify.shadowOrbCount >= 3)
                    {
                        WorldModify.shadowOrbCount = 0;

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

                        var args = new HookArgs.PlayerTriggeredEvent
                        {
                            X    = (int)(player.Position.X / 16),
                            Y    = (int)(player.Position.Y / 16),
                            Type = WorldEventType.BOSS,
                            Name = "Eater of Worlds",
                        };

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

                        if (!ctx.CheckForKick() && ctx.Result != HookResult.IGNORE)
                        {
                            ProgramLog.Users.Log("{0} @ {1}: Eater of Worlds summoned by {2}.", player.IPAddress, player.whoAmi, player.Name);
                            NetMessage.SendData(Packet.PLAYER_CHAT, -1, -1, string.Concat(player.Name, " has summoned the Eater of Worlds!"), 255, 255, 128, 150);
                            NPC.SpawnOnPlayer(player, player.whoAmi, 13);
                        }
                    }
                    else
                    {
                        string text = "A horrible chill goes down your spine...";
                        if (WorldModify.shadowOrbCount == 2)
                        {
                            text = "Screams echo around you...";
                        }
                        NetMessage.SendData(25, -1, -1, text, 255, 50f, 255f, 130f, 0);
                    }
                    break;
                }

                case SideEffectType.NEW_ITEM:
                {
                    Item.NewItem(eff.X, eff.Y, eff.Width, eff.Height, eff.Type, eff.Stack, eff.NoBroadcast);
                    break;
                }

                case SideEffectType.KILL_SIGN:
                {
                    Sign.KillSign(eff.X, eff.Y);
                    break;
                }

                case SideEffectType.DESTROY_CHEST:
                {
                    Chest.DestroyChest(eff.X, eff.Y);
                    break;
                }

                case SideEffectType.FALLING_BLOCK_PROJECTILE:
                {
                    int p    = Projectile.NewProjectile((float)(eff.X * 16 + 8), (float)(eff.Y * 16 + 8), 0f, 0.41f, eff.Type, 10, 0f, 255);
                    var proj = Main.projectile[p];
                    proj.Creator     = player;
                    proj.Velocity.Y  = 0.5f;
                    proj.Position.Y += 2f;
                    proj.ai[0]       = 1f;
                    NetMessage.SendTileSquare(-1, eff.X, eff.Y, 1);
                    break;
                }
                }
            }
        }
 public override void AfterPopulateProperty(HookContext Context)
 {
     if (Context.ArgumentValue != null) SetStickyArg(Context.Property.GetArgumentName(), Context.ArgumentValue);
 }
        public override void Process(int whoAmI, byte[] readBuffer, int length, int num)
        {
            int playerIndex = readBuffer[num++];

            if (playerIndex != whoAmI)
            {
                NetPlay.slots[whoAmI].Kick("Cheating detected (INVENTORY_DATA forgery).");
                return;
            }

            var player = Main.players[whoAmI];

            var ctx = new HookContext
            {
                Connection = NetPlay.slots[whoAmI].conn,
                Sender     = player,
                Player     = player,
            };

            var args = new HookArgs.InventoryItemReceived
            {
                InventorySlot = readBuffer[num++],
                Amount        = readBuffer[num++],
                Prefix        = readBuffer[num++],
                NetID         = BitConverter.ToInt16(readBuffer, num),
                //Name = Networking.StringCache.FindOrMake (new ArraySegment<Byte> (readBuffer, num, length - 4)),
            };

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

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

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

            var itemName      = args.Name;
            var inventorySlot = args.InventorySlot;
            var stack         = args.Amount;

            if (args.NetID < 0)
            {
                return;                             // FIXME
            }
            var item = Item.netDefaults(args.NetID);

            item.SetPrefix(args.Prefix);
            item.Stack = stack;

            if (inventorySlot < Player.MAX_INVENTORY)
            {
                player.inventory[inventorySlot] = item;
            }
            else
            {
                player.armor[inventorySlot - Player.MAX_INVENTORY] = item;
            }

            if (ctx.Result != HookResult.CONTINUE)
            {
                if (Server.RejectedItemsContains(itemName) ||
                    Server.RejectedItemsContains(item.Type.ToString()))
                {
                    player.Kick(((itemName.Length > 0) ? itemName : item.Type.ToString()) + " is not allowed on this server.");
                }
            }

            NetMessage.SendData(5, -1, whoAmI, itemName, playerIndex, (float)inventorySlot, args.Prefix);
        }
 /// <summary>
 /// This hook is called before an argument is transformed from a string into a proper type and validated.
 /// </summary>
 /// <param name="context">An object that has useful context.  See the documentation of each property for information about when those properties are populated.</param>
 public virtual void BeforePopulateProperty(HookContext context)
 {
 }
Exemple #19
0
 /// <summary>
 /// Calls the underlying hook if it was specified in the constructor
 /// </summary>
 /// <param name="context">The processing context</param>
 public override void BeforePrepareUsage(HookContext context)
 {
     DoHook("BeforePrepareUsage", context);
 }
 /// <summary>
 /// This hook is called after the arguments defined in a class are populated.  For actions (or sub commands) this hook will
 /// get called once for the main class and once for the specified action.
 /// </summary>
 /// <param name="context">An object that has useful context.  See the documentation of each property for information about when those properties are populated.</param>
 public virtual void AfterPopulateProperties(HookContext context)
 {
 }
Exemple #21
0
        private void ValidatePipeline(HookContext context)
        {
            foreach(var action in context.Definition.Actions)
            {
                bool hasMapper = false;
                bool hasDirectTarget = false;
                foreach(var argument in action.Arguments)
                {
                    hasMapper = hasMapper ? true : argument.Metadata.HasMeta<ArgPipelineExtractor>();

                    if (hasDirectTarget && argument.Metadata.HasMeta<ArgPipelineTarget>())
                    {
                        throw new InvalidArgDefinitionException("Action '" + action.DefaultAlias + "' has more than one argument with ArgPipelineTarget metadata.  Only one argument can be designated as a direct pipeline target.");
                    }
                    else
                    {
                        hasDirectTarget = argument.Metadata.HasMeta<ArgPipelineTarget>();
                    }

                    if(hasMapper && hasDirectTarget)
                    {
                        throw new InvalidArgDefinitionException("Action '"+action.DefaultAlias+"' cannot have both ArgPipelineMapper and ArgPipelineTarget metadata.  You must choose one or the other.");
                    }

                    if(hasDirectTarget && argument.Metadata.Meta<ArgPipelineTarget>().PipelineOnly == false && ArgRevivers.CanRevive(argument.ArgumentType) == false)
                    {
                        throw new InvalidArgDefinitionException("There is no reviver for type " + argument.ArgumentType.Name);
                    }
                }
            }
        }
Exemple #22
0
        public override void Process(int whoAmI, byte[] readBuffer, int length, int num)
        {
            //TODO [KillProjectileReceived]

            int identity = (int)ReadInt16(readBuffer);
            int playerId = (int)ReadByte(readBuffer);

            if (playerId != whoAmI && Entry.EnableCheatProtection)
            {
                Terraria.Netplay.Clients[whoAmI].Kick("Cheating detected (KILL_PROJECTILE forgery).");
                return;
            }

            var index = Tools.FindExistingProjectileForUser(whoAmI, identity);

            if (index == -1)
            {
                return;
            }

            var player = Main.player[whoAmI];

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

            var args = new HookArgs.KillProjectileReceived
            {
                Id    = identity,
                Owner = whoAmI,
                Index = index,
            };

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

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

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

            if (ctx.Result == HookResult.RECTIFY)
            {
                var msg = NewNetMessage.PrepareThreadInstance();
                msg.Projectile(Main.projectile[index]);
                msg.Send(whoAmI);
                return;
            }

            var projectile = Main.projectile[index];

            if (projectile.owner == whoAmI && projectile.identity == identity)
            {
                projectile.Kill();
                NewNetMessage.SendData(29, -1, whoAmI, String.Empty, identity, (float)whoAmI);
            }
        }
        /// <summary>
        /// If the given property has a non null value then that value is persisted for the next use.
        /// </summary>
        /// <param name="Context">Used to see if the property was specified.</param>
        public override void AfterPopulateProperty(HookContext Context)
        {
            if (Context.ArgumentValue != null)
            {
                if (userSpecifiedPersistenceProvider == null && Context.Property.DeclaringType.HasAttr<StickyArgPersistence>())
                {
                    userSpecifiedPersistenceProvider = Context.Property.DeclaringType.Attr<StickyArgPersistence>().PersistenceProvider;
                }

                SetStickyArg(Context.Property.GetArgumentName(), Context.ArgumentValue);
            }
        }
Exemple #24
0
        public override void Process(int whoAmI, byte[] readBuffer, int length, int num)
        {
            short identity = BitConverter.ToInt16(readBuffer, num);

            num += 2;
            byte owner = readBuffer[num];

            owner = (byte)whoAmI;

            int index = Projectile.FindExisting(identity, owner);

            if (index == 1000)
            {
                return;
            }

            var player = Main.players[whoAmI];

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

            var args = new HookArgs.KillProjectileReceived
            {
                Id    = identity,
                Owner = owner,
                Index = (short)index,
            };

            HookPoints.KillProjectileReceived.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.Projectile(Main.projectile[index]);
                msg.Send(whoAmI);
                return;
            }

            var projectile = Main.projectile[index];

            if (projectile.Owner == owner && projectile.identity == identity)
            {
                projectile.Kill(null, null);
                projectile.Reset();
                NetMessage.SendData(29, -1, whoAmI, "", (int)identity, (float)owner);
            }
        }
Exemple #25
0
        private void TryReplaceArg(HookContext context, List<string> newCommandLine, string originalArg, string argumentName, string explicitValue)
        {
            bool ignoreCase = true;

            if (context.Property.HasAttr<ArgIgnoreCase>() &&
                context.Property.Attr<ArgIgnoreCase>().IgnoreCase == false)
            {
                ignoreCase = false;
            }

            if (ignoreCase && argumentName.ToLower() == this.value.ToLower())
            {
                newCommandLine.Add("-" + context.Property.GetArgumentName());
                if (explicitValue != null)
                {
                    newCommandLine.Add(explicitValue);
                }
            }
            else if (!ignoreCase && argumentName == this.value)
            {
                newCommandLine.Add("-" + context.Property.GetArgumentName());
                if (explicitValue != null)
                {
                    newCommandLine.Add(explicitValue);
                }
            }
            else
            {
                // No match - pass through
                newCommandLine.Add(originalArg);
            }
        }
Exemple #26
0
            public override void BeforeValidateDefinition(HookContext context)
            {
                context.Definition.IsNonInteractive = true;

                base.BeforeValidateDefinition(context);
            }
Exemple #27
0
 void OnWorldLoaded(ref HookContext ctx, ref HookArgs.WorldLoaded args)
 {
     /* For the template Warp, it uses  spawn axis, so they need to be loaded. */
     LoadData(KitFile, typeof(Kit).Name, KitManager.LoadData, KitManager.CreateTemplate);
     LoadData(WarpFile, typeof(Warp).Name, WarpManager.LoadData, WarpManager.CreateTemplate);
 }
Exemple #28
0
        public bool Read(int bufferId, int start, int length)
        {
            var buffer = NetMessage.buffer[bufferId];
            var player = Main.player[bufferId];

            short size   = buffer.reader.ReadInt16();
            int   startX = (int)buffer.reader.ReadInt16();
            int   startY = (int)buffer.reader.ReadInt16();

            if (!WorldGen.InWorld(startX, startY, 3))
            {
                return(true);
            }

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

            var args = new TDSMHookArgs.TileSquareReceived
            {
                X          = startX,
                Y          = startY,
                Size       = size,
                ReadBuffer = buffer.readBuffer
                             //                start = num
            };

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

            //            if (args.applied > 0)
            //            {
            //                WorldGen.RangeFrame(startX, startY, startX + (int)size, startY + (int)size);
            //                NetMessage.SendData((int)Packet.TILE_SQUARE, -1, bufferId, String.Empty, (int)size, (float)startX, (float)startY, 0f, 0);
            //            }

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

            BitsByte bitsByte10 = 0;
            BitsByte bitsByte11 = 0;

            for (int x = startX; x < startX + (int)size; x++)
            {
                for (int y = startY; y < startY + (int)size; y++)
                {
                    if (Main.tile[x, y] == null)
                    {
                        Main.tile[x, y] = new OTA.Memory.MemTile();
                    }
                    var  tile  = Main.tile[x, y];
                    bool flag7 = tile.active();
                    bitsByte10 = buffer.reader.ReadByte();
                    bitsByte11 = buffer.reader.ReadByte();
                    tile.active(bitsByte10[0]);
                    tile.wall = (bitsByte10[2] ? (byte)1 : (byte)0);
                    bool flag8 = bitsByte10[3];
                    if (Main.netMode != 2)
                    {
                        tile.liquid = (flag8 ? (byte)1 : (byte)0);
                    }
                    tile.wire(bitsByte10[4]);
                    tile.halfBrick(bitsByte10[5]);
                    tile.actuator(bitsByte10[6]);
                    tile.inActive(bitsByte10[7]);
                    tile.wire2(bitsByte11[0]);
                    tile.wire3(bitsByte11[1]);
                    if (bitsByte11[2])
                    {
                        tile.color(buffer.reader.ReadByte());
                    }
                    if (bitsByte11[3])
                    {
                        tile.wallColor(buffer.reader.ReadByte());
                    }
                    if (tile.active())
                    {
                        int type3 = (int)tile.type;
                        tile.type = buffer.reader.ReadUInt16();
                        if (Main.tileFrameImportant[(int)tile.type])
                        {
                            tile.frameX = buffer.reader.ReadInt16();
                            tile.frameY = buffer.reader.ReadInt16();
                        }
                        else
                        {
                            if (!flag7 || (int)tile.type != type3)
                            {
                                tile.frameX = -1;
                                tile.frameY = -1;
                            }
                        }
                        byte b4 = 0;
                        if (bitsByte11[4])
                        {
                            b4 += 1;
                        }
                        if (bitsByte11[5])
                        {
                            b4 += 2;
                        }
                        if (bitsByte11[6])
                        {
                            b4 += 4;
                        }
                        tile.slope(b4);
                    }
                    if (tile.wall > 0)
                    {
                        tile.wall = buffer.reader.ReadByte();
                    }
                    if (flag8)
                    {
                        tile.liquid = buffer.reader.ReadByte();
                        tile.liquidType((int)buffer.reader.ReadByte());
                    }
                }
            }
            WorldGen.RangeFrame(startX, startY, startX + (int)size, startY + (int)size);
            if (Main.netMode == 2)
            {
                NetMessage.SendData((int)Packet.TILE_SQUARE, -1, bufferId, "", (int)size, (float)startX, (float)startY, 0, 0, 0, 0);
            }

            return(true);
        }
 public virtual void BeforeParse(HookContext context)
 {
 }
        public static void Main(string[] args)
        {
            Thread.CurrentThread.Name = "Main";

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

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

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

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

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

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

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

                Platform.InitPlatform();

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

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

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

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

                ParseArgs(args);

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

                LoadMonitor.Start();

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

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

                ProgramLog.Log(Languages.Startup_PreparingServerData);

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

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

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

                LoadPlugins();

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

                HookContext ctx;
                HookArgs.ServerStateChange eArgs;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                World.SavePath = worldFile;

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

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

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

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

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

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

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

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

                while (!NetPlay.ServerUp)
                {
                }

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

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

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

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

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

            RemoteConsole.RConServer.Stop();
        }
 public override void BeforePopulateProperty(HookContext Context)
 {
     if (Context.ArgumentValue == null) Context.ArgumentValue = Value.ToString();
 }
        public static void Load(string file)
        {
            if (File.Exists(file))
            {
                using (var sr = new StreamReader(file))
                {
                    string line;
                    while (!sr.EndOfStream)
                    {
                        line = sr.ReadLine();
                        if (line != null)
                        {
                            var ix = line.IndexOf("=");
                            if (ix > -1)
                            {
                                var key   = line.Substring(0, ix).Trim();
                                var value = line.Substring(ix + 1, line.Length - (ix + 1));
#if Full_API
                                switch (key.ToLower())
                                {
                                case "world":
                                    Main.ActiveWorldFileData = WorldFile.GetAllMetadata(value, false);
                                    break;

                                case "port":
                                    int port;
                                    if (!Int32.TryParse(value, out port))
                                    {
                                        Tools.WriteLine("Failed to parse config option {0}", key);
                                    }
                                    else
                                    {
                                        Terraria.Netplay.ListenPort = port;
                                    }
                                    break;

                                case "maxplayers":
                                    int maxplayers;
                                    if (!Int32.TryParse(value, out maxplayers))
                                    {
                                        Tools.WriteLine("Failed to parse config option {0}", key);
                                    }
                                    else
                                    {
                                        Terraria.Main.maxNetPlayers = maxplayers;
                                    }
                                    break;

                                case "priority":
                                    if (!Program.LaunchParameters.ContainsKey("-forcepriority"))
                                    {
                                        if (Tools.RuntimePlatform != RuntimePlatform.Mono)
                                        {
                                            try
                                            {
                                                int priority = Convert.ToInt32(value);
                                                if (priority >= 0 && priority <= 5)
                                                {
                                                    Process currentProcess = Process.GetCurrentProcess();
                                                    if (priority == 0)
                                                    {
                                                        currentProcess.PriorityClass = ProcessPriorityClass.RealTime;
                                                    }
                                                    else if (priority == 1)
                                                    {
                                                        currentProcess.PriorityClass = ProcessPriorityClass.High;
                                                    }
                                                    else if (priority == 2)
                                                    {
                                                        currentProcess.PriorityClass = ProcessPriorityClass.AboveNormal;
                                                    }
                                                    else if (priority == 3)
                                                    {
                                                        currentProcess.PriorityClass = ProcessPriorityClass.Normal;
                                                    }
                                                    else if (priority == 4)
                                                    {
                                                        currentProcess.PriorityClass = ProcessPriorityClass.BelowNormal;
                                                    }
                                                    else if (priority == 5)
                                                    {
                                                        currentProcess.PriorityClass = ProcessPriorityClass.Idle;
                                                    }
                                                }
                                                else
                                                {
                                                    Tools.WriteLine("Invalid priority value: " + priority);
                                                }
                                            }
                                            catch
                                            {
                                            }
                                        }
                                        else
                                        {
                                            Tools.WriteLine("Skipped setting process priority on mono");
                                        }
                                    }
                                    break;

                                case "password":
                                    Terraria.Netplay.ServerPassword = value;
                                    break;

                                case "motd":
                                    Terraria.Main.motd = value;
                                    break;

                                case "lang":
                                    int lang;
                                    if (!Int32.TryParse(value, out lang))
                                    {
                                        Tools.WriteLine("Failed to parse config option {0}", key);
                                    }
                                    else
                                    {
                                        Lang.lang = lang;
                                    }
                                    break;

                                case "worldpath":
                                    Terraria.Main.WorldPath = value;
                                    break;

                                case "worldname":
                                    Terraria.Main.worldName = value;
                                    break;

                                case "banlist":
                                    Netplay.BanFilePath = value;
                                    break;

                                case "difficulty":
                                    Main.expertMode = value == "1";
                                    break;

                                case "autocreate":
                                    int autocreate;
                                    if (!Int32.TryParse(value, out autocreate))
                                    {
                                        Tools.WriteLine("Failed to parse config option {0}", key);
                                    }
                                    else
                                    {
                                        switch (autocreate)
                                        {
                                        case 0:
                                            Terraria.Main.autoGen = false;
                                            break;

                                        case 1:
                                            Terraria.Main.maxTilesX = 4200;
                                            Terraria.Main.maxTilesY = 1200;
                                            Terraria.Main.autoGen   = true;
                                            break;

                                        case 2:
                                            Terraria.Main.maxTilesX = 6300;
                                            Terraria.Main.maxTilesY = 1800;
                                            Terraria.Main.autoGen   = true;
                                            break;

                                        case 3:
                                            Terraria.Main.maxTilesX = 8400;
                                            Terraria.Main.maxTilesY = 2400;
                                            Terraria.Main.autoGen   = true;
                                            break;
                                        }
                                    }
                                    break;

                                case "secure":
                                    Terraria.Netplay.spamCheck = value == "1";
                                    break;

                                case "upnp":
                                    Terraria.Netplay.UseUPNP = value == "1";
                                    if (Terraria.Netplay.UseUPNP && Tools.RuntimePlatform == RuntimePlatform.Mono)
                                    {
                                        Tools.WriteLine("[Warning] uPNP is only available on Windows platforms.");
                                    }
                                    break;

                                case "npcstream":
                                    int npcstream;
                                    if (!Int32.TryParse(value, out npcstream))
                                    {
                                        Tools.WriteLine("Failed to parse config option {0}", key);
                                    }
                                    else
                                    {
                                        Terraria.Main.npcStreamSpeed = npcstream;
                                    }
                                    break;

                                default:
                                    var ctx = new HookContext()
                                    {
                                        Sender = HookContext.ConsoleSender
                                    };
                                    var args = new HookArgs.ConfigurationLine()
                                    {
                                        Key   = key,
                                        Value = value
                                    };

                                    HookPoints.ConfigurationLine.Invoke(ref ctx, ref args);
                                    break;
                                }
#endif
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                }
            }
            else
            {
                Tools.WriteLine("Configuration was specified but does not exist.");
            }
        }
 public override void BeforePopulateProperty(HookContext Context)
 {
     if (Context.ArgumentValue == null) Context.ArgumentValue = GetStickyArg(Context.Property.GetArgumentName());
 }
        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);
        }