Lookin for a windows Internet check

I’m building a small app to use offline with my business so i can cut back on paperwork. would like to be able to sent data to a server and then be able to print a hard copy of that data once processed and broken down.
_
I’m looking for a simple check solution for internet connectivity. it will be for windows only and is used to change the color of an image and wheather to store data or send it once. i think I have to do my store to script data in the offline callback plus a set synced bool to false. Then the check if (synced == false) in the online callback. if false during online callback then send stored data to backend and set it to synced = true; (basically making it fire only once)
_
I’d also have a sync button to do that similar call to update server manually. If in offline mode:prompt a warning window. If online mode: update the server data.
_
Is this worded well enough? I’m out of practice with this LOL.
_
Anyway, Network.player.ipAddress; is depricated and I’m not looking for an android enum check or Google ping solution that i keep seeing on here. Is there any other way within unity’s code to check this?? @Bunny83 always has best answers for situations i need, so if you are not busy I’d super appreciate a small amount of help

Well, first of all the “internet” isn’t a single thing you connect to. The internet is the sum of the international network infrastructure run by countless of decentral and individual companies. It just works like the road / street network. Pretty much every house is connected to the street infrastructure (since it’s usually built next to a street). Just being physically connected to the network, does not guarantee that you can reach a certain end point. There are essentially 3 things that have to work out well in order to get from point A to point B.

First it’s your own ability to “leave” your house. If your front door is locked or blocked you can’t even enter the street. This would be the same as the plain physical connectivity to the “internet”.

The next obstacle would be any issues you might encounter while moving on the street network. There might be an accident, closed road, traffic jam. Usually you can take a detour to move around such obstacles but that might not always be the case. So temporarily you might be cut off of certain parts of a city, even though you can enter the street network and move to various places, just not the one you wanted to reach.

The last issue might be at your destination. So the network is fine, but your target location has an issue. For example you wanted to go to the local library, but it’s currently closed. So you can reach your destination, but it’s out of service / not responding.

When it comes to checking the “connectivity to the internet” you should ask yourself what information you’re actually interested in. Just the fact that you have wifi connectivity or a direct connection to an ISP does not guarantee that you can reach your target. Checking if you can reach another public service / server like google.com for example only tells you that you can reach google, but does not necessarily mean you can reach your own server. So all those “tests” that many people recommend are pretty pointless. Of course you could assume that if you can reach google.com, that you can also reach yourServer.com, but that’s not really a reliable way of testing if you can reach a certain service on your server.

So the only real solution in such a case is to actually contact your own service / server. This clears all 3 questions at once. Just put a simple php script or resourcce on your server that you can query from your client. If you can access it successfully, you can reach your server. How you actually reach it doesn’t matter.

Of course in case your probing request to your server fails you can take additional actions to provide the user with more insight. For example if the connection to your server fails there are generally two cases you might want to distinguish: Either your own server is not reachable (your server’s fault or maybe a temporary issue with that route / internet) or the user might have no connection to the internet at all. To distinguish those two cases you could simply check several other public endpoints on the internet. So if none are reachable, the user probably isn’t connected to the internet at all. If some are reachable but your server isn’t, it’s just an issue with your server (maintenance?).

So if you can reach your server, just do your business as normal. If your server isn’t reachable but other servers are reachable, you might want to inform the user that your service might be down for maintenence and he should try it again later. In case none of your testing URLs are working you might want to inform the user to check the internet connectivity.

So keep in mind, first check if you can reach your own server. Only in case that fails you might want to check other testing URLs to see if the user can reach anything else on the net.

ps: Please also keep in mind that most public services (like google) have quite strict terms of services when it comes to automated uses of their services. So be careful what other testing URLs you’re using. Of course if you just want to tell if your server is reachable or not, just requesting your own test resource from your server would be enough.

what I’ve got worked out so far, but still unsure how to implement a Ping or if i need to…
_

