C#:
using CompanionServer;
using ConVar;
using Network;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Configuration;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using Oxide.Game.Rust.Libraries.Covalence;
using Rust.Workshop;
using Steamworks;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using UnityEngine;
using Connection = Network.Connection;
using Net = Network.Net;
using Pool = Facepunch.Pool;
namespace Oxide.Plugins {
[Info("Compilation", "Shady", "1.0.0", ResourceId = 0)]
internal class Compilation : RustPlugin {
/*
* Copyright 2024 PRISM
*
* This file is part of PRISM's plugins.*
* PRISM's plugins is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.*
* PRISM's plugins is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* GNU General Public License for more details.*
* You should have received a copy of the GNU General Public License
* along with PRISM's plugins.If not, see <https://www.gnu.org/licenses/>.*/
/*
* The below is not a license (that can be found above), but simply a notice to the reader of this code:
* The development of PRISM has been gradual and started in 2014.* Some of the code provided in this repository may be outdated and may not be the best representation of the author's current coding practices.* Some of the code provided in this repository may have been initially developed in 2014.* Files not containing the above license are not uniquely part of PRISM's plugins and are subject to the license of the original plugin, where applicable.* No copyright infringement is ever intended and the author of PRISM's plugins will comply with any requests to remove code.* PRISM's plugins are provided as is and no functionality is guaranteed.* Many of these plugins will not work without significant changes as there are numerous instances of hard-coded functions and may rely on external API calls that are not a part of this project itself.*
*
* With those notices out of the way, I, Shady, the author of this plugin, would like you to read and acknowledge the following:
* These plugins are part of a decade long passion project where we, PRISM, created a unique experience to all players on our Rust servers.* This was a significant part of my life.I dedicated a decade to developing and maintaining these plugins and the servers themselves.* I implore you that, should you use any of the code or plugins provided in this repository, where it belongs solely to PRISM, that you respect the time and effort put into it.* Please remember that I, a single human, invested a significant amount of time and effort into these plugins and the servers they were used on.* Please feel free to critique my code as it is written; I am aware it is not perfect.Much of it is old, and I'm capable of doing far better now.* Moreover, I ask, sincerely, that you do not use these plugins or code without acknowledging that someone dedicated themselves to this passion project.* In asking that, it is my simple desire that you do not let these plugins be used in a way that is inconsistent with my own desires and love.* Please do not use them and claim them as your own.I wish for you to use them on your server and make that server something of your own.* Something unique and beautiful.However, I ask that you do not use these plugins and claim them as your own work.* Should you make changes to them, you are, of course, the author of those changes.But, if your code is based on one of PRISM's original plugins, please do not claim it as your own.* I also request that you do not use the plugins in a way that would be detrimental to the Rust community or the community of server owners.* In doing so, I ask that you please do not monetize the functions within these plugins with any changes you should make.* Should you use any of PRISM's plugins or its code, please do not lock anything behind a paywall or in a way that is unfair to the community of Rust.* My origin is that of one where I saw, daily, very young players who only wished to enjoy a few hours of their life on a video game and in many cases had little or no expendable income.* For many people, even purchasing the game is significantly difficult.It is, in my eyes, unfair to create fun, custom content, and suggest that you care about the community while also charging for it or creating an unfair environment where players who pay are significantly advantaged compared to those who cannot afford to do so.* I cannot control what you do with this code, but I ask that you respect the spirit in which it was created:
* That is one of sincere love, care, and appreciation for the people who played on PRISM's servers.* Our community, much like yours, is your entire server.Your people matter, just as you matter.Please remember that *everyone* deserves a fair, fun environment.* I ask that should you use these plugins, you do so with the same love and care that I put into them.I ask that you do so with the same respect, love, care, and appreciation for the people who will play on your server.*
* One of my greatest helps over the years was MBR.He has been a wonderful person, friend, and developer; I am beyond grateful for his contributions to us, but moreover, his friendship.* Some of these plugins were authored solely by him, or with his help.Where this has occurred, it should be noted in the author field at the top of the plugin.* Worthy of note is that he is solely responsible for our top-tier Discord integration.* If you so wish to see his GitHub page, here it is linked below:
* https://github.com/MBR-0001
*
*
* Should you wish to support the work that I have put into this project of the past decade, please consider doing so here:
* https://www.buymeacoffee.com/shady757
*
* I neither expect nor anticipate any such donations.You are by no means obligated, it is truly a donation.It should be done out of the kindness of your heart, if you so choose.*
* PRISM, as a community, has not ceased and continues to exist.We have no plans of ceasing our community.We have, however, ceased our Rust servers and thus made these plugins open source.* If you ever wish to contact me, or simply join our community and become one of our beloved members, please join us here:
* https://discord.gg/DUCnZhZ
*
* To quote Rush: "There is magic at your fingers".* With love,
* Shady and all of PRISM.Thank you for everything, always.*
*/
/*/
* God With Us.(Gott Mit Uns)
* /*/
//i purple you
private const string CHAT_STEAM_ID = "76561198865536053";
private const string SHOCK_EFFECT = "assets/prefabs/locks/keypad/effects/lock.code.shock.prefab";
private const string PRISM_RAINBOW_TXT = "<color=#FF0030>P</color><color=#FE950A>R</color><color=#FEF506>I</color><color=#53D559>S</color><color=#2BACE2>M</color>";
private const string PRISM_UX_CHAT_PREFIX = "<color=#FF0030>P</color><color=#FE950A>R</color><color=#FEF506>I</color><color=#53D559>S</color><color=#2BACE2>M</color> | <color=#fffcb5>UX:</color> ";
private const uint TEST_RIDABLE_HORSE_PREFAB_ID = 2421623959;
private const uint MURDERER_CORPSE_PREFAB_ID = 2400390439;
private const int SCRAP_ITEM_ID = -932201673;
private readonly HashSet<int> _ignoreItems = new() {
878301596, -2027988285, -44066823, -1364246987, 62577426, 1776460938, -17123659, 999690781, -810326667, 996757362, 1015352446, 1414245162, -1449152644, -187031121, 1768112091, 1770744540, -602717596, 1223900335, 1036321299, 204970153, 236677901, -399173933, 1561022037, 1046904719, 1394042569, -561148628, 861513346, -1366326648, -1884328185, 1878053256, 550753330, 696029452, 755224797, 1230691307, 1364514421, -455286320, 1762167092, -282193997, 180752235, -1386082991, 70102328, 22947882, 81423963, 1409529282, -1779180711, -277057363, -544317637, 1113514903
}
;
private readonly HashSet<string> _forbiddenTags = new() {
"</color>", "</size>", "<b>", "</b>", "<i>", "</i>"
}
;
private readonly Regex _colorRegex = new("(<color=.+?>)", RegexOptions.Compiled);
private readonly Regex _sizeRegex = new("(<size=.+?>)", RegexOptions.Compiled);
private readonly Regex _hexRegex = new(@"^#(?:[0-9a-fA-F]{3}){1,2}$", RegexOptions.Compiled);
//private readonly Regex _discordServerEmojiRegex = new Regex("<:[a-zA-Z0-9]+:[0-9]+>", RegexOptions.Compiled);
private readonly Regex _discordServerEmojiRegex = new("<:[a-zA-Z0-9_]+:[0-9]+>", RegexOptions.Compiled);
private readonly StringBuilder _decaySbBuffer = new();
private readonly HashSet<Coroutine> _coroutines = new();
private readonly Dictionary<string, StringBuilder> rocketBuffer = new();
// private readonly FieldInfo lastWoundedTime = typeof(BasePlayer).GetField("lastWoundedTime", BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
private readonly FieldInfo curList = typeof(InvokeHandler).GetField("curList", BindingFlags.Instance | BindingFlags.NonPublic);
private readonly FieldInfo restartCoroutine = typeof(ServerMgr).GetField("restartCoroutine", BindingFlags.Instance | BindingFlags.NonPublic);
private readonly FieldInfo upkeepBrackets = typeof(BuildingPrivlidge).GetField("upkeepBrackets", BindingFlags.Static | BindingFlags.NonPublic);
private readonly BaseEntity.RPCMessage _defaultMessage = new();
private readonly int _constructionColl = LayerMask.GetMask(new string[] {
"Construction", "Deployable", "Prevent Building", "Deployed"
}
);
public readonly int deployColl = LayerMask.GetMask(new string[] {
"Deployable", "Deployed"
}
);
private const int CONSTRUCTION_LAYER = Rust.Layers.Construction;
//LayerMask.GetMask(new string[] { "Construction" });
private const int PLAYER_LAYER = 131072;
//LayerMask.GetMask(new string[] { "Player (Server)" });
private readonly int defaultColl = LayerMask.GetMask("Default");
private readonly int groundWorldLayer = LayerMask.GetMask("World", "Default", "Terrain");
private readonly int groundWorldConstLayer = LayerMask.GetMask("World", "Default", "Terrain", "Construction", "Deployable", "Prevent Building", "Deployed");
private const int flamerColl = 1084427009;
private const int c4Coll = 2230528;
private readonly HashSet<PlayerCorpse> allPlayerCorpses = new();
private readonly HashSet<BaseNpc> allAnimals = new();
private readonly HashSet<LootContainer> allContainers = new();
private bool init = false;
private readonly System.Random randomSpawn = new();
private readonly string[] invalidNames = {
"battlegroundsrust", "rusteo.com", "zombienation", "knightstable", "changeme", "changeyourname"
}
;
private DateTime SaveTime {
get {
return SaveRestore.SaveCreatedTime;
}
}
private DateTime LocalSaveTime {
get {
return SaveRestore.SaveCreatedTime.ToLocalTime();
}
}
private TimeSpan SaveSpan {
get {
return DateTime.UtcNow - SaveRestore.SaveCreatedTime;
}
}
private TimeSpan LocalSaveSpan {
get {
return DateTime.Now - SaveRestore.SaveCreatedTime.ToLocalTime();
}
}
private float ScaleHours(float value, float offsetMult = 1f) {
if (IsEasyServer()) value *= 0.66f;
var span = GetWipeDate() - LocalSaveTime;
return ((span.TotalDays < 12.5) ? (value / 2.5f) : value) * offsetMult;
}
private readonly HashSet<DroppedItem> droppedItems = new();
private readonly List<int> allBlueprints = new();
private List<string> halucFXs = new();
private bool IsNight() {
return TOD_Sky.Instance.Cycle.Hour > TOD_Sky.Instance.SunsetTime || TOD_Sky.Instance.Cycle.Hour < TOD_Sky.Instance.SunriseTime;
}
private bool IsNight(float offset) {
return TOD_Sky.Instance.Cycle.Hour > (TOD_Sky.Instance.SunsetTime + offset) || TOD_Sky.Instance.Cycle.Hour < TOD_Sky.Instance.SunriseTime;
}
private bool IsAM() {
return TOD_Sky.Instance.Cycle.Hour <= TOD_Sky.Instance.SunriseTime;
}
public EnvSync EnvSync {
get {
if (_envSync == null) {
foreach (var entity in BaseNetworkable.serverEntities) {
var sync = entity as EnvSync;
if (sync != null) {
_envSync = sync;
break;
}
}
}
return _envSync;
}
}
private EnvSync _envSync = null;
private bool? _wasEasy;
private bool IsEasyServer() {
if (_wasEasy.HasValue) return (bool)_wasEasy;
var val = ConVar.Server.hostname.Contains("#2") || ConVar.Server.hostname.Contains("#3");
_wasEasy = val;
return val;
}
private bool? _wasHard;
private bool IsHardServer() {
if (_wasHard.HasValue) return (bool)_wasHard;
var val = ConVar.Server.hostname.Contains("RED");
_wasHard = val;
return val;
}
private enum ServerType {
None, x3, x10, BF
}
private ServerType serverType = ServerType.None;
private bool IsStreamerMode(BasePlayer player) {
if (player == null || !player.IsConnected) return false;
return player?.net?.connection?.info?.GetBool("global.streamermode", false) ?? false;
}
public string PluginNamePrefix {
get {
return Name + ":";
}
}
public readonly Regex basicLatin = new(@"^[\P{L}\p{IsBasicLatin}]+$", RegexOptions.Compiled);
private HashSet<T> ToHashSet<T>(HashSet<T> hash) {
return new HashSet<T>(hash);
}
private HashSet<T> ToHashSet<T>(List<T> list) {
return new HashSet<T>(list);
}
private HashSet<T> ToHashSet<T>(IEnumerable<T> enumerable) {
return new HashSet<T>(enumerable);
}
private PatrolHelicopter ActiveHeli {
get {
return PatrolHelicopterAI.heliInstance?.helicopterBase ?? null;
}
}
private PatrolHelicopterAI ActiveHeliAI {
get {
return PatrolHelicopterAI.heliInstance;
}
}
private bool IsLooting(BasePlayer player) {
return player?.inventory?.loot?.entitySource != null;
}
private readonly Dictionary<ulong, Vector3> cachedRotation = new();
public static Compilation ins;
private Vector3 GetPlayerRotation(BasePlayer player) {
return player == null ? Vector3.zero : Quaternion.Euler(player?.serverInput?.current?.aimAngles ?? Vector3.zero) * Vector3.forward;
}
private DateTime GetWipeDate() {
return WipeInfo?.Call<DateTime>("GetWipeDate") ?? DateTime.MinValue;
}
private Quaternion GetPlayerRotationQ(BasePlayer player) {
return Quaternion.Euler(player?.serverInput?.current?.aimAngles ?? Vector3.zero);
}
private bool IsNullOrEmpty<T>(List<T> List) {
return (List?.Count ?? 0) < 1;
}
[PluginReference]
private readonly Plugin PlayersByDatabase;
[PluginReference]
private readonly Plugin SteamBansAPI;
[PluginReference]
private readonly Plugin Clans;
[PluginReference]
private readonly Plugin ZoneManager;
[PluginReference]
private readonly Plugin Godmode;
[PluginReference]
private readonly Plugin WipeInfo;
[PluginReference]
private readonly Plugin AAIPDatabase;
[PluginReference]
private readonly Plugin BanSystem;
[PluginReference]
private readonly Plugin SteamStatsAPI;
[PluginReference]
private readonly Plugin SkinsAPI;
[PluginReference]
private readonly Plugin Deathmatch;
[PluginReference]
private readonly Plugin Vanish;
[PluginReference]
private readonly Plugin ServerESP;
[PluginReference]
private readonly Plugin Known;
[PluginReference]
private readonly Plugin LocalStatsAPI;
[PluginReference]
private readonly Plugin Friends;
[PluginReference]
private readonly Plugin FindGround;
[PluginReference]
private readonly Plugin NoEscape;
[PluginReference]
private readonly Plugin BetterChat;
[PluginReference]
private readonly Plugin NTeleportation;
[PluginReference]
private readonly Plugin Vote;
[PluginReference]
private readonly Plugin OneCountry;
[PluginReference]
private readonly Plugin DiscordAPI2;
[PluginReference]
private readonly Plugin Luck;
[PluginReference]
private readonly Plugin Playtimes;
private Dictionary<string, int> newsLevel;
//read from data
public class MovementLog {
[JsonProperty(PropertyName = "t", Required = Required.AllowNull, NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)]
private string _time = string.Empty;
[JsonProperty(PropertyName = "p", Required = Required.AllowNull, NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)]
private string _pos = string.Empty;
[JsonIgnore]
public Vector3 Position {
get {
return GetVector3FromString(_pos);
}
set {
_pos = value.ToString().Replace("(", "").Replace(")", "");
}
}
[JsonIgnore]
public DateTime Time {
get {
if (DateTime.TryParse(_time, out DateTime time)) return time;
return DateTime.MinValue;
}
set {
_time = value.ToString();
}
}
public MovementLog() {
}
public MovementLog(Vector3 position, DateTime time) {
if (position == Vector3.zero || time == DateTime.MinValue) return;
Position = position;
Time = time;
}
}
public class MovementInfo {
[JsonProperty(PropertyName = "id", NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)]
public ulong UserID = 0;
[JsonIgnore]
public string UserIDString {
get {
return UserID.ToString();
}
set {
if (ulong.TryParse(value, out ulong uid)) UserID = uid;
}
}
[JsonProperty(PropertyName = "l", NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)]
public List<MovementLog> Logs = new();
public MovementInfo() {
}
public MovementInfo(string userID) {
if (!string.IsNullOrEmpty(userID)) UserIDString = userID;
}
public MovementInfo(ulong userID) {
UserID = userID;
}
}
private MovementData moveData;
private class MovementData {
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)]
public List<MovementInfo> infos = new();
public MovementData() {
}
}
private void AddMovementLog(ulong userID, Vector3 position, DateTime time) {
if (userID == 0 || position == Vector3.zero || time == DateTime.MinValue || moveData?.infos == null) {
PrintWarning("AddMovementLog called with bad args or moveData.infos == null!!!");
return;
}
MovementInfo findInfo = null;
for (int i = 0; i < moveData.infos.Count; i++) {
var info = moveData.infos[i];
if (info != null && info.UserID == userID) {
findInfo = info;
break;
}
}
if (findInfo == null) {
findInfo = new MovementInfo(userID);
if (!moveData.infos.Contains(findInfo)) moveData.infos.Add(findInfo);
}
if (findInfo?.Logs == null) findInfo.Logs = new List<MovementLog>();
var lastPos = findInfo.Logs.Count > 0 ? findInfo?.Logs[findInfo.Logs.Count - 1]?.Position ?? Vector3.zero : Vector3.zero;
if (lastPos != Vector3.zero && Vector3.Distance(lastPos, position) <= 0.75f) return;
findInfo.Logs.Add(new MovementLog(position, time));
}
private void AddMovementLog(string userID, Vector3 position, DateTime time) {
if (!ulong.TryParse(userID, out ulong uID)) return;
else AddMovementLog(uID, position, time);
}
private List<MovementLog> GetMovementLogs(ulong userID, TimeSpan maxLogAge = default) {
if (moveData?.infos == null || moveData.infos.Count < 1) {
PrintWarning("no move log infos");
return null;
}
var isDefaultAge = maxLogAge == default;
var now = DateTime.UtcNow;
PrintWarning("GetMovementLogs called: " + userID + " , maxLogAge: " + maxLogAge);
for (int i = 0; i < moveData.infos.Count; i++) {
var info = moveData.infos[i];
if (info?.Logs == null) {
PrintWarning("info?.Logs == null for index: " + i + "!!");
continue;
}
if (info.UserID != userID) continue;
if (isDefaultAge) {
PrintWarning("no max age specified, returning info.Logs with count: " + info.Logs.Count + " for: " + userID);
return info.Logs;
}
else {
var newLogs = new List<MovementLog>();
if (info.Logs.Count > 0) {
for (int j = 0; j < info.Logs.Count; j++) {
var log = info.Logs[j];
if (log != null && (log.Time <= DateTime.MinValue || (now - log.Time) <= maxLogAge)) newLogs.Add(log);
}
}
return newLogs;
}
}
return null;
}
private class BPInfo {
public ulong UserID = 0;
public List<int> unlocked = new();
public bool IsUnlocked(int itemid) => unlocked.Contains(itemid);
public void Unlock(int itemid) {
if (!unlocked.Contains(itemid)) unlocked.Add(itemid);
}
public void Lock(int itemid) {
if (unlocked.Contains(itemid)) unlocked.Remove(itemid);
}
public BPInfo() {
}
public BPInfo(ulong uid) {
UserID = uid;
}
}
private class BPData {
public List<BPInfo> blueprints = new();
public BPInfo GetBPInfo(ulong userID) {
if (blueprints?.Count < 1) return null;
for (int i = 0; i < blueprints.Count; i++) {
var bp = blueprints[i];
if (bp?.UserID == userID) return bp;
}
return null;
}
public bool HasBPInfo(ulong userID) {
if (blueprints?.Count < 1) return false;
for (int i = 0; i < blueprints.Count; i++) {
var bp = blueprints[i];
if (bp?.UserID == userID) return true;
}
return false;
}
public BPInfo AddBPInfo(ulong userID) {
if (!HasBPInfo(userID)) {
var bpInfo = new BPInfo(userID);
blueprints.Add(bpInfo);
return bpInfo;
}
else return GetBPInfo(userID);
}
public BPData() {
}
}
private class TagData {
public List<TagInfo> tagList = new();
public TagData() {
}
}
private class TagInfo {
public string permission = string.Empty;
public ulong userID = 0;
public string UserIDString {
get {
return userID.ToString();
}
set {
if (ulong.TryParse(value, out ulong id)) userID = id;
}
}
public string colorOverride = string.Empty;
public bool hide = false;
}
private TagData tagData;
private BPData bpData;
private void SaveTagData() => Interface.Oxide.DataFileSystem.WriteObject("TagData", tagData);
private void SaveNewsData() => Interface.Oxide.DataFileSystem.WriteObject("NewsLevel", newsLevel);
private void SaveBPData() {
if (bpData?.blueprints != null && bpData.blueprints.Count > 0) Interface.Oxide.DataFileSystem.WriteObject("BPData", bpData);
}
private void SaveRangeData() {
if (turretRange != null && turretRange.Count > 0) {
var toRemove = new HashSet<NetworkableId>();
foreach (var kvp in turretRange) {
var foundTurret = false;
foreach (var ent in BaseEntity.saveList) {
if (ent?.net?.ID == kvp.Key) {
foundTurret = true;
break;
}
}
if (!foundTurret) toRemove.Add(kvp.Key);
}
foreach (var key in toRemove) turretRange.Remove(key);
}
Interface.Oxide.DataFileSystem.WriteObject("TurretRange", turretRange);
}
private void LoadRangeData() {
turretRange = Interface.Oxide?.DataFileSystem?.ReadObject<Dictionary<NetworkableId, float>>("TurretRange") ?? new Dictionary<NetworkableId, float>();
if (turretRange != null && turretRange.Count > 0) {
foreach (var kvp in turretRange) {
AutoTurret findTurret = null;
foreach (var ent in BaseEntity.saveList) {
if (ent?.net?.ID == kvp.Key) {
findTurret = ent as AutoTurret;
break;
}
}
if (findTurret != null && !findTurret.IsDestroyed) {
findTurret.sightRange = kvp.Value;
findTurret.SendNetworkUpdate();
}
}
}
}
public bool IsPurging {
get;
set;
}
= false;
private System.Collections.IEnumerator PurgeMoveData2() {
if (IsPurging) yield return null;
var watch = Stopwatch.StartNew();
Puts("Beginning PurgeMoveData2()");
IsPurging = true;
var totalCount = 0;
var enumCount = 0;
var enumMax = 20;
var logMax = 50;
var utcNow = DateTime.UtcNow;
for (int i = 0; i < moveData.infos.Count; i++) {
var info = moveData.infos[i];
if (info == null || info.Logs == null || info.Logs.Count < 1) continue;
int logCount = 0;
enumCount++;
if (enumCount >= enumMax) {
enumCount = 0;
yield return CoroutineEx.waitForEndOfFrame;
}
var toRemove = new HashSet<MovementLog>();
for (int j = 0; j < info.Logs.Count; j++) {
var log = info.Logs[j];
if (log == null) continue;
if (logCount >= logMax) {
logCount = 0;
yield return CoroutineEx.waitForEndOfFrame;
}
if ((utcNow - log.Time).TotalHours > 4) toRemove.Add(log);
logCount++;
}
totalCount += toRemove.Count;
if (toRemove.Count > 0) foreach (var log in toRemove) info.Logs.Remove(log);
}
IsPurging = false;
watch.Stop();
PrintWarning("Removed " + totalCount.ToString("N0") + " logs older than 4 hours (coroutine) (took: " + watch.Elapsed.TotalMilliseconds + "ms).");
}
private string PlayerListString = string.Empty;
private Admin.PlayerInfo[] GetPlayerList() {
var count = BasePlayer.activePlayerList.Count;
if (count < 1) return null;
var array = new Admin.PlayerInfo[count];
for (int i = 0; i < count; i++) {
var x = BasePlayer.activePlayerList[i];
array[i] = new Admin.PlayerInfo {
SteamID = x.UserIDString, OwnerSteamID = x.OwnerID.ToString(), DisplayName = x.displayName, Ping = (x?.net?.connection == null) ? -1 : Net.sv.GetAveragePing(x.net.connection), Address = (x?.net?.connection == null) ? string.Empty : x.net.connection.ipaddress, ConnectedSeconds = (x?.net?.connection == null) ? -1 : (int)x.net.connection.GetSecondsConnected(), VoiationLevel = x.violationLevel, Health = x.Health()
}
;
}
return array;
}
private System.Collections.IEnumerator LoadAllHalucFX() {
yield return CoroutineEx.waitForEndOfFrame;
var strs = GameManifest.Current.pooledStrings;
halucFXs = new List<string>();
var cur = 0;
var max = 75;
for (int i = 0; i < strs.Length; i++) {
var str = strs[i];
if (cur >= max) {
cur = 0;
yield return CoroutineEx.waitForEndOfFrame;
}
if (string.IsNullOrEmpty(str.str)) continue;
if (str.str.Contains("assets/bundled/prefabs/fx/impacts/") || str.str.EndsWith("attack.prefab") || str.str.EndsWith("attack_muzzlebrake") || str.str.EndsWith("attack_silenced")) halucFXs.Add(str.str);
cur++;
}
// halucFXs = GameManifest.Current.pooledStrings?.Select(p => p.str)?.Where(p => p.Contains("assets/bundled/prefabs/fx/impacts/") || p.EndsWith("attack.prefab") || p.EndsWith("attack_muzzlebrake") || p.EndsWith("attack_silenced"))?.ToList() ?? new List<string>();
halucFXs.Add("assets/bundled/prefabs/fx/build/promote_toptier.prefab");
halucFXs.Add("assets/bundled/prefabs/fx/collect/collect stone.prefab");
halucFXs.Add("assets/bundled/prefabs/fx/collect/collect stump.prefab");
halucFXs.Add("assets/bundled/prefabs/fx/collect/collect plant.prefab");
halucFXs.Add("assets/bundled/prefabs/fx/impacts/additive/explosion.prefab");
halucFXs.Add("assets/bundled/prefabs/fx/explosions/water_bomb.prefab");
halucFXs.Add("assets/bundled/prefabs/fx/entities/loot_barrel/impact.prefab");
halucFXs.Add("assets/bundled/prefabs/fx/entities/loot_barrel/gib.prefab");
halucFXs.Add("assets/bundled/prefabs/fx/impacts/stab/rock/stab_rock_01.prefab");
halucFXs.Add("assets/bundled/prefabs/fx/player/howl.prefab");
halucFXs.Add("assets/bundled/prefabs/fx/player/gutshot_scream.prefab");
halucFXs.Add("assets/bundled/prefabs/fx/weapons/landmine/landmine_trigger.prefab");
yield return CoroutineEx.waitForSeconds(0.05f);
halucFXs.Add("assets/prefabs/locks/keypad/effects/lock.code.denied.prefab");
halucFXs.Add("assets/prefabs/npc/autoturret/effects/targetacquired.prefab");
halucFXs.Add("assets/prefabs/npc/autoturret/effects/targetlost.prefab");
halucFXs.Add("assets/prefabs/npc/m2bradley/effects/coaxmgmuzzle.prefab");
halucFXs.Add("assets/prefabs/npc/murderer/sound/breathing.prefab");
halucFXs.Add("assets/prefabs/npc/murderer/sound/death.prefab");
halucFXs.Add("assets/bundled/prefabs/fx/oiljack/pump_up.prefab");
halucFXs.Add("assets/bundled/prefabs/fx/oiljack/pump_down.prefab");
halucFXs.Add("assets/prefabs/tools/c4/effects/c4_stick.prefab");
}
//emitted by SteamAuthOverride *after* the connection was approved, oxide hooks don't provide that
private void OnConnectionApproved(Connection connection) {
if (connection == null) return;
timer.Once(0.5f, () => {
if (connection == null) return;
var netWrite = Net.sv.StartWrite();
netWrite.PacketID(Message.Type.Message);
netWrite.String("<size=52><color=#FF0030>P</color><color=#FE950A>R</color><color=#FEF506>I</color><color=#53D559>S</color><color=#2BACE2>M</color></size>");
netWrite.String(string.Empty);
netWrite.Send(new SendInfo(connection));
}
);
}
private void Init() {
var watch = Stopwatch.StartNew();
ins = this;
Unsubscribe(nameof(OnEntityDeath));
Unsubscribe(nameof(OnEntityTakeDamage));
Unsubscribe(nameof(OnPlayerInput));
// Subscribe(nameof(CanCustomNetworkTo));
var watchData = Stopwatch.StartNew();
// if ((suspectData = Interface.Oxide.DataFileSystem.ReadObject<SuspectData>("SuspectData")) == null) suspectData = new SuspectData();
if ((tagData = Interface.Oxide.DataFileSystem.ReadObject<TagData>("TagData")) == null) tagData = new TagData();
if ((bpData = Interface.Oxide.DataFileSystem.ReadObject<BPData>("BPData")) == null) bpData = new BPData();
newsLevel = Interface.Oxide?.DataFileSystem?.ReadObject<Dictionary<string, int>>("NewsLevel") ?? new Dictionary<string, int>();
moveData = new MovementData();
watchData.Stop();
jsonsettings = new JsonSerializerSettings();
jsonsettings.Converters.Add(new KeyValuesConverter());
var perms = new List<string>(15) {
"warn", "say", "tp", "mcpick", "steamid", "alias", "clearchat", "getup", "blind", "pinfo", "heal", "bug", "sapi", "teleportany", "nojoinmsg"
}
;
for (int i = 0; i < perms.Count; i++) {
var permName = Name + "." + perms[i];
if (!permission.PermissionExists(permName, this)) permission.RegisterPermission(permName, this);
}
var watchCmd = Stopwatch.StartNew();
string[] donateCommands = {
"donate", "vipd", "mvp", "donating"
}
;
string[] playersByDatabaseDebugCmds = {
"pbd"
}
;
string[] addVmCmds = {
"addvm", "vmadd", "vmorder", "addorder"
}
;
AddCovalenceCommand(addVmCmds, nameof(cmdAddVendingMachineSellOrder));
AddCovalenceCommand(playersByDatabaseDebugCmds, nameof(cmdPbdDebug));
AddCovalenceCommand("loot.delete", nameof(cmdKillAllLoot));
AddCovalenceCommand("movelog", "cmdMoveLog");
AddCovalenceCommand(donateCommands, "cmdDonate");
AddCovalenceCommand("joinmsg", "cmdJoinMsg");
string[] playerCmds = {
"players", "online", "who", "pop", "population", "player"
}
;
string[] ipCmds = {
"10x", "2x", "0.5x", "server2", "server1", "3x", "#2", "#1", "ip", "ips", "server", "servers", "prism", "1x", "red", "blue", "arpg"
}
;
AddCovalenceCommand(ipCmds, "cmdServers");
AddCovalenceCommand(playerCmds, nameof(cmdPlayers));
AddCovalenceCommand("popupall", "cmdPopup");
AddCovalenceCommand("sapi", "cmdInfo");
AddCovalenceCommand("pinfo", nameof(cmdPInfo));
AddCovalenceCommand("steamid", "cmdSteamID");
AddCovalenceCommand("gameban", "cmdGameBan");
AddCovalenceCommand("fc", "cmdForceCommand");
AddCovalenceCommand("teleportany", "cmdTeleportAny");
string[] adminHelpCmds = {
"hack", "hacks", "hacker", "cheats", "cheat", "cheaters", "hax", "admin", "admins", "mods", "reporth", "reporthelp", "adm", "mod", "moderator", "administrator"
}
;
string[] contactCmds = {
"contact", "ts3", "disc", "discord", "discordlink", "tslink", "teamspeak", "client", "download"
}
;
string[] shopCmds = {
"vms", "vm", "vending", "battery", "batteries", "sell", "vendingmachine", "vendingmachines"
}
;
string[] townCmds = {
"town", "towns", "outpost", "bandit", "banditcamp"
}
;
AddCovalenceCommand(adminHelpCmds, "cmdAdminHelp");
AddCovalenceCommand(contactCmds, nameof(cmdContactHelp));
AddCovalenceCommand("playerlist", "cmdPlayerList");
string[] helpCmds = {
"help", "info", "infos", "information", "cmds", "commands", "how", "gelp", "helps", "hlep", "hepl"
}
;
AddCovalenceCommand(helpCmds, nameof(cmdHelp2));
AddCovalenceCommand(shopCmds, nameof(cmdShop));
AddCovalenceCommand("shock", nameof(cmdSlapPlayer));
string[] tagCmds = {
"tagc", "ctag", "tegc", "cteg", "tagcol", "coltag", "tagcolor", "tagcolors", "tagcolour", "tagcolours", "colortag", "namecolor", "colorname", "titlecolor"
}
;
AddCovalenceCommand(tagCmds, nameof(cmdTag));
timer.Once(1f, () => AddCovalenceCommand(townCmds, nameof(cmdTown)));
AddCovalenceCommand("setoldwipe", "cmdSetOldWipe");
AddCovalenceCommand("dumpe", "cmdEffectDump");
AddCovalenceCommand("frametest", "cmdFrameTest");
AddCovalenceCommand("gametags", "cmdGameTags");
AddCovalenceCommand("connections", "cmdConnections");
AddCovalenceCommand("idlers", "cmdIdlePlayers");
AddCovalenceCommand(new string[] {
"mymini", "Minicopter", "Minicopters", "myheli", "minimy"
}
, nameof(cmdMyMini));
watchCmd.Stop();
watch.Stop();
PrintWarning("Init() took: " + watch.Elapsed.TotalMilliseconds + "ms, watchData: " + watchData.Elapsed.TotalMilliseconds + "ms, watchCmd: " + watchCmd.Elapsed.TotalMilliseconds + "ms");
}
private void cmdForceCommand(IPlayer player, string command, string[] args) {
if (player == null) return;
if (!player.IsAdmin) return;
if (args.Length < 2) {
SendReply(player, "You must supply a target and command!");
return;
}
var target = FindConnectedPlayer(args[0]);
if (target == null) {
SendReply(player, "No target found by name: " + args[0]);
return;
}
var consCmd = !args[1].StartsWith("/", StringComparison.OrdinalIgnoreCase);
var cmdStr = (!consCmd ? "chat.say " + "\"" + args[1] : args[1]) + ((args.Length > 2) ? " " : "");
var cmdSB = Pool.Get<StringBuilder>();
try {
cmdSB.Clear().Append(cmdStr);
if (args.Length > 2) {
for (int i = 2; i < args.Length; i++) {
var arg = args[i];
cmdSB.Append(arg).Append(" ");
}
cmdSB.Length -= 1;
}
var cmd = cmdSB.Append(!consCmd ? "\"" : "").ToString();
target.Command(cmd);
PrintWarning("CMD: " + cmd);
}
finally {
Pool.Free(ref cmdSB);
}
}
private const string NEWS_URL = @"https://prismrust.com/api/discord/server-updates?simple=true";
private const string grulesURL = @"https://prismrust.com/api/rust/grules?simple=true";
private Timer _newsTimer = null;
public Timer NewsTimer {
get {
return _newsTimer;
}
set {
_newsTimer?.Destroy();
_newsTimer = value;
}
}
private DateTime lastNews = DateTime.MinValue;
private Timer pingCheck = null;
private Timer signTimer = null;
private int bingFailTimes = 0;
private MonumentInfo _largeOilRig = null;
public MonumentInfo LargeOilRig {
get {
if (_largeOilRig == null) {
for (int i = 0; i < TerrainMeta.Path.Monuments.Count; i++) {
var mon = TerrainMeta.Path.Monuments[i];
if (mon.displayPhrase.english.Contains("large oil rig", CompareOptions.OrdinalIgnoreCase)) {
_largeOilRig = mon;
break;
}
}
}
if (_largeOilRig == null) PrintError(nameof(_largeOilRig) + " could not be found!!!");
return _largeOilRig;
}
}
private MonumentInfo _oilRig = null;
public MonumentInfo SmallOilRig {
get {
if (_oilRig == null) {
for (int i = 0; i < TerrainMeta.Path.Monuments.Count; i++) {
var mon = TerrainMeta.Path.Monuments[i];
if (mon != LargeOilRig && mon.displayPhrase.english.Contains("oil rig", CompareOptions.OrdinalIgnoreCase)) {
_oilRig = mon;
break;
}
}
}
if (_oilRig == null) PrintError(nameof(_oilRig) + " could not be found!!!");
return _oilRig;
}
}
public bool IsMoveLogging {
get;
set;
}
= false;
private System.Collections.IEnumerator MoveLogAllPlayers() {
if (BasePlayer.activePlayerList != null && BasePlayer.activePlayerList.Count > 0 && !IsMoveLogging) {
IsMoveLogging = true;
try {
var count = 0;
var max = (int)Math.Round(BasePlayer.activePlayerList.Count * 0.25f, MidpointRounding.AwayFromZero);
for (int i = 0; i < BasePlayer.activePlayerList.Count; i++) {
var player = BasePlayer.activePlayerList[i];
if (player == null || player.gameObject == null || player.IsDestroyed || player?.transform == null || !player.IsConnected || player.IsSleeping() || player.IsDead() || player.IdleTime >= 20) continue;
if (count >= max) {
count = 0;
yield return CoroutineEx.waitForEndOfFrame;
}
var pos = player?.transform?.position ?? Vector3.zero;
if (pos == Vector3.zero) continue;
var newPos = new Vector3(pos.x, pos.y + 0.15f, pos.z);
AddMovementLog(player.userID, newPos, DateTime.UtcNow);
count++;
}
}
finally {
IsMoveLogging = false;
}
}
}
private string GetDescriptionFromData() {
var str = string.Empty;
try {
str = (Interface.Oxide?.DataFileSystem?.ReadObject<object>("Description") ?? null)?.ToString() ?? string.Empty;
}
catch (Exception ex) {
PrintError(ex.ToString() + Environment.NewLine + " ^ GetDescriptionFromData() ^ ");
}
return str;
}
private readonly bool oldUpkeep = ConVar.Decay.upkeep;
private readonly float oldScale = ConVar.Decay.scale;
private int _initFpsLimit = -1;
private void OnServerInitialized() {
try {
var watch = Stopwatch.StartNew();
if (ConVar.Server.hostname.Contains("#2")) serverType = ServerType.x10;
else if (ConVar.Server.hostname.Contains("#3")) serverType = ServerType.BF;
else serverType = ServerType.x3;
for (int i = 0; i < ItemManager.itemList.Count; i++) {
var item = ItemManager.itemList[i];
if (item?.Blueprint == null || !item.Blueprint.userCraftable || !item.Blueprint.isResearchable) continue;
allBlueprints.Add(item.itemid);
}
NewsTimer = timer.Every(1500f, () => {
if (lastNews != DateTime.MinValue && (DateTime.Now - lastNews).TotalSeconds < 1490) {
PrintWarning("NewsTimer ticked too quickly!!");
return;
}
BroadcastNews();
lastNews = DateTime.Now;
}
);
timer.Once(UnityEngine.Random.Range(25f, 45f), () => {
Action pingAct = null;
pin
// ... [Code preview truncated due to length. Full source in attached file] ...