﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Libraries.Covalence;
using Oxide.Game.Rust;
using Rust;
using UnityEngine;
using Random = UnityEngine.Random;

namespace Oxide.Plugins
{
    [Info("Godmode", "Wulf/lukespragg/Arainrr/dFxPhoeniX", "4.2.15")]
    [Description("Allows players with permission to be invulnerable and god-like")]
    internal class Godmode : RustPlugin
    {
        #region Fields

        private const string PermAdmin = "godmode.admin";
        private const string PermInvulnerable = "godmode.invulnerable";
        private const string PermLootPlayers = "godmode.lootplayers";
        private const string PermLootProtection = "godmode.lootprotection";
        private const string PermNoAttacking = "godmode.noattacking";
        private const string PermToggle = "godmode.toggle";
        private const string PermUntiring = "godmode.untiring";
        private const string PermAutoEnable = "godmode.autoenable";

        private readonly object _false = false, _true = true;
        private Dictionary<ulong, float> _informHistory;
        private readonly StoredMetabolism _storedMetabolism = new StoredMetabolism();

        #endregion Fields

        #region Oxide Hook

        private void Init()
        {
            LoadData();
            permission.RegisterPermission(PermAdmin, this);
            permission.RegisterPermission(PermInvulnerable, this);
            permission.RegisterPermission(PermLootPlayers, this);
            permission.RegisterPermission(PermLootProtection, this);
            permission.RegisterPermission(PermNoAttacking, this);
            permission.RegisterPermission(PermToggle, this);
            permission.RegisterPermission(PermUntiring, this);
            permission.RegisterPermission(PermAutoEnable, this);

            AddCovalenceCommand(configData.godCommand, nameof(GodCommand));
            AddCovalenceCommand(configData.godsCommand, nameof(GodsCommand));
            if (configData.informOnAttack)
            {
                _informHistory = new Dictionary<ulong, float>();
            }
            if (!configData.disconnectDisable)
            {
                Unsubscribe(nameof(OnPlayerDisconnected));
            }
        }

        private void OnServerInitialized()
        {
            if (!_storedMetabolism.FetchDefaultMetabolism())
            {
                PrintError("Failed to fetch default metabolism data");
            }
            foreach (var god in storedData.godPlayers.ToArray())
            {
                if (!permission.UserHasPermission(god, PermToggle))
                {
                    storedData.godPlayers.Remove(god);
                    continue;
                }
                EnableGodmode(god, true);
            }
            CheckHooks();
        }

        private void OnServerSave()
        {
            timer.Once(Random.Range(0f, 60f), SaveData);
        }

        private void OnPlayerConnected(BasePlayer player)
        {
            if (IsGod(player))
            {
                PlayerRename(player, true);
                ModifyMetabolism(player, true);
            }
            else if (permission.UserHasPermission(player.UserIDString, PermAutoEnable))
            {
                EnableGodmode(player.UserIDString);
            }
        }

        private void OnPlayerDisconnected(BasePlayer player, string reason)
        {
            if (IsGod(player))
            {
                DisableGodmode(player.UserIDString);
            }
        }

        private void Unload()
        {
            foreach (var god in storedData.godPlayers.ToArray())
            {
                DisableGodmode(god, true);
            }
            SaveData();
        }

        private object CanBeWounded(BasePlayer player)
        {
            return IsGod(player) ? _false : null;
        }

        private object CanLootPlayer(BasePlayer target, BasePlayer looter)
        {
            if (target == null || looter == null || target == looter)
            {
                return null;
            }
            if (IsGod(target) && permission.UserHasPermission(target.UserIDString, PermLootProtection) && !permission.UserHasPermission(looter.UserIDString, PermLootPlayers))
            {
                Print(looter, Lang("NoLooting", looter.UserIDString));
                return _false;
            }
            return null;
        }