using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;
namespace ZeredaGames
{
    public class MainPanelClass : MonoBehaviour
    {
        public static MainPanelClass MainMenuWindow = null;
        public GameObject backgroundImage = null;
        public Button openLeaderboards = null;
        public Button settingsButton = null;
        public Button logoutButton = null;
        public Button switchModeButton = null;
        public Text registerTxt = null;
        public Text versionTxt = null;
        public Text sectionTxt = null;
        public Text usernameDisplayTxt = null;
        public Text accountIdDisplayTxt = null;
        public Text mainContent = null;
        public Text tipsContent = null;
        public Text messageBoard = null;
        public static Color testingMainMenueBackgroundColor = Color.grey;
        public static Color onlineLocalMainMenueBackgroundColor = new Color(0f, 195f, 48f, 255f);
        public static Color onlineServerMainMenueBackgroundColor = new Color(61, 78, 243, 255);
        public static Color offlineMainMenueBackgroundColor = new Color(236, 125, 0, 255);
        private static bool OfflineMode = true;
        private static bool IsOnline = false;
        private static bool LocalMode = false;
        private static bool Sync = false;
        private static DataStorageContainer data;
        private static LoginState loginState = LoginState.Offline;
        private static GameObject WarningWindow = null;

        [Space(2), Header("Settings Popups: Windows")]
        public SetNamePanelClass setNameWindow;
        public SetEmaiPanelClass setEmaiWindow;

        //Not used yet but wanna have an idicator or something with a string.
        public const string OfflineModeDisplay_Key = "OFFLINE";
        public const string OnlineModeDisplay_Key = "ONLINE";

        /// <summary>
        /// Added this for changing the button function depending on the mode in update, 
        /// but i only want it to fire 1 time not keep adding and trying 
        /// to remove listeners from a button, it would cause a null reff error for sure.
        /// </summary>
        private const string CheckKey = "CHECKED";

        /// <summary>
        /// Initiation is set off upon first setup when game runs and is 
        /// activated after the login panel has been chosen depending on 
        /// a hand full of bools.
        /// </summary>
        public void Init()
        {
            if (SetupClass.DebugMode)
                Debug.Log("Init MainPanelClass");
            if (PlayFabLoginManager.GetInstance.platformUsingSettings.classesUsed.mainPanelWindow)
            {
                if (SetupClass.DebugMode)
                    Debug.Log("Find UI");
                FindUI();
            }
            else
            {
                if (SetupClass.DebugMode)
                    Debug.Log("Disabled");
            }
        }

        void Update()
        {
            if (gameObject.activeInHierarchy)
            {
                //Requires PlayFab Extension Editor and Unity SDK to access
                IsOnline = PlayFab.PlayFabClientAPI.IsClientLoggedIn(); ;//Just to make sure this is the check
                if (IsOnline && !LocalMode)
                {
                    loginState = LoginState.OnlineServer;
                }
                else if (IsOnline && LocalMode)
                {
                    loginState = LoginState.OnlineLocal;
                }
                else if (!IsOnline && !LocalMode)
                {
                    loginState = LoginState.Offline;
                }
                else if (!IsOnline && LocalMode)
                {
                    LocalMode = false;
                    OfflineMode = true;
                    loginState = LoginState.Offline;
                }

                if (loginState == LoginState.Offline)
                {
                    if (string.IsNullOrEmpty(PlayerPrefs.GetString(CheckKey)))
                    {
                        switchModeButton.onClick.RemoveListener(SetToLocalModeFromOnline);
                        switchModeButton.onClick.RemoveListener(SetToOnlineModeFromLocal);
                        PlayerPrefs.SetString(CheckKey, "Complete");
                    }

                    OfflineMode = true;
                    backgroundImage.GetComponent<Image>().color = offlineMainMenueBackgroundColor;
                    StoreData(data);
                    if (Sync)
                    {
                        DisplayWarning1();
                        Sync = false;
                    }
                }
                else if (loginState == LoginState.OnlineLocal)
                {
                    if (string.IsNullOrEmpty(PlayerPrefs.GetString(CheckKey)))
                    {
                        switchModeButton.onClick.RemoveListener(SetToOnlineModeFromLocal);
                        switchModeButton.onClick.AddListener(SetToLocalModeFromOnline);
                        PlayerPrefs.SetString(CheckKey, "Complete");
                    }

                    OfflineMode = false;
                    backgroundImage.GetComponent<Image>().color = onlineLocalMainMenueBackgroundColor;
                    StoreData(data);
                    SetGuiData(Sync, data);
                }
                else if (loginState == LoginState.OnlineServer)
                {
                    if (string.IsNullOrEmpty(PlayerPrefs.GetString(CheckKey)))
                    {
                        switchModeButton.onClick.RemoveListener(SetToLocalModeFromOnline);
                        switchModeButton.onClick.AddListener(SetToLocalModeFromOnline);
                        PlayerPrefs.SetString(CheckKey, "Complete");
                    }
                    OfflineMode = false;
                    backgroundImage.GetComponent<Image>().color = onlineServerMainMenueBackgroundColor;
                    data = GetGuiData(data);
                }
            }
        }

