C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Oxide.Core.Plugins;
using UnityEngine;
using Physics = UnityEngine.Physics;
namespace Oxide.Plugins
{
[Info("Door Permissions", "TheForbiddenAi", "2.0.0"),
Description("Allows admins to lock doors to specific permissions.")]
public class DoorPermissions : RustPlugin
{
#region Fields
private readonly DynamicConfigFile _dataFile = Interface.Oxide.DataFileSystem.GetDatafile("DoorPermissions");
private ConfigData _configData;
private const BUTTON SelectDoorButton = BUTTON.FIRE_PRIMARY;
private const string DoorPermPrefix = "doorpermissions.door.";
private const string LockDoorPerm = "doorpermissions.lockdoor";
private const string UnlockDoorPerm = "doorpermissions.unlockdoor";
private const string ActivateDoorPerm = "doorpermissions.activatedoor";
private const string DeactivateDoorPerm = "doorpermissions.deactivatedoor";
private const string ViewDoorInfoPerm = "doorpermissions.viewdoorinfo";
private const string SetDoorNamePerm = "doorpermissions.setdoorname";
private const string SetTeleportDoorPerm = "doorpermissions.setteleportdoor";
private const string SetTeleportPointPerm = "doorpermissions.setteleportpoint";
private const string SetCategoryPerm = "doorpermissions.setcategory";
private const string SetCategoryNamePerm = "doorpermissions.setcategoryname";
private const string AddCategoryPermPerm = "doorpermissions.addcategoryperm";
private const string RemoveCategoryPermPerm = "doorpermissions.removecategoryperm";
private const string CreateCategoryPerm = "doorpermissions.createcategory";
private const string DeleteCategoryPerm = "doorpermissions.deletecategory";
private const string ViewCategoryInfoPerm = "doorpermissions.viewcategoryinfo";
private const string ViewCategoriesPerm = "doorpermissions.viewcategories";
private List<string> _zDoorFronts = new List<string>();
private List<string> _positiveEntrances = new List<string>();
private enum DoorActions
{
Lock,
Unlock,
Activate,
Deactivate,
ViewInfo,
SetDoorName,
SetTeleportDoor,
CreatingTelePoint,
SettingDoorCategory
}
private string _version;
#endregion
#region Config
private class ConfigData
{
// Default values exist in the scenario that someone messes up their config keys, the code will still execute
[JsonProperty(PropertyName = "Date File Version - DO NOT MODIFY")]
public string DataFileVersion = "1.0.1";
[JsonProperty(PropertyName = "Send No Permissons Message When Opening Door Without Required Permissions")]
public bool SendInsufficientPerms = false;
[JsonProperty(PropertyName = "Allow Damage To Locked Doors")]
public bool AllowDamage = false;
[JsonProperty(PropertyName = "Should Delete Doors On Category Deletion")]
public bool ShouldDeleteDoors = false;
public static ConfigData DefaultConfig()
{
return new ConfigData()
{
DataFileVersion = "2.0.0",
SendInsufficientPerms = true,
AllowDamage = false,
ShouldDeleteDoors = false
};
}
}
protected override void LoadConfig()
{
base.LoadConfig();
_configData = Config.ReadObject<ConfigData>();
if (_configData == null)
{
LoadDefaultConfig();
}
}
protected override void LoadDefaultConfig()
{
Config.WriteObject(GetDefaultConfig(), true);
}
private ConfigData GetDefaultConfig()
{
return ConfigData.DefaultConfig();
}
private void SaveConfig()
{
Config.WriteObject(_configData, true);
}
#endregion
#region Localization
protected override void LoadDefaultMessages()
{
lang.RegisterMessages(new Dictionary<string, string>
{
["Insufficient Permissions"] =
"<color=red>You do not have the required permission to do this action!</color>",
["Invalid Syntax"] = "<color=red>Invalid Syntax:</color> <color=white>{0}</color>",
["Lock Door Syntax"] = "/lockdoor <permissions...> [note: {0} is implied in the permission]",
["Set Door Name Syntax"] = "/setdoorname <name>",
["Set Category Syntax"] = "/setcategory <id>",
["Set Category Name Syntax"] = "/setcategoryname <id> <name>",
["Add Category Perm Syntax"] =
"/addcategoryperm <id> <permissions...> [note: {0} is implied in the permission]",
["Remove Category Perm Syntax"] =
"/removecategoryperm <id> <permissions...> [note: {0} is implied in the permission]",
["Create Category Syntax"] =
"/createcategory <name> (permissions...) [note: {0} is implied in the permission]",
["Delete Category Syntax"] = "/deletecategory <id>",
["View Category Info Syntax"] = "/viewcategoryinfo <id>",
["Entered Locking Process"] =
"<color=#00ffffff>Look at a door and, use your primary attack keybind, to lock it, to cancel run /lockdoor!</color>",
["Entered Unlocking Process"] =
"<color=#00ffffff>Look at a door and, use your primary attack keybind, to unlock it, to cancel run /unlockdoor!</color>",
["Entered Activation Process"] =
"<color=#00ffffff>Look at a door and, use your primary attack keybind, to activate it, to cancel run /activatedoor!</color>",
["Entered Deactivation Process"] =
"<color=#00ffffff>Look at a door and, use your primary attack keybind, to deactivate it, to cancel run /deactivatedoor!</color>",
["Entered View Info Process"] =
"<color=#00ffffff>Look at a door and, use your primary attack keybind, to view it's information, to cancel run /viewdoorinfo!</color>",
["Entered Set Door Name Process"] =
"<color=#00ffffff>Look at a door and, use your primary attack keybind, to set it's name, to cancel run /setdoorname!</color>",
["Entered Set Tele Door Process"] =
"<color=#00ffffff>Look at a door and, use your primary attack keybind," +
" to make it a teleportation door, to cancel run /setteleportdoor!</color>",
["Entered Set Tele Point Process"] =
"<color=#00ffffff>Look at a door and, use your primary attack keybind, " +
"to create a teleportation point, to cancel run /setteleportpoint!</color>",
["Entered Set Category Process"] =
"<color=#00ffffff>Look at a door and, use your primary attack keybind, to set its category, to cancel run /setcategory!</color>",
["Door Locked"] = "<i>Door has been locked to the permission(s):</i> <color=green>{0}</color>",
["Door Locked New Permissions"] =
"<i>Door has been locked to the permission(s):</i> <color=green>{0}</color> <i>(prexisiting permissions still remain)</i>",
["Door Unlocked"] =
"<i>This door is no longer locked to the following permission(s):</i> <color=green>{0}</color>",
["Door Activated"] = "<color=green>This door is now activated!</color>",
["Door Deactivated"] =
"<color=green>This door is now</color> <color=red>deactivated</color><color=green>!</color>",
["Set Door Name"] =
"<color=green>Successfully changed the door's name to</color> {0}<color=green>!</color>",
["Set Tele Door"] = "<color=green>This door is now a teleportation door!</color>",
["Removed Tele Door"] = "<color=green>This door is no longer a teleportation door!</color>",
["Set Tele Point"] = "<color=green>Set Teleportation Point at</color> {0}",
["Set Category Name"] =
"<color=green>Successfully changed category name to</color> {0}<color=green>!</color>",
["Category Locked New Permissions"] =
"<i>The given category has been locked to the permission(s):</i> <color=green>{0}</color> <i>(prexisiting permissions still remain)</i>",
["Category Set"] =
"<color=green>Successfully changed the category to the category with an id of</color> {0}<color=green>!</color>",
["Category Unlocked"] =
"<i>The given category is no longer locked to the following permission(s):</i> <color=green>{0}</color>",
["Category Created"] =
"<color=green>Successfully created a category with the name of</color> {0}<color=green>!</color>",
["Category Deleted"] =
"<color=green>Successfully deleted the category with the id of</color> {0}<color=green>!</color>",
["Exited Process"] = "<color=green>Successfully exited the previous process!</color>",
["Locked To Category Not Door"] =
"<color=red>This door is not locked to the permission:</color> <i>{0}<i>, but it's category is! Continuing with remaining permissions.",
["View Door Info Format"] =
"<color=yellow>Door Name:</color> {0},\n<color=yellow>Category Id:</color> {1}," +
"\n<color=yellow>Door Active:</color> {2},\n<color=yellow>Permission List(Does not include category permissions):</color> {3}",
["View Category Info Format"] =
"<color=yellow>Category Name:</color> {0},\n<color=yellow>Category Id:</color> {1}," +
"\n<color=yellow>Permission List(Does not include any door permissions):</color> {2}",
["View Categories Format"] = "<color=yellow>Id:</color> {0}, <color=yellow>Name:</color> {1},\n",
["Failed To Create Codelock"] =
"<color=red>Failed to create code lock entity, please try again.</color>",
["Time Ended"] = "<color=yellow>The time period to select a door has ended!</color>",
["Not A Door"] =
"<color=red>You are either too far from the door or the entity you are looking at is not a door!</color>",
["Door Not Locked"] = "<color=red>This door is not currently locked to any permission!</color>",
["Door Is Not Locked To That Permission"] =
"<color=red>This door is not locked to the permission:</color> <i>{0}</i> " +
"<color=red>continuing with remaining permissions!</color>",
["Door Already Locked"] =
"<color=red>This door is already locked to the permission:</color> {0} </color>continuing with remaining permissions</color>",
["Door Already Activated"] = "<color=red>This door is already activated!</color>",
["Door Already Deactivated"] = "<color=red>This door is already deactivated!</color>",
["Door Already Has Name"] = "<color=red>This door is already has that name!</color>",
["Not A Category"] = "<color=red>There is no category with the id</color> {0}<color=red>!</color>",
["Not A Number"] = "<color=red>That is not a valid id, ids are only numbers!</color>",
["Already Has Category"] =
"<color=red>The selected door already has the category with an id of</color> {0}<color=green>!</color>",
["Category Already Locked"] =
"<color=red>That category is already locked to the permission:</color> {0} </color>continuing with remaining permissions</color>",
["Category Already Has Name"] = "<color=red>That category already has that name!</color>",
["Can Not Delete Default Category"] = "<color=red>You can not delete the default category!</color>",
["Category Is Not Locked To That Permission"] =
"<color=red>That category is not locked to the permission:</color> <i>{0}</i> " +
"<color=red>continuing with remaining permissions!</color>",
["No Categories Found"] = "<color=red>Uh Oh! There are no categories to display.</color>"
}, this);
}
private string GetMessage(string key, BasePlayer player, params object[] args) =>
string.Format(lang.GetMessage(key, this, player.UserIDString), args);
#endregion
#region Initalization
private void Init()
{
_version = Version.ToString();
if (_configData.AllowDamage)
{
Unsubscribe("OnEntityTakeDamage");
}
RegisterPermissions(
LockDoorPerm,
UnlockDoorPerm,
ActivateDoorPerm,
DeactivateDoorPerm,
ViewDoorInfoPerm,
SetDoorNamePerm,
SetTeleportDoorPerm,
SetTeleportPointPerm,
SetCategoryPerm,
SetCategoryNamePerm,
AddCategoryPermPerm,
RemoveCategoryPermPerm,
CreateCategoryPerm,
DeleteCategoryPerm,
ViewCategoryInfoPerm,
ViewCategoriesPerm
);
string dataFileVersion = _configData.DataFileVersion;
if (!dataFileVersion.Equals(_version))
{
UpdateDataFile(dataFileVersion);
}
CacheDataObjects();
InitializeQuaternionLists();
}
private void CacheDataObjects()
{
Dictionary<string, object> categoryJson = _dataFile["Categories"] as Dictionary<string, object>;
if (categoryJson == null)
{
Puts("Invalid Data File!");
return;
}
foreach (KeyValuePair<string, object> pair in categoryJson)
{
string catJson = JsonConvert.SerializeObject(pair.Value);
CategoryObject category = JsonConvert.DeserializeObject<CategoryObject>(catJson);
category.Id = int.Parse(pair.Key);
category.Doors.ForEach(door =>
{
door.Category = category;
RegisterPermissions(door.GetAllPermissions().ToArray());
DoorObject.AddDoors(door);
});
CategoryObject.AddCategory(category);
}
}
private void UpdateDataFile(string oldVersion)
{
switch (oldVersion)
{
case "1.0.1":
int catId = 0;
List<DoorObject> doors = new List<DoorObject>();
foreach (KeyValuePair<string, object> pair in _dataFile)
{
DoorObject doorObj = new DoorObject();
string[] coords = Regex.Replace(pair.Key, @"[^0-9,.-]", "").Split(',');
doorObj.Position = new Vector3(float.Parse(coords[0]), float.Parse(coords[1]),
float.Parse(coords[2]));
doorObj.CategoryId = catId;
doorObj.IsActive = (bool) _dataFile[pair.Key, "active"];
List<object> rawPermissions = (List<object>) _dataFile[pair.Key, "permissions"];
List<string> permissions = rawPermissions.Select(obj => obj.ToString()).ToList();
doorObj.Permissions = permissions;
doors.Add(doorObj);
}
CategoryObject category = new CategoryObject
{
Id = catId,
Doors = doors,
Permissions = new List<string>()
};
_dataFile.Clear();
_dataFile["Categories", catId.ToString()] = category;
_configData.DataFileVersion = _version;
SaveConfig();
_dataFile.Save();
break;
}
}
private void InitializeQuaternionLists()
{
Quaternion xDoorFrontQ = new Quaternion(0, 0.2F, 0, -1F);
string xDoorFront = xDoorFrontQ.ToString();
Quaternion zDoorFrontQ = new Quaternion(0, 0.6F, 0, 0.8F);
Quaternion zDoorFront2Q = new Quaternion(0, 0.8F, 0, -0.6F);
string zDoorFront = zDoorFrontQ.ToString();
string zDoorFront2 = zDoorFront2Q.ToString();
string zDoorFront3 = Quaternion.Inverse(zDoorFrontQ).ToString();
string zDoorFront4 = Quaternion.Inverse(zDoorFront2Q).ToString();
_zDoorFronts = new List<string> {zDoorFront, zDoorFront2, zDoorFront3, zDoorFront4};
_positiveEntrances = new List<string> {xDoorFront, zDoorFront2, zDoorFront4};
}
#endregion
#region Hooks
private object CanUseLockedEntity(BasePlayer player, BaseLock baseLock)
{
BaseEntity parent = baseLock.GetParentEntity();
if (!(parent is Door)) return null;
Vector3 doorPosition = parent.transform.position;
DoorObject doorData = DoorObject.GetDoorByLocation(doorPosition);
if (doorData == null) return null;
if (!doorData.IsActive) return null;
List<string> permList = doorData.GetAllPermissions();
if (!HasPermissions(player, permList.ToArray()))
{
if (_configData.SendInsufficientPerms)
player.ChatMessage(GetMessage("Insufficient Permissions", player));
return null;
}
bool shouldUnlock = true;
if (doorData.IsTeleportationDoor)
{
Vector3 playerPosition = player.transform.position;
Vector3 entrance = doorData.TeleportationEntrance;
Vector3 exit = doorData.TeleportationExit;
bool shouldEnter = !IsDoorEntrance((Door) parent, playerPosition);
player.Teleport(shouldEnter ? entrance : exit);
shouldUnlock = false;
}
GameObjectRef unlockSound = (baseLock as CodeLock)?.effectUnlocked;
if (unlockSound == null)
{
Puts("Unable to retrieve unlock sound for code lock!");
return shouldUnlock;
}
Effect.server.Run(unlockSound.resourcePath, player.transform.position, Vector3.zero);
return shouldUnlock;
}
private object OnEntityTakeDamage(BaseCombatEntity entity, HitInfo info)
{
BaseEntity baseEntity = info.HitEntity;
if (!(baseEntity is Door)) return null;
Vector3 position = baseEntity.transform.position;
DoorObject doorData = DoorObject.GetDoorByLocation(position);
if (doorData == null) return null;
return true;
}
private void OnEntityKill(BaseNetworkable entity)
{
if (!(entity is Door)) return;
Vector3 position = entity.transform.position;
DoorObject doorData = DoorObject.GetDoorByLocation(position);
if (doorData == null) return;
doorData.IsActive = false;
doorData.UpdateDoor(this);
}
#endregion
#region Commands
[ChatCommand("lockdoor")]
private void LockDoorCommand(BasePlayer player, string command, string[] args)
{
if (!HasPermissions(player, LockDoorPerm))
{
player.ChatMessage(GetMessage("Insufficient Permissions", player));
return;
}
if (TimerHandler.HasTimer(player) && TimerHandler.GetTimer(player).Action == DoorActions.Lock)
{
player.ChatMessage(GetMessage("Exited Process", player));
TimerHandler.RemoveTimer(player);
return;
}
if (args.Length < 1)
{
string syntax = GetMessage("Lock Door Syntax", player, DoorPermPrefix);
player.ChatMessage(GetMessage("Invalid Syntax", player, syntax));
return;
}
TimerHandler.RemoveTimer(player);
args = args.Select(str => (DoorPermPrefix + str).ToLower()).ToArray();
player.ChatMessage(GetMessage("Entered Locking Process", player));
TimerHandler timerHandler = new TimerHandler(this,
player,
DoorActions.Lock,
0.1f,
LockDoor(player, args)
);
}
[ChatCommand("unlockdoor")]
private void UnlockDoorCommand(BasePlayer player, string command, string[] args)
{
if (!HasPermissions(player, UnlockDoorPerm))
{
player.ChatMessage(GetMessage("Insufficient Permissions", player));
return;
}
if (TimerHandler.HasTimer(player) && TimerHandler.GetTimer(player).Action == DoorActions.Unlock)
{
player.ChatMessage(GetMessage("Exited Process", player));
TimerHandler.RemoveTimer(player);
return;
}
TimerHandler.RemoveTimer(player);
args = args.Select(str => (DoorPermPrefix + str).ToLower()).ToArray();
player.ChatMessage(GetMessage("Entered Unlocking Process", player));
TimerHandler timerHandler = new TimerHandler(this,
player,
DoorActions.Unlock,
0.1f,
UnlockDoor(player, args)
);
}
[ChatCommand("activatedoor")]
private void ActivateDoorCommand(BasePlayer player, string command, string[] args)
{
if (!HasPermissions(player, ActivateDoorPerm))
{
player.ChatMessage(GetMessage("Insufficient Permissions", player));
return;
}
if (TimerHandler.HasTimer(player) && TimerHandler.GetTimer(player).Action == DoorActions.Activate)
{
player.ChatMessage(GetMessage("Exited Process", player));
TimerHandler.RemoveTimer(player);
return;
}
TimerHandler.RemoveTimer(player);
player.ChatMessage(GetMessage("Entered Activation Process", player));
TimerHandler timerHandler = new TimerHandler(this,
player,
DoorActions.Activate,
0.1f,
ActivateDoor(player)
);
}
[ChatCommand("deactivatedoor")]
private void DeactivateDoorCommand(BasePlayer player, string command, string[] args)
{
if (!HasPermissions(player, DeactivateDoorPerm))
{
player.ChatMessage(GetMessage("Insufficient Permissions", player));
return;
}
if (TimerHandler.HasTimer(player) && TimerHandler.GetTimer(player).Action == DoorActions.Deactivate)
{
player.ChatMessage(GetMessage("Exited Process", player));
TimerHandler.RemoveTimer(player);
return;
}
TimerHandler.RemoveTimer(player);
player.ChatMessage(GetMessage("Entered Deactivation Process", player));
TimerHandler timerHandler = new TimerHandler(this,
player,
DoorActions.Deactivate,
0.1f,
DeactivateDoor(player)
);
}
[ChatCommand("viewdoorinfo")]
private void ViewDoorInfoCommand(BasePlayer player, string command, string[] args)
{
if (!HasPermissions(player, ViewDoorInfoPerm))
{
player.ChatMessage(GetMessage("Insufficient Permissions", player));
return;
}
if (TimerHandler.HasTimer(player) && TimerHandler.GetTimer(player).Action == DoorActions.ViewInfo)
{
player.ChatMessage(GetMessage("Exited Process", player));
TimerHandler.RemoveTimer(player);
return;
}
TimerHandler.RemoveTimer(player);
player.ChatMessage(GetMessage("Entered View Info Process", player));
TimerHandler timerHandler = new TimerHandler(this,
player,
DoorActions.ViewInfo,
0.1f,
ViewDoorInfo(player)
);
}
[ChatCommand("setdoorname")]
private void SetDoorNameCommand(BasePlayer player, string command, string[] args)
{
if (!HasPermissions(player, LockDoorPerm))
{
player.ChatMessage(GetMessage("Insufficient Permissions", player));
return;
}
if (TimerHandler.HasTimer(player) && TimerHandler.GetTimer(player).Action == DoorActions.SetDoorName)
{
player.ChatMessage(GetMessage("Exited Process", player));
TimerHandler.RemoveTimer(player);
return;
}
if (args.Length < 1)
{
string syntax = GetMessage("Set Door Name Syntax", player);
player.ChatMessage(GetMessage("Invalid Syntax", player, syntax));
return;
}
TimerHandler.RemoveTimer(player);
string newName = string.Join(" ", args);
player.ChatMessage(GetMessage("Entered Set Door Name Process", player));
TimerHandler timerHandler = new TimerHandler(this,
player,
DoorActions.SetDoorName,
0.1f,
SetDoorName(player, newName)
);
}
[ChatCommand("setteleportdoor")]
private void SetTeleportDoorCommand(BasePlayer player, string command, string[] args)
{
if (!HasPermissions(player, SetTeleportDoorPerm))
{
player.ChatMessage(GetMessage("Insufficient Permissions", player));
return;
}
if (TimerHandler.HasTimer(player) && TimerHandler.GetTimer(player).Action == DoorActions.SetTeleportDoor)
{
player.ChatMessage(GetMessage("Exited Process", player));
TimerHandler.RemoveTimer(player);
return;
}
TimerHandler.RemoveTimer(player);
player.ChatMessage(GetMessage("Entered Set Tele Door Process", player));
TimerHandler timerHandler = new TimerHandler(this,
player,
DoorActions.SetTeleportDoor,
0.1f,
SetTeleDoor(player)
);
}
[ChatCommand("setteleportpoint")]
private void SetTeleportPointCommand(BasePlayer player, string command, string[] args)
{
if (!HasPermissions(player, SetTeleportPointPerm))
{
player.ChatMessage(GetMessage("Insufficient Permissions", player));
return;
}
if (TimerHandler.HasTimer(player) && TimerHandler.GetTimer(player).Action == DoorActions.CreatingTelePoint)
{
player.ChatMessage(GetMessage("Exited Process", player));
TimerHandler.RemoveTimer(player);
return;
}
TimerHandler.RemoveTimer(player);
player.ChatMessage(GetMessage("Entered Set Tele Point Process", player));
Vector3 playerPosition = player.transform.position;
TimerHandler timerHandler = new TimerHandler(this,
player,
DoorActions.CreatingTelePoint,
0.1f,
SetTelePoint(player, playerPosition)
);
}
[ChatCommand("setcategory")]
private void SetCategoryCommand(BasePlayer player, string command, string[] args)
{
if (!HasPermissions(player, SetCategoryPerm))
{
player.ChatMessage(GetMessage("Insufficient Permissions", player));
return;
}
if (TimerHandler.HasTimer(player) &&
TimerHandler.GetTimer(player).Action == DoorActions.SettingDoorCategory)
{
player.ChatMessage(GetMessage("Exited Process", player));
TimerHandler.RemoveTimer(player);
return;
}
if (args.Length < 1)
{
string syntax = GetMessage("Set Category Syntax", player);
player.ChatMessage(GetMessage("Invalid Syntax", player, syntax));
return;
}
CategoryObject category = TryGetCategory(player, args[0]);
if (category == null) return;
TimerHandler.RemoveTimer(player);
player.ChatMessage(GetMessage("Entered Set Category Process", player));
TimerHandler timerHandler = new TimerHandler(this,
player,
DoorActions.SettingDoorCategory,
0.1f,
SetCategory(player, category)
);
}
[ChatCommand("setcategoryname")]
private void SetCategoryNameCommand(BasePlayer player, string command, string[] args)
{
if (!HasPermissions(player, SetCategoryNamePerm))
{
player.ChatMessage(GetMessage("Insufficient Permissions", player));
return;
}
if (args.Length < 2)
{
string syntax = GetMessage("Set Category Name Syntax", player);
player.ChatMessage(GetMessage("Invalid Syntax", player, syntax));
return;
}
CategoryObject category = TryGetCategory(player, args[0]);
if (category == null) return;
List<string> nameArgs = args.ToList();
nameArgs.Remove(args[0]);
string newName = string.Join(" ", nameArgs);
if (category.Name.Equals(newName))
{
player.ChatMessage(GetMessage("Category Already Has Name", player));
return;
}
category.Name = newName;
category.Save(this);
player.ChatMessage(GetMessage("Set Category Name", player, newName));
}
[ChatCommand("addcategoryperm")]
private void AddCategoryPermCommand(BasePlayer player, string command, string[] args)
{
if (!HasPermissions(player, AddCategoryPermPerm))
{
player.ChatMessage(GetMessage("Insufficient Permissions", player));
return;
}
if (args.Length < 2)
{
string syntax = GetMessage("Add Category Perm Syntax", player, DoorPermPrefix);
player.ChatMessage(GetMessage("Invalid Syntax", player, syntax));
return;
}
CategoryObject category = TryGetCategory(player, args[0]);
if (category == null) return;
List<string> permissions = category.Permissions;
List<string> newPerms = args.ToList();
newPerms.Remove(args[0]);
newPerms = newPerms.Select(str => (DoorPermPrefix + str).ToLower()).ToList();
newPerms.RemoveAll(perm =>
{
if (!permissions.Contains(perm)) return false;
player.ChatMessage(GetMessage("Category Already Locked", player, perm));
return true;
});
if (newPerms.Count == 0) return;
permissions.AddRange(newPerms);
UpdateCategoryPermissions(category, permissions.ToArray());
player.ChatMessage(GetMessage("Category Locked New Permissions", player, string.Join(", ", newPerms)));
}
[ChatCommand("removecategoryperm")]
private void RemoveCategoryPermCommand(BasePlayer player, string command, string[] args)
{
if (!HasPermissions(player, RemoveCategoryPermPerm))
{
player.ChatMessage(GetMessage("Insufficient Permissions", player));
return;
}
if (args.Length < 2)
{
string syntax = GetMessage("Remove Category Perm Syntax", player, DoorPermPrefix);
player.ChatMessage(GetMessage("Invalid Syntax", player, syntax));
return;
}
CategoryObject category = TryGetCategory(player, args[0]);
if (category == null) return;
List<string> permissions = category.Permissions;
List<string> removePerms = args.ToList();
removePerms.Remove(args[0]);
removePerms = removePerms.Select(str => (DoorPermPrefix + str).ToLower()).ToList();
removePerms.RemoveAll(perm =>
{
if (permissions.Contains(perm)) return false;
player.ChatMessage(GetMessage("Category Is Not Locked To That Permission", player, perm));
return true;
});
if (removePerms.Count == 0) return;
permissions.RemoveAll(perm => removePerms.Contains((perm)));
UpdateCategoryPermissions(category, permissions.ToArray());
player.ChatMessage(GetMessage("Category Unlocked", player, string.Join(", ", removePerms)));
}
[ChatCommand("createcategory")]
private void CreateCategoryCommand(BasePlayer player, string command, string[] args)
{
if (!HasPermissions(player, CreateCategoryPerm))
{
player.ChatMessage(GetMessage("Insufficient Permissions", player));
return;
}
if (args.Length < 1)
{
string syntax = GetMessage("Create Category Syntax", player, DoorPermPrefix);
player.ChatMessage(GetMessage("Invalid Syntax", player, syntax));
return;
}
string catName = args[0];
List<string> catPerms = args.ToList();
catPerms.Remove(catName);
catPerms = catPerms.Select(str => (DoorPermPrefix + str).ToLower()).ToList();
CategoryObject newCategory = new CategoryObject
{
Id = CategoryObject.GetNewCategoryId(),
Name = catName,
Permissions = catPerms
};
RegisterPermissions(catPerms.ToArray());
// Save method adds category to cache automatically
newCategory.Save(this);
player.ChatMessage(GetMessage("Category Created", player, catName));
}
[ChatCommand("deletecategory")]
private void DeleteCategoryCommand(BasePlayer player, string command, string[] args)
{
if (!HasPermissions(player, DeleteCategoryPerm))
{
player.ChatMessage(GetMessage("Insufficient Permissions", player));
return;
}
if (args.Length < 1)
{
string syntax = GetMessage("Delete Category Syntax", player);
player.ChatMessage(GetMessage("Invalid Syntax", player, syntax));
return;
}
CategoryObject category = TryGetCategory(player, args[0]);
if (category == null) return;
if (category.Id == 0)
{
player.ChatMessage(GetMessage("Can Not Delete Default Category", player));
return;
}
if (!_configData.ShouldDeleteDoors)
{
// 0 is default category
category.MoveAllDoors(this, 0);
}
CategoryObject.DeleteCategory(this, category.Id);
player.ChatMessage(GetMessage("Category Deleted", player, args[0]));
}
[ChatCommand("viewcategoryinfo")]
private void ViewCategoryInfoCommand(BasePlayer player, string command, string[] args)
{
if (!HasPermissions(player, DeleteCategoryPerm))
{
player.ChatMessage(GetMessage("Insufficient Permissions", player));
return;
}
if (args.Length < 1)
{
string syntax = GetMessage("View Category Info Syntax", player);
player.ChatMessage(GetMessage("Invalid Syntax", player, syntax));
return;
}
CategoryObject category = TryGetCategory(player, args[0]);
if (category == null) return;
string catName = category.Name;
string catPerms = string.Join(", ", category.Permissions);
player.ChatMessage(GetMessage("View Category Info Format", player, catName, args[0], catPerms));
}
[ChatCommand("viewcategories")]
private void ViewCategoriesCommand(BasePlayer player, string command, string[] args)
{
if (!HasPermissions(player, ViewCategoriesPerm))
{
player.ChatMessage(GetMessage("Insufficient Permissions", player));
return;
}
StringBuilder stringBuilder = new StringBuilder();
CategoryObject.GetCategories().ForEach(category =>
{
int catId = category.Id;
string catName = category.Name;
string format = GetMessage("View Categories Format", player, catId, catName);
stringBuilder.Append(format);
});
player.ChatMessage(stringBuilder.Length == 0
? GetMessage("No Categories Found", player)
: stringBuilder.ToString());
}
#endregion
#region Door Logic
private Action LockDoor(BasePlayer player, string[] args)
{
return () =>
{
if (!player.serverInput.IsDown(SelectDoorButton)) return;
Door door = RetrieveDoorEntity(player);
if (door == null) return;
Vector3 doorPosition = door.transform.position;
List<string> newPerms = args.ToList();
DoorObject doorData = DoorObject.GetDoorByLocation(doorPosition);
if (doorData != null)
{
List<string> currentPermissionList = doorData.GetAllPermissions();
newPerms.RemoveAll(perm =>
{
if (!currentPermissionList.Contains(perm)) return false;
player.ChatMessage(GetMessage("Door Already Locked", player, perm));
return true;
});
if (newPerms.Count == 0) return;
currentPermissionList.AddRange(newPerms);
UpdateDoorPermissions(doorData, currentPermissionList.ToArray());
string joinedPerms = string.Join(", ", newPerms);
player.ChatMessage(GetMessage("Door Locked New Permissions", player, joinedPerms));
TimerHandler.RemoveTimer(player);
return;
}
doorData = new DoorObject
{
Name = "Unknown",
Position = doorPosition,
Permissions = newPerms,
Category = CategoryObject.GetCategoryById(0)
};
RegisterPermissions(args);
if (!PutLockOnDoor(door, player))
{
TimerHandler.RemoveTimer(player);
return;
}
DoorObject.AddDoors(doorData);
doorData.UpdateDoor(this);
string permStr = string.Join(", ", newPerms);
player.ChatMessage(GetMessage("Door Locked", player, permStr));
TimerHandler.RemoveTimer(player);
};
}
private Action UnlockDoor(BasePlayer player, string[] args)
{
return () =>
{
if (!player.serverInput.IsDown(SelectDoorButton)) return;
Door door = RetrieveDoorEntity(player);
if (door == null) return;
Vector3 doorPosition = door.transform.position;
List<string> unlockPerms = args.ToList();
DoorObject doorData = DoorObject.GetDoorByLocation(doorPosition);
if (doorData == null)
{
player.ChatMessage(GetMessage("Door Not Locked", player));
TimerHandler.RemoveTimer(player);
return;
}
List<string> newDoorPerms = doorData.Permissions;
// New list to stop aliasing
List<string> preserveDoorPerms = new List<string>(doorData.Permissions);
unlockPerms.RemoveAll(perm =>
{
if (newDoorPerms.Contains(perm)) return false;
string msg = doorData.Category.Permissions.Contains(perm)
? "Locked To Category Not Door"
: "Door Is Not Locked To That Permission";
player.ChatMessage(GetMessage(msg, player, perm));
return true;
});
newDoorPerms.RemoveAll(perm => unlockPerms.Contains(perm));
bool killEntity = unlockPerms.Count == 0 ||
(newDoorPerms.Count == 0 && doorData.Category.Permissions.Count == 0);
if (killEntity)
{
RemoveLockOnDoor(door);
doorData.DeleteDoor(this);
}
else
{
UpdateDoorPermissions(doorData, newDoorPerms.ToArray());
}
List<string> permList = killEntity ? preserveDoorPerms : unlockPerms;
player.ChatMessage(GetMessage("Door Unlocked", player, string.Join(", ", permList)));
TimerHandler.RemoveTimer(player);
};
}
private Action ActivateDoor(BasePlayer player)
{
return () =>
{
if (!player.serverInput.IsDown(SelectDoorButton)) return;
Door door = RetrieveDoorEntity(player);
if (door == null) return;
Vector3 doorPosition = door.transform.position;
DoorObject doorData = DoorObject.GetDoorByLocation(doorPosition);
if (doorData == null)
{
player.ChatMessage(GetMessage("Door Not Locked", player));
TimerHandler.RemoveTimer(player);
return;
}
if (doorData.IsActive)
{
player.ChatMessage(GetMessage("Door Already Activated", player));
TimerHandler.RemoveTimer(player);
return;
}
if (!PutLockOnDoor(door, player))
{
TimerHandler.RemoveTimer(player);
return;
}
player.ChatMessage(GetMessage("Door Activated", player));
doorData.IsActive = true;
doorData.UpdateDoor(this);
TimerHandler.RemoveTimer(player);
};
}
private Action DeactivateDoor(BasePlayer player)
{
return () =>
{
if (!player.serverInput.IsDown(SelectDoorButton)) return;
Door door = RetrieveDoorEntity(player);
if (door == null) return;
Vector3 doorPosition = door.transform.position;
DoorObject doorData = DoorObject.GetDoorByLocation(doorPosition);
if (doorData == null)
{
player.ChatMessage(GetMessage("Door Not Locked", player));
TimerHandler.RemoveTimer(player);
return;
}
if (!doorData.IsActive)
{
player.ChatMessage(GetMessage("Door Already Deactivated", player));
TimerHandler.RemoveTimer(player);
return;
}
RemoveLockOnDoor(door);
player.ChatMessage(GetMessage("Door Deactivated", player));
doorData.IsActive = false;
doorData.UpdateDoor(this);
TimerHandler.RemoveTimer(player);
};
}
private Action ViewDoorInfo(BasePlayer player)
{
return () =>
{
if (!player.serverInput.IsDown(SelectDoorButton)) return;
Door door = RetrieveDoorEntity(player);
if (door == null) return;
Vector3 doorPosition = door.transform.position;
DoorObject doorData = DoorObject.GetDoorByLocation(doorPosition);
if (doorData == null)
{
player.ChatMessage(GetMessage("Door Not Locked", player));
TimerHandler.RemoveTimer(player);
return;
}
string name = doorData.Name;
int catId = doorData.CategoryId;
bool active = doorData.IsActive;
List<string> permList = doorData.Permissions;
string formattedPerms = string.Join(", ", permList);
string message = GetMessage("View Door Info Format", player, name, catId, active, formattedPerms);
player.ChatMessage(message);
TimerHandler.RemoveTimer(player);
};
}
private Action SetDoorName(BasePlayer player, string newName)
{
return () =>
{
if (!player.serverInput.IsDown(SelectDoorButton)) return;
Door door = RetrieveDoorEntity(player);
if (door == null) return;
Vector3 doorPosition = door.transform.position;
DoorObject doorData = DoorObject.GetDoorByLocation(doorPosition);
if (doorData == null)
{
player.ChatMessage(GetMessage("Door Not Locked", player));
TimerHandler.RemoveTimer(player);
return;
}
if (doorData.Name.Equals(newName))
{
player.ChatMessage(GetMessage("Door Already Has Name", player));
// ... [Code preview truncated due to length. Full source in attached file] ...