        private object OnEntityTakeDamage(BasePlayer player, HitInfo info)
        {
            if (player == null || !player.userID.IsSteamId())
            {
                return null;
            }
            var attacker = info?.InitiatorPlayer;
            if (IsGod(player) && permission.UserHasPermission(player.UserIDString, PermInvulnerable))
            {
                InformPlayers(player, attacker);
                NullifyDamage(ref info);
                return _true;
            }
            if (IsGod(attacker) && permission.UserHasPermission(attacker.UserIDString, PermNoAttacking))
            {
                InformPlayers(player, attacker);
                NullifyDamage(ref info);
                return _true;
            }
            return null;
        }

        private object OnRunPlayerMetabolism(PlayerMetabolism metabolism, BasePlayer player, float delta)
        {
            if (!IsGod(player))
            {
                return null;
            }
            metabolism.hydration.value = _storedMetabolism.GetMaxHydration();
            if (!permission.UserHasPermission(player.UserIDString, PermUntiring))
            {
                return null;
            }
            var currentCraftLevel = player.currentCraftLevel;
            player.SetPlayerFlag(BasePlayer.PlayerFlags.Workbench1, currentCraftLevel == 1f);
            player.SetPlayerFlag(BasePlayer.PlayerFlags.Workbench2, currentCraftLevel == 2f);
            player.SetPlayerFlag(BasePlayer.PlayerFlags.Workbench3, currentCraftLevel == 3f);
            player.SetPlayerFlag(BasePlayer.PlayerFlags.SafeZone, player.InSafeZone());
            return _false;
        }

        #endregion Oxide Hook

        #region Methods

        private void CheckHooks()
        {
            if (storedData.godPlayers.Count > 0)
            {
                Subscribe(nameof(CanBeWounded));
                Subscribe(nameof(CanLootPlayer));
                Subscribe(nameof(OnEntityTakeDamage));
                Subscribe(nameof(OnRunPlayerMetabolism));
            }
            else
            {
                Unsubscribe(nameof(CanBeWounded));
                Unsubscribe(nameof(CanLootPlayer));
                Unsubscribe(nameof(OnEntityTakeDamage));
                Unsubscribe(nameof(OnRunPlayerMetabolism));
            }
        }

        private void InformPlayers(BasePlayer victim, BasePlayer attacker)
        {
            if (!configData.informOnAttack || victim == null || attacker == null || victim == attacker)
            {
                return;
            }
            if (!victim.userID.IsSteamId() || !attacker.userID.IsSteamId())
            {
                return;
            }
            float victimTime;
            if (!_informHistory.TryGetValue(victim.userID, out victimTime))
            {
                _informHistory.Add(victim.userID, 0);
            }
            float attackerTime;
            if (!_informHistory.TryGetValue(attacker.userID, out attackerTime))
            {
                _informHistory.Add(attacker.userID, 0);
            }
            var currentTime = Time.realtimeSinceStartup;
            if (IsGod(victim))
            {
                if (currentTime - victimTime > configData.informInterval)
                {
                    _informHistory[victim.userID] = currentTime;
                    Print(attacker, Lang("InformAttacker", attacker.UserIDString, victim.displayName));
                }
                if (currentTime - attackerTime > configData.informInterval)
                {
                    _informHistory[attacker.userID] = currentTime;
                    Print(victim, Lang("InformVictim", victim.UserIDString, attacker.displayName));
                }
            }
            else if (IsGod(attacker))
            {
                if (currentTime - victimTime > configData.informInterval)
                {
                    _informHistory[victim.userID] = currentTime;
                    Print(attacker, Lang("CantAttack", attacker.UserIDString, victim.displayName));
                }
                if (currentTime - attackerTime > configData.informInterval)
                {
                    _informHistory[attacker.userID] = currentTime;
                    Print(victim, Lang("InformVictim", victim.UserIDString, attacker.displayName));
                }
            }
        }

        #region Godmode Toggle

