Skip to content
This repository was archived by the owner on Mar 10, 2022. It is now read-only.

Commit 1513bc7

Browse files
authored
Added gamedesign game parameters (#260)
Issue #260
1 parent e7d4f76 commit 1513bc7

File tree

17 files changed

+199
-10
lines changed

17 files changed

+199
-10
lines changed

.github/workflows/ci.yaml

+8
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ jobs:
1515

1616
steps:
1717
- uses: actions/checkout@v2
18+
with:
19+
submodules: recursive
1820

1921
- uses: actions/cache@v2
2022
with:
@@ -62,6 +64,8 @@ jobs:
6264

6365
steps:
6466
- uses: actions/checkout@v2
67+
with:
68+
submodules: recursive
6569

6670
- uses: actions/cache@v2
6771
with:
@@ -94,6 +98,8 @@ jobs:
9498

9599
steps:
96100
- uses: actions/checkout@v2
101+
with:
102+
submodules: recursive
97103

98104
- uses: actions/cache@v2
99105
with:
@@ -140,6 +146,8 @@ jobs:
140146

141147
steps:
142148
- uses: actions/checkout@v2
149+
with:
150+
submodules: recursive
143151

144152
- name: Docker meta
145153
id: docker_meta

.github/workflows/codeql-analysis.yml

+2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ jobs:
3030
steps:
3131
- name: Checkout repository
3232
uses: actions/checkout@v2
33+
with:
34+
submodules: recursive
3335

3436
- name: Set up JDK ${{ env.JAVA_VERSION }}
3537
uses: actions/setup-java@v2

.github/workflows/javadocs.yaml

+4
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ jobs:
1717

1818
steps:
1919
- uses: actions/checkout@v2
20+
with:
21+
submodules: recursive
2022

2123
- uses: actions/cache@v2
2224
with:
@@ -46,6 +48,8 @@ jobs:
4648

4749
steps:
4850
- uses: actions/checkout@v2
51+
with:
52+
submodules: recursive
4953

5054
- uses: actions/cache@v2
5155
with:

.gitmodules

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "config/gamedesign"]
2+
path = config/gamedesign
3+
url = https://github.com/cryptic-game/gamedesign.git

admin-panel/build.gradle

+3
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,7 @@ dependencies {
2323
developmentOnly 'org.springframework.boot:spring-boot-devtools'
2424
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
2525
annotationProcessor 'org.springframework:spring-context-indexer'
26+
27+
compileOnly project(':config-processor')
28+
annotationProcessor project(':config-processor')
2629
}

