C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using Rust;
using UnityEngine;
using UnityEngine.Networking;
namespace Oxide.Plugins {
[Info("RTM", "AhigaO#4485", "1.3.4")]
internal class RTM : RustPlugin {
#region Static
private const string Layer = "UI_RTM";
private Data _data;
private Configuration _config;
private bool CanRaidNow = false;
private bool Update = true;
private Timer DiscordTimer;
private List<ulong> AlertCooldown = new List<ulong>();
private List<ulong> ClosedUI = new List<ulong>();
private Dictionary<ulong, DateTime> LeaveTime = new Dictionary<ulong, DateTime>();
private string[] DaysOfWeek = {
"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"
}
;
private List<string> UIPositions = new List<string> {
"UPPER_LEFT", "UPPER_CENTER", "UPPER_RIGHT", "LOWER_CENTER", "LOWER_RIGHT", "LOWER_CENTER_LITE"
}
;
private List<string> ZoneManagerSettings = new List<string> {
"DISABLED", "TRUE", "FALSE"
}
;
#region Image
[PluginReference]
private Plugin ImageLibrary, RaidableBases, TruePVE, ZoneManager;
private int ILCheck = 0;
private Dictionary<string, string> Images = new Dictionary<string, string>();
private void AddImage(string url) {
if (!ImageLibrary.Call<bool>("HasImage", url)) ImageLibrary.Call("AddImage", url, url);
timer.In(1f, () => {
Images.Add(url, ImageLibrary.Call<string>("GetImage", url));
}
);
}
private string GetImage(string url) {
return Images[url];
}
private void LoadImages() {
AddImage("https://i.imgur.com/dvmwW5c.png");
AddImage("https://i.imgur.com/afJY7cT.png");
AddImage("https://i.imgur.com/pO6eVOK.png");
AddImage("https://i.imgur.com/nPqbl6m.png");
AddImage("https://i.imgur.com/Qo14QIG.png");
AddImage("https://i.imgur.com/mwbQmBO.png");
}
#endregion
#region Classes
private class Data {
public Dictionary<string, DateTime> NPP = new Dictionary<string, DateTime>();
}
private class RaidBlockTime {
[JsonProperty(PropertyName = "Start Raid Block(Hours)")]
public int StartHours;
[JsonProperty(PropertyName = "Start Raid Block(Minutes)")]
public int StartMinutes;
[JsonProperty(PropertyName = "Stop Raid Block(Hours)")]
public int StopHours;
[JsonProperty(PropertyName = "Stop Raid Block(Minutes)")]
public int StopMinutes;
}
private class RaidBlockDay {
[JsonProperty(PropertyName = "Year")]
public int Year;
[JsonProperty(PropertyName = "Month")]
public int Month;
[JsonProperty(PropertyName = "Day")]
public int Day;
public static RaidBlockDay GetFromString(string input) {
var result = input.Split('/');
return new RaidBlockDay {
Month = int.Parse(result[0]), Day = int.Parse(result[1]), Year = int.Parse(result[2])
}
;
}
public override string ToString() => $"{Month}/{Day}/{Year}";
}
private class Configuration {
[JsonProperty(PropertyName = "Command for open Raid Time Managment UI")]
public string Command = "rtm";
[JsonProperty(PropertyName = "Timezone(Difference between UTC and your time)")]
public int TimeZone = 60;
[JsonProperty(PropertyName = "Time format for UI(True - 24H format, False - 12H format)")]
public bool TimeFormat = false;
[JsonProperty(PropertyName = "Display UI")]
public bool DisplayUI = true;
[JsonProperty(PropertyName = "Enable Alerts")]
public bool Alerts = true;
[JsonProperty(PropertyName = "Discord webhook [empty = not use]")]
public string DiscordWebHook = "";
[JsonProperty(PropertyName = "Time before the start of the raid in minutes when to send a discord notification")]
public int DiscordMessageTime = 120;
[JsonProperty(PropertyName = "Allow players to close the UI")]
public bool AllowToCloseUI = true;
[JsonProperty(PropertyName = "[RaidableBases] Allow raiding RB bases in SafeTime")]
public bool RaidRBInSafeTime = true;
[JsonProperty(PropertyName = "[TruePVE] Safe Time RuleSet")]
public string SafeTimeRuleSet = "default";
[JsonProperty(PropertyName = "[TruePVE] Raid Time RuleSet")]
public string RaidTimeRuleSet = "default";
[JsonProperty(PropertyName = "[ZoneManager] The plugin will work on entities in the zones")]
public string ZoneManagerSettings = "DISABLED";
[JsonProperty(PropertyName = "[ZoneManager] Zone ID List", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<string> ZoneIDs = new List<string>();
[JsonProperty(PropertyName = "UI Position")]
public string UIPosition = "UPPER_LEFT";
[JsonProperty(PropertyName = "NPP amount")]
public int NPP = 0;
[JsonProperty(PropertyName = "Block only offline raids")]
public bool BlockOnlyOffline = false;
[JsonProperty(PropertyName = "Allow bots raids in any time")]
public bool BotsRaids = false;
[JsonProperty(PropertyName = "Offline defence activation time")]
public int OfflineDefenceTimer = 3600;
[JsonProperty(PropertyName = "Add safe days after wipe")]
public int AdditionalSafeHours = 1;
[JsonProperty(PropertyName = "Commands to be executed when raid time starts", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<string> CommandOnRaidStarted = new List<string>();
[JsonProperty(PropertyName = "Commands to be executed when safe time starts", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<string> CommandOnSafeStarted = new List<string>();
[JsonProperty(PropertyName = "Forbidden actions during the blocking of the raid")]
public Dictionary<string, bool> RaidBlockSettings = new Dictionary<string, bool> {
["Default Raid By Player"]
= true, ["Damage Own Buildings"] = false, ["Raid By Patrol Helicopter"] = true, ["Raid By MLRS"] = true, ["Using Ladders In Building Block"] = true, ["Damage By Fire"] = true, ["Build Ceiling In Building Block"] = true, ["Build Turrets In 2x Building Block Radius"] = true, ["Break down twig buildings"] = false,
}
;
[JsonProperty(PropertyName = "List of prefabs that can always be damaged", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<string> AlwaysDamaged = new List<string>();
[JsonProperty(PropertyName = "Manage raids by day of the week (Used by default)", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public Dictionary<string, List<RaidBlockTime>> BlockByWeekDay = new Dictionary<string, List<RaidBlockTime>> {
["Monday"]
= new List<RaidBlockTime> {
new RaidBlockTime {
StartHours = 18, StartMinutes = 0, StopHours = 22, StopMinutes = 0
}
}
, ["Tuesday"] = new List<RaidBlockTime> {
new RaidBlockTime {
StartHours = 18, StartMinutes = 0, StopHours = 22, StopMinutes = 0
}
}
, ["Wednesday"] = new List<RaidBlockTime> {
new RaidBlockTime {
StartHours = 18, StartMinutes = 0, StopHours = 22, StopMinutes = 0
}
}
, ["Thursday"] = new List<RaidBlockTime> {
new RaidBlockTime {
StartHours = 18, StartMinutes = 0, StopHours = 22, StopMinutes = 0
}
}
, ["Friday"] = new List<RaidBlockTime> {
new RaidBlockTime {
StartHours = 18, StartMinutes = 0, StopHours = 22, StopMinutes = 0
}
}
, ["Saturday"] = new List<RaidBlockTime> {
new RaidBlockTime {
StartHours = 10, StartMinutes = 0, StopHours = 22, StopMinutes = 0
}
}
, ["Sunday"] = new List<RaidBlockTime> {
new RaidBlockTime {
StartHours = 8, StartMinutes = 0, StopHours = 22, StopMinutes = 0
}
}
}
;
[JsonProperty(PropertyName = "Raid management for specific days(Takes precedence over raid management by day of the week)", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public Dictionary<string, List<RaidBlockTime>> BlockByDay = new Dictionary<string, List<RaidBlockTime>>();
}
#endregion
#endregion
#region Config
protected override void LoadConfig() {
base.LoadConfig();
try {
_config = Config.ReadObject<Configuration>();
if (_config == null) throw new Exception();
SaveConfig();
}
catch {
PrintError("Your configuration file contains an error.Using default configuration values.");
LoadDefaultConfig();
}
}
protected override void SaveConfig() => Config.WriteObject(_config);
protected override void LoadDefaultConfig() => _config = new Configuration();
#endregion
#region Data
private void LoadData() => _data = Interface.Oxide.DataFileSystem.ExistsDatafile($"{Name}/data") ? Interface.Oxide.DataFileSystem.ReadObject<Data>($"{Name}/data") : new Data();
private void OnServerSave() => SaveData();
private void SaveData() {
if (_data != null) Interface.Oxide.DataFileSystem.WriteObject($"{Name}/data", _data);
}
#endregion
#region OxideHooks
private void OnRaidableBaseStarted(Vector3 raidPos, int mode, bool allowPVP, string id, float spawnTime, float despawnTime, float loadTime, ulong ownerId, BasePlayer owner, List<BasePlayer> raiders, List<BasePlayer> intruders, List<BaseEntity> entities) {
foreach (var check in entities) {
if (check == null) continue;
check._name = "ITRBBASE";
}
}
private void OnEntityTakeDamage(DecayEntity entity, HitInfo info) {
if (entity == null || info == null || entity._name == "ITRBBASE" || _config.AlwaysDamaged.Contains(entity.PrefabName) || !entity.OwnerID.IsSteamId()) return;
var player = info.InitiatorPlayer;
if ((CanRaidNow || player != null && _config.BotsRaids && !player.userID.IsSteamId()) && !PlayerHasNPP(entity.OwnerID)) return;
if (!InCorrectZone(entity) || CanRaidPlayer(entity)) return;
if (player != null) {
var team = player.Team;
var tc = entity.GetBuildingPrivilege();
if ((tc != null && tc.IsAuthed(player)) || (player.userID == entity.OwnerID || (team != null && team.members.Contains(entity.OwnerID)))) {
if (_config.RaidBlockSettings["Damage Own Buildings"]) {
ShowUIAlert(player, GetMsg(player?.UserIDString, "UI_CANDAMAGEOWN"));
info.damageTypes.ScaleAll(0);
return;
}
return;
}
if (entity is BuildingBlock) {
if ((entity as BuildingBlock).grade == BuildingGrade.Enum.Twigs) {
if (!_config.RaidBlockSettings["Break down twig buildings"]) return;
info?.damageTypes?.ScaleAll(0);
return;
}
}
if (_config.RaidBlockSettings["Default Raid By Player"]) {
info.damageTypes.ScaleAll(0);
ShowUIAlert(player, GetMsg(player?.UserIDString, "UI_CANDAMAGE"));
}
return;
}
if (_config.RaidBlockSettings["Raid By Patrol Helicopter"] && InitiatorIsHelicopter(info)) {
info.damageTypes.ScaleAll(0);
return;
}
if (_config.RaidBlockSettings["Raid By MLRS"] && info.WeaponPrefab != null && info.WeaponPrefab.ShortPrefabName == "rocket_mlrs") {
info.damageTypes.ScaleAll(0);
return;
}
if (_config.RaidBlockSettings["Damage By Fire"] && info.damageTypes.Has(DamageType.Heat)) info.damageTypes.Scale(DamageType.Heat, 0);
}
private bool PlayerHasNPP(ulong entityOwnerID, bool checkTeam = true) {
if (_config.NPP == 0) return false;
DateTime time;
if (!_data.NPP.TryGetValue(entityOwnerID.ToString(), out time)) return false;
if (time.Subtract(DateTime.Now).TotalSeconds < 0) return false;
if (!checkTeam) return true;
var team = RelationshipManager.ServerInstance.FindPlayersTeam(entityOwnerID);
if (team == null) return true;
foreach (var check in team.members) if (!PlayerHasNPP(check, false)) return false;
return true;
}
private object CanBuild(Planner bplan, Construction prefab, Construction.Target target) {
var player = bplan?.GetOwnerPlayer();
if (player == null || !InCorrectZone(player)) return null;
var tc = player.GetBuildingPrivilege();
if (tc == null || tc.IsAuthed(player)) return null;
switch (prefab.fullName) {
case "assets/prefabs/building/ladder.wall.wood/ladder.wooden.wall.prefab" : if (!_config.RaidBlockSettings["Using Ladders In Building Block"]) return null;
ShowUIAlert(player, GetMsg(player?.UserIDString, "UI_LADDERBLOCK"));
return false;
case "assets/prefabs/building core/floor/floor.prefab" : case "assets/prefabs/building core/floor.triangle/floor.triangle.prefab" : case "assets/prefabs/building core/floor.frame/floor.frame.prefab" : case "assets/prefabs/building core/floor.triangle.frame/floor.triangle.frame.prefab" : if (!_config.RaidBlockSettings["Build Ceiling In Building Block"]) return null;
ShowUIAlert(player, GetMsg(player?.UserIDString, "UI_CEILINGBLOCK"));
return false;
case "assets/prefabs/npc/autoturret/autoturret_deployed.prefab" : if (!_config.RaidBlockSettings["Build Turrets In 2x Building Block Radius"]) return null;
var tcs = Facepunch.Pool.GetList<BuildingPrivlidge>();
Vis.Entities(player.transform.position, 36, tcs);
foreach (var check in tcs) {
if (check.IsAuthed(player)) continue;
ShowUIAlert(player, GetMsg(player?.UserIDString, "UI_TURRETBLOCK"));
return false;
}
return null;
default : return null;
}
}
private void OnPlayerConnected(BasePlayer player) {
if (player == null || !_config.DisplayUI) return;
ShowHudUI(player);
if (_config.NPP == 0) return;
if (!_data.NPP.ContainsKey(player?.UserIDString)) _data.NPP.Add(player?.UserIDString, DateTime.Now.AddHours(_config.NPP));
}
private void OnPlayerDisconnected(BasePlayer player) {
if (player == null) return;
LeaveTime.TryAdd(player.userID, DateTime.Now);
}
private void OnServerInitialized() {
if (!ImageLibrary) {
if (ILCheck == 3) {
PrintError("ImageLibrary not found!Unloading");
Interface.Oxide.UnloadPlugin(Name);
return;
}
timer.In(1, () => {
ILCheck++;
OnServerInitialized();
}
);
return;
}
LoadData();
ToggleOnHooks();
LoadImages();
ClearDateCache();
CheckForStartSafeTime();
cmd.AddChatCommand(_config.Command, this, nameof(cmdChatRTM));
timer.In(1.5f, OnServerInitializedLate);
}
private void OnServerInitializedLate() {
foreach (var check in BasePlayer.activePlayerList) OnPlayerConnected(check);
ServerMgr.Instance.StartCoroutine(CheckTimer());
}
private void Unload() {
Update = false;
ToggleOffHooks();
foreach (var check in BasePlayer.activePlayerList) {
CuiHelper.DestroyUi(check, Layer + ".bg");
CuiHelper.DestroyUi(check, Layer + ".alert");
CuiHelper.DestroyUi(check, Layer + ".HUD");
}
}
#endregion
#region Commands
private void cmdChatRTM(BasePlayer player, string command, string[] args) {
if (player == null) return;
if (args.Length == 0) {
ShowUIBackGround(player);
ShowRTMInfo(player, Time.Year, Time.Month, player.IsAdmin);
return;
}
if (args.Length == 1 && args[0] == "hud") {
if (ClosedUI.Contains(player.userID)) {
ClosedUI.Remove(player.userID);
ShowHudUI(player);
return;
}
if (!_config.AllowToCloseUI) return;
SendMessage(player, "CM_CLOSE_HUD");
ClosedUI.Add(player.userID);
CuiHelper.DestroyUi(player, Layer + ".HUD");
}
}
[ConsoleCommand("UI_RTM")]
private void cmdConsoleUI_RTM(ConsoleSystem.Arg arg) {
var player = arg?.Player();
if (player == null || !arg.HasArgs()) return;
int time;
switch (arg.GetString(0)) {
case "OPENMONTH" : ShowRTMInfo(player, arg.GetInt(1), arg.GetInt(2), player.IsAdmin);
return;
case "SHOWDAYINFO" : ShowUIDayInfo(player, arg.GetInt(1), arg.GetInt(2), arg.GetInt(3));
return;
case "CLOSE" : if (!_config.AllowToCloseUI) return;
SendMessage(player, "CM_CLOSE_HUD");
ClosedUI.Add(player.userID);
CuiHelper.DestroyUi(player, Layer + ".HUD");
break;
case "OPENSETTINGS" : ShowUISettings(player);
return;
case "COMMAND" : if (!arg.HasArgs(2)) return;
_config.Command = arg.GetString(1);
player.ChatMessage("You need to reload plugin after this change");
break;
case "TIMEZONE" : if (!arg.HasArgs(2)) return;
_config.TimeZone = arg.GetInt(1);
player.ChatMessage("You need to reload plugin after this change");
break;
case "ASD" : if (!arg.HasArgs(2)) return;
_config.AdditionalSafeHours = arg.GetInt(1);
player.ChatMessage("You need to reload plugin after this change");
break;
case "NPP" : if (!arg.HasArgs(2)) return;
_config.NPP = arg.GetInt(1);
player.ChatMessage("You need to reload plugin after this change");
break;
case "TIMEFORMAT" : _config.TimeFormat = !_config.TimeFormat;
break;
case "DISPLAYUI" : _config.DisplayUI = !_config.DisplayUI;
if (_config.DisplayUI) foreach (var check in BasePlayer.activePlayerList) OnPlayerConnected(check);
else foreach (var check in BasePlayer.activePlayerList) CuiHelper.DestroyUi(check, Layer + ".HUD");
break;
case "RBAR" : _config.RaidRBInSafeTime = !_config.RaidRBInSafeTime;
break;
case "ACUIBP" : _config.AllowToCloseUI = !_config.AllowToCloseUI;
break;
case "BOF" : _config.BlockOnlyOffline = !_config.BlockOnlyOffline;
break;
case "ENABLEALERTS" : _config.Alerts = !_config.Alerts;
break;
case "SETTINGS" : var type = string.Join(" ", arg.Args.Skip(1));
_config.RaidBlockSettings[type] = !_config.RaidBlockSettings[type];
break;
case "UITYPE" : var currUIPos = UIPositions.IndexOf(UIPositions.FirstOrDefault(x => x == _config.UIPosition));
_config.UIPosition = UIPositions[currUIPos >= UIPositions.Count - 1 ? 0 : currUIPos + 1];
foreach (var check in BasePlayer.activePlayerList) OnPlayerConnected(check);
break;
case "ZONEMANAGER" : var currState = ZoneManagerSettings.IndexOf(ZoneManagerSettings.FirstOrDefault(x => x == _config.ZoneManagerSettings));
_config.ZoneManagerSettings = ZoneManagerSettings[currState >= ZoneManagerSettings.Count - 1 ? 0 : currState + 1];
foreach (var check in BasePlayer.activePlayerList) OnPlayerConnected(check);
break;
case "ADDDAY" : if (_config.BlockByDay.ContainsKey($"{arg.GetString(2)}/{arg.GetString(3)}/{arg.GetString(1)}")) return;
_config.BlockByDay.Add($"{arg.GetString(2)}/{arg.GetString(3)}/{arg.GetString(1)}", new List<RaidBlockTime> {
new RaidBlockTime {
StartHours = 18, StartMinutes = 0, StopHours = 24, StopMinutes = 0
}
}
);
break;
case "OPENADDDAYS" : ShowRTMInfoAddDays(player, arg.GetInt(1), arg.GetInt(2));
return;
case "OPENNEXTPAGE" : ShowUISettings(player, arg.GetString(1), arg.GetInt(2));
return;
case "ADDNEWRAIDTIME" : if (_config.BlockByWeekDay.ContainsKey(arg.GetString(1))) {
_config.BlockByWeekDay[arg.GetString(1)].Add(new RaidBlockTime {
StartHours = 0, StartMinutes = 0, StopHours = 0, StopMinutes = 0
}
);
ShowUISettings(player, arg.GetString(1), arg.GetInt(2));
return;
}
_config.BlockByDay[arg.GetString(1)].Add(new RaidBlockTime {
StartHours = 0, StartMinutes = 0, StopHours = 0, StopMinutes = 0
}
);
ShowUISettings(player, arg.GetString(1), arg.GetInt(2));
return;
case "SSH" : if (!arg.HasArgs(4)) return;
time = arg.GetInt(3);
if (time > 24) time = 24;
if (time < 0) time = 0;
_config.BlockByWeekDay[arg.GetString(1)][arg.GetInt(2)].StartHours = time;
ShowUISettings(player, arg.GetString(1), arg.GetInt(2));
SaveConfig();
return;
case "SSM" : if (!arg.HasArgs(4)) return;
time = arg.GetInt(3);
if (time > 59) time = 59;
if (time < 0) time = 0;
_config.BlockByWeekDay[arg.GetString(1)][arg.GetInt(2)].StartMinutes = time;
ShowUISettings(player, arg.GetString(1), arg.GetInt(2));
SaveConfig();
return;
case "SEH" : if (!arg.HasArgs(4)) return;
time = arg.GetInt(3);
if (time > 24) time = 24;
if (time < 0) time = 0;
_config.BlockByWeekDay[arg.GetString(1)][arg.GetInt(2)].StopHours = time;
ShowUISettings(player, arg.GetString(1), arg.GetInt(2));
SaveConfig();
return;
case "SEM" : if (!arg.HasArgs(4)) return;
time = arg.GetInt(3);
if (time > 59) time = 59;
if (time < 0) time = 0;
_config.BlockByWeekDay[arg.GetString(1)][arg.GetInt(2)].StopMinutes = time;
ShowUISettings(player, arg.GetString(1), arg.GetInt(2));
SaveConfig();
return;
case "DSSH" : if (!arg.HasArgs(6)) return;
var dssh = _config.BlockByDay.FirstOrDefault(x => x.Key == $"{arg.GetString(2)}/{arg.GetString(3)}/{arg.GetString(1)}");
if (dssh.Value == null) return;
time = arg.GetInt(5);
if (time > 24) time = 24;
if (time < 0) time = 0;
dssh.Value[arg.GetInt(4)].StartHours = time;
ShowUISettings(player, $"{arg.GetString(2)}/{arg.GetString(3)}/{arg.GetString(1)}", arg.GetInt(4));
SaveConfig();
return;
case "DSSM" : if (!arg.HasArgs(6)) return;
var dssm = _config.BlockByDay.FirstOrDefault(x => x.Key == $"{arg.GetString(2)}/{arg.GetString(3)}/{arg.GetString(1)}");
if (dssm.Value == null) return;
time = arg.GetInt(5);
if (time > 59) time = 59;
if (time < 0) time = 0;
dssm.Value[arg.GetInt(4)].StartMinutes = time;
ShowUISettings(player, $"{arg.GetString(2)}/{arg.GetString(3)}/{arg.GetString(1)}", arg.GetInt(4));
SaveConfig();
return;
case "DSEH" : if (!arg.HasArgs(6)) return;
var dseh = _config.BlockByDay.FirstOrDefault(x => x.Key == $"{arg.GetString(2)}/{arg.GetString(3)}/{arg.GetString(1)}");
if (dseh.Value == null) return;
time = arg.GetInt(5);
if (time > 24) time = 24;
if (time < 0) time = 0;
dseh.Value[arg.GetInt(4)].StopHours = time;
ShowUISettings(player, $"{arg.GetString(2)}/{arg.GetString(3)}/{arg.GetString(1)}", arg.GetInt(4));
SaveConfig();
return;
case "DSEM" : if (!arg.HasArgs(6)) return;
var dsem = _config.BlockByDay.FirstOrDefault(x => x.Key == $"{arg.GetString(2)}/{arg.GetString(3)}/{arg.GetString(1)}");
if (dsem.Value == null) return;
time = arg.GetInt(5);
if (time > 59) time = 59;
if (time < 0) time = 0;
dsem.Value[arg.GetInt(4)].StopMinutes = time;
ShowUISettings(player, $"{arg.GetString(2)}/{arg.GetString(3)}/{arg.GetString(1)}", arg.GetInt(4));
SaveConfig();
return;
case "REMOVEDAYPAGE" : var page = arg.GetInt(2);
if (_config.BlockByWeekDay.ContainsKey(arg.GetString(1))) {
_config.BlockByWeekDay[arg.GetString(1)].RemoveAt(page);
ShowUISettings(player, arg.GetString(1), page);
return;
}
_config.BlockByDay[arg.GetString(1)].RemoveAt(page);
ShowUISettings(player, arg.GetString(1), page);
return;
case "REMOVEDAY" : _config.BlockByDay.Remove(_config.BlockByDay.FirstOrDefault(x => x.Key == $"{arg.GetString(2)}/{arg.GetString(3)}/{arg.GetString(1)}").Key);
break;
case "TRUEPVESAFE" : _config.SafeTimeRuleSet = arg.GetString(1);
break;
case "TRUEPVERAID" : _config.RaidTimeRuleSet = arg.GetString(1);
break;
}
ShowUISettings(player);
SaveConfig();
}
[ConsoleCommand("UI_RTMCLOSEALERT")]
private void cmdConsoleUI_RTMCLOSEALERT(ConsoleSystem.Arg arg) {
if (arg?.Player() == null) return;
DestroyAlert(arg.Player());
}
#endregion
#region Functions
private void CheckForStartSafeTime() {
if (_config.AdditionalSafeHours == 0 || DateTime.UtcNow.Subtract(SaveRestore.SaveCreatedTime.Date).TotalSeconds > _config.AdditionalSafeHours * 86400) return;
SetStartSafeTime(SaveRestore.SaveCreatedTime);
}
private void SetStartSafeTime(DateTime wipeTime) {
var additionDays = _config.AdditionalSafeHours;
var settings = _config.BlockByDay;
for (int i = 0; i < additionDays + 1; i++) {
if (i == 0) {
if (settings.ContainsKey($"{wipeTime.Month}/{wipeTime.Day}/{wipeTime.Year}")) settings[$"{wipeTime.Month}/{wipeTime.Day}/{wipeTime.Year}"] = new List<RaidBlockTime> {
new RaidBlockTime {
StartHours = 0, StartMinutes = 0, StopHours = wipeTime.Hour, StopMinutes = wipeTime.Minute
}
}
;
else settings.Add($"{wipeTime.Month}/{wipeTime.Day}/{wipeTime.Year}", new List<RaidBlockTime> {
new RaidBlockTime {
StartHours = 0, StartMinutes = 0, StopHours = wipeTime.Hour, StopMinutes = wipeTime.Minute
}
}
);
continue;
}
if (i == additionDays) {
wipeTime = wipeTime.AddDays(1);
if (settings.ContainsKey($"{wipeTime.Month}/{wipeTime.Day}/{wipeTime.Year}")) settings[$"{wipeTime.Month}/{wipeTime.Day}/{wipeTime.Year}"] = new List<RaidBlockTime> {
new RaidBlockTime {
StartHours = wipeTime.Hour, StartMinutes = wipeTime.Minute, StopHours = 24, StopMinutes = 0
}
}
;
else settings.Add($"{wipeTime.Month}/{wipeTime.Day}/{wipeTime.Year}", new List<RaidBlockTime> {
new RaidBlockTime {
StartHours = wipeTime.Hour, StartMinutes = wipeTime.Minute, StopHours = 24, StopMinutes = 0
}
}
);
continue;
}
wipeTime = wipeTime.AddDays(1);
if (settings.ContainsKey($"{wipeTime.Month}/{wipeTime.Day}/{wipeTime.Year}")) settings[$"{wipeTime.Month}/{wipeTime.Day}/{wipeTime.Year}"] = new List<RaidBlockTime> {
new RaidBlockTime {
StartHours = 0, StartMinutes = 0, StopHours = 0, StopMinutes = 0
}
}
;
else settings.Add($"{wipeTime.Month}/{wipeTime.Day}/{wipeTime.Year}", new List<RaidBlockTime> {
new RaidBlockTime {
StartHours = 0, StartMinutes = 0, StopHours = 0, StopMinutes = 0
}
}
);
}
SaveConfig();
}
private void ShowHudUI(BasePlayer player) {
switch (_config.UIPosition) {
case "UPPER_LEFT" : ShowUIUpperLeftBG(player);
break;
case "UPPER_RIGHT" : ShowUIUpperRightBG(player);
break;
case "LOWER_RIGHT" : ShowUILowerRightBG(player);
break;
case "UPPER_CENTER" : ShowUIUpperCenterBG(player);
break;
case "LOWER_CENTER" : ShowUILowerCenterBG(player);
break;
case "LOWER_CENTER_LITE" : ShowUILowerCenterLiteBG(player);
break;
}
}
private void UpdateHudUI() {
switch (_config.UIPosition) {
case "UPPER_LEFT" : ShowUIUpperLeftChange();
break;
case "UPPER_RIGHT" : ShowUIUpperRightChange();
break;
case "LOWER_RIGHT" : ShowUILowerRightChange();
break;
case "UPPER_CENTER" : ShowUIUpperCenterChange();
break;
case "LOWER_CENTER" : ShowUILowerCenterChange();
break;
case "LOWER_CENTER_LITE" : ShowUILowerCenterLiteChange();
break;
}
}
private void SendDiscordMessage() {
var currentDay = Time;
var time = _config.BlockByDay.FirstOrDefault(x => x.Key == $"{currentDay.Month}/{currentDay.Day}/{currentDay.Year}").Value ?? _config.BlockByWeekDay[new DateTime(currentDay.Year, currentDay.Month, currentDay.Day).DayOfWeek.ToString()];
var raidTime = GetNearesTime(time);
var field = new WWWForm();
field.AddField("content", $"The raid will start in {_config.DiscordMessageTime} minutes, and will last {raidTime.StopHours * 60 - raidTime.StartHours * 60 + raidTime.StopMinutes - raidTime.StartMinutes} minutes [{(_config.BlockOnlyOffline ? "Offline" : "Online")} raids]");
UnityWebRequest.Post(_config.DiscordWebHook, field).SendWebRequest();
}
private IEnumerator CheckTimer() {
while (Update) {
if (_config.DisplayUI) UpdateHudUI();
if (IsRaidTime()) {
if (CanRaidNow) {
yield return new WaitForSeconds(5f);
continue;
}
CanRaidNow = true;
ToggleOffHooks();
PrintWarning("Raid time has begun!");
foreach (var check in _config.CommandOnRaidStarted) Server.Command(check);
if (TruePVE != null) TruePVE.Call("ResetRules", _config.RaidTimeRuleSet);
foreach (var player in BasePlayer.activePlayerList) ShowUIAlert(player, GetMsg(player?.UserIDString, "UI_START_RAID_TIME"));
}
else {
if (DiscordTimer == null && !string.IsNullOrEmpty(_config.DiscordWebHook)) {
var currentDay = Time;
var time = _config.BlockByDay.FirstOrDefault(x => x.Key == $"{currentDay.Month}/{currentDay.Day}/{currentDay.Year}").Value ?? _config.BlockByWeekDay[new DateTime(currentDay.Year, currentDay.Month, currentDay.Day).DayOfWeek.ToString()];
if (!IsSafeDay(time)) {
var raidTime = GetNearesTime(time);
var startTimer = (raidTime.StartHours - currentDay.Hour) * 60 * 60 + (raidTime.StartMinutes - currentDay.Minute) * 60 - _config.DiscordMessageTime * 60;
if (startTimer < 0) DiscordTimer = timer.Once(1f, null);
else DiscordTimer = timer.Once((raidTime.StartHours - currentDay.Hour) * 60 * 60 + (raidTime.StartMinutes - currentDay.Minute) * 60 - _config.DiscordMessageTime * 60, SendDiscordMessage);
}
}
if (!CanRaidNow) {
yield return new WaitForSeconds(5f);
continue;
}
CanRaidNow = false;
ToggleOnHooks();
PrintWarning("The raid time is over.");
foreach (var check in _config.CommandOnSafeStarted) Server.Command(check);
if (TruePVE != null) TruePVE.Call("ResetRules", _config.SafeTimeRuleSet);
foreach (var player in BasePlayer.activePlayerList) ShowUIAlert(player, GetMsg(player?.UserIDString, "UI_STOP_RAID_TIME"));
DiscordTimer = null;
}
yield return new WaitForSeconds(5f);
}
}
private RaidBlockTime GetNearesTime(List<RaidBlockTime> times) {
if (times.Count == 1) return times[0];
var currentTime = Time;
var currentMinutes = currentTime.Hour * 60 + currentTime.Minute;
RaidBlockTime raidBlockTime = null;
foreach (var check in times) {
var startMinutes = check.StartHours * 60 + check.StartMinutes;
var stopMinutes = check.StopHours * 60 + check.StopMinutes;
if (startMinutes > currentMinutes || stopMinutes < currentMinutes) continue;
if (raidBlockTime != null && raidBlockTime.StartHours * 60 + raidBlockTime.StartMinutes < startMinutes) continue;
raidBlockTime = check;
}
return raidBlockTime ?? times[times.Count - 1];
}
private bool IsSafeDay(List<RaidBlockTime> times) {
foreach (var check in times) if (check.StartHours != check.StopHours || check.StartMinutes != check.StopMinutes) return false;
return true;
}
private string GetCorrectDate(int year, int month, int day) {
var date = string.Empty;
date += month >= 10 ? $"{month}/" : $"0{month}/";
date += day >= 10 ? $"{day}/" : $"0{day}/";
date += $"{year}";
return date;
}
private int GetStartPosOfDay(DayOfWeek day) {
switch (day) {
case DayOfWeek.Sunday : return 590;
case DayOfWeek.Monday : return 140;
case DayOfWeek.Tuesday : return 215;
case DayOfWeek.Wednesday : return 290;
case DayOfWeek.Thursday : return 365;
case DayOfWeek.Friday : return 440;
case DayOfWeek.Saturday : return 515;
default : return 140;
}
}
private bool IsRaidTime() {
var RaidBlockDay = GetCurrentDayBlock();
return RaidBlockDay != null ? IsRaidTime(_config.BlockByDay[RaidBlockDay.ToString()]) : IsRaidTime(_config.BlockByWeekDay[Time.DayOfWeek.ToString()]);
}
private bool CanRaidPlayer(BaseEntity entity) {
if (!_config.BlockOnlyOffline) return false;
var owner = entity.OwnerID;
var team = RelationshipManager.ServerInstance.FindPlayersTeam(owner);
if (team == null) return IsOnlineRecently(owner);
foreach (var check in team.members) if (IsOnlineRecently(check)) return true;
return false;
}
private bool IsOnlineRecently(ulong id) {
var player = BasePlayer.FindByID(id);
if (player != null) return true;
DateTime leaveTime;
if (!LeaveTime.TryGetValue(id, out leaveTime)) return false;
if (DateTime.Now.Subtract(leaveTime).TotalSeconds < _config.OfflineDefenceTimer) return true;
return false;
}
private bool IsRaidTime(List<RaidBlockTime> times) {
var currentTime = Time.Hour * 60 + Time.Minute;
foreach (var time in times) if (time.StartHours * 60 + time.StartMinutes <= currentTime && time.StopHours * 60 + time.StopMinutes > currentTime) return true;
return false;
}
private RaidBlockDay GetCurrentDayBlock() {
var time = Time;
foreach (var check in _config.BlockByDay) {
var key = RaidBlockDay.GetFromString(check.Key);
if (key.Year != time.Year || key.Month != time.Month || key.Day != time.Day) continue;
return key;
}
return null;
}
private void ToggleOnHooks() {
Subscribe(nameof(CanBuild));
}
private void ToggleOffHooks() {
Unsubscribe(nameof(CanBuild));
}
private bool InitiatorIsHelicopter(HitInfo hitInfo) {
if (hitInfo.Initiator is BaseHelicopter || (hitInfo.Initiator != null && (hitInfo.Initiator.ShortPrefabName.Equals("oilfireballsmall") || hitInfo.Initiator.ShortPrefabName.Equals("napalm")))) return true;
return hitInfo.WeaponPrefab != null && (hitInfo.WeaponPrefab.ShortPrefabName.Equals("rocket_heli") || hitInfo.WeaponPrefab.ShortPrefabName.Equals("rocket_heli_napalm"));
}
private void ClearDateCache() {
var currentDate = Time;
var blockByDay = _config.BlockByDay;
foreach (var check in _config.BlockByDay.ToArray()) {
var key = RaidBlockDay.GetFromString(check.Key);
if (key.Year < currentDate.Year) {
blockByDay.Remove(check.Key);
continue;
}
if (key.Year > currentDate.Year) continue;
if (key.Month < currentDate.Month) {
blockByDay.Remove(check.Key);
continue;
}
if (key.Month > currentDate.Month || key.Day >= currentDate.Day) continue;
blockByDay.Remove(check.Key);
}
}
private string TimeString(string userID) {
var time = Time;
if (_config.TimeFormat) return time.ToShortTimeString();
return time.Hour > 12 ? $"{time.Hour - 12}:{time.Minute} {GetMsg(userID, "UI_PM")}" : $"{time.ToShortTimeString()} {GetMsg(userID, "UI_AM")}";
}
private string TimeString(int hours, int minutes, string userID) {
var time = string.Empty;
time += hours >= 10 ? $"{hours}:" : $"0{hours}:";
time += minutes >= 10 ? $"{minutes}" : $"0{minutes}";
if (_config.TimeFormat) return time;
return hours > 12 ? minutes >= 10 ? $"{hours - 12}:{minutes} {GetMsg(userID, "UI_PM")}" : $"{hours - 12}:0{minutes} {GetMsg(userID, "UI_PM")}" : $"{time} {GetMsg(userID, "UI_AM")}";
}
private DateTime Time => DateTime.UtcNow.AddMinutes(_config.TimeZone);
private bool InCorrectZone(BaseEntity entity) {
if (_config.ZoneManagerSettings == "DISABLED" || ZoneManager == null) return true;
if (_config.ZoneManagerSettings == "TRUE") {
foreach (var check in _config.ZoneIDs) if (ZoneManager.Call<bool>("IsEntityInZone", check, entity)) return true;
return false;
}
foreach (var check in _config.ZoneIDs) if (ZoneManager.Call<bool>("IsEntityInZone", check, entity)) return false;
return true;
}
#endregion
#region UI
#region LowerCenterLite
private void ShowUILowerCenterLiteChange(BasePlayer player = null) {
var container = new CuiElementContainer();
var currentDay = Time;
var time = _config.BlockByDay.FirstOrDefault(x => x.Key == $"{currentDay.Month}/{currentDay.Day}/{currentDay.Year}").Value ?? _config.BlockByWeekDay[new DateTime(currentDay.Year, currentDay.Month, currentDay.Day).DayOfWeek.ToString()];
var currentPos = (currentDay.Hour * 60 + currentDay.Minute) / 1440f;
container.Add(new CuiPanel {
RectTransform = {
AnchorMin = "0.31 0.03", AnchorMax = "0.89 0.07"
}
, Image = {
Color = "0.2 0.6 0.2 1"
}
}
, Layer + ".HUD", Layer + ".timeLine");
foreach (var check in time) {
var startPos = (check.StartHours * 60 + check.StartMinutes) / 1440f;
var stopPos = (check.StopHours * 60 + check.StopMinutes) / 1440f;
container.Add(new CuiPanel {
RectTransform = {
AnchorMin = $"{startPos} 0", AnchorMax = $"{stopPos} 0.78"
}
, Image = {
Color = "0.6 0.2 0.2 1"
}
}
, Layer + ".timeLine");
}
container.Add(new CuiElement {
Parent = Layer + ".timeLine", Components = {
new CuiImageComponent {
Color = "1 1 1 1"
}
, new CuiRectTransformComponent {
AnchorMin = $"{currentPos} 0", AnchorMax = $"{currentPos} 0.9", OffsetMin = "-1 -2", OffsetMax = "1 2"
}
, new CuiOutlineComponent {
Color = "0 0 0 1", Distance = "-0.5 -0.5"
}
}
}
);
container.Add(new CuiPanel {
RectTransform = {
AnchorMin = "0.155 0", AnchorMax = "0.33 0.1"
}
, Image = {
Color = "0 0 0 0"
}
}
, Layer + ".HUD", Layer + ".raideTimeStatus");
container.Add(new CuiPanel {
RectTransform = {
AnchorMin = "0.15 0.4", AnchorMax = "0.18 0.6"
}
, Image = {
Color = CanRaidNow ? "1 0 0 1" : "0 1 0 1", Sprite = "assets/icons/isbroken.png"
}
}
, Layer + ".raideTimeStatus");
if (player == null) {
foreach (var check in BasePlayer.activePlayerList) {
if (ClosedUI.Contains(check.userID)) continue;
var container1 = new CuiElementContainer();
container1.Add(new CuiLabel {
RectTransform = {
AnchorMin = "0.225 0", AnchorMax = "1 1", OffsetMin = "0 0", OffsetMax = "0 0"
}
, Text = {
Text = CanRaidNow ? GetMsg(check.UserIDString, "UI_RAID_TIME") : GetMsg(check.UserIDString, "UI_SAFE_TIME"), FontSize = 9, Font = "robotocondensed-regular.ttf", Color = "1 1 1 1", Align = TextAnchor.MiddleLeft
}
}
, Layer + ".raideTimeStatus");
CuiHelper.DestroyUi(check, Layer + ".time");
CuiHelper.DestroyUi(check, Layer + ".timeLine");
CuiHelper.DestroyUi(check, Layer + ".raideTimeStatus");
CuiHelper.DestroyUi(check, Layer + ".dayTime");
CuiHelper.AddUi(check, container);
CuiHelper.AddUi(check, container1);
}
return;
}
container.Add(new CuiLabel {
RectTransform = {
AnchorMin = "0.225 0", AnchorMax = "1 1", OffsetMin = "0 0", Of
// ... [Code preview truncated due to length. Full source in attached file] ...