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

wurstscript / WurstScript / 204

19 Oct 2023 11:41AM CUT coverage: 63.756% (-0.002%) from 63.758%
204

push

circleci

Frotty
fix JHCR war3map.j file handling

17246 of 27050 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
        result.script = compiledScript;
×
42
        try (MpqEditor mpq = MpqEditorFactory.getEditor(Optional.of(targetMap))) {
×
43
            byte[] scriptBytes;
44
            if (!projectConfig.getBuildMapData().getName().isEmpty()) {
×
45
                result.script = new File(buildDir, "war3mapj_with_config.j.txt");
×
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
                Files.write(scriptBytes, result.script);
×
73
            }
74

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

89
        } catch (Exception e) {
×
90
            throw new RuntimeException(e);
×
91
        }
×
92

93
        applyMapHeader(projectConfig, targetMap);
×
94

95
        return result;
×
96
    }
97

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

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

117
        return w3I;
×
118
    }
119

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

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

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

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

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

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

181
            old.ifPresent(player1 -> applyExistingPlayerConfig(player1, player));
×
182

183
            setVolatilePlayerConfig(wplayer, player);
×
184
        }
×
185
    }
×
186

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

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

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

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