Search in sources :

Example 1 with ModLoadFailureException

use of io.xol.chunkstories.api.exceptions.content.mods.ModLoadFailureException in project chunkstories by Hugobros3.

the class ModsSelection method buildModsList.

private void buildModsList() {
    modsContainer.elements.clear();
    Collection<String> currentlyEnabledMods = Arrays.asList(Client.getInstance().getContent().modsManager().getEnabledModsString());
    Set<String> uniqueMods = new HashSet<String>();
    // First put in already loaded mods
    for (Mod mod : Client.getInstance().getContent().modsManager().getCurrentlyLoadedMods()) {
        // Should use md5 hash instead ;)
        if (uniqueMods.add(mod.getModInfo().getName().toLowerCase()))
            modsContainer.elements.add(modsContainer.new ModItem(mod, true));
    }
    // Then look for mods in folder fashion
    for (File f : new File(GameDirectory.getGameFolderPath() + "/mods/").listFiles()) {
        if (f.isDirectory()) {
            File txt = new File(f.getAbsolutePath() + "/mod.txt");
            if (txt.exists()) {
                try {
                    ModFolder mod = new ModFolder(f);
                    // Should use md5 hash instead ;)
                    if (uniqueMods.add(mod.getModInfo().getName().toLowerCase()))
                        modsContainer.elements.add(modsContainer.new ModItem(mod, currentlyEnabledMods.contains(mod.getModInfo().getName())));
                    System.out.println("mod:" + mod.getModInfo().getName() + " // " + currentlyEnabledMods.contains(mod.getModInfo().getName()));
                } catch (ModLoadFailureException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    // First look for mods in folder fashion
    for (File f : new File(GameDirectory.getGameFolderPath() + "/mods/").listFiles()) {
        if (f.getName().endsWith(".zip")) {
            try {
                ModZip mod = new ModZip(f);
                // Should use md5 hash instead ;)
                if (uniqueMods.add(mod.getModInfo().getName().toLowerCase()))
                    modsContainer.elements.add(modsContainer.new ModItem(mod, currentlyEnabledMods.contains(mod.getModInfo().getName())));
            } catch (ModLoadFailureException e) {
                e.printStackTrace();
            }
        }
    }
}
Also used : ModLoadFailureException(io.xol.chunkstories.api.exceptions.content.mods.ModLoadFailureException) Mod(io.xol.chunkstories.api.content.mods.Mod) ModItem(io.xol.chunkstories.gui.layer.config.ModsSelection.ModsScrollableContainer.ModItem) ModFolder(io.xol.chunkstories.content.mods.ModFolder) File(java.io.File) HashSet(java.util.HashSet) ModZip(io.xol.chunkstories.content.mods.ModZip)

Example 2 with ModLoadFailureException

use of io.xol.chunkstories.api.exceptions.content.mods.ModLoadFailureException in project chunkstories by Hugobros3.

the class ModsManagerImplementation method buildModsFileSystem.

private void buildModsFileSystem() {
    avaibleAssets.clear();
    avaibleForeignClasses.clear();
    pluginsWithinEnabledMods.clear();
    // Obtain a cache folder
    if (cacheFolder == null) {
        cacheFolder = new File(GameDirectory.getGameFolderPath() + "/cache/" + ((int) (Math.random() * 10000)));
        cacheFolder.mkdirs();
        // cacheFolder.deleteOnExit();
        Runtime.getRuntime().addShutdownHook(new Thread() {

            public void run() {
                System.out.println("Deleting cache folder " + cacheFolder);
                FoldersUtils.deleteFolder(cacheFolder);
            }
        });
    }
    // Checks for the base assets folder presence and sanity
    try {
        if (coreContentLocation.isDirectory())
            baseAssets = new ModFolder(coreContentLocation);
        else
            baseAssets = new ModZip(coreContentLocation);
    } catch (ModLoadFailureException e) {
        logger().error("Fatal : failed to load in the base assets folder. Exception : {}", e);
    // e.printStackTrace(logger().getPrintWriter());
    }
    ClassLoader childClassLoader = loadModAssets(baseAssets, Thread.currentThread().getContextClassLoader());
    // Iterates over mods, in order of priority (lowest to highest)
    for (Mod mod : enabledMods) {
        childClassLoader = loadModAssets((ModImplementation) mod, childClassLoader);
    }
    finalClassLoader = childClassLoader;
}
Also used : ModLoadFailureException(io.xol.chunkstories.api.exceptions.content.mods.ModLoadFailureException) Mod(io.xol.chunkstories.api.content.mods.Mod) ForeignCodeClassLoader(io.xol.chunkstories.content.sandbox.ForeignCodeClassLoader) File(java.io.File)

Example 3 with ModLoadFailureException

use of io.xol.chunkstories.api.exceptions.content.mods.ModLoadFailureException in project chunkstories by Hugobros3.

the class ModsManagerImplementation method loadEnabledMods.

@Override
public void loadEnabledMods() throws NotAllModsLoadedException {
    enabledMods.clear();
    List<ModLoadFailureException> modLoadExceptions = new ArrayList<ModLoadFailureException>();
    // Creates mods dir if it needs to
    File modsDir = new File(GameDirectory.getGameFolderPath() + "/mods");
    if (!modsDir.exists())
        modsDir.mkdirs();
    // Server mods
    File serverMods = new File(GameDirectory.getGameFolderPath() + "/servermods");
    if (!serverMods.exists())
        serverMods.mkdirs();
    for (String name : modsEnabled) {
        try {
            ModImplementation mod = null;
            // Servers give a md5 hash for their required mods
            if (name.startsWith("md5:")) {
                // Look for a mod with that md5 hash
                String hash = name.substring(4, name.length());
                String url = null;
                // If the hash is bundled with an url, split'em
                if (hash.contains(":")) {
                    int i = hash.indexOf(":");
                    url = hash.substring(i + 1);
                    hash = hash.substring(0, i);
                }
                System.out.println("Looking for hashed mod " + hash + " (url = " + url + ")");
                // Look for the mod zip in local fs first.
                File zippedMod = new File(serverMods.getAbsolutePath() + "/" + hash + ".zip");
                if (zippedMod.exists()) {
                    // Awesome we found it !
                    mod = new ModZip(zippedMod);
                } else if (url != null) {
                // TODO download and hanle files from server
                } else {
                // We failed. Mod won't be loaded
                }
            } else {
                System.out.println("Looking for mod " + name + " on the local filesystem");
                // First look for it in the directory section
                File modDirectory = new File(modsDir.getAbsolutePath() + "/" + name);
                if (modDirectory.exists()) {
                    mod = new ModFolder(modDirectory);
                    System.out.println("Found mod in directory : " + modDirectory);
                } else {
                    // Then look for a .zip file in the same directory
                    File zippedMod = new File(modsDir.getAbsolutePath() + "/" + name + ".zip");
                    if (zippedMod.exists()) {
                        mod = new ModZip(zippedMod);
                        System.out.println("Found mod in zipfile : " + zippedMod);
                    } else {
                        // Finally just look for it in the global os path
                        if (name.endsWith(".zip")) {
                            zippedMod = new File(name);
                            if (zippedMod.exists()) {
                                mod = new ModZip(zippedMod);
                                System.out.println("Found mod in global zipfile : " + zippedMod);
                            }
                        } else {
                            modDirectory = new File(name);
                            if (modDirectory.exists()) {
                                mod = new ModFolder(modDirectory);
                                System.out.println("Found mod in global directory : " + modDirectory);
                            }
                        }
                    }
                }
            }
            // Did we manage it ?
            if (mod != null) {
                if (!enabledMods.add(mod)) {
                    // Somehow we added a mod twice and it's now conflicting.
                    throw new ModLoadFailureException(mod, "Conflicting mod, another mod with the same name or hash is already loaded.");
                }
            } else
                throw new ModNotFoundException(name);
        } catch (ModLoadFailureException exception) {
            modLoadExceptions.add(exception);
        }
    }
    buildModsFileSystem();
    // Return an exception if some mods failed to load.
    if (modLoadExceptions.size() > 0)
        throw new NotAllModsLoadedException(modLoadExceptions);
}
Also used : ModLoadFailureException(io.xol.chunkstories.api.exceptions.content.mods.ModLoadFailureException) ArrayList(java.util.ArrayList) File(java.io.File) ModNotFoundException(io.xol.chunkstories.api.exceptions.content.mods.ModNotFoundException) NotAllModsLoadedException(io.xol.chunkstories.api.exceptions.content.mods.NotAllModsLoadedException)

Example 4 with ModLoadFailureException

use of io.xol.chunkstories.api.exceptions.content.mods.ModLoadFailureException in project chunkstories by Hugobros3.

the class ConnectionSequence method run.

@Override
public void run() {
    logger.info("Connection sequence initialized.");
    try {
        if (!connection.connect())
            abort("Failed to establish connection");
        if (Client.offline) {
            connection.sendTextMessage("login/start");
            connection.sendTextMessage("login/username:" + Client.username);
            connection.sendTextMessage("login/logintoken:nopenopenopenopenope");
            connection.sendTextMessage("login/version:" + VersionInfo.networkProtocolVersion);
            connection.sendTextMessage("login/confirm");
            status = new ConnectionStep("Offline-mode enabled, skipping login token phase");
        } else {
            status = new ConnectionStep("Requesting a login token...");
            SimplePostRequest spr = new SimplePostRequest("https://chunkstories.xyz/api/serverTokenObtainer.php", "username=" + Client.username + "&sessid=" + Client.session_key);
            String reply = spr.result();
            if (reply != null && reply.startsWith("ok")) {
                String loginToken = reply.split(":")[1];
                connection.sendTextMessage("login/start");
                connection.sendTextMessage("login/username:" + Client.username);
                connection.sendTextMessage("login/logintoken:" + loginToken);
                connection.sendTextMessage("login/version:" + VersionInfo.networkProtocolVersion);
                connection.sendTextMessage("login/confirm");
                status = new ConnectionStep("Token obtained, logging in...");
            } else {
                abort("Failed to obtain a login token from the servers");
            }
        }
        if (!authSemaphore.tryAcquire(5, TimeUnit.SECONDS))
            abort("Server login timed out");
        // Obtain the mods list, check if we have them enabled
        this.status = new ConnectionStep("Asking server required mods...");
        connection.sendTextMessage("mods");
        if (!modsSemaphore.tryAcquire(5, TimeUnit.SECONDS))
            abort("Failed to obtain mods list from server");
        Set<String> requiredMd5s = new HashSet<String>();
        for (String requiredMod : modsString.split(";")) {
            if (!requiredMod.contains(":"))
                continue;
            String[] properties = requiredMod.split(":");
            if (properties.length < 3)
                continue;
            String modInternalName = properties[0];
            String modMd5Hash = properties[1];
            long modSizeInBytes = Long.parseLong(properties[2]);
            // String md5Required = requiredMod.contains(":") ? requiredMod.split(":")[0] : requiredMod;
            Client.getInstance().logger().info("Server asks for mod " + modInternalName + " (" + modSizeInBytes + " bytes), md5=" + modMd5Hash);
            requiredMd5s.add(modMd5Hash);
            File cached = new File(GameDirectory.getGameFolderPath() + "/servermods/" + modMd5Hash + ".zip");
            if (!cached.exists()) {
                // Sequentially download all the mods from the server
                status = connection.obtainModFile(modMd5Hash, cached);
                status.waitForEnd();
            }
            // Check their size and signature
            if (cached.length() != modSizeInBytes) {
                Client.getInstance().logger().info("Invalid filesize for downloaded mod " + modInternalName + " (hash: " + modMd5Hash + ")" + " expected filesize = " + modSizeInBytes + " != actual filesize = " + cached.length());
                // Delete suspicious file
                cached.delete();
                abort("Failed to download " + modInternalName + ", wrong file size. You can try again.");
            }
            // Test if the mod loads
            ModZip testHash = null;
            try {
                testHash = new ModZip(cached);
            } catch (ModLoadFailureException e) {
                e.printStackTrace();
                Client.getInstance().logger().info("Could not load downloaded mod " + modInternalName + " (hash: " + modMd5Hash + "), see stack trace");
                // Delete suspicious file
                cached.delete();
                abort("Failed to load " + modInternalName + ", check error log.");
            }
            // Test the md5 hash wasn't tampered with
            String actualMd5Hash = testHash.getMD5Hash();
            if (!actualMd5Hash.equals(modMd5Hash)) {
                Client.getInstance().logger().info("Invalid md5 hash for mod " + modInternalName + " expected md5 hash = " + modMd5Hash + " != actual md5 hash = " + actualMd5Hash);
                // Delete suspicious file
                cached.delete();
                abort("Mod " + modInternalName + " hash did not match.");
            }
        }
        // Build the string to pass to the modsManager as to ask it to enable said mods
        String[] requiredMods = new String[requiredMd5s.size()];
        int i = 0;
        for (String m : requiredMd5s) {
            requiredMods[i++] = "md5:" + m;
        }
        Client.getInstance().getContent().modsManager().setEnabledMods(requiredMods);
        status = new ConnectionStep("Reloading mods...");
        Client.getInstance().reloadAssets();
        status = new ConnectionStep("Loading ContentTranslator...");
        connection.sendTextMessage("world/translator");
        if (!translatorSemaphore.tryAcquire(5, TimeUnit.SECONDS))
            abort("Timed out waiting for content translator");
        // Ask the server world info and if allowed where to spawn and preload chunks
        connection.sendTextMessage("world/enter");
        if (!worldSemaphore.tryAcquire(15, TimeUnit.SECONDS))
            abort("Timed out waiting for world");
        status = new ConnectionStep("Loading world...");
        // TODO
        synchronized (this) {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        // We are good.
        isDone = true;
    } catch (AbortException e) {
        logger.info("Connection sequence aborted.");
    } catch (InterruptedException e1) {
        e1.printStackTrace();
    }
}
Also used : SimplePostRequest(io.xol.chunkstories.net.http.SimplePostRequest) ModZip(io.xol.chunkstories.content.mods.ModZip) ModLoadFailureException(io.xol.chunkstories.api.exceptions.content.mods.ModLoadFailureException) File(java.io.File) HashSet(java.util.HashSet)

Aggregations

ModLoadFailureException (io.xol.chunkstories.api.exceptions.content.mods.ModLoadFailureException)4 File (java.io.File)4 Mod (io.xol.chunkstories.api.content.mods.Mod)2 ModZip (io.xol.chunkstories.content.mods.ModZip)2 HashSet (java.util.HashSet)2 ModNotFoundException (io.xol.chunkstories.api.exceptions.content.mods.ModNotFoundException)1 NotAllModsLoadedException (io.xol.chunkstories.api.exceptions.content.mods.NotAllModsLoadedException)1 ModFolder (io.xol.chunkstories.content.mods.ModFolder)1 ForeignCodeClassLoader (io.xol.chunkstories.content.sandbox.ForeignCodeClassLoader)1 ModItem (io.xol.chunkstories.gui.layer.config.ModsSelection.ModsScrollableContainer.ModItem)1 SimplePostRequest (io.xol.chunkstories.net.http.SimplePostRequest)1 ArrayList (java.util.ArrayList)1