Compare commits

...

4 Commits

Author SHA1 Message Date
Zukero
547f76de33 Merge branch 'master' into git_integration
Conflicts:
	.classpath
	src/com/gpl/rpg/atcontentstudio/ATContentStudio.java
2018-09-28 09:48:36 +02:00
Zukero
3e5f732f82 Added Minify.java license 2018-09-28 09:42:50 +02:00
Zukero
b497493853 Fixed issues in i18n tools. Added beanshell worker indicator.
Added resources compression tools too.
2018-09-21 18:51:12 +02:00
Zukero
6701d9784d Added JGit libs and deps in classpath. Update to Java 8 needed. 2017-10-20 17:22:25 +02:00
23 changed files with 978 additions and 40 deletions

View File

@@ -4,7 +4,8 @@
<classpathentry kind="src" path="res"/>
<classpathentry kind="src" path="hacked-libtiled"/>
<classpathentry kind="src" path="siphash-zackehh/src/main/java"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="src" path="minify"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk1.8.0_152"/>
<classpathentry kind="lib" path="lib/jide-oss.jar"/>
<classpathentry kind="lib" path="lib/json_simple-1.1.jar"/>
<classpathentry kind="lib" path="lib/junit-4.10.jar"/>
@@ -14,5 +15,18 @@
<classpathentry kind="lib" path="lib/bsh-2.0b4.jar"/>
<classpathentry kind="lib" path="lib/jsoup-1.10.2.jar" sourcepath="lib/jsoup-1.10.2-sources.jar"/>
<classpathentry kind="lib" path="lib/AndorsTrainer_v0.1.4.jar"/>
<classpathentry kind="lib" path="lib/JGit/commons-codec-1.6.jar"/>
<classpathentry kind="lib" path="lib/JGit/commons-logging-1.1.3.jar"/>
<classpathentry kind="lib" path="lib/JGit/httpclient-4.3.6.jar"/>
<classpathentry kind="lib" path="lib/JGit/httpcore-4.3.3.jar"/>
<classpathentry kind="lib" path="lib/JGit/JavaEWAH-1.1.6.jar"/>
<classpathentry kind="lib" path="lib/JGit/jsch-0.1.54.jar"/>
<classpathentry kind="lib" path="lib/JGit/jzlib-1.0.7.jar"/>
<classpathentry kind="lib" path="lib/JGit/org.eclipse.jgit-4.9.0.201710071750-r.jar">
<attributes>
<attribute name="javadoc_location" value="jar:platform:/resource/ATContentStudio/lib/JGit/org.eclipse.jgit-4.9.0.201710071750-r-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="lib/JGit/slf4j-api-1.7.2.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
</classpath>

View File

@@ -1,11 +1,12 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.6
org.eclipse.jdt.core.compiler.source=1.8

View File