        /// <summary>
        /// Find all the UI objects so we do not have to in Unity by hand.
        /// </summary>
        private void FindUI()
        {
            MainMenuWindow = this;
            backgroundImage = GameObject.Find("Header");
            openLeaderboards = GameObject.Find("LeaderboardsButton").GetComponent<Button>();
            settingsButton = GameObject.Find("SettingsButton").GetComponent<Button>();
            logoutButton = GameObject.Find("LogoutButton").GetComponent<Button>();
            switchModeButton = GameObject.Find("SwitchModeButton").GetComponent<Button>();
            registerTxt = GameObject.Find("RegisterDisplayText").GetComponent<Text>();
            versionTxt = GameObject.Find("VersionDisplayText").GetComponent<Text>();
            sectionTxt = GameObject.Find("ParkDisplayText").GetComponent<Text>();
            usernameDisplayTxt = GameObject.Find("UsernameDisplayText").GetComponent<Text>();
            accountIdDisplayTxt = GameObject.Find("AccountIdDisplayTxt").GetComponent<Text>();
            mainContent = GameObject.Find("MainContentText").GetComponent<Text>();
            tipsContent = GameObject.Find("TipsText").GetComponent<Text>();
            messageBoard = GameObject.Find("MessageBoardText").GetComponent<Text>();

            PlayFabLoginManager.GetUserAccountDataFromWeb();

            if (!Equals(MainMenuWindow, PlayFabLoginManager.mainPanelWindow))
            {
                PlayFabLoginManager.mainPanelWindow = MainMenuWindow;
            }
            BindUIButtons();
            NextWindowsToLoad(
                PlayFabLoginManager.GetInstance.platformUsingSettings.classesUsed.loggedInWindow,
                PlayFabLoginManager.GetInstance.platformUsingSettings.classesUsed.leaderboardsWindow,
                PlayFabLoginManager.GetInstance.platformUsingSettings.classesUsed.settingsWindow,
                true, true);
            MainMenuWindow.gameObject.SetActive(false);
        }

        /// <summary>
        /// Set's up all the button OnClick events on initiation.
        /// </summary>
        private void BindUIButtons()
        {
            logoutButton.onClick.RemoveAllListeners();
            logoutButton.onClick.AddListener(OnClickLogout);

            openLeaderboards.onClick.RemoveAllListeners();
            openLeaderboards.onClick.AddListener(ShowLeaderboard);

            settingsButton.onClick.RemoveAllListeners();
            settingsButton.onClick.AddListener(OpenSettingsWindow);

            switchModeButton.onClick.RemoveAllListeners();

            switchModeButton.onClick.AddListener(SetToLocalModeFromOnline);
        }