        private bool? ToggleGodmode(BasePlayer target, BasePlayer player)
        {
            var isGod = IsGod(target);
            if (Interface.CallHook("OnGodmodeToggle", target.UserIDString, !isGod) != null)
            {
                return null;
            }
            if (isGod)
            {
                DisableGodmode(target.UserIDString);
                if (player != null)
                {
                    if (target == player)
                    {
                        Print(player, Lang("GodmodeDisabled", player.UserIDString));
                    }
                    else
                    {
                        Print(player, Lang("GodmodeDisabledFor", player.UserIDString, target.displayName));
                        Print(target, Lang("GodmodeDisabledBy", target.UserIDString, player.displayName));
                    }
                }
                else
                {
                    Print(target, Lang("GodmodeDisabledBy", target.UserIDString, "server console"));
                }
                return false;
            }

            EnableGodmode(target.UserIDString);
            if (player != null)
            {
                if (target == player)
                {
                    Print(player, Lang("GodmodeEnabled", player.UserIDString));
                }
                else
                {
                    Print(player, Lang("GodmodeEnabledFor", player.UserIDString, target.displayName));
                    Print(target, Lang("GodmodeEnabledBy", target.UserIDString, player.displayName));
                }
            }
            else
            {
                Print(target, Lang("GodmodeEnabledBy", target.UserIDString, "server console"));
            }
            var targetId = target.UserIDString;
            if (configData.timeLimit > 0)
            {
                timer.Once(configData.timeLimit, () => DisableGodmode(targetId));
            }
            return true;
        }

        private bool EnableGodmode(string playerId, bool isInit = false)
        {
            if (string.IsNullOrEmpty(playerId) || !isInit && IsGod(playerId))
            {
                return false;
            }
            var player = RustCore.FindPlayerByIdString(playerId);
            if (player == null)
            {
                return false;
            }
            PlayerRename(player, true);
            ModifyMetabolism(player, true);
            if (!isInit)
            {
                storedData.godPlayers.Add(player.UserIDString);
                CheckHooks();
            }
            Interface.CallHook("OnGodmodeToggled", playerId, true);
            return true;
        }

        private bool DisableGodmode(string playerId, bool isUnload = false)
        {
            if (string.IsNullOrEmpty(playerId) || !IsGod(playerId))
            {
                return false;
            }
            var player = RustCore.FindPlayerByIdString(playerId);
            if (player == null)
            {
                return false;
            }
            PlayerRename(player, false);
            ModifyMetabolism(player, false);
            if (!isUnload)
            {
                storedData.godPlayers.Remove(player.UserIDString);
                CheckHooks();
            }
            Interface.CallHook("OnGodmodeToggled", playerId, false);
            return true;
        }

        private void PlayerRename(BasePlayer player, bool isGod)
        {
            if (player == null || !configData.showNamePrefix || string.IsNullOrEmpty(configData.namePrefix))
            {
                return;
            }
            var originalName = GetPayerOriginalName(player.userID);
            if (isGod)
            {
                Rename(player, configData.namePrefix + originalName);
            }
            else
            {
                Rename(player, originalName);
            }
        }

        private void Rename(BasePlayer player, string newName)
        {
            if (player == null || string.IsNullOrEmpty(newName.Trim()))
            {
                return;
            }
            player._name = player.displayName = newName;
            if (player.IPlayer != null)
            {
                player.IPlayer.Name = newName;
            }
            if (player.net?.connection != null)
            {
                player.net.connection.username = newName;
            }
            permission.UpdateNickname(player.UserIDString, newName);
            Player.Teleport(player, player.transform.position);
            player.SendNetworkUpdateImmediate();
            //SingletonComponent<ServerMgr>.Instance.persistance.SetPlayerName(player.userID, newName);
        }

        private void ModifyMetabolism(BasePlayer player, bool isGod)
        {
            if (player == null || player.metabolism == null)
            {
                return;
            }

            if (isGod)
            {
                player.health = player.MaxHealth();
                _storedMetabolism.Unlimited(player.metabolism);
            }
            else
            {
                player.health = player.MaxHealth();
                _storedMetabolism.Restore(player.metabolism);
            }
        }