@@ -98,27 +98,42 @@ public class TileSet implements Iterable<Tile>
File f = new File(imgFilename);
Image image = ImageIO.read(f.getCanonicalFile());
BufferedImage image = ImageIO.read(f.getCanonicalFile());
if (image == null) {
throw new IOException("Failed to load " + tilebmpFile);
throw new IOException("Failed to load " + imgFilename);
}
Toolkit tk = Toolkit.getDefaultToolkit();
tilebmpFile = f;
tileDimensions = new Rectangle(cutter.getTileDimensions());
// Toolkit tk = Toolkit.getDefaultToolkit();
//
// if (transparentColor != null) {
// int rgb = transparentColor.getRGB();
// image = tk.createImage(
// new FilteredImageSource(image.getSource(),
// new TransparentImageFilter(rgb)));
// }
//
// BufferedImage buffered = new BufferedImage(
// image.getWidth(null),
// image.getHeight(null),
// BufferedImage.TYPE_INT_ARGB);
// buffered.getGraphics().drawImage(image, 0, 0, null);
if (transparentColor != null) {
int rgb = transparentColor.getRGB();
image = tk.createImage(
new FilteredImageSource(image.getSource(),
new TransparentImageFilter(rgb)));
}
importTileBitmap(image, cutter);
}
public void weakImportTileBitmap(String imgFilename, TileCutter cutter)
throws IOException
{
setTilesetImageFilename(imgFilename);
File f = new File(imgFilename);
BufferedImage buffered = new BufferedImage(
image.getWidth(null),
image.getHeight(null),
BufferedImage.TYPE_INT_ARGB);
buffered.getGraphics().drawImage(image, 0, 0, null);
tilebmpFile = f;
tileDimensions = new Rectangle(cutter.getTileDimensions());
importTileBitmap(buffered, cutter);
}
public void loadFromProject(String name, TMXMap tmxMap, int tileWidth, int tileHeight) {

BIN
lib/JGit/JavaEWAH-1.1.6.jar Executable file

Binary file not shown.

BIN
lib/JGit/commons-codec-1.6.jar Executable file

Binary file not shown.

Binary file not shown.

BIN
lib/JGit/httpclient-4.3.6.jar Executable file

Binary file not shown.

BIN
lib/JGit/httpcore-4.3.3.jar Executable file

Binary file not shown.

BIN
lib/JGit/jsch-0.1.54.jar Executable file

Binary file not shown.

BIN
lib/JGit/jzlib-1.0.7.jar Executable file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
lib/JGit/slf4j-api-1.7.2.jar Executable file

Binary file not shown.

View File

@@ -0,0 +1,405 @@
/**
* ----------------------
* Minify.java 2015-10-04
* ----------------------
*
* Copyright (c) 2015 Charles Bihis (www.whoischarles.com)
*
* This work is an adaptation of JSMin.java published by John Reilly which is a translation from C to Java of jsmin.c
* published by Douglas Crockford. Permission is hereby granted to use this Java version under the same conditions as
* the original jsmin.c on which all of these derivatives are based.
*
*
*
* ---------------------
* JSMin.java 2006-02-13
* ---------------------
*
* Copyright (c) 2006 John Reilly (www.inconspicuous.org)
*
* This work is a translation from C to Java of jsmin.c published by Douglas Crockford. Permission is hereby granted to
* use the Java version under the same conditions as the jsmin.c on which it is based.
*
*
*
* ------------------
* jsmin.c 2003-04-21
* ------------------
*
* Copyright (c) 2002 Douglas Crockford (www.crockford.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
* documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
* Software.
*
* The Software shall be used for Good, not Evil.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.whoischarles.util.json;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PushbackInputStream;
import java.nio.charset.StandardCharsets;
/**
* Minify.java is written by Charles Bihis (www.whoischarles.com) and is adapted from JSMin.java written by John Reilly
* (www.inconspicuous.org) which is itself a translation of jsmin.c written by Douglas Crockford (www.crockford.com).
*
* @see <a href="http://www.unl.edu/ucomm/templatedependents/JSMin.java">http://www.unl.edu/ucomm/templatedependents/JSMin.java</a>
* @see <a href="http://www.crockford.com/javascript/jsmin.c">http://www.crockford.com/javascript/jsmin.c</a>
*/
public class Minify {
private static final int EOF = -1;
private PushbackInputStream in;
private OutputStream out;
private int currChar;
private int nextChar;
private int line;
private int column;
public static enum Action {
OUTPUT_CURR, DELETE_CURR, DELETE_NEXT
}
public Minify() {
this.in = null;
this.out = null;
}
/**
* Minifies the input JSON string.
*
* Takes the input JSON string and deletes the characters which are insignificant to JavaScipt. Comments will be
* removed, tabs will be replaced with spaces, carriage returns will be replaced with line feeds, and most spaces
* and line feeds will be removed. The result will be returned.
*
* @param json The JSON string for which to minify
* @return A minified, yet functionally identical, version of the input JSON string
*/
public String minify(String json) {
InputStream in = new ByteArrayInputStream(json.getBytes(StandardCharsets.UTF_8));
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
minify(in, out);
} catch (Exception e) {
e.printStackTrace();
return null;
}
return out.toString().trim();
}
/**
* Takes an input stream to a JSON string and outputs minified JSON to the output stream.
*
* Takes the input JSON via the input stream and deletes the characters which are insignificant to JavaScript.
* Comments will be removed, tabs will be replaced with spaaces, carriage returns will be replaced with line feeds,
* and most spaces and line feeds will be removed. The result is streamed to the output stream.
*
* @param in The <code>InputStream</code> from which to get the un-minified JSON
* @param out The <code>OutputStream</code> where the resulting minified JSON will be streamed to
* @throws IOException
* @throws UnterminatedRegExpLiteralException
* @throws UnterminatedCommentException
* @throws UnterminatedStringLiteralException
*/
public void minify(InputStream in, OutputStream out) throws IOException, UnterminatedRegExpLiteralException,
UnterminatedCommentException,
UnterminatedStringLiteralException {
// Initialize
this.in = new PushbackInputStream(in);
this.out = out;
this.line = 0;
this.column = 0;
// currChar = '\n';
// action(Action.DELETE_NEXT);
currChar = get();
nextChar = peek();
// Process input
while (currChar != EOF) {
switch (currChar) {
case ' ':
if (isAlphanum(nextChar)) {
action(Action.OUTPUT_CURR);
} else {
action(Action.DELETE_CURR);
}
break;
case '\n':
switch (nextChar) {
case '{':
case '[':
case '(':
case '+':
case '-':
action(Action.OUTPUT_CURR);
break;
case ' ':
action(Action.DELETE_NEXT);
break;
default:
if (isAlphanum(nextChar)) {
action(Action.OUTPUT_CURR);
} else {
action(Action.DELETE_CURR);
}
}
break;
default:
switch (nextChar) {
case ' ':
if (isAlphanum(currChar)) {
action(Action.OUTPUT_CURR);
break;
}
action(Action.DELETE_NEXT);
break;
case '\n':
switch (currChar) {
case '}':
case ']':
case ')':
case '+':
case '-':
case '"':
case '\'':
action(Action.OUTPUT_CURR);
break;
default:
if (isAlphanum(currChar)) {
action(Action.OUTPUT_CURR);
} else {
action(Action.DELETE_NEXT);
}
}
break;
default:
action(Action.OUTPUT_CURR);
break;
}
}
}
out.flush();
}
/**
* Process the current character with an appropriate action.
*
* The action that occurs is determined by the current character. The options are:
*
* 1. Output currChar: output currChar, copy nextChar to currChar, get the next character and save it to nextChar
* 2. Delete currChar: copy nextChar to currChar, get the next character and save it to nextChar
* 3. Delete nextChar: get the next character and save it to nextChar
*
* This method essentially treats a string as a single character. Also recognizes regular expressions if they are
* preceded by '(', ',', or '='.
*
* @param action The action to perform
* @throws IOException
* @throws UnterminatedRegExpLiteralException
* @throws UnterminatedCommentException
* @throws UnterminatedStringLiteralException
*/
private void action(Action action) throws IOException, UnterminatedRegExpLiteralException, UnterminatedCommentException,
UnterminatedStringLiteralException {
// Process action
switch (action) {
case OUTPUT_CURR:
out.write(currChar);
case DELETE_CURR:
currChar = nextChar;
if (currChar == '\'' || currChar == '"') {
for ( ; ; ) {
out.write(currChar);
currChar = get();
if (currChar == nextChar) {
break;
}
if (currChar <= '\n') {
throw new UnterminatedStringLiteralException(line,
column);
}
if (currChar == '\\') {
out.write(currChar);
currChar = get();
}
}
}
case DELETE_NEXT:
nextChar = next();
if (nextChar == '/'
&& (currChar == '(' || currChar == ',' || currChar == '=' || currChar == ':')) {
out.write(currChar);
out.write(nextChar);
for ( ; ; ) {
currChar = get();
if (currChar == '/') {
break;
} else if (currChar == '\\') {
out.write(currChar);
currChar = get();
} else if (currChar <= '\n') {
throw new UnterminatedRegExpLiteralException(line,
column);
}
out.write(currChar);
}
nextChar = next();
}
}
}
/**
* Determines whether a given character is a letter, digit, underscore, dollar sign, or non-ASCII character.
*
* @param c The character to compare
* @return True if the character is a letter, digit, underscore, dollar sign, or non-ASCII character. False otherwise.
*/
private boolean isAlphanum(int c) {
return ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z')
|| c == '_' || c == '$' || c == '\\' || c > 126);
}
/**
* Returns the next character from the input stream.
*
* Will pop the next character from the input stack. If the character is a control character, translate it to a space
* or line feed.
*
* @return The next character from the input stream
* @throws IOException
*/
private int get() throws IOException {
int c = in.read();
if (c == '\n') {
line++;
column = 0;
} else {
column++;
}
if (c >= ' ' || c == '\n' || c == EOF) {
return c;
}
if (c == '\r') {
column = 0;
return '\n';
}
return ' ';
}
/**
* Returns the next character from the input stream without popping it from the stack.
*
* @return The next character from the input stream
* @throws IOException
*/
private int peek() throws IOException {
int lookaheadChar = in.read();
in.unread(lookaheadChar);
return lookaheadChar;
}
/**
* Get the next character from the input stream, excluding comments.
*
* Will read from the input stream via the <code>get()</code> method. Will exclude characters that are part of
* comments. <code>peek()</code> is used to se if a '/' is followed by a '/' or a '*' for the purpose of identifying
* comments.
*
* @return The next character from the input stream, excluding characters from comments
* @throws IOException
* @throws UnterminatedCommentException
*/
private int next() throws IOException, UnterminatedCommentException {
int c = get();
if (c == '/') {
switch (peek()) {
case '/':
for ( ; ; ) {
c = get();
if (c <= '\n') {
return c;
}
}
case '*':
get();
for ( ; ; ) {
switch (get()) {
case '*':
if (peek() == '/') {
get();
return ' ';
}
break;
case EOF:
throw new UnterminatedCommentException(line, column);
}
}
default:
return c;
}
}
return c;
}
/**
* Exception to be thrown when an unterminated comment appears in the input.
*/
public static class UnterminatedCommentException extends Exception {
public UnterminatedCommentException(int line, int column) {
super("Unterminated comment at line " + line + " and column " + column);
}
}
/**
* Exception to be thrown when an unterminated string literal appears in the input.
*/
public static class UnterminatedStringLiteralException extends Exception {
public UnterminatedStringLiteralException(int line, int column) {
super("Unterminated string literal at line " + line + " and column " + column);
}
}
/**
* Exception to be thrown when an unterminated regular expression literal appears in the input.
*/
public static class UnterminatedRegExpLiteralException extends Exception {
public UnterminatedRegExpLiteralException(int line, int column) {
super("Unterminated regular expression at line " + line + " and column " + column);
}
}
}

