Gridarta Editor
TreasureLoader.java
Go to the documentation of this file.
1 /*
2  * Gridarta MMORPG map editor for Crossfire, Daimonin and similar games.
3  * Copyright (C) 2000-2023 The Gridarta Developers.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 package net.sf.gridarta.model.treasurelist;
21 
22 import java.io.BufferedReader;
23 import java.io.File;
24 import java.io.FileInputStream;
25 import java.io.FilenameFilter;
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.io.InputStreamReader;
29 import java.io.Reader;
30 import java.util.ArrayList;
31 import java.util.Arrays;
32 import java.util.Collection;
33 import java.util.Comparator;
34 import java.util.List;
35 import java.util.Map;
36 import javax.swing.tree.DefaultMutableTreeNode;
37 import javax.swing.tree.MutableTreeNode;
43 import net.sf.gridarta.utils.IOUtils;
44 import org.apache.log4j.Category;
45 import org.apache.log4j.Logger;
46 import org.jetbrains.annotations.NotNull;
47 import org.jetbrains.annotations.Nullable;
48 
54 public class TreasureLoader {
55 
59  @NotNull
60  private static final Category LOG = Logger.getLogger(TreasureLoader.class);
61 
66  @NotNull
67  private static final Comparator<TreasureTreeNode> TREASURE_NODE_COMPARATOR = (o1, o2) -> String.CASE_INSENSITIVE_ORDER.compare(o1.getTreasureObj().getName(), o2.getTreasureObj().getName());
68 
72  @NotNull
73  private static final FilenameFilter TREASURE_LIST_FILTER = (dir, name) -> {
74  if (name.startsWith(".")) {
75  return false;
76  }
77 
78  final File fullPath = new File(dir, name);
79  if (fullPath.isDirectory()) {
80  return true;
81  }
82 
83  final String lowerCaseName = name.toLowerCase();
84  return lowerCaseName.endsWith(".tl") || lowerCaseName.endsWith(".trs");
85  };
86 
90  private TreasureLoader() {
91  }
92 
101  @NotNull
102  public static TreasureTree parseTreasures(@NotNull final ErrorView errorView, @NotNull final Map<String, TreasureTreeNode> specialTreasureLists, @NotNull final ConfigSource configSource, @NotNull final ProjectSettings projectSettings) {
103  final List<TreasureTreeNode> tmpList = new ArrayList<>(); // tmp. container for all treasurelists
104  final List<TreasureTreeNode> needLink = new ArrayList<>(); // all sub-treasurelist nodes that need linking
105 
106  // first step: parsing data file, adding all treasurelists to the tmpList vector
107  int index = 0;
108  while (true) {
109  final File treasureLocation;
110  try {
111  treasureLocation = configSource.getFile(projectSettings, "treasures", index);
112  } catch (final IOException ex) {
113  errorView.addWarning(ErrorViewCategory.TREASURES_FILE_INVALID, ex.getMessage());
114  index++;
115  continue;
116  }
117  if (treasureLocation == null) {
118  break;
119  }
120 
121  final int tmpListSize = tmpList.size();
122  if (treasureLocation.isDirectory()) {
123  loadTreasureDir(errorView, treasureLocation, tmpList, needLink);
124  } else if (treasureLocation.isFile()) {
125  loadTreasureList(errorView, treasureLocation, tmpList, needLink);
126  } else {
127  new ErrorViewCollector(errorView, treasureLocation).addWarning(ErrorViewCategory.TREASURES_FILE_INVALID, "location is neither file nor directory");
128  }
129  if (LOG.isInfoEnabled()) {
130  LOG.info("Loaded " + (tmpList.size() - tmpListSize) + " treasurelists from '" + treasureLocation + "'.");
131  }
132  index++;
133  }
134 
135  return createTreasureTree(tmpList, needLink, specialTreasureLists);
136  }
137 
146  @NotNull
147  private static TreasureTree createTreasureTree(@NotNull final List<TreasureTreeNode> tmpList, @NotNull final Iterable<TreasureTreeNode> needLink, @NotNull final Map<String, TreasureTreeNode> specialTreasureLists) {
148  final DefaultMutableTreeNode root = new DefaultMutableTreeNode("Treasurelists:");
149  final TreasureTree treasures = new TreasureTree(root);
150  treasures.putAll(tmpList);
151  addTopLevelEntries(tmpList, specialTreasureLists, root);
152  linkSubLists(needLink, treasures);
153  addSpecialEntries(specialTreasureLists, root);
154  return treasures;
155  }
156 
165  private static void addTopLevelEntries(@NotNull final List<TreasureTreeNode> tmpList, @NotNull final Map<String, TreasureTreeNode> specialTreasureLists, @NotNull final DefaultMutableTreeNode root) {
166  tmpList.sort(TREASURE_NODE_COMPARATOR);
167 
168  // Calculate the real ratio of chances (summed up to be 100%). Also
169  // attach lists to tree model.
170  for (final TreasureTreeNode realNode : tmpList) {
171  realNode.recalculateChances();
172 
173  // check for special treasurelists, which are put in sub-folders
174  final DefaultMutableTreeNode specialTreasureList = specialTreasureLists.get(realNode.getTreasureObj().getName());
175  if (specialTreasureList == null) {
176  root.add(realNode); // normal treasurelist - attach to root node
177  } else {
178  specialTreasureList.add(realNode);
179  }
180  }
181  }
182 
188  private static void linkSubLists(@NotNull final Iterable<TreasureTreeNode> needLink, @NotNull final TreasureTree treasures) {
189  final List<TreasureTreeNode> needSecondLink = new ArrayList<>();
190  linkSubList2(needLink, treasures, false, needSecondLink);
191  linkSubList2(needSecondLink, treasures, true, null); // do second linking to link all what is left
192  }
193 
194  private static void linkSubList2(@NotNull final Iterable<TreasureTreeNode> needLink, @NotNull final TreasureTree treasures, final boolean processSecondLinking, @Nullable final List<TreasureTreeNode> needSecondLink) {
195  for (final TreasureTreeNode node : needLink) {
196  final TreasureTreeNode realNode = getRealNode(treasures, node);
197  if (realNode != null) {
198  node.getTreasureObj().copyListType(realNode.getTreasureObj());
199 
200  for (int i = 0; i < realNode.getChildCount(); i++) {
201  final TreasureTreeNode ttn = (TreasureTreeNode) realNode.getChildAt(i);
202  node.add(ttn.getClone(processSecondLinking, needSecondLink));
203  }
204  }
205  }
206  }
207 
214  @Nullable
215  private static TreasureTreeNode getRealNode(@NotNull final TreasureTree treasures, @NotNull final TreasureTreeNode node) {
216  return treasures.get(node.getTreasureObj().getName());
217  }
218 
225  private static void addSpecialEntries(@NotNull final Map<String, TreasureTreeNode> specialTreasureLists, @NotNull final DefaultMutableTreeNode root) {
226  for (final MutableTreeNode folder : specialTreasureLists.values()) {
227  root.add(folder);
228  }
229  }
230 
240  private static void loadTreasureList(@NotNull final ErrorView errorView, @NotNull final File file, final Collection<TreasureTreeNode> tmpList, final List<TreasureTreeNode> needLink) {
241  final ErrorViewCollector errorViewCollector = new ErrorViewCollector(errorView, file);
242  try {
243  try (InputStream inputStream = new FileInputStream(file)) {
244  try (Reader reader = new InputStreamReader(inputStream, IOUtils.MAP_ENCODING)) {
245  try (BufferedReader bufferedReader = new BufferedReader(reader)) {
246  while (true) {
247  final String rawLine = bufferedReader.readLine();
248  if (rawLine == null) {
249  break;
250  }
251  final String line = rawLine.trim();
252  if (!line.isEmpty() && !line.startsWith("#")) {
253  if (line.startsWith("treasure")) {
254  final int i = line.indexOf(' ');
255  if (i == -1) {
256  errorViewCollector.addWarning(ErrorViewCategory.TREASURES_ENTRY_INVALID, "unexpected line: \"" + line + "\"");
257  } else {
258  final String name = line.substring(i).trim();
260  tmpList.add(node);
261 
262  readInsideList(errorViewCollector, node, bufferedReader, needLink);
263  }
264  } else {
265  errorViewCollector.addWarning(ErrorViewCategory.TREASURES_ENTRY_INVALID, "unexpected line: \"" + line + "\"");
266  }
267  }
268  }
269  }
270  }
271  }
272  } catch (final IOException ex) {
273  errorViewCollector.addWarning(ErrorViewCategory.TREASURES_FILE_INVALID, ex.getMessage());
274  }
275  }
276 
286  private static void loadTreasureDir(@NotNull final ErrorView errorView, @NotNull final File dir, @NotNull final List<TreasureTreeNode> tmpList, @NotNull final List<TreasureTreeNode> needLink) {
287  final String[] traverse = dir.list(TREASURE_LIST_FILTER);
288  if (traverse == null) {
289  return;
290  }
291 
292  Arrays.sort(traverse);
293  for (final String entry : traverse) {
294  final File file = new File(dir, entry);
295  if (file.isFile()) {
296  loadTreasureList(errorView, file, tmpList, needLink);
297  } else if (file.isDirectory()) {
298  loadTreasureDir(errorView, file, tmpList, needLink);
299  }
300  }
301  }
302 
312  private static void readInsideList(@NotNull final ErrorViewCollector errorViewCollector, @NotNull final TreasureTreeNode parentNode, @NotNull final BufferedReader reader, @NotNull final List<TreasureTreeNode> needLink) throws IOException {
313  TreasureTreeNode node = null;
314 
315  boolean insideArch = false;
316 
317  while (true) {
318  final String rawLine = reader.readLine();
319  if (rawLine == null) {
320  break;
321  }
322  final String line = rawLine.trim();
323  if (line.equals("end")) {
324  break;
325  }
326  if (!line.isEmpty() && !line.startsWith("#")) {
327  if (insideArch) {
328  if (line.equals("more")) {
329  insideArch = false;
330  } else if (line.startsWith("chance")) {
331  try {
332  node.getTreasureObj().setChance(Integer.parseInt(line.substring(line.indexOf(' ') + 1).trim()));
333  } catch (final NumberFormatException ignored) {
334  errorViewCollector.addWarning(ErrorViewCategory.TREASURES_ENTRY_INVALID, "list " + parentNode.getTreasureObj().getName() + ": arch " + node.getTreasureObj().getName() + " chance is not a number.");
335  }
336  } else if (line.startsWith("nrof")) {
337  try {
338  node.getTreasureObj().setNrof(Integer.parseInt(line.substring(line.indexOf(' ') + 1).trim()));
339  } catch (final NumberFormatException ignored) {
340  errorViewCollector.addWarning(ErrorViewCategory.TREASURES_ENTRY_INVALID, "list " + parentNode.getTreasureObj().getName() + ": arch " + node.getTreasureObj().getName() + " nrof value is not a number.");
341  }
342  } else if (line.startsWith("magic")) {
343  try {
344  node.getTreasureObj().setMagic(Integer.parseInt(line.substring(line.indexOf(' ') + 1).trim()));
345  } catch (final NumberFormatException ignored) {
346  errorViewCollector.addWarning(ErrorViewCategory.TREASURES_ENTRY_INVALID, "list " + parentNode.getTreasureObj().getName() + ": arch " + node.getTreasureObj().getName() + " magic value is not a number.");
347  }
348  } else if (line.startsWith("artifact_chance") || line.startsWith("title") || line.startsWith("difficulty") || line.startsWith("quality_quality") || line.startsWith("quality_range") || line.startsWith("material_quality") || line.startsWith("material_range")) {
349  // ignored for now; prevent error message when loading Daimonin/Atrinik treasure lists
350  } else if (line.startsWith("name") || line.startsWith("t_style") || line.startsWith("affinity")) {
351  // ignored for now; prevent error message when loading Atrinik treasure lists
352  } else if (line.startsWith("artifact ") || line.startsWith("list_magic_value ") || line.startsWith("list_magic_adjustment ") || line.startsWith("change_name ") || line.startsWith("change_title ") || line.startsWith("slaying ")) {
353  // ignored for now; prevent error message when loading Crossfire treasure lists
354  } else if (line.equals("no")) {
355  final int parentChance = node.getTreasureObj().getChance();
356  final int chance;
357  if (parentChance == TreasureObj.UNSET) {
358  errorViewCollector.addWarning(ErrorViewCategory.TREASURES_ENTRY_INVALID, "list " + parentNode.getTreasureObj().getName() + ": arch " + node.getTreasureObj().getName() + " has NO-list but chance is unset!");
359  chance = 0;
360  } else {
361  chance = 100 - parentChance;
362  }
363 
364  final TreasureTreeNode subNode = new TreasureTreeNode(new NoTreasureObj(chance));
365  node.add(subNode);
366 
367  readInsideList(errorViewCollector, subNode, reader, needLink);
368  } else if (line.equals("yes")) {
369  final TreasureTreeNode subNode = new TreasureTreeNode(new YesTreasureObj(node.getTreasureObj().getChance()));
370  node.add(subNode);
371  readInsideList(errorViewCollector, subNode, reader, needLink);
372  } else {
373  errorViewCollector.addWarning(ErrorViewCategory.TREASURES_ENTRY_INVALID, "list " + parentNode.getTreasureObj().getName() + ", arch " + node.getTreasureObj().getName() + ": unexpected line: \"" + line + "\"");
374  }
375  } else {
376  if (line.startsWith("arch ")) {
377  node = new TreasureTreeNode(new ArchTreasureObj(line.substring(line.indexOf(' ')).trim()));
378  parentNode.add(node);
379  insideArch = true;
380  } else if (line.startsWith("list ")) {
381  final String newName = line.substring(line.indexOf(' ')).trim();
383  parentNode.add(node);
384  needLink.add(node); // this node needs to be linked to it's content later
385 
386  // check for potential infinite loops by lists containing itself
387  if (node.getTreasureObj().isTreasureList() && parentNode.getTreasureObj().getName().equals(newName)) {
388  node.getTreasureObj().setHasLoop(true);
389  }
390 
391  insideArch = true;
392  } else {
393  errorViewCollector.addWarning(ErrorViewCategory.TREASURES_ENTRY_INVALID, parentNode + ": unknown line: \"" + line + "\"");
394  }
395  }
396  }
397  }
398  }
399 
400 }
net.sf.gridarta.model.treasurelist.TreasureObj.setMagic
void setMagic(final int magic)
Sets the magic attribute.
Definition: TreasureObj.java:166
name
name
Definition: ArchetypeTypeSetParserTest-ignoreDefaultAttribute1-result.txt:2
net.sf.gridarta.model.errorview.ErrorViewCollector.addWarning
void addWarning(@NotNull final ErrorViewCategory category)
Adds a warning message.
Definition: ErrorViewCollector.java:68
net.sf.gridarta.model.treasurelist.TreasureTreeNode
Subclass: Nodes in the CFTreasureListTree.
Definition: TreasureTreeNode.java:33
net.sf.gridarta.model.treasurelist.TreasureLoader.readInsideList
static void readInsideList(@NotNull final ErrorViewCollector errorViewCollector, @NotNull final TreasureTreeNode parentNode, @NotNull final BufferedReader reader, @NotNull final List< TreasureTreeNode > needLink)
Reads and parses the text inside a treasurelist definition.
Definition: TreasureLoader.java:312
net.sf.gridarta.model.treasurelist.TreasureLoader
Loader for treasure list files.
Definition: TreasureLoader.java:54
net.sf.gridarta.model.treasurelist.TreasureLoader.TREASURE_LIST_FILTER
static final FilenameFilter TREASURE_LIST_FILTER
The FilenameFilter for recursively loading treasure list files.
Definition: TreasureLoader.java:73
net.sf.gridarta
Base package of all Gridarta classes.
net.sf.gridarta.model.treasurelist.TreasureObj.getName
String getName()
Returns the name of this treasure object.
Definition: TreasureObj.java:225
net.sf.gridarta.model.treasurelist.TreasureLoader.addSpecialEntries
static void addSpecialEntries(@NotNull final Map< String, TreasureTreeNode > specialTreasureLists, @NotNull final DefaultMutableTreeNode root)
Add the special treasure list parents to the root {}.
Definition: TreasureLoader.java:225
net.sf.gridarta.model.treasurelist.TreasureListTreasureObj
A TreasureObj representing a "treasure" entry.
Definition: TreasureListTreasureObj.java:28
net.sf.gridarta.model.errorview.ErrorViewCategory.TREASURES_ENTRY_INVALID
TREASURES_ENTRY_INVALID
Definition: ErrorViewCategory.java:88
net.sf
net.sf.gridarta.model.treasurelist.TreasureObj.UNSET
static final int UNSET
Unset values.
Definition: TreasureObj.java:42
net.sf.gridarta.model.treasurelist.TreasureLoader.linkSubList2
static void linkSubList2(@NotNull final Iterable< TreasureTreeNode > needLink, @NotNull final TreasureTree treasures, final boolean processSecondLinking, @Nullable final List< TreasureTreeNode > needSecondLink)
Definition: TreasureLoader.java:194
net.sf.gridarta.model.treasurelist.TreasureLoader.loadTreasureDir
static void loadTreasureDir(@NotNull final ErrorView errorView, @NotNull final File dir, @NotNull final List< TreasureTreeNode > tmpList, @NotNull final List< TreasureTreeNode > needLink)
Recursively traverses a directory and parses all treasurelist files.
Definition: TreasureLoader.java:286
net.sf.gridarta.model.errorview.ErrorView
Interface for classes displaying error messages.
Definition: ErrorView.java:28
net.sf.gridarta.model.treasurelist.TreasureObj
Subclass: UserObject (= content object) for nodes in the CFTreasureListTree These can be either treas...
Definition: TreasureObj.java:32
net.sf.gridarta.model.treasurelist.TreasureLoader.getRealNode
static TreasureTreeNode getRealNode(@NotNull final TreasureTree treasures, @NotNull final TreasureTreeNode node)
Returns the "real" (top-level) node that corresponds to a given node.
Definition: TreasureLoader.java:215
net.sf.gridarta.model.treasurelist.TreasureLoader.TREASURE_NODE_COMPARATOR
static final Comparator< TreasureTreeNode > TREASURE_NODE_COMPARATOR
Comparator for TreasureTreeNodes that compares their object name case insensitive.
Definition: TreasureLoader.java:67
net.sf.gridarta.model.treasurelist.TreasureLoader.linkSubLists
static void linkSubLists(@NotNull final Iterable< TreasureTreeNode > needLink, @NotNull final TreasureTree treasures)
Links sub-treasure tree nodes to their parent nodes.
Definition: TreasureLoader.java:188
net.sf.gridarta.model.treasurelist.TreasureLoader.parseTreasures
static TreasureTree parseTreasures(@NotNull final ErrorView errorView, @NotNull final Map< String, TreasureTreeNode > specialTreasureLists, @NotNull final ConfigSource configSource, @NotNull final ProjectSettings projectSettings)
Parses a treasure file into a TreasureTree instance.
Definition: TreasureLoader.java:102
net.sf.gridarta.model.treasurelist.TreasureObj.setHasLoop
void setHasLoop(final boolean hasLoop)
Sets whether this treasure object contains itself.
Definition: TreasureObj.java:198
net.sf.gridarta.model.treasurelist.YesTreasureObj
A TreasureObj representing a "yes" entry.
Definition: YesTreasureObj.java:28
net.sf.gridarta.model.configsource.ConfigSource
Possible source locations for configuration files.
Definition: ConfigSource.java:37
net.sf.gridarta.model.treasurelist.TreasureObj.getChance
int getChance()
Returns the chance attribute.
Definition: TreasureObj.java:139
net.sf.gridarta.model.treasurelist.TreasureLoader.createTreasureTree
static TreasureTree createTreasureTree(@NotNull final List< TreasureTreeNode > tmpList, @NotNull final Iterable< TreasureTreeNode > needLink, @NotNull final Map< String, TreasureTreeNode > specialTreasureLists)
Creates a TreasureTree instance from a list of {TreasureTreeNodes}.
Definition: TreasureLoader.java:147
net.sf.gridarta.model.treasurelist.TreasureObj.setChance
void setChance(final int value)
Sets the chance attribute.
Definition: TreasureObj.java:131
net
net.sf.gridarta.model.errorview
Definition: ErrorView.java:20
net.sf.gridarta.model.errorview.ErrorViewCollector
Convenience class for adding messages to a ErrorView instance using a fixed category name.
Definition: ErrorViewCollector.java:31
net.sf.gridarta.model.treasurelist.TreasureLoader.LOG
static final Category LOG
The Logger for printing log messages.
Definition: TreasureLoader.java:60
net.sf.gridarta.model.treasurelist.TreasureLoader.TreasureLoader
TreasureLoader()
Private constructor to prevent instantiation.
Definition: TreasureLoader.java:90
net.sf.gridarta.model.errorview.ErrorViewCategory
Defines possible error categories for ErrorView instances.
Definition: ErrorViewCategory.java:28
net.sf.gridarta.model.treasurelist.TreasureListTreasureObjType.ONE
ONE
A "treasureone" list.
Definition: TreasureListTreasureObjType.java:36
net.sf.gridarta.model.treasurelist.TreasureTree
Stores all defined treasure lists.
Definition: TreasureTree.java:32
net.sf.gridarta.model.treasurelist.ArchTreasureObj
A TreasureObj representing an "arch" entry.
Definition: ArchTreasureObj.java:28
net.sf.gridarta.model.treasurelist.TreasureTreeNode.getClone
MutableTreeNode getClone(final boolean processSecondLinking, @Nullable final List< TreasureTreeNode > needSecondLink)
Return a new cloned instance of this object.
Definition: TreasureTreeNode.java:59
net.sf.gridarta.model.treasurelist.NoTreasureObj
A TreasureObj representing a "no" entry.
Definition: NoTreasureObj.java:28
net.sf.gridarta.model.configsource
Definition: AbstractConfigSource.java:20
net.sf.gridarta.model.settings.ProjectSettings
Settings that apply to a project.
Definition: ProjectSettings.java:29
net.sf.gridarta.model.treasurelist.TreasureLoader.addTopLevelEntries
static void addTopLevelEntries(@NotNull final List< TreasureTreeNode > tmpList, @NotNull final Map< String, TreasureTreeNode > specialTreasureLists, @NotNull final DefaultMutableTreeNode root)
Adds a list of TreasureTreeNodes to a root DefaultMutableTreeNode.
Definition: TreasureLoader.java:165
net.sf.gridarta.model.treasurelist.TreasureObj.setNrof
void setNrof(final int nrof)
Sets the maximum number of generated items.
Definition: TreasureObj.java:182
net.sf.gridarta.model.treasurelist.TreasureListTreasureObjType
Type of TreasureListTreasureObj instances.
Definition: TreasureListTreasureObjType.java:26
net.sf.gridarta.model
net.sf.gridarta.model.errorview.ErrorViewCategory.TREASURES_FILE_INVALID
TREASURES_FILE_INVALID
Definition: ErrorViewCategory.java:90
net.sf.gridarta.model.treasurelist.TreasureObj.isTreasureList
final boolean isTreasureList
Whether this treasure object is a "treasure" or "treasureone" object.
Definition: TreasureObj.java:55
net.sf.gridarta.utils.IOUtils
Utility-class for Gridarta's I/O.
Definition: IOUtils.java:40
net.sf.gridarta.model.treasurelist.TreasureListTreasureObjType.MULTI
MULTI
A "treasure" list.
Definition: TreasureListTreasureObjType.java:31
net.sf.gridarta.model.treasurelist.TreasureTreeNode.getTreasureObj
TreasureObj getTreasureObj()
Definition: TreasureTreeNode.java:100
net.sf.gridarta.model.treasurelist.TreasureLoader.loadTreasureList
static void loadTreasureList(@NotNull final ErrorView errorView, @NotNull final File file, final Collection< TreasureTreeNode > tmpList, final List< TreasureTreeNode > needLink)
Parses one treasurelist file.
Definition: TreasureLoader.java:240
net.sf.gridarta.utils
Definition: ActionBuilderUtils.java:20
net.sf.gridarta.model.settings
Definition: AbstractDefaultProjectSettings.java:20
net.sf.gridarta.utils.IOUtils.MAP_ENCODING
static final String MAP_ENCODING
Encoding to use for maps and other data.
Definition: IOUtils.java:52
net.sf.gridarta.model.treasurelist.TreasureTree.putAll
void putAll(final Iterable< TreasureTreeNode > treasureTreeNodes)
Adds all TreasureTreeNode.
Definition: TreasureTree.java:76