        #endregion Godmode Toggle

        #region Stored Metabolism

        private class StoredMetabolism
        {
            private struct Attribute
            {
                public float Min { get; private set; }
                public float Max { get; private set; }

                public Attribute(MetabolismAttribute attribute)
                {
                    Min = attribute.min;
                    Max = attribute.max;
                }

                public void Reset(MetabolismAttribute attribute)
                {
                    attribute.min = Min;
                    attribute.max = Max;
                }
            }

            public bool FetchDefaultMetabolism()
            {
                var playerPrefab = "assets/prefabs/player/player.prefab";
                var playerMetabolism = GameManager.server.FindPrefab(playerPrefab)?.GetComponent<PlayerMetabolism>();
                if (playerMetabolism != null)
                {
                    Store(playerMetabolism);
                    return true;
                }
                return false;
            }

            private Attribute calories;
            private Attribute hydration;
            private Attribute heartrate;
            private Attribute temperature;
            private Attribute poison;
            private Attribute radiation_level;
            private Attribute radiation_poison;
            private Attribute wetness;
            private Attribute dirtyness;
            private Attribute oxygen;
            private Attribute bleeding;

            // private Attribute comfort;
            // private Attribute pending_health;
            public float GetMaxHydration()
            {
                return hydration.Max;
            }
            public void Store(PlayerMetabolism playerMetabolism)
            {
                calories = new Attribute(playerMetabolism.calories);
                hydration = new Attribute(playerMetabolism.hydration);
                heartrate = new Attribute(playerMetabolism.heartrate);
                temperature = new Attribute(playerMetabolism.temperature);
                poison = new Attribute(playerMetabolism.poison);
                radiation_level = new Attribute(playerMetabolism.radiation_level);
                radiation_poison = new Attribute(playerMetabolism.radiation_poison);
                wetness = new Attribute(playerMetabolism.wetness);
                dirtyness = new Attribute(playerMetabolism.dirtyness);
                oxygen = new Attribute(playerMetabolism.oxygen);
                bleeding = new Attribute(playerMetabolism.bleeding);
                // comfort = new Attribute(playerMetabolism.comfort);
                // pending_health = new Attribute(playerMetabolism.pending_health);
            }

            public void Unlimited(PlayerMetabolism playerMetabolism)
            {
                playerMetabolism.calories.min = calories.Max;
                playerMetabolism.calories.value = calories.Max;
                // playerMetabolism.hydration.min = hydration.Max; // It causes the character to walk slowly
                playerMetabolism.hydration.value = hydration.Max;
                playerMetabolism.heartrate.min = heartrate.Max;
                playerMetabolism.heartrate.value = heartrate.Max;
                playerMetabolism.temperature.min = 37;
                playerMetabolism.temperature.max = 37;
                playerMetabolism.temperature.value = 37;
                playerMetabolism.poison.max = poison.Min;
                playerMetabolism.poison.value = poison.Min;
                playerMetabolism.radiation_level.max = radiation_level.Min;
                playerMetabolism.radiation_level.value = radiation_level.Min;
                playerMetabolism.radiation_poison.max = radiation_poison.Min;
                playerMetabolism.radiation_poison.value = radiation_poison.Min;
                playerMetabolism.wetness.max = wetness.Min;
                playerMetabolism.wetness.value = wetness.Min;
                playerMetabolism.dirtyness.max = dirtyness.Min;
                playerMetabolism.dirtyness.value = dirtyness.Min;
                playerMetabolism.oxygen.min = oxygen.Max;
                playerMetabolism.oxygen.value = oxygen.Max;
                playerMetabolism.bleeding.max = bleeding.Min;
                playerMetabolism.bleeding.value = bleeding.Min;

                playerMetabolism.SendChanges();
            }

