RaidAlarm - Failed to compile: 'Util' does not contain a definition for 'GetServerPairingData' | Line: 137, Pos: 100

RaidAlarm - Failed to compile: 'Util' does not contain a definition for 'GetServerPairingData' | Line: 137, Pos: 100

Here's something that can tie us over until haggbart can issue an update:

 

using System;
using System.Collections.Generic;
using Oxide.Core;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("Raid Alarm", "haggbart", "0.4.1")]
    [Description("Receive raid notifications through the official Rust companion mobile app")]
    internal class RaidAlarm : RustPlugin
    {
        #region init, data and cleanup

        private static HashSet<ulong> disabled = new HashSet<ulong>();
        private const string PERMISSION = "raidalarm.use";

        private void SaveData() => Interface.Oxide.DataFileSystem.WriteObject(Name, disabled);
        private void ReadData() => disabled = Interface.Oxide.DataFileSystem.ReadObject<HashSet<ulong>>(Name);

        private void Init()
        {
            config = Config.ReadObject<PluginConfig>();
            SaveConfig();
            permission.RegisterPermission(PERMISSION, this);
            ReadData();
        }

        private void OnServerSave() => SaveData();
        private void Unload() => SaveData();

        #endregion

        #region config

        private PluginConfig config;

        private class PluginConfig
        {
            public bool usePermissions;
        }

        protected override void LoadDefaultConfig() => Config.WriteObject(GetDefaultConfig(), true);
        private new void SaveConfig() => Config.WriteObject(config, true);

        private static PluginConfig GetDefaultConfig()
        {
            return new PluginConfig
            {
                usePermissions = false
            };
        }

        #endregion

        #region localization

        private static class Loc
        {
            public const string TITLE = "AlarmTitle";
            public const string BODY = "AlarmBody";
            public const string HELP = "AlarmHelp";
            public const string HELP_COMMANDS = "AlarmHelpCommands";
            public const string STATUS_ENABLED = "AlarmStatusEnabled";
            public const string STATUS_DISABLED = "AlarmStatusDisabled";
            public const string TEST_SENT = "AlarmTestSent";
            public const string TEST_DESTROYED = "AlarmTestDestroyedItem";
            public const string NO_PERMISSION = "NoPermission";
        }

        private string GetStatusText(BasePlayer player)
        {
            return lang.GetMessage(disabled.Contains(player.userID) ? Loc.STATUS_DISABLED : Loc.STATUS_ENABLED, this, player.UserIDString);
        }

        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                [Loc.TITLE] = "You're getting raided!",
                [Loc.BODY] = "{0} destroyed at {1}",
                [Loc.HELP] = "To receive Raid Alarm notifications, " +
                             "you need the official Rust+ companion app on your mobile device and pair it with this server. " +
                             "To do this, press Esc and click \"Rust+\" in the main menu.\n\n" +
                             "Use /raidalarm test to test your alarm. To disable, use /raidalarm disable.",
                [Loc.HELP_COMMANDS] = "Available commands:\n/raidalarm status|enable|disable|test",
                [Loc.STATUS_ENABLED] = "Raid Alarm is enabled.",
                [Loc.STATUS_DISABLED] = "Raid Alarm is disabled.",
                [Loc.TEST_SENT] = "Test notification sent. If you don't receive it, make sure you're paired with the server.",
                [Loc.TEST_DESTROYED] = "chair",
                [Loc.NO_PERMISSION] = "You don't have permission to use this command."
            }, this);
        }

        #endregion

        private readonly Dictionary<string, DateTime> raidblocked = new Dictionary<string, DateTime>();
        private DateTime lastAttack = DateTime.Now;

        private void OnEntityDeath(BaseCombatEntity entity, HitInfo info)
        {
            if (info == null) return;
            if (!IsRaidEntity(entity)) return;
            if (info.InitiatorPlayer == null) return;

            // prevent spam
            if ((DateTime.Now - lastAttack).TotalSeconds < 1) return;
            lastAttack = DateTime.Now;

            var buildingPrivilege = entity.GetBuildingPrivilege();
            if (buildingPrivilege == null || buildingPrivilege.authorizedPlayers.IsEmpty()) return;

            var victims = new List<ulong>();
            foreach (var victim in buildingPrivilege.authorizedPlayers)
            {
                if (victim == null) continue;
                if (config.usePermissions && !permission.UserHasPermission(victim.userid.ToString(), PERMISSION)) continue;
                if (victim.userid == info.InitiatorPlayer.userID) return;
                if (disabled.Contains(victim.userid)) continue;
                victims.Add(victim.userid);
            }

            string grid = GetGrid(entity.transform.position);
            raidblocked[grid] = lastAttack;

            foreach (var userId in victims)
            {
                // Sending a chat message using SendReply() for notifications
                var victimPlayer = BasePlayer.FindByID(userId);
                if (victimPlayer != null)
                {
                    SendReply(victimPlayer, lang.GetMessage(Loc.TITLE, this));
                    SendReply(victimPlayer, string.Format(lang.GetMessage(Loc.BODY, this), entity.ShortPrefabName, grid));
                }
            }
        }

        private static bool IsRaidEntity(BaseCombatEntity entity)
        {
            if (entity is Door) return true;
            if (entity is BuildingBlock block) return block.grade != BuildingGrade.Enum.Twigs;
            return false;
        }

        private static string GetGrid(Vector3 pos)
        {
            const float scale = 150f;
            float x = pos.x + World.Size / 2f;
            float z = pos.z + World.Size / 2f;
            int lat = Mathf.FloorToInt(x / scale);
            int lon = Mathf.FloorToInt((World.Size - z) / scale);
            char latChar = (char)('A' + lat);
            return $"{latChar}{lon}";
        }

        [ChatCommand("raidalarm")]
        private void ChatRaidAlarm(BasePlayer player, string command, string[] args)
        {
            if (config.usePermissions && !permission.UserHasPermission(player.UserIDString, PERMISSION))
            {
                SendReply(player, lang.GetMessage(Loc.NO_PERMISSION, this, player.UserIDString));
                return;
            }

            if (args.Length == 0)
            {
                SendReply(player, lang.GetMessage(Loc.HELP, this, player.UserIDString));
                return;
            }

            switch (args[0].ToLower())
            {
                case "status":
                    SendReply(player, GetStatusText(player));
                    break;
                case "enable":
                    disabled.Remove(player.userID);
                    SendReply(player, lang.GetMessage(Loc.STATUS_ENABLED, this, player.UserIDString));
                    break;
                case "disable":
                    disabled.Add(player.userID);
                    SendReply(player, lang.GetMessage(Loc.STATUS_DISABLED, this, player.UserIDString));
                    break;
                case "test":
                    if (disabled.Contains(player.userID))
                    {
                        SendReply(player, lang.GetMessage(Loc.STATUS_DISABLED, this, player.UserIDString));
                        return;
                    }

                    SendReply(player, lang.GetMessage(Loc.TEST_SENT, this, player.UserIDString));
                    var grid = GetGrid(player.transform.position);
                    SendReply(player, string.Format(lang.GetMessage(Loc.BODY, this, player.UserIDString),
                        lang.GetMessage(Loc.TEST_DESTROYED, this, player.UserIDString), grid));
                    break;
                default:
                    SendReply(player, lang.GetMessage(Loc.HELP_COMMANDS, this, player.UserIDString));
                    break;
            }
        }

        #region Dev API

        private bool IsRaidBlocked(BasePlayer player)
        {
            return raidblocked.TryGetValue(GetGrid(player.transform.position), out var last) &&
                   (DateTime.Now - last).TotalHours < 1;
        }

        #endregion
    }
}

