Иконка ресурса

FREE Friends : 1.11.0 1.11.0

Нет прав для скачивания
C#:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text.RegularExpressions;
using Facepunch;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Oxide.Core;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using Oxide.Game.Rust;
using Oxide.Game.Rust.Cui;
using ProtoBuf;
using UnityEngine;
using WebSocketSharp;
namespace Oxide.Plugins {
    [Info("Friends", "Mevent", "1.11.0⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠")]
    [Description("Adds a friends system with a visual interface for quick interaction")]
    public class Friends : RustPlugin {
#region Fields
        [PluginReference]
        private Plugin ImageLibrary, Notifications, PlayerList;
        private const string Layer = "Com.Mevent.Main";
        private static Friends _instance;
        private readonly Dictionary<ulong, EntityEntry> playerEntites = new Dictionary<ulong, EntityEntry>();
        private class EntityEntry {
            public HashSet<AutoTurret> autoTurrets = new HashSet<AutoTurret>();
            public HashSet<BuildingPrivlidge> buildingPrivlidges = new HashSet<BuildingPrivlidge>();
        }
        private enum AutoAuthType {
            All, Turret, Cupboard
        }
        private enum BtnType {
            None, Doors, Cupboard, Turrets, Containers, FriendlyFire
        }
#endregion
#region Config
        private static Configuration _config;
        private class Configuration {
            [JsonProperty(PropertyName = "Добавлять в команду | Add to team")]
            public bool AddTeam = true;
            [JsonProperty(PropertyName = "Максимальное кол-во друзей | Max Friends")]
            public int MaxFriendsAmount = 3;
            [JsonProperty(PropertyName = "Задержка между сообщениями FF | Delay between FF messages")]
            public float FFDelay = 1;
            [JsonProperty(PropertyName = "Огонь по друзьям | Friendly Fire")]
            public bool FriendlyFire;
            [JsonProperty(PropertyName = "Двери | Doors")]
            public bool Doors = true;
            [JsonProperty(PropertyName = "Турели | Turrets")]
            public bool Turrets = true;
            [JsonProperty(PropertyName = "Шкаф | Cupboard")]
            public bool Cupboard = true;
            [JsonProperty(PropertyName = "Ящики | Containers")]
            public bool Containers = true;
            [JsonProperty(PropertyName = "Фон | Background")]
            public IPanel Background = new IPanel {
                AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "0 0", OffsetMax = "0 0", Image = string.Empty, Color = new IColor("#0D1F4E", 95), isRaw = false, Sprite = "Assets/Content/UI/UI.Background.Tile.psd", Material = "Assets/Icons/IconMaterial.mat"
            }
            ;
            [JsonProperty(PropertyName = "Заглавие | Title")]
            public IText Title = new IText {
                AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-150 300", OffsetMax = "150 360", Font = "robotocondensed-bold.ttf", Align = TextAnchor.MiddleCenter, FontSize = 38, Color = new IColor("#FFFFFF", 100)
            }
            ;
            [JsonProperty(PropertyName = "Закрыть | Close")]
            public IText Close = new IText {
                AnchorMin = "1 1", AnchorMax = "1 1", OffsetMin = "-35 -35", OffsetMax = "-5 -5", Font = "robotocondensed-bold.ttf", Align = TextAnchor.MiddleCenter, FontSize = 24, Color = new IColor("#FFFFFF", 100)
            }
            ;
            [JsonProperty(PropertyName = "Ошибка | Error")]
            public IText Error = new IText {
                AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-300 -150", OffsetMax = "300 150", Font = "robotocondensed-bold.ttf", Align = TextAnchor.MiddleCenter, FontSize = 38, Color = new IColor("#FFFFFF", 100)
            }
            ;
            [JsonProperty(PropertyName = "Назад | Back")]
            public IText Back = new IText {
                AnchorMin = "0 0.5", AnchorMax = "0 0.5", OffsetMin = "0 -40", OffsetMax = "65 40", Font = "robotocondensed-bold.ttf", Align = TextAnchor.MiddleCenter, FontSize = 60, Color = new IColor("#FFFFFF", 100)
            }
            ;
            [JsonProperty(PropertyName = "Вперёд | Next")]
            public IText Next = new IText {
                AnchorMin = "1 0.5", AnchorMax = "1 0.5", OffsetMin = "-65 -40", OffsetMax = "0 40", Font = "robotocondensed-bold.ttf", Align = TextAnchor.MiddleCenter, FontSize = 60, Color = new IColor("#FFFFFF", 100)
            }
            ;
            [JsonProperty(PropertyName = "Настройка интерфейса | Interface Settings")]
            public IFriendPanel Panel = new IFriendPanel {
                AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", Height = 100, Width = 820, Margin = 20, Count = 4, Color = new IColor("#1D3676", 100), Avatar = new InterfacePosition {
                    AnchorMin = "0 0", AnchorMax = "0 0", OffsetMin = "5 5", OffsetMax = "95 95"
                }
                , Nickname = new IText {
                    AnchorMin = "0 0", AnchorMax = "0 0", OffsetMin = "100 40", OffsetMax = "500 100", Align = TextAnchor.LowerLeft, Font = "robotocondensed-regular.ttf", Color = new IColor("#FFFFFF", 100), FontSize = 38
                }
                , Status = new SText {
                    AnchorMin = "0 0", AnchorMax = "0 0", OffsetMin = "100 0", OffsetMax = "200 50", Align = TextAnchor.UpperLeft, Font = "robotocondensed-regular.ttf", Color = new IColor("#B5FFC9", 100), OfflineColor = new IColor("#B46292", 100), FontSize = 16
                }
                , Button = new IButton {
                    AnchorMin = "1 0.5", AnchorMax = "1 0.5", Height = 35, Width = 120, Margin = 5
                }
                , Buttons = new List<FButton> {
                    new FButton {
                        Type = BtnType.None, Text = "Trade", Command = "chat.say /trade {user}", ActiveColor = new IColor("#5D8FDF", 95), DisactiveColor = new IColor("#5D8FDF", 35), FontSize = 20, Font = "robotocondensed-regular.ttf", Align = TextAnchor.MiddleCenter, TColor = new IColor("#1D3676", 100)
                    }
                    , new FButton {
                        Type = BtnType.Doors, Text = "Двери", Command = "friend doors {user}", ActiveColor = new IColor("#5D8FDF", 95), DisactiveColor = new IColor("#5D8FDF", 35), FontSize = 20, Font = "robotocondensed-regular.ttf", Align = TextAnchor.MiddleCenter, TColor = new IColor("#1D3676", 100)
                    }
                    , new FButton {
                        Type = BtnType.Cupboard, Text = "Шкаф", Command = "friend cupboard {user}", ActiveColor = new IColor("#5D8FDF", 95), DisactiveColor = new IColor("#5D8FDF", 35), FontSize = 20, Font = "robotocondensed-regular.ttf", Align = TextAnchor.MiddleCenter, TColor = new IColor("#1D3676", 100)
                    }
                    , new FButton {
                        Type = BtnType.Containers, Text = "Ящики", Command = "friend containers {user}", ActiveColor = new IColor("#5D8FDF", 95), DisactiveColor = new IColor("#5D8FDF", 35), FontSize = 20, Font = "robotocondensed-regular.ttf", Align = TextAnchor.MiddleCenter, TColor = new IColor("#1D3676", 100)
                    }
                    , new FButton {
                        Type = BtnType.None, Text = "Исключить", Command = "friend remove {user}", ActiveColor = new IColor("#5D8FDF", 95), DisactiveColor = new IColor("#5D8FDF", 35), FontSize = 20, Font = "robotocondensed-regular.ttf", Align = TextAnchor.MiddleCenter, TColor = new IColor("#1D3676", 100)
                    }
                    , new FButton {
                        Type = BtnType.Turrets, Text = "Турели", Command = "friend turrets {user}", ActiveColor = new IColor("#5D8FDF", 95), DisactiveColor = new IColor("#5D8FDF", 35), FontSize = 20, Font = "robotocondensed-regular.ttf", Align = TextAnchor.MiddleCenter, TColor = new IColor("#1D3676", 100)
                    }
                    , new FButton {
                        Type = BtnType.FriendlyFire, Text = "Урон", Command = "ff {user}", ActiveColor = new IColor("#5D8FDF", 95), DisactiveColor = new IColor("#5D8FDF", 35), FontSize = 20, Font = "robotocondensed-regular.ttf", Align = TextAnchor.MiddleCenter, TColor = new IColor("#1D3676", 100)
                    }
                    , new FButton {
                        Type = BtnType.None, Text = "ТП", Command = "tpr {user}", ActiveColor = new IColor("#5D8FDF", 95), DisactiveColor = new IColor("#5D8FDF", 35), FontSize = 20, Font = "robotocondensed-regular.ttf", Align = TextAnchor.MiddleCenter, TColor = new IColor("#1D3676", 100)
                    }
                }
            }
            ;
            [JsonProperty(PropertyName = "Приглашение в друзья | Friend Invite")]
            public INotify FriendInvite = new INotify {
                Image = "friend", Url = "https://i.imgur.com/qAxHQIn.png", Delay = 30, Buttons = new List<INotifyButton> {
                    new INotifyButton {
                        AnchorMin = "0.5 0", AnchorMax = "0.5 0", OffsetMin = "-137.5 5", OffsetMax = "-2.5 25", Align = TextAnchor.MiddleCenter, Font = "robotocondensed-regular.ttf", FontSize = 14, Color = new IColor("#FFFFFF", 95), BColor = new IColor("#528A4E", 95), Command = "friend accept", Msg = "Accept"
                    }
                    , new INotifyButton {
                        AnchorMin = "0.5 0", AnchorMax = "0.5 0", OffsetMin = "2.5 5", OffsetMax = "137.5 25", Align = TextAnchor.MiddleCenter, Font = "robotocondensed-regular.ttf", FontSize = 14, Color = new IColor("#FFFFFF", 95), BColor = new IColor("#50488A", 95), Command = "friend cancel", Msg = "Cancel"
                    }
                }
            }
            ;
            [JsonProperty(PropertyName = "Оповещение | Notification")]
            public INotify Notify = new INotify {
                Image = "friend", Url = "https://i.imgur.com/qAxHQIn.png", Delay = 5, Buttons = new List<INotifyButton>()
            }
            ;
            [JsonProperty(PropertyName = "Найти друга | Find a Friend")]
            public INotifyButton FindFriendBtn = new INotifyButton {
                AnchorMin = "0.5 0", AnchorMax = "0.5 0", OffsetMin = "-150 25", OffsetMax = "150 60", Align = TextAnchor.MiddleCenter, FontSize = 14, Font = "robotocondensed-regular.ttf", Color = new IColor("#5D8FDF", 100), BColor = new IColor("#1D3676", 100), Command = "playerslist", Msg = "FindFriend"
            }
            ;
        }
        private class INotify {
            [JsonProperty(PropertyName = "Ключ изображения | Image Key")]
            public string Image;
            [JsonProperty(PropertyName = "Ссылка на изображение | Image Url")]
            public string Url;
            [JsonProperty(PropertyName = "Время показа | Show Time")]
            public float Delay;
            [JsonProperty(PropertyName = "Кнопки | Buttons", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public List<INotifyButton> Buttons;
        }
        private class INotifyButton : IText {
            [JsonProperty(PropertyName = "Цвет | Color")]
            public IColor BColor;
            [JsonProperty(PropertyName = "Ключ языкового файла | Lang Key")]
            public string Msg;
            [JsonProperty(PropertyName = "Команда | Command")]
            public string Command;
            public void Get(ref CuiElementContainer container, BasePlayer player, string name = null, string parent = "") {
                if (string.IsNullOrEmpty(name)) name = CuiHelper.GetGuid();
                container.Add(new CuiButton {
                    RectTransform = {
                        AnchorMin = AnchorMin, AnchorMax = AnchorMax, OffsetMin = OffsetMin, OffsetMax = OffsetMax
                    }
                    , Text = {
                        Text = _instance.Msg(Msg, player.UserIDString), Align = Align, FontSize = FontSize, Color = Color.Get(), Font = Font
                    }
                    , Button = {
                        Color = BColor.Get(), Command = Command
                    }
                }
                , parent, name);
            }
        }
        private abstract class IAnchors {
            public string AnchorMin;
            public string AnchorMax;
        }
        private class InterfacePosition : IAnchors {
            public string OffsetMin;
            public string OffsetMax;
        }
        private class IFriendPanel : IAnchors {
            [JsonProperty(PropertyName = "Высота | Height")]
            public float Height;
            [JsonProperty(PropertyName = "Ширина | Width")]
            public float Width;
            [JsonProperty(PropertyName = "Отступ | Margin")]
            public float Margin;
            [JsonProperty(PropertyName = "Количество на странице | Count On Page")]
            public int Count;
            [JsonProperty(PropertyName = "Цвет | Color")]
            public IColor Color;
            [JsonProperty(PropertyName = "Аватарка | Avatar")]
            public InterfacePosition Avatar;
            [JsonProperty(PropertyName = "Никнейм | Nickname")]
            public IText Nickname;
            [JsonProperty(PropertyName = "Статус | Status")]
            public SText Status;
            [JsonProperty(PropertyName = "Кнопка | Button")]
            public IButton Button;
            [JsonProperty(PropertyName = "Кнопки | Buttons", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public List<FButton> Buttons;
            public void Get(ref CuiElementContainer container, BasePlayer player, FriendData data, string parent, string name, string oMin, string oMax) {
                if (name.IsNullOrEmpty()) name = CuiHelper.GetGuid();
                container.Add(new CuiPanel {
                    RectTransform = {
                        AnchorMin = AnchorMin, AnchorMax = AnchorMax, OffsetMin = oMin, OffsetMax = oMax
                    }
                    , Image = {
                        Color = Color.Get()
                    }
                }
                , parent, name);
                if (_instance != null && _instance.ImageLibrary && Avatar != null) container.Add(new CuiElement {
                    Parent = name, Components = {
                        new CuiRawImageComponent {
                            Png = _instance.ImageLibrary.Call<string>("GetImage", $"avatar_{data.UserId}")
                        }
                        , new CuiRectTransformComponent {
                            AnchorMin = Avatar.AnchorMin, AnchorMax = Avatar.AnchorMax, OffsetMin = Avatar.OffsetMin, OffsetMax = Avatar.OffsetMax
                        }
                    }
                }
                );
#region Name
                var targetId = $"{data.UserId}";
                var target = _instance?.covalence.Players.FindPlayer(targetId);
                var displayName = target?.Name;
                if (string.IsNullOrEmpty(displayName)) displayName = targetId;
                var status = target != null && target.IsConnected;
                Nickname?.Get(ref container, name, name + ".Nickname", displayName);
                if (_instance != null) Status?.Get(ref container, status, name, name + ".Status", _instance.Msg(status ? Online : Offline, player.UserIDString));
#endregion
#region Buttons
                if (Buttons != null) {
                    var xSwitch = -Button.Margin;
                    for (var i = 0; i < Buttons.Count; i++) {
                        var button = Buttons[i];
                        if (button == null) continue;
                        var up = i < Buttons.Count / 2;
                        var ySwitch = up ? Button.Height + Button.Margin / 2f : -(Button.Margin / 2f);
                        button.Get(ref container, data, name, name + $".Btn.{i}", Button.AnchorMin, Button.AnchorMax, $"{xSwitch - Button.Width} {ySwitch - Button.Height}", $"{xSwitch} {ySwitch}");
                        if (i + 1 == Buttons.Count / 2) xSwitch = -Button.Margin;
                        else xSwitch = xSwitch - Button.Margin - Button.Width;
                    }
                }
#endregion
            }
        }
        private class IPanel : InterfacePosition {
            [JsonProperty(PropertyName = "Изображение | Image")]
            public string Image;
            [JsonProperty(PropertyName = "Цвет | Color")]
            public IColor Color;
            [JsonProperty(PropertyName = "Сохранять цвет изображения? | Save Image Color")]
            public bool isRaw;
            [JsonProperty(PropertyName = "Sprite")]
            public string Sprite;
            [JsonProperty(PropertyName = "Material")]
            public string Material;
            public void Get(ref CuiElementContainer container, string parent = "Hud", string name = null, bool cursor = false) {
                if (string.IsNullOrEmpty(name)) name = CuiHelper.GetGuid();
                if (isRaw) {
                    var element = new CuiElement {
                        Name = name, Parent = parent, Components = {
                            new CuiRawImageComponent {
                                Png = !string.IsNullOrEmpty(Image) ? _instance.ImageLibrary.Call<string>("GetImage", Image) : null, Color = Color.Get(), Material = Material, Sprite = !Sprite.IsNullOrEmpty() ? Sprite : "Assets/Icons/rust.png"
                            }
                            , new CuiRectTransformComponent {
                                AnchorMin = AnchorMin, AnchorMax = AnchorMax, OffsetMin = OffsetMin, OffsetMax = OffsetMax
                            }
                        }
                    }
                    ;
                    if (cursor) element.Components.Add(new CuiNeedsCursorComponent());
                    container.Add(element);
                }
                else {
                    container.Add(new CuiPanel {
                        RectTransform = {
                            AnchorMin = AnchorMin, AnchorMax = AnchorMax, OffsetMin = OffsetMin, OffsetMax = OffsetMax
                        }
                        , Image = {
                            Png = !string.IsNullOrEmpty(Image) ? _instance.ImageLibrary.Call<string>("GetImage", Image) : null, Color = Color.Get(), Sprite = !Sprite.IsNullOrEmpty() ? Sprite : "Assets/Content/UI/UI.Background.Tile.psd", Material = !Material.IsNullOrEmpty() ? Material : "Assets/Icons/IconMaterial.mat"
                        }
                        , CursorEnabled = cursor
                    }
                    , parent, name);
                }
            }
        }
        private class FButton {
            [JsonProperty(PropertyName = "Тип | Type")]
            [JsonConverter(typeof(StringEnumConverter))]
            public BtnType Type;
            [JsonProperty(PropertyName = "Текст | Text")]
            public string Text;
            [JsonProperty(PropertyName = "Команда | Command")]
            public string Command;
            [JsonProperty(PropertyName = "Активный Цвет | Active Color")]
            public IColor ActiveColor;
            [JsonProperty(PropertyName = "Неактивный Цвет | Disactive Color")]
            public IColor DisactiveColor;
            [JsonProperty(PropertyName = "Font Size")]
            public int FontSize;
            [JsonProperty(PropertyName = "Font")]
            public string Font;
            [JsonProperty(PropertyName = "Align")]
            [JsonConverter(typeof(StringEnumConverter))]
            public TextAnchor Align;
            [JsonProperty(PropertyName = "Text Color")]
            public IColor TColor;
            public void Get(ref CuiElementContainer container, FriendData data, string parent, string name, string aMin, string aMax, string oMin, string oMax) {
                if (name.IsNullOrEmpty()) name = CuiHelper.GetGuid();
                var color = ActiveColor;
                switch (Type) {
                    case BtnType.Doors : color = data.Doors ? ActiveColor : DisactiveColor;
                    break;
                    case BtnType.Cupboard : color = data.Cupboard ? ActiveColor : DisactiveColor;
                    break;
                    case BtnType.Turrets : color = data.Turrets ? ActiveColor : DisactiveColor;
                    break;
                    case BtnType.FriendlyFire : color = data.FriendlyFire ? ActiveColor : DisactiveColor;
                    break;
                    case BtnType.Containers : color = data.Containers ? ActiveColor : DisactiveColor;
                    break;
                }
                var text = Text.Replace("{user}", data.UserId.ToString());
                var command = Command.Replace("{user}", data.UserId.ToString());
                container.Add(new CuiButton {
                    RectTransform = {
                        AnchorMin = aMin, AnchorMax = aMax, OffsetMin = oMin, OffsetMax = oMax
                    }
                    , Text = {
                        Text = $"{text}", Align = Align, Font = Font, FontSize = FontSize, Color = TColor.Get()
                    }
                    , Button = {
                        Command = command.Contains("chat.say") ? $"friendssendcmd {command}" : $"{command}", Color = color.Get(), Close = Layer
                    }
                }
                , parent, name);
            }
        }
        private class IButton : IAnchors {
            [JsonProperty(PropertyName = "Высота | Height")]
            public float Height;
            [JsonProperty(PropertyName = "Ширина | Width")]
            public float Width;
            [JsonProperty(PropertyName = "Отступ | Margin")]
            public float Margin;
        }
        private class SText : InterfacePosition {
            [JsonProperty(PropertyName = "Font Size")]
            public int FontSize;
            [JsonProperty(PropertyName = "Font")]
            public string Font;
            [JsonProperty(PropertyName = "Align")]
            [JsonConverter(typeof(StringEnumConverter))]
            public TextAnchor Align;
            [JsonProperty(PropertyName = "Цвет игрока онлайн | Online Color")]
            public IColor Color;
            [JsonProperty(PropertyName = "Цвет игрока оффлайн | Offline Color")]
            public IColor OfflineColor;
            public void Get(ref CuiElementContainer container, bool online, string parent = "Hud", string name = null, string text = "") {
                if (string.IsNullOrEmpty(name)) name = CuiHelper.GetGuid();
                container.Add(new CuiLabel {
                    RectTransform = {
                        AnchorMin = AnchorMin, AnchorMax = AnchorMax, OffsetMin = OffsetMin, OffsetMax = OffsetMax
                    }
                    , Text = {
                        Text = $"{text}", Align = Align, FontSize = FontSize, Color = online ? Color.Get() : OfflineColor.Get(), Font = Font
                    }
                }
                , parent, name);
            }
        }
        private class IText : InterfacePosition {
            [JsonProperty(PropertyName = "Font Size")]
            public int FontSize;
            [JsonProperty(PropertyName = "Font")]
            public string Font;
            [JsonProperty(PropertyName = "Align")]
            [JsonConverter(typeof(StringEnumConverter))]
            public TextAnchor Align;
            [JsonProperty(PropertyName = "Text Color")]
            public IColor Color;
            public void Get(ref CuiElementContainer container, string parent = "Hud", string name = null, string text = "") {
                if (string.IsNullOrEmpty(name)) name = CuiHelper.GetGuid();
                container.Add(new CuiLabel {
                    RectTransform = {
                        AnchorMin = AnchorMin, AnchorMax = AnchorMax, OffsetMin = OffsetMin, OffsetMax = OffsetMax
                    }
                    , Text = {
                        Text = $"{text}", Align = Align, FontSize = FontSize, Color = Color.Get(), Font = Font
                    }
                }
                , parent, name);
            }
        }
        private class IColor {
            [JsonProperty(PropertyName = "HEX")]
            public string HEX;
            [JsonProperty(PropertyName = "Непрозрачность | Opacity (0 - 100)")]
            public float Alpha;
            public string Get() {
                if (string.IsNullOrEmpty(HEX)) HEX = "#FFFFFF";
                var str = HEX.Trim('#');
                if (str.Length != 6) throw new Exception(HEX);
                var r = byte.Parse(str.Substring(0, 2), NumberStyles.HexNumber);
                var g = byte.Parse(str.Substring(2, 2), NumberStyles.HexNumber);
                var b = byte.Parse(str.Substring(4, 2), NumberStyles.HexNumber);
                return $"{(double) r / 255} {(double) g / 255} {(double) b / 255} {Alpha / 100}";
            }
            public IColor(string hex, float alpha) {
                HEX = hex;
                Alpha = alpha;
            }
        }
        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 static PluginData _data;
        private void SaveData() {
            Interface.Oxide.DataFileSystem.WriteObject(Name, _data);
        }
        private void LoadData() {
            try {
                _data = Interface.Oxide.DataFileSystem.ReadObject<PluginData>(Name);
            }
            catch (Exception e) {
                PrintError(e.ToString());
            }
            if (_data == null) _data = new PluginData();
        }
        private class PluginData {
            [JsonProperty(PropertyName = "Players", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public Dictionary<ulong, PlayerData> Players = new Dictionary<ulong, PlayerData>();
        }
        private class PlayerData {
            [JsonProperty(PropertyName = "Display Name")]
            public string DisplayName;
            [JsonProperty(PropertyName = "UserId")]
            public ulong UserId;
            [JsonProperty(PropertyName = "Friends", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public List<FriendData> Friends = new List<FriendData>();
            [JsonProperty(PropertyName = "Removed Friends", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public List<ulong> RemovedFriends = new List<ulong>();
            public bool IsFriend(ulong friend) {
                for (var i = 0; i < Friends.Count; i++) {
                    var check = Friends[i];
                    if (check.UserId == friend) return true;
                }
                return false;
            }
            public FriendData GetFriend(ulong friend) {
                for (var i = 0; i < Friends.Count; i++) {
                    var check = Friends[i];
                    if (check.UserId == friend) return check;
                }
                return null;
            }
            public void AddFriend(ulong friend) {
                if (Friends.Exists(x => x.UserId == friend) || !friend.IsSteamId()) return;
                Friends.Add(new FriendData {
                    UserId = friend, FriendlyFire = _config.FriendlyFire, Doors = _config.Doors, Turrets = _config.Turrets, Cupboard = _config.Cupboard, Containers = _config.Containers
                }
                );
                RemovedFriends.Remove(friend);
            }
            public void RemoveFriend(ulong friend) {
                Friends?.ToList().ForEach(f => {
                    if (f.UserId == friend) {
                        if (!RemovedFriends.Contains(friend)) RemovedFriends.Add(friend);
                        Friends.Remove(f);
                    }
                }
                );
            }
        }
        private class FriendData {
            public ulong UserId;
            public bool FriendlyFire;
            public bool Doors;
            public bool Turrets;
            public bool Cupboard;
            public bool Containers;
        }
        private static PlayerData GetPlayerData(BasePlayer player) {
            if (player == null || !player.userID.IsSteamId()) return null;
            if (!_data.Players.ContainsKey(player.userID)) _data.Players.Add(player.userID, new PlayerData {
                DisplayName = player.displayName, UserId = player.userID
            }
            );
            return _data.Players[player.userID];
        }
        private static PlayerData GetPlayerData(ulong userId) {
            if (!userId.IsSteamId()) return null;
            if (!_data.Players.ContainsKey(userId)) _data.Players.Add(userId, new PlayerData {
                UserId = userId
            }
            );
            return _data.Players[userId];
        }
#endregion
#region Hooks
        private void Init() {
            _instance = this;
            LoadData();
            AddCovalenceCommand(new[] {
                "ff", "friendlyfire", "friend", "friends", "f", "fmenu", "f.menu"
            }
            , nameof(CmdFriends));
            if (!_config.AddTeam) {
                Unsubscribe(nameof(OnTeamLeave));
                Unsubscribe(nameof(OnTeamAcceptInvite));
                Unsubscribe(nameof(OnTeamKick));
                Unsubscribe(nameof(OnTeamInvite));
                Unsubscribe(nameof(OnTeamRejectInvite));
            }
        }
        private void OnServerInitialized() {
            if (!ImageLibrary) PrintWarning("IMAGE LIBRARY IS NOT INSTALLED.");
#region Init
            foreach (var player in BasePlayer.activePlayerList) OnPlayerConnected(player);
#endregion
#region Notifications
            Notifications?.Call("AddImage", _config.FriendInvite.Image, _config.FriendInvite.Url);
            Notifications?.Call("AddImage", _config.Notify.Image, _config.Notify.Url);
#endregion
#region Team
            RelationshipManager.maxTeamSize = _config.MaxFriendsAmount + 1;
#endregion
#region Auth
            foreach (var entity in BaseNetworkable.serverEntities.OfType<BaseEntity>()) CheckEntity(entity);
#endregion
            timer.Every(1, TimeHandle);
        }
        private void OnServerSave() {
            SaveData();
        }
        private void Unload() {
            foreach (var player in BasePlayer.activePlayerList) CuiHelper.DestroyUi(player, Layer);
            SaveData();
            _instance = null;
            _config = null;
            _data = null;
        }
        private void OnPlayerConnected(BasePlayer player) {
            if (player == null || !player.userID.IsSteamId()) return;
            var data = GetPlayerData(player);
            if (data == null) return;
            data.DisplayName = player.displayName;
            GetAvatar(player.userID, avatar => ImageLibrary?.Call("AddImage", avatar, $"avatar_{player.UserIDString}"));
            if (_config.AddTeam && data.Friends.Count > 0) {
                RelationshipManager.PlayerTeam team;
                var friend = data.Friends.Find(x => RelationshipManager.Instance.playerToTeam.ContainsKey(x.UserId));
                if (friend == null) {
                    team = RelationshipManager.Instance.CreateTeam();
                    team.AddPlayer(player);
                    team.SetTeamLeader(player.userID);
                    var friendPlayer = FindPlayer(data.Friends);
                    if (friendPlayer != null) team.AddPlayer(friendPlayer);
                }
                else {
                    team = RelationshipManager.Instance.playerToTeam[friend.UserId];
                    if (team == null) return;
                    team.AddPlayer(player);
                }
            }
        }
#region Cooldown
        private readonly Dictionary<ulong, float> _cooldown = new Dictionary<ulong, float>();
        private bool IsCd(ulong user) {
            return GetCd(user) >= 0;
        }
        private int GetCd(ulong user) {
            return _cooldown.ContainsKey(user) ? (int) (_cooldown[user] - Time.time) : -1;
        }
        private void SetCd(ulong user) {
            var time = Time.time + _config.FFDelay;
            if (_cooldown.ContainsKey(user)) _cooldown[user] = time;
            else _cooldown.Add(user, time);
        }
#endregion
        private void OnEntityTakeDamage(BasePlayer player, HitInfo info) {
            if (player == null || info == null) return;
            var initiator = info.InitiatorPlayer;
            if (initiator == null) return;
            if (!IsFriend(player.userID, initiator.userID) || player.userID == initiator.userID) return;
            var data = GetPlayerData(initiator);
            var friend = data?.Friends.Find(x => x.UserId == player.userID);
            if (friend == null || friend.FriendlyFire) return;
            info.damageTypes.ScaleAll(0);
            if (IsCd(initiator.userID)) return;
            Notify(initiator, _config.Notify.Delay, Msg(NotifyTitle, initiator.UserIDString), Msg(FF, initiator.UserIDString, player.displayName), _config.Notify.Image);
            SetCd(initiator.userID);
        }
#region Team
        private void OnTeamLeave(RelationshipManager.PlayerTeam playerTeam, BasePlayer player) {
            if (playerTeam == null || player == null) return;
            playerTeam.members.ToList().ForEach(user => {
                GetPlayerData(player)?.RemoveFriend(user);
                GetPlayerData(user)?.RemoveFriend(player.userID);
            }
            );
            UpdateAuthList(player.userID, AutoAuthType.All);
            UpdateTeamAuthList(playerTeam.members);
        }
        private void OnTeamAcceptInvite(RelationshipManager.PlayerTeam playerTeam, BasePlayer player) {
            NextTick(() => {
                if (playerTeam == null || player == null || !player.userID.IsSteamId()) return;
                var invite = _invites.Find(x => x.Target == player);
                if (invite != null && playerTeam.members.Exists(x => invite.Inviter.userID == x)) {
                    AcceptInvite(player);
                    return;
                }
                if (playerTeam.members.Contains(player.userID)) {
                    playerTeam.members.ToList().ForEach(user => {
                        if (user == player.userID) return;
                        GetPlayerData(player)?.AddFriend(user);
                        GetPlayerData(user)?.AddFriend(player.userID);
                    }
                    );
                    UpdateTeamAuthList(playerTeam.members);
                }
            }
            );
        }
        private void OnTeamKick(RelationshipManager.PlayerTeam playerTeam, BasePlayer player, ulong target) {
            NextTick(() => {
                if (playerTeam == null) return;
                if (!playerTeam.members.Contains(target)) {
                    playerTeam.members.ToList().ForEach(user => {
                        GetPlayerData(player)?.RemoveFriend(user);
                        GetPlayerData(user)?.RemoveFriend(player.userID);
                    }
                    );
                    UpdateAuthList(target, AutoAuthType.All);
                    UpdateTeamAuthList(playerTeam.members);
                }
            }
            );
        }
        private void OnTeamInvite(BasePlayer inviter, BasePlayer target) {
            SendInvite(inviter, target);
        }
        /*
		private object OnTeamInvite(BasePlayer inviter, BasePlayer target)
		{
			if (inviter.Team == null || inviter.Team.members.Count >= _config.MaxFriends + 1)
			{
				Notify(inviter, _config.Notify.Delay, Msg(NotifyTitle, inviter.UserIDString),
					Msg(TargetMaxFriends, inviter.UserIDString), _config.Notify.Image);
				return false;
			}
			
			SendInvite(inviter, target);
			return null;
		}*/
        private void OnTeamRejectInvite(BasePlayer rejector, RelationshipManager.PlayerTeam team) {
            CancelInvite(rejector);
        }
        private void UpdateTeamAuthList(List<ulong> teamMembers) {
            if (teamMembers.Count <= 0) return;
            teamMembers.ForEach(member => UpdateAuthList(member, AutoAuthType.All));
        }
#endregion
#endregion
#region Commands
        private void CmdFriends(IPlayer cov, string command, string[] args) {
            var player = cov?.Object as BasePlayer;
            if (player == null) return;
            switch (command) {
                case "friendlyfire" : case "ff" : {
                    var data = GetPlayerData(player);
                    if (data == null) return;
                    if (args.Length < 1) {
                        Reply(player, FFErrorSyntax, command);
                        return;
                    }
                    var friends = FindRemoveFriend(player, args[0]);
                    if (friends == null || friends.Count == 0) {
                        Notify(player, _config.Notify.Delay, Msg(NotifyTitle, player.UserIDString), Msg(NotFound, player.UserIDString, args[0]), _config.Notify.Image);
                        return;
                    }
                    PlayerData friend;
                    if (friends.Count > 1) {
                        int index;
                        if (args.Length >= 3 && int.TryParse(args[2], out index)) {
                            if (index - 1 < 0 || friends.Count <= index - 1) return;
                            friend = friends[index - 1];
                        }
                        else {
                            var f = 0;
                            var str = string.Join(", ", friends.Select(x => {
                                f++;
                                return $"{x.DisplayName} ({x.UserId}) [{f}]";
                            }
                            ));
                            Reply(player, MultipleFound, str, f, args[0], args[1]);
                            return;
                        }
                    }
                    else {
                        friend = friends.FirstOrDefault();
                    }
                    if (friend == null) {
                        Notify(player, _config.Notify.Delay, Msg(NotifyTitle, player.UserIDString), Msg(NotFound, player.UserIDString, args[0]), _config.Notify.Image);
                        return;
                    }
                    var fData = data.GetFriend(friend.UserId);
                    if (fData == null) {
                        Notify(player, _config.Notify.Delay, Msg(NotifyTitle, player.UserIDString), Msg(IsNotFriend, player.UserIDString, friend.DisplayName), _config.Notify.Image);
                        return;
                    }
                    if (args.Length > 2) switch (args[1].ToLower()) {
                        case "on" : {
                            fData.FriendlyFire = true;
                            break;
                        }
                        case "off" : {
                            fData.FriendlyFire = false;
                            break;
                        }
                    }
                    else fData.FriendlyFire = !fData.FriendlyFire;
                    Notify(player, _config.Notify.Delay, Msg(NotifyTitle, player.UserIDString), Msg(fData.FriendlyFire ? FFOn : FFOff, player.UserIDString), _config.Notify.Image);
                    break;
                }
                default : {
                    if (args.Length == 0) {
                        MainUi(player);
                        return;
                    }
                    switch (args[0].ToLower()) {
                        case "+" : case "i" : case "inv" : case "invite" : case "add" : {
                            if (args.Length < 2) {
                                Reply(player, ErrorSyntax, command, args[0]);
                                return;
                            }
                            var friends = FindPlayer(args[1]);
                            if (friends.Count == 0) {
                                Notify(player, _config.Notify.Delay, Msg(NotifyTitle, player.UserIDString), Msg(NotFound, player.UserIDString, args[1]), _config.Notify.Image);
                                return;
                            }
                            BasePlayer friend;
                            if (friends.Count > 1) {
                                int index;
                                if (args.Length >= 3 && int.TryParse(args[2], out index)) {
                                    if (index - 1 < 0 || friends.Count <= index - 1) return;
                                    friend = friends[index - 1];
                                }
                                else {
                                    var f = 0;
                                    var str = string.Join(", ", friends.Select(x => {
                                        f++;
                                        return $"{x.displayName} ({x.UserIDString}) [{f}]";
                                    }
                                    ));
                                    Reply(player, MultipleFound, str, f, args[0], args[1]);
                                    return;
                                }
                            }
                            else {
                                friend = friends.FirstOrDefault();
                            }
                            if (friend == null) {
                                Notify(player, _config.Notify.Delay, Msg(NotifyTitle, player.UserIDString), Msg(NotFound, player.UserIDString, args[1]), _config.Notify.Image);
                                return;
                            }
                            if (player.userID == friend.userID) {
                                Notify(player, _config.Notify.Delay, Msg(NotifyTitle, player.UserIDString), Msg(CantAddSelf, player.UserIDString), _config.Notify.Image);
                                retu
// ... [Code preview truncated due to length. Full source in attached file] ...

Автор
15FPS
Скачиваний
0
Просмотры
1
Первый выпуск
Обновление
Оценка
0.00 звёзд 0 оценок

Другие ресурсы пользователя 15FPS

Сверху