43
res/LICENSE.minify Normal file
View File

@@ -0,0 +1,43 @@
----------------------
Minify.java 2015-10-04
----------------------
Copyright (c) 2015 Charles Bihis (www.whoischarles.com)
This work is an adaptation of JSMin.java published by John Reilly which is a translation from C to Java of jsmin.c
published by Douglas Crockford. Permission is hereby granted to use this Java version under the same conditions as
the original jsmin.c on which all of these derivatives are based.
---------------------
JSMin.java 2006-02-13
---------------------
Copyright (c) 2006 John Reilly (www.inconspicuous.org)
This work is a translation from C to Java of jsmin.c published by Douglas Crockford. Permission is hereby granted to
use the Java version under the same conditions as the jsmin.c on which it is based.
------------------
jsmin.c 2003-04-21
------------------
Copyright (c) 2002 Douglas Crockford (www.crockford.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -32,6 +32,17 @@ import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import javax.swing.plaf.FontUIResource;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.attributes.AttributesNodeProvider;
import org.eclipse.jgit.internal.storage.file.FileRepository;
import org.eclipse.jgit.lib.ObjectDatabase;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefDatabase;
import org.eclipse.jgit.lib.ReflogReader;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.StoredConfig;
import prefuse.data.expression.parser.ExpressionParser;
import com.gpl.rpg.atcontentstudio.model.Workspace;
@@ -73,6 +84,19 @@ public class ATContentStudio {
}
}
// try {
// Git git = new Git(new FileRepository("/home/xxx/git_repos/andors-trail/.git/"));
// List<Ref> branches = git.branchList().call();
// for (Ref branch : branches) {
// System.out.println(branch.getName());
// }
// } catch (IOException e1) {
// e1.printStackTrace();
// } catch (GitAPIException e1) {
// e1.printStackTrace();
// }
ConfigCache.init();
try {

View File

@@ -1,4 +1,4 @@
package com.gpl.rpg.atcontentstudio.ui.tools.i18n;
package com.gpl.rpg.atcontentstudio.model.tools.i18n;
import java.io.File;
import java.io.FileWriter;

View File

@@ -1,4 +1,4 @@
package com.gpl.rpg.atcontentstudio.ui.tools.i18n;
package com.gpl.rpg.atcontentstudio.model.tools.i18n;
import java.io.File;
import java.io.FileFilter;
@@ -24,15 +24,15 @@ import net.launchpad.tobal.poparser.POParser;
* To use this, paste the following script in the beanshell console of ATCS.
* Don't forget to change the project number to suit your needs.
*
* import com.gpl.rpg.atcontentstudio.model.Workspace;
* import com.gpl.rpg.atcontentstudio.ui.tools.i18n.PotGenerator;
* import com.gpl.rpg.atcontentstudio.ui.tools.i18n.PotComparator;
*
* proj = Workspace.activeWorkspace.projects.get(7);
* PotGenerator.generatePotFileForProject(proj);
* comp = new PotComparator(proj);
* comp.compare();
* comp.updatePoFiles(proj);
import com.gpl.rpg.atcontentstudio.model.Workspace;
import com.gpl.rpg.atcontentstudio.model.tools.i18n.PotGenerator;
import com.gpl.rpg.atcontentstudio.model.tools.i18n.PotComparator;
proj = Workspace.activeWorkspace.projects.get(7);
PotGenerator.generatePotFileForProject(proj);
comp = new PotComparator(proj);
comp.compare();
comp.updatePoFiles(proj);
*
*
*

View File

@@ -1,4 +1,4 @@
package com.gpl.rpg.atcontentstudio.ui.tools.i18n;
package com.gpl.rpg.atcontentstudio.model.tools.i18n;
import java.io.File;
import java.util.LinkedHashMap;

View File

@@ -0,0 +1,381 @@
package com.gpl.rpg.atcontentstudio.model.tools.resoptimizer;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.nio.CharBuffer;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.imageio.ImageIO;
import org.json.simple.JSONArray;
import com.gpl.rpg.atcontentstudio.io.JsonPrettyWriter;
import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.GameSource;
import com.gpl.rpg.atcontentstudio.model.Project;
import com.gpl.rpg.atcontentstudio.model.gamedata.ActorCondition;
import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet;
import com.gpl.rpg.atcontentstudio.model.gamedata.Item;
import com.gpl.rpg.atcontentstudio.model.gamedata.NPC;
import com.gpl.rpg.atcontentstudio.model.maps.TMXMap;
import com.gpl.rpg.atcontentstudio.model.maps.TMXMapSet;
import com.gpl.rpg.atcontentstudio.model.sprites.SpriteSheetSet;
import com.gpl.rpg.atcontentstudio.utils.FileUtils;
import com.whoischarles.util.json.Minify;
import com.whoischarles.util.json.Minify.UnterminatedCommentException;
import com.whoischarles.util.json.Minify.UnterminatedRegExpLiteralException;
import com.whoischarles.util.json.Minify.UnterminatedStringLiteralException;
import tiled.core.TileSet;
import tiled.io.TMXMapWriter;
/**
*
* @author Kevin
*
* To use this, paste the following script in the beanshell console of ATCS.
* Don't forget to change the project number to suit your needs.
*
import com.gpl.rpg.atcontentstudio.model.tools.resoptimizer.ResourcesCompactor;
import com.gpl.rpg.atcontentstudio.model.Workspace;
proj = Workspace.activeWorkspace.projects.get(0);
new ResourcesCompactor(proj).compactData();
*
*/
public class ResourcesCompactor {
public static String DEFAULT_REL_PATH_IN_PROJECT = "compressed"+File.separator;
private Project proj;
private File baseFolder;
private List<CompressedSpritesheet> compressedSpritesheets = new LinkedList<CompressedSpritesheet>();
private List<File> preservedSpritesheets = new LinkedList<File>();
private Map<SpritesheetId, SpritesheetId> spritesRelocationForObjects = new LinkedHashMap<SpritesheetId, SpritesheetId>();
private Integer currentSpritesheetIndexForObjects = 0;
private CompressedSpritesheet currentSpritesheetForObjects = null;
private Map<SpritesheetId, SpritesheetId> spritesRelocationForMaps = new LinkedHashMap<SpritesheetId, SpritesheetId>();
private Map<SpritesheetId, CompressedSpritesheet> spritesheetsBySidForMaps = new LinkedHashMap<SpritesheetId, CompressedSpritesheet>();
private Integer currentSpritesheetIndexForMaps = 0;
private CompressedSpritesheet currentSpritesheetForMaps = null;
public ResourcesCompactor(Project proj) {
this.proj = proj;
this.baseFolder = new File(proj.baseFolder, DEFAULT_REL_PATH_IN_PROJECT);
if (!baseFolder.exists()) baseFolder.mkdirs();
}
public void compactData() {
compactJsonData();
for(CompressedSpritesheet cs : compressedSpritesheets) {
cs.drawFile();
}
for (File preserved : preservedSpritesheets) {
FileUtils.copyFile(preserved, new File(baseFolder.getAbsolutePath()+File.separator+DEFAULT_DRAWABLE_REL_PATH+File.separator+preserved.getName()));
}
compactMaps();
}
public void compactJsonData() {
final List<File> filesCovered = new LinkedList<File>();
File folder = new File(baseFolder.getAbsolutePath()+File.separator+GameDataSet.DEFAULT_REL_PATH_IN_SOURCE);
if (!folder.exists()) folder.mkdirs();
for (ActorCondition ac : proj.baseContent.gameData.actorConditions) {
if (filesCovered.contains(ac.jsonFile)) continue;
File currentFile = ac.jsonFile;
filesCovered.add(currentFile);
List<Map> dataToSave = new ArrayList<Map>();
for (ActorCondition acond : proj.baseContent.gameData.actorConditions) {
if (!acond.jsonFile.equals(currentFile)) continue;
Map json = acond.toJson();
json.put("iconID", convertObjectSprite(acond.icon_id).toStringID());
dataToSave.add(json);
}
File target = new File(folder, ac.jsonFile.getName());
writeJson(dataToSave, target);
}
for (Item it : proj.baseContent.gameData.items) {
if (filesCovered.contains(it.jsonFile)) continue;
File currentFile = it.jsonFile;
filesCovered.add(currentFile);
List<Map> dataToSave = new ArrayList<Map>();
for (Item item : proj.baseContent.gameData.items) {
if (!item.jsonFile.equals(currentFile)) continue;
Map json = item.toJson();
json.put("iconID", convertObjectSprite(item.icon_id).toStringID());
dataToSave.add(json);
}
File target = new File(folder, it.jsonFile.getName());
writeJson(dataToSave, target);
}
for (NPC np : proj.baseContent.gameData.npcs) {
if (filesCovered.contains(np.jsonFile)) continue;
File currentFile = np.jsonFile;
filesCovered.add(currentFile);
List<Map> dataToSave = new ArrayList<Map>();
for (NPC npc : proj.baseContent.gameData.npcs) {
if (!npc.jsonFile.equals(currentFile)) continue;
Map json = npc.toJson();
if (proj.getImage(npc.icon_id).getWidth(null) == TILE_WIDTH_IN_PIXELS || proj.getImage(npc.icon_id).getHeight(null) == TILE_HEIGHT_IN_PIXELS) {
json.put("iconID", convertObjectSprite(npc.icon_id).toStringID());
}
dataToSave.add(json);
}
File target = new File(folder, np.jsonFile.getName());
writeJson(dataToSave, target);
}
File[] remainingFiles = proj.baseContent.gameData.baseFolder.listFiles(new FileFilter() {
@Override
public boolean accept(File arg0) {
return arg0.getName().endsWith(".json") && !filesCovered.contains(arg0);
}
});
for (File source : remainingFiles) {
File target = new File(folder, source.getName());
minifyJson(source, target);
}
}
private Minify jsonMinifier = new Minify();
private void writeJson(List<Map> dataToSave, File target) {
StringWriter writer = new JsonPrettyWriter();
try {
JSONArray.writeJSONString(dataToSave, writer);
} catch (IOException e) {
//Impossible with a StringWriter
}
String toWrite = writer.toString();
try {
FileWriter w = new FileWriter(target);
w.write(jsonMinifier.minify(toWrite));
w.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private void minifyJson(File source, File target) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
FileInputStream fis = new FileInputStream(source);
jsonMinifier.minify(fis, baos);
FileWriter w = new FileWriter(target);
w.write(baos.toString());
w.close();
} catch (IOException e) {
e.printStackTrace();
} catch (UnterminatedRegExpLiteralException e) {
e.printStackTrace();
} catch (UnterminatedCommentException e) {
e.printStackTrace();
} catch (UnterminatedStringLiteralException e) {
e.printStackTrace();
}
}
private void compactMaps() {
for (TMXMap map : proj.baseContent.gameMaps.tmxMaps) {
TMXMap clone = map.clone();
for (GameDataElement gde : clone.getBacklinks()) {
gde.removeBacklink(clone);
}
clone.getBacklinks().clear();
tiled.core.Map tmx = clone.tmxMap;
compactMap(tmx, map.id);
clone.tmxMap = null;
clone.groups.clear();
clone = null;
}
}
private void compactMap(tiled.core.Map tmx, String name) {
File target = new File(baseFolder.getAbsolutePath()+File.separator+TMXMapSet.DEFAULT_REL_PATH_IN_SOURCE+File.separator+name+".tmx");
if (!target.getParentFile().exists()) target.getParentFile().mkdirs();
Map<tiled.core.Tile, SpritesheetId> localConvertions = new LinkedHashMap<tiled.core.Tile, SpritesheetId>();
List<CompressedSpritesheet> usedSpritesheets = new LinkedList<CompressedSpritesheet>();
List<tiled.core.TileSet> toRemove = new LinkedList<TileSet>();
for (tiled.core.TileSet ts : tmx.getTileSets()) {
if (!ts.getName().equalsIgnoreCase("map_dynamic_placeholders")) {
toRemove.add(ts);
}
}
for (tiled.core.TileLayer layer : tmx.getTileLayers()) {
for (int x = 0; x < layer.getWidth(); x++) {
for (int y = 0; y < layer.getHeight(); y++) {
tiled.core.Tile tile = layer.getTileAt(x, y);
if (tile != null && !tile.getTileSet().getName().equalsIgnoreCase("map_dynamic_placeholders")) {
SpritesheetId sid = convertMapSprite(SpritesheetId.toStringID(tile.getTileSet().getName(), tile.getId()));
localConvertions.put(tile, sid);
if (!usedSpritesheets.contains(spritesheetsBySidForMaps.get(sid))) {
usedSpritesheets.add(spritesheetsBySidForMaps.get(sid));
}
}
}
}
}
Map<CompressedSpritesheet, tiled.core.TileSet> csToTs = new LinkedHashMap<CompressedSpritesheet, tiled.core.TileSet>();
for (CompressedSpritesheet cs : usedSpritesheets) {
cs.drawFile();
tiled.core.TileSet ts = new tiled.core.TileSet();
csToTs.put(cs, ts);
tiled.util.BasicTileCutter cutter = new tiled.util.BasicTileCutter(TILE_WIDTH_IN_PIXELS, TILE_HEIGHT_IN_PIXELS, 0, 0);
try {
ts.importTileBitmap(cs.f.getAbsolutePath(), cutter);
} catch (IOException e) {
e.printStackTrace();
}
ts.setName(cs.prefix+Integer.toString(cs.index));
//ts.setSource("../drawable/"+ts.getName()+TILESHEET_SUFFIX);
tmx.addTileset(ts);
}
for (tiled.core.TileLayer layer : tmx.getTileLayers()) {
for (tiled.core.Tile tile : localConvertions.keySet()) {
SpritesheetId sid = localConvertions.get(tile);
layer.replaceTile(tile, csToTs.get(spritesheetsBySidForMaps.get(sid)).getTile(sid.offset));
}
}
for (tiled.core.TileSet ts : toRemove) {
tmx.removeTileset(ts);
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
TMXMapWriter writer = new TMXMapWriter();
writer.settings.layerCompressionMethod = TMXMapWriter.Settings.LAYER_COMPRESSION_METHOD_ZLIB;
try {
writer.writeMap(tmx, baos, target.getAbsolutePath());
String xml = baos.toString();
FileWriter w = new FileWriter(target);
w.write(xml);
w.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private SpritesheetId convertObjectSprite(String originalSpriteId) {
if (spritesRelocationForObjects.containsKey(SpritesheetId.getInstance(originalSpriteId))) {
return spritesRelocationForObjects.get(SpritesheetId.getInstance(originalSpriteId));
} else if (currentSpritesheetForObjects == null || !currentSpritesheetForObjects.hasFreeSlot()) {
currentSpritesheetForObjects = new CompressedSpritesheet(TILESHEET_PREFIX_FOR_OBJECTS, currentSpritesheetIndexForObjects);
compressedSpritesheets.add(currentSpritesheetForObjects);
currentSpritesheetIndexForObjects++;
}
SpritesheetId sid = currentSpritesheetForObjects.addSprite(originalSpriteId);
spritesRelocationForObjects.put(SpritesheetId.getInstance(originalSpriteId), sid);
return sid;
}
private SpritesheetId convertMapSprite(String originalSpriteId) {
if (spritesRelocationForMaps.containsKey(SpritesheetId.getInstance(originalSpriteId))) {
return spritesRelocationForMaps.get(SpritesheetId.getInstance(originalSpriteId));
} else if (currentSpritesheetForMaps == null || !currentSpritesheetForMaps.hasFreeSlot()) {
currentSpritesheetForMaps = new CompressedSpritesheet(TILESHEET_PREFIX_FOR_MAPS, currentSpritesheetIndexForMaps);
compressedSpritesheets.add(currentSpritesheetForMaps);
currentSpritesheetIndexForMaps++;
}
SpritesheetId sid = currentSpritesheetForMaps.addSprite(originalSpriteId);
spritesRelocationForMaps.put(SpritesheetId.getInstance(originalSpriteId), sid);
spritesheetsBySidForMaps.put(sid, currentSpritesheetForMaps);
return sid;
}
private static final int TILESHEET_WIDTH_IN_SPRITES = 8;
private static final int TILESHEET_HEIGHT_IN_SPRITES = 8;
private static final int TILE_WIDTH_IN_PIXELS = 32;
private static final int TILE_HEIGHT_IN_PIXELS = 32;
private static final String TILESHEET_PREFIX_FOR_OBJECTS = "obj_";
private static final String TILESHEET_PREFIX_FOR_MAPS = "map_";
private static final String TILESHEET_SUFFIX = ".png";
private static final String DEFAULT_DRAWABLE_REL_PATH = SpriteSheetSet.DEFAULT_REL_PATH_IN_SOURCE;
private class CompressedSpritesheet {
String prefix;
int index;
File f;
boolean mustDraw = true;
int nextFreeSlot = 0;
String[] originalSpritesId = new String[TILESHEET_WIDTH_IN_SPRITES * TILESHEET_HEIGHT_IN_SPRITES];
public CompressedSpritesheet(String prefix, int index) {
this.prefix = prefix;
this.index = index;
File folder = new File(ResourcesCompactor.this.baseFolder.getAbsolutePath()+File.separator+DEFAULT_DRAWABLE_REL_PATH);
if (!folder.exists()) folder.mkdirs();
this.f = new File(folder, prefix+Integer.toString(index)+TILESHEET_SUFFIX);
}
public boolean hasFreeSlot() {
return nextFreeSlot < TILESHEET_WIDTH_IN_SPRITES * TILESHEET_HEIGHT_IN_SPRITES;
}
public SpritesheetId addSprite(String spriteId) {
mustDraw = true;
originalSpritesId[nextFreeSlot] = spriteId;
nextFreeSlot++;
return SpritesheetId.getInstance(prefix+Integer.toString(index), nextFreeSlot - 1);
}
public void drawFile() {
if (!mustDraw) return;
BufferedImage img = new BufferedImage(TILESHEET_WIDTH_IN_SPRITES * TILE_WIDTH_IN_PIXELS, TILESHEET_HEIGHT_IN_SPRITES * TILE_HEIGHT_IN_PIXELS, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = (Graphics2D)img.getGraphics();
Color transparent = new Color(0, 0, 0, 0);
g.setColor(transparent);
g.fillRect(0, 0, img.getWidth(), img.getHeight());
for (int i = 0; i < nextFreeSlot; i++) {
g.drawImage(
proj.getImage(originalSpritesId[i]),
(i % TILESHEET_WIDTH_IN_SPRITES) * TILE_WIDTH_IN_PIXELS,
(i / TILESHEET_WIDTH_IN_SPRITES) * TILE_HEIGHT_IN_PIXELS,
TILE_WIDTH_IN_PIXELS,
TILE_HEIGHT_IN_PIXELS,
null);
}
try {
ImageIO.write(img, "png", f);
mustDraw = false;
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

View File

@@ -0,0 +1,38 @@
package com.gpl.rpg.atcontentstudio.model.tools.resoptimizer;
import java.util.LinkedHashMap;
import java.util.Map;
public class SpritesheetId {
static Map<String, SpritesheetId> instancesCache = new LinkedHashMap<String, SpritesheetId>();
String tileset;
int offset;
static SpritesheetId getInstance(String id) {
String[] values = id.split(":");
return getInstance(values[0], Integer.parseInt(values[1]));
}
static SpritesheetId getInstance(String tilesetId, int offset) {
if (!instancesCache.containsKey(toStringID(tilesetId, offset))) {
SpritesheetId instance = new SpritesheetId(tilesetId, offset);
instancesCache.put(instance.toStringID(), instance);
}
return instancesCache.get(toStringID(tilesetId, offset));
}
private SpritesheetId(String tileset, int offset) {
this.tileset = tileset;
this.offset = offset;
}
public String toStringID() {
return toStringID(tileset, offset);
}
static String toStringID(String tileset, int offset) {
return tileset+":"+Integer.toString(offset);
}
}

View File

@@ -82,6 +82,9 @@ public class AboutEditor extends Editor {
"A slightly modified version of <a href=\"https://launchpad.net/po-parser\">General PO Parser</a> by Bal<61>zs T<>th<br/>" +
"License: <a href=\"http://www.gnu.org/licenses/gpl-3.0.html\">GPL v3</a><br/>" +
"<br/>" +
"A slightly modified version of <a href=\"www.whoischarles.com\">Minify.java</a> by Charles Bihis<br/>" +
"License: <a href=\"https://github.com/charlesbihis/minify#license\">Douglas Crockford variant of MIT License</a><br/>" +
"<br/>" +
"See the tabs below to find the full license text for each of these.<br/>" +
"<br/>" +
"The Windows installer was created with:<br/>" +
@@ -134,6 +137,7 @@ public class AboutEditor extends Editor {
editorTabsHolder.add("SipHash for Java License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/LICENSE.siphash-zackehh.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text"));
editorTabsHolder.add("jsoup License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/LICENSE.jsoup.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text"));
editorTabsHolder.add("General PO Parser License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/LICENSE.GPLv3.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text"));
editorTabsHolder.add("Minify.java License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/LICENSE.minify.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text"));
editorTabsHolder.add("ATCS License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/LICENSE.GPLv3.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text"));
}

View File

@@ -22,6 +22,7 @@ import bsh.EvalError;
import bsh.Interpreter;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
import com.gpl.rpg.atcontentstudio.ui.WorkerDialog;
import com.jidesoft.swing.JideBoxLayout;
public class BeanShellView extends JFrame {
@@ -85,17 +86,29 @@ public class BeanShellView extends JFrame {
run.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Interpreter shInt = new Interpreter();
PrintStream printOut = new PrintStream(new AreaOutputStream(outArea));
final Interpreter shInt = new Interpreter();
final PrintStream printOut = new PrintStream(new AreaOutputStream(outArea));
shInt.setOut(printOut);
PrintStream printErr = new PrintStream(new AreaOutputStream(errArea));
final PrintStream printErr = new PrintStream(new AreaOutputStream(errArea));
shInt.setErr(printErr);
try {
shInt.eval(shArea.getText());
} catch (EvalError e1) {
e1.printStackTrace(printErr);
}
WorkerDialog.showTaskMessage("Running your script...", null, new Runnable() {
@Override
public void run() {
try {
shInt.eval(shArea.getText());
} catch (EvalError e1) {
e1.printStackTrace(printErr);
}
printOut.flush();
printErr.flush();
printOut.close();
printErr.close();
}
});
}
});