Untitled

mail@pastecode.io avatar
unknown
plain_text
a year ago
30 kB
5
Indexable
package com.zaros.cache;

import com.alex.store.Index;
import com.alex.store.Store;
import com.alex.utils.Constants;
import com.alex.utils.Utils;
import com.zaros.util.XteaRepository;
import com.zaros.world.region.RegionManager;
import org.apache.commons.lang3.tuple.Pair;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;
import java.util.zip.GZIPInputStream;

public final class CacheBuilder {

    private static final DecimalFormat format = new DecimalFormat("#.##");

    private static void fixNames() {
        for (File sprite : new File("sprites").listFiles()) {
            String name = sprite.getName();
            if (!name.matches("sprite_\\d+_0\\.png")) {
                continue;
            }
            name = name.substring("sprites_".length() - 1, name.length() - 6);
            sprite.renameTo(new File(sprite.getParentFile(), name + ".png"));
        }
    }

    public static void main(String[] args) throws IOException {
        Store cache = new Store("data/new_cache/");
        Store os_cache = new Store("data/new_cache/");
     //   Store cache = new Store("C://Users//austi//Documents//GitHub//PrimalV2//data//Zaros_Raw//");
     //      Store cache = new Store("data/Zaros_Raw/");

        //C:\Users\austi\Documents\GitHub\PrimalV2\data\zaros_raw
//        transport_index(os_cache, 7, cache, 4);
//        transport_index(os_cache, 2, cache, 13);
//        transport_index(os_cache, 0, cache, 17);
//        transport_index(os_cache, 1, cache, 18);
//        transport_dat(new File("G:\\test\\dump\\os_map_index.dat"), cache, 16);
 // transport_gzs("maps", cache, 10);
//        transport_flat_archive("anims_os", cache, 0);
//        transport_flat_archive("anims_667", cache, 1);
//        transport_flat_archive("anims_742", cache, 2);
//        transport_flat_archive("textures", cache, 3);
//        transport_flat_archive("models_os", cache, 4);
//        transport_flat_archive("models_667", cache, 5);
//        transport_flat_archive("models_718", cache, 6);
//        transport_flat_archive("urnmodels", cache, 21);
//        transport_flat_archive("textures_new", cache, 8);
    //    transport_flat_archive(new File("sprites"), cache, 9, "png");
      //  rs2_sprites(cache);
        transport_flat_archive("maps_os", cache, 10);
//        transport_flat_archive("maps_742", cache, 11);
//        transport_flat_archive("music", cache, 12);
//        transport_flat_groups("config-osrs", cache, 13);
//        transport_flat_groups("config-667", cache, 14);
//        transport_flat_groups("config-742", cache, 15);
     //   transport_dats("dat", cache, 16);
//        transport_textures(new File("C:\\Users\\Walied K. Yassen\\zaros_raw\\textures\\"), cache, 8);
    //    transport_flat_archive("models-custom", cache, 20);
     //    update_os_maps(cache, os_cache);

        //transport_maps(Path.of("./data/Zaros_Raw/maps/"), cache, 10);

        System.out.println("lenght: " + cache.getIndexes().length);
        System.out.println("table: " + cache.getIndexes()[10].getTable());
        System.out.println("id: " + cache.getIndexes()[10].getCRC());
        System.out.println("id: " + cache.getIndexes()[10].getKeys());
        System.out.println("size: " + cache.getIndexes()[10].getArchive(625).getId());
    }

