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

wurstscript / WurstScript / 203

18 Oct 2023 02:20PM UTC coverage: 63.758% (+0.3%) from 63.447%
203

push

circleci

web-flow
Update deps, improve performance, JHCR fixes (#1080)

- update dependencies
- update stdlib verison for unit tests
- only apply nullsetting when `-opt` is enabled to save some build time for testing
- minor performance improvements
- make build deterministic
- apply build map config before compilation
- hot code reload now more reliable

17246 of 27049 relevant lines covered (63.76%)

0.64 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/languageserver/ProjectConfigBuilder.java
1
package de.peeeq.wurstio.languageserver;
2

3
import com.google.common.io.Files;
4
import config.*;
5
import de.peeeq.wurstio.languageserver.requests.MapRequest;
6
import de.peeeq.wurstio.languageserver.requests.RequestFailedException;
7
import de.peeeq.wurstio.mpq.MpqEditor;
8
import de.peeeq.wurstio.mpq.MpqEditorFactory;
9
import de.peeeq.wurstio.utils.W3InstallationData;
10
import de.peeeq.wurstscript.RunArgs;
11
import net.moonlightflower.wc3libs.bin.app.MapFlag;
12
import net.moonlightflower.wc3libs.bin.app.MapHeader;
13
import net.moonlightflower.wc3libs.bin.app.W3I;
14
import net.moonlightflower.wc3libs.bin.app.W3I.Force;
15
import net.moonlightflower.wc3libs.bin.app.W3I.Player;
16
import net.moonlightflower.wc3libs.dataTypes.app.Controller;
17
import net.moonlightflower.wc3libs.dataTypes.app.LoadingScreenBackground;
18
import net.moonlightflower.wc3libs.port.GameVersion;
19
import org.apache.commons.lang.StringUtils;
20
import org.eclipse.lsp4j.MessageType;
21

22
import java.io.File;
23
import java.io.FileInputStream;
24
import java.io.IOException;
25
import java.io.StringWriter;
26
import java.nio.charset.StandardCharsets;
27
import java.util.ArrayList;
28
import java.util.List;
29
import java.util.Optional;
30

31
public class ProjectConfigBuilder {
×
32
    public static final String FILE_NAME = "wurst.build";
33

34
    public static MapRequest.CompilationResult apply(WurstProjectConfigData projectConfig, File targetMap, File compiledScript, File buildDir,
35
                                                     RunArgs runArgs, W3InstallationData w3data) throws IOException {
36
        if (projectConfig.getProjectName().isEmpty()) {
×
37
            throw new RequestFailedException(MessageType.Error, "wurst.build is missing projectName.");
×
38
        }
39

40
        MapRequest.CompilationResult result = new MapRequest.CompilationResult();
×
41

42
        try (MpqEditor mpq = MpqEditorFactory.getEditor(Optional.of(targetMap))) {
×
43
            result.script = new File(buildDir, "wa3mapj_with_config.j.txt");
×
44
            byte[] scriptBytes;
45
            if (!projectConfig.getBuildMapData().getName().isEmpty()) {
×
46
                // Apply w3i config values
47
                W3I w3I = prepareW3I(projectConfig, mpq);
×
48
                FileInputStream inputStream = new FileInputStream(compiledScript);
×
49
                StringWriter sw = new StringWriter();
×
50

51
                if (runArgs.isLua()) {
×
52
                    w3I.injectConfigsInLuaScript(inputStream, sw);
×
53
                } else {
54
                    if (w3data.getWc3PatchVersion().isPresent()) {
×
55
                        w3I.injectConfigsInJassScript(inputStream, sw, w3data.getWc3PatchVersion().get());
×
56
                    } else {
57
                        GameVersion version = GameVersion.VERSION_1_32;
×
58
                        System.out.println(
×
59
                            "Failed to determine installed game version. Falling back to " + version.toString()
×
60
                        );
61
                        w3I.injectConfigsInJassScript(inputStream, sw, version);
×
62
                    }
63
                }
64
                scriptBytes = sw.toString().getBytes(StandardCharsets.UTF_8);
×
65

66
                result.w3i = new File(buildDir, "war3map.w3i");
×
67
                if (runArgs.isLua()) {
×
68
                    w3I.setScriptLang(W3I.ScriptLang.LUA);
×
69
                    w3I.setFileVersion(W3I.EncodingFormat.W3I_0x1C.getVersion());
×
70
                }
71
                w3I.write(result.w3i);
×
72
            } else {
×
73
                scriptBytes = java.nio.file.Files.readAllBytes(compiledScript.toPath());
×
74
            }
75

76
            Files.write(scriptBytes, result.script);
×
77
//            if (!runArgs.isDisablePjass()) {
78
//                Pjass.runPjass(file, new File(buildDir, "common.j").getAbsolutePath(),
79
//                    new File(buildDir, "blizzard.j").getAbsolutePath());
80
//            }
81
//            String mapScriptName;
82
//            if (runArgs.isLua()) {
83
//                mapScriptName = "war3map.lua";
84
//            } else {
85
//                mapScriptName = "war3map.j";
86
//            }
87
//            mpq.deleteFile("war3map.lua");
88
//            mpq.deleteFile("war3map.j");
89
//            mpq.insertFile(mapScriptName, scriptBytes);
90

91
        } catch (Exception e) {
×
92
            throw new RuntimeException(e);
×
93
        }
×
94

95
        applyMapHeader(projectConfig, targetMap);
×
96

97
        return result;
×
98
    }
99

100
    private static W3I prepareW3I(WurstProjectConfigData projectConfig, MpqEditor mpq) throws Exception {
101
        W3I w3I = new W3I(mpq.extractFile("war3map.w3i"));
×
102
        WurstProjectBuildMapData buildMapData = projectConfig.getBuildMapData();
×
103
        if (StringUtils.isNotBlank(buildMapData.getName())) {
×
104
            w3I.setMapName(buildMapData.getName());
×
105
        }
106
        if (StringUtils.isNotBlank(buildMapData.getAuthor())) {
×
107
            w3I.setMapAuthor(buildMapData.getAuthor());
×
108
        }
109
        applyScenarioData(w3I, buildMapData);
×
110

111
        if (buildMapData.getPlayers().size() > 0) {
×
112
            applyPlayers(projectConfig, w3I);
×
113
        }
114
        if (buildMapData.getForces().size() > 0) {
×
115
            applyForces(projectConfig, w3I);
×
116
        }
117
        applyOptionFlags(projectConfig, w3I);
×
118

119
        return w3I;
×
120
    }
121

122
    private static void applyOptionFlags(WurstProjectConfigData projectConfig, W3I w3I) {
123
        WurstProjectBuildOptionFlagsData optionsFlags = projectConfig.getBuildMapData().getOptionsFlags();
×
124
        w3I.setFlag(MapFlag.HIDE_MINIMAP, optionsFlags.getForcesFixed() || w3I.getFlag(MapFlag.HIDE_MINIMAP));
×
125
        w3I.setFlag(MapFlag.FIXED_PLAYER_FORCE_SETTING, optionsFlags.getForcesFixed() || w3I.getFlag(MapFlag.FIXED_PLAYER_FORCE_SETTING));
×
126
        w3I.setFlag(MapFlag.MASKED_AREAS_PARTIALLY_VISIBLE, optionsFlags.getForcesFixed() || w3I.getFlag(MapFlag.MASKED_AREAS_PARTIALLY_VISIBLE));
×
127
        w3I.setFlag(MapFlag.SHOW_WATER_WAVES_ON_CLIFF_SHORES, optionsFlags.getShowWavesOnCliffShores() || w3I.getFlag(MapFlag.SHOW_WATER_WAVES_ON_CLIFF_SHORES));
×
128
        w3I.setFlag(MapFlag.SHOW_WATER_WAVES_ON_ROLLING_SHORES, optionsFlags.getShowWavesOnRollingShores() || w3I.getFlag(MapFlag.SHOW_WATER_WAVES_ON_ROLLING_SHORES));
×
129
    }
×
130

131
    private static void applyScenarioData(W3I w3I, WurstProjectBuildMapData buildMapData) {
132
        WurstProjectBuildScenarioData scenarioData = buildMapData.getScenarioData();
×
133
        if (StringUtils.isNotBlank(scenarioData.getSuggestedPlayers())) {
×
134
            w3I.setPlayersRecommendedAmount(scenarioData.getSuggestedPlayers());
×
135
        }
136
        if (StringUtils.isNotBlank(scenarioData.getDescription())) {
×
137
            w3I.setMapDescription(scenarioData.getDescription());
×
138
        }
139
        if (scenarioData.getLoadingScreen() != null) {
×
140
            applyLoadingScreen(w3I, scenarioData.getLoadingScreen());
×
141
        }
142
    }
×
143

144
    private static void applyLoadingScreen(W3I w3I, WurstProjectBuildLoadingScreenData loadingScreen) {
145
        if (StringUtils.isNotBlank(loadingScreen.getModel())) {
×
146
            w3I.getLoadingScreen().setBackground(new LoadingScreenBackground.CustomBackground(new File(loadingScreen.getModel())));
×
147
        } else {
148
            w3I.getLoadingScreen().setBackground(LoadingScreenBackground.PresetBackground.findByName(loadingScreen.getBackground()));
×
149
        }
150

151
        w3I.getLoadingScreen().setTitle(loadingScreen.getTitle());
×
152
        w3I.getLoadingScreen().setSubtitle(loadingScreen.getSubTitle());
×
153
        w3I.getLoadingScreen().setText(loadingScreen.getText());
×
154
    }
×
155

156
    private static void applyForces(WurstProjectConfigData projectConfig, W3I w3I) {
157
        w3I.clearForces();
×
158
        ArrayList<WurstProjectBuildForce> forces = projectConfig.getBuildMapData().getForces();
×
159
        for (WurstProjectBuildForce wforce : forces) {
×
160
            W3I.Force force = new Force();
×
161
            force.setName(wforce.getName());
×
162
            force.setFlag(W3I.Force.Flags.Flag.ALLIED, wforce.getFlags().getAllied());
×
163
            force.setFlag(W3I.Force.Flags.Flag.ALLIED_VICTORY, wforce.getFlags().getAlliedVictory());
×
164
            force.setFlag(W3I.Force.Flags.Flag.SHARED_VISION, wforce.getFlags().getSharedVision());
×
165
            force.setFlag(W3I.Force.Flags.Flag.SHARED_UNIT_CONTROL, wforce.getFlags().getSharedControl());
×
166
            force.setFlag(W3I.Force.Flags.Flag.SHARED_UNIT_CONTROL_ADVANCED, wforce.getFlags().getSharedControlAdvanced());
×
167
            force.addPlayerNums(wforce.getPlayerIds());
×
168
            w3I.addForce(force);
×
169
        }
×
170
        w3I.setFlag(MapFlag.USE_CUSTOM_FORCES, true);
×
171
    }
×
172

173
    private static void applyPlayers(WurstProjectConfigData projectConfig, W3I w3I) {
174
        List<W3I.Player> existing = new ArrayList<>(w3I.getPlayers());
×
175
        w3I.getPlayers().clear();
×
176
        ArrayList<WurstProjectBuildPlayer> players = projectConfig.getBuildMapData().getPlayers();
×
177
        for (WurstProjectBuildPlayer wplayer : players) {
×
178
            Optional<W3I.Player> old = existing.stream().filter(player -> player.getNum() == wplayer.getId()).findFirst();
×
179
            W3I.Player player = new Player();
×
180
            player.setNum(wplayer.getId());
×
181
            w3I.addPlayer(player);
×
182

183
            old.ifPresent(player1 -> applyExistingPlayerConfig(player1, player));
×
184

185
            setVolatilePlayerConfig(wplayer, player);
×
186
        }
×
187
    }
×
188

189
    private static void applyExistingPlayerConfig(W3I.Player oldPlayer, W3I.Player player) {
190
        player.setStartPos(oldPlayer.getStartPos());
×
191
        player.setName(oldPlayer.getName());
×
192
        player.setRace(oldPlayer.getRace());
×
193
        player.setType(oldPlayer.getType());
×
194
        player.setStartPosFixed(oldPlayer.getStartPosFixed());
×
195
        player.setAllyLowPrioFlags(oldPlayer.getAllyLowPrioFlags());
×
196
        player.setAllyHighPrioFlags(oldPlayer.getAllyHighPrioFlags());
×
197
    }
×
198

199
    private static void setVolatilePlayerConfig(WurstProjectBuildPlayer wplayer, W3I.Player player) {
200
        if (wplayer.getName() != null) {
×
201
            player.setName(wplayer.getName());
×
202
        }
203

204
        if (wplayer.getRace() != null) {
×
205
            W3I.Player.UnitRace val = W3I.Player.UnitRace.valueOf(wplayer.getRace().toString());
×
206
            if (val != null) {
×
207
                player.setRace(val);
×
208
            }
209
        }
210
        if (wplayer.getController() != null) {
×
211
            net.moonlightflower.wc3libs.dataTypes.app.Controller val1 = Controller.valueOf(wplayer.getController().toString());
×
212
            if (val1 != null) {
×
213
                player.setType(val1);
×
214
            }
215
        }
216
        if (wplayer.getFixedStartLoc() != null) {
×
217
            player.setStartPosFixed(wplayer.getFixedStartLoc() ? 1 : 0);
×
218
        }
219
    }
×
220

221
    private static void applyMapHeader(WurstProjectConfigData projectConfig, File targetMap) throws IOException {
222
        MapHeader mapHeader = MapHeader.ofFile(targetMap);
×
223
        if (projectConfig.getBuildMapData().getPlayers().size() > 0) {
×
224
            mapHeader.setMaxPlayersCount(projectConfig.getBuildMapData().getPlayers().size());
×
225
        }
226
        if (StringUtils.isNotBlank(projectConfig.getBuildMapData().getName())) {
×
227
            mapHeader.setMapName(projectConfig.getBuildMapData().getName());
×
228
        }
229
        mapHeader.writeToMapFile(targetMap);
×
230
    }
×
231
}
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