            public void Restore(PlayerMetabolism playerMetabolism)
            {
                calories.Reset(playerMetabolism.calories);
                hydration.Reset(playerMetabolism.hydration);
                heartrate.Reset(playerMetabolism.heartrate);
                temperature.Reset(playerMetabolism.temperature);
                poison.Reset(playerMetabolism.poison);
                radiation_level.Reset(playerMetabolism.radiation_level);
                radiation_poison.Reset(playerMetabolism.radiation_poison);
                wetness.Reset(playerMetabolism.wetness);
                dirtyness.Reset(playerMetabolism.dirtyness);
                oxygen.Reset(playerMetabolism.oxygen);
                bleeding.Reset(playerMetabolism.bleeding);
                // comfort.Reset(playerMetabolism.comfort);
                // pending_health.Reset(playerMetabolism.pending_health);

                playerMetabolism.Reset();

                playerMetabolism.calories.value = calories.Max;
                playerMetabolism.hydration.value = hydration.Max;

                playerMetabolism.SendChanges();
            }
        }

        #endregion Stored Metabolism

        #endregion Methods

        #region Helpers

        private static void NullifyDamage(ref HitInfo info)
        {
            info.damageTypes = new DamageTypeList();
            info.HitMaterial = 0;
            info.PointStart = Vector3.zero;
        }

        private static string GetPayerOriginalName(ulong playerId)
        {
            return SingletonComponent<ServerMgr>.Instance.persistance.GetPlayerName(playerId);
        }

        #endregion Helpers

        #region API

        private bool EnableGodmode(IPlayer iPlayer)
        {
            return EnableGodmode(iPlayer.Id);
        }

        private bool EnableGodmode(ulong playerId)
        {
            return EnableGodmode(playerId.ToString());
        }

        private bool DisableGodmode(IPlayer iPlayer)
        {
            return DisableGodmode(iPlayer.Id);
        }

        private bool DisableGodmode(ulong playerId)
        {
            return DisableGodmode(playerId.ToString());
        }

        private bool IsGod(ulong playerId)
        {
            return IsGod(playerId.ToString());
        }

        private bool IsGod(BasePlayer player)
        {
            return player != null && IsGod(player.UserIDString);
        }

        private bool IsGod(string playerId)
        {
            return storedData.godPlayers.Contains(playerId);
        }

        private string[] AllGods(string playerId) => AllGods();
        private string[] AllGods()
        {
            return storedData.godPlayers.ToArray();
        }

        #endregion API

        #region Commands

        private void GodCommand(IPlayer iPlayer, string command, string[] args)
        {
            if (args.Length > 0 && !iPlayer.HasPermission(PermAdmin) || !iPlayer.HasPermission(PermToggle))
            {
                Print(iPlayer, Lang("NotAllowed", iPlayer.Id, command));
                return;
            }
            if (args.Length == 0 && iPlayer.Id == "server_console")
            {
                Print(iPlayer, $"The server console cannot use {command}");
                return;
            }
            var target = args.Length > 0 ? RustCore.FindPlayer(args[0]) : iPlayer.Object as BasePlayer;
            if (args.Length > 0 && target == null)
            {
                Print(iPlayer, Lang("PlayerNotFound", iPlayer.Id, args[0]));
                return;
            }
            var obj = ToggleGodmode(target, iPlayer.Object as BasePlayer);
            if (obj.HasValue && iPlayer.Id == "server_console" && args.Length > 0)
            {
                if (obj.Value)
                {
                    Print(iPlayer, $"'{target?.displayName}' have enabled godmode");
                }
                else
                {
                    Print(iPlayer, $"'{target?.displayName}' have disabled godmode");
                }
            }
        }

