/// <summary> /// Registers the appropriate hooks, loads the existing config or write one if not, and then starts the one second update timer. /// </summary> public override void Initialize() { ServerApi.Hooks.NetGetData.Register(this, GetData); ServerApi.Hooks.ServerJoin.Register(this, ServerJoin); ServerApi.Hooks.ServerLeave.Register(this, ServerLeave); ServerApi.Hooks.ServerChat.Register(this, ServerChat); ServerApi.Hooks.NetSendData.Register(this, SendData); Commands.ChatCommands.Add(new Command("pvpcontroller.reload", Reload, "pvpcreload")); Commands.ChatCommands.Add(new Command("pvpcontroller.spectate", ToggleSpectate, "spectate")); SetupConfig(); foreach (var netID in Config.BannedArmorPieces) { EquipItems.Add(new EquipItem(netID, true)); } if (Config.UseDatabase) { SetupDatabase(); } if (Config.UseRedis) { Synchroniser = new Synchroniser(this); } GetDataHandler = new GetDataHandlers(this); DataSender = new DataSender(); SetupUpdateTimer(); SetupDuplicateEquipPrevention(); }
/// <summary> /// Applies an amount of damage to this player, updating their client and the server version of their health /// </summary> /// <param name="killer"></param> /// <param name="victim"></param> /// <param name="killersWeapon"></param> /// <param name="dir"></param> /// <param name="damage"></param> /// <param name="realDamage"></param> public void ApplyPlayerDamage(PlayerKiller killer, Item killersWeapon, int dir, int damage, int realDamage) { // Send the damage using the special method to avoid invincibility frames issue DataSender.SendPlayerDamage(TshockPlayer, dir, damage); Controller.RaisePlayerDamageEvent(this, new PlayerDamageEventArgs(killer.Player, TshockPlayer, killersWeapon, realDamage)); TPlayer.statLife -= realDamage; // Hurt the player to prevent instant regen activating var savedHealth = TPlayer.statLife; TPlayer.Hurt(new PlayerDeathReason(), damage, 0, true, false, false, 3); TPlayer.statLife = savedHealth; if (TPlayer.statLife <= 0) { TshockPlayer.Dead = true; IsDead = true; DataSender.SendPlayerDeath(TshockPlayer); if (TPlayer.hostile && killer != null) { PlayerKillEventArgs killArgs = new PlayerKillEventArgs(killer.Player, TshockPlayer, killer.Weapon); Controller.RaisePlayerKillEvent(this, killArgs); } return; } DataSender.SendClientHealth(this, TPlayer.statLife); }
/// <summary> /// Updates this players health, keeping it within the bounds of their max health /// </summary> /// <param name="health">The amount to set this players health to</param> public void SetActiveHealth(int health) { TPlayer.statLife = health; if (TPlayer.statLife > TPlayer.statLifeMax2) { TPlayer.statLife = TPlayer.statLifeMax2; } DataSender.SendClientHealth(this, TPlayer.statLife); }
/// <summary> /// Applies a player heal for the given amount, not going over the players max hp /// </summary> /// <param name="player">The player who is healing</param> /// <param name="healAmt">The amount they are healing for</param> public void Heal(int healAmt) { TPlayer.statLife += healAmt; if (TPlayer.statLife > TPlayer.statLifeMax2) { TPlayer.statLife = TPlayer.statLifeMax2; } DataSender.SendClientHealth(this, TPlayer.statLife); }
/// <summary> /// Ensures that this player has non-prefixed armor if the option is enabled /// </summary> /// <param name="handlers"></param> internal void CheckArmorAndEnforce(GetDataHandlers handlers) { if (TPlayer.armor[0].prefix > 0) { TPlayer.armor[0].prefix = 0; DataSender.SendSlotUpdate(this, 59, TPlayer.armor[0]); } if (TPlayer.armor[1].prefix > 0) { DataSender.SendSlotUpdate(this, 60, TPlayer.armor[1]); } if (TPlayer.armor[2].prefix > 0) { DataSender.SendSlotUpdate(this, 61, TPlayer.armor[2]); } }
/// <summary> /// Prevents prefixes on armor items /// </summary> /// <param name="args">The GetDataHandlerArgs object containing the player who sent the packet and the /// data in it</param> /// <returns>Whether or not the packet was handled (and should therefore not be processed /// by anything else)</returns> private bool HandleInventoryUpdate(GetDataHandlerArgs args) { args.Data.ReadByte(); int slotId = args.Data.ReadByte(); args.Data.ReadInt16(); byte prefix = (byte)args.Data.ReadByte(); int netId = args.Data.ReadInt16(); // Is prefixed armor armor if (Controller.Config.BanPrefixedArmor && prefix > 0 && slotId >= 59 && slotId <= 61) { Item fixedArmorItem = new Item(); fixedArmorItem.Prefix(0); fixedArmorItem.stack = 1; DataSender.SendSlotUpdate(args.Player, slotId, fixedArmorItem); } bool impossibleEquip = false; if (Controller.Config.PreventImpossibleEquipment && netId != 0) { if (slotId >= 59 && slotId <= 66) { Item newEquip = new Item(); newEquip.SetDefaults(netId); newEquip.Prefix(prefix); if (EquipController.ShouldPreventEquip(args.Player, newEquip, slotId)) { impossibleEquip = true; args.Player.TPlayer.armor[slotId - 59].SetDefaults(0); } } } return(impossibleEquip); }