Solved Sending resource pack from server to client directly

Discussion in 'Spigot Plugin Development' started by JustDJplease, Jul 17, 2018.

  1. Uhm, this is a bit of a 'special' idea I had. A plugin of mine generates a resource pack based of the server configuration, player preferences etc. This folder is then zipped and stored in the plugin directory. Now, I'm curious if I were to be able to send it to the client directly.

    What do I mean?
    Well usually, you would upload the resource pack to a file sharing webserver (dropbox, drive, mediafire) and send the clients the direct download url with the setResourcePack(String url, byte[] hash) method.

    I would like to know if it is possible to skip this webserver step and directly upload the resource pack to the client. Here is my thinking: You can start an HttpServer on a different thread (with the server IP and a configurable port), which redirects to the file in my plugin directory that holds the resource pack. Then, I could use the setResourcePack(url, hash) method with my ip : port as url and apply that to the client.

    Is there anyone with experience on this? I had a look through dynmap's source code and some other web-plugins but I have absolutely no experience with the HttpServer thing.
     
  2. I don't really understand: you are trying to get a file in your computer upload it to an Http server and then use setResourcePack(url, hash) ??
     
  3. Almost. I'm trying to turn the JVM on which the spigot server runs itself into a webserver (like dynmap does) and then send the resourcepack from the server itself.

    (My art skills are trash pls)
    [​IMG]
     
    #3 JustDJplease, Jul 17, 2018
    Last edited: Jul 17, 2018
  4. I don't think you can directly send it to the client. The client downloads it from somewhere through HTTP. I don't think you can directly send it to the client like that. Naturally however, you could start up this mini web server through Bukkit and send that URL instead. I'll help you out in Discord if you need to setup some mini, super lightweight webserver.
     
    • Friendly Friendly x 1
  5. I've figured this out. My solution: Let the server create a HttpServer with VertX as a dependency. Then, upon httpServerRequest, directly send the file to the client. This HttpServer is started on serverIP : Port.

    Made a tiny mistake there. The URL used in the setResourcePack(url) method has to start with "http://". It will not work without it. (Spend a good few hours on debugging this lol)

    If you're interested:
    Code (Text):
    import io.vertx.core.Vertx;
    import io.vertx.core.http.HttpServer;
    import me.theblockbender.web.Main;

    import java.io.File;

    public class WebServerHandler {

        // -------------------------------------------- //
        // INSTANCES & VARIABLES
        // -------------------------------------------- //
        public int port;
        public String ip;

        private HttpServer httpServer;
        private Main main;

        // -------------------------------------------- //
        // CONSTRUCTOR
        // -------------------------------------------- //
        public WebServerHandler(Main main) {
            this.main = main;
        }

        // -------------------------------------------- //
        // WEB HANDLERS
        // -------------------------------------------- //
        public boolean start() {
            ip = main.getServer().getIp();
            if (ip == null || ip.equals("")) ip = "localhost";
            try {
                port = main.getConfig().getInt("port");
            } catch (Exception ex) {
                main.outputError("Invalid port configured in the config.yml");
                return false;
            }
            try {
                httpServer = Vertx.vertx().createHttpServer();
                httpServer.requestHandler(httpServerRequest -> httpServerRequest.response().sendFile(getFileLocation()));
                httpServer.listen(port);
            }catch(Exception ex){
                main.outputError("Unable to bind to port. Please assign the plugin to a different port!");
                ex.printStackTrace();
                return false;
            }
            return true;
        }

        // TODO this does not unassign the web server from the port.
        public void stop() {
            httpServer.close();
        }

        // -------------------------------------------- //
        // GETTERS
        // -------------------------------------------- //
        private String getFileLocation() {
            return main.getDataFolder().getPath() + File.separator + "web" + File.separator + "rp.zip";
        }
    }
     
    Then, I can simply send the pack using
    Code (Text):
    String url = "http://" + main.webServerHandler.ip + ":" + main.webServerHandler.port;
    player.setResourcePack(url);
     
    #5 JustDJplease, Jul 17, 2018
    Last edited: Jul 17, 2018
    • Like Like x 1
    • Winner Winner x 1
  6. Hey hey that was my suggestion :LOL:

    But yes, as seen from the code, making an efficient, lightweight webserver in Java really doesn't need much. You could probably do it with bare bone Java too, but using tiny frameworks here and there is quite lovely and interesting, right? ;)
     
    • Winner Winner x 1