Thanks for the quick community fix!

Super Danke 💯 😍

I managed to find the updated method. Its "TryGetServerParingData" instead of "GetServerPairingData". Just change that in line 137 and 199 and the plugin will work like it should :)

0QeMP2U5NCT9NrV.jpg stag

Here's something that can tie us over until haggbart can issue an update:

 

using System;
using System.Collections.Generic;
using Oxide.Core;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("Raid Alarm", "haggbart", "0.4.1")]
    [Description("Receive raid notifications through the official Rust companion mobile app")]
    internal class RaidAlarm : RustPlugin
    {
        #region init, data and cleanup

        private static HashSet<ulong> disabled = new HashSet<ulong>();
        private const string PERMISSION = "raidalarm.use";

        private void SaveData() => Interface.Oxide.DataFileSystem.WriteObject(Name, disabled);
        private void ReadData() => disabled = Interface.Oxide.DataFileSystem.ReadObject<HashSet<ulong>>(Name);

        private void Init()
        {
            config = Config.ReadObject<PluginConfig>();
            SaveConfig();
            permission.RegisterPermission(PERMISSION, this);
            ReadData();
        }

        private void OnServerSave() => SaveData();
        private void Unload() => SaveData();

        #endregion

        #region config

        private PluginConfig config;

        private class PluginConfig
        {
            public bool usePermissions;
        }

        protected override void LoadDefaultConfig() => Config.WriteObject(GetDefaultConfig(), true);
        private new void SaveConfig() => Config.WriteObject(config, true);

        private static PluginConfig GetDefaultConfig()
        {
            return new PluginConfig
            {
                usePermissions = false
            };
        }

        #endregion

        #region localization

        private static class Loc
        {
            public const string TITLE = "AlarmTitle";
            public const string BODY = "AlarmBody";
            public const string HELP = "AlarmHelp";
            public const string HELP_COMMANDS = "AlarmHelpCommands";
            public const string STATUS_ENABLED = "AlarmStatusEnabled";
            public const string STATUS_DISABLED = "AlarmStatusDisabled";
            public const string TEST_SENT = "AlarmTestSent";
            public const string TEST_DESTROYED = "AlarmTestDestroyedItem";
            public const string NO_PERMISSION = "NoPermission";
        }

        private string GetStatusText(BasePlayer player)
        {
            return lang.GetMessage(disabled.Contains(player.userID) ? Loc.STATUS_DISABLED : Loc.STATUS_ENABLED, this, player.UserIDString);
        }

        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                [Loc.TITLE] = "You're getting raided!",
                [Loc.BODY] = "{0} destroyed at {1}",
                [Loc.HELP] = "To receive Raid Alarm notifications, " +
                             "you need the official Rust+ companion app on your mobile device and pair it with this server. " +
                             "To do this, press Esc and click \"Rust+\" in the main menu.\n\n" +
                             "Use /raidalarm test to test your alarm. To disable, use /raidalarm disable.",
                [Loc.HELP_COMMANDS] = "Available commands:\n/raidalarm status|enable|disable|test",
                [Loc.STATUS_ENABLED] = "Raid Alarm is enabled.",
                [Loc.STATUS_DISABLED] = "Raid Alarm is disabled.",
                [Loc.TEST_SENT] = "Test notification sent. If you don't receive it, make sure you're paired with the server.",
                [Loc.TEST_DESTROYED] = "chair",
                [Loc.NO_PERMISSION] = "You don't have permission to use this command."
            }, this);
        }

        #endregion

        private readonly Dictionary<string, DateTime> raidblocked = new Dictionary<string, DateTime>();
        private DateTime lastAttack = DateTime.Now;

        private void OnEntityDeath(BaseCombatEntity entity, HitInfo info)
        {
            if (info == null) return;
            if (!IsRaidEntity(entity)) return;
            if (info.InitiatorPlayer == null) return;

            // prevent spam
            if ((DateTime.Now - lastAttack).TotalSeconds < 1) return;
            lastAttack = DateTime.Now;

            var buildingPrivilege = entity.GetBuildingPrivilege();
            if (buildingPrivilege == null || buildingPrivilege.authorizedPlayers.IsEmpty()) return;

            var victims = new List<ulong>();
            foreach (var victim in buildingPrivilege.authorizedPlayers)
            {
                if (victim == null) continue;
                if (config.usePermissions && !permission.UserHasPermission(victim.userid.ToString(), PERMISSION)) continue;
                if (victim.userid == info.InitiatorPlayer.userID) return;
                if (disabled.Contains(victim.userid)) continue;
                victims.Add(victim.userid);
            }

            string grid = GetGrid(entity.transform.position);
            raidblocked[grid] = lastAttack;

            foreach (var userId in victims)
            {
                // Sending a chat message using SendReply() for notifications
                var victimPlayer = BasePlayer.FindByID(userId);
                if (victimPlayer != null)
                {
                    SendReply(victimPlayer, lang.GetMessage(Loc.TITLE, this));
                    SendReply(victimPlayer, string.Format(lang.GetMessage(Loc.BODY, this), entity.ShortPrefabName, grid));
                }
            }
        }

        private static bool IsRaidEntity(BaseCombatEntity entity)
        {
            if (entity is Door) return true;
            if (entity is BuildingBlock block) return block.grade != BuildingGrade.Enum.Twigs;
            return false;
        }

        private static string GetGrid(Vector3 pos)
        {
            const float scale = 150f;
            float x = pos.x + World.Size / 2f;
            float z = pos.z + World.Size / 2f;
            int lat = Mathf.FloorToInt(x / scale);
            int lon = Mathf.FloorToInt((World.Size - z) / scale);
            char latChar = (char)('A' + lat);
            return $"{latChar}{lon}";
        }

        [ChatCommand("raidalarm")]
        private void ChatRaidAlarm(BasePlayer player, string command, string[] args)
        {
            if (config.usePermissions && !permission.UserHasPermission(player.UserIDString, PERMISSION))
            {
                SendReply(player, lang.GetMessage(Loc.NO_PERMISSION, this, player.UserIDString));
                return;
            }

            if (args.Length == 0)
            {
                SendReply(player, lang.GetMessage(Loc.HELP, this, player.UserIDString));
                return;
            }

            switch (args[0].ToLower())
            {
                case "status":
                    SendReply(player, GetStatusText(player));
                    break;
                case "enable":
                    disabled.Remove(player.userID);
                    SendReply(player, lang.GetMessage(Loc.STATUS_ENABLED, this, player.UserIDString));
                    break;
                case "disable":
                    disabled.Add(player.userID);
                    SendReply(player, lang.GetMessage(Loc.STATUS_DISABLED, this, player.UserIDString));
                    break;
                case "test":
                    if (disabled.Contains(player.userID))
                    {
                        SendReply(player, lang.GetMessage(Loc.STATUS_DISABLED, this, player.UserIDString));
                        return;
                    }

                    SendReply(player, lang.GetMessage(Loc.TEST_SENT, this, player.UserIDString));
                    var grid = GetGrid(player.transform.position);
                    SendReply(player, string.Format(lang.GetMessage(Loc.BODY, this, player.UserIDString),
                        lang.GetMessage(Loc.TEST_DESTROYED, this, player.UserIDString), grid));
                    break;
                default:
                    SendReply(player, lang.GetMessage(Loc.HELP_COMMANDS, this, player.UserIDString));
                    break;
            }
        }

        #region Dev API

        private bool IsRaidBlocked(BasePlayer player)
        {
            return raidblocked.TryGetValue(GetGrid(player.transform.position), out var last) &&
                   (DateTime.Now - last).TotalHours < 1;
        }

        #endregion
    }
}

