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

FREE BlueprintShare : 1.2.10 1.2.10

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Game.Rust;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("Blueprint Share", "c_creep", "1.2.10")]
    [Description("Allows players to share researched blueprints with their friends, clan or team")]
    class BlueprintShare : RustPlugin
    {
        #region Fields

        [PluginReference]
        private Plugin Clans, Friends;

        private StoredData storedData;
        
        private const string UsePermission = "blueprintshare.use";
        private const string TogglePermission = "blueprintshare.toggle";
        private const string SharePermission = "blueprintshare.share";

        #endregion

        #region Oxide Hooks

        private void Init()
        {
            LoadData();

            permission.RegisterPermission(UsePermission, this);
            permission.RegisterPermission(TogglePermission, this);
            permission.RegisterPermission(SharePermission, this);
        }

        private void OnNewSave(string filename)
        {
            if (!config.ClearDataOnWipe) return;

            CreateData();
        }

        private void OnPlayerConnected(BasePlayer player)
        {
            var playerID = player.UserIDString;

            if (PlayerDataExists(playerID)) return;

            CreatePlayerData(playerID);
        }

        private void OnItemAction(Item item, string action, BasePlayer player)
        {
            if (!config.PhysicalSharingEnabled) return;
            if (player == null || item == null) return;
            if (action != "study") return;
            
            if (CanShareBlueprint(item.blueprintTargetDef, player))
            {
                item.Remove();
            }
        }

        private void OnTechTreeNodeUnlocked(Workbench workbench, TechTreeData.NodeInstance node, BasePlayer player)
        {
            if (!config.TechTreeSharingEnabled) return;
            if (workbench == null || node == null || player == null) return;

            CanShareBlueprint(node.itemDef, player);
        }

        private void OnTeamAcceptInvite(RelationshipManager.PlayerTeam team, BasePlayer player)
        {
            if (!config.ShareBlueprintsOnJoin) return;
            
            NextTick(() =>
            {
                if (team == null || player == null) return;

                if (team.members.Contains(player.userID))
                {
                    ShareWithPlayer(team.GetLeader(), player);
                }
            });
        }

        #endregion

        #region External Plugins

        #region Friends

        private bool HasFriends(ulong playerID)
        {
            if (Friends == null || !Friends.IsLoaded) return false;

            var friendsList = Friends.Call<ulong[]>("GetFriends", playerID);

            return friendsList != null && friendsList.Length != 0;
        }

        private List<ulong> GetFriends(ulong playerID)
        {
            if (Friends == null || !Friends.IsLoaded) return new List<ulong>();
            
            var friends = Friends.Call<ulong[]>("GetFriends", playerID);

            return friends.ToList();
        }

        private bool AreFriends(string playerID, string targetID)
        {
            return Friends != null && Friends.IsLoaded && Friends.Call<bool>("AreFriends", playerID, targetID);
        }

        #endregion

        #region Clan

        private bool InClan(ulong playerID)
        {
            if (Clans == null) return false;

            var clanName = Clans?.Call<string>("GetClanOf", playerID);

            return clanName != null;
        }

        private List<ulong> GetClanMembers(ulong playerID)
        {
            // Clans and Clans Reborn
            var clanMembers = Clans?.Call<List<string>>("GetClanMembers", playerID);

            if (clanMembers != null)
            {
                return clanMembers.Select(x => ulong.Parse(x)).ToList();
            }

            // Rust:IO Clans
            var clanName = Clans?.Call<string>("GetClanOf", playerID);

            return !string.IsNullOrEmpty(clanName) ? GetClanMembers(clanName) : null;
        }

        private List<ulong> GetClanMembers(string clanName)
        {
            var clan = Clans?.Call<JObject>("GetClan", clanName);

            var members = clan?.GetValue("members") as JArray;

            return members?.Select(Convert.ToUInt64).ToList();
        }

        private bool SameClan(string playerID, string targetID)
        {
            if (Clans == null) return false;

            // Clans and Clans Reborn
            var isClanMember = Clans?.Call("IsClanMember", playerID, targetID);

            if (isClanMember != null)
            {
                return (bool)isClanMember;
            }

            // Rust:IO Clans
            var playerClan = Clans?.Call("GetClanOf", playerID);

            if (playerClan == null) return false;

            var targetClan = Clans?.Call("GetClanOf", targetID);

            if (targetClan == null) return false;

            return (string)playerClan == (string)targetClan;
        }

        #endregion

        #region Team

        private bool InTeam(ulong playerID)
        {
            var player = RustCore.FindPlayerById(playerID);

            return player.currentTeam != 0;
        }

        private List<ulong> GetTeamMembers(ulong playerID)
        {
            var player = RustCore.FindPlayerById(playerID);

            return player?.Team.members;
        }

        private bool SameTeam(BasePlayer player, BasePlayer target)
        {
            if (player.currentTeam == 0 || target.currentTeam == 0) return false;

            var playerTeam = player.currentTeam;
            var targetTeam = target.currentTeam;

            return playerTeam == targetTeam;
        }

        #endregion

        #endregion

        #region External Plugin Hooks

        private void OnFriendAdded(string playerID, string friendID)
        {
            if (!config.ShareBlueprintsOnJoin) return;

            var player = RustCore.FindPlayerByIdString(playerID);

            if (player == null) return;

            var friend = RustCore.FindPlayerByIdString(friendID);

            if (friend == null) return;

            ShareWithPlayer(player, friend);
        }

        private void OnClanMemberJoined(string playerID, List<string> memberIDs)
        {
            if (!config.ShareBlueprintsOnJoin) return;

            var player = RustCore.FindPlayerByIdString(playerID);

            var ids = memberIDs.Select(x => ulong.Parse(x)).ToList();

            var clanMembers = FindPlayers(ids, player.userID);

            if (clanMembers.Count > 0)
            {
                foreach (var clanMember in clanMembers)
                {
                    if (player == null || clanMember == null) continue;
                            
                    ShareWithPlayer(clanMember, player);
                }
            }
        }

        #endregion

        #region Core

        private bool CanShareBlueprint(ItemDefinition item, BasePlayer player)
        {
            if (item == null || player == null) return false;
            if (!permission.UserHasPermission(player.UserIDString, UsePermission)) return false;

            var playerID = player.UserIDString;

            if (BlueprintBlocked(item))
            {
                player.ChatMessage(GetLangValue("Prefix", playerID) + GetLangValue("BlueprintBlocked", playerID, item.displayName.translated));

                return false;
            }

            if (SharingEnabled(playerID))
            {
                if (InTeam(player.userID) || InClan(player.userID) || HasFriends(player.userID))
                {
                    if (SomeoneWillLearnBlueprint(player, item))
                    {
                        ShareWithPlayers(player, item);
                        HandleAdditionalBlueprints(player, item);

                        return true;
                    }
                }
            }

            return false;
        }

        private void HandleAdditionalBlueprints(BasePlayer player, ItemDefinition item)
        {
            var additionalBlueprints = item.Blueprint.additionalUnlocks;

            if (additionalBlueprints.Count > 0)
            {
                foreach (var blueprint in additionalBlueprints)
                {
                    UnlockBlueprint(player, blueprint.itemid);

                    ShareWithPlayers(player, blueprint);
                }
            }
        }

        private bool UnlockBlueprint(BasePlayer player, int blueprint)
        {
            if (player == null) return false;

            var playerInfo = player.PersistantPlayerInfo;

            var unlockedBlueprints = playerInfo.unlockedItems;

            if (!unlockedBlueprints.Contains(blueprint))
            {
                unlockedBlueprints.Add(blueprint);

                player.PersistantPlayerInfo = playerInfo;
                player.SendNetworkUpdateImmediate();
                player.ClientRPCPlayer(null, player, "UnlockedBlueprint", 0);

                PlaySoundEffect(player);

                return true;
            }

            return false;
        }

        private void ShareWithPlayers(BasePlayer player, ItemDefinition item)
        {
            if (player == null || item == null) return;

            var targets = SelectSharePlayers(player);

            var successfulUnlocks = 0;

            foreach (var target in targets)
            {
                if (target != null)
                {
                    if (SharingEnabled(target.UserIDString))
                    {
                        if (UnlockBlueprint(target, item.itemid))
                        {
                            target.ChatMessage(GetLangValue("Prefix", player.UserIDString) + GetLangValue("TargetLearntBlueprint", target.UserIDString, player.displayName, item.displayName.translated));

                            successfulUnlocks++;
                        }
                    }
                }
            }

            if (successfulUnlocks > 0)
            {
                player.ChatMessage(GetLangValue("Prefix", player.UserIDString) + GetLangValue("SharerLearntBlueprint", player.UserIDString, item.displayName.translated, successfulUnlocks));
            }
        }

        private void ShareWithPlayer(BasePlayer player, BasePlayer target)
        {
            if (player == null || target == null) return;

            var playerID = player.UserIDString;
            var targetID = target.UserIDString;

            if (!SharingEnabled(targetID))
            {
                player.ChatMessage(GetLangValue("Prefix", playerID) + GetLangValue("TargetSharingDisabled", playerID, target.displayName));

                return;
            }

            if (!SameTeam(player, target) && !SameClan(playerID, targetID) && !AreFriends(playerID, targetID))
            {
                player.ChatMessage(GetLangValue("Prefix", playerID) + GetLangValue("CannotShare", playerID));

                return;
            }

            var playerBlueprints = GetPlayerBlueprintItems(player.PersistantPlayerInfo.unlockedItems);

            foreach (var blueprint in playerBlueprints.ToList())
            {
                if (BlueprintBlocked(blueprint))
                {
                    playerBlueprints.Remove(blueprint);
                }
            }

            var unlockedItems = ConvertItemsToIds(playerBlueprints);
            var learnedBlueprints = UnlockBlueprints(target, unlockedItems);

            if (learnedBlueprints > 0)
            {
                player.ChatMessage(GetLangValue("Prefix", playerID) + GetLangValue("SharerSuccess", playerID, learnedBlueprints, target.displayName));

                target.ChatMessage(GetLangValue("Prefix", targetID) + GetLangValue("ShareReceieve", targetID, player.displayName, learnedBlueprints));
            }
            else
            {
                player.ChatMessage(GetLangValue("Prefix", playerID) + GetLangValue("NoBlueprintsToShare", playerID, target.displayName));
            }
        }

        private int UnlockBlueprints(BasePlayer player, List<int> blueprints)
        {
            if (player != null)
            {
                var playerInfo = player.PersistantPlayerInfo;

                var unlockedBlueprints = playerInfo.unlockedItems;

                var successfulUnlocks = 0;

                foreach (var blueprint in blueprints)
                {
                    if (!unlockedBlueprints.Contains(blueprint))
                    {
                        unlockedBlueprints.Add(blueprint);

                        successfulUnlocks++;
                    }
                }

                player.PersistantPlayerInfo = playerInfo;
                player.SendNetworkUpdateImmediate();
                player.ClientRPCPlayer(null, player, "UnlockedBlueprint", 0);

                PlaySoundEffect(player);

                return successfulUnlocks;
            }

            return 0;
        }

        private bool SomeoneWillLearnBlueprint(BasePlayer player, ItemDefinition item)
        {
            if (player == null || item == null) return false;

            var targets = SelectSharePlayers(player);

            if (targets.Count > 0)
            {
                var counter = 0;

                foreach (var target in targets)
                {
                    if (target != null)
                    {
                        if (!target.blueprints.HasUnlocked(item))
                        {
                            counter++;
                        }
                    }
                }

                return counter > 0;
            }

            return false;
        }

        private List<BasePlayer> SelectSharePlayers(BasePlayer player)
        {
            var ids = new List<ulong>();

            var playerID = player.userID;

            if (config.ClansEnabled && Clans != null && InClan(playerID))
            {
                ids.AddRange(GetClanMembers(playerID));
            }

            if (config.FriendsEnabled && HasFriends(playerID))
            {
                ids.AddRange(GetFriends(playerID));
            }

            if (config.TeamsEnabled && InTeam(playerID))
            {
                ids.AddRange(GetTeamMembers(playerID));
            }

            return FindPlayers(ids, playerID);
        }

        #endregion

        #region Utility

        private BasePlayer FindPlayer(string playerName, BasePlayer player, string playerID)
        {
            var targets = FindPlayers(playerName);

            if (targets.Count <= 0)
            {
                player.ChatMessage(GetLangValue("Prefix", playerID) + GetLangValue("PlayerNotFound", playerID));

                return null;
            }

            if (targets.Count > 1)
            {
                player.ChatMessage(GetLangValue("Prefix", playerID) + GetLangValue("MultiplePlayersFound", playerID));

                return null;
            }

            return targets.First();
        }

        private List<BasePlayer> FindPlayers(string playerName)
        {
            if (string.IsNullOrEmpty(playerName)) return null;

            return BasePlayer.allPlayerList.Where(p => p && p.UserIDString == playerName || p.displayName.Contains(playerName, CompareOptions.OrdinalIgnoreCase)).ToList();
        }

        private void PlaySoundEffect(BasePlayer player)
        {
            if (player == null) return;

            var soundEffect = new Effect("assets/prefabs/deployable/research table/effects/research-success.prefab", player.transform.position, Vector3.zero);

            if (soundEffect == null) return;

            EffectNetwork.Send(soundEffect, player.net.connection);
        }

        private List<BasePlayer> FindPlayers(List<ulong> ids, ulong playerId)
        {
            var targets = new List<BasePlayer>();

            foreach (var id in ids)
            {
                var target = RustCore.FindPlayerById(id);

                if (target != null && id != playerId && !targets.Contains(target))
                {
                    targets.Add(target);
                }
            }

            return targets;
        }

        private List<ItemDefinition> GetPlayerBlueprintItems(List<int> blueprintIds)
        {
            var blueprintItems = new List<ItemDefinition>();

            foreach (var id in blueprintIds)
            {
                var item = ItemManager.FindItemDefinition(id);

                if (item == null) continue;

                blueprintItems.Add(item);
            }

            return blueprintItems;
        }

        private List<int> ConvertItemsToIds(List<ItemDefinition> items)
        {
            var ids = new List<int>();

            foreach (var item in items)
            {
                if (item == null) continue;

                ids.Add(item.itemid);
            }

            return ids;
        }

        private bool BlueprintBlocked(ItemDefinition item) => config.BlockedItems.Contains(item.shortname);

        #endregion

        #region Chat Commands

        [ChatCommand("bs")]
        private void ToggleCommand(BasePlayer player, string command, string[] args)
        {
            var playerID = player.UserIDString;

            if (args.Length < 1)
            {
                player.ChatMessage(GetLangValue("Help", playerID));

                return;
            }

            switch (args[0].ToLower())
            {
                case "help":
                {
                    player.ChatMessage(GetLangValue("Help", playerID));

                    break;
                }

                case "toggle":
                {
                    if (!permission.UserHasPermission(playerID, TogglePermission))
                    {
                        player.ChatMessage(GetLangValue("Prefix", playerID) + GetLangValue("NoPermission", playerID));

                        return;
                    }

                    if (!PlayerDataExists(playerID))
                    {
                        CreatePlayerData(playerID);
                    }

                    player.ChatMessage(GetLangValue("Prefix", playerID) + GetLangValue(SharingEnabled(playerID) ? "ToggleOff" : "ToggleOn", playerID));

                    storedData.Players[playerID].SharingEnabled = !storedData.Players[playerID].SharingEnabled;

                    SaveData();

                    break;
                }

                case "share":
                {
                    if (!config.ManualSharingEnabled)
                    {
                        player.ChatMessage(GetLangValue("Prefix", playerID) + GetLangValue("ManualSharingDisabled", playerID));

                        return;
                    }

                    if (!permission.UserHasPermission(playerID, SharePermission))
                    {
                        player.ChatMessage(GetLangValue("Prefix", playerID) + GetLangValue("NoPermission", playerID));

                        return;
                    }

                    if (args.Length != 2)
                    {
                        player.ChatMessage(GetLangValue("Prefix", playerID) + GetLangValue("NoTarget", playerID));

                        return;
                    }

                    var target = FindPlayer(args[1], player, playerID);

                    if (target == null) return;

                    if (target == player)
                    {
                        player.ChatMessage(GetLangValue("Prefix", playerID) + GetLangValue("TargetEqualsPlayer", playerID));

                        return;
                    }

                    ShareWithPlayer(player, target);

                    break;
                }

                default:
                {
                    player.ChatMessage(GetLangValue("Prefix", playerID) + GetLangValue("ArgumentsError", playerID));

                    break;
                }
            }
        }

        #endregion

        #region Configuration File

        private Configuration config;

        private class Configuration
        {
            [JsonProperty("Teams Sharing Enabled")]
            public bool TeamsEnabled = true;

            [JsonProperty("Clans Sharing Enabled")]
            public bool ClansEnabled = true;

            [JsonProperty("Friends Sharing Enabled")]
            public bool FriendsEnabled = true;

            [JsonProperty("Share Physical Blueprints")]
            public bool PhysicalSharingEnabled = true;

            [JsonProperty("Share Tech Tree Blueprints")]
            public bool TechTreeSharingEnabled = true;

            [JsonProperty("Allow Manual Sharing of Blueprints")]
            public bool ManualSharingEnabled = true;

            [JsonProperty("Share Blueprints on Join")]
            public bool ShareBlueprintsOnJoin = false;

            [JsonProperty("Clear Data File on Wipe")]
            public bool ClearDataOnWipe = true;

            [JsonProperty("Items Blocked from Sharing")]
            public List<string> BlockedItems = new List<string>();
        }

        protected override void LoadDefaultConfig()
        {
            PrintWarning("Generating new configuration file");

            config = new Configuration();
        }

        protected override void SaveConfig()
        {
            PrintWarning("Configuration file has been saved");

            Config.WriteObject(config, true);
        }

        protected override void LoadConfig()
        {
            base.LoadConfig();

            try
            {
                config = Config.ReadObject<Configuration>();

                if (config == null)
                {
                    throw new JsonException();
                }
            }
            catch
            {
                PrintError($"Configuration file {Name}.json is invalid; Resetting configuration to default values");

                LoadDefaultConfig();
            }
        }

        #endregion

        #region Data File

        private class StoredData
        {
            public Dictionary<string, PlayerData> Players = new Dictionary<string, PlayerData>();
        }

        private class PlayerData
        {
            public bool SharingEnabled;
        }

        private void CreateData()
        {
            storedData = new StoredData();

            SaveData();
        }

        private void LoadData()
        {
            if (Interface.Oxide.DataFileSystem.ExistsDatafile(Name))
            {
                storedData = Interface.Oxide.DataFileSystem.ReadObject<StoredData>(Name);
            }
            else
            {
                CreateData();
            }
        }

        private void SaveData() => Interface.Oxide.DataFileSystem.WriteObject(Name, storedData);

        private bool PlayerDataExists(string playerID) => storedData.Players.ContainsKey(playerID);

        private void CreatePlayerData(string playerID)
        {
            storedData.Players.Add(playerID, new PlayerData
            {
                SharingEnabled = true
            });

            SaveData();
        }

        #endregion

        #region Localization File

        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["Prefix"] = "<color=#D85540>[Blueprint Share] </color>",
                ["ArgumentsError"] = "Error, incorrect arguments.Try /bs help.",
                ["Help"] = "<color=#D85540>Blueprint Share Help:</color>\n\n<color=#D85540>/bs toggle</color> - Toggles the sharing of blueprints.\n<color=#D85540>/bs share <player></color> - Shares your blueprints with other player.",
                ["ToggleOn"] = "You have <color=#00ff00>enabled</color> sharing blueprints.",
                ["ToggleOff"] = "You have <color=#ff0000>disabled</color> sharing blueprints.",
                ["NoPermission"] = "You don't have permission to use this command!",
                ["CannotShare"] = "You cannot share blueprints with this player because they aren't a friend or in the same clan or team!",
                ["NoTarget"] = "You didn't specify a player to share with!",
                ["TargetEqualsPlayer"] = "You cannot share blueprints with yourself!",
                ["PlayerNotFound"] = "Could not find a player with that name!",
                ["MultiplePlayersFound"] = "Found multiple players with a similar name: {0}",
                ["SharerSuccess"] = "You shared <color=#ffff00>{0}</color> blueprint(s) with <color=#ffff00>{1}</color>.",
                ["ShareReceieve"] = "<color=#ffff00>{0}</color> has shared <color=#ffff00>{1}</color> blueprint(s) with you.",
                ["NoBlueprintsToShare"] = "You don't have any new blueprints to share with <color=#ffff00>{0}</color>.",
                ["SharerLearntBlueprint"] = "You have learned the <color=#ffff00>{0}</color> blueprint and have shared it with <color=#ffff00>{1}</color> player(s)!",
                ["TargetLearntBlueprint"] = "<color=#ffff00>{0}</color> has shared the <color=#ffff00>{1}</color> blueprint with you!",
                ["BlueprintBlocked"] = "The server has blocked the <color=#ffff00>{0}</color> blueprint from being shared but you will still learn the blueprint.",
                ["ManualSharingDisabled"] = "Manual sharing of blueprints is disabled on this server.",
                ["TargetSharingDisabled"] = "Unable to share blueprints with <color=#ffff00>{0}</color> because they have disabled their sharing."
            }, this);
        }

        private string GetLangValue(string key, string id = null, params object[] args)
        {
            var msg = lang.GetMessage(key, this, id);

            return args.Length > 0 ? string.Format(msg, args) : msg;
        }

        #endregion

        #region API

        private bool SharingEnabled(string playerID) => !storedData.Players.ContainsKey(playerID) || storedData.Players[playerID].SharingEnabled;

        #endregion
    }
}

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