        /// <summary>
        /// Set up in this manner for loading sequance puposes. everything get's initiated from the LoginController Parent.
        /// </summary>
        /// <param name="loggedInWindow"></param>
        /// <param name="leaderboardsWindow"></param>
        /// <param name="settingsWindow"></param>
        /// <param name="enableNameWindow"></param>
        /// <param name="enableEmailWindow"></param>
        private void NextWindowsToLoad(bool loggedInWindow, bool leaderboardsWindow, bool settingsWindow, bool enableNameWindow, bool enableEmailWindow)
        {
            if (loggedInWindow)
            {
                LoggedInPanelClass.loggedInPanel = GameObject.Find("LoggedInWindow").GetComponent<LoggedInPanelClass>();
                LoggedInPanelClass.loggedInPanel.Init();
            }

            if (leaderboardsWindow)
            {
                LeaderboardsPanelClass.LeaderboardsWindow = GameObject.Find("LeaderboardsWindow").GetComponent<LeaderboardsPanelClass>();
                LeaderboardsPanelClass.LeaderboardsWindow.Init();
            }

            if (settingsWindow)
            {
                SettingsPanelClass.SettingsWindow = GameObject.Find("SettingsWindow").GetComponent<SettingsPanelClass>();
                SettingsPanelClass.SettingsWindow.Init();
            }

            if (enableNameWindow)
            {
                SetNamePanelClass.SetUsernamePanel = GameObject.Find("SetUsernameWindow").GetComponent<SetNamePanelClass>();
                if (SetNamePanelClass.SetUsernamePanel == null)
                    Debug.Log("WHY!!!");
                SetNamePanelClass.SetUsernamePanel.Init();
            }

            if (enableEmailWindow)
            {
                SetEmaiPanelClass.SetEmailPanel = GameObject.Find("SetEmailWindow").GetComponent<SetEmaiPanelClass>();
                if (SetEmaiPanelClass.SetEmailPanel == null)
                    Debug.Log("WHY!!!");
                SetEmaiPanelClass.SetEmailPanel.Init();
            }
            Debug.Log("MainMenuWindow Loaded.");
        }

        /// <summary>
        /// Coppied and slightly altered method from main login for ease of change back to 
        /// online mode without actually showing the whole login business and loading screen. 
        /// The color change is a perfect indicator which mode you are in.
        /// </summary>
        private static void Login()
        {
            if (SetupClass.DebugMode)
                Debug.Log("Login");
            ZGPlayFabSettings.AuthService.Email = SetupClass.OwnerEmail;
            ZGPlayFabSettings.AuthService.Password = SetupClass.OwnerPassword;
            ZGPlayFabSettings.AuthService.InfoRequestParams = PlayFabLoginManager.GetInstance.InfoRequestParams;
            ZGPlayFabSettings.AuthService.AuthType = Authtypes.EmailAndPassword;
            ZGPlayFabSettings.AuthService.Authenticate();
        }

        /// <summary>
        /// Turns LocalMode = false; OfflineMode = false;
        /// </summary>
        public static void OnLoginSuccess()
        {
            LocalMode = false;
            OfflineMode = false;
            PlayerPrefs.DeleteKey(CheckKey);
        }

        /// <summary>
        /// Method build in main Login Controller (One with the Parent and one with don't destroy on load)
        /// </summary>
        public static void OnClickLogout()
        {
            if (SetupClass.DebugMode)
                Debug.Log("OnClick_Logout");
            PlayFabLoginManager.GetInstance.OnQuit();
        }

        /// <summary>
        /// Takes the stored data and updates the server. when 'Sync' is enabled
        /// </summary>
        /// <param name="sync"></param>
        /// <param name="inputData"></param>
        private void SetGuiData(bool sync, DataStorageContainer inputData)
        {
            Sync = sync;
            if (Sync)
            {
                //Server Data = Stored Data. then send a new Playfab User Statistic Request
                Sync = false;
            }
            //Do nothing if sync isn't true
        }

        /// <summary>
        /// Takes the input Data container data and changes it's variables to that of the server and then returns it.
        /// </summary>
        /// <param name="inputData"></param>
        /// <returns></returns>
        private DataStorageContainer GetGuiData(DataStorageContainer inputData)
        {
            //Stored Data = Server Data. by Get Playfab User Statistic Request
            return inputData;
        }

        /// <summary>
        /// Takes the input Data container data and stores the data in a local location 'get;set;'
        /// </summary>
        /// <param name="inputData"></param>
        private void StoreData(DataStorageContainer inputData)
        {
            //Stored Data to local variables, possibly PlayerPrefs??
        }

        /// <summary>
        /// Public Button Call to SetToLocalModeFromOnline (changes modes)
        /// </summary>
        public void SetToLocalModeFromOnline()
        {
            LocalMode = true;
            OfflineMode = false;
            PlayerPrefs.DeleteKey(CheckKey);
        }