    private static void update_os_maps(Store cache, Store os_cache) throws IOException {
        //   transport_index(os_cache, 5, cache, 10);
/*       transport_map(cache, 10, 0, 1, 6699);
        transport_map(cache, 10, 2, 3, 6698);
        transport_map(cache, 10, 4, 5, 6697);
        transport_map(cache, 10, 6, 7, 6700);//treasure*/



      /*  System.out.println("transport");
        transport_map(cache, 10, 144, 145, 12951);

        transport_maps(Path.of("./data/Zaros_Raw/maps/"), cache,10);
        System.out.println("123");*/


       /* transport_map(cache, 10, 8, 9, 6701);

        transport_map(cache, 10, 0, 1, 6697);
        transport_map(cache, 10, 6, 7, 6698);//treasure

        transport_map(cache, 10, 2, 3, 6441);
        transport_map(cache, 10, 6, 7, 6442);//treasure


        transport_map(cache, 10, 4, 5, 6185);
        transport_map(cache, 10, 6, 7, 6186);//treasure*/


        // transport_map(cache, 10, 1698, 1699, 12095); // wildy chest
        //transport_map(cache, 10, 624, 625, 12342); // home @ edge
    }

    private static void rs2_sprites(Store target_cache) throws IOException {
        Store rs2 = new Store("G:\\RSPS\\742\\cache\\");
        Set<Integer> ids = new HashSet<>(Arrays.asList(2184, 2954, 2955, 2956, 2957, 2958, 2959, 2960, 2961, 2834, 2962, 2835, 2963, 2836, 2964, 2965, 2837, 2838, 2966, 2839, 2967, 2840, 2968, 2841, 2842, 2843, 2844, 2989, 2864, 2869, 821, 2870, 822, 2871, 823, 2872, 2873, 2874, 826, 2875, 827, 2876, 2878, 831, 2879, 832, 2880, 2881, 1123, 1124, 1125, 3183, 2548, 2549, 2038, 2042, 2043));
        for (var i = 0; i < 47; i++) {
            ids.add(2787 + i);
        }
        ids.addAll(Arrays.asList(2866, 5471, 5474, 5475, 5476, 2205, 2206, 2184));
        ids.addAll(Arrays.asList(2866, 5471, 5474, 5475, 5476));// dung rewards
        ids.addAll(Arrays.asList(2944, 2945, 2946, 2947, 2953, 2834, 2835, 2836, 2842, 2843, 2844, 2989, 2864, 2869, 821, 2870, 822, 2871, 823, 2872, 2873, 2874, 826, 2875, 827, 2876, 831, 832, 2883, 2884, 2885, 2886, 2887, 2888, 2889, 2890, 2891, 2892, 2893, 2894, 2895, 2896, 2897, 2898, 2899, 2900, 2901, 2902, 2903, 2904, 2905, 2906, 2907, 2908, 2909, 2910, 2911, 2912, 2913, 2914, 1123, 2915, 1124, 2916, 1125, 2917, 2918, 2919, 2920, 2921, 2922, 2923, 2924, 2925, 2926, 2927, 2928, 2929, 2930, 2931, 2932, 2933, 2934, 2935, 2936, 3064, 2937, 2938, 2939, 2940, 2941, 2942, 2943));// dung floor selection
        ids.addAll(Arrays.asList(160, 161, 162, 163, 164, 165, 166, 297, 841, 170, 820, 821, 822, 823, 824, 825, 826, 827, 828, 156, 157, 158, 159));
        ids.addAll(Arrays.asList(777, 2834, 2835, 2837, 2838, 1175, 2839, 2840, 2841, 2842, 2849, 2850, 2851, 2853, 2854, 2855, 2989, 2861, 2862, 2863, 821, 2869, 3893, 822, 2870, 3894, 823, 2871, 3895, 2872, 3896, 2873, 3897, 826, 2874, 3898, 827, 2875, 3899, 2876, 3900, 3901, 3005, 3006, 3902, 3007, 3008, 1732, 2526, 1123, 1124, 1125, 1767, 3055, 3063, 1148, 1533, 1535));

        String[] names = {"scrollbar_v2", "scrollbar_dragger_v2", "v2_stone_button_in", "v2_stone_button", "v2_stone_close_button", "headicons_prayer"};
        for (String name : names) {
            int id = rs2.getIndexes()[8].getArchiveId(name);
            if (id != -1) {
                ids.add(id);
            }

            for (int i = 0; i < 100; i++) {
                String combined = name + "," + i;
                id = rs2.getIndexes()[8].getArchiveId(combined);
                if (id != -1) {
                    ids.add(id);
                }
            }
        }
        ensure_exists(target_cache, 19);
        for (int spriteId : ids) {
            byte[] data = rs2.getIndexes()[8].getFile(spriteId, 0);
            if (data == null) {
                continue;
            }
            int originalName = rs2.getIndexes()[8].getTable().getArchives()[spriteId].getNameHash();
            target_cache.getIndexes()[19].putFile(spriteId, 0, Constants.GZIP_COMPRESSION, data, null, false, true, originalName, -1);
        }
        target_cache.getIndexes()[19].rewriteTable();
    }

