public static bool RestrictionCheckNone(Character __instance, string restriction)
        {
            Character p = __instance;

            // Are we in a zone? if so select that zone.
            if (ZoneHandler.Zones.Count() == 0)
            {
                return(false);
            }
            ZoneHandler.Zone        z     = new ZoneHandler.Zone();
            ZoneHandler.ZoneTypes   zt    = new ZoneHandler.ZoneTypes();
            List <ZoneHandler.Zone> zlist = ZoneHandler.ListOccupiedZones(p.transform.position);

            if (zlist.Count == 0)
            {
                zt = ZoneHandler.FindZoneType("wilderness");
            }
            else
            {
                z  = ZoneHandler.TopZone(zlist);
                zt = ZoneHandler.FindZoneType(z.Type);
            }
            string key = "";

            // Lets set our admin list and keys...
            key = zt.Configurations;
            if (key.ToLower().Contains(restriction))
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
예제 #2
0
        private static void ZNet__SendPeerInfo(ZNet __instance, ZRpc rpc)
        {
            // Run away clients, we don't want you here!?!?ZoneHandler.Serialize
            if (!__instance.IsServer())
            {
                return;
            }

            // Syncing Zone Handler Settings.
#if DEBUG
            Debug.Log("S2C ZoneHandler (SendPeerInfo)");
            ZoneHandler._debug();
#endif
            Game.instance.StartCoroutine(Util.ZoneHandler2(rpc));
            // Syncing the Client State with the server defaults.
#if DEBUG
            Debug.Log("S2C ClientState (SendPeerInfo)");
            Client._debug();
#endif
            Game.instance.StartCoroutine(Util.Client2(rpc));
            Util.Connections.Add(new Util.ConnectionData
            {
                rpc = rpc
            });
        }
 public static IEnumerator ZoneHandler2(ZRpc rpc)
 {
     rpc.Invoke("ZoneHandler", new object[] {
         ZoneHandler.Serialize(rpc.GetSocket().GetHostName())
     });
     yield return(new WaitForSeconds(1));
 }
예제 #4
0
 private static void OnChangedZONE(object sender, FileSystemEventArgs e)
 {
     if (e.ChangeType != WatcherChangeTypes.Changed)
     {
         return;
     }
     Debug.Log("ZONES FILE CHANGED!");
     ZoneHandler.LoadZoneData(WorldofValheimZones.ZonePath.Value);
     Util.Broadcast("Reloading Zone");
     Game.instance.StartCoroutine(Util.SendAllUpdate());
 }
        public static float RestrictionCheckFloatReturnCharacter(Character __instance, string restriction)
        {
            Character p = __instance;
            string    CharacterSteamID = (ZNet.instance.GetPeer(__instance.GetZDOID().m_userID)).m_socket.GetHostName();

            // Are we in a zone? if so select that zone.
            ZoneHandler.Zone        z     = new ZoneHandler.Zone();
            ZoneHandler.ZoneTypes   zt    = new ZoneHandler.ZoneTypes();
            List <ZoneHandler.Zone> zlist = ZoneHandler.ListOccupiedZones(p.transform.position);

            if (zlist.Count == 0)
            {
                zt = ZoneHandler.FindZoneType("wilderness");
            }
            else
            {
                z  = ZoneHandler.TopZone(zlist);
                zt = ZoneHandler.FindZoneType(z.Type);
            }
            string key    = "";
            string admins = "";

            // Lets set our admins and keys..
            admins = zt.Admins;
            key    = zt.Configurations;
            // Lets see if the user is actually an admin in the zone first..
            if (admins.Contains(CharacterSteamID))
            {
                // Ok they are an admin. Therefore, do not initialize the change...
                return(1);
            }
            if (key.ToLower().Contains(restriction))
            {
                string s = key.ToLower();
                string restrictioncheck = restriction + "(";
                int    indexStart       = s.IndexOf(restrictioncheck) + restrictioncheck.Length;
                string test             = "";
                for (int i = indexStart; i < indexStart + 20; i++)
                {
                    if (s[i] == ')')
                    {
                        break;
                    }
                    test += s[i];
                }
                float multiplier = 1;
                multiplier = Convert.ToSingle(test, new CultureInfo("en-US"));
                return(multiplier);
            }
            else
            {
                return(1);
            }
        }
 public static IEnumerator SendAllUpdate()
 {
     foreach (var p in ZNet.instance.m_peers)
     {
         string SteamID = p.m_socket.GetHostName();
         ZRoutedRpc.instance.InvokeRoutedRPC(p.m_uid, "ZoneHandler", new object[] {
             ZoneHandler.Serialize(SteamID)
         });
     }
     yield return(new WaitForSeconds(1));
 }
        public static bool RestrictionCheckCharacter(Character __instance, string restriction)
        {
            Character p = __instance;
            string    CharacterSteamID = (ZNet.instance.GetPeer(__instance.GetZDOID().m_userID)).m_socket.GetHostName();

            // Are we in a zone? if so select that zone.
            if (ZoneHandler.Zones.Count() == 0)
            {
                return(false);
            }
            ZoneHandler.Zone        z     = new ZoneHandler.Zone();
            ZoneHandler.ZoneTypes   zt    = new ZoneHandler.ZoneTypes();
            List <ZoneHandler.Zone> zlist = ZoneHandler.ListOccupiedZones(p.transform.position);

            if (zlist.Count == 0)
            {
                zt = ZoneHandler.FindZoneType("wilderness");
            }
            else
            {
                z  = ZoneHandler.TopZone(zlist);
                zt = ZoneHandler.FindZoneType(z.Type);
            }
            string key    = "";
            string admins = "";

            // Lets set our admin list and keys...
            admins = zt.Admins;
            key    = zt.Configurations;
            // Lets check and see if the user is actually an admin in the zone.
            if (admins.Contains(CharacterSteamID))
            {
                return(false);
            }
            if (key.ToLower().Contains(restriction))
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
        public static bool RestrictionCheck(string restriction)
        {
            Player p = Player.m_localPlayer;

            // Are we in a zone? if so select that zone.
            if (ZoneHandler.Zones.Count() == 0)
            {
                return(false);
            }
            ZoneHandler.Zone        z     = new ZoneHandler.Zone();
            ZoneHandler.ZoneTypes   zt    = new ZoneHandler.ZoneTypes();
            List <ZoneHandler.Zone> zlist = ZoneHandler.ListOccupiedZones(p.transform.position);

            if (zlist.Count == 0)
            {
                zt = ZoneHandler.FindZoneType("wilderness");
            }
            else
            {
                z  = ZoneHandler.TopZone(zlist);
                zt = ZoneHandler.FindZoneType(z.Type);
            }
            string key    = "";
            string admins = "";

            // Lets set our admin list and keys...
            admins = zt.Admins;
            key    = zt.Configurations;
            // Lets check and see if the user is actually an admin in the zone.
            if (admins.Contains(WorldofValheimZones.MySteamID))
            {
                return(false);
            }
            if (key.ToLower().Contains(restriction))
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
        public static void ReloadZones(long sender, ZPackage pkg)
        {
            ZNetPeer peer = ZNet.instance.GetPeer(sender);

            if (peer != null)
            {
                string permissionnode   = "HackShardGaming.WoV-Zones.Reload";
                string peerSteamID      = ((ZSteamSocket)peer.m_socket).GetPeerID().m_SteamID.ToString(); // Get the SteamID from peer.
                bool   PlayerPermission = ValheimPermissions.ValheimDB.CheckUserPermission(peerSteamID, permissionnode);
                if (PlayerPermission)
                {
                    ZoneHandler.LoadZoneData(WorldofValheimZones.ZonePath.Value);
                    Util.Broadcast("Reloading Zone");
                    Debug.Log("S2C ZoneHandler (SendPeerInfo)");
                    Game.instance.StartCoroutine(Util.SendAllUpdate());
                }
                else
                {
                    RoutedBroadcast(sender, $"Sorry! You do not have the permission to use !ReloadZones (Required Permission: {permissionnode})");
                }
            }
        }
예제 #10
0
        private static void Game__Update()
        {
            if (Player.m_localPlayer)
            {
                //
                // Goes through the zones and setup the necessary enforcements.

                ZoneHandler.Zone      zone;
                ZoneHandler.ZoneTypes ztype;
                string Message = "";
                bool   changed;
                bool   zonedDetected = ZoneHandler.Detect(Player.m_localPlayer.transform.position, out changed, out zone, out ztype);
                if (changed)
                {
                    if (zonedDetected)
                    {
                        var    color = (ztype.PVPEnforce ? (ztype.PVP ? WorldofValheimZones.PVPColor.Value : WorldofValheimZones.PVEColor.Value) : WorldofValheimZones.NonEnforcedColor.Value);
                        string Name  = zone.Name.Replace("_", " ");
                        Message = $"<color={color}>Now entering <b>{Name}</b>.</color>";
                        string BiomeMessage = (ztype.PVPEnforce ? ztype.PVP ? "PVP Enabled" : "PVP Disabled" : String.Empty);
                        // The message at the end is in the format of (PVP) (NOPVP) (NON-ENFORCED)
                        Player.m_localPlayer.Message(MessageHud.MessageType.Center, Message,
                                                     0, null);
                        if (Client.EnforceZones && ztype.PVPEnforce && ztype.PVP != Player.m_localPlayer.m_pvp && WorldofValheimZones.BiomePVPAnnouncement.Value)
                        {
                            MessageHud.instance.ShowBiomeFoundMsg(BiomeMessage, true);
                        }
                    }
                    else
                    {
                        var    color = (ztype.PVPEnforce ? (ztype.PVP ? WorldofValheimZones.PVPColor.Value : WorldofValheimZones.PVEColor.Value) : WorldofValheimZones.NonEnforcedColor.Value);
                        string Name  = "The Wilderness";
                        Message = $"<color={color}>Now entering <b>{Name}</b>.</color>";
                        string BiomeMessage = (ztype.PVPEnforce ? ztype.PVP ? "PVP Enabled" : "PVP Disabled" : String.Empty);
                        // The message at the end is in the format of (PVP) (NOPVP) (NON-ENFORCED)

                        if (Client.EnforceZones && ztype.PVPEnforce && ztype.PVP != Player.m_localPlayer.m_pvp && WorldofValheimZones.BiomePVPAnnouncement.Value)
                        {
                            MessageHud.instance.ShowBiomeFoundMsg(BiomeMessage, true);
                        }
                    }
                    // Zones are now being enforced?
                    if (Client.EnforceZones)
                    {
                        // Update the client settings based on zone type
                        // PVP settings:
                        Client.PVPEnforced = ztype.PVPEnforce;
                        if (ztype.PVPEnforce)
                        {
                            Client.PVPMode = ztype.PVP;
                        }
                        // Position settings:
                        Client.PositionEnforce = ztype.PositionEnforce;
                        if (ztype.PositionEnforce)
                        {
                            Client.ShowPosition = ztype.ShowPosition;
                        }
                        // Run the updated settings for the Clients
                        Player.m_localPlayer.SetPVP(Client.PVPMode);
                        InventoryGui.instance.m_pvp.isOn         = Client.PVPMode;
                        InventoryGui.instance.m_pvp.interactable = !Client.PVPEnforced;
                        ZNet.instance.SetPublicReferencePosition(Client.ShowPosition);
                        Util.InsertChatMessage(Message);
                        Player.m_localPlayer.Message(MessageHud.MessageType.Center, Message,
                                                     0, null);
                        // Other settings are scattered among the wind to other functions
                        // (Use Client class for the current state)
                    }
#if DEBUG
                    ZoneHandler._debug(ztype);
                    Client._debug();
#endif
                }
                else
                {
                    if (Client.PVPEnforced && (Player.m_localPlayer.m_pvp != Client.PVPMode))
                    {
                        Debug.Log($"{ModInfo.Title}: ERROR: Your PVP Mode was changed by another plugin.  Resetting client PVP!");
                        Player.m_localPlayer.SetPVP(Client.PVPMode);
                    }
                    if (Client.PositionEnforce && (ZNet.instance.m_publicReferencePosition != Client.ShowPosition))
                    {
                        Debug.Log($"{ModInfo.Title}: ERROR: Your Position Sharing was changed by another plugin.  Resetting client Position Sharing!");
                        ZNet.instance.SetPublicReferencePosition(Client.ShowPosition);
                    }
                }
            }
        }
예제 #11
0
        public void Awake()
        {
            string ConfigPath    = Path.Combine(BepInEx.Paths.ConfigPath, "WoV");
            string ZonesLocation = Path.Combine(ConfigPath, "Zones.txt");
            string ZoneConfiguration_Location = Path.Combine(ConfigPath, "Zone_Configuration.txt");

            plugin = this;
            bool SERVER = Paths.ProcessName.Equals("valheim_server", StringComparison.OrdinalIgnoreCase) ? true : false;

            WorldofValheimZones.NexusID = base.Config.Bind <int>("WorldofValheimZones", "NexusID", ModInfo.NexusID, "Nexus ID to make Nexus Update Happy!");
            Client.EnforceZones         = true;
            if (SERVER)
            {
                Debug.Log("[Server Mode]");
                WorldofValheimZones.ReloadDetection       = base.Config.Bind <bool>("Config", "ReloadDetection", false, "SERVER ONLY: Should the server auto reload if the config file is changed? (May cause DeSync)");
                WorldofValheimZones.NoItemLoss            = base.Config.Bind <bool>("Death", "NoItemLoss", false, "SERVER ONLY: Should we prevent a user from losing items/skills on death globally?");
                WorldofValheimZones.RespawnTimer          = base.Config.Bind <Single>("Death", "RespawnTimer", 10, "SERVER ONLY: How fast should the clients respawn?");
                WorldofValheimZones.ZonePath              = base.Config.Bind <string>("WorldofValheimZones", "ZonePath", ZonesLocation, "SERVER ONLY: The file path to the zone file. If it does not exist, it will be created with a default zone.");
                WorldofValheimZones.WardProtectDamage     = base.Config.Bind <bool>("Ward", "Building_ProtectDamage", false, "SERVER ONLY: Protect buildings from being damaged inside Warded Areas?");
                WorldofValheimZones.WardProtectItemPickup = base.Config.Bind <bool>("Ward", "Item_Pickup", false, "SERVER ONLY: Protect Picking up items in Warded Areas?");
                WorldofValheimZones.WardProtectItemDrop   = base.Config.Bind <bool>("Ward", "Item_Drop", false, "SERVER ONLY: Protect Dropping items in Warded Areas?");
                Client.Ward.Damage  = WorldofValheimZones.WardProtectDamage.Value;
                Client.Ward.Pickup  = WorldofValheimZones.WardProtectItemPickup.Value;
                Client.Ward.Drop    = WorldofValheimZones.WardProtectItemDrop.Value;
                Client.NoItemLoss   = WorldofValheimZones.NoItemLoss.Value;
                Client.RespawnTimer = WorldofValheimZones.RespawnTimer.Value;
                // Check if the Zones file and folder exist
                string pathwithoutfile2 = Path.GetDirectoryName(WorldofValheimZones.ZonePath.Value);
                if (!Directory.Exists(pathwithoutfile2))
                {
                    Directory.CreateDirectory(Path.GetDirectoryName(WorldofValheimZones.ZonePath.Value));
                }
                Debug.Log(Path.GetDirectoryName(WorldofValheimZones.ZonePath.Value));
                if (!File.Exists(WorldofValheimZones.ZonePath.Value))
                {
                    Debug.Log($"Creating Zones file at {WorldofValheimZones.ZonePath.Value}");
                    string text = global::WorldofValheimZones.Properties.Resources.Default_zones;
                    File.WriteAllText(WorldofValheimZones.ZonePath.Value, text);
                }
                if (WorldofValheimZones.ReloadDetection.Value)
                {
                    zonewatcher = new FileSystemWatcher(Path.GetDirectoryName(WorldofValheimZones.ZonePath.Value));
                    Debug.Log("STARTED WATCHER AT " + Path.GetDirectoryName(WorldofValheimZones.ZonePath.Value));
                    zonewatcher.Changed            += OnChangedZONE;
                    zonewatcher.Filter              = Path.GetFileName(WorldofValheimZones.ZonePath.Value);
                    zonewatcher.EnableRaisingEvents = true;
                }
                ZoneHandler.LoadZoneData(WorldofValheimZones.ZonePath.Value);
            }
            else
            {
                Debug.Log("[Client Mode]");
                WorldofValheimZones.BiomePVPAnnouncement = base.Config.Bind <bool>("Biome", "BiomePVPAnnouncement", true, "Should we announce changing PVP in a Biome Announcement? true or false");
                WorldofValheimZones.PVPColor             = base.Config.Bind <string>("Colors", "PVPColor", "Red", "What color should our 'Now Entering' message be if the zone type has PVP on");
                WorldofValheimZones.PVEColor             = base.Config.Bind <string>("Colors", "PVEColor", "White", "What color should our 'Now Entering' message be if the zone type has PVE off");
                WorldofValheimZones.NonEnforcedColor     = base.Config.Bind <string>("Colors", "NonEnforcedColor", "Yellow", "What color should our 'Now Entering' message be if the zone type has No PVP Enforcement");
            }
            Debug.Log("Haz awoke!!?!");
#if DEBUG
            Debug.Log("Development Version Activated!!!");
            Debug.Log("Warning: This may break your game (90% stable)");
            Debug.Log("***Do Not Release To Public***");
#endif
            // Run the grand patch all and hope everything works (This is fine...)
            new Harmony(ModInfo.Guid).PatchAll();
        }
예제 #12
0
        // WorldofValheimZones.ServerSafeZonePath.Value
        public static void LoadZoneData(string ZonePath)
        {
            Debug.Log($"Loading zone file: {ZonePath}");
            // Clean up the old zone data
            ZoneT.Clear();
            Zones.Clear();
            int pos = 0;

            foreach (string text2 in File.ReadAllLines(ZonePath))
            {
                if (!string.IsNullOrWhiteSpace(text2) && text2[0] != '#')
                {
                    string[] array2 = text2.Split(' ');
                    // Check if it is a type
                    if (array2[0].ToLower() == "type:")
                    {
                        Debug.Log($"Loading Type: {array2[1]}");
                        ZoneTypes zt = new ZoneTypes {
                            Name = array2[1]
                        };

                        // Go through each argument to override defaults.

                        if (array2.Length >= 3)
                        {
                            zt.PVP = bool.Parse(array2[2]);
                        }

                        if (array2.Length >= 4)
                        {
                            zt.PVPEnforce = bool.Parse(array2[3]);
                        }

                        if (array2.Length >= 5)
                        {
                            zt.ShowPosition = bool.Parse(array2[4]);
                        }

                        if (array2.Length >= 6)
                        {
                            zt.PositionEnforce = bool.Parse(array2[5]);
                        }

                        ZoneT.Add(zt);
                    }
                    else if (array2[0].ToLower() == "configuration:")
                    {
                        string   texttosend      = text2.Replace(": ", "|");
                        string[] array           = texttosend.Replace(" | ", "|").Split('|');
                        ZoneHandler.ZoneTypes zt = ZoneHandler.FindZoneType(array[1]);
                        if (zt.Name.ToLower() != array[1].ToString().ToLower())
                        {
                            Debug.Log($"ERROR: While applying custom configuration for the Zone Type: {array[1]},");
                            Debug.Log($"Zone Type: {array[1]} Does not exist in the {WorldofValheimZones.ZonePath.Value} file!");
                            return;
                        }
                        else
                        {
                            Debug.Log($"Loading Custom Configuration for the Zone Type: {array[1]} with an Overridable Permission Node of: 'HackShardGaming.WoV-Zones.Override.{array[1]}'");
                            zt.Admins         = array[2];
                            zt.Configurations = array[3];
                        }
                    }
                    else
                    {
                        if (array2.Length != 7)
                        {
                            Debug.Log($"Zone {text2} is not correctly formated!");
                        }
                        else
                        {
                            Debug.Log($"Loading Zone: {array2[0]}");
                            Zone z = new Zone();
                            z.Name     = array2[0];
                            z.Type     = array2[1];
                            z.Priority = int.Parse(array2[2]);
                            z.Shape    = array2[3];
                            Vector2     posi = new Vector3();
                            CultureInfo info = new CultureInfo("en-US");
                            z.Position = new Vector2(Convert.ToSingle(array2[4], info), Convert.ToSingle(array2[5], info));
                            z.Radius   = Convert.ToSingle(array2[6], info);
                            //z.pvp = bool.Parse(array2[7]);
                            z.ID = pos;
                            Zones.Add(z);
                            pos++;
                        }
                    }
                }
            }
#if DEBUG
            _debug();
#endif
        }
        /// <summary>
        /// FixedUpdate<> Patch
        /// Includes the following:
        ///     PushAway (Do not enter zone)
        ///     PeriodicDamage
        ///     PeriodicHeal
        ///     Last Updated: 4/24/2021
        ///     Status: 100% Working
        /// </summary>
        public static void FixedUpdatez()
        {
            if (WorldofValheimZones.EffectTick > 0)
            {
                WorldofValheimZones.EffectTick--;
            }
            if (WorldofValheimZones.HealTick > 0)
            {
                WorldofValheimZones.HealTick--;
            }
            if (WorldofValheimZones.DamageTick > 0)
            {
                WorldofValheimZones.DamageTick--;
            }
            Player p = Player.m_localPlayer;

            if (p != null)
            {
                // Are we in a zone? if so select that zone.
                ZoneHandler.Zone        z     = new ZoneHandler.Zone();
                ZoneHandler.ZoneTypes   zt    = new ZoneHandler.ZoneTypes();
                List <ZoneHandler.Zone> zlist = ZoneHandler.ListOccupiedZones(p.transform.position);
                if (zlist.Count == 0)
                {
                    zt = ZoneHandler.FindZoneType("wilderness");
                }
                else
                {
                    z  = ZoneHandler.TopZone(zlist);
                    zt = ZoneHandler.FindZoneType(z.Type);
                }
                // Lets set our strings...
                string admins = zt.Admins;
                string key    = zt.Configurations;
                // Lets see if the user is considered a Zone Admin!
                if (admins.Contains(WorldofValheimZones.MySteamID))
                {
                    return;
                }
                // Keep player out of an area.
                if (key.ToLower().Contains("pushaway"))
                {
                    Vector3 zposition  = new Vector3(z.Position.x, p.transform.position.y, z.Position.y);
                    Vector3 newVector3 = p.transform.position +
                                         (p.transform.position - zposition).normalized * 0.15f;
                    p.transform.position = new Vector3(newVector3.x, p.transform.position.y, newVector3.z);
                }
                // Deal damage to the player while they are in the area.
                if (key.ToLower().Contains("periodicdamage") && WorldofValheimZones.DamageTick <= 0)
                {
                    WorldofValheimZones.DamageTick = 100;
                    string s          = key.ToLower();
                    int    indexStart = s.IndexOf("periodicdamage(") + "periodicdamage(".Length;
                    string test       = "";
                    for (int i = indexStart; i < indexStart + 30; i++)
                    {
                        if (s[i] == ')')
                        {
                            break;
                        }
                        test += s[i];
                    }
                    int      damage = 0;
                    HitData  hit    = new HitData();
                    string[] array  = test.Split(',');
                    if (array.Count() == 2)
                    {
                        int.TryParse(array[1], out damage);
                        if (array[0].ToLower() == "fire")
                        {
                            hit.m_damage.m_fire = (float)damage;
                        }
                        else if (array[0].ToLower() == "frost")
                        {
                            hit.m_damage.m_frost = (float)damage;
                        }
                        else if (array[0].ToLower() == "poison")
                        {
                            hit.m_damage.m_poison = (float)damage;
                        }
                        else if (array[0].ToLower() == "lightning")
                        {
                            hit.m_damage.m_lightning = (float)damage;
                        }
                        else if (array[0].ToLower() == "pierce")
                        {
                            hit.m_damage.m_pierce = (float)damage;
                        }
                        else if (array[0].ToLower() == "blunt")
                        {
                            hit.m_damage.m_blunt = (float)damage;
                        }
                        else if (array[0].ToLower() == "slash")
                        {
                            hit.m_damage.m_slash = (float)damage;
                        }
                        else if (array[0].ToLower() == "damage")
                        {
                            hit.m_damage.m_damage = (float)damage;
                        }
                        else
                        {
                            hit.m_damage.m_fire = (float)damage;
                        }
                    }
                    else
                    {
                        int.TryParse(test, out damage);
                        hit.m_damage.m_fire = (float)damage;
                    }
                    p.Damage(hit);
                }
                // Heal the player while they are in the area
                if (key.ToLower().Contains("periodicheal") && WorldofValheimZones.HealTick <= 0)
                {
                    WorldofValheimZones.HealTick = 50;
                    string s          = key.ToLower();
                    int    indexStart = s.IndexOf("periodicheal(") + "periodicheal(".Length;
                    string test       = "";
                    for (int i = indexStart; i < indexStart + 20; i++)
                    {
                        if (s[i] == ')')
                        {
                            break;
                        }
                        test += s[i];
                    }
                    int damage = 0;
                    int.TryParse(test, out damage);
                    p.Heal(damage, true);
                }
            }
        }
 public static void AddZone(long sender, ZPackage pkg)
 {
     if (pkg != null && pkg.Size() > 0)
     {                                                                                                 // Check that our Package is not null, and if it isn't check that it isn't empty.
         ZNetPeer peer = ZNet.instance.GetPeer(sender);                                                // Get the Peer from the sender, to later check the SteamID against our Adminlist.
         if (peer != null)
         {                                                                                             // Confirm the peer exists
             string permissionnode   = "HackShardGaming.WoV-Zones.Add";
             string peerSteamID      = ((ZSteamSocket)peer.m_socket).GetPeerID().m_SteamID.ToString(); // Get the SteamID from peer.
             bool   PlayerPermission = ValheimPermissions.ValheimDB.CheckUserPermission(peerSteamID, permissionnode);
             if (PlayerPermission)
             {
                 string   msg     = pkg.ReadString();
                 string[] results = msg.Split(' ');
                 string   Name    = results[0];
                 Debug.Log($"C-<S AddZone (RPC Call)");
                 string Type = results[1];
                 ZoneHandler.ZoneTypes zt = ZoneHandler.FindZoneType(results[1]);
                 if (zt.Name != Type)
                 {
                     msg = $"ERROR: The requested Zone Type {Type} does not exist!";
                     Util.RoutedBroadcast(sender, msg);
                     return;
                 }
                 int Priority = Int32.Parse(results[2]);
                 if (Priority < 1 || Priority > 5)
                 {
                     msg = $"ERROR: The requested Priority {Priority} is out of bounds! (Priorities are ranged from 1-5)!";
                     Util.RoutedBroadcast(sender, msg);
                     return;
                 }
                 string Shape = results[3];
                 if (Shape.ToLower() != "circle" && Shape.ToLower() != "square")
                 {
                     msg = $"ERROR: The requested Shape: {Shape} is incorrectly formated! (Shapes can either be circle or square only)";
                     Util.RoutedBroadcast(sender, msg);
                     return;
                 }
                 Single i = new float();
                 string X = results[4];
                 if (!Single.TryParse(X, out i))
                 {
                     msg = $"ERROR: The requested X {X} is incorrectly formated! (Correct Format is 0.0)!";
                     Util.RoutedBroadcast(sender, msg);
                     return;
                 }
                 string Y = results[5];
                 if (!Single.TryParse(Y, out i))
                 {
                     msg = $"ERROR: The requested Y {Y} is incorrectly formated! (Correct Format is 0.0)!";
                     Util.RoutedBroadcast(sender, msg);
                     return;
                 }
                 string R = results[6];
                 if (!Single.TryParse(R, out i))
                 {
                     msg = $"ERROR: The requested Radius {R} is incorrectly formated! (Correct Format is 0.0)!";
                     Util.RoutedBroadcast(sender, msg);
                     return;
                 }
                 string addline = Name + " " + Type + " " + Priority + " " + Shape + " " + X + " " + Y + " " + R;
                 File.AppendAllText(WorldofValheimZones.ZonePath.Value, addline + Environment.NewLine);
             }
             else
             {
                 Util.RoutedBroadcast(sender, $"Sorry! You do not have the permission to use !AddZone (Required Permission: {permissionnode})");
                 Debug.Log($"An unauthorized user {peerSteamID} attempted to use the AddZone RPC!");
                 string msg = pkg.ReadString();
                 Debug.Log($"Here is a log of the attempted AddZone {msg}");
             }
         }
     }
 }