        /// <summary>
        /// Public Button Call to SetToOnlineModeFromLocal (changes modes)
        /// </summary>
        public void SetToOnlineModeFromLocal()
        {
            Login();
            LocalMode = true;
            OfflineMode = false;
            PlayerPrefs.DeleteKey(CheckKey);
        }

        /// <summary>
        /// Load's a prefab find's the variables and changes them for this instance. 
        /// In this window and this method we are only destroying the instantiated window clone.
        /// </summary>
        void DisplayWarning1()
        {
            WarningWindow = PlayFabLoginManager.LoadWarningWindow1();
            var warningText = GameObject.Find("WarningText").GetComponent<Text>();
            var warningLable = GameObject.Find("WarningLable").GetComponent<Text>();
            var confirmButton = GameObject.Find("ConfirmButton").GetComponent<Button>();
            warningText.text = "Sorry, you must be online to use this feature.";
            warningLable.text = "ATTENTION!";
            warningLable.color = Color.red;
            warningText.color = offlineMainMenueBackgroundColor;//Cuz its an orange i wanna use.
            confirmButton.onClick.AddListener(DestroyWarningWindow);
        }

        /// <summary>
        /// Destroy the worning window in the scene set the refrence to null so it 
        /// doesn't say 'Missing' in the inspector.
        /// </summary>
        void DestroyWarningWindow()
        {
            var window = GameObject.Find("WarningWindow1(Clone)");
            Destroy(window.gameObject);
            WarningWindow = null;
        }

        /// <summary>
        /// TODO: Add a boolean to enable or destroy and second one in scene on load.
        /// </summary>
        public static void OpenSettingsWindow()
        {
            if (SetupClass.DebugMode)
                Debug.Log("OpenSettingsWindow");
            SettingsPanelClass.SettingsWindow.gameObject.SetActive(true);

            /* Not using atm but was workin as intended. I will not be using this 
                * settings panel but i am building a package to reuse while building this app.
            TODO: Add a check boolean to see which setting panel to activate.

            */
        }

        /// <summary>
        /// Set up for games but will be removed and commented in this code for this app.
        /// </summary>
        public static void ShowLeaderboard()
        {
            if (SetupClass.DebugMode)
                Debug.Log("ShowLeaderboard");
            PlayFabLoginManager.leaderboardsWindow.gameObject.SetActive(true);
        }

    }

    [System.Serializable]
    public class McBees
    {
        public ParkSelection park = ParkSelection.AliceLake;

        [Range(1, MaxSites)]
        public int siteNumber = 1;
        public const int MaxSites = 999;

        public string primaryNameFirst = "";
        public string primaryNameInitial = "";
        public string primaryNameLast = "";
        public string primaryAddress = "";
        public string primaryPhoneNumber = "";
        public string primaryEmailAdress = "";

        public string secondaryNameFirst = "";
        public string secondaryNameInitial = "";
        public string secondaryNameLast = "";
        public string secondaryAddress = "";
        public string secondaryPhoneNumber = "";
        public string secondaryEmailAdress = "";

        public System.DateTime arrivalDate;
        public System.DateTime departureDate;

        public float regularValuePerNightFee = 18;
        public float seniorValuePerNightFee = 9;
        public float disabledValuePerNightFee = 0;
        public float parkEmpValuePerNightFee = 0;
        public float volunteerValuePerNightFee = 0;

        public float extraVehicleValuePerNightFee = 9;
        public float seniorExtraVehicleValuePerNightFee = 4.5f;
        public float parkEmpExtraVehicleValuePerNightFee = 9;
        public float disabledExtraVehicleValuePerNightFee = 0;
        public float volunteerExtraVehicleValuePerNightFee = 0;

        public bool sellWoodAtPark = true;
        public float oneBundleValue = 12;
        public float threeBundleValue = 32;
        [Range(1, 12)]
        public int buddlesOfWoodSold = 0;

        public bool sellIceAtPark = false;
        public float iceValue = 5;
        [Range(1, 10)]
        public int buddlesOfIceSold = 0;

