AutoUpdate

Discussion in 'Spigot Plugin Development' started by Kyllian, Apr 17, 2017.

  1. Hello,

    I was wondering what the BEST and most efficient way to auto receive plugin updates.

    (I want to implement it in my plugin, not a maven plugin)
     
  2. Automatically downloading it and checking upon startup?
     
  3. No auto download. Just a message
     
  4. then just check if there is a new version out?
     
  5. How. I mean I want my plugins to tell the user it
     
  6. you make it send a message to console, which you should know how to.
     
  7. You need to communicate with something external. For example, create a json document online for example using pastebin as so. You would have to edit this document as the versions progress. You can open this paste in raw text by using the /raw/ tag. Now that we have raw json data (not all the HTML and stuff), we could retrieve it and use the native JSON library for example to parse and use it as so:

    Hastebin or pastebin or raw code below:
    Code (Text):
    import org.json.JSONObject;
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.net.HttpURLConnection;
    import java.net.URL;

    /**
    * Project created by ExpDev
    */

    public class PastebinJson {

        /**
         * Runs when the program starts
         */
        public static void main(String[] strings) {
            // The endpoint which we will get the data from
            String requestUrl = "https://pastebin.com/raw/JVPCnziR";

            // Our string builder which we will append our results to later
            StringBuilder sb = new StringBuilder();
            try {
                // Using the String and turning into an URL object
                URL url = new URL(requestUrl);
                // Opening a connection with our URL
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();

                // The connection should be able to handle outputs
                connection.setDoOutput(true);
                // Using a simple GET
                connection.setRequestMethod("GET");
                // We want JSON back
                connection.setRequestProperty("Accept", "application/json");
                connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");

                // reading our response
                BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                String line;
                while ((line = br.readLine()) != null) {
                    sb.append(line);
                }
                // Closing the reader
                br.close();
                // Disconnecting the connection is also important
                connection.disconnect();
            } catch (Exception e) {
                throw new RuntimeException(e.getMessage());
            }
            String response = sb.toString();
            System.out.println(response);

            JSONObject jsonObject = new JSONObject(response);

            double currentVer = 2.0;
            String name = jsonObject.getString("name");
            double latestVer = jsonObject.getDouble("latestVersion");

            System.out.println("Newest version of " + name + " is: " + (latestVer));
            System.out.println("Have to update?: " + (latestVer > currentVer));
        }

    }
    Output:
    Code (Text):
    {name:"MyPlugin",latestVersion:2.1}
    Newest version of MyPlugin is: 2.1
    Have to update?: true
    As you can see, it's very easy. Now, you could just not use json, and instead just have the page return one number like this. However, it could get tricky when you want to store more information. And json is much more organized and quicker for the computer to read.

    -------------
    EDIT: Do this on onEnable or something and send a message to the console that they need to update. You could also probably keep a link to the newest version in the pastebin as well.

    EDIT2: Disclaimer: downloading external files is not allowed on SpigotMC as stated in the rules. So please only leave a notification, and do not take use of Java to install the newest version on the machine that contains your plugin.

    EDIT3: I just tested how long the operation takes:
    Code (Text):
    Operation took 291738699 nanoseconds (291 milliseconds)
    This is a considerable amount of time, so I would suggest performing the operation once, and caching the results for about an hour before you do it again if you wanna constantly send the update notification. So if within an hour you have edited the json document, they will know once the cache outdates itself and new results are cached.

    EDIT4: Remember to create a Pastebin account to be able to edit your pastebins.
    -------------

    Hope I helped!
     
    #7 ExpDev, Apr 17, 2017
    Last edited: Apr 17, 2017
  8. Mas

    Mas

  9. Alright thanks for the awesome explanation.

    I got it almost working. Only issue I have now is that:

    JSONObject jsonObject = new JSONObject(response);

    Gives the error:

    The constructor JSONObject(String) is undefined
     
    • Like Like x 1
  10. @ItsMas_ So i've tried it. And just to make sure. Should this work? Because i'm really bad at reading other people their codes:

    Code (Text):
    package me.kyllian.system32.utils;

    import java.net.URL;

    import org.apache.commons.io.IOUtils;
    import org.json.simple.JSONArray;
    import org.json.simple.JSONObject;
    import org.json.simple.JSONValue;

    import me.kyllian.system32.System32;

    public class UpdateChecker {

        private static System32 sys32 = System32.getInstance();

        final static String VERSION_URL = "https://api.spiget.org/v2/resources/37249/versions?size=" + Integer.MAX_VALUE;
        final static String DESCRIPTION_URL = "https://api.spiget.org/v2/resources/37249/updates?size=1"
                + Integer.MAX_VALUE;

        public static Object[] getLastUpdate() {
            try {
                JSONArray versionsArray = (JSONArray) JSONValue
                        .parseWithException(IOUtils.toString(new URL(String.valueOf(VERSION_URL))));
                Double lastVersion = Double
                        .parseDouble(((JSONObject) versionsArray.get(versionsArray.size() - 1)).get("name").toString());
                if (lastVersion > Double.parseDouble(sys32.getDescription().getVersion())) {
                    JSONArray updatesArray = (JSONArray) JSONValue
                            .parseWithException(IOUtils.toString(new URL(String.valueOf(DESCRIPTION_URL))));
                    String updateName = ((JSONObject) updatesArray.get(updatesArray.size() - 1)).get("title").toString();
                    Object[] update = { lastVersion, updateName };
                    return update;
                }
            } catch (Exception exc) {
                return new String[0];
            }
            return new String[0];
        }
    }
     
     
  11. That's just an example of how he parsed it. You can do it however you'd like, if you do not wish to use his code. As long as you retrieve the data, you can parse it how u want.
     
  12. Alrighty, I'm using the spiget method now.

    Is there any way to test if this works?
     
  13. You seem to have 28 resources on here, so test it yourself.
     
  14. Did that, Put my own plugin version down to see if it saw the update. The result is no.

    I used the code for x.x format. Is it because my plugin version is like 0.18 etc?
     
  15. No. I put it in myself for the version, but get nothing but an empty array back. Think that one is broken, as the others work just fine. But that update thing doesn't work. Might want to resolve back to the Pasebin temporarily if urgent, then contact him and ask what is wrong.

    EDIT:
    For example: https://api.spiget.org/v2/resources/22027/versions?size=2147483647 returns nothing but an empty array ([]), however https://api.spiget.org/v2/resources/22027/updates?size=2147483647 returns correct information.
     
  16. Alright, I will contact him.
     
  17. Ok :)
     
  18. You can to use an text file and the plugin to read theat or to put the plugin to read on mysql the version and to cheak in is the new version.
     
    • Agree Agree x 1
  19. None of this is optimal.
    • Prefer third-party services that do this for you and use their own code and hosting. There's plenty of auto-update systems out there with configurable options to do whatever you'd like.
    • No need to store a text file with the version. Bukkit stores that internally so you can retrieve it from there.
    • Please don't roll your own PHP/MySQL backend. It's a security and logistic nightmare.