private void OnTilePlaced(TileChangedEventArgs args)
        {
            //Debug.Print("OnTilePlaced!");

            var player = args.Player;

            if (!CanBuild(args.TileX, args.TileY, player))
            {
                Debug.Print("Cannot build here.");
                return;
            }

            if (!PlayerTileTracker.HasModifiedTile(player.Name, args.TileX, args.TileY))
            {
                PlayerTileTracker.ModifyTile(player.Name, args.TileX, args.TileY);

                if (args.Player != null)
                {
                    var reward = new MiningReward(args.Player, args.GetTypeOrWall(), args.TileSubTarget, RewardReason.Placing);
                    RewardDistributor.EnqueueReward(reward);
                }
            }
            else
            {
                Debug.Print("Already placed.");
            }
        }
        private void OnTileKilled(TileChangedEventArgs args)
        {
            //Debug.Print("OnTileKilled!");

            var player = args.Player;

            if (!CanBuild(args.TileX, args.TileY, player))
            {
                Debug.Print("Cannot build here.");
                return;
            }

            if (!PlayerTileTracker.HasModifiedTile(player.Name, args.TileX, args.TileY))
            {
                //ignore walls and grass.. this should be filtered already...
                //if( tile.collisionType > 0 )
                {
                    PlayerTileTracker.ModifyTile(player.Name, args.TileX, args.TileY);

                    if (player != null)
                    {
                        var reward = new MiningReward(player, args.GetTypeOrWall(), args.TileSubTarget, RewardReason.Mining);
                        RewardDistributor.EnqueueReward(reward);
                    }
                }
            }
            else
            {
                Debug.Print("Already destroyed.");
            }
        }
        private void onLoad()
        {
            Config.Instance = JsonConfig.LoadOrCreate <Config>(this, ConfigPath);

            try
            {
                Debug.Print($"Loading Bank.");

                if (Bank == null)
                {
                    PlayerRewardNotificationDistributor = new PlayerRewardNotificationDistributor();
                    Bank             = new Bank();
                    NpcSpawnHP       = new ConcurrentDictionary <int, int>();
                    NpcStrikeTracker = new NpcStrikeTracker();
                    NpcStrikeTracker.StruckNpcKilled += OnStruckNpcKilled;
                    PlayerFishingTracker              = new PlayerFishingTracker();
                    PlayerTileTracker    = new PlayerTileTracker(DataDirectory);
                    PlayerSessionTracker = new PlayingRewardTracker();
                    RewardDistributor    = new RewardDistributor();
                    VoteChecker          = new VoteChecker();
                }

                NpcStrikeTracker.Clear();
                Bank.Load();
            }
            catch (Exception ex)
            {
                this.LogPrint(ex.ToString(), TraceLevel.Error);
            }
        }
        private void OnStruckNpcKilled(object sender, StruckNpcKilledEventArgs args)
        {
            //Debug.Print("OnStruckNpcKilled!");

            var reward = new KillingReward(args.PlayerStrikeInfo, args.NpcGivenOrTypeName, args.NpcHitPoints, args.NpcSpawnedFromStatue);

            RewardDistributor.EnqueueReward(reward);
        }
 private void OnGameUpdate(EventArgs args)
 {
     NpcStrikeTracker.OnGameUpdate();
     PlayerFishingTracker.OnGameUpdate();
     PlayerSessionTracker.OnGameUpdate();
     RewardDistributor.OnGameUpdate();
     PlayerRewardNotificationDistributor.Send(400);
 }
        private void OnNetGetData(GetDataEventArgs args)
        {
            if (args.Handled)
            {
                return;
            }

            switch (args.MsgID)
            {
            case PacketTypes.Tile:
                using (var reader = new BinaryReader(new MemoryStream(args.Msg.readBuffer, args.Index, args.Length)))
                {
                    var action = reader.ReadByte();

                    if (action >= 0 && action <= 3)                        //0 kill, 1 place tile, 2 kill, 3 place wall
                    {
                        var tileX = reader.ReadInt16();
                        var tileY = reader.ReadInt16();
                        var var1  = reader.ReadInt16();                               //kill tile status
                        var var2  = reader.ReadInt16();                               //place tile

                        //Debug.Print($"action: {action}");
                        //Debug.Print($"tileX: {tileX}");
                        //Debug.Print($"tileY: {tileY}");
                        //Debug.Print($"var1: {var1}");
                        //Debug.Print($"var2: {var2}");

                        var           player = TShock.Players[args.Msg.whoAmI];
                        TileSubTarget tileSubTarget;

                        if (action < 2)
                        {
                            tileSubTarget = TileSubTarget.Tile;
                        }
                        else
                        {
                            tileSubTarget = TileSubTarget.Wall;
                        }

                        if ((action == 0 || action == 2) && var1 == 0)
                        {
                            var tile = Main.tile[tileX, tileY];

                            //kill tile
                            if (action == 2 || tile.collisionType > 0)                                 //ignore grass
                            {
                                OnTileKilled(new TileChangedEventArgs(player, tileX, tileY, tile.type, tile.wall, tileSubTarget));
                                return;
                            }
                        }
                        else if (action == 1 || action == 3)                           // && var1 > 0)
                        {
                            //var1 should hold the type of the tile or wall we placed.

                            //place tile
                            OnTilePlaced(new TileChangedEventArgs(player, tileX, tileY, (ushort)var1, (byte)var1, tileSubTarget));
                            return;
                        }
                    }
                }

                break;

            case PacketTypes.PlayerDeathV2:
                //based off of MarioE's original code from the Leveling plugin...
                using (var reader = new BinaryReader(new MemoryStream(args.Msg.readBuffer, args.Index, args.Length)))
                {
                    var player = TShock.Players[args.Msg.whoAmI];

                    reader.ReadByte();
                    var deathReason = PlayerDeathReason.FromReader(reader);
                    reader.ReadInt16();
                    reader.ReadByte();
                    var wasPvP = ((BitsByte)reader.ReadByte())[0];
                    if (wasPvP)
                    {
                        var otherPlayer = deathReason.SourcePlayerIndex >= 0
                                                                ? TShock.Players[deathReason.SourcePlayerIndex]
                                                                : null;
                        if (otherPlayer == player)
                        {
                            return;
                        }

                        if (otherPlayer != null)
                        {
                            var reward = new DeathReward(player.Name, RewardReason.DeathPvP, otherPlayer.Name);
                            RewardDistributor.EnqueueReward(reward);
                        }
                        else
                        {
                            var reward = new DeathReward(player.Name, RewardReason.DeathPvP, "");
                            RewardDistributor.EnqueueReward(reward);
                        }
                    }
                    else
                    {
                        var reward = new DeathReward(player.Name, RewardReason.Death, "");
                        RewardDistributor.EnqueueReward(reward);
                    }
                }

                break;

            case PacketTypes.ProjectileNew:
                //Debug.Print("ProjectileNew!");

                using (var reader = new BinaryReader(new MemoryStream(args.Msg.readBuffer, args.Index, args.Length)))
                {
                    var projectileId = reader.ReadInt16();
                    reader.ReadSingle();
                    reader.ReadSingle();
                    reader.ReadSingle();
                    reader.ReadSingle();
                    reader.ReadSingle();
                    reader.ReadInt16();
                    var playerId = reader.ReadByte();
                    var type     = reader.ReadInt16();
                    //var aiFlags = reader.ReadByte();
                    //var ai0 = reader.ReadSingle();
                    //var ai1 = reader.ReadSingle();
                    //var projUUID = reader.ReadSingle();

                    PlayerFishingTracker.TryBeginFishing(playerId, projectileId, type);
                }

                break;

            case PacketTypes.ProjectileDestroy:
                //Debug.Print("ProjectileDestroy!");
                using (var reader = new BinaryReader(new MemoryStream(args.Msg.readBuffer, args.Index, args.Length)))
                {
                    var projectileId = reader.ReadInt16();
                    var ownerId      = reader.ReadByte();

                    PlayerFishingTracker.TryEndFishing(ownerId, projectileId);
                }

                break;

            case PacketTypes.PlayerSlot:
                //Debug.Print("PlayerSlot!");
                using (var reader = new BinaryReader(new MemoryStream(args.Msg.readBuffer, args.Index, args.Length)))
                {
                    var playerId = reader.ReadByte();
                    var slotId   = reader.ReadByte();
                    var stack    = reader.ReadInt16();
                    var prefix   = reader.ReadByte();
                    var itemId   = reader.ReadInt16();

                    if (PlayerFishingTracker.IsItemFromFishing(playerId))                           //, stack, prefix, itemId))
                    {
                        var player = TShock.Players[args.Msg.whoAmI];
                        var reward = new FishingReward(player.Name, stack, prefix, itemId);
                        RewardDistributor.EnqueueReward(reward);
                    }
                }

                break;

            default:
                break;
            }
        }