        public bool sellBugRepelentAtPark = false;
        public float bugRepelentValue = 18;
        [Range(1, 4)]
        public int cansOfBugRepelentSold = 18;

        public bool sellMicilaniousItemsListAtPark = false;//for future setup
        public List<float> micilaniousItemsList = new List<float>();//for future setup
        [Range(1, 4)]
        public List<int> micilaniousItemsSold = new List<int>();

        public bool sellBoatRentals = false;
        public float boatRentalValue = 38;
        public int boatRentalsSold = 0;

        public bool sellTrailerRentals = false;
        public float trailerRentalValue = 125;
        public int trailerRentalsSold = 0;

        public bool sellCabinRentals = false;
        public float cabinRentalValue = 250;
        public int nightsForCabinRentalSold = 0;

        public bool sellGroupCampRentals = true;
        public bool isGroupCamp;
        public bool hasExtraGuestInGroupCamp;
        public int nightsForGroupCampSold = 0;
        public float groupCampRentalValue = 80;
        public const float groupCampRentalExtraPersonValue = 1;
        [Range(1, 16)]
        public int extraPeopleCountForGroupCampSold = 0;

        public int stayLength = 1;

        public float totalSale = 0;

        [Range(1, 4)]
        public int adultCount = 1;
        public AdultSelectionList adultSelection = AdultSelectionList._1_;

        [Range(0, 4)]
        public int childCount = 0;
        public ChildSelectionList childSelection = ChildSelectionList._0_;

        [Range(0, 4)]
        public int UnitTypeSelection = 0;
        public CampingUnitType campingUnitType = CampingUnitType._1_Tent;
        public bool hasTent = false;
        [Range(0, 2)]
        public int tentCount = 0;
        public TentType tents = TentType.None;
        public bool hasVehicle = false;
        [Range(0, 2)]
        public int vehicleCount = 1;
        public VehicleType vehicle = VehicleType._1_;
        public bool hasTrailer = false;
        [Range(0, 1)]
        public int trailerCount = 0;
        public TrailerType trailerSelection = TrailerType.None;

        [Range(0, 3)]
        public int warningCount = 0;
        public List<string> warnings = new List<string>();
        public bool issueRefund = false;
        public bool isBCResident = true;
        public bool isBanned = false;
        public string reasonForBan = "";
        public bool hasWarningBeenIssued = false;
        public bool hasEvictionNeenIssued = false;
        public bool havePoliceBeenCalled = false;
    }

    [System.Serializable]
    public class DataStorageContainer
    {
        public List<McBees> mcBeeList = new List<McBees>();
        public List<string> batchNumbersList = new List<string>();
        public List<int> parkBatchNumbers = new List<int>();
        public List<int> systemBatchNumbers = new List<int>();
    }

    public enum AdultSelectionList
    {
        _1_,
        _2_,
        _3_,
        _4_
    };

    public enum ChildSelectionList
    {
        _0_,
        _1_,
        _2_,
        _3_,
        _4_
    };

    public enum TentType
    {
        None,
        _1_,
        _2_,
        _3_
    };

    public enum TrailerType
    {
        None,
        SmallTowTrailer,
        LargeTowTrailer,
        Motorhome
    };

    public enum VehicleType
    {
        None,
        _1_,
        _2_,
    };

    public enum CampingUnitType
    {
        _1_Tent,
        _2_Tent,
        _3_TentOrShelter,
        CamperOrVan,
        SmallCamperUpTo18Feet
    }

    public enum UsageClassification
    {
        Regular,
        SSCFE,
        BC_Senior,
        Park_Employee,
        Volunteer
    }

    /// <summary>
    /// List of parks to compair to List(string) ParkNames (- used to populate Dropdown) and can be used for a case switch comparison.
    /// </summary>
    public enum ParkSelection
    {
        NoneSelected,
        AliceLake,
        BirkenheadLake,
        BrandywineFalls,
        BridalVeilFalls,
        ChilliwackLake,
        CultusLake,
        MapleBay,
        MountSeymour,
        Murrin,
        NairnFalls,
        PorteauCove,
        Sasquatch,
        ShannonFalls,
        SilverLake,
        SkagitValley,
        StawamusChief
    };
}