Gridarta Editor
AbstractResourcesReader.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.resource;
21 
22 import java.io.BufferedReader;
23 import java.io.File;
24 import java.io.FileNotFoundException;
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.io.InputStreamReader;
28 import java.io.Reader;
29 import java.net.URL;
30 import java.util.HashMap;
31 import java.util.List;
32 import java.util.Map;
45 import net.sf.gridarta.utils.IOUtils;
46 import net.sf.japi.swing.action.ActionBuilder;
47 import net.sf.japi.swing.action.ActionBuilderFactory;
48 import org.apache.log4j.Category;
49 import org.apache.log4j.Logger;
50 import org.jetbrains.annotations.NotNull;
51 import org.jetbrains.annotations.Nullable;
52 
60 public abstract class AbstractResourcesReader<G extends GameObject<G, ?, ?>> {
61 
65  @NotNull
66  private static final ActionBuilder ACTION_BUILDER = ActionBuilderFactory.getInstance().getActionBuilder("net.sf.gridarta");
67 
71  @NotNull
72  private static final Category LOG = Logger.getLogger(AbstractResourcesReader.class);
73 
77  @NotNull
78  private final File collectedDirectory;
79 
84  @Nullable
85  private final String imageSet;
86 
90  @NotNull
92 
96  @NotNull
97  private final FaceObjects faceObjects;
98 
106  protected AbstractResourcesReader(@NotNull final File collectedDirectory, @Nullable final String imageSet, @NotNull final AnimationObjects animationObjects, @NotNull final FaceObjects faceObjects) {
107  this.collectedDirectory = collectedDirectory;
108  this.imageSet = imageSet;
109  this.animationObjects = animationObjects;
110  this.faceObjects = faceObjects;
111  }
112 
120  protected void loadAnimationsFromCollect(@NotNull final ErrorView errorView, @NotNull final Map<String, String> animations, @NotNull final AbstractAnimationObjectsReader animationObjectsReader) {
121  final int animationObjectsSize = animationObjects.size();
122 
123  try {
124  final URL animationsURL = IOUtils.getResource(collectedDirectory, "animations");
125  final ErrorViewCollector errorViewCollector = new ErrorViewCollector(errorView, animationsURL);
126  try {
127  try (InputStream inputStream = animationsURL.openStream()) {
128  try (Reader reader = new InputStreamReader(inputStream, IOUtils.MAP_ENCODING)) {
129  try (Reader bufferedReader = new BufferedReader(reader)) {
130  animationObjectsReader.loadAnimations(animationObjects, errorViewCollector, bufferedReader, "anim ", null, animations);
131  }
132  }
133  }
134  } catch (final IOException ex) {
135  errorView.addWarning(ErrorViewCategory.ANIMATIONS_FILE_INVALID, animationsURL + ": " + ex.getMessage());
136  } catch (final AnimationParseException ex) {
137  errorView.addWarning(ErrorViewCategory.ANIMATIONS_FILE_INVALID, ex.getLineNumber(), animationsURL + ": " + ex.getMessage());
138  }
139 
140  if (LOG.isInfoEnabled()) {
141  LOG.info("Loaded " + (animationObjects.size() - animationObjectsSize) + " animations from '" + animationsURL + "'.");
142  }
143  } catch (final FileNotFoundException ex) {
144  errorView.addWarning(ErrorViewCategory.ANIMATIONS_FILE_INVALID, new File(collectedDirectory, "animations") + ": " + ex.getMessage());
145  }
146  }
147 
157  protected void addPNGFace(@NotNull final String filename, @NotNull final String path, @NotNull final String name, @NotNull final ErrorView errorView, @NotNull final ArchFaceProvider archFaceProvider) {
158  final String facename = generateFaceName(name);
159  archFaceProvider.addInfo(facename, filename);
160  try {
161  faceObjects.addFaceObject(facename, path + "/" + facename, 0, (int) new File(filename).length());
162  } catch (final DuplicateFaceException e) {
163  errorView.addWarning(ErrorViewCategory.ARCHETYPE_INVALID, ACTION_BUILDER.format("loadDuplicateFace", e.getDuplicate().getFaceName(), e.getDuplicate().getOriginalFilename(), e.getExisting().getOriginalFilename()));
164  } catch (final IllegalFaceException ex) {
165  errorView.addWarning(ErrorViewCategory.ARCHETYPE_INVALID, ACTION_BUILDER.format("loadIllegalFace", ex.getFaceObject().getFaceName(), ex.getFaceObject().getOriginalFilename()));
166  }
167  }
168 
174  @NotNull
175  private String generateFaceName(@NotNull final String name) {
176  //noinspection VariableNotUsedInsideIf
177  if (imageSet != null) {
178  // we have to snip out the image set information here from
179  // the 'name', and the ".png": (e.g. blocked.base.111.png -> blocked.111)
180  int firstDot = 0;
181  int secondDot = 0;
182  for (int t = 0; t < name.length() && secondDot == 0; t++) {
183  if (name.charAt(t) == '.') {
184  if (firstDot == 0) {
185  firstDot = t;
186  } else {
187  secondDot = t;
188  }
189  }
190  }
191 
192  if (firstDot != 0 && secondDot != 0) {
193  return name.substring(0, firstDot) + name.substring(secondDot, name.length() - 4);
194  }
195  return name.substring(0, name.length() - 4);
196  }
197 
198  // no image set: we need only cut off the ".png"
199  return name.substring(0, name.length() - 4);
200  }
201 
208  @NotNull
209  public abstract FaceProvider read(@NotNull ErrorView errorView, @NotNull List<G> invObjects);
210 
218  @NotNull
219  protected static Map<String, String> loadAnimTree(@NotNull final URL url) throws IOException {
220  final Map<String, String> animations;
221  try (InputStream inputStream = url.openStream()) {
222  try (Reader reader = new InputStreamReader(inputStream, IOUtils.MAP_ENCODING)) {
223  try (BufferedReader bufferedReader = new BufferedReader(reader)) {
224  animations = loadAnimTree(bufferedReader);
225  }
226  }
227  }
228  if (LOG.isInfoEnabled()) {
229  LOG.info("Loaded " + animations.size() + " animations from '" + url + "'.");
230  }
231  return animations;
232  }
233 
240  @NotNull
241  private static Map<String, String> loadAnimTree(@NotNull final BufferedReader reader) throws IOException {
242  final Map<String, String> animations = new HashMap<>();
243  while (true) {
244  final String line = reader.readLine();
245  if (line == null) {
246  break;
247  }
248  final int index = line.lastIndexOf('/');
249  final String name = line.substring(index + 1);
250  animations.put(name, line);
251  }
252  return animations;
253  }
254 
255 }
net.sf.gridarta.utils.IOUtils.getResource
static URL getResource(@NotNull final File dir, @NotNull final String fileName)
Get the URL of a resource.
Definition: IOUtils.java:69
net.sf.gridarta.model.face.FaceProvider
This interface represents a lazy loader that provides images on demand.
Definition: FaceProvider.java:30
name
name
Definition: ArchetypeTypeSetParserTest-ignoreDefaultAttribute1-result.txt:2
net.sf.gridarta.model.resource.AbstractResourcesReader.addPNGFace
void addPNGFace(@NotNull final String filename, @NotNull final String path, @NotNull final String name, @NotNull final ErrorView errorView, @NotNull final ArchFaceProvider archFaceProvider)
Loads a png from the file, convert it to IconImage and attach it to the face list.
Definition: AbstractResourcesReader.java:157
net.sf.gridarta.model.resource.AbstractResourcesReader.loadAnimationsFromCollect
void loadAnimationsFromCollect(@NotNull final ErrorView errorView, @NotNull final Map< String, String > animations, @NotNull final AbstractAnimationObjectsReader animationObjectsReader)
Loads all animations from the big collected animations file.
Definition: AbstractResourcesReader.java:120
net.sf.gridarta
Base package of all Gridarta classes.
net.sf.gridarta.model.resource.AbstractResourcesReader.AbstractResourcesReader
AbstractResourcesReader(@NotNull final File collectedDirectory, @Nullable final String imageSet, @NotNull final AnimationObjects animationObjects, @NotNull final FaceObjects faceObjects)
Creates a new instance.
Definition: AbstractResourcesReader.java:106
net.sf.gridarta.model.face.FaceObject.getOriginalFilename
String getOriginalFilename()
Get the original filename of this face.
net.sf.gridarta.model.resource.AbstractResourcesReader.LOG
static final Category LOG
The logger for printing log messages.
Definition: AbstractResourcesReader.java:72
net.sf.gridarta.model.anim.AnimationObjects
AnimationObjects is a container for AnimationObjects.
Definition: AnimationObjects.java:30
net.sf.gridarta.model.face.ArchFaceProvider
Implementation of FaceProvider which reads images from the arch directory.
Definition: ArchFaceProvider.java:38
net.sf.gridarta.model.face.DuplicateFaceException.getDuplicate
FaceObject getDuplicate()
Returns the duplicate that caused this exception.
Definition: DuplicateFaceException.java:60
net.sf.gridarta.model.resource.AbstractResourcesReader
Abstract base class for archetype set loader classes.
Definition: AbstractResourcesReader.java:60
net.sf
net.sf.gridarta.model.resource.AbstractResourcesReader.animationObjects
final AnimationObjects animationObjects
The animation objects instance.
Definition: AbstractResourcesReader.java:91
net.sf.gridarta.model.io.AbstractAnimationObjectsReader
Utility class for reading AnimationObjects from files.
Definition: AbstractAnimationObjectsReader.java:44
net.sf.gridarta.model.data.NamedObjects.size
int size()
Get the number of objects.
net.sf.gridarta.model.face.DuplicateFaceException.getExisting
FaceObject getExisting()
Returns the other duplicate that caused this exception.
Definition: DuplicateFaceException.java:68
net.sf.gridarta.model.errorview.ErrorViewCategory.ANIMATIONS_FILE_INVALID
ANIMATIONS_FILE_INVALID
Definition: ErrorViewCategory.java:38
net.sf.gridarta.model.errorview.ErrorView
Interface for classes displaying error messages.
Definition: ErrorView.java:28
net.sf.gridarta.model.gameobject.GameObject
Reflects a game object (object on a map).
Definition: GameObject.java:36
net.sf.gridarta.model.face.IllegalFaceException
Exception thrown to indicate that a face object is not acceptable.
Definition: IllegalFaceException.java:28
net.sf.gridarta.model.anim.AnimationParseException.getLineNumber
int getLineNumber()
Returns the number of the erroneous line.
Definition: AnimationParseException.java:59
net.sf.gridarta.model.resource.AbstractResourcesReader.collectedDirectory
final File collectedDirectory
The collected directory.
Definition: AbstractResourcesReader.java:78
net.sf.gridarta.model.gameobject
GameObjects are the objects based on Archetypes found on maps.
Definition: AbstractGameObject.java:20
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.anim.AnimationParseException
This exception is thrown when parsing an animation definition file (.
Definition: AnimationParseException.java:31
net.sf.gridarta.model.errorview.ErrorViewCategory
Defines possible error categories for ErrorView instances.
Definition: ErrorViewCategory.java:28
net.sf.gridarta.model.resource.AbstractResourcesReader.imageSet
final String imageSet
The current image set.
Definition: AbstractResourcesReader.java:85
net.sf.gridarta.model.resource.AbstractResourcesReader.ACTION_BUILDER
static final ActionBuilder ACTION_BUILDER
Action Builder.
Definition: AbstractResourcesReader.java:66
net.sf.gridarta.model.face.FaceObjects
FaceObjects is a container for FaceObjects.
Definition: FaceObjects.java:31
net.sf.gridarta.model.errorview.ErrorViewCategory.ARCHETYPE_INVALID
ARCHETYPE_INVALID
Definition: ErrorViewCategory.java:50
net.sf.gridarta.model.resource.AbstractResourcesReader.read
abstract FaceProvider read(@NotNull ErrorView errorView, @NotNull List< G > invObjects)
Reads the resources.
net.sf.gridarta.model.io
Reading and writing of maps, handling of paths.
Definition: AbstractAnimationObjectsReader.java:20
net.sf.gridarta.model.resource.AbstractResourcesReader.generateFaceName
String generateFaceName(@NotNull final String name)
Generates the facename for a face.
Definition: AbstractResourcesReader.java:175
net.sf.gridarta.model
net.sf.gridarta.model.resource.AbstractResourcesReader.faceObjects
final FaceObjects faceObjects
The face objects instance.
Definition: AbstractResourcesReader.java:97
net.sf.gridarta.utils.IOUtils
Utility-class for Gridarta's I/O.
Definition: IOUtils.java:40
net.sf.gridarta.model.face
The face is the appearance of an object.
Definition: AbstractFaceObjects.java:20
net.sf.gridarta.model.anim
Gridarta can handle frame information of animations and allow the selection of an animation using a t...
Definition: AbstractAnimationObjects.java:20
net.sf.gridarta.model.face.FaceObject.getFaceName
String getFaceName()
Get the faceName, which is the name of the face as usable by the "face" attribute.
net.sf.gridarta.model.face.IllegalFaceException.getFaceObject
FaceObject getFaceObject()
Returns the illegal face object.
Definition: IllegalFaceException.java:57
net.sf.gridarta.model.face.FaceObjects.addFaceObject
void addFaceObject(@NotNull String faceName, @NotNull String originalFilename, int offset, int size)
Adds a new face object.
net.sf.gridarta.model.resource.AbstractResourcesReader.loadAnimTree
static Map< String, String > loadAnimTree(@NotNull final BufferedReader reader)
Reads Animation Tree from Stream.
Definition: AbstractResourcesReader.java:241
net.sf.gridarta.model.face.DuplicateFaceException
Exception that's thrown in case a face name was not unique.
Definition: DuplicateFaceException.java:26
net.sf.gridarta.utils
Definition: ActionBuilderUtils.java:20
net.sf.gridarta.model.resource.AbstractResourcesReader.loadAnimTree
static Map< String, String > loadAnimTree(@NotNull final URL url)
Loads animations from a file.
Definition: AbstractResourcesReader.java:219
net.sf.gridarta.utils.IOUtils.MAP_ENCODING
static final String MAP_ENCODING
Encoding to use for maps and other data.
Definition: IOUtils.java:52