C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using UnityEngine;
using Oxide.Core.Libraries;
using Oxide.Core.Plugins;
using VLB;
using Layer = Rust.Layer;
using UnityEngine.Networking;
using Pool = Facepunch.Pool;
using ConVar;
using Time = UnityEngine.Time;
using System.Text;
using System;
using System.Globalization;
using Newtonsoft.Json;
using System.Linq;
using System.Collections;
using Oxide.Game.Rust.Cui;
using System.Collections.Generic;
using Oxide.Core;
using Oxide.Plugins.RaidBlockExt;
using Rust;
namespace Oxide.Plugins {
[Info("RaidBlock", "DezLife & Mercury", "1.1.43")]
public class RaidBlock : RustPlugin {
private bool FindItemInInventory(BasePlayer player, ulong skinId) {
return player.inventory.containerMain.itemList.Any(item => item.skin == skinId) || player.inventory.containerBelt.itemList.Any(item => item.skin == skinId) || player.inventory.containerWear.itemList.Any(item => item.skin == skinId);
}
[PluginReference]
Plugin Friends, Clans, IQChat;
void OnPlayerEnteredRaidableBase(BasePlayer player, Vector3 raidPos, bool allowPVP, int mode) {
float time = config.RaidBlockMain.RaidableBasesIntegration.RaidBlockDuration;
RaidPlayer raidPlayer = player.GetOrAddComponent<RaidPlayer>();
SendChat("RAIDBLOCK_ENTER_RAID_ZONE".GetAdaptedMessage(player.UserIDString, time.ToTimeFormat()), player, 3f);
raidPlayer.ActivateBlock(Time.realtimeSinceStartup + time);
Interface.CallHook("OnEnterRaidZone", player);
}
protected override void LoadConfig() {
base.LoadConfig();
try {
config = Config.ReadObject<Configuration>();
if (config == null) {
throw new Exception();
}
SaveConfig();
}
catch {
for (int i = 0; i < 3; i++) {
PrintError(LanguageEn ? "Configuration file is corrupt! Check your config file at https://jsonlint.com/" : "Вы допустили ошибку синтаксиса в конфигурационном файле! Проверьте файл на https://jsonlint.com/");
}
LoadDefaultConfig();
}
ValidateConfig();
SaveConfig();
}
private static InterfaceBuilder _interface;
protected override void SaveConfig() {
Config.WriteObject(config);
}
private object OnStructureRotate(BaseCombatEntity entity, BasePlayer player) => CanActions(player);
private readonly string _permIgnoreRaid = ".ignore";
private void ValidateConfig() {
if (config.RaidBlockMain.RaidZoneSphereSettings.DomeTransparencyLevel > 5) {
config.RaidBlockMain.RaidZoneSphereSettings.DomeTransparencyLevel = 3;
}
}
private void CheckUnsubscribeOrSubscribeHooks() {
if (_raidZoneComponents.Count == 0) UnsubscribeHook(false, true);
else SubscribeHook(false, true);
}
private void DeleteNotification(BasePlayer player, float seconds) {
Timer timers = timer.Once(seconds, () => {
player.SendConsoleCommand("gametip.hidegametip");
}
);
if (_playerTimer.ContainsKey(player)) {
if (_playerTimer[player] != null && !_playerTimer[player].Destroyed) _playerTimer[player].Destroy();
_playerTimer[player] = timers;
}
else _playerTimer.Add(player, timers);
}
private List<RaidPlayer> raidPlayersList = new();
private object CanRemove(BasePlayer player) => CanActions(player);
public static RaidBlock Instance;
private List<BasePlayer> playerInCache = new();
private object CanRedeemKit(BasePlayer player) => CanActions(player);
private void SubscribeHook(bool main, bool raidActions) {
if (main) {
Subscribe(nameof(OnEntityDeath));
Subscribe(nameof(OnPlayerConnected));
if(config.BlockDetect.RaidBlockOnTakeDamageHook.ActivateBlockOnTakeDamage) Subscribe(nameof(OnEntityTakeDamage));
if (config.RaidBlockMain.RaidableBasesIntegration.useRaidableBases) {
if(config.RaidBlockMain.RaidableBasesIntegration.BlockOnEnterZone) Subscribe(nameof(OnPlayerEnteredRaidableBase));
if(config.RaidBlockMain.RaidableBasesIntegration.BlockOnExitZone) Subscribe(nameof(OnPlayerExitedRaidableBase));
}
}
if (raidActions) {
if (config.ActionsBlocked.RbBlackListCommand != null && config.ActionsBlocked.RbBlackListCommand.Count != 0) {
if (config.ActionsBlocked.RbBlackListCommand.Count == 1 && config.ActionsBlocked.RbBlackListCommand[0].Equals("commandExample")) return;
Subscribe(nameof(OnPlayerCommand));
Subscribe(nameof(OnServerCommand));
}
if (config.RaidBlockMain.RaidBlockOnPlayerDeath) {
Subscribe(nameof(OnPlayerDeath));
}
if (config.ActionsBlocked.CanUseKit) {
Subscribe(nameof(CanRedeemKit));
}
if (config.ActionsBlocked.CanUseTeleport) {
Subscribe(nameof(canTeleport));
Subscribe(nameof(CanTeleport));
}
if (config.ActionsBlocked.CanUseTrade) {
Subscribe(nameof(canTrade));
Subscribe(nameof(CanTrade));
}
if (config.ActionsBlocked.CanDemolishObjects) {
Subscribe(nameof(OnStructureDemolish));
Subscribe(nameof(canRemove));
Subscribe(nameof(CanRemove));
}
if (config.ActionsBlocked.CanRepairObjects) {
Subscribe(nameof(OnStructureRepair));
}
if (config.ActionsBlocked.CanBuildTwig || config.ActionsBlocked.CanDeployObjects || config.ActionsBlocked.RbDeployWhiteList.Count > 0) {
Subscribe(nameof(CanBuild));
}
if (config.ActionsBlocked.CanUseBGrade) {
Subscribe(nameof(CanBGrade));
}
if (config.ActionsBlocked.CanUpgradeObjects) {
Subscribe(nameof(OnStructureUpgrade));
Subscribe(nameof(OnStructureRotate));
}
if (config.ActionsBlocked.CanPickUpObjects) {
Subscribe(nameof(CanPickupEntity));
}
}
}
object CanBGrade (BasePlayer player, int grade, BuildingBlock buildingBlock, Planner planner) {
RaidPlayer playPlayer = player.GetComponent<RaidPlayer>();
if (playPlayer != null && playPlayer.UnblockTimeLeft > 0) {
RunEffect(player, "assets/prefabs/locks/keypad/effects/lock.code.denied.prefab");
return -1;
}
return null;
}
private void DrawUI_RB_Main(BasePlayer player, float timeLeft = 0f) {
string Interface = InterfaceBuilder.GetInterface(InterfaceBuilder.RB_MAIN);
if (Interface == null) return;
switch (InterfaceBuilder.TypeUi) {
case 0 : Interface = Interface.Replace("%Descriptions%", "RAIDBLOCK_UI_DESCRIPTIONS_V1".GetAdaptedMessage(player.UserIDString));
break;
case 1 : Interface = Interface.Replace("%Descriptions%", "RAIDBLOCK_UI_DESCRIPTIONS_V2".GetAdaptedMessage(player.UserIDString));
break;
}
Interface = Interface.Replace("%Title%", "RAIDBLOCK_UI_TITLE".GetAdaptedMessage(player.UserIDString));
CuiHelper.DestroyUi(player, InterfaceBuilder.RB_MAIN);
CuiHelper.AddUi(player, Interface);
DrawUI_RB_Updated(player, timeLeft == 0 ? config.RaidBlockMain.RaidBlockDuration : timeLeft, true);
}
private bool IsBlocked(BasePlayer player) {
RaidPlayer obj = player.GetComponent<RaidPlayer>();
return obj != null && obj.UnblockTimeLeft > 0;
}
private void CreateToolGunItem(BasePlayer player, string name, ulong skinId) {
Item toolGun = ItemManager.CreateByName(RB_WHITE_AND_BLACK_LIST_ITEM, 1, skinId);
toolGun.name = name;
toolGun.info.stackable = 1;
player.GiveItem(toolGun);
}
private float GetHealthPercent (BaseEntity entity, float damage = 0f) => (entity.Health () - damage) * 100f / entity.MaxHealth ();
private bool IsRaidBlocked(BasePlayer player) => IsBlocked(player);
private readonly Dictionary<BasePlayer, Timer> _playerTimer = new Dictionary<BasePlayer, Timer>();
private RaidPlayer GetRaidPlayer(BasePlayer player) {
RaidPlayer obj = player.GetComponent<RaidPlayer>();
return obj;
}
protected override void LoadDefaultConfig() {
config = new Configuration();
}
private object CanTeleport(BasePlayer player) => CanActions(player, true);
private bool IsRaidBlocked(ulong playerId) {
BasePlayer target = BasePlayer.Find(playerId.ToString());
return target != null && IsBlocked(target);
}
private readonly string _permHelperToolGun = ".toolgun";
private const string EXPLOSION_MAP_MARKER_PREFAB = "assets/prefabs/tools/map/explosionmarker.prefab";
private static ImageUI _imageUI;
private void Unload() {
foreach (RaidableZone obj in _raidZoneComponents) UnityEngine.Object.DestroyImmediate(obj);
foreach (RaidPlayer rPlayer in raidPlayersList) if(rPlayer != null) rPlayer.Kill(true);
if (_imageUI != null) {
_imageUI.UnloadImages();
_imageUI = null;
}
_interface = null;
Instance = null;
}
private object OnStructureDemolish(BaseCombatEntity entity, BasePlayer player, bool immediate) => CanActions(player);
private object OnServerCommand(ConsoleSystem.Arg arg) {
BasePlayer player = arg.Player();
if (player == null || arg.cmd.FullName == "chat.say") return null;
string command = arg.cmd.Name;
if (arg.Args != null && arg.Args.Length != 0) command += " " + string.Join(" ", arg.Args);
string onlyCommand = !string.IsNullOrWhiteSpace(command) && command.Contains(" ") ? command.Substring(0, command.IndexOf(" ", StringComparison.Ordinal)) : command;
return config.ActionsBlocked.RbBlackListCommand.Contains(onlyCommand.ToLower()) ? CanActions(player) : null;
}
private void CreateOrRefreshRaidblock(Vector3 position, BasePlayer player) {
if (permission.UserHasPermission(player.UserIDString, Name + _permIgnoreRaid)) return;
if (Interface.Call("CanRaidBlock", player, position) != null) return;
RaidableZone raidableZone = _raidZoneComponents != null && _raidZoneComponents.Count != 0 ? _raidZoneComponents.FirstOrDefault(x => x != null && Vector3.Distance(position, x.transform.position) < config.RaidBlockMain.RaidBlockDistance) : null;
if (raidableZone != null) raidableZone.RefreshTimer(position, player);
else {
raidableZone = new GameObject().AddComponent<RaidableZone>();
_raidZoneComponents.Add(raidableZone);
raidableZone.CreateRaidZone(position, player);
}
Interface.CallHook("OnRaidBlock", position);
}
private object CanTrade(BasePlayer player) => CanActions(player, true);
private void OnPlayerDeath(BasePlayer player, HitInfo hitInfo) {
if (player == null || hitInfo == null || !player.userID.IsSteamId()) return;
RaidPlayer raidPlayer = GetRaidPlayer(player);
if (raidPlayer != null) {
Instance.SendChat("RAIDBLOCK_KILL_PLAYER".GetAdaptedMessage(player.UserIDString), player);
UnityEngine.Object.DestroyImmediate(raidPlayer);
}
}
private enum SphereTypes {
BlackSphere, BRSphere,
}
private class RaidPlayer : FacepunchBehaviour {
public BasePlayer player;
public Single blockEnds;
public float UnblockTimeLeft => Convert.ToInt32(blockEnds - Time.realtimeSinceStartup);
private void Awake() {
player = GetComponent<BasePlayer>();
if(!Instance.raidPlayersList.Contains(this)) Instance.raidPlayersList.Add(this);
Interface.CallHook("OnRaidBlockStarted", player);
}
public void Kill(Boolean force = false) {
if (!force) {
if (Instance.raidPlayersList.Contains(this)) Instance.raidPlayersList.Remove(this);
}
DestroyImmediate(this);
}
private void OnDestroy() {
CuiHelper.DestroyUi(player, InterfaceBuilder.RB_MAIN);
Interface.CallHook("OnRaidBlockStopped", player);
}
public void UpdateTime(Single time, Boolean customTime = false) {
if (customTime) {
blockEnds = time;
return;
}
if (time > blockEnds) blockEnds = time;
}
public void ActivateBlock(Single time) {
if(time > blockEnds) blockEnds = time;
CrateUI();
InvokeRepeating(CheckTimeLeft, 0, 1);
}
private void CheckTimeLeft() {
if (UnblockTimeLeft > 0) {
RefreshUI();
}
else {
CuiHelper.DestroyUi(player, InterfaceBuilder.RB_MAIN);
CancelInvoke(nameof(CheckTimeLeft));
Kill();
}
}
public void CrateUI() => Instance.DrawUI_RB_Main(player, UnblockTimeLeft);
private void RefreshUI() => Instance.DrawUI_RB_Updated(player, UnblockTimeLeft);
}
private const Boolean LanguageEn = false;
private const string VISUALIZATION_SPHERE_PREFAB = "assets/prefabs/visualization/sphere.prefab";
private List<BasePlayer> GetPlayerFriends(BasePlayer player) {
List<BasePlayer> teamMembers = new List<BasePlayer>();
if (RelationshipManager.maxTeamSize > 0 && player.currentTeam != 0UL) {
foreach (ulong member in player.Team.members) {
BasePlayer playerInTeam = BasePlayer.FindByID(member);
if(playerInTeam != null && playerInTeam != player) teamMembers.Add(playerInTeam);
}
}
else if (Friends) {
ulong[] playersInTeam = Friends?.Call<ulong[]>("GetFriends", player.userID) ?? new ulong[] {
}
;
foreach (ulong member in playersInTeam) {
BasePlayer playerInTeam = BasePlayer.FindByID(member);
if(playerInTeam != null) teamMembers.Add(playerInTeam);
}
}
return teamMembers;
}
private static RaidableZone GetRbZone(Vector3 position) {
List<SphereCollider> sphereColliders = new ();
Vis.Colliders(position, 0.1f, sphereColliders);
if (sphereColliders.Count <= 0) return null;
foreach (SphereCollider sCollider in sphereColliders) {
if (!sCollider.gameObject.TryGetComponent(out RaidableZone rbZone)) continue;
return rbZone;
}
return null;
}
[ChatCommand("rbtest")]
void rbtest(BasePlayer player) {
if(!player.IsAdmin) return;
CreateOrRefreshRaidblock(player.transform.position, player);
}
private bool IsWhiteList(BaseCombatEntity entity) {
return config.BlockDetect.RbWhiteList.Any(whiteEnt => entity.prefabID == whiteEnt);
}
private bool IsBlackList(BaseCombatEntity entity) {
return config.BlockDetect.RbBlackList.Any(blackEnt => entity.prefabID == blackEnt);
}
private const string VISUALIZATION_BR_SPHERE_PREFAB_PURPLE = "assets/bundled/prefabs/modding/events/twitch/br_sphere_purple.prefab";
private ulong[] GetFriendList(BasePlayer targetPlayer) {
List<ulong> friendList = new();
if (Friends) {
if (Friends.Call("GetFriends", targetPlayer.userID) is ulong[] friends) friendList.AddRange(friends);
}
if (Clans) {
if (Clans.Call("GetClanMembers", targetPlayer.UserIDString) is ulong[] clanMembers) friendList.AddRange(clanMembers);
}
if(targetPlayer.Team != null) friendList.AddRange(targetPlayer.Team.members);
return friendList.ToArray();
}
private Dictionary<string, string> _prefabNameItem = new() {
["40mm_grenade_he"]
= "multiplegrenadelauncher", ["grenade.beancan.deployed"] = "grenade.beancan", ["grenade.f1.deployed"] = "grenade.f1", ["explosive.satchel.deployed"] = "explosive.satchel", ["explosive.timed.deployed"] = "explosive.timed", ["rocket_basic"] = "ammo.rocket.basic", ["rocket_hv"] = "ammo.rocket.hv", ["rocket_fire"] = "ammo.rocket.fire", ["survey_charge.deployed"] = "surveycharge"
}
;
void OnPlayerSleepEnded(BasePlayer player) {
if (player == null || player.IsDead() || !player.IsConnected) return;
RaidableZone rbZone = GetRbZone(player.transform.position);
if (rbZone == null) return;
rbZone.AddPlayer(player);
}
private int ApiGetTime(ulong userId) {
if (!IsRaidBlocked(userId.ToString())) return 0;
BasePlayer player = BasePlayer.FindByID(userId);
if (player == null) return 0;
RaidPlayer obj = player.GetComponent<RaidPlayer>();
return obj == null ? 0 : int.Parse(obj.UnblockTimeLeft.ToString(CultureInfo.InvariantCulture));
}
private object CanPickupEntity(BasePlayer player, BaseEntity entity) => CanActions(player);
private object OnHammerHit(BasePlayer player, HitInfo info) {
if (player == null || info is null) return null;
if (player.GetActiveItem() is not {
}
activeItem) return null;
if (!activeItem.info.shortname.Equals(RB_WHITE_AND_BLACK_LIST_ITEM) || (activeItem.skin is not RB_WHITELIST_ITEM_SKIN and not RB_BLACKLIST_ITEM_SKIN)) return null;
if (!HasPermission(player)) return null;
UpdateWhiteOrBlackList(player, activeItem.skin, info);
return false;
}
private enum BRZoneColor {
Blue, Green, Purple, Red
}
private const ulong RB_WHITELIST_ITEM_SKIN = 3100653846;
private List<RaidableZone> _raidZoneComponents = new();
private bool CheckEntity(BaseCombatEntity entity, HitInfo info, BasePlayer raider) {
if (entity.OwnerID == 0) return false;
if (config.BlockDetect.IgnoreEntsHealth > 0 && entity.MaxHealth() < config.BlockDetect.IgnoreEntsHealth) return false;
if (entity is BuildingBlock {
grade : BuildingGrade.Enum.Twigs
}
block) return false;
if (raider != null && config.BlockDetect.RaidYourself == false) {
if (raider.userID == entity.OwnerID) return false;
if (IsFriends(raider, entity.OwnerID)) return false;
}
return true;
}
private void Init() {
Instance = this;
UnsubscribeHook(true, true);
}
private void DrawUI_RB_Updated(BasePlayer player, float timeLeft, bool upd = false) {
string Interface = InterfaceBuilder.GetInterface(InterfaceBuilder.RB_PROGRESS_BAR);
if (Interface == null) return;
double factor = InterfaceBuilder.Factor * timeLeft / config.RaidBlockMain.RaidBlockDuration;
Interface = Interface.Replace("%left%", factor.ToString(CultureInfo.InvariantCulture));
Interface = Interface.Replace("%TimeLeft%", "RAIDBLOCK_UI_TIMER".GetAdaptedMessage(player.UserIDString, timeLeft.ToTimeFormat()));
if(!upd) Interface = Interface.Replace("0.222", "0");
CuiHelper.DestroyUi(player, InterfaceBuilder.RB_PROGRESS);
CuiHelper.DestroyUi(player, InterfaceBuilder.RB_PROGRESS_TIMER);
CuiHelper.AddUi(player, Interface);
}
private const string GENERIC_MAP_MARKER_PREFAB = "assets/prefabs/tools/map/genericradiusmarker.prefab";
private enum MarkerTypes {
Explosion, MarkerRadius, ExplosionMarkerRadius, MarkerRadiusTimer,
}
private object OnStructureRepair(BaseCombatEntity entity, BasePlayer player) => CanActions(player);
private object OnPlayerCommand(BasePlayer player, string command, string[] args) {
if (player == null) return null;
if (args != null && args.Length != 0) command += " " + string.Join(" ", args);
string onlyCommand = !string.IsNullOrWhiteSpace(command) && command.Contains(" ") ? command.Substring(0, command.IndexOf(" ", StringComparison.Ordinal)) : command;
return config.ActionsBlocked.RbBlackListCommand.Contains(onlyCommand.ToLower()) ? CanActions(player) : null;
}
private bool IsFriends(BasePlayer player, ulong targetID) {
ulong[] friendList = GetFriendList(player);
return friendList != null && friendList.Contains(targetID);
}
private object canRemove(BasePlayer player) => CanActions(player);
private bool IsRaidBlocked(string playerId) {
BasePlayer target = BasePlayer.Find(playerId);
return target != null && IsBlocked(target);
}
private const string RB_WHITE_AND_BLACK_LIST_ITEM = "toolgun";
private static string GetGridString(Vector3 position) => MapHelper.PositionToString(position);
private void OnEntityTakeDamage(BaseCombatEntity entity, HitInfo info) {
if (info == null || entity == null) return;
DamageType majorityDamageType = info.damageTypes.GetMajorityDamageType();
if (majorityDamageType == DamageType.Decay) return;
BasePlayer raider = info.InitiatorPlayer != null ? info.InitiatorPlayer : entity.lastAttacker as BasePlayer;
if (raider == null) return;
Configuration.RaidBlockDetect.RaidBlockOnTakeDamage damageRaidBlock = config.BlockDetect.RaidBlockOnTakeDamageHook;
if (IsRaidBlocked(raider) && !damageRaidBlock.UpdateBlockOnTakeDamage) return;
String shortnameWeapon = String.Empty;
if (info.WeaponPrefab != null) {
if (!_prefabID2Item.TryGetValue(info.WeaponPrefab.prefabID, out shortnameWeapon)) _prefabNameItem.TryGetValue(info.WeaponPrefab.ShortPrefabName, out shortnameWeapon);
}
if (!String.IsNullOrWhiteSpace(shortnameWeapon) && damageRaidBlock.RbOnTakeDamageBlackList.Contains(shortnameWeapon)) return;
if (GetHealthPercent(entity, info.damageTypes.Total()) > config.BlockDetect.RaidBlockOnTakeDamageHook.RbOnTakeDamageMinCondition) return;
OnEntCheck(entity, info);
}
private void UnsubscribeHook(bool main, bool raidActions) {
if (main) {
Unsubscribe(nameof(OnEntityDeath));
Unsubscribe(nameof(OnEntityTakeDamage));
Unsubscribe(nameof(OnPlayerConnected));
Unsubscribe(nameof(OnPlayerEnteredRaidableBase));
Unsubscribe(nameof(OnPlayerExitedRaidableBase));
}
if (raidActions) {
Unsubscribe(nameof(OnPlayerDeath));
Unsubscribe(nameof(CanBGrade));
Unsubscribe(nameof(CanBuild));
Unsubscribe(nameof(OnStructureUpgrade));
Unsubscribe(nameof(OnStructureRepair));
Unsubscribe(nameof(OnStructureDemolish));
Unsubscribe(nameof(OnStructureRotate));
Unsubscribe(nameof(canTeleport));
Unsubscribe(nameof(CanTeleport));
Unsubscribe(nameof(OnPlayerCommand));
Unsubscribe(nameof(OnServerCommand));
Unsubscribe(nameof(canRemove));
Unsubscribe(nameof(CanRemove));
Unsubscribe(nameof(canTrade));
Unsubscribe(nameof(CanTrade));
Unsubscribe(nameof(CanRedeemKit));
Unsubscribe(nameof(CanPickupEntity));
}
}
private object OnStructureUpgrade(BuildingBlock block, BasePlayer player, BuildingGrade.Enum grade) => CanActions(player);
private const string VISUALIZATION_BR_SPHERE_PREFAB_GREEN = "assets/bundled/prefabs/modding/events/twitch/br_sphere_green.prefab";
private object CanBuild(Planner planner, Construction prefab, Construction.Target target) {
BasePlayer player = planner.GetOwnerPlayer();
if (player == null) return null;
string shortname = prefab.hierachyName[(prefab.hierachyName.IndexOf("/", StringComparison.Ordinal) + 1)..];
if (config.ActionsBlocked.RbDeployWhiteList.Contains(shortname)) return null;
Deployable deployable = planner.GetDeployable();
if (deployable != null && !config.ActionsBlocked.CanDeployObjects) return null;
if (prefab.defaultGrade != null && !config.ActionsBlocked.CanBuildTwig) return null;
return CanActions(player);
}
private void OnEntCheck(BaseCombatEntity entity, HitInfo info) {
DamageType? majorityDamageType = info?.damageTypes.GetMajorityDamageType();
if (majorityDamageType == DamageType.Decay) return;
if(!config.BlockDetect.CanRaidIfNotCupboard && entity.GetBuildingPrivilege() == null) return;
BasePlayer raider = info?.InitiatorPlayer ? info.InitiatorPlayer : entity.lastAttacker as BasePlayer;
if(raider == null) return;
if (IsBlackList(entity) || (IsBlockedClass(entity) && !IsWhiteList(entity))) {
if (CheckEntity(entity, info, raider)) {
BasePlayer ownerPlayer = BasePlayer.FindByID(entity.OwnerID);
if (ownerPlayer != null && ownerPlayer.IsConnected) SendChat("RAIDBLOCK_OWNER_NOTIFY".GetAdaptedMessage(ownerPlayer.UserIDString, GetGridString(entity.transform.position)), ownerPlayer, 3f);
CreateOrRefreshRaidblock(entity.transform.position, raider);
}
}
}
private static void RunEffect(BasePlayer player, string prefab) {
Effect effect = new();
effect.Init(Effect.Type.Generic, player.transform.position, Vector3.zero);
effect.pooledString = prefab;
EffectNetwork.Send(effect, player.net.connection);
}
private void GameTipsSendPlayer(BasePlayer player, string message, float seconds = 10f, bool error = false) {
player.SendConsoleCommand("gametip.hidegametip");
string tips = error ? "showtoast 1" : "showgametip";
player.SendConsoleCommand($"gametip.{tips} \"{message}\"");
DeleteNotification(player, seconds);
}
private class Configuration {
public class IQChat {
[JsonProperty(LanguageEn ? "IQChat : Custom prefix in the chat" : "IQChat : Кастомный префикс в чате")]
public String CustomPrefix = "[RaidBlock]";
[JsonProperty(LanguageEn ? "IQChat : Custom avatar in the chat (If required)" : "IQChat : Кастомный аватар в чате(Если требуется)")]
public String CustomAvatar = "0";
[JsonProperty(LanguageEn ? "IQChat : Use UI notifications" : "IQChat : Использовать UI уведомления")]
public Boolean UIAlertUse = false;
}
public class RaidBlockDetect {
[JsonProperty(LanguageEn ? "List of items that will trigger a raid block upon destruction (prefabID)" : "Список предметов за которые при уничтожении будет даваться рейдблок (prefabID)", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public HashSet<uint> RbBlackList = new() {
12312312,
}
;
[JsonProperty(LanguageEn ? "List of items that will not trigger a raid block upon destruction (prefabID)" : "Список предметов за которые при уничтожении не будет даваться рейдблок (prefabID)", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public HashSet<uint> RbWhiteList = new() {
1231223,
}
;
[JsonProperty(LanguageEn ? "Ignore objects with a maximum health state less than N (0 - disabled)" : "Игнорировать объекты с максимальным состоянием здоровья меньше N (0 - отключено)")]
public int IgnoreEntsHealth = 0;
[JsonProperty(LanguageEn ? "Activate raidblock upon the destruction of own or friends' buildings" : "Активировать рейдблок при уничтожении собственного строения или строения друзей")]
public bool RaidYourself = false;
[JsonProperty(LanguageEn ? "Activate raidblock if there is no tool cupboard in the building" : "Активировать рейдблок если в строении нет шкафа")]
public bool CanRaidIfNotCupboard = false;
[JsonProperty(LanguageEn ? "Setting the activation of the raid block when dealing damage to structures" : "Настройка активации рейд блока при нанесении урона строениям")]
public RaidBlockOnTakeDamage RaidBlockOnTakeDamageHook = new();
public class RaidBlockOnTakeDamage {
[JsonProperty(LanguageEn ? "Activate raid block when dealing damage to structures? (true - yes/false - no)" : "Активировать рейд блок при нанесении урона строениям (true - да/false - нет)")]
public bool ActivateBlockOnTakeDamage = false;
[JsonProperty(LanguageEn ? "Extend raid block upon subsequent damage to structures? (true - yes/false - no)" : "Продлить рейд блок при повторном нанесении урона строениям (true - да/false - нет)")]
public bool UpdateBlockOnTakeDamage = false;
[JsonProperty(LanguageEn ? "Blacklist of items for which raid block will not activate or extend upon damage (ShortName)" : "Черный список предметов за которые при нанесении урона не будет активироваться и продлеваться рейд блок (ShortName)", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public HashSet<string> RbOnTakeDamageBlackList = new() {
"torch",
}
;
[JsonProperty(LanguageEn ? "The condition of a structure before blocking will start (percentage)" : "Состояние структуры перед началом блокировки (Процент)")]
public float RbOnTakeDamageMinCondition = 100;
}
}
[JsonProperty(LanguageEn ? "Setting IQChat" : "Настройка IQChat")]
public IQChat IQChatSetting = new IQChat();
[JsonProperty(LanguageEn ? "Setting up triggers for the raidblock" : "Настройка триггеров для рейдблока")]
public RaidBlockDetect BlockDetect = new();
public class RaidBlock {
[JsonProperty(LanguageEn ? "Radius of blocking zone (Meters)" : "Радиус зоны блокировки (Метры)")]
public int RaidBlockDistance = 130;
[JsonProperty(LanguageEn ? "Blocking time (Seconds)" : "Время блокировки (Секунды)")]
public int RaidBlockDuration = 300;
[JsonProperty(LanguageEn ? "Use dynamic raid zone (shift the zone center to the explosion location)" : "Использовать динамичную зону рейда (смещение центра зоны к месту взрыва)")]
public bool IsDynamicRaidZone = false;
[JsonProperty(LanguageEn ? "Spread raidblock to all team players" : "Распространять рейд блок на всех игроков в команде инициатора рейда")]
public bool RaidBlockShareOnFriends = true;
[JsonProperty(LanguageEn ? "When entering the active raid block zone, activate the player raid block" : "При входе в активную зону рейдблока - активировать рейдблок игроку")]
public bool RaidBlockOnEnterRaidZone = true;
[JsonProperty(LanguageEn ? "Upon exiting the raid block zone, deactivate the raid block for the player" : "При выходе из зоны рейдблока - деактивировать рейдблок игроку")]
public bool RaidBlockOnExitRaidZone = false;
[JsonProperty(LanguageEn ? "When exiting the raid block zone, leave a lock for N seconds (leave 0 if you don't need it)" : "При выходе из зоны рейдблока - оставлять N секунд блокировки (оставьте 0 - если вам не нужно это)")]
public Int32 TimeLeftOnExitZone = 0;
[JsonProperty(LanguageEn ? "Activate raid block for all players within the effective radius after the raid starts" : "Активировать рейдблок для всех игроков в радиусе действия после начала рейда")]
public bool RaidBlockAddedAllPlayersInZoneRaid = true;
[JsonProperty(LanguageEn ? "Deactivate the raid block for the player upon death" : "Деактивировать рейдблок игроку после смерти")]
public bool RaidBlockOnPlayerDeath = true;
[JsonProperty(LanguageEn ? "Raid zone map marker settings" : "Настройки маркера на карте в зоне рейда")]
public MapMarkerSettings mapMarkerSettings = new();
[JsonProperty(LanguageEn ? "Visual raid zone (Dome) settings" : "Настройка визуальной зоны рейда (купол)")]
public SphereSettings RaidZoneSphereSettings = new();
[JsonProperty(LanguageEn ? "Integration settings with RaidableBases" : "Настройки интеграции с RaidableBases")]
public RaidableBases RaidableBasesIntegration = new();
public class SphereSettings {
[JsonProperty(LanguageEn ? "Activate visual raid zone (Dome)" : "Активировать визуальную зону рейда (купол)")]
public bool IsSphereEnabled = false;
[JsonProperty(LanguageEn ? "Choose marker type: 0 - standard dome, 1 - BattleRoyale dome" : "Выберете тип купола : 0 - cтандартный купол, 1 - BattleRoyale купол")]
public SphereTypes SphereType = SphereTypes.BlackSphere;
[JsonProperty(LanguageEn ? "Color for BattleRoyale dome: 0 - blue | 1 - green | 2 - purple | 3 - red" : "Цвет для BattleRoyale купола : 0 - blue | 1 - green | 2 - purple | 3 - red")]
public BRZoneColor BRZoneColor = BRZoneColor.Blue;
[JsonProperty(LanguageEn ? "Transparency level of the standard dome (Lower values mean more transparency.The value should not exceed 5)" : "Уровень прозрачности стандартного купола (Чем меньше - тем прозрачнее.Значения должно быть не более 5)")]
public int DomeTransparencyLevel = 3;
public string GetBRZonePrefab() {
return BRZoneColor switch {
BRZoneColor.Blue => VISUALIZATION_BR_SPHERE_PREFAB_BLUE, BRZoneColor.Green => VISUALIZATION_BR_SPHERE_PREFAB_GREEN, BRZoneColor.Purple => VISUALIZATION_BR_SPHERE_PREFAB_PURPLE, BRZoneColor.Red => VISUALIZATION_BR_SPHERE_PREFAB_RED, _ => throw new ArgumentOutOfRangeException(nameof(BRZoneColor), BRZoneColor, null)
}
;
}
}
public class MapMarkerSettings {
[JsonProperty(LanguageEn ? "Display the block zone on the G map" : "Отображать зону блокировки на G карте")]
public bool IsRaidBlockMarkerEnabled = true;
[JsonProperty(LanguageEn ? "Choose marker type: 0 - Explosion, 1 - Circle, 2 - Explosion + Circle, 3 - Circle + Timer" : "Выберите тип маркера: 0 - Explosion | 1 - Marker Radius | 2 - Explosion + Marker Radius | 3 - Marker Radius + Timer")]
public MarkerTypes RaidBlockMarkerType = MarkerTypes.ExplosionMarkerRadius;
[JsonProperty(LanguageEn ? "Marker color (without #) (For marker types 1, 2, and 3)" : "Цвет маркера (без #) (Для маркера типа 1, 2 и 3)")]
public string MarkerColorHex = "f3ecad";
[JsonProperty(LanguageEn ? "Outline color (without #) (For marker types 1, 2, and 3)" : "Цвет обводки (без #) (Для маркера типа 1, 2 и 3)")]
public string OutlineColorHex = "ff3535";
[JsonProperty(LanguageEn ? "Marker transparency (For marker types 1, 2, and 3)" : "Прозрачность маркера (Для маркера типа 1, 2 и 3)")]
public float MarkerAlpha = 0.5f;
}
}
public class RaidBlockActionsBlocked {
[JsonProperty(LanguageEn ? "Forbid building repair" : "Запретить починку строений")]
public bool CanRepairObjects = true;
[JsonProperty(LanguageEn ? "Forbid picking up items (furnaces, boxes, etc.)" : "Запретить поднятие вещей (печки/ящики и т.д)")]
public bool CanPickUpObjects = false;
[JsonProperty(LanguageEn ? "Forbid upgrading buildings" : "Запретить улучшение строений")]
public bool CanUpgradeObjects = true;
[JsonProperty(LanguageEn ? "Forbid building removal" : "Запретить удаление строений")]
public bool CanDemolishObjects = true;
[JsonProperty(LanguageEn ? "Forbid teleportation" : "Запретить телепортацию")]
public bool CanUseTeleport = true;
[JsonProperty(LanguageEn ? "Forbid the use of BGrade" : "Запретить использования BGrade")]
public bool CanUseBGrade = true;
[JsonProperty(LanguageEn ? "Forbid the use of kits" : "Запретить использование китов")]
public bool CanUseKit = true;
[JsonProperty(LanguageEn ? "Forbid the use of trade" : "Запретить использование обмена (Trade)")]
public bool CanUseTrade = true;
[JsonProperty(LanguageEn ? "Forbid building" : "Запретить строение")]
public bool CanBuildTwig = true;
[JsonProperty(LanguageEn ? "Forbid object placement (furnaces, boxes, etc.)" : "Запретить размещение объектов (Печки, ящики и другое)")]
public bool CanDeployObjects = false;
[JsonProperty(LanguageEn ? "List of objects allowed to build/place during the raidblock (shortname)" : "Список объектов, которые разрешено строить/размещать во время рейдблока (PrefabName)", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<string> RbDeployWhiteList = new() {
"bed_deployed", "ladder.wooden.wall",
}
;
[JsonProperty(LanguageEn ? "List of prohibited commands when blocking is active [specify them without a slash (/) in lower case]" : "Список запрещенных команд при активной блокировки [указывайте их без слэша (/) в нижнем регистре]", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<string> RbBlackListCommand = new() {
"commandexample",
}
;
}
[JsonProperty(LanguageEn ? "Main raidblock settings" : "Основные настройки рейд-блока")]
public RaidBlock RaidBlockMain = new();
public class RaidBlockUi {
[JsonProperty(LanguageEn ? "Interface variant (0, 1, 2) - example: " : "Вариант интерфейса (0, 1, 2)")]
public int UiType = 0;
[JsonProperty(LanguageEn ? "Interface layer: Overlay - will overlay other UI, Hud - will be overlaid by other interfaces" : "Слой интерфейса : Overlay - будет перекрывать другие UI, Hud - будет перекрываться другим интерфейсом")]
public string Layers = "Hud";
[JsonProperty(LanguageEn ? "Vertical padding" : "Вертикальный отступ")]
public int OffsetY = 0;
[JsonProperty(LanguageEn ? "Horizontal padding" : "Горизонтальный отступ")]
public int OffsetX = 0;
[JsonProperty(LanguageEn ? "Interface settings for variant 0" : "Настройки интерфейса для варианта 0")]
public RaidBlockUiSettings InterfaceSettingsVariant0 = new() {
BackgroundColor = "0.1921569 0.1921569 0.1921569 1", IconColor = "0 0.7764706 1 1", AdditionalElementsColor = "", MainTextColor = "1 1 1 1", SecondaryTextColor = "1 1 1 0.5019608", ProgressBarMainColor = "0.3411765 0.5490196 0.9607843 1", ProgressBarBackgroundColor = "1 1 1 0.1019608", SmoothTransition = 0.222f,
}
;
[JsonProperty(LanguageEn ? "Interface settings for variant 1" : "Настройки интерфейса для варианта 1")]
public RaidBlockUiSettings InterfaceSettingsVariant1 = new() {
BackgroundColor = "0.9607843 0.772549 0.7333333 0.7019608", IconColor = "1 1 1 1", AdditionalElementsColor = "0.9215686 0.3058824 0.172549 1", MainTextColor = "0.1921569 0.1921569 0.1921569 1", SecondaryTextColor = "0.1320755 0.1320755 0.1320755 1", ProgressBarMainColor = "0.9215686 0.3058824 0.172549 1", ProgressBarBackgroundColor = "1 1 1 0.4117647", SmoothTransition = 0.222f
}
;
[JsonProperty(LanguageEn ? "Interface settings for variant 2" : "Настройки интерфейса для варианта 2")]
public RaidBlockUiSettings InterfaceSettingsVariant2 = new() {
BackgroundColor = "0.1921569 0.1921569 0.1921569 1", IconColor = "0.9411765 0.3137255 0.2866228 1", AdditionalElementsColor = "0.9568627 0.3607843 0.2623232 1", MainTextColor = "1 1 1 1", SecondaryTextColor = "1 1 1 0.5019608", ProgressBarMainColor = "1 1 1 1", ProgressBarBackgroundColor = "1 1 1 0.4117647", SmoothTransition = 0.222f
}
;
public class RaidBlockUiSettings {
[JsonProperty(LanguageEn ? "Background color (RGBA)" : "Цвет фона (RGBA)")]
public string BackgroundColor;
[JsonProperty(LanguageEn ? "Icon color (RGBA)" : "Цвет иконки (RGBA)")]
public string IconColor;
[JsonProperty(LanguageEn ? "Color of additional elements (RGBA)" : "Цвет дополнительных элементов (RGBA)")]
public string AdditionalElementsColor;
[JsonProperty(LanguageEn ? "Main text color (RGBA)" : "Цвет основного текста (RGBA)")]
public string MainTextColor;
[JsonProperty(LanguageEn ? "Secondary text Color (RGBA)" : "Цвет второстепенного текста (RGBA)")]
public string SecondaryTextColor;
[JsonProperty(LanguageEn ? "Main color of the progress-bar (RGBA)" : "Основной цвет прогресс-бара (RGBA)")]
public string ProgressBarMainColor;
[JsonProperty(LanguageEn ? "Background Color of the Progress Bar (RGBA)" : "Цвет фона прогресс-бара (RGBA)")]
public string ProgressBarBackgroundColor;
[JsonProperty(LanguageEn ? "Delay before the UI appears and disappears (for smooth transitions)" : "Задержка перед появлением и исчезновением UI (для плавности)")]
public float SmoothTransition;
}
}
[JsonProperty(LanguageEn ? "Setting restrictions during the raid block" : "Настройка ограничений во время рейдблока")]
public RaidBlockActionsBlocked ActionsBlocked = new();
[JsonProperty(LanguageEn ? "Interface settings" : "Настройки интерфейса")]
public RaidBlockUi RaidBlockInterface = new();
public class RaidableBases {
[JsonProperty(LanguageEn ? "RaidableBases: Enable support for Raidable Bases?" : "RaidableBases : Включить поддержку Raidable Bases ?")]
public bool useRaidableBases = false;
[JsonProperty(LanguageEn ? "RaidableBases: Blocking time (Seconds)" : "RaidableBases: Время блокировки (Секунды)")]
public int RaidBlockDuration = 600;
[JsonProperty(LanguageEn ? "RaidableBases : Give a raid block when entering the Raidable Bases zone" : "RaidableBases : Давать рейд блок при входе в зону Raidable Bases")]
public bool BlockOnEnterZone = false;
[JsonProperty(LanguageEn ? "RaidableBases : Remove the raid block when leaving the Raidable Bases zone" : "RaidableBases : Снимать рейд блок при выходе из зоны Raidable Bases")]
public bool BlockOnExitZone = false;
}
}
private object canTrade(BasePlayer player) => CanTrade(player);
[ChatCommand("rb.white")]
private void RaidBlockDetectWhiteList(BasePlayer player) {
if (!HasPermission(player)) return;
string itemName = "RAIDBLOCK_TOOLGUN_WHITELIST_ITEM_NAME".GetAdaptedMessage(player.UserIDString);
if (FindItemInInventory(player, RB_WHITELIST_ITEM_SKIN)) {
GameTipsSendPlayer(player, "RAIDBLOCK_TOOLGUN_ALREADY_IN_INVENTORY".GetAdaptedMessage(player.UserIDString, itemName), error : true);
return;
}
CreateToolGunItem(player, itemName, RB_WHITELIST_ITEM_SKIN);
GameTipsSendPlayer(player, "RAIDBLOCK_TOOLGUN_WHITELIST_USAGE".GetAdaptedMessage(player.UserIDString, itemName));
}
private void UpdateWhiteOrBlackList(BasePlayer player, ulong skinId, HitInfo info) {
BaseEntity entity = info.HitEntity;
if (entity == null) return;
uint prefabId = entity.prefabID;
HashSet<uint> listToUpdate = skinId switch {
RB_WHITELIST_ITEM_SKIN => config.BlockDetect.RbWhiteList, RB_BLACKLIST_ITEM_SKIN => config.BlockDetect.RbBlackList, _ => null
}
;
if (listToUpdate == null) return;
string messageKey = UpdateList(listToUpdate, prefabId) ? skinId == RB_WHITELIST_ITEM_SKIN ? "RAIDBLOCK_TOOLGUN_ADDED_TO_WHITELIST" : "RAIDBLOCK_TOOLGUN_ADDED_TO_BLACKLIST" : skinId == RB_WHITELIST_ITEM_SKIN ? "RAIDBLOCK_TOOLGUN_REMOVED_FROM_WHITELIST" : "RAIDBLOCK_TOOLGUN_REMOVED_FROM_BLACKLIST";
GameTipsSendPlayer(player, messageKey.GetAdaptedMessage(player.UserIDString, entity.ShortPrefabName, prefabId));
// ... [Code preview truncated due to length. Full source in attached file] ...