    private static void transport_map(Store target_cache, int target_id, int mapId, int locId, int regionId) throws IOException {
        final var folder = Paths.get("maps");
        if (XteaRepository.getCached().isEmpty()) {
            XteaRepository.initialise();
        }
        int regionx = regionId >> 8;
        int regiony = regionId & 0xff;
        byte[] mapData = Files.readAllBytes(folder.resolve(mapId + ".dat"));
        byte[] locData = Files.readAllBytes(folder.resolve(locId + ".dat"));

        mapId = target_cache.getIndexes()[target_id].getArchiveId("m" + regionx + "_" + regiony);
        if (mapId == -1) {
            mapId = target_cache.getIndexes()[target_id].getLastArchiveId() + 1;
        }
        locId = target_cache.getIndexes()[target_id].getArchiveId("l" + regionx + "_" + regiony);
        if (locId == -1) {
            locId = target_cache.getIndexes()[target_id].getLastArchiveId() + 2;
        }
        int[] xteas = XteaRepository.get(regionId);
        target_cache.getIndexes()[target_id].putFile(mapId, 0, Constants.GZIP_COMPRESSION, mapData, null, false, false, target_cache.getIndexes()[target_id].getTable().getArchives()[mapId].getNameHash(), -1);
        target_cache.getIndexes()[target_id].putFile(locId, 0, Constants.GZIP_COMPRESSION, locData, xteas, false, false, target_cache.getIndexes()[target_id].getTable().getArchives()[locId].getNameHash(), -1);
        target_cache.getIndexes()[target_id].rewriteTable();

    }

    private static void transport_maps(Path folder, Store target_cache, int target_id) throws IOException {
        RegionManager.MapIndex mapIndex = RegionManager.MapIndex.load(target_cache.getIndexes()[10]);
        XteaRepository.initialise();
        List<Integer> fileIds = Files.list(folder).filter(path -> path.getFileName().toString().matches("\\d+\\.dat")).map(path -> {
            String name = path.getFileName().toString();
            return Integer.parseInt(name.substring(0, name.length() - 4));
        }).sorted().collect(Collectors.toList());
        while (!fileIds.isEmpty()) {
            Integer mapId = fileIds.get(0);
            Integer locId = null;
            Integer regionId = null;
            for (Map.Entry<Integer, Pair<Integer, Integer>> entry : mapIndex.getMaps().entrySet()) {
                regionId = entry.getKey();
                if (entry.getValue().getLeft().equals(mapId)) {
                    // mapId = left
                    // locId = right
                    locId = entry.getValue().getRight();
                    break;
                } else if (entry.getValue().getRight().equals(mapId)) {
                    // mapId = right
                    // locId = lef
                    Integer old = mapId;
                    mapId = entry.getValue().getLeft();
                    locId = old;
                    break;
                }
            }
            if (locId == null) {
                fileIds.remove(mapId);
                System.out.println("Failed to find the original id of: " + mapId);
                continue;
            }
            if (!fileIds.remove(mapId) || !fileIds.remove(locId)) {
                System.out.println("Failed to map the original id of: " + mapId);
                continue;
            }
            byte[] mapData = Files.readAllBytes(folder.resolve(mapId + ".dat"));
            byte[] locData = Files.readAllBytes(folder.resolve(locId + ".dat"));
            int[] xteas = XteaRepository.get(regionId);
            target_cache.getIndexes()[target_id].putFile(mapId, 0, Constants.GZIP_COMPRESSION, mapData, null, false, false, target_cache.getIndexes()[target_id].getTable().getArchives()[mapId].getNameHash(), -1);
            target_cache.getIndexes()[target_id].putFile(locId, 0, Constants.GZIP_COMPRESSION, locData, xteas, false, false, target_cache.getIndexes()[target_id].getTable().getArchives()[locId].getNameHash(), -1);
        }
        target_cache.getIndexes()[target_id].rewriteTable();
    }