config-processor/build.gradle

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
plugins {
2+
}
3+
4+
dependencies {
5+
implementation 'org.yaml:snakeyaml:1.27'
6+
compileOnly 'com.google.auto.service:auto-service:1.0-rc7'
7+
annotationProcessor 'com.google.auto.service:auto-service:1.0-rc7'
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
package net.cryptic_game.backend.processor.config;
2+
3+
import com.google.auto.service.AutoService;
4+
5+
import java.io.File;
6+
import java.io.FileReader;
7+
import java.io.IOException;
8+
import java.io.Reader;
9+
import java.lang.reflect.InvocationTargetException;
10+
import java.lang.reflect.Method;
11+
import java.util.Collections;
12+
import java.util.LinkedList;
13+
import java.util.List;
14+
import java.util.Locale;
15+
import java.util.Map;
16+
import java.util.Queue;
17+
import java.util.Set;
18+
import javax.annotation.processing.AbstractProcessor;
19+
import javax.annotation.processing.Processor;
20+
import javax.annotation.processing.RoundEnvironment;
21+
import javax.annotation.processing.SupportedAnnotationTypes;
22+
import javax.annotation.processing.SupportedSourceVersion;
23+
import javax.lang.model.SourceVersion;
24+
import javax.lang.model.element.TypeElement;
25+
import javax.lang.model.element.VariableElement;
26+
import javax.lang.model.util.ElementFilter;
27+
28+
import org.yaml.snakeyaml.Yaml;
29+
30+
@AutoService(Processor.class)
31+
@SupportedSourceVersion(SourceVersion.RELEASE_11)
32+
@SupportedAnnotationTypes("net.cryptic_game.backend.processor.config.ConfigValue")
33+
public class ConfigProcessor extends AbstractProcessor {
34+
35+
private final Map<String, Object> config;
36+
37+
public ConfigProcessor() {
38+
final File workingDir = new File(System.getProperty("user.dir"), "config/gamedesign/parameter");
39+
this.config = this.loadConfig(workingDir);
40+
}
41+
42+
@Override
43+
public boolean process(final Set<? extends TypeElement> annotations, final RoundEnvironment roundEnv) {
44+
annotations.stream()
45+
.flatMap(annotation -> ElementFilter.fieldsIn(roundEnv.getElementsAnnotatedWith(annotation)).stream())
46+
.forEach(this::process);
47+
48+
return true;
49+
}
50+
51+
private void process(final VariableElement element) {
52+
final ConfigValue configValue = element.getAnnotation(ConfigValue.class);
53+
final String name = configValue.value().isEmpty() ? element.getSimpleName().toString() : configValue.value();
54+
55+
final Object value = this.getValue(this.config, new LinkedList<>(List.of(name.toLowerCase(Locale.ROOT).split("_"))));
56+
57+
if (value == null) {
58+
throw new RuntimeException(String.format("Unable to find config value \"%s\".", name));
59+
}
60+
61+
if (!element.asType().toString().equals(value.getClass().getName())) {
62+
throw new RuntimeException(String.format(
63+
"Config value \"%s\" has wrong type. (Required: %s, Provided: %s)",
64+
name,
65+
element.asType().toString(),
66+
value.getClass().getName()
67+
));
68+
}
69+
70+
try {
71+
final Method method = element.getClass()
72+
.getMethod("setData", Object.class);
73+
74+
method.setAccessible(true);
75+
method.invoke(element, value);
76+
} catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
77+
throw new RuntimeException(e);
78+
}
79+
}
80+
81+
private Map<String, Object> loadConfig(final File configDir) {
82+
final File[] files = configDir.listFiles();
83+
if (files == null) {
84+
return Collections.emptyMap();
85+
}
86+
87+
Map<String, Object> config = null;
88+
89+
for (final File file : files) {
90+
final String name = file.getName().toLowerCase(Locale.ENGLISH);
91+
if (file.isDirectory() || !(name.endsWith(".yaml") || name.endsWith(".yml"))) continue;
92+
93+
final Map<String, Object> data;
94+
95+
try (Reader reader = new FileReader(file)) {
96+
data = new Yaml().load(reader);
97+
} catch (IOException e) {
98+
throw new RuntimeException(e);
99+
}
100+
101+
if (config == null) config = data;
102+
else this.merge(config, data);
103+
}
104+
105+
return config;
106+
}
107+
108+
private void merge(final Map<String, Object> first, final Map<String, Object> second) {
109+
second.forEach((secondKey, secondValue) -> {
110+
final Object firstValue = first.get(secondKey);
111+
112+
if (firstValue instanceof Map && secondValue instanceof Map) {
113+
this.merge((Map<String, Object>) firstValue, (Map<String, Object>) secondValue);
114+
return;
115+
}
116+
117+
first.put(secondKey, secondValue);
118+
});
119+
}
120+
121+
private Object getValue(final Map<String, Object> config, final Queue<String> key) {
122+
if (config == null) return null;
123+
124+
if (key.isEmpty()) throw new IllegalArgumentException();
125+
126+
return key.size() == 1
127+
? config.get(key.poll())
128+
: this.getValue((Map<String, Object>) config.get(key.poll()), key);
129+
}
130+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package net.cryptic_game.backend.processor.config;
2+
3+
import java.lang.annotation.ElementType;
4+
import java.lang.annotation.Retention;
5+
import java.lang.annotation.RetentionPolicy;
6+
import java.lang.annotation.Target;
7+
8+
@Target(ElementType.FIELD)
9+
@Retention(RetentionPolicy.SOURCE)
10+
public @interface ConfigValue {
11+
12+
String value() default "";
13+
}

config/gamedesign

Submodule gamedesign added at 6748a65

gradle.properties

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
org.gradle.parallel=true
22
org.gradle.vfs.watch=true
3-
org.gradle.jvmargs=-XX:+UseParallelGC
3+
# --add-opens jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED -> for module 'configuration-processor'
4+
org.gradle.jvmargs=-XX:+UseParallelGC --add-opens jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED

java-base/build.gradle

+3
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,7 @@ dependencies {
4444

4545
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
4646
annotationProcessor 'org.springframework:spring-context-indexer'
47+
48+
compileOnly project(':config-processor')
49+
annotationProcessor project(':config-processor')
4750
}

java-daemon-endpoints/build.gradle

+3
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,7 @@ dependencies {
1515

1616
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
1717
annotationProcessor 'org.springframework:spring-context-indexer'
18+
19+
compileOnly project(':config-processor')
20+
annotationProcessor project(':config-processor')
1821
}

java-daemon/build.gradle

+3
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,7 @@ dependencies {
1111
developmentOnly 'org.springframework.boot:spring-boot-devtools'
1212
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
1313
annotationProcessor 'org.springframework:spring-context-indexer'
14+
15+
compileOnly project(':config-processor')
16+
annotationProcessor project(':config-processor')
1417
}

java-data/build.gradle

+3
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,7 @@ dependencies {
1414

1515
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
1616
annotationProcessor 'org.springframework:spring-context-indexer'
17+
18+
compileOnly project(':config-processor')
19+
annotationProcessor project(':config-processor')
1720
}

server/build.gradle

+3-9
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,7 @@ dependencies {
1212
developmentOnly 'org.springframework.boot:spring-boot-devtools'
1313
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
1414
annotationProcessor 'org.springframework:spring-context-indexer'
15-
}
1615

17-
//jar {
18-
// from "${rootDir}/LICENSE"
19-
// manifest.attributes([
20-
// 'Implementation-Title' : 'Cryptic Server',
21-
// 'Implementation-Version': project.version,
22-
// 'Implementation-Vendor' : 'Cryptic Game (https://cryptic-game.net)'
23-
// ])
24-
//}
16+
compileOnly project(':config-processor')
17+
annotationProcessor project(':config-processor')
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package net.cryptic_game.backend.server;
2+
3+
import net.cryptic_game.backend.processor.config.ConfigValue;
4+
5+
public class Constants {
6+
7+
@ConfigValue
8+
private static final Boolean IS_THIS_ADUMMYVALUE = true;
9+
}

settings.gradle

+1
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,5 @@ include 'java-base'
2020
include 'java-data'
2121
include 'java-daemon-endpoints'
2222
include 'admin-panel'
23+
include 'config-processor'
2324

0 commit comments

Comments
 (0)