Skip to content
This repository was archived by the owner on Nov 9, 2025. It is now read-only.

Commit 7d40e66

Browse files
committed
inner-class symbol names chaining
1 parent f18bfef commit 7d40e66

File tree

10 files changed

+349
-150
lines changed

10 files changed

+349
-150
lines changed

common/src/main/java/org/screamingsandals/nms/generator/build/AccessorClassGenerator.java

Lines changed: 62 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -240,53 +240,71 @@ public void run() throws IOException {
240240
}
241241

242242
public CodeBlock generateMappings(ConfigurationNode node) {
243+
return generateMappings(List.of(node));
244+
}
245+
246+
public CodeBlock generateMappings(List<ConfigurationNode> nodes) {
243247
var codeBlock = CodeBlock.builder()
244248
.add("mapper -> {\n")
245249
.indent();
246250

247-
var obfuscatedFallback = node.node("OBFUSCATED")
248-
.childrenMap()
249-
.entrySet()
250-
.stream()
251-
.flatMap(entry -> Arrays.stream(entry.getKey().toString().split(",")).map(s1 -> Map.entry(s1, entry.getValue().getString(""))))
252-
.filter(stringStringEntry -> {
253-
if (
254-
(configuration.getMinMinecraftVersion() != null && !configuration.getMinMinecraftVersion().isEmpty())
255-
|| (configuration.getMaxMinecraftVersion() != null && !configuration.getMaxMinecraftVersion().isEmpty())
256-
) {
257-
var version = new ComparableVersion(stringStringEntry.getKey());
258-
if (configuration.getMinMinecraftVersion() != null && !configuration.getMinMinecraftVersion().isEmpty()) {
259-
var min = new ComparableVersion(configuration.getMinMinecraftVersion());
260-
if (version.compareTo(min) < 0) {
261-
return false;
262-
}
251+
var usedNode = new HashMap<String, ConfigurationNode>();
252+
var rawObfuscatedFallback = new HashMap<String, String>();
253+
nodes.forEach(node -> {
254+
node.node("OBFUSCATED")
255+
.childrenMap()
256+
.entrySet()
257+
.stream()
258+
.flatMap(entry -> Arrays.stream(entry.getKey().toString().split(",")).map(s1 -> Map.entry(s1, entry.getValue().getString(""))))
259+
.filter(stringStringEntry -> {
260+
if (rawObfuscatedFallback.containsKey(stringStringEntry.getKey())) {
261+
return false; // don't overwrite it
263262
}
264-
if (configuration.getMaxMinecraftVersion() != null && !configuration.getMaxMinecraftVersion().isEmpty()) {
265-
var max = new ComparableVersion(configuration.getMaxMinecraftVersion());
266-
if (version.compareTo(max) > 0) {
267-
return false;
263+
264+
if (
265+
(configuration.getMinMinecraftVersion() != null && !configuration.getMinMinecraftVersion().isEmpty())
266+
|| (configuration.getMaxMinecraftVersion() != null && !configuration.getMaxMinecraftVersion().isEmpty())
267+
) {
268+
var version = new ComparableVersion(stringStringEntry.getKey());
269+
if (configuration.getMinMinecraftVersion() != null && !configuration.getMinMinecraftVersion().isEmpty()) {
270+
var min = new ComparableVersion(configuration.getMinMinecraftVersion());
271+
if (version.compareTo(min) < 0) {
272+
return false;
273+
}
274+
}
275+
if (configuration.getMaxMinecraftVersion() != null && !configuration.getMaxMinecraftVersion().isEmpty()) {
276+
var max = new ComparableVersion(configuration.getMaxMinecraftVersion());
277+
if (version.compareTo(max) > 0) {
278+
return false;
279+
}
268280
}
269281
}
270-
}
271-
return true;
272-
})
282+
return true;
283+
})
284+
.forEach(e -> {
285+
rawObfuscatedFallback.put(e.getKey(), e.getValue());
286+
usedNode.put(e.getKey(), node);
287+
});
288+
});
289+
var obfuscatedFallback = rawObfuscatedFallback.entrySet()
290+
.stream()
273291
.sorted(Comparator.comparing(o -> new ComparableVersion(o.getKey())))
274292
.collect(Collectors.toList());
275293

294+
276295
// currently support spigot and searge. vanilla servers are not supported
277296
var spigotLatest = new AtomicReference<String>();
278297

279-
var allSpigotMappings = node.node("SPIGOT").childrenMap().entrySet()
280-
.stream()
281-
.flatMap(entry -> Arrays.stream(entry.getKey().toString().split(",")).map(s1 -> Map.entry(s1, entry.getValue().getString(""))))
282-
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
283-
284298
obfuscatedFallback.forEach(entry -> {
285-
var value = entry.getValue();
286-
287-
if (allSpigotMappings.containsKey(entry.getKey())) {
288-
value = allSpigotMappings.get(entry.getKey());
289-
}
299+
var value = usedNode.get(entry.getKey())
300+
.node("SPIGOT")
301+
.childrenMap()
302+
.entrySet()
303+
.stream()
304+
.filter(e -> Arrays.asList(e.getKey().toString().split(",")).contains(entry.getKey()))
305+
.findFirst()
306+
.map(e -> e.getValue().getString())
307+
.orElse(entry.getValue());
290308

291309
if (spigotLatest.get() == null || !spigotLatest.get().equals(value)) {
292310
codeBlock.add("$N.$N($S, $S, $S);\n", "mapper", "map", "spigot", entry.getKey(), value);
@@ -297,16 +315,19 @@ public CodeBlock generateMappings(ConfigurationNode node) {
297315

298316
var seargeLatest = new AtomicReference<String>();
299317

300-
var allSeargeMappings = node.node("SEARGE").childrenMap().entrySet()
301-
.stream()
302-
.flatMap(entry -> Arrays.stream(entry.getKey().toString().split(",")).map(s1 -> Map.entry(s1, entry.getValue().getString(""))))
303-
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
304-
305318
obfuscatedFallback.forEach(entry -> {
306319
var value = entry.getValue();
307-
308-
if (allSeargeMappings.containsKey(entry.getKey())) {
309-
value = allSeargeMappings.get(entry.getKey());
320+
var seargeValue = usedNode.get(entry.getKey())
321+
.node("SEARGE")
322+
.childrenMap()
323+
.entrySet()
324+
.stream()
325+
.filter(e -> Arrays.asList(e.getKey().toString().split(",")).contains(entry.getKey()))
326+
.findFirst()
327+
.map(e -> e.getValue().getString());
328+
329+
if (seargeValue.isPresent()) {
330+
value = seargeValue.get();
310331
} else if (seargeLatest.get() != null) {
311332
// Searge mappings are usually consistent across versions, so skip the mapping if there's no value in mappings but there's value in the seargeLatest variable
312333
return;

common/src/main/java/org/screamingsandals/nms/generator/configuration/NMSMapperConfiguration.java

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
import org.screamingsandals.nms.generator.utils.Action;
2525
import org.screamingsandals.nms.generator.utils.GroovyUtils;
2626

27+
import java.util.ArrayList;
28+
import java.util.List;
2729
import java.util.function.Consumer;
2830

2931
@Data
@@ -44,9 +46,9 @@ public RequiredClass reqClass(String unifiedString) {
4446
if (split.length == 1) {
4547
return reqClass(split[0], classContext.getDefaultMapping(), classContext.getDefaultForcedVersion());
4648
} else if (split.length == 2) {
47-
return reqClass(split[1], split[0], classContext.getDefaultForcedVersion());
49+
return reqClass(split[1], split[0].isBlank() ? classContext.getDefaultMapping() : split[0], classContext.getDefaultForcedVersion());
4850
} else if (split.length == 3) {
49-
return reqClass(split[1], split[0], split[2]);
51+
return reqClass(split[1], split[0].isBlank() ? classContext.getDefaultMapping() : split[0], split[2].isBlank() ? classContext.getDefaultForcedVersion() : split[2]);
5052
} else {
5153
throw new RuntimeException("Invalid configuration: Can't parse " + unifiedString);
5254
}
@@ -57,9 +59,9 @@ public RequiredClass reqClass(String unifiedString, Action<RequiredClass> consum
5759
if (split.length == 1) {
5860
return reqClass(split[0], classContext.getDefaultMapping(), classContext.getDefaultForcedVersion(), consumer);
5961
} else if (split.length == 2) {
60-
return reqClass(split[1], split[0], classContext.getDefaultForcedVersion(), consumer);
62+
return reqClass(split[1], split[0].isBlank() ? classContext.getDefaultMapping() : split[0], classContext.getDefaultForcedVersion(), consumer);
6163
} else if (split.length == 3) {
62-
return reqClass(split[1], split[0], split[2], consumer);
64+
return reqClass(split[1], split[0].isBlank() ? classContext.getDefaultMapping() : split[0], split[2].isBlank() ? classContext.getDefaultForcedVersion() : split[2], consumer);
6365
} else {
6466
throw new RuntimeException("Invalid configuration: Can't parse " + unifiedString);
6567
}
@@ -83,6 +85,37 @@ public RequiredClass reqClass(String className, String mapping, @Nullable String
8385
return reqClass(className, mapping, forcedVersion, GroovyUtils.convertToAction(consumer));
8486
}
8587

88+
public RequiredNameChain chain(String... unifiedStrings) {
89+
if (unifiedStrings.length == 0) {
90+
throw new RuntimeException("Invalid configuration: name chain needs at least one name");
91+
}
92+
var list = new ArrayList<RequiredName>();
93+
for (var unifiedString : unifiedStrings) {
94+
var split = unifiedString.split(":");
95+
if (split.length == 1) {
96+
list.add(name(split[0], classContext.getDefaultMapping(), classContext.getDefaultForcedVersion()));
97+
} else if (split.length == 2) {
98+
list.add(name(split[1], split[0].isBlank() ? classContext.getDefaultMapping() : split[0], classContext.getDefaultForcedVersion()));
99+
} else if (split.length == 3) {
100+
list.add(name(split[1], split[0].isBlank() ? classContext.getDefaultMapping() : split[0], split[2].isBlank() ? classContext.getDefaultForcedVersion() : split[2]));
101+
} else {
102+
throw new RuntimeException("Invalid configuration: Can't parse " + unifiedString);
103+
}
104+
}
105+
return new RequiredNameChain(list);
106+
}
107+
108+
public RequiredNameChain chain(RequiredName... names) {
109+
if (names.length == 0) {
110+
throw new RuntimeException("Invalid configuration: name chain needs at least one name");
111+
}
112+
return new RequiredNameChain(List.of(names));
113+
}
114+
115+
public RequiredName name(String name, String mapping, @Nullable String forcedVersion) {
116+
return new RequiredName(mapping, name, forcedVersion != null ? forcedVersion : classContext.getDefaultForcedVersion());
117+
}
118+
86119
@SneakyThrows
87120
@ApiStatus.Internal
88121
public NMSMapperConfiguration call(Consumer<NMSMapperConfiguration> closure) {
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Copyright 2022 ScreamingSandals
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.screamingsandals.nms.generator.configuration;
18+
19+
import lombok.Data;
20+
21+
@Data
22+
public class RequiredChainedSymbol implements Required {
23+
private final RequiredNameChain chain;
24+
}

common/src/main/java/org/screamingsandals/nms/generator/configuration/RequiredClass.java

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,14 +80,19 @@ public RequiredClass reqField(String unifiedString) {
8080
if (split.length == 1) {
8181
return reqField(split[0], context.getDefaultMapping(), context.getDefaultForcedVersion());
8282
} else if (split.length == 2) {
83-
return reqField(split[1], split[0], context.getDefaultForcedVersion());
83+
return reqField(split[1], split[0].isBlank() ? context.getDefaultMapping() : split[0], context.getDefaultForcedVersion());
8484
} else if (split.length == 3) {
85-
return reqField(split[1], split[0], split[2]);
85+
return reqField(split[1], split[0].isBlank() ? context.getDefaultMapping() : split[0], split[2].isBlank() ? context.getDefaultForcedVersion() : split[2]);
8686
} else {
8787
throw new RuntimeException("Invalid configuration: Can't parse " + unifiedString);
8888
}
8989
}
9090

91+
public RequiredClass reqField(RequiredNameChain chain) {
92+
requiredSymbols.add(new RequiredField(chain));
93+
return this;
94+
}
95+
9196
public RequiredClass reqField(String name, String mapping, @Nullable String forcedVersion) {
9297
requiredSymbols.add(new RequiredField(mapping, name, forcedVersion));
9398
return this;
@@ -98,14 +103,19 @@ public RequiredClass reqEnumField(String unifiedString) {
98103
if (split.length == 1) {
99104
return reqEnumField(split[0], context.getDefaultMapping(), context.getDefaultForcedVersion());
100105
} else if (split.length == 2) {
101-
return reqEnumField(split[1], split[0], context.getDefaultForcedVersion());
106+
return reqEnumField(split[1], split[0].isBlank() ? context.getDefaultMapping() : split[0], context.getDefaultForcedVersion());
102107
} else if (split.length == 3) {
103-
return reqEnumField(split[1], split[0], split[2]);
108+
return reqEnumField(split[1], split[0].isBlank() ? context.getDefaultMapping() : split[0], split[2].isBlank() ? context.getDefaultForcedVersion() : split[2]);
104109
} else {
105110
throw new RuntimeException("Invalid configuration: Can't parse " + unifiedString);
106111
}
107112
}
108113

114+
public RequiredClass reqEnumField(RequiredNameChain chain) {
115+
requiredSymbols.add(new RequiredEnumField(chain));
116+
return this;
117+
}
118+
109119
public RequiredClass reqEnumField(String name, String mapping, @Nullable String forcedVersion) {
110120
requiredSymbols.add(new RequiredEnumField(mapping, name, forcedVersion));
111121
return this;
@@ -127,14 +137,19 @@ public RequiredClass reqMethod(String unifiedString, Object... params) {
127137
if (split.length == 1) {
128138
return reqMethod(split[0], context.getDefaultMapping(), context.getDefaultForcedVersion(), params);
129139
} else if (split.length == 2) {
130-
return reqMethod(split[1], split[0], context.getDefaultForcedVersion(), params);
140+
return reqMethod(split[1], split[0].isBlank() ? context.getDefaultMapping() : split[0], context.getDefaultForcedVersion(), params);
131141
} else if (split.length == 3) {
132-
return reqMethod(split[1], split[0], split[2], params);
142+
return reqMethod(split[1], split[0].isBlank() ? context.getDefaultMapping() : split[0], split[2].isBlank() ? context.getDefaultForcedVersion() : split[2], params);
133143
} else {
134144
throw new RuntimeException("Invalid configuration: Can't parse " + unifiedString);
135145
}
136146
}
137147

148+
public RequiredClass reqMethod(RequiredNameChain chain, Object... params) {
149+
requiredSymbols.add(new RequiredMethod(chain, parseParams(params)));
150+
return this;
151+
}
152+
138153
public RequiredClass reqMethod(String name, String mapping, String forcedVersion, Object[] params) {
139154
requiredSymbols.add(new RequiredMethod(mapping, name, forcedVersion, parseParams(params)));
140155
return this;

0 commit comments

Comments
 (0)