C#:
using Newtonsoft.Json;
using Oxide.Core.Plugins;
using System;
using System.Collections.Generic;
using UnityEngine;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Libraries;
using Oxide.Core;
using Oxide.Core.Configuration;
using Oxide.Game.Rust.Cui;
using Network;
namespace Oxide.Plugins {
[Info("Monument Lock", "Rustonauts", "1.9.6")]
[Description("Locks down monuments for players and teams who arrive first, and may broadcast it via chat.")]
class MonumentLock : RustPlugin {
[PluginReference]
private Plugin PuzzlePoints, MonumentFinder, ImageLibrary;
ThePermissions Perms;
#region Fields
private List<Dictionary<string, object>> _monumentsFinder;
private Dictionary<string, Timer> timers = new Dictionary<string, Timer>();
public List<MapMarkerGenericRadius> LockedMarkers = new List<MapMarkerGenericRadius>();
private Configuration _config;
private StoredData storedData;
//private MUI mui = new MUI();
private string api_hook = "";
//placing timer text on map
private Vector3 _monumentPos;
private Timer _timer;
private float _timeLeft = 600;
private const string _RED_KEYCARD = "keycard_red";
#endregion
#region Init
private void Init() {
Perms = new ThePermissions(this);
LoadData();
// Initialize the pool with 10 objects
ObjectPool<MSession>.Initialize(8);
//LoadImages();
// foreach (var player in BasePlayer.activePlayerList)
// {
// TopRightCornerCui(player);
// MenuButtonCui(player);
// }
// foreach(BasePlayer _player in BasePlayer.activePlayerList) {
// mui.Init(_player, Perms);
// timer.Every(60f, () => mui.Refresh(_player));
// }
}
private void OnPlayerConnected(BasePlayer player) {
if (player == null) return;
//mui.Init(player, Perms);
}
#endregion
#region Oxide Hooks
// void OnEntitySpawned(BaseNetworkable entity)
// {
// Puts("OnEntitySpawned works!");
// }
void OnDestroyUI(BasePlayer player, string json) {
//Puts($".. destroy ui: {json}");
}
object CanUseUI(BasePlayer player, string json) {
//Puts($"..add UI: {json}");
return null;
}
object OnPlayerDeath(BasePlayer player, HitInfo info) {
//if not configed to unlock, abort
if (!_config.unlock_on_death) return null;
//sessions
foreach (MSession _session in new List<MSession>(storedData.m_sessions)) {
//if on a team
if (player.currentTeam != 0) {
//if player has an actively locked monument
if (player.currentTeam.ToString() == _session.GetTeamId()) {
//iterate through active players
foreach (BasePlayer activePlayer in new List<BasePlayer>(BasePlayer.activePlayerList)) {
if (activePlayer.UserIDString != player.UserIDString && activePlayer.currentTeam.ToString() == _session.GetTeamId()) {
//if no other teammate is in the monument, then unlock
var dictClosestMonument = MonumentFinder?.Call("API_GetClosestMonument", activePlayer.ServerPosition) as Dictionary<string, object>;
if (_session.SessionMonument.shortName == dictClosestMonument["ShortName"].ToString()) return null;
}
}
UnlockMonument(player, _session);
return null;
}
}
//solo
if (_session.player_id == player.UserIDString) UnlockMonument(player, _session);
}
return null;
}
private object OnPPSwipe(BasePlayer player, string cardType, CardReader cardReader, string monumentName, string gridPosition) {
api_hook = "card_swipe";
//guards
if (!Perms.CanUse(player)) return null;
if (!MonumentEnabled(player)) return null;
//can't swipe card
if (!LockCheck(player, "swipe")) return false;
// PrintToChat($"{GetLang("CardSwipedAt", player.UserIDString, player.displayName, cardType, GetDisplayName(monumentName), gridPosition)}");
BroadcastToChat("CardSwipedAt", player.displayName, cardType, GetDisplayName(monumentName), gridPosition);
return null;
}
object OnItemPickup(Item item, BasePlayer player) {
api_hook = "item_pickup";
//guards
if (!MonumentEnabled(player)) return null;
if (!Perms.CanUse(player)) return null;
if (!LockCheck(player, item.info.category.ToString())) return false;
return null;
}
object CanMoveItem(Item item, PlayerInventory playerLoot = null, uint targetContainer = 0, int targetSlot = 0, int amount = 0) {
api_hook = "move_item";
// //guards
BasePlayer player = playerLoot.loot.GetComponent<BasePlayer>();
if (!MonumentEnabled(player)) return null;
if (!Perms.CanUse(player)) return null;
if (!LockCheck(player, item.info.category.ToString())) return false;
return null;
}
void OnLootEntity(BasePlayer player, BaseEntity entity = null) {
api_hook = "loot_entity";
if (MonumentEnabled(player) && Perms.CanUse(player)) LockCheck(player, entity.ShortPrefabName);
}
object CanLootEntity(BasePlayer _player, DroppedItemContainer container) {
api_hook = "loot_entity";
if (!Perms.CanUse(_player)) return null;
if (!MonumentEnabled(_player)) return null;
if (!LockCheck(_player, container.ShortPrefabName)) return false;
return null;
}
object CanHackCrate(BasePlayer player, HackableLockedCrate crate = null) {
api_hook = "hack_crate";
//guards
if (!MonumentEnabled(player)) return null;
if (!Perms.CanUse(player)) return null;
if (!LockCheck(player, "locked_crate")) return false;
return null;
}
object OnPlayerAttack(BasePlayer attacker, HitInfo info = null) {
api_hook = "player_attack";
if (!Perms.CanUse(attacker)) return null;
if (!MonumentEnabled(attacker)) return null;
if (!LockCheck(attacker, "attack")) return false;
return null;
}
#endregion
#region MonumentLock Hooks API
private void OnImportFailed() {
Puts("-- Failed to import monuments..");
}
private void NoPermissions(BasePlayer player, string perm) {
player.ChatMessage(GetLang("NoPerms", player.UserIDString));
}
private object OnTeamHasActiveSession(BasePlayer player) {
player.ChatMessage(GetLang("TeamAlreadyLocked", player.UserIDString));
return true;
}
private object OnMonumentLocked(BasePlayer player, string displayName, string gridPosition) {
Puts($"{GetLang("MonumentLocked", null, player.displayName, displayName, gridPosition)}");
BroadcastToChat("MonumentLocked", player.displayName, displayName, gridPosition);
RemoveMapMarkers();
LoadMapMarkers();
// foreach (var player1 in BasePlayer.activePlayerList)
// {
// NotificationCui(player1, $"{displayName} has been locked by {player.displayName}");
// }
return null;
}
private object OnMonumentUnlocked(BasePlayer player, string displayName, string gridPosition) {
BroadcastToChat("MonumentUnlocked", displayName, gridPosition);
RemoveMapMarkers();
LoadMapMarkers();
// foreach (var player1 in BasePlayer.activePlayerList)
// {
// NotificationCui(player1, $"{displayName} is unlocked!");
// }
return null;
}
private object OnAccessDenied(BasePlayer player, string seconds, BasePlayer lockedPlayer) {
SendReply(player, GetLang("MonumentIsLocked", player.UserIDString, lockedPlayer.displayName, seconds));
return null;
}
private object OnAccessGranted(BasePlayer player, string shortName, string gridPosition) {
// UpdateLockTimer(shortName);
return null;
}
#endregion API_MonumentLock_Hooks
#region Chat
[ChatCommand("mu")]
private void mu(BasePlayer player, string command, string[] args) {
UnlockMonument(player);
}
[ChatCommand("mlock")]
private void mlock(BasePlayer player, string command, string[] args) {
//guards
if (!Perms.CanUse(player) && !Perms.CanCommands(player)) return;
//user typed /mlock
if (args.Length < 1) {
//launch ui
//if(Perms.CanUiView(player)) mui.Toggle(player);
}
//user typed /mlock <something>
else if (args.Length == 1) {
if (args[0] == "list") {
MonumentsListReply(player);
}
else if (args[0] == "clear") {
if (!Perms.IsAdmin(player)) return;
storedData.m_sessions.Clear();
RemoveMapMarkers(true);
}
else if (args[0] == "unlock") {
//player type /mlock unlock in chat to unlock a monument
UnlockMonument(player);
}
//user typed /mlock <monument name>
else {
if (MonumentEnabled(player, args[0])) {
if (!LockCheck(player, "chat", args[0])) {
SendReply(player, GetLang("MonumentAlreadyLocked"));
}
}
else {
SendReply(player, GetLang("MonumentNotValid"));
MonumentsListReply(player);
}
}
}
//admin locking monument for a player /mlock <monument name> <player>
else if (args.Length == 2) {
//guard
if (!Perms.IsAdmin(player)) return;
//2nd argument is player_name
string locked_playerName = args[1];
BasePlayer locked_player = BasePlayer.FindAwakeOrSleeping(locked_playerName);
if (MonumentEnabled(player, args[0])) {
if (!LockCheck(locked_player, "chat", args[0])) {
//SendReply(player, GetLang("MonumentAlreadyLocked"));
}
}
else {
SendReply(player, GetLang("MonumentNotValid"));
MonumentsListReply(player);
}
}
}
#endregion
#region Console
[ConsoleCommand("mlock.mem")]
private void mem(ConsoleSystem.Arg arg) {
PrintMemoryUsage();
}
[ConsoleCommand("mu")]
private void mU(ConsoleSystem.Arg arg) {
BasePlayer player = arg.Player();
if (player == null) return;
UnlockMonument(player);
//mui.Toggle(player, arg.Args[0]);
}
[ConsoleCommand("mlock")]
private void mLock(ConsoleSystem.Arg arg) {
BasePlayer player = arg.Player();
if (!LockCheck(player, "chat", arg.GetString(0))) {
// Patch by Death
SendReply(player, GetLang("MonumentAlreadyLocked"));
}
//mui.Toggle(player, arg.Args[0]);
}
[ConsoleCommand("mui.toggle")]
private void mToggle(ConsoleSystem.Arg arg) {
BasePlayer player = arg.Player();
if (player == null) return;
//mui.Toggle(player);
}
[ConsoleCommand("mui.refresh")]
private void MuiRefresh(ConsoleSystem.Arg arg) {
BasePlayer player = arg.Player();
// mui.Show(player, ref storedData, ref _config);
}
[ConsoleCommand("mui.config")]
private void MuiConfig(ConsoleSystem.Arg arg) {
BasePlayer player = arg.Player();
// mui.ShowConfig(player, ref storedData, ref _config);
}
[ConsoleCommand("mui.config.hardtimer")]
private void MuiConfigHardtimer(ConsoleSystem.Arg arg) {
BasePlayer player = arg.Player();
if (player == null) return;
_config.hard_timer = !_config.hard_timer;
SaveConfig();
player.SendConsoleCommand("mui.config");
player.SendConsoleCommand("mui.config");
}
[ConsoleCommand("mui.config.maxtimer")]
private void MuiConfigMaxtimer(ConsoleSystem.Arg arg) {
BasePlayer player = arg.Player();
if (player == null) return;
_config.enable_max_timer = !_config.enable_max_timer;
SaveConfig();
player.SendConsoleCommand("mui.config");
player.SendConsoleCommand("mui.config");
}
[ConsoleCommand("mui.closeall")]
void CloseAllMUI(ConsoleSystem.Arg args) {
// MUI.CloseAll();
}
[ConsoleCommand("mui.sync")]
private void SyncMonuments(ConsoleSystem.Arg arg) {
ImportMonuments();
BasePlayer _player = arg.Player();
if (_player == null) return;
// mui.SyncMonuments(_player);
}
[ConsoleCommand("mlock.import")]
void ImportMonuments(ConsoleSystem.Arg args) {
ImportMonuments();
Puts($"{GetLang("MonumentsImported", null)}");
}
[ConsoleCommand("mlock.default")]
void DefaultMonuments(ConsoleSystem.Arg args) {
_config.Monuments.Clear();
SaveConfig();
DefaultMonuments();
Puts($"{GetLang("MonumentsDefaulted", null)}");
}
[ConsoleCommand("mlock.fresh")]
void FreshMonuments(ConsoleSystem.Arg args) {
_config.Monuments.Clear();
DefaultMonuments();
ImportMonuments();
Puts($"{GetLang("MonumentsImported", null)}");
}
[ConsoleCommand("mlock.remove")]
void ClearMonuments(ConsoleSystem.Arg args) {
_config.Monuments.Clear();
SaveConfig();
Puts($"{GetLang("MonumentsRemoved", null)}");
}
#endregion Commands
#region Pooling
private void PrintMemoryUsage() {
// Force garbage collection for accurate measurement
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
// Get total memory in bytes
long memoryUsageByes = GC.GetTotalMemory(false);
double memoryUsageMB = memoryUsageByes / (1024.0 * 1024.0);
Puts($"memory usage: {memoryUsageMB:F2} MB");
}
public static class ObjectPool<T> where T : class, new() {
private static readonly Stack<T> _pool = new Stack<T>();
// Pre-populate the pool with a specified number of objects
public static void Initialize(int initialSize) {
for (int i = 0; i < initialSize; i++) {
_pool.Push(new T());
}
}
public static T Get() {
return _pool.Count > 0 ? _pool.Pop() : new T();
}
public static void Free(ref T obj) {
if (obj == null) return;
_pool.Push(obj);
obj = null;
}
}
public interface IPooled {
void ResetToPool();
}
#endregion
#region Core
private MSession GetSession(BasePlayer player) {
foreach (MSession _session in storedData.m_sessions) {
//is player the monument owner
if (_session.GetPlayerId() == player.UserIDString) {
return _session;
}
//no?
else {
//is the player on the team of the monument owner?
if ((player.currentTeam > 0) && (_session.GetTeamId() == player.currentTeam.ToString())) {
return _session;
}
}
}
return null;
}
private string FindMonumentShortName(BasePlayer _player, string _shortNameFromCommand) {
if (_shortNameFromCommand != null) return _shortNameFromCommand;
//check monuments
var dictMonument = IsInMonument(_player);
if (dictMonument != null) return dictMonument["ShortName"].ToString();
//check if we're in cargo
foreach (var entity in BaseNetworkable.serverEntities) {
if (entity is CargoShip) {
var cargo = (entity as CargoShip);
if (Vector3.Distance(cargo.transform.position, _player.transform.position) < 100) return "cargo_ship";
}
}
return null;
}
private bool IsSessionActive(BasePlayer _player, MSession _session) {
if (!_session.IsActive()) {
UnlockMonument(_player, _session);
SaveData();
return false;
}
SaveData();
return true;
}
private bool LockCheck(BasePlayer player, string loot = "", string _shortNameFromCommand = null) {
var _shortName = FindMonumentShortName(player, _shortNameFromCommand);
var is_locked = false;
if (_shortNameFromCommand == null && _shortName == null) return true;
//player isn't in monument
foreach (MSession _session in storedData.m_sessions) {
if (_session.SessionMonument.shortName == _shortName) {
if (IsSessionActive(player, _session)) {
is_locked = true;
SaveData();
//active session found
if (!_session.IsLockedToMyTeam(player)) {
//if cancel_cards global is turned off, stop here and grant access to swiping
if (loot == "swipe" && !_config.cancel_cards && !_session.IsCancelCards()) return true;
//if lock_attack global is turned off, stop here and grant access to attacking
if (loot == "attack" && !_config.lock_attack && !_session.IsLockAttack()) return true;
//if lock_crate_hacking global is turned off, stop here and grant access to crate hacking
if (loot == "locked_crate" && !_config.lock_crate_hacking && !_session.IsLockedCrate()) return true;
//if food crate
if (loot == "trash-pile-1" || loot == "food") return true;
//if lock_looting monument is turned off, stop here and grant access to looting
if (!_config.lock_looting && !_session.IsLockLooting()) return true;
return false;
}
//it is locked to my team
Interface.Call("OnAccessGranted", player, _shortName, GetGridPosition(player.ServerPosition));
return true;
}
return LockMonument(_shortName, player, GetGridPosition(player.ServerPosition));
}
}
//monument not in an active sessions, lock monument and create session
return LockMonument(_shortName, player, GetGridPosition(player.ServerPosition));
;
}
private Dictionary<string, object> IsInMonument(BasePlayer player) {
var dictClosestMonument = MonumentFinder?.Call("API_GetClosestMonument", player.ServerPosition) as Dictionary<string, object>;
if (dictClosestMonument != null) {
var IsInBounds = ((Func<Vector3, bool>)dictClosestMonument["IsInBounds"]).Invoke(player.ServerPosition);
if (IsInBounds && MonumentInConfig(dictClosestMonument["ShortName"].ToString())) return dictClosestMonument;
}
//clean up all locked monuments for this player, if no active session. but if there is, cannot unlock
MyTeamHasActiveSession(player);
return null;
}
private bool MonumentInConfig(string _shortName) {
foreach (Monument _monument in _config.Monuments) {
if (_monument.shortName == _shortName) return true;
}
return false;
}
private void UnlockMonument(BasePlayer player, MSession _expired_session = null) {
bool unlocked = false;
MSession unlockedSession = _expired_session ?? GetSession(player);
//find my team session
// if(unlockedSession == null) unlockedSession = GetSession(player);
if (unlockedSession != null) {
unlocked = true;
// Cancel the timer if it exists
unlockedSession.UnlockTimer?.Destroy();
unlockedSession.UnlockTimer = null;
}
//if the config hard timer is true and monument.hard_timer is true, and is active then don't unlock
if (_config.hard_timer && unlockedSession.SessionMonument.hard_timer && unlockedSession.IsActive()) unlocked = false;
//if the player or team has a locked monument
if (unlocked) {
storedData.m_sessions.Remove(unlockedSession);
SaveData();
Interface.Call("OnMonumentUnlocked", player, unlockedSession.SessionMonument.displayName, GetGridPosition(player.ServerPosition));
ObjectPool<MSession>.Free(ref unlockedSession);
}
return;
}
private bool LockMonument(string shortName, BasePlayer player, string gridPosition) {
if (MyTeamHasActiveSession(player)) {
if (Interface.Call("OnTeamHasActiveSession", player) != null) {
return false;
}
}
//does the current player action allow for locking a monument
if (!CanActionLock()) return false;
//get monuments from config
foreach (Monument _monument in _config.Monuments) {
//find the monument in _config by short name
if (_monument.shortName == shortName) {
if (Interface.Call("CanMonumentLock", player, _monument.displayName, gridPosition) != null) {
return false;
}
// MSession _mSession = Facepunch.Pool.Pool.Get<MSession>().Initialize(player.UserIDString, _monument);
MSession _mSession = ObjectPool<MSession>.Get().Initialize(player.UserIDString, _monument);
storedData.m_sessions.Add(_mSession);
SaveData();
if (_config.hard_timer || _monument.hard_timer) {
_mSession.UnlockTimer = timer.Once(_monument.lock_timer, () => {
LockCheck(player);
}
);
}
if (Interface.Call("OnMonumentLocked", player, _monument.displayName, gridPosition) != null) {
return false;
}
return true;
}
}
return false;
}
#endregion Core
#region External Plugins API
private List<Dictionary<string, object>> GetMonuments(string filter = null) {
if (UseMonumentFinder()) return MonumentFinder.Call("API_FindMonuments", filter) as List<Dictionary<string, object>>;
return null;
}
#endregion
#region Configuration
private void DisableMonuments() {
//make config monuments disabled
foreach (Monument _monument in _config.Monuments) {
if (_monument.shortName != "cargo_ship") {
_monument.enabled = false;
_monument.is_online = false;
}
}
SaveConfig();
}
private void ImportMonuments() {
//enabled should never be adjusted, it's how the plugin knows if the monument is on the map
//is_online is a dynamic state, and admins/other plugins can adjust it
_monumentsFinder = GetMonuments();
if (_monumentsFinder == null) Interface.Call("OnImportFailed");
if (_monumentsFinder == null) return;
DisableMonuments();
//iteration through the monuments from Monument Finder
foreach (Dictionary<string, object> _monument in _monumentsFinder) {
bool import_monument = true;
//ignore monuments from the exceptions list (in config file)
foreach (string _exception in _config.Exceptions) {
if (_exception == _monument["ShortName"].ToString()) {
import_monument = false;
}
}
//updating existing monuments
foreach (Monument _configMonument in _config.Monuments) {
if (_configMonument.shortName == _monument["ShortName"].ToString() && _configMonument.shortName != "cargo_ship") {
_configMonument.enabled = true;
_configMonument.is_online = true;
_configMonument.gridPos = GetGridPosition((Vector3)_monument["Position"]);
_configMonument.prefabName = _monument["PrefabName"].ToString();
//do something around the icon
import_monument = false;
}
}
//importing new monuments
if (import_monument) {
_config.Monuments.Add(new Monument(new MonumentSettings {
enabled = true, is_online = true, prefabName = _monument["PrefabName"].ToString(), shortName = _monument["ShortName"].ToString(), displayName = _monument["ShortName"].ToString(), gridPos = GetGridPosition((Vector3)_monument["Position"]), lock_attack = true, lock_crate_hacking = true, lock_timer = 600, lock_looting = true, cancel_cards = true, enable_broadcasting = true, icon = "" //do something to import
}
));
}
}
SaveConfig();
}
private void DefaultMonuments() {
_config.Monuments.Add(new Monument(new MonumentSettings {
enabled = true, prefabName = "", shortName = "cargo_ship", displayName = "Cargo Ship", gridPos = "", lock_attack = true, lock_crate_hacking = true, lock_timer = 1500, hard_timer = false, lock_looting = true, cancel_cards = true, enable_broadcasting = true, icon = ""
}
));
_config.Monuments.Add(new Monument(new MonumentSettings {
enabled = true, prefabName = "assets/bundled/prefabs/autospawn/monument/harbor/harbor_1.prefab", shortName = "harbor_1", displayName = "Large Harbor", gridPos = "", lock_attack = true, lock_crate_hacking = true, lock_timer = 600, hard_timer = false, lock_looting = true, cancel_cards = true, enable_broadcasting = true, icon = "https://i.imgur.com/ND4c70v.png"
}
));
_config.Monuments.Add(new Monument(new MonumentSettings {
enabled = true, prefabName = "assets/bundled/prefabs/autospawn/monument/harbor/harbor_2.prefab", shortName = "harbor_2", displayName = "Small Harbor", gridPos = "", lock_looting = true, lock_attack = true, lock_crate_hacking = true, lock_timer = 600, hard_timer = false, cancel_cards = true, enable_broadcasting = true, icon = "https://i.imgur.com/ND4c70v.png"
}
));
_config.Monuments.Add(new Monument(new MonumentSettings {
enabled = true, prefabName = "assets/bundled/prefabs/autospawn/monument/arctic_bases/arctic_research_base_a.prefab", shortName = "arctic_research_base_a", displayName = "Arctic Research Base", gridPos = "", lock_attack = true, lock_crate_hacking = true, lock_timer = 600, hard_timer = false, lock_looting = true, cancel_cards = true, enable_broadcasting = true, icon = ""
}
));
_config.Monuments.Add(new Monument(new MonumentSettings {
enabled = true, prefabName = "assets/bundled/prefabs/autospawn/monument/large/military_tunnel_1.prefab", shortName = "military_tunnel_1", displayName = "Military Tunnel", gridPos = "", lock_attack = true, lock_crate_hacking = true, lock_timer = 600, hard_timer = false, lock_looting = true, cancel_cards = true, enable_broadcasting = true, icon = "https://i.imgur.com/6RwXvC2.png"
}
));
_config.Monuments.Add(new Monument(new MonumentSettings {
enabled = true, prefabName = "assets/bundled/prefabs/autospawn/monument/large/powerplant_1.prefab", shortName = "powerplant_1", displayName = "Power Plant", gridPos = "", lock_attack = true, lock_crate_hacking = true, lock_timer = 600, hard_timer = false, lock_looting = true, cancel_cards = true, enable_broadcasting = true, icon = "https://i.imgur.com/ZxqiBc6.png"
}
));
_config.Monuments.Add(new Monument(new MonumentSettings {
enabled = true, prefabName = "assets/bundled/prefabs/autospawn/monument/small/sphere_tank.prefab", shortName = "sphere_tank", displayName = "Dome", gridPos = "", lock_attack = true, lock_crate_hacking = true, lock_timer = 600, hard_timer = false, lock_looting = true, cancel_cards = true, enable_broadcasting = true, icon = "https://i.imgur.com/mPRgBF2.png"
}
));
_config.Monuments.Add(new Monument(new MonumentSettings {
enabled = true, prefabName = "oilrig_1", shortName = "oilrig_1", displayName = "Large Oil", gridPos = "", lock_attack = true, lock_crate_hacking = true, lock_timer = 600, hard_timer = false, lock_looting = true, cancel_cards = true, enable_broadcasting = true, icon = "https://i.imgur.com/AAhZO7k.png"
}
));
_config.Monuments.Add(new Monument(new MonumentSettings {
enabled = true, prefabName = "radtown_1", shortName = "radtown_1", displayName = "Radtown", gridPos = "", lock_attack = true, lock_crate_hacking = true, lock_timer = 600, hard_timer = false, lock_looting = true, cancel_cards = true, enable_broadcasting = true, icon = "https://i.imgur.com/AAhZO7k.png"
}
));
_config.Monuments.Add(new Monument(new MonumentSettings {
enabled = true, prefabName = "oilrig_2", shortName = "oilrig_2", displayName = "Small Oil", gridPos = "", lock_attack = true, lock_crate_hacking = true, lock_timer = 600, hard_timer = false, lock_looting = true, cancel_cards = true, enable_broadcasting = true, icon = "https://i.imgur.com/AAhZO7k.png"
}
));
_config.Monuments.Add(new Monument(new MonumentSettings {
enabled = true, prefabName = "assets/bundled/prefabs/autospawn/monument/large/launch_site_1.prefab", shortName = "launch_site_1", displayName = "Launch", gridPos = "", lock_attack = true, lock_crate_hacking = true, lock_timer = 600, hard_timer = false, lock_looting = true, cancel_cards = true, enable_broadcasting = true, icon = "https://i.imgur.com/gjdynsc.png"
}
));
_config.Monuments.Add(new Monument(new MonumentSettings {
enabled = true, prefabName = "assets/bundled/prefabs/autospawn/monument/military_bases/desert_military_base_a.prefab", shortName = "desert_military_base_a", displayName = "Milly Base", gridPos = "", lock_attack = true, lock_crate_hacking = true, lock_timer = 600, hard_timer = false, lock_looting = true, cancel_cards = true, enable_broadcasting = true, icon = ""
}
));
_config.Monuments.Add(new Monument(new MonumentSettings {
enabled = true, prefabName = "assets/bundled/prefabs/autospawn/monument/medium/radtown_small_3.prefab", shortName = "radtown_small_3", displayName = "Sewer Branch", gridPos = "", lock_attack = true, lock_crate_hacking = true, lock_timer = 600, hard_timer = false, lock_looting = true, cancel_cards = true, enable_broadcasting = true, icon = "https://i.imgur.com/PbKZQdZ.png"
}
));
_config.Monuments.Add(new Monument(new MonumentSettings {
enabled = true, prefabName = "assets/bundled/prefabs/autospawn/monument/large/water_treatment_plant_1.prefab", shortName = "water_treatment_plant_1", displayName = "Water Treatment Plant", gridPos = "", lock_attack = true, lock_crate_hacking = true, lock_timer = 600, hard_timer = false, lock_looting = true, cancel_cards = true, enable_broadcasting = true, icon = "https://i.imgur.com/5L2Gdag.png"
}
));
_config.Monuments.Add(new Monument(new MonumentSettings {
enabled = true, prefabName = "assets/bundled/prefabs/autospawn/monument/small/satellite_dish.prefab", shortName = "satellite_dish", displayName = "Satellite Dish", gridPos = "", lock_attack = true, lock_crate_hacking = true, lock_timer = 600, hard_timer = false, lock_looting = true, cancel_cards = true, enable_broadcasting = true, icon = "https://i.imgur.com/XwSpCJY.png"
}
));
// _config.Monuments.Add (new Monument(new MonumentSettings
// {
// enabled = true,
// prefabName = "assets/bundled/prefabs/autospawn/monument/underwater_lab/underwater_lab_a.prefab",
// shortName = "underwater_lab_a",
// displayName = "Underwater Lab A",
// gridPos = "",
// lock_attack = true,
// lock_crate_hacking = true,
// lock_timer = 600,
// hard_timer = false,
// lock_looting = true,
// cancel_cards = true,
// enable_broadcasting = true,
// icon = ""
// }));
// _config.Monuments.Add (new Monument(new MonumentSettings
// {
// enabled = true,
// prefabName = "assets/bundled/prefabs/autospawn/monument/underwater_lab/underwater_lab_b.prefab",
// shortName = "underwater_lab_b",
// displayName = "Underwater Lab B",
// gridPos = "",
// lock_attack = true,
// lock_crate_hacking = true,
// lock_timer = 600,
// hard_timer = false,
// lock_looting = true,
// cancel_cards = true,
// enable_broadcasting = true,
// icon = ""
// }));
// _config.Monuments.Add (new Monument(new MonumentSettings
// {
// enabled = true,
// prefabName = "assets/bundled/prefabs/autospawn/monument/underwater_lab/underwater_lab_c.prefab",
// shortName = "underwater_lab_c",
// displayName = "Underwater Lab C",
// gridPos = "",
// lock_attack = true,
// lock_crate_hacking = true,
// lock_timer = 600,
// hard_timer = false,
// lock_looting = true,
// cancel_cards = true,
// enable_broadcasting = true,
// icon = ""
// }));
// _config.Monuments.Add (new Monument(new MonumentSettings
// {
// enabled = true,
// prefabName = "assets/bundled/prefabs/autospawn/monument/underwater_lab/underwater_lab_d.prefab",
// shortName = "underwater_lab_d",
// displayName = "Underwater Lab D",
// gridPos = "",
// lock_attack = true,
// lock_crate_hacking = true,
// lock_timer = 600,
// hard_timer = false,
// lock_looting = true,
// cancel_cards = true,
// enable_broadcasting = true,
// icon=""
// }));
_config.Monuments.Add(new Monument(new MonumentSettings {
enabled = true, prefabName = "assets/bundled/prefabs/autospawn/monument/harbor/ferry_terminal_1.prefab", shortName = "ferry_terminal_1", displayName = "Ferry Terminal", gridPos = "", lock_attack = true, lock_crate_hacking = true, lock_timer = 600, hard_timer = false, lock_looting = true, cancel_cards = true, enable_broadcasting = true, icon = ""
}
));
_config.Monuments.Add(new Monument(new MonumentSettings {
enabled = true, prefabName = "assets/bundled/prefabs/autospawn/monument/medium/nuclear_missile_silo.prefab", shortName = "nuclear_missile_silo", displayName = "Nuclear Silo", gridPos = "", lock_attack = true, lock_crate_hacking = true, lock_timer = 600, hard_timer = false, lock_looting = true, cancel_cards = true, enable_broadcasting = true, icon = ""
}
));
_config.Monuments.Add(new Monument(new MonumentSettings {
enabled = true, prefabName = "assets/bundled/prefabs/autospawn/monument/large/excavator_1.prefab", shortName = "excavator_1", displayName = "Excavator", gridPos = "", lock_attack = true, lock_crate_hacking = true, lock_timer = 600, hard_timer = false, lock_looting = true, cancel_cards = true, enable_broadcasting = true, icon = ""
}
));
_config.Monuments.Add(new Monument(new MonumentSettings {
enabled = true, prefabName = "assets/bundled/prefabs/autospawn/monument/large/airfield_1.prefab", shortName = "airfield_1", displayName = "Airfield", gridPos = "", lock_attack = true, lock_crate_hacking = true, lock_timer = 600, hard_timer = false, lock_looting = true, cancel_cards = true, enable_broadcasting = true, icon = ""
}
));
_config.Monuments.Add(new Monument(new MonumentSettings {
enabled = true, prefabName = "assets/bundled/prefabs/autospawn/monument/medium/junkyard_1.prefab", shortName = "junkyard_1", displayName = "Junkyard", gridPos = "", lock_attack = true, lock_crate_hacking = true, lock_timer = 600, hard_timer = false, lock_looting = true, cancel_cards = true, enable_broadcasting = true, icon = ""
}
));
SaveConfig();
}
protected override void LoadConfig() {
base.LoadConfig();
try {
_config = Config.ReadObject<Configuration>();
if (_config == null) throw new Exception();
Puts("Config loaded");
}
catch {
Puts("config error, create defaults");
LoadDefaultConfig();
}
//if(!IsConfigCompatible()) LoadDefaultConfig();
}
protected override void LoadDefaultConfig() {
_config = new Configuration();
DefaultMonuments();
SaveConfig();
}
protected override void SaveConfig() {
Config.WriteObject(_config, true);
}
protected bool IsConfigCompatible() {
string gridPos;
foreach (Monument _monument in _config.Monuments) {
try {
gridPos = _monument.gridPos;
}
catch {
return false;
}
if (gridPos == null) return false;
}
return true;
}
public struct MonumentSettings {
[JsonProperty(PropertyName = "Enabled: Is Monument enabled?")]
public bool enabled;
[JsonProperty(PropertyName = "is_online: Is Monument online and able to be locked?")]
public bool is_online;
[JsonProperty(PropertyName = "Lock Looting: When a player enters this monument while locked, do we lock their looting abilities?")]
public bool lock_looting;
[JsonProperty(PropertyName = "Lock Attack: When a player enters a locked monument, do we lock their attacking abilities?")]
public bool lock_attack;
[JsonProperty(PropertyName = "Cancel Cards: When a player enters this monument while locked, do we lock their card swiping abilities?")]
public bool cancel_cards;
[JsonProperty(PropertyName = "Lock Crate: When a player enters this monument while locked, do we lock their hacking on locked crates?")]
public bool lock_crate_hacking;
[JsonProperty(PropertyName = "Broadcasting: Do we want this plugin to broadcast to the server when this monument is locked?")]
public bool enable_broadcasting;
[JsonProperty(PropertyName = "Monument Display Name")]
public string displayName;
[JsonProperty(PropertyName = "Monument Prefab Name")]
public string prefabName;
[JsonProperty(PropertyName = "Monument Short Name")]
public string shortName;
[JsonProperty(PropertyName = "Monument Grid Position")]
public string gridPos;
[JsonProperty(PropertyName = "Lock timer (600 = 10 min)?")]
public int lock_timer;
[JsonProperty(PropertyName = "Only timer expiration will unlock a monument ")]
public bool hard_timer;
[JsonProperty(PropertyName = "Monument Icon")]
public string icon;
}
public class Monument {
[JsonProperty(PropertyName = "enabled: Is Monument enabled and to be used in this map?")]
public bool enabled;
[JsonProperty(PropertyName = "is_online: Is Monument online and able to be locked?")]
public bool is_online {
get;
set;
}
= true;
[JsonProperty(PropertyName = "Lock Looting: When a player enters this monument while locked, do we lock their looting abilities?")]
public bool lock_looting;
[JsonProperty(PropertyName = "Lock Attack: When a player enters a locked monument, do we lock their attacking abilities?")]
public bool lock_attack {
get;
set;
}
= true;
[JsonProperty(PropertyName = "Cancel Cards: When a player enters this monument while locked, do we lock their card swiping abilities?")]
public bool cancel_cards;
[JsonProperty(PropertyName = "Lock Crate: When a player enters this monument while locked, do we lock their hacking on locked crates?")]
public bool lock_crate_hacking;
[JsonProperty(PropertyName = "Broadcasting: Do we want this plugin to broadcast to the server when this monument is locked?")]
public bool enable_broadcasting;
[JsonProperty(PropertyName = "Monument Display Name")]
public string displayName;
[JsonProperty(PropertyName = "Monument Prefab Name")]
public string prefabName;
[JsonProperty(PropertyName = "Monument Short Name")]
public string shortName;
[JsonProperty(PropertyName = "Monument Grid Position")]
public string gridPos;
[JsonProperty(PropertyName = "Monument Icon")]
public string icon;
[JsonProperty(PropertyName = "Lock timer (600 = 10 min)?")]
public int lock_timer {
get;
set;
}
= 600;
[JsonProperty(PropertyName = "Only timer expiration will unlock a monument ")]
public bool hard_timer {
get;
set;
}
= false;
public Monument() {
}
public Monument(MonumentSettings settings) {
enabled = settings.enabled;
is_online = settings.is_online;
lock_looting = settings.lock_looting;
lock_attack = settings.lock_attack;
cancel_cards = settings.cancel_cards;
lock_crate_hacking = settings.lock_crate_hacking;
enable_broadcasting = settings.enable_broadcasting;
displayName = settings.displayName;
prefabName = settings.prefabName;
shortName = settings.shortName;
lock_timer = settings.lock_timer;
icon = settings.icon;
}
}
private class Configuration {
// public List<Monument> EnabledMonuments()
// {
// private List<Monument> _enabled = new List<Monument>{};
// foreach(Monument _monument in Monuments) {
// if(_monument.enabled) _enabled.Add(_monument);
// }
// return _enabled;
// }
[JsonProperty(PropertyName = "Lock timer (600 = 10 min)?")]
public int lock_timer {
get;
set;
}
= 600;
[JsonProperty(PropertyName = "Hard timer: Only timer expiration will unlock a monument ")]
public bool hard_timer {
get;
set;
}
= false;
[JsonProperty(PropertyName = "Enable max timer (regardless of how active player is)?")]
public bool enable_max_timer {
get;
set;
}
= false;
[JsonProperty(PropertyName = "Max timer (1200 = 20 min)?")]
public int max_timer {
get;
set;
}
= 1200;
[JsonProperty(PropertyName = "When a player enters a locked monument, do we lock their looting abilities?")]
public bool lock_looting {
get;
set;
}
= true;
[JsonProperty(PropertyName = "When a player enters a locked monument, do we lock their card swiping abilities?")]
public bool cancel_cards {
get;
set
// ... [Code preview truncated due to length. Full source in attached file] ...