    private static void ensure_exists(Store target_cache, int target_id) throws IOException {
        if (target_cache.getIndexes().length <= target_id) {
            if (target_cache.getIndexes().length != target_id) {
                throw new IllegalStateException("The cache has more than one gap between the source_index and the target_index!");
            }
            target_cache.addIndex(true, false, Constants.GZIP_COMPRESSION);
            System.out.println("\t ^ Index was created!");
        }
    }

    private static void transport_textures(File source_folder, Store target_cache, int target_id) throws IOException {
        System.out.println("Attempting to transport index from source id of " + source_folder + " and target id of " + target_id);
        if (target_cache.getIndexes().length <= target_id) {
            if (target_cache.getIndexes().length != target_id) {
                throw new IllegalStateException("The cache has more than one gap between the source_index and the target_index!");
            }
            target_cache.addIndex(true, false, Constants.GZIP_COMPRESSION);
            System.out.println("\t ^ Index was created!");
        }
        Index target_index = target_cache.getIndexes()[target_id];
        List<Path> paths = Files.list(source_folder.toPath()).collect(Collectors.toList());
        System.out.println("\t ^ Attempting to pack: " + paths.size());
        paths.forEach(path -> {
            if (!Files.isRegularFile(path)) {
                return;
            }
            String name = path.getFileName().toString();
            if (!name.endsWith(".png")) {
                return;
            }
            byte[] data;
            try {
                data = Files.readAllBytes(path);
            } catch (IOException e) {
                e.printStackTrace();
                return;
            }
            try {
                BufferedImage image = ImageIO.read(new ByteArrayInputStream(data));
                try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
                    try (DataOutputStream dos = new DataOutputStream(bos)) {
                        dos.writeShort(image.getWidth());
                        dos.writeShort(image.getHeight());
                        for (int y = 0; y < image.getHeight(); y++) {
                            for (int x = 0; x < image.getWidth(); x++) {
                                int rgb = image.getRGB(x, y);
                                dos.writeShort(rgb >> 8);
                                dos.writeByte(rgb & 0xff);
                            }
                        }
                        dos.flush();
                        bos.flush();
                        target_index.putFile(Integer.parseInt(name.substring(0, name.length() - 4)), 0, Constants.GZIP_COMPRESSION, bos.toByteArray(), null, false, true, -1, -1);
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
        System.out.println("\t ^ Rewriting table..");
        target_index.rewriteTable();
        System.out.println("\t ^ Finished!");
        System.out.println();
    }

    private static void transport_index(Store source_cache, int source_id, Store target_cache, int target_id) throws
            IOException {
        System.out.println("Attempting to transport index from source id of " + source_id + " and target id of " + target_id);
        Index source_index = source_cache.getIndexes()[source_id];
        if (target_cache.getIndexes().length <= target_id) {
            if (target_cache.getIndexes().length != target_id) {
                throw new IllegalStateException("The cache has more than one gap between the source_index and the target_index!");
            }
            target_cache.addIndex(source_index.getTable().isNamed(), source_index.getTable().usesWhirpool(), Constants.GZIP_COMPRESSION);
            System.out.println("\t ^ Index was created!");
        }

        Index target_index = target_cache.getIndexes()[target_id];
        int num_groups = source_index.getLastArchiveId() + 1;
        System.out.println("\t ^ Attempting to pack " + num_groups + " group(s)..");

        double last = 0.0D;
        for (int group_id = 0; group_id < num_groups; group_id++) {
            if (source_index.archiveExists(group_id)) {
                target_index.putArchive(source_id, group_id, source_cache, false, true);
                double percentage = (double) group_id / (double) num_groups * 100D;
                if (group_id == num_groups - 1 || percentage - last >= 1.0D) {
                    System.out.println("\t ^ Percentage Completed: " + format.format(percentage) + "%");
                    last = percentage;
                }
            }
        }
        System.out.println("\t ^ Rewriting table..");
        target_index.rewriteTable();
        System.out.println("\t ^ Finished!");
        System.out.println();
    }

    private static void transport_dat(File source_file, Store target_cache, int target_id) throws IOException {
        System.out.println("Attempting to transport index from source id of " + source_file + " and target id of " + target_id);
        if (target_cache.getIndexes().length <= target_id) {
            if (target_cache.getIndexes().length != target_id) {
                throw new IllegalStateException("The cache has more than one gap between the source_index and the target_index!");
            }
            target_cache.addIndex(true, false, Constants.GZIP_COMPRESSION);
            System.out.println("\t ^ Index was created!");
        }
        Index target_index = target_cache.getIndexes()[target_id];
        if (!target_index.getTable().isNamed()) {
            target_index.getTable().setNamed(true);
            System.out.println("\t ^ Forced naming");
        }
        Path path = source_file.toPath();
        if (!Files.isRegularFile(path)) {
            return;
        }
        String name = path.getFileName().toString();
        byte[] data;
        try {
            data = Files.readAllBytes(path);
        } catch (IOException e) {
            e.printStackTrace();
            return;
        }
        int archiveId = target_index.getArchiveId(name);
        if (archiveId == -1) {
            archiveId = target_index.getLastArchiveId() + 1;
        }
        target_index.putFile(archiveId, 0, Constants.GZIP_COMPRESSION, data, null, false, true, Utils.getNameHash(name), Utils.getNameHash(""));

        System.out.println("\t ^ Rewriting table..");
        target_index.rewriteTable();
        System.out.println("\t ^ Finished!");
        System.out.println();
    }

    private static void transport_gzs(String source_folder, Store target_cache, int target_id) throws IOException {
        transport_gzs(new File("./data/Zaros_Raw/dump/" + source_folder + "\\"), target_cache, target_id);
    }

    private static void transport_gzs(File source_folder, Store target_cache, int target_id) throws IOException {
        System.out.println("Attempting to transport index from source id of " + source_folder + " and target id of " + target_id);
        if (target_cache.getIndexes().length <= target_id) {
            if (target_cache.getIndexes().length != target_id) {
                throw new IllegalStateException("The cache has more than one gap between the source_index and the target_index!");
            }
            System.out.println("here : ");
            target_cache.addIndex(true, false, Constants.GZIP_COMPRESSION);
            System.out.println("\t ^ Index was created!");
        }
        Index target_index = target_cache.getIndexes()[target_id];
        if (!target_index.getTable().isNamed()) {
            target_index.getTable().setNamed(true);
            System.out.println("\t ^ Forced naming");
        }
        List<Path> paths = Files.list(source_folder.toPath()).collect(Collectors.toList());
        System.out.println("\t ^ Attempting to pack: " + paths.size());
        paths.forEach(path -> {
            if (!Files.isRegularFile(path) || !path.toString().endsWith(".gz")) {
                return;
            }
            String name = path.getFileName().toString();
            name = name.substring(0, name.length() - 3);
            byte[] data;
            try {
                data = tryUngzip(Files.readAllBytes(path));
            } catch (IOException e) {
                e.printStackTrace();
                return;
            }


            int archiveId = Integer.parseInt(name);/*target_index.getArchiveId(name);
            if (archiveId == -1) {
                archiveId = target_index.getLastArchiveId() + 1;
            }*/
            System.out.println("put file : " + data);
            System.out.println("archiveId : " + archiveId);

            target_index.putFile(archiveId, 0, Constants.GZIP_COMPRESSION, data,
                    null, false, true, Utils.getNameHash(name), Utils.getNameHash(""));
        });
        System.out.println("\t ^ Rewriting table..");
        target_index.rewriteTable();
        System.out.println("\t ^ Finished!");
        System.out.println();
    }

    private static void transport_dats(String source_folder, Store target_cache, int target_id) throws IOException {
        transport_dats(new File(".\\data\\zaros_raw\\" + source_folder + "\\"), target_cache, target_id);
    }

    private static void transport_dats(File source_folder, Store target_cache, int target_id) throws IOException {
        System.out.println("Attempting to transport index from source id of " + source_folder + " and target id of " + target_id);
        if (target_cache.getIndexes().length <= target_id) {
            if (target_cache.getIndexes().length != target_id) {
                throw new IllegalStateException("The cache has more than one gap between the source_index and the target_index!");
            }
            target_cache.addIndex(true, false, Constants.GZIP_COMPRESSION);
            System.out.println("\t ^ Index was created!");
        }
        Index target_index = target_cache.getIndexes()[target_id];
        if (!target_index.getTable().isNamed()) {
            target_index.getTable().setNamed(true);
            System.out.println("\t ^ Forced naming");
        }
        List<Path> paths = Files.list(source_folder.toPath()).collect(Collectors.toList());
        System.out.println("\t ^ Attempting to pack: " + paths.size());
        paths.forEach(path -> {
            if (!Files.isRegularFile(path)) {
                return;
            }
            String name = path.getFileName().toString();
            byte[] data;
            try {
                data = Files.readAllBytes(path);
            } catch (IOException e) {
                e.printStackTrace();
                return;
            }
            int archiveId = target_index.getArchiveId(name);
            if (archiveId == -1) {
                archiveId = target_index.getLastArchiveId() + 1;
            }
            target_index.putFile(archiveId, 0, Constants.GZIP_COMPRESSION, data, null, false, true, Utils.getNameHash(name), Utils.getNameHash(""));
        });
        System.out.println("\t ^ Rewriting table..");
        target_index.rewriteTable();
        System.out.println("\t ^ Finished!");
        System.out.println();
    }

    private static void transport_flat_groups(String source_folder, Store target_cache, int target_id) throws
            IOException {
        transport_flat_groups(new File("C:\\Users\\Walied K. Yassen\\IdeaProjects\\novite_server\\data\\Zaros_Raw\\" + source_folder + "\\"), target_cache, target_id);
    }

    private static void transport_flat_groups(File source_folder, Store target_cache, int target_id) throws
            IOException {
        System.out.println("Attempting to transport index from source id of " + source_folder + " and target id of " + target_id);
        if (target_cache.getIndexes().length <= target_id) {
            if (target_cache.getIndexes().length != target_id) {
                throw new IllegalStateException("The cache has more than one gap between the source_index and the target_index!");
            }
            target_cache.addIndex(false, false, Constants.GZIP_COMPRESSION);
            System.out.println("\t ^ Index was created!");
        }
        Index target_index = target_cache.getIndexes()[target_id];
        List<Path> paths = Files.list(source_folder.toPath()).collect(Collectors.toList());
        System.out.println("\t ^ Attempting to pack: " + paths.size());
        paths.forEach(groupPath -> {
            if (!Files.isDirectory(groupPath)) {
                return;
            }
            String groupName = groupPath.getFileName().toString();
            if (!groupName.matches("[0-9]+")) {
                return;
            }
            int groupId;
            try {
                groupId = Integer.parseInt(groupName);
            } catch (NumberFormatException e) {
                e.printStackTrace();
                return;
            }
            FilePacker groupPacker = new FilePacker(target_index, groupId);
            try {
                Files.list(groupPath).forEach(filePath -> {
                    if (!Files.isRegularFile(filePath)) {
                        return;
                    }
                    String fileName = filePath.getFileName().toString();
                    if (!fileName.matches("[0-9]+\\.dat")) {
                        return;
                    }
                    int fileId;
                    try {
                        fileId = Integer.parseInt(fileName.substring(0, fileName.length() - 4));
                    } catch (NumberFormatException e) {
                        e.printStackTrace();
                        return;
                    }
                    byte[] data;
                    try {
                        data = Files.readAllBytes(filePath);
                    } catch (IOException e) {
                        e.printStackTrace();
                        return;
                    }
                    groupPacker.put(fileId, data);
                });
            } catch (IOException e) {
                e.printStackTrace();
            }
            groupPacker.pack();
        });
        System.out.println("\t ^ Finished!");
        System.out.println();
    }

    private static void transport_flat_archive(String source_folder, Store target_cache, int target_id) throws
            IOException {
        transport_flat_archive(new File("./data/Zaros_Raw/" + source_folder + "/"), target_cache, target_id, "dat");
    }


    private static void transport_flat_archive(File source_folder, Store target_cache, int target_id, String
            extension) throws IOException {
        System.out.println("Attempting to transport index from source id of " + source_folder + " and target id of " + target_id);
        if (target_cache.getIndexes().length <= target_id) {
            if (target_cache.getIndexes().length != target_id) {
                throw new IllegalStateException("The cache has more than one gap between the source_index and the target_index!");
            }
            target_cache.addIndex(false, false, Constants.GZIP_COMPRESSION);
            System.out.println("\t ^ Index was created!");
        }
        Index target_index = target_cache.getIndexes()[target_id];
        List<Path> paths = Files.list(source_folder.toPath()).collect(Collectors.toList());
        System.out.println("\t ^ Attempting to pack: " + paths.size());
        paths.forEach(path -> {
            if (!Files.isRegularFile(path)) {
                return;
            }
            String name = path.getFileName().toString();
            if (!name.matches("[0-9]+\\." + extension)) {
                return;
            }
            int id;
            try {
                id = Integer.parseInt(name.substring(0, name.length() - 4));
            } catch (NumberFormatException e) {
                e.printStackTrace();
                return;
            }
            byte[] data;
            try {
                data = Files.readAllBytes(path);
            } catch (IOException e) {
                e.printStackTrace();
                return;
            }
            if (Arrays.equals(data, target_index.getFile(id, 0))) {
                return;
            }
            int archiveName = -1;
            int fileName = -1;
            if (target_index.archiveExists(id)) {
                archiveName = target_index.getTable().getArchives()[id].getNameHash();
                fileName = target_index.getTable().getArchives()[id].getFiles()[0].getNameHash();
            }
            target_index.putFile(id, 0, Constants.GZIP_COMPRESSION, data, null, false, true, archiveName, fileName);
        });
        System.out.println("\t ^ Rewriting table..");
        target_index.rewriteTable();
        System.out.println("\t ^ Finished!");
        System.out.println();
    }

    private static byte[] tryUngzip(byte[] gzip) throws IOException {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        try (GZIPInputStream in = new GZIPInputStream(new ByteArrayInputStream(gzip))) {
            byte[] buffer = new byte[1024];
            do {
                int numRead = in.read(buffer, 0, buffer.length);
                if (numRead == -1) {
                    break;
                }
                out.write(buffer, 0, numRead);
            } while (true);
        }
        return out.toByteArray();
    }
}