EDCD / EDDI

Companion application for Elite Dangerous
Other
440 stars 81 forks source link

EDDI Core: Update delivery mechanism? #26

Closed Tkael closed 6 years ago

Tkael commented 7 years ago

We need to assess the update delivery mechanism. jgm had it working very painlessly for end users and I would like to preserve that. Of course, unless he is willing and able to grant us control of the relevant update server, we will have to implement some sort of manual transition. This will need thought.

Tkael commented 7 years ago

The URL that EDDI checks for version control is http://api.eddp.co/_info. The file is formatted like a json. We just need to change this to something that we can keep up to date, and to establish a location for hosting new releases.

The relevant code for automatic updating / checking for new versions of EDDI appears to be located beginning at line 243 of EDDI.cs:

        /// <summary>
        /// Check to see if an upgrade is available and populate relevant variables
        /// </summary>
        public void CheckUpgrade()
        {
            // Clear the old values
            UpgradeRequired = false;
            UpgradeAvailable = false;
            UpgradeLocation = null;
            UpgradeVersion = null;
            Motd = null;

            try
            {
                ServerInfo updateServerInfo = ServerInfo.FromServer("http://api.eddp.co/");
                if (updateServerInfo == null)
                {
                    Logging.Warn("Failed to contact update server");
                }
                else
                {
                    EDDIConfiguration configuration = EDDIConfiguration.FromFile();
                    InstanceInfo info = configuration.Beta ? updateServerInfo.beta : updateServerInfo.production;
                    Motd = info.motd;
                    if (updateServerInfo.productionbuilds != null)
                    {
                        ProductionBuilds = updateServerInfo.productionbuilds;
                    }

                    if (Versioning.Compare(info.minversion, Constants.EDDI_VERSION) == 1)
                    {
                        // There is a mandatory update available
                        if (!FromVA)
                        {
                            SpeechService.Instance.Say(null, "Mandatory Eddi upgrade to " + info.version.Replace(".", " point ") + " is required.", false);
                        }
                        UpgradeRequired = true;
                        UpgradeLocation = info.url;
                        UpgradeVersion = info.version;
                    }

                    if (Versioning.Compare(info.version, Constants.EDDI_VERSION) == 1)
                    {
                        // There is an update available
                        if (!FromVA)
                        {
                            SpeechService.Instance.Say(null, "Eddi version " + info.version.Replace(".", " point ") + " is now available.", false);
                        }
                        UpgradeAvailable = true;
                        UpgradeLocation = info.url;
                        UpgradeVersion = info.version;
                    }
                }
            }
            catch (Exception ex)
            {
                SpeechService.Instance.Say(null, "There was a problem connecting to external data services; some features may be temporarily unavailable", false);
                Logging.Warn("Failed to access api.eddp.co", ex);
            }
        }

        /// <summary>
        /// Obtain and check the information from the update server
        /// </summary>
        private bool UpdateServer()
        {
            try
            {
                ServerInfo updateServerInfo = ServerInfo.FromServer("http://api.eddp.co/");
                if (updateServerInfo == null)
                {
                    Logging.Warn("Failed to contact update server");
                    return false;
                }
                else
                {
                    InstanceInfo info = Constants.EDDI_VERSION.Contains("b") ? updateServerInfo.beta : updateServerInfo.production;
                    Motd = info.motd;
                    if (Versioning.Compare(info.minversion, Constants.EDDI_VERSION) == 1)
                    {
                        Logging.Warn("This version of Eddi is too old to operate; please upgrade at " + info.url);
                        SpeechService.Instance.Say(null, "This version of Eddiis too old to operate; please upgrade.", true);
                        UpgradeRequired = true;
                        UpgradeLocation = info.url;
                        UpgradeVersion = info.version;
                        //SpeechService.Instance.Say(null, "EDDI requires an update.  Downloading.", true);
                        //// We are too old to run - update
                        //string updateFile = Net.DownloadFile(info.url, @"EDDI-update.exe");
                        //if (updateFile == null)
                        //{
                        //    SpeechService.Instance.Say(null, "Download failed.  Please try again later.", true);
                        //}
                        //else
                        //{
                        //    Logging.Info("Downloaded to " + updateFile);
                        //    SpeechService.Instance.Say(null, "Download complete.  Please restart EDDI once upgrade has finished.", true);
                        //    Process.Start(updateFile, @"/silent /nocancel /noicon /dir=""" + Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"""");
                        //}
                        //System.Environment.Exit(1);
                    }

                    if (Versioning.Compare(info.version, Constants.EDDI_VERSION) == 1)
                    {
                        // There is an update available
                        SpeechService.Instance.Say(null, "EDDI version " + info.version.Replace(".", " point ") + " is now available.", true);
                        UpgradeAvailable = true;
                        UpgradeLocation = info.url;
                        UpgradeVersion = info.version;
                        //SpeechService.Instance.Say(null, "EDDI version " + info.version.Replace(".", " point ") + " is now available.  Downloading.", true);
                        //string updateFile = Net.DownloadFile(info.url, @"EDDI-update.exe");
                        //if (updateFile == null)
                        //{
                        //    SpeechService.Instance.Say(null, "Download failed.  EDDI will try again next time.", true);
                        //}
                        //else
                        //{
                        //    Logging.Info("Downloaded to " + updateFile);
                        //    SpeechService.Instance.Say(null, "Download complete.  Please restart EDDI once upgrade has finished.", true);
                        //    Process.Start(updateFile, @"/silent /nocancel /noicon /dir=""" + Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"""");
                        //    System.Environment.Exit(1);
                        //}
                    }

                    if (info.motd != null)
                    {
                        // There is a message
                        SpeechService.Instance.Say(null, info.motd, false);
                    }
                }
            }
            catch (Exception ex)
            {
                SpeechService.Instance.Say(null, "There was a problem connecting to external data services; some features may be temporarily unavailable", false);
                Logging.Warn("Failed to access api.eddp.co", ex);
            }
            return true;
        }

        [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
        [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
        public void Upgrade()
        {
            try
            {
                if (UpgradeLocation != null)
                {
                    Logging.Info("Downloading upgrade from " + UpgradeLocation);
                    SpeechService.Instance.Say(null, "Downloading upgrade.", true);
                    string updateFile = Net.DownloadFile(UpgradeLocation, @"EDDI-update.exe");
                    if (updateFile == null)
                    {
                        SpeechService.Instance.Say(null, "Download failed.  Please try again later.", true);
                    }
                    else
                    {
                        // Inno setup will attempt to restart this application so register it
                        RegisterApplicationRestart(null, RestartFlags.NONE);

                        Logging.Info("Downloaded update to " + updateFile);
                        Logging.Info("Path is " + Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
                        File.SetAttributes(updateFile, FileAttributes.Normal);
                        SpeechService.Instance.Say(null, "Starting upgrade.", true);
                        Logging.Info("Starting upgrade.");

                        Process.Start(updateFile, @"/closeapplications /restartapplications /silent /log /nocancel /noicon /dir=""" + Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"""");
                    }
                }
            }
            catch (Exception ex)
            {
                SpeechService.Instance.Say(null, "Upgrade failed.  Please try again later.", true);
                Logging.Error("Upgrade failed", ex);
            }
        }

        public void Start()
        {
            if (!started)
            {
                EDDIConfiguration configuration = EDDIConfiguration.FromFile();

                foreach (EDDIMonitor monitor in monitors)
                {
                    bool enabled;
                    if (!configuration.Plugins.TryGetValue(monitor.MonitorName(), out enabled))
                    {
                        // No information; default to enabled
                        enabled = true;
                    }

                    if (!enabled)
                    {
                        Logging.Debug(monitor.MonitorName() + " is disabled; not starting");
                    }
                    else
                    {
                        if (monitor.NeedsStart())
                        {
                            Thread monitorThread = new Thread(() => keepAlive(monitor.MonitorName(), monitor.Start))
                            {
                                IsBackground = true
                            };
                            Logging.Info("Starting keepalive for " + monitor.MonitorName());
                            monitorThread.Start();
                        }
                    }
                }

                foreach (EDDIResponder responder in responders)
                {
                    bool enabled;
                    if (!configuration.Plugins.TryGetValue(responder.ResponderName(), out enabled))
                    {
                        // No information; default to enabled
                        enabled = true;
                    }

                    if (!enabled)
                    {
                        Logging.Debug(responder.ResponderName() + " is disabled; not starting");
                    }
                    else
                    {
                        bool responderStarted = responder.Start();
                        if (responderStarted)
                        {
                            activeResponders.Add(responder);
                            Logging.Info("Started " + responder.ResponderName());
                        }
                        else
                        {
                            Logging.Warn("Failed to start " + responder.ResponderName());
                        }
                    }
                }
                started = true;
            }
        }

        public void Stop()
        {
            running = false; // Otherwise keepalive restarts them
            if (started)
            {
                foreach (EDDIResponder responder in responders)
                {
                    responder.Stop();
                    activeResponders.Remove(responder);
                }
                foreach (EDDIMonitor monitor in monitors)
                {
                    monitor.Stop();
                }
            }

            Logging.Info(Constants.EDDI_NAME + " " + Constants.EDDI_VERSION + " stopped");

            ExceptionlessClient.Default.Shutdown();

            started = false;
        }
Tkael commented 7 years ago

There's a possible hosting source here on Github: https://pages.github.com/

Syrrianyl commented 7 years ago

If needed, I have the personnal page that I never used with my internet provider (because i don't know how, and not interrested to learn). If I create a mail like "EDDI.international@free.fr" I will have a link for a free personnal page, with the choice of no SQL or MySQL or PostgreSQL ,

rule (with google translate)

The "Personal Pages" service allows you to have disk space on the FREE servers, dedicated exclusively to hosting personal web pages. These personal pages must be directly accessible by a browser. They must have a home page (index), which must allow access directly or indirectly to all the files contained or stored in the disk space reserved for you. The disk space available to you in the "Personal Pages" service is not a space for storing and / or saving personal documents, since all elements in a Web directory are 'be indexed by the search engines if you do not take any protective action. ....snip... If you want to use turnkey PHP scripts such as Dotclear, Wikini, Spip, PhpBB (not exhaustive list), be sure to update them as and when the developers of these CMS corrections.

Any application of statistics, generating a disproportionate number of requests is prohibited (the account will be suspended or even destroyed). Also improve the security and avoid the spam of the database of your PHP forums by installing Captcha (http://www.captcha.net/), prohibiting the users invited, protecting the different files of your site with Htaccess (http://www.phpdebutant.org/article51.php). Protect yourself also by having different passwords for your account, SQL database and FTP of your personal space.

For your statistics, use the version of phpmyvisites that we put at your disposal http://st.free.fr

Tkael commented 7 years ago

I'm currently looking at using Github pages. That way, we add it to the Github organization where it can more easily be maintained by a group rather than a single individual.

Tkael commented 7 years ago

Current rev. status is controlled by jgm at location: http://api.eddp.co/_info Test of an alternate hosting location: http://edcd.github.io/EDDP/info.json

Tkael commented 6 years ago

Transition build with altered upgrade location is now uploaded for testing.

Tkael commented 6 years ago

Tested and working.