Skip to content

Commit e9245d8

Browse files
author
NeumimTo
committed
fixed class dependency graph loading & junit tests
1 parent 797b5aa commit e9245d8

37 files changed

Lines changed: 322 additions & 276 deletions

File tree

API/src/main/java/cz/neumimto/rpg/api/configuration/PluginConfig.java

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import com.electronwill.nightconfig.core.conversion.Converter;
2323
import com.electronwill.nightconfig.core.conversion.Path;
2424
import com.electronwill.nightconfig.core.conversion.PreserveNotNull;
25-
import com.typesafe.config.Optional;
2625
import cz.neumimto.rpg.api.logging.Log;
2726
import cz.neumimto.rpg.api.utils.DebugLevel;
2827

@@ -93,17 +92,6 @@ public class PluginConfig {
9392
@Path("MAX_PARTY_SIZE")
9493
public double MAX_PARTY_SIZE = -1;
9594

96-
97-
/* "If a player chooses a race and a class, where both those classes define damage value for one specific weapon, or "
98-
+ "projectile" +
99-
" this option specifies how the weapon damage will be calculated." +
100-
"1 = sum" +
101-
"2 = take highest value")
102-
103-
*/
104-
@Path("WEAPON_MERGE_STRATEGY")
105-
public int WEAPON_MERGE_STRATEGY = 2;
106-
10795
@Path("PLAYER_CHOOSED_SKILLTREE_SPECIALIZATION_GLOBAL_MESSAGE")
10896
public boolean PLAYER_CHOOSED_SKILLTREE_SPECIALIZATION_GLOBAL_MESSAGE;
10997

@@ -251,6 +239,10 @@ public String convertFromField(ItemDamageProcessor value) {
251239

252240
@Override
253241
public ItemDamageProcessor convertToField(String value) {
242+
if (value == null) {
243+
Log.error("Unknown item damage processor definition - Could not find class " + value + ". SEtting to Max()");
244+
return new Max();
245+
}
254246
try {
255247
return (ItemDamageProcessor) Class.forName(value).newInstance();
256248
} catch (Exception e) {
Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package cz.neumimto.rpg.api.configuration.adapters;
22

33
import com.electronwill.nightconfig.core.Config;
4-
import cz.neumimto.rpg.api.Rpg;
5-
import cz.neumimto.rpg.api.classes.ClassService;
64
import cz.neumimto.rpg.api.entity.players.classes.ClassDefinition;
75
import cz.neumimto.rpg.api.entity.players.classes.DependencyGraph;
86

@@ -11,28 +9,32 @@
119

1210
public class ClassDependencyGraphAdapter {
1311

14-
public DependencyGraph deserialize(Config value, ClassDefinition classDef) {
15-
List<String> soft = value.get("Soft");
16-
List<String> hard = value.get("Hard");
17-
List<String> conflicts = value.get("Conflicts");
12+
public static DependencyGraph load(Config value, ClassDefinition classDef, Set<ClassDefinition> set) {
13+
List<String> soft = readOrEmpty(value,"Soft");
14+
List<String> hard = readOrEmpty(value,"Hard");
15+
List<String> conflicts = readOrEmpty(value,"Conflicts");
1816

1917
DependencyGraph graph = classDef.getClassDependencyGraph();
2018

21-
graph.getSoftDepends().addAll(toClass(soft));
22-
graph.getHardDepends().addAll(toClass(hard));
23-
graph.getConflicts().addAll(toClass(conflicts));
19+
graph.getSoftDepends().addAll(toClass(soft, set));
20+
graph.getHardDepends().addAll(toClass(hard, set));
21+
graph.getConflicts().addAll(toClass(conflicts, set));
2422
return graph;
2523
}
2624

27-
private Collection<? extends ClassDefinition> toClass(List<String> list) {
28-
ClassService classService = Rpg.get().getClassService();
29-
return list.stream().map(classService::getClassDefinitionByName).collect(Collectors.toSet());
25+
private static List<String> readOrEmpty(Config config, String node) {
26+
return config.contains(node) ? config.get(node) : Collections.emptyList();
3027
}
3128

32-
public void serialize(ClassDefinition classDef, Config value) {
29+
private static Collection<? extends ClassDefinition> toClass(List<String> list, Set<ClassDefinition> all) {
30+
return all.stream().filter(c -> list.contains(c.getName())).collect(Collectors.toSet());
31+
}
32+
33+
public static void serialize(ClassDefinition classDef, Config value) {
3334
Map<String, Set<String>> map = new HashMap<>();
3435
value.set("Soft", classDef.getClassDependencyGraph().getSoftDepends().stream().map(ClassDefinition::getName).collect(Collectors.toSet()));
3536
value.set("Conflicts", classDef.getClassDependencyGraph().getConflicts().stream().map(ClassDefinition::getName).collect(Collectors.toSet()));
3637
value.set("Hard", classDef.getClassDependencyGraph().getHardDepends().stream().map(ClassDefinition::getName).collect(Collectors.toSet()));
3738
}
39+
3840
}

API/src/main/java/cz/neumimto/rpg/api/entity/players/CharacterService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,5 +156,5 @@ public interface CharacterService<T extends IActiveCharacter> {
156156

157157
void notifyCooldown(IActiveCharacter caster, PlayerSkillContext skillInfo, long cd);
158158

159-
void updateSpellbook(T character, int page, int slot, ISkill o);
159+
void updateSpellbook(T character, int page, String line, ISkill[] o);
160160
}

API/src/main/java/cz/neumimto/rpg/api/scripting/IScriptEngine.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,17 @@
33
import cz.neumimto.rpg.api.skills.scripting.JsBinding;
44
import jdk.nashorn.api.scripting.JSObject;
55

6-
import javax.script.CompiledScript;
76
import javax.script.ScriptEngine;
8-
import javax.script.ScriptException;
97
import java.io.File;
108
import java.net.URLClassLoader;
11-
import java.util.List;
9+
import java.nio.file.Path;
1210
import java.util.Map;
1311

1412
public interface IScriptEngine {
1513
ScriptEngine getEngine();
1614

15+
Path getScriptsRootFolder();
16+
1717
void initEngine();
1818

1919
void loadSkillDefinitionFile(URLClassLoader urlClassLoader, File confFile);

Common/src/main/java/cz/neumimto/rpg/common/classes/ClassServiceImpl.java

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -108,18 +108,6 @@ public void load() {
108108

109109
classDefinitions.forEach(this::registerClassDefinition);
110110

111-
for (ClassDefinition result : classDefinitions) {
112-
Map<String, ClassDefinition> classes = getClasses();
113-
for (ClassDefinition classDefinition : classes.values()) {
114-
if (classDefinition.getName().equalsIgnoreCase(result.getName())) {
115-
continue;
116-
}
117-
if (classDefinition.getClassType().equalsIgnoreCase(result.getClassType())) {
118-
result.getClassDependencyGraph().getConflicts().add(classDefinition);
119-
}
120-
}
121-
}
122-
123111
Log.info("Successfully loaded " + classes.size() + " classes");
124112
}
125113
}

Common/src/main/java/cz/neumimto/rpg/common/commands/ACFBootstrap.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import co.aikar.commands.CommandManager;
55
import co.aikar.commands.InvalidCommandArgument;
66
import co.aikar.commands.contexts.ContextResolver;
7+
import co.aikar.locales.MessageKey;
78
import cz.neumimto.rpg.api.Rpg;
89
import cz.neumimto.rpg.api.configuration.AttributeConfig;
910
import cz.neumimto.rpg.api.effects.IGlobalEffect;
@@ -163,6 +164,28 @@ public static void initializeACF(CommandManager manager, List<BaseCommand> comma
163164
throw new IllegalStateException("Required to register OnlineOtherPlayer acf context resolver!!");
164165
}
165166

167+
manager.getCommandCompletions().registerAsyncCompletion("@skillbook", c -> {
168+
UUID uuid = c.getIssuer().getUniqueId();
169+
IActiveCharacter character = Rpg.get().getCharacterService().getCharacter(uuid);
170+
Map<String, PlayerSkillContext> skills = character.getSkillsByName();
171+
Set<String> set = new HashSet<>(skills.keySet());
172+
set.add("-");
173+
return set;
174+
});
175+
176+
manager.getCommandContexts().registerIssuerAwareContext(ISkill[].class, c -> {
177+
UUID uuid = c.getIssuer().getUniqueId();
178+
IActiveCharacter character = Rpg.get().getCharacterService().getCharacter(uuid);
179+
int i = 0;
180+
while (!c.isLastArg()) {
181+
String s = c.popFirstArg();
182+
i++;
183+
}
184+
if (i != 8) {
185+
c.getIssuer().sendError(MessageKey.of(""));
186+
}
187+
return null;
188+
});
166189

167190
for (BaseCommand o : commandClasses) {
168191
manager.registerCommand(o);

Common/src/main/java/cz/neumimto/rpg/common/commands/CharacterCommands.java

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,17 @@
22

33

44
import co.aikar.commands.BaseCommand;
5-
import co.aikar.commands.annotation.*;
5+
import co.aikar.commands.annotation.CommandAlias;
6+
import co.aikar.commands.annotation.CommandCompletion;
7+
import co.aikar.commands.annotation.Default;
8+
import co.aikar.commands.annotation.Subcommand;
69
import cz.neumimto.rpg.api.classes.ClassService;
710
import cz.neumimto.rpg.api.configuration.AttributeConfig;
811
import cz.neumimto.rpg.api.entity.players.CharacterService;
912
import cz.neumimto.rpg.api.entity.players.IActiveCharacter;
1013
import cz.neumimto.rpg.api.entity.players.classes.ClassDefinition;
1114
import cz.neumimto.rpg.api.gui.Gui;
12-
import cz.neumimto.rpg.api.persistance.model.CharacterBase;
1315
import cz.neumimto.rpg.api.skills.ISkill;
14-
import cz.neumimto.rpg.api.skills.PlayerSkillContext;
1516

1617
import javax.inject.Inject;
1718
import javax.inject.Singleton;
@@ -86,17 +87,13 @@ public void spellbookCommand(IActiveCharacter character) {
8687
Gui.displaySpellbook(character);
8788
}
8889

90+
8991
@Subcommand("spellbook-put")
90-
@CommandCompletion("@range:1-3 @range:1-8 @learnedskill")
91-
public void spellbookPut(IActiveCharacter character, int page, int slot, @Optional ISkill skill) {
92-
if (skill == null) {
93-
characterService.updateSpellbook(character, page, slot, null);
94-
} else {
95-
CharacterBase characterBase = character.getCharacterBase();
96-
characterBase.getSpellbookPages()[page - 1][slot - 1] = null;
97-
PlayerSkillContext info = character.getSkillInfo(skill);
98-
99-
}
92+
@CommandCompletion("@range:1-3 ")
93+
public void spellbookPut(IActiveCharacter character, int page, ISkill[] skills) {
94+
// characterService.updateSpellbook(character, page, skills);
10095
}
96+
97+
10198
}
10299

Common/src/main/java/cz/neumimto/rpg/common/persistance/dao/ClassDefinitionDao.java

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import com.electronwill.nightconfig.core.file.NoFormatFoundException;
2424
import cz.neumimto.rpg.api.Rpg;
2525
import cz.neumimto.rpg.api.configuration.ClassTypeDefinition;
26+
import cz.neumimto.rpg.api.configuration.adapters.ClassDependencyGraphAdapter;
2627
import cz.neumimto.rpg.api.entity.players.classes.ClassDefinition;
2728
import cz.neumimto.rpg.api.entity.players.leveling.EmptyLevelProgression;
2829

@@ -46,14 +47,20 @@
4647
@Singleton
4748
public class ClassDefinitionDao {
4849

49-
public Set<ClassDefinition> parseClassFiles() {
50+
public Path getClassDirectory() {
5051
Path path = Paths.get(Rpg.get().getWorkingDirectory(), "classes");
52+
try {
53+
Files.createDirectories(path);
54+
} catch (IOException e) {
55+
e.printStackTrace();
56+
}
57+
return path;
58+
}
5159

52-
60+
public Set<ClassDefinition> parseClassFiles() {
5361
Set<ClassDefinition> set = new HashSet<>();
5462
try {
55-
Files.createDirectories(path);
56-
Map<String, Path> stringPathMap = preloadClassDefs(path, set);
63+
Map<String, Path> stringPathMap = preloadClassDefs(getClassDirectory(), set);
5764
for (Map.Entry<String, Path> stringPathEntry : stringPathMap.entrySet()) {
5865
String key = stringPathEntry.getKey();
5966
Path p = stringPathEntry.getValue();
@@ -89,6 +96,7 @@ public Set<ClassDefinition> parseClassFiles() {
8996
//because of dependency graph
9097
private Map<String, Path> preloadClassDefs(Path path, Set<ClassDefinition> set) throws IOException {
9198
Map<String, Path> map = new HashMap<>();
99+
92100
Files.walk(path)
93101
.filter(Files::isRegularFile)
94102
.forEach(p -> {
@@ -125,6 +133,24 @@ private Map<String, Path> preloadClassDefs(Path path, Set<ClassDefinition> set)
125133
error(" - File malformed", e);
126134
}
127135
});
136+
137+
Files.walk(path)
138+
.filter(Files::isRegularFile)
139+
.forEach(p -> {
140+
try (FileConfig fileConfig = FileConfig.of(p)) {
141+
fileConfig.load();
142+
if (fileConfig.contains("Name") && fileConfig.contains("ClassType") && fileConfig.contains("Dependencies")) {
143+
info("Preloading class dependency graph file " + p.getFileName());
144+
for (ClassDefinition classDefinition : set) {
145+
if (classDefinition.getName().equals(fileConfig.get("Name"))) {
146+
ClassDependencyGraphAdapter.load(fileConfig.get("Dependencies"), classDefinition, set);
147+
}
148+
}
149+
}
150+
}
151+
});
152+
153+
128154
return map;
129155
}
130156
}

Common/src/main/java/cz/neumimto/rpg/common/scripting/JSLoader.java

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,6 @@
1818

1919
package cz.neumimto.rpg.common.scripting;
2020

21-
import static cz.neumimto.rpg.api.logging.Log.error;
22-
import static cz.neumimto.rpg.api.logging.Log.info;
23-
2421
import com.electronwill.nightconfig.core.conversion.ObjectConverter;
2522
import com.electronwill.nightconfig.core.file.FileConfig;
2623
import com.google.inject.Injector;
@@ -40,6 +37,9 @@
4037
import jdk.nashorn.api.scripting.JSObject;
4138
import net.bytebuddy.dynamic.loading.MultipleParentClassLoader;
4239

40+
import javax.inject.Inject;
41+
import javax.inject.Singleton;
42+
import javax.script.*;
4343
import java.io.File;
4444
import java.io.FileInputStream;
4545
import java.io.IOException;
@@ -53,9 +53,8 @@
5353
import java.nio.file.StandardOpenOption;
5454
import java.util.*;
5555

56-
import javax.inject.Inject;
57-
import javax.inject.Singleton;
58-
import javax.script.*;
56+
import static cz.neumimto.rpg.api.logging.Log.error;
57+
import static cz.neumimto.rpg.api.logging.Log.info;
5958

6059
/**
6160
* Created by NeumimTo on 13.3.2015.
@@ -95,10 +94,17 @@ public ScriptEngine getEngine() {
9594
}
9695

9796
@Override
98-
public void initEngine() {
99-
try {
97+
public Path getScriptsRootFolder() {
98+
if (scripts_root == null) {
10099
scripts_root = Paths.get(Rpg.get().getWorkingDirectory() + "/scripts");
101100
FileUtils.createDirectoryIfNotExists(scripts_root);
101+
}
102+
return scripts_root;
103+
}
104+
105+
@Override
106+
public void initEngine() {
107+
try {
102108
loadNashorn();
103109
if (engine != null) {
104110
setup();
@@ -151,7 +157,7 @@ public void loadNashorn() throws Exception {
151157
}
152158

153159
private Path mergeScriptFiles() {
154-
Path path = Paths.get(scripts_root + File.separator + ".deployed.js");
160+
Path path = Paths.get(getScriptsRootFolder() + File.separator + ".deployed.js");
155161
if (path.toFile().exists()) {
156162
path.toFile().delete();
157163
}
@@ -161,7 +167,7 @@ private Path mergeScriptFiles() {
161167

162168
try {
163169
Queue<Path> directories = new PriorityQueue<>();
164-
directories.add(scripts_root);
170+
directories.add(getScriptsRootFolder());
165171
while (directories.size() != 0) {
166172
Files.list(directories.poll()).forEach((file -> {
167173
if (file.toFile().isDirectory()) directories.add(file);
@@ -189,7 +195,7 @@ private void setup() {
189195
try (InputStreamReader rs = new InputStreamReader(new FileInputStream(path.toFile()))) {
190196
Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
191197
bindings.put("Injector", injector);
192-
bindings.put("Folder", scripts_root);
198+
bindings.put("Folder", getScriptsRootFolder());
193199
bindings.put("Rpg", Rpg.get());
194200
bindings.put("Bindings", new BindingsHelper(engine));
195201
for (Map.Entry<Class<?>, JsBinding.Type> objectTypeEntry : dataToBind.entrySet()) {

0 commit comments

Comments
 (0)