• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

wurstscript / WurstScript / 195

09 Oct 2023 10:08PM UTC coverage: 63.447% (+0.006%) from 63.441%
195

Pull #1079

circleci

Frotty
small performance fixes
Pull Request #1079: small performance fixes

17146 of 27024 relevant lines covered (63.45%)

0.63 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
de.peeeq.wurstscript/src/main/java/de/peeeq/wurstio/map/importer/ImportFile.java
1
package de.peeeq.wurstio.map.importer;
2

3
import com.google.common.io.Files;
4
import com.google.common.io.LittleEndianDataInputStream;
5
import de.peeeq.wurstio.mpq.MpqEditor;
6
import de.peeeq.wurstio.mpq.MpqEditorFactory;
7
import de.peeeq.wurstscript.RunArgs;
8
import de.peeeq.wurstscript.WLogger;
9
import de.peeeq.wurstscript.utils.TempDir;
10

11
import javax.swing.*;
12
import java.io.*;
13
import java.nio.ByteBuffer;
14
import java.nio.ByteOrder;
15
import java.nio.charset.StandardCharsets;
16
import java.nio.file.Path;
17
import java.util.*;
18
import java.util.stream.Collectors;
19
import java.util.stream.Stream;
20

21
public class ImportFile {
×
22
    private static final String DEFAULT_IMPORT_PATH = "war3mapImported\\";
23
    private static final int FILE_VERSION = 1;
24

25
    /**
26
     * Use this to start the extraction process
27
     */
28
    public static void extractImportsFromMap(File mapFile, RunArgs runArgs) {
29
        WLogger.info("Extracting all imported Files...");
×
30
        if (!mapFile.exists() || !mapFile.isFile() || mapFile.getName().endsWith("w3m")) {
×
31
            JOptionPane.showMessageDialog(null, "Map " + mapFile.getAbsolutePath() + " does not exist or is of wrong format (w3x only)");
×
32
            return;
×
33
        }
34

35
        try {
36
            File projectFolder = mapFile.getParentFile();
×
37
            File importDirectory = getImportDirectory(projectFolder);
×
38
            File tempMap = getCopyOfMap(mapFile);
×
39

40
            extractImportsFrom(importDirectory, tempMap, runArgs);
×
41
        } catch (Exception e) {
×
42
            WLogger.severe(e);
×
43
            JOptionPane.showMessageDialog(null, "Could not export objects (2): " + e.getMessage());
×
44
        }
×
45
    }
×
46

47
    private static void extractImportsFrom(File importDirectory, File tempMap, RunArgs runArgs) throws Exception {
48
        try (MpqEditor editor = MpqEditorFactory.getEditor(Optional.of(tempMap))) {
×
49
            LinkedList<String> failed = extractImportedFiles(editor, importDirectory);
×
50

51
            if (failed.isEmpty()) {
×
52
                JOptionPane.showMessageDialog(null, "All imports were extracted to " + importDirectory.getAbsolutePath());
×
53
            } else {
54
                String message = "Following files could not be extracted:\n" + String.join(",", failed);
×
55
                WLogger.info(message);
×
56
                JOptionPane.showMessageDialog(null, message);
×
57
            }
58
        }
59
    }
×
60

61
    private static LinkedList<String> extractImportedFiles(MpqEditor mpq, File directory) {
62
        LinkedList<String> failed = new LinkedList<>();
×
63
        byte[] temp;
64
        try {
65
            temp = mpq.extractFile("war3map.imp");
×
66
        } catch (Exception e1) {
×
67
            JOptionPane.showMessageDialog(null, "No vaild war3map.imp was found, or there are no imports");
×
68
            return failed;
×
69
        }
×
70
        try (LittleEndianDataInputStream reader = new LittleEndianDataInputStream(new ByteArrayInputStream(temp))) {
×
71
            @SuppressWarnings("unused")
72
            int fileFormatVersion = reader.readInt(); // Not needed
×
73
            int fileCount = reader.readInt();
×
74
            WLogger.info("Imported FileCount: " + fileCount);
×
75

76
            for (int i = 1; i <= fileCount; i++) {
×
77
                extractImportedFile(mpq, directory, failed, reader);
×
78
            }
79

80
            return failed;
×
81
        } catch (Exception e) {
×
82
            throw new RuntimeException(e);
×
83
        }
84
    }
85

86
    private static void extractImportedFile(MpqEditor mpq, File directory, LinkedList<String> failed, LittleEndianDataInputStream reader) throws Exception {
87
        byte b = reader.readByte();
×
88
        String path = directory.getPath() + "\\";
×
89
        String mpqpath = "";
×
90
        if (isStandardPath(b)) {
×
91
            path += DEFAULT_IMPORT_PATH;
×
92
            mpqpath += DEFAULT_IMPORT_PATH;
×
93
        }
94

95
        String filename = readString(reader);
×
96
        WLogger.info("Extracting file: " + filename);
×
97

98
        filename = filename.trim();
×
99
        mpqpath += filename;
×
100
        path += filename;
×
101

102
        extractFile(mpq, directory, failed, path, mpqpath, filename);
×
103
    }
×
104

105
    private static void extractFile(MpqEditor mpq, File directory, LinkedList<String> failed, String path, String mpqpath, String filename) throws Exception {
106
        File out = new File(path);
×
107
        out.getParentFile().mkdirs();
×
108
        try {
109
            byte[] xx = mpq.extractFile(mpqpath);
×
110
            Files.write(xx, out);
×
111
        } catch (IOException e) {
×
112
            out.delete();
×
113
            out = new File(directory.getPath() + "\\" + DEFAULT_IMPORT_PATH + filename);
×
114
            out.getParentFile().mkdirs();
×
115
            try {
116
                byte[] xx = mpq.extractFile(DEFAULT_IMPORT_PATH + mpqpath);
×
117
                Files.write(xx, out);
×
118
            } catch (IOException e1) {
×
119
                failed.add(mpqpath);
×
120
            }
×
121
        }
×
122
    }
×
123

124
    /**
125
     * Blizzard magic numbers for standard path
126
     */
127
    private static boolean isStandardPath(byte b) {
128
        return b == 5 || b == 8;
×
129
    }
130

131
    /**
132
     * Reads chars from the inputstream until it hits a 0-char
133
     */
134
    private static String readString(LittleEndianDataInputStream reader) throws IOException {
135
        StringBuilder sb = new StringBuilder();
×
136
        try {
137
            while (true) {
138
                char c = (char) reader.readByte();
×
139
                if (c == 0) {
×
140
                    return sb.toString();
×
141
                }
142
                sb.append(c);
×
143
            }
×
144
        } catch (EOFException e) {
×
145
            return sb.toString();
×
146
        }
147
    }
148

149
    private static LinkedList<File> getFilesOfDirectory(File dir, LinkedList<File> addTo) {
150
        for (File f : dir.listFiles()) {
×
151
            if (f.isDirectory()) {
×
152
                getFilesOfDirectory(f, addTo);
×
153
            } else {
154
                addTo.add(f);
×
155
            }
156
        }
157
        return addTo;
×
158

159
    }
160

161
    private static void insertImportedFiles(MpqEditor mpq, List<File> directories) throws Exception {
162
        for (File directory : directories) {
×
163
            LinkedList<File> files = new LinkedList<>();
×
164
            getFilesOfDirectory(directory, files);
×
165

166
            ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
×
167
            DataOutputStream dataOut = new DataOutputStream(byteOut);
×
168
            dataOut.write(ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(FILE_VERSION).array());
×
169
            dataOut.write(ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(files.size()).array());
×
170
            for (File f : files) {
×
171
                Path p = f.toPath();
×
172
                p = directory.toPath().relativize(p);
×
173
                String normalizedWc3Path = p.toString().replaceAll("/", "\\\\");
×
174
                dataOut.writeByte((byte) 13);
×
175
                dataOut.write(normalizedWc3Path.getBytes(StandardCharsets.UTF_8));
×
176
                dataOut.write((byte) 0);
×
177
                mpq.deleteFile(normalizedWc3Path);
×
178
                mpq.insertFile(normalizedWc3Path, f);
×
179
            }
×
180
            dataOut.flush();
×
181
            mpq.deleteFile("war3map.imp");
×
182
            mpq.insertFile("war3map.imp", byteOut.toByteArray());
×
183
        }
×
184
    }
×
185

186
    public static void importFilesFromImports(File projectFolder, MpqEditor ed) {
187
        LinkedList<File> folders = new LinkedList<>();
×
188
        folders.add(getImportDirectory(projectFolder));
×
189
        folders.addAll(Arrays.asList(getTransientImportDirectories(projectFolder)));
×
190

191
        folders.removeIf(folder -> !folder.exists());
×
192

193
        try {
194
            insertImportedFiles(ed, folders);
×
195
        } catch (Exception e) {
×
196
            WLogger.severe(e);
×
197
            JOptionPane.showMessageDialog(null, "Couldn't import resources. " + e.getMessage());
×
198
        }
×
199

200
    }
×
201

202
    private static File getCopyOfMap(File mapFile) throws IOException {
203
        File mapTemp = File.createTempFile("temp", "w3x", TempDir.get());
×
204
        mapTemp.deleteOnExit();
×
205
        Files.copy(mapFile, mapTemp);
×
206
        return mapTemp;
×
207
    }
208

209
    private static File getImportDirectory(File projectFolder) {
210
        return new File(projectFolder, "imports");
×
211
    }
212

213
    private static File[] getTransientImportDirectories(File projectFolder) {
214
        ArrayList<Path> paths = new ArrayList<>();
×
215
        Path dependencies = projectFolder.toPath().resolve("_build").resolve("dependencies");
×
216
        try (Stream<Path> spaths = java.nio.file.Files.list(dependencies)) {
×
217
            spaths.forEach(dependency -> {
×
218
                if (java.nio.file.Files.exists(dependency.resolve("imports"))) {
×
219
                    paths.add(dependency.resolve("imports"));
×
220
                }
221
            });
×
222
        } catch (IOException e) {
×
223
            e.printStackTrace();
×
224
        }
×
225
        File[] arr = new File[paths.size()];
×
226
        return paths.stream().map(Path::toFile).collect(Collectors.toList()).toArray(arr);
×
227
    }
228

229
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc