C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
// Reference: Oxide.Ext.Rust
// Reference: Newtonsoft.Json
// Reference: UnityEngine
using Oxide.Core;
using Oxide.Core.Libraries;
using Oxide.Core.Plugins;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using UnityEngine;
using Rust;
namespace Oxide.Plugins {
[Info("FriendlyFire", "playrust.io / dcode", "1.3.4", ResourceId = 840)]
public class FriendlyFire : RustPlugin {
#region Rust:IO Bindings
private Library lib;
private MethodInfo isInstalled;
private MethodInfo hasFriend;
private MethodInfo addFriend;
private MethodInfo deleteFriend;
private void InitializeRustIO() {
lib = Interface.GetMod().GetLibrary<Library>("RustIO");
if (lib == null || (isInstalled = lib.GetFunction("IsInstalled")) == null || (hasFriend = lib.GetFunction("HasFriend")) == null || (addFriend = lib.GetFunction("AddFriend")) == null || (deleteFriend = lib.GetFunction("DeleteFriend")) == null) {
lib = null;
Puts("{0}: {1}", Title, "Rust:IO is not present.You need to install Rust:IO first in order to use this plugin!");
}
}
private bool IsInstalled() {
if (lib == null) return false;
return (bool)isInstalled.Invoke(lib, new object[] {
}
);
}
private bool HasFriend(string playerId, string friendId) {
if (lib == null) return false;
return (bool)hasFriend.Invoke(lib, new object[] {
playerId, friendId
}
);
}
private bool AddFriend(string playerId, string friendId) {
if (lib == null) return false;
return (bool)addFriend.Invoke(lib, new object[] {
playerId, friendId
}
);
}
private bool DeleteFriend(string playerId, string friendId) {
if (lib == null) return false;
return (bool)deleteFriend.Invoke(lib, new object[] {
playerId, friendId
}
);
}
#endregion
private List<ulong> manuallyEnabledBy = new List<ulong>();
private List<string> texts = new List<string>() {
"%NAME% is your friend and cannot be hurt.To disable this, unshare your location with %NAME% on the live map or type: <color=\"#ffd479\">/ff on</color>", "Usage: <color=\"#ffd479\">/ff [on|off]</color>", "Friendly fire is <color=#cd422b>enabled</color> for your friends:", "Friendly fire is <color=#8acd2b>disabled</color> for your friends:", "You do not have any friends currently.", "You may add or delete friends using the live map.", "To toggle friendly fire on or off, type: <color=\"#ffd479\">/ff on|off</color>", "Friendly fire for your friends is already <color=#cd422b>enabled</color>.Take care!", "You have <color=#cd422b>enabled</color> friendly fire for your friends.Take care!", "Friendly fire for your friends is already <color=#8acd2b>disabled</color>.They are safe!", "You have <color=#8acd2b>disabled</color> friendly fire for your friends.They are safe!", "<color=\"#ffd479\">/ff</color> - Displays your friendly fire status", "<color=\"#ffd479\">/ff on|off</color> - Toggles friendly fire <color=#cd422b>on</color> or <color=#8acd2b>off</color>"
}
;
private Dictionary<string, string> messages = new Dictionary<string, string>();
private Dictionary<string, DateTime> notificationTimes = new Dictionary<string, DateTime>();
// Translates a string
private string _(string text, Dictionary<string, string> replacements = null) {
if (messages.ContainsKey(text) && messages[text] != null) text = messages[text];
if (replacements != null) foreach (var replacement in replacements) text = text.Replace("%" + replacement.Key + "%", replacement.Value);
return text;
}
// Loads the default configuration
protected override void LoadDefaultConfig() {
var messages = new Dictionary<string, object>();
foreach (var text in texts) {
if (messages.ContainsKey(text)) Puts("{0}: {1}", Title, "Duplicate translation string: " + text);
else messages.Add(text, text);
}
Config["messages"] = messages;
}
// Gets a config value of a specific type
private T GetConfig<T>(string name, T defaultValue) {
if (Config[name] == null) return defaultValue;
return (T)Convert.ChangeType(Config[name], typeof(T));
}
[HookMethod("OnServerInitialized")]
void OnServerInitialized() {
try {
InitializeRustIO();
LoadConfig();
var customMessages = GetConfig<Dictionary<string, object>>("messages", null);
if (customMessages != null) foreach (var pair in customMessages) messages[pair.Key] = Convert.ToString(pair.Value);
}
catch (Exception ex) {
Error("OnServerInitialized failed: " + ex.Message);
}
}
private void RestoreDefaults(BasePlayer player) {
manuallyEnabledBy.Remove(player.userID);
}
[HookMethod("OnPlayerInit")]
void OnPlayerInit(BasePlayer player) {
RestoreDefaults(player);
}
[HookMethod("OnPlayerDisconnected")]
void OnPlayerDisconnected(BasePlayer player) {
RestoreDefaults(player);
}
[HookMethod("OnEntityTakeDamage")]
object OnEntityTakeDamage(BaseCombatEntity entity, HitInfo hit) {
try {
if (lib == null || !(entity is BasePlayer) || !(hit.Initiator is BasePlayer) || (entity == hit.Initiator)) return null;
var victim = entity as BasePlayer;
var victimId = victim.userID.ToString();
var attacker = hit.Initiator as BasePlayer;
var attackerId = attacker.userID.ToString();
var key = attackerId + "-" + victimId;
if (!manuallyEnabledBy.Contains(attacker.userID) && HasFriend(attackerId, victimId)) {
DateTime now = DateTime.UtcNow;
DateTime time;
if (!notificationTimes.TryGetValue(key, out time) || time < now.AddSeconds(-10)) {
attacker.SendConsoleCommand("chat.add", "", _("%NAME% is your friend and cannot be hurt.To disable this, unshare your location with %NAME% on the live map or type: <color=\"#ffd479\">/ff on</color>", new Dictionary<string, string>() {
{
"NAME", victim.displayName
}
}
));
notificationTimes[key] = now;
}
hit.damageTypes = new DamageTypeList();
// clear damage
return false;
}
}
catch (Exception ex) {
Error("OnEntityAttacked failed: " + ex.Message);
}
return null;
}
[ChatCommand("ff")]
private void cmdChatFF(BasePlayer player, string command, string[] args) {
if (!IsInstalled()) return;
if (args.Length > 1) {
SendReply(player, _("Usage: <color=\"#ffd479\">/ff [on|off]</color>"));
return;
}
if (args.Length == 0) {
var sb = new StringBuilder();
int n = 0;
sb.Append("<size=22>FriendlyFire</size> "+Version+" by <color=#ce422b>http://playrust.io</color>\n");
if (manuallyEnabledBy.Contains(player.userID)) sb.Append(_("Friendly fire is <color=#cd422b>enabled</color> for your friends:")).Append("\n");
else sb.Append(_("Friendly fire is <color=#8acd2b>disabled</color> for your friends:")).Append("\n");
var playerId = player.userID.ToString();
foreach (var p in BasePlayer.activePlayerList) {
var pId = p.userID.ToString();
if (HasFriend(playerId, pId)) {
if (n > 0) sb.Append(", ");
sb.Append(p.displayName);
++n;
}
}
foreach (var p in BasePlayer.sleepingPlayerList) {
var pId = p.userID.ToString();
if (HasFriend(playerId, pId)) {
if (n > 0) sb.Append(", ");
sb.Append(p.displayName);
++n;
}
}
if (n == 0) sb.Append(_("You do not have any friends currently."));
sb.Append("\n").Append(_("You may add or delete friends using the live map."));
sb.Append("\n").Append(_("To toggle friendly fire on or off, type: <color=\"#ffd479\">/ff on|off</color>"));
SendReply(player, sb.ToString());
}
else if (args.Length == 1) {
switch (args[0]) {
case "on" : if (manuallyEnabledBy.Contains(player.userID)) {
SendReply(player, _("Friendly fire for your friends is already <color=#cd422b>enabled</color>.Take care!"));
}
else {
manuallyEnabledBy.Add(player.userID);
SendReply(player, _("You have <color=#cd422b>enabled</color> friendly fire for your friends.Take care!"));
}
break;
case "off" : if (!manuallyEnabledBy.Contains(player.userID)) {
SendReply(player, _("Friendly fire for your friends is already <color=#8acd2b>disabled</color>.They are safe!"));
}
else {
manuallyEnabledBy.Remove(player.userID);
SendReply(player, _("You have <color=#8acd2b>disabled</color> friendly fire for your friends.They are safe!"));
}
break;
default : SendReply(player, _("Usage: <color=\"#ffd479\">/ff [on|off]</color>"));
return;
}
}
}
[HookMethod("SendHelpText")]
private void SendHelpText(BasePlayer player) {
var sb = new StringBuilder().Append("<size=18>FriendlyFire</size> by <color=#ce422b>http://playrust.io</color>\n").Append(" ").Append(_("<color=\"#ffd479\">/ff</color> - Displays your friendly fire status")).Append("\n").Append(" ").Append(_("<color=\"#ffd479\">/ff on|off</color> - Toggles friendly fire <color=#cd422b>on</color> or <color=#8acd2b>off</color>"));
player.ChatMessage(sb.ToString());
}
[HookMethod("BuildServerTags")]
private void BuildServerTags(IList<string> taglist) {
taglist.Add("friendlyfire");
}
#region Utility Methods
private void Log(string message) {
Puts("{0}: {1}", Title, message);
}
private void Warn(string message) {
PrintWarning("{0}: {1}", Title, message);
}
private void Error(string message) {
PrintError("{0}: {1}", Title, message);
}
#endregion
}
}