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

FREE DeathPenalty : 1.2.0 1.2.0

Нет прав для скачивания
C#:
// TODO: dataファイルに時間を取り日付が変わったタイミングでカウント0

#region 更新履歴
// 1.2.0
//   * コンフィグ変更
//   * コンフィグ変更後に変更した値を読み込めない問題の修正
//
#endregion

using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using Oxide.Core;
using Oxide.Core.Configuration;
using Oxide.Core.Plugins;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("DeathPenalty", "babu77", "1.2.0")]
    [Description("Dead players will be deprived of their property.")]
    public class DeathPenalty : RustPlugin
    {
        [PluginReference]
        private Plugin Economics, ServerRewards;//, ZoneManeger;

        #region Variables
        const string pName = "<color=yellow>[DeathPenalty]:</color>";
        const string perm_use = "deathpenalty.use";
        const string perm_admin = "deathpenalty.admin";
        private DynamicConfigFile DATA_PLAYER_LOST_CR;//コインとRPのロスト分集計用データファイル
        private Dictionary<ulong, PlayerDataCR> LOST_DATA;
        private Dictionary<string, object> DATA_CONFIG;
        //List<TimeSpan> loadedTime;
        #endregion

        #region Classes

        private class PlayerDataCR
        {
            public double Coins { get; set; }
            public int RP { get; set; }
        }
        #endregion

        #region Configurations
        private bool Changed;
        //
        private double MinRateEconomics;
        private double MaxRateEconomics;
        private double MinRateRP;
        private double MaxRateRP;
        private string ReceiverSteamID;
        private bool ReceiverFlag;
        private bool UseEconomics;
        private bool UseServerRewards;
        private void LoadVariables()
        {
            MinRateEconomics = Convert.ToDouble(GetConfig("Config", "Min_Rate_Economics(0.00 - 1.00)", 0.01));
            MaxRateEconomics = Convert.ToDouble(GetConfig("Config", "Max_Rate_Economics(0.00 - 1.00)", 0.1));
            MinRateRP = Convert.ToDouble(GetConfig("Config", "Min_Rate_RP(0.00 - 1.00)", 0.01));
            MaxRateRP = Convert.ToDouble(GetConfig("Config", "Max_Rate_RP(0.00 - 1.00)", 0.1));
            ReceiverFlag = Convert.ToBoolean(GetConfig("Config", "Receiver", false));
            ReceiverSteamID = Convert.ToString(GetConfig("Config", "Receiver_Player_steamID", "0"));
            UseEconomics = Convert.ToBoolean(GetConfig("Config", "Use_Economics", false));
            UseServerRewards = Convert.ToBoolean(GetConfig("Config", "Use_ServerRewards", false));
        }
        private object GetConfig(string menu, string dataValue, object defaultValue)
        {
            Dictionary<string, object> data = Config[menu] as Dictionary<string, object>;
            if (data == null)
            {
                data = new Dictionary<string, object>();
                Config[menu] = data;
                Changed = true;
            }
            object value;
            if (!data.TryGetValue(dataValue, out value))
            {
                value = defaultValue;
                data[dataValue] = value;
                Changed = true;
            }
            return value;
        }
        private void DPLoadConfig()
        {
            DATA_CONFIG = Config["Config"] as Dictionary<string, object>;
            LoadVariables();
        }
        #endregion

        #region OxideHook
        private void Init()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                {"NoPerm", "You don't have a permission."},
                {"NoEconomics", "Can't find Economics Plugin."},
                {"InternalError", "A serious error has occurred in the plugin. Please report this to the administrator." },
                {"NotRun", "Plugin is not running." },
                {"PlayerLostCoins", "You have lost {reduce} of your Economics balance."},
                {"PlayerLostRP", "You have lost {reduce} RP."},
                {"CheckBalance", "The balance you've lost so far.\n Economics: {amountEconomics}\n RP: {amountRP}" }
            }, this);
        }
        protected override void LoadDefaultConfig()
        {
            Config.Clear();
            LoadVariables();
        }
        private void Loaded()
        {
            permission.RegisterPermission(perm_admin, this);
            permission.RegisterPermission(perm_use, this);

            //コインとRPロスト分
            DATA_PLAYER_LOST_CR = GetFile(nameof(DeathPenalty));
            LOST_DATA = DATA_PLAYER_LOST_CR.ReadObject<Dictionary<ulong, PlayerDataCR>>();

            DPLoadConfig();
            //Puts($"{MinRateEconomics}, {MaxRateEconomics}, {MinRateRP}, {MaxRateRP}, {ReceiverFlag}, {ReceiverSteamID}, {UseEconomics}. {UseServerRewards}");
        }
        private object OnPlayerDeath(BasePlayer player, HitInfo info)
        {
            if(!permission.UserHasPermission(player.UserIDString, perm_use))
            {
                return null;
            }

            /** 追記 ここから **/
            //BasePlayer attacker = player.lastAttacker?.ToPlayer();
            /** 追記 ここまで **/

            ChangeEconomicsOrRp(player);
            return null;
        }
        private void OnServerSave()
        {
            SaveLostData();
        }
        private void OnServerShutdown() => OnServerSave();
        private void Unload() => OnServerSave();

        private void SaveLostData()
        {
            if (LOST_DATA == null) return;
            DATA_PLAYER_LOST_CR.WriteObject(LOST_DATA);
        }

        private void OnNewSave()
        {
            DATA_PLAYER_LOST_CR.Clear();
        }
        #endregion

        #region Functions
        private DynamicConfigFile GetFile(string name)
        {
            var file = Interface.Oxide.DataFileSystem.GetFile(name);
            file.Settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
            file.Settings.Converters = new JsonConverter[] { new UnityVector3Converter(), new CustomComparerDictionaryCreationConverter<string>(StringComparer.OrdinalIgnoreCase) };
            return file;
        }

        /// <summary>
        /// コインとRPの変更(メイン)
        /// </summary>
        /// <param name="player">プレイヤー</param>
        private void ChangeEconomicsOrRp(BasePlayer player)
        {
            bool checker = true;
            bool _bool;

            //Puts($"Economics: {UseEconomics}, Server Rewards: {UseServerRewards}");

            if (UseEconomics && UseServerRewards)
            {
                if (Economics != null && ServerRewards != null)//正常系
                {
                    SqueezeSelector(player);
                }
                else
                {
                    SendMessage(player, lang.GetMessage("InternalError", this));
                    Puts("Can not find Economics and ServerRewards.");
                }
            }
            else if(UseEconomics && !UseServerRewards)
            {
                if (Economics != null)//ServerRewardsなし
                {
                    _bool = ChangeEconomics(player);
                }
                else
                {
                    SendMessage(player, lang.GetMessage("InternalError", this));
                    Puts("Can not find Economics.");
                }
            }
            else if (!UseEconomics && UseServerRewards)
            {
                Puts("OK");
                if (ServerRewards != null) //Economicsなし
                {
                    _bool = ChangeRp(player);
                }
                else
                {
                    SendMessage(player, lang.GetMessage("InternalError", this));
                    Puts("Can not find ServerRewards.");
                }
            }
            else
            {
                Puts("DeathPenalty is not active.");
            }

            return;

            //if (Economics == null && ServerRewards == null)//全部だめ
            //{
            //    SendMessage(player, lang.GetMessage("InternalError", this));
            //    Puts("Can not find Economics and ServerRewards.");
            //    return;
            //}
            //else if(Economics != null && ServerRewards == null)//ServerRewardsなし
            //{
            //    _bool = ChangeEconomics(player);
            //    return;
            //}
            //else if (Economics == null && ServerRewards != null)//Economicsなし
            //{
            //    _bool = ChangeRp(player);
            //    return;
            //}
            //else if (Economics != null && ServerRewards != null)//正常系
            //{
            //    SqueezeSelector(player);
            //    return;
            //}
            //else
            //{
            //    SendMessage(player, lang.GetMessage("InternalError", this));
            //    Puts("Can not find Economics and ServerRewards.");
            //    return;
            //}
        }

        private void SqueezeSelector(BasePlayer player)
        {
            double rateRandom = (double)UnityEngine.Random.Range(0, 1.0f);
            rateRandom = Math.Round(rateRandom, 1, MidpointRounding.AwayFromZero);

            bool _bool;

            if (0.5 <= rateRandom)
            {
                _bool = ChangeEconomics(player);
            }
            else
            {
                _bool = ChangeRp(player);
            }

            return;
        }

        private bool ChangeEconomics(BasePlayer player)
        {
            double playerCoins = (double)Economics.CallHook("Balance", player.UserIDString);

            if (playerCoins == 0)
            {
                return true;
            }

            double rateRandom = UnityEngine.Random.Range(Convert.ToSingle(MinRateEconomics), Convert.ToSingle(MaxRateEconomics));

            double reduce = Math.Round(playerCoins * rateRandom, 1, MidpointRounding.AwayFromZero);

            object tmp_economics;
            if (ReceiverFlag && ReceiverSteamID != "0")
            {
                tmp_economics = Economics.CallHook("Transfer", player.UserIDString, ReceiverSteamID, reduce);
            }
            else
            {
                tmp_economics = Economics.CallHook("Withdraw", player.UserIDString, reduce);
            }

            if (tmp_economics == null || !(tmp_economics is bool) && !(bool)tmp_economics)
            {
                SendMessage(player, lang.GetMessage("NotRun", this));
                Puts("Plugin is not running.:Economics");
                return false;
            }

            playerCoins = (double)Economics.CallHook("Balance", player.UserIDString);
            LoggingDeathData(player, reduce, "COINS");

            return true;
        }

        private bool ChangeRp(BasePlayer player)
        {

            int? NplayerRP = (int)ServerRewards?.Call("CheckPoints", player.userID);
            int playerRP;

            if (NplayerRP == null || NplayerRP == 0)
            {
                return true;
            }
            else
            {
                playerRP = Convert.ToInt32(NplayerRP);
            }

            double rateRandom = UnityEngine.Random.Range(Convert.ToSingle(MinRateRP), Convert.ToSingle(MaxRateRP));

            int reduce = (int)Math.Round(playerRP * rateRandom, 0, MidpointRounding.AwayFromZero);

            object tmp_RP;
            object tmp_RP_T;
            if (ReceiverFlag && ReceiverSteamID != "0")
            {
                tmp_RP = ServerRewards?.Call("TakePoints", player.userID, reduce);
                tmp_RP_T = ServerRewards?.Call("AddPoints", Convert.ToUInt64(ReceiverSteamID), reduce);
            }
            else
            {
                tmp_RP = ServerRewards?.Call("TakePoints", player.userID, reduce);
            }

            if (tmp_RP == null || tmp_RP is bool && !(bool)tmp_RP)
            {
                SendMessage(player, lang.GetMessage("NotRun", this));
                Puts("Plugin is not running.:ServerRewards");
                return false;
            }

            playerRP = (int)ServerRewards?.Call("CheckPoints", player.userID);
            LoggingDeathData(player, reduce, "RP");

            return true;
        }

        /// <summary>
        /// ログ吐き出し
        /// </summary>
        /// <param name="player">プレイヤー</param>
        /// <param name="reduce">値</param>
        private void LoggingDeathData(BasePlayer player,double reduce, string type)
        {
            //double currentDouble;
            //int currentInt;
            PlayerDataCR currentPlayerData;

            if (!LOST_DATA.TryGetValue(player.userID, out currentPlayerData))
            {
                currentPlayerData = new PlayerDataCR();
                LOST_DATA.Add(player.userID, currentPlayerData);
            }

            if (type.Equals("COINS"))
            {
                Log(player + " lost " + reduce + " coins");

                currentPlayerData.Coins += reduce;

                SendMessage(player, lang.GetMessage("PlayerLostCoins", this).Replace("{reduce}", reduce.ToString()));
                Puts(player.displayName + "[" + player.UserIDString + "] lost " + reduce + " coins.");

                return;
            }
            if (type.Equals("RP"))
            {
                Log(player + " lost " + reduce + " RP");

                currentPlayerData.RP += (int)reduce;

                SendMessage(player, lang.GetMessage("PlayerLostRP", this).Replace("{reduce}", reduce.ToString()));
                Puts(player.displayName + "[" + player.UserIDString + "] lost " + reduce + " RP.");
                
                return;
            }

            LOST_DATA[player.userID] = currentPlayerData;

            return;
        }
        #endregion

        #region Commands

        //[ConsoleCommand("deathpenalty.convert")]
        //private void DataConvert()
        //{
        //    Puts("Data convert START");

        //    DynamicConfigFile dataPlayerLostCoins;//コインロスト分集計用データファイル
        //    DynamicConfigFile dataPlayerLostRP;//RPロスト分集計用データファイル

        //    Dictionary<ulong, double> LostCoinData;
        //    Dictionary<ulong, int> LostRPData; 
            
        //    //コインロスト分集計
        //    dataPlayerLostCoins = GetFile(nameof(DeathPenalty) + "_LostCoins");
        //    LostCoinData = dataPlayerLostCoins.ReadObject<Dictionary<ulong, double>>();

        //    //RPロスト分集計
        //    dataPlayerLostRP = GetFile(nameof(DeathPenalty) + "_LostRP");
        //    LostRPData = dataPlayerLostRP.ReadObject<Dictionary<ulong, int>>();

        //    Puts("Coins Data convert START");
        //    if (LostCoinData != null)
        //    {
        //        foreach (var playerOldCoinData in LostCoinData)
        //        {
        //            //Puts($"COINS OLD DATA:   {playerOldCoinData.Key}:{playerOldCoinData.Value}");
        //            PlayerDataCR playerNewData;
        //            if (!LOST_DATA.TryGetValue(playerOldCoinData.Key, out playerNewData))
        //            {
        //                playerNewData = new PlayerDataCR();
        //                playerNewData.Coins += playerOldCoinData.Value;
        //                LOST_DATA.Add(playerOldCoinData.Key, playerNewData);
        //            }
        //            else
        //            {
        //                playerNewData.Coins += playerOldCoinData.Value;
        //            }

        //            LOST_DATA[playerOldCoinData.Key] = playerNewData;
        //        }
        //    }
        //    Puts("Coins Data convert END");
            
        //    SaveLostData();

        //    Puts("RP Data convert START");
        //    if (LostRPData != null)
        //    {
        //        foreach (var playerOldRPData in LostRPData)
        //        {
        //            PlayerDataCR playerNewData;
        //            //Puts($"RP OLD DATA:   {playerOldRPData.Key}:{playerOldRPData.Value}");
        //            if (!LOST_DATA.TryGetValue(playerOldRPData.Key, out playerNewData))
        //            {
        //                playerNewData = new PlayerDataCR();
        //                playerNewData.RP += playerOldRPData.Value;
        //                LOST_DATA.Add(playerOldRPData.Key, playerNewData);
        //            }
        //            else
        //            {
        //                playerNewData.RP += playerOldRPData.Value;
        //            }

        //            LOST_DATA[playerOldRPData.Key] = playerNewData;
        //        }
        //    }
        //    Puts("RP Data convert END");

        //    SaveLostData();

        //    Puts("Data convert END");

        //}

        [ChatCommand("dp")]
        private void DpCmd(BasePlayer player, string command, string[] args)
        {
            PlayerDataCR playerData;

            if(!LOST_DATA.TryGetValue(player.userID, out playerData))
            {
                playerData = new PlayerDataCR();
                LOST_DATA.Add(player.userID, playerData);
            }

            //SendMessage(player, lang.GetMessage("CPlayerLostCoins", this).Replace("{amount}", playerData.Coins.ToString()));
            //SendMessage(player, lang.GetMessage("CPlayerLostRP", this).Replace("{amount}", playerData.RP.ToString()));
            SendMessage(player, lang.GetMessage("CheckBalance", this).Replace("{amountEconomics}", playerData.Coins.ToString()).Replace("{amountRP}", playerData.RP.ToString()));
        }
        #endregion

        #region Helper
        private class UnityVector3Converter : JsonConverter
        {
            public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
            {
                var vector = (Vector3)value;
                writer.WriteValue($"{vector.x} {vector.y} {vector.z}");
            }
            public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
            {
                if (reader.TokenType == JsonToken.String)
                {
                    var values = reader.Value.ToString().Trim().Split(' ');
                    return new Vector3(Convert.ToSingle(values[0]), Convert.ToSingle(values[1]), Convert.ToSingle(values[2]));
                }
                var o = JObject.Load(reader);
                return new Vector3(Convert.ToSingle(o["x"]), Convert.ToSingle(o["y"]), Convert.ToSingle(o["z"]));
            }
            public override bool CanConvert(Type objectType)
            {
                return objectType == typeof(Vector3);
            }
        }
        private class CustomComparerDictionaryCreationConverter<T> : CustomCreationConverter<IDictionary>
        {
            private readonly IEqualityComparer<T> comparer;
            public CustomComparerDictionaryCreationConverter(IEqualityComparer<T> comparer)
            {
                if (comparer == null) throw new ArgumentNullException(nameof(comparer));
                this.comparer = comparer;
            }
            public override bool CanConvert(Type objectType)
            {
                return HasCompatibleInterface(objectType) && HasCompatibleConstructor(objectType);
            }
            private static bool HasCompatibleInterface(Type objectType)
            {
                return objectType.GetInterfaces().Where(i => HasGenericTypeDefinition(i, typeof(IDictionary<,>))).Any(i => typeof(T).IsAssignableFrom(i.GetGenericArguments().First()));
            }
            private static bool HasGenericTypeDefinition(Type objectType, Type typeDefinition)
            {
                return objectType.IsGenericType && objectType.GetGenericTypeDefinition() == typeDefinition;
            }
            private static bool HasCompatibleConstructor(Type objectType)
            {
                return objectType.GetConstructor(new[] { typeof(IEqualityComparer<T>) }) != null;
            }
            public override IDictionary Create(Type objectType)
            {
                return Activator.CreateInstance(objectType, comparer) as IDictionary;
            }
        }
        void SendMessage(BasePlayer player, string message, params object[] args) => PrintToChat(player, pName + message, args);
        private void Log(string text) => LogToFile("death", $"[{DateTime.Now}] {text}", this);
        #endregion
    }
}

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