What's the difference between the updated method you found and the 1st fix by stag? His fix also compiled for me so I'm unsure if that's all working good.

jKWssub1E2CYWyI.jpg Flammable

What's the difference between the updated method you found and the 1st fix by stag? His fix also compiled for me so I'm unsure if that's all working good.

His fix was just removing the method entirely that threw the error xD
Facepunch changed the name of that method and I found the updated name and replaced it. If you keep the version where the method is removed, im pretty sure it would stop the notifications from beeing sent to the app.

Thanks you!

Just to double check. I've swapped both lines with `TryGetServerPairingData` but still have a compile error come up.
Error while compiling RaidAlarm: 'Util' does not contain a definition for 'TryGetServerParingData' | Line: 137, Pos: 100
does Util. also need to we swapped?

WfaEWm1kCU3gBVx.png MrScrubby

I managed to find the updated method. Its "TryGetServerParingData" instead of "GetServerPairingData". Just change that in line 137 and 199 and the plugin will work like it should :)

Rustychops

Just to double check. I've swapped both lines with `TryGetServerPairingData` but still have a compile error come up.
Error while compiling RaidAlarm: 'Util' does not contain a definition for 'TryGetServerParingData' | Line: 137, Pos: 100
does Util. also need to we swapped?

You've got a typo - pairing not paring. 

Util.TryGetServerPairingData()

So the plugin doesnt work due to this typo again?

Ah thank you. My bad, not sure if that was a me mistake or i copied it somewhere. Working now.

roben

You've got a typo - pairing not paring. 

Util.TryGetServerPairingData()
jYrQnooX9uz8I86.jpg Flammable

So the plugin doesnt work due to this typo again?

It does work, I just had a typo in my answer like roben mentioned. 

Am I stupid or there's no GetServerPairingData or TryGetServerPairingData()​ in the code shared here. I'm searching but nothing. Can someone paste the updated file here. I tried to search stag's code for GetServerPairingData in order to replace it but nothing.

Merged post

My bad, I downloaded the original plugin file and I can replace these now. I was trying to work with the stag code where he just removed the lines...

Thank you

 

p1CxkjJfrlsU4k3.png MrScrubby

I managed to find the updated method. Its "TryGetServerParingData" instead of "GetServerPairingData". Just change that in line 137 and 199 and the plugin will work like it should :)