        private void GodsCommand(IPlayer iPlayer, string command, string[] args)
        {
            if (!iPlayer.HasPermission(PermAdmin))
            {
                Print(iPlayer, Lang("NotAllowed", iPlayer.Id, command));
                return;
            }
            if (storedData.godPlayers.Count == 0)
            {
                Print(iPlayer, Lang("NoGods", iPlayer.Id));
                return;
            }
            var stringBuilder = new StringBuilder();
            stringBuilder.AppendLine();
            foreach (var god in storedData.godPlayers)
            {
                var player = RustCore.FindPlayerByIdString(god);
                stringBuilder.AppendLine(player == null ? god : player.ToString());
            }
            Print(iPlayer, stringBuilder.ToString());
        }

        #endregion Commands

        #region ConfigurationFile

        private ConfigData configData;

        private class ConfigData
        {
            [JsonProperty(PropertyName = "Inform On Attack (true/false)")]
            public bool informOnAttack = true;

            [JsonProperty(PropertyName = "Inform Interval (Seconds)")]
            public float informInterval = 15;

            [JsonProperty(PropertyName = "Show Name Prefix (true/false)")]
            public bool showNamePrefix = true;

            [JsonProperty(PropertyName = "Name Prefix (Default [God])")]
            public string namePrefix = "[God] ";

            [JsonProperty(PropertyName = "Time Limit (Seconds, 0 to Disable)")]
            public float timeLimit = 0f;

            [JsonProperty(PropertyName = "Disable godmode after disconnect (true/false)")]
            public bool disconnectDisable = false;

            [JsonProperty(PropertyName = "Chat Prefix")]
            public string prefix = "[Godmode]:";

            [JsonProperty(PropertyName = "Chat Prefix color")]
            public string prefixColor = "#00FFFF";

            [JsonProperty(PropertyName = "Chat steamID icon")]
            public ulong steamIDIcon = 0;

            [JsonProperty(PropertyName = "God commands", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public string[] godCommand = { "god", "godmode" };

            [JsonProperty(PropertyName = "Gods commands", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public string[] godsCommand = { "gods", "godlist" };
        }

        protected override void LoadConfig()
        {
            base.LoadConfig();
            try
            {
                configData = Config.ReadObject<ConfigData>();
                if (configData == null)
                {
                    LoadDefaultConfig();
                }
            }
            catch (Exception ex)
            {
                PrintError($"The configuration file is corrupted. \n{ex}");
                LoadDefaultConfig();
            }
            SaveConfig();
        }

        protected override void LoadDefaultConfig()
        {
            PrintWarning("Creating a new configuration file");
            configData = new ConfigData();
        }

        protected override void SaveConfig()
        {
            Config.WriteObject(configData);
        }

        #endregion ConfigurationFile

        #region DataFile

        private StoredData storedData;

        private class StoredData
        {
            public readonly HashSet<string> godPlayers = new HashSet<string>();
        }

        private void LoadData()
        {
            try
            {
                storedData = Interface.Oxide.DataFileSystem.ReadObject<StoredData>(Name);
            }
            catch
            {
                storedData = null;
            }
            if (storedData == null)
            {
                ClearData();
            }
        }

        private void SaveData()
        {
            Interface.Oxide.DataFileSystem.WriteObject(Name, storedData);
        }

        private void ClearData()
        {
            storedData = new StoredData();
            SaveData();
        }

        #endregion DataFile

        #region LanguageFile

        private void Print(IPlayer iPlayer, string message)
        {
            iPlayer?.Reply(message,
                           iPlayer.Id == "server_console"
                                   ? $"{configData.prefix}"
                                   : $"<color={configData.prefixColor}>{configData.prefix}</color>");
        }

        private void Print(BasePlayer player, string message)
        {
            Player.Message(player, message, string.IsNullOrEmpty(configData.prefix) ? string.Empty : $"<color={configData.prefixColor}>{configData.prefix}</color>", configData.steamIDIcon);
        }

        private string Lang(string key, string id = null, params object[] args)
        {
            try
            {
                return string.Format(lang.GetMessage(key, this, id), args);
            }
            catch (Exception)
            {
                PrintError($"Error in the language formatting of '{key}'. (userid: {id}. lang: {lang.GetLanguage(id)}. args: {string.Join(" ,", args)})");
                throw;
            }
        }

        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["GodmodeDisabled"] = "You have <color=#FF4500>Disabled</color> godmode",
                ["GodmodeDisabledBy"] = "Your godmode has been <color=#FF4500>Disabled</color> by {0}",
                ["GodmodeDisabledFor"] = "You have <color=#FF4500>Disabled</color> godmode for {0}",
                ["GodmodeEnabled"] = "You have <color=#FF4500>Enabled</color> godmode",
                ["GodmodeEnabledBy"] = "Your godmode has been <color=#FF4500>Enabled</color> by {0}",
                ["GodmodeEnabledFor"] = "You have <color=#FF4500>Enabled</color> godmode for {0}",
                ["InformAttacker"] = "{0} is in godmode and can't take any damage",
                ["InformVictim"] = "{0} just tried to deal damage to you",
                ["CantAttack"] = "You are in godmode and can't attack {0}",
                ["NoGods"] = "No players currently have godmode enabled",
                ["NoLooting"] = "You are not allowed to loot a player with godmode",
                ["NotAllowed"] = "You are not allowed to use the '{0}' command",
                ["PlayerNotFound"] = "Player '{0}' was not found"
            }, this);
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["GodmodeDisabled"] = "Ai <color=#FF4500>dezactivat</color> godmode",
                ["GodmodeDisabledBy"] = "Godmode-ul tău a fost <color=#FF4500>dezactivat</color> de către {0}",
                ["GodmodeDisabledFor"] = "Ai <color=#FF4500>dezactivat</color> godmode pentru {0}",
                ["GodmodeEnabled"] = "Ai <color=#FF4500>activat</color> godmode",
                ["GodmodeEnabledBy"] = "Godmode-ul tău a fost <color=#FF4500>activat</color> de către {0}",
                ["GodmodeEnabledFor"] = "Ai <color=#FF4500>activat</color> godmode pentru {0}",
                ["InformAttacker"] = "{0} este în godmode și nu poate primi daune",
                ["InformVictim"] = "{0} a încercat să-ți provoace daune",
                ["CantAttack"] = "Ești în godmode și nu-l poți ataca pe {0}",
                ["NoGods"] = "Momentan nu există jucători cu godmode activat",
                ["NoLooting"] = "Nu ai permisiunea de a fura de la un jucător cu godmode",
                ["NotAllowed"] = "Nu ai permisiunea de a utiliza comanda '{0}'",
                ["PlayerNotFound"] = "Jucătorul '{0}' nu a fost găsit"
            }, this, "ro");
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["GodmodeDisabled"] = "您的上帝模式 <color=#FF4500>已禁用</color>",
                ["GodmodeDisabledBy"] = "{0} <color=#FF4500>禁用了</color> 您的上帝模式",
                ["GodmodeDisabledFor"] = "您 <color=#FF4500>禁用了</color> {0} 的上帝模式",
                ["GodmodeEnabled"] = "您的上帝模式 <color=#FF4500>已启用</color>",
                ["GodmodeEnabledBy"] = "{0} <color=#FF4500>启用了</color> 您的上帝模式",
                ["GodmodeEnabledFor"] = "您 <color=#FF4500>启用了</color> {0} 的上帝模式",
                ["InformAttacker"] = "{0} 处于上帝模式，您不能伤害他",
                ["InformVictim"] = "{0} 想伤害您",
                ["CantAttack"] = "您处于上帝模式，不能伤害 {0}",
                ["NoGods"] = "当前没有玩家启用上帝模式",
                ["NoLooting"] = "您不能掠夺处于上帝模式的玩家",
                ["NotAllowed"] = "您没有权限使用 '{0}' 命令",
                ["PlayerNotFound"] = "玩家 '{0}' 未找到"
            }, this, "zh-CN");
        }

        #endregion LanguageFile
    }
}