Merge branch 'pulls/1195352/10' workspace + project as json

This commit is contained in:
Nut.andor
2025-08-04 21:05:23 +02:00
26 changed files with 1881 additions and 2519 deletions

View File

@@ -10,7 +10,6 @@
<element id="extracted-dir" path="$PROJECT_DIR$/lib/jsoup-1.10.2.jar" path-in-jar="/" /> <element id="extracted-dir" path="$PROJECT_DIR$/lib/jsoup-1.10.2.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/json_simple-1.1.jar" path-in-jar="/" /> <element id="extracted-dir" path="$PROJECT_DIR$/lib/json_simple-1.1.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/ui.jar" path-in-jar="/" /> <element id="extracted-dir" path="$PROJECT_DIR$/lib/ui.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/AndorsTrainer_v0.1.5.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/jide-oss.jar" path-in-jar="/" /> <element id="extracted-dir" path="$PROJECT_DIR$/lib/jide-oss.jar" path-in-jar="/" />
</element> </element>
</root> </root>

View File

@@ -10,5 +10,10 @@
<option name="BINARY_OPERATION_WRAP" value="5" /> <option name="BINARY_OPERATION_WRAP" value="5" />
<option name="SOFT_MARGINS" value="120" /> <option name="SOFT_MARGINS" value="120" />
</codeStyleSettings> </codeStyleSettings>
<codeStyleSettings language="JSON">
<indentOptions>
<option name="INDENT_SIZE" value="4" />
</indentOptions>
</codeStyleSettings>
</code_scheme> </code_scheme>
</component> </component>

View File

@@ -61,6 +61,8 @@ if not exist %2\%1\.gitignore (
echo .workspace > .gitignore echo .workspace > .gitignore
echo .project >> .gitignore echo .project >> .gitignore
echo .workspace.json >> .gitignore
echo .project.json >> .gitignore
echo altered/drawable >> .gitignore echo altered/drawable >> .gitignore
echo altered/drawable/* >> .gitignore echo altered/drawable/* >> .gitignore
echo created/drawable >> .gitignore echo created/drawable >> .gitignore

Binary file not shown.

View File

@@ -31,7 +31,6 @@ EXTRA_SOURCE_DIRS=(
# --- Libraries to include --- # --- Libraries to include ---
LIBRARIES=( LIBRARIES=(
"AndorsTrainer_v0.1.5.jar"
"bsh-2.0b4.jar" "bsh-2.0b4.jar"
"jide-oss.jar" "jide-oss.jar"
"json_simple-1.1.jar" "json_simple-1.1.jar"

View File

@@ -20,6 +20,10 @@ import java.io.InputStreamReader;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.URL; import java.net.URL;
import java.net.http.HttpTimeoutException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.*; import java.util.*;
import java.util.logging.Level; import java.util.logging.Level;
@@ -183,8 +187,14 @@ public class ATContentStudio {
} }
} catch (MalformedURLException e) { } catch (MalformedURLException e) {
e.printStackTrace(); e.printStackTrace();
} catch (HttpTimeoutException e) {
System.out.println("Could not connect to url to check for updates (timeout): " + CHECK_UPDATE_URL);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); if (e.getMessage() != null && e.getMessage().startsWith("Server returned HTTP response code:")) {
System.out.println("Could not fetch current version from server to check for updates (non-success-status): " + e.getMessage());
} else {
System.out.println("Could not check for updates: '" + CHECK_UPDATE_URL + "' - " + e.getMessage());
}
} finally { } finally {
try { try {
if (in != null) if (in != null)

View File

@@ -0,0 +1,8 @@
package com.gpl.rpg.atcontentstudio.io;
import java.util.Map;
public interface JsonSerializable {
Map toMap();
void fromMap(Map map);
}

View File

@@ -1,5 +1,6 @@
package com.gpl.rpg.atcontentstudio.model; package com.gpl.rpg.atcontentstudio.model;
import com.gpl.rpg.atcontentstudio.io.JsonSerializable;
import com.gpl.rpg.atcontentstudio.model.Project.ResourceSet; import com.gpl.rpg.atcontentstudio.model.Project.ResourceSet;
import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet; import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet;
import com.gpl.rpg.atcontentstudio.model.maps.TMXMapSet; import com.gpl.rpg.atcontentstudio.model.maps.TMXMapSet;
@@ -24,7 +25,7 @@ import java.io.*;
import java.util.List; import java.util.List;
import java.util.*; import java.util.*;
public class GameSource implements ProjectTreeNode, Serializable { public class GameSource implements ProjectTreeNode, Serializable, JsonSerializable {
private static final long serialVersionUID = -1512979360971918158L; private static final long serialVersionUID = -1512979360971918158L;
@@ -38,6 +39,22 @@ public class GameSource implements ProjectTreeNode, Serializable {
public transient WriterModeDataSet writerModeDataSet; public transient WriterModeDataSet writerModeDataSet;
private transient SavedSlotCollection v; private transient SavedSlotCollection v;
@Override
public Map toMap() {
Map map = new HashMap();
map.put("type", type.toString());
map.put("baseFolder", baseFolder.getPath());
return map;
}
@Override
public void fromMap(Map map) {
if(map==null)return;
type = Enum.valueOf(Type.class, (String)map.get("type"));
baseFolder = new File((String) map.get("baseFolder"));
}
public static enum Type { public static enum Type {
source, source,
referenced, referenced,
@@ -52,6 +69,10 @@ public class GameSource implements ProjectTreeNode, Serializable {
public transient Map<String, List<String>> referencedSourceFiles = null; public transient Map<String, List<String>> referencedSourceFiles = null;
public GameSource(Map json, Project parent) {
fromMap(json);
refreshTransients(parent);
}
public GameSource(File folder, Project parent) { public GameSource(File folder, Project parent) {
this.parent = parent; this.parent = parent;
this.baseFolder = folder; this.baseFolder = folder;

View File

@@ -1,19 +1,53 @@
package com.gpl.rpg.atcontentstudio.model; package com.gpl.rpg.atcontentstudio.model;
import com.gpl.rpg.atcontentstudio.io.JsonSerializable;
import java.awt.*; import java.awt.*;
import java.io.Serializable; import java.io.Serializable;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class Preferences implements Serializable { public class Preferences implements Serializable, JsonSerializable {
private static final long serialVersionUID = 2455802658424031276L; private static final long serialVersionUID = 2455802658424031276L;
public Dimension windowSize = null; public Dimension windowSize = null;
public Map<String, Integer> splittersPositions = new HashMap<String, Integer>(); public Map<String, Integer> splittersPositions = new HashMap<>();
public Preferences() { public Preferences() {
} }
@Override
public Map toMap() {
Map map = new HashMap();
if(windowSize!= null){
Map windowSizeMap = new HashMap<>();
windowSizeMap.put("width", windowSize.width);
windowSizeMap.put("height", windowSize.height);
map.put("windowSize", windowSizeMap);
}
map.put("splittersPositions", splittersPositions);
return map;
}
@Override
public void fromMap(Map map) {
if(map == null) return;
Map windowSize1 = (Map) map.get("windowSize");
if(windowSize1 != null){
windowSize = new Dimension(((Number) windowSize1.get("width")).intValue(), ((Number) windowSize1.get("height")).intValue());
}
Map<String, Number> splitters = (Map<String, Number>) map.get("splittersPositions");
Map<String, Integer> splittersInt = new HashMap<>(splitters.size());
for (Map.Entry<String, Number> entry : splitters. entrySet()){
splittersInt.put(entry.getKey(), entry.getValue().intValue());
}
splittersPositions = splittersInt;
}
} }

File diff suppressed because it is too large Load Diff

View File

@@ -2,27 +2,29 @@ package com.gpl.rpg.atcontentstudio.model;
import com.gpl.rpg.atcontentstudio.ATContentStudio; import com.gpl.rpg.atcontentstudio.ATContentStudio;
import com.gpl.rpg.atcontentstudio.Notification; import com.gpl.rpg.atcontentstudio.Notification;
import com.gpl.rpg.atcontentstudio.io.JsonSerializable;
import com.gpl.rpg.atcontentstudio.io.SettingsSave; import com.gpl.rpg.atcontentstudio.io.SettingsSave;
import com.gpl.rpg.atcontentstudio.model.GameSource.Type; import com.gpl.rpg.atcontentstudio.model.GameSource.Type;
import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet; import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet;
import com.gpl.rpg.atcontentstudio.ui.ProjectsTree.ProjectsTreeModel; import com.gpl.rpg.atcontentstudio.ui.ProjectsTree.ProjectsTreeModel;
import com.gpl.rpg.atcontentstudio.ui.WorkerDialog; import com.gpl.rpg.atcontentstudio.ui.WorkerDialog;
import com.gpl.rpg.atcontentstudio.utils.FileUtils;
import org.jsoup.SerializationException;
import javax.swing.tree.TreeNode; import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath; import javax.swing.tree.TreePath;
import java.awt.*; import java.awt.*;
import java.io.File; import java.io.*;
import java.io.IOException;
import java.io.Serializable;
import java.nio.file.Files; import java.nio.file.Files;
import java.util.List; import java.util.List;
import java.util.*; import java.util.*;
public class Workspace implements ProjectTreeNode, Serializable { public class Workspace implements ProjectTreeNode, Serializable, JsonSerializable {
private static final long serialVersionUID = 7938633033601384956L; private static final long serialVersionUID = 7938633033601384956L;
public static final String WS_SETTINGS_FILE = ".workspace"; public static final String WS_SETTINGS_FILE = ".workspace";
public static final String WS_SETTINGS_FILE_JSON = ".workspace.json";
public static Workspace activeWorkspace; public static Workspace activeWorkspace;
@@ -38,6 +40,7 @@ public class Workspace implements ProjectTreeNode, Serializable {
public transient ProjectsTreeModel projectsTreeModel = null; public transient ProjectsTreeModel projectsTreeModel = null;
public Workspace(File workspaceRoot) { public Workspace(File workspaceRoot) {
boolean freshWorkspace = false;
baseFolder = workspaceRoot; baseFolder = workspaceRoot;
if (!workspaceRoot.exists()) { if (!workspaceRoot.exists()) {
try { try {
@@ -49,44 +52,105 @@ public class Workspace implements ProjectTreeNode, Serializable {
} }
} }
settings = new WorkspaceSettings(this); settings = new WorkspaceSettings(this);
settingsFile = new File(workspaceRoot, WS_SETTINGS_FILE); settingsFile = new File(workspaceRoot, WS_SETTINGS_FILE_JSON);
if (!settingsFile.exists()) { if (!settingsFile.exists()) {
try { try {
settingsFile.createNewFile(); settingsFile.createNewFile();
freshWorkspace = true;
} catch (IOException e) { } catch (IOException e) {
Notification.addError("Error creating workspace datafile: " Notification.addError("Error creating workspace datafile: "
+ e.getMessage()); + e.getMessage());
e.printStackTrace(); e.printStackTrace();
} }
Notification.addSuccess("New workspace created: "
+ workspaceRoot.getAbsolutePath());
} }
Notification.addSuccess("New workspace created: " if (freshWorkspace)
+ workspaceRoot.getAbsolutePath()); save();
save(); }
@Override
public Map toMap() {
Map map = new HashMap();
map.put("serialVersionUID", serialVersionUID);
map.put("preferences", preferences.toMap());
map.put("projectsName", (new ArrayList<String>(projectsName)));
map.put("projectsOpenByName", projectsOpenByName);
List<String> l = new ArrayList<>(knownMapSourcesFolders.size());
for (File f: knownMapSourcesFolders){
l.add(f.getPath());
}
map.put("knownMapSourcesFolders", l);
return map;
}
@Override
public void fromMap(Map map) {
if(serialVersionUID != (long) map.get("serialVersionUID")){
throw new SerializationException("wrong seriaVersionUID");
}
preferences.fromMap((Map) map.get("preferences"));
projectsName = new HashSet<>((List<String>) map.getOrDefault("projectsName", new HashSet<String>()));
projectsOpenByName = (Map<String, Boolean>) map.getOrDefault("projectsOpenByName", new HashMap<String, Boolean>() );
List<String> knownMapSourcesFolders1 = (List<String>) map.getOrDefault("knownMapSourcesFolders", new ArrayList<String>());
knownMapSourcesFolders = new HashSet<>();
if (knownMapSourcesFolders1 != null){
int size = knownMapSourcesFolders1.size();
for (String path: knownMapSourcesFolders1) {
//TODO: catch invalid paths...?
knownMapSourcesFolders.add(new File(path));
}
}
} }
public static void setActive(File workspaceRoot) { public static void setActive(File workspaceRoot) {
Workspace w; Workspace w;
File f = new File(workspaceRoot, WS_SETTINGS_FILE); File f2 = new File(workspaceRoot, WS_SETTINGS_FILE_JSON);
if (!workspaceRoot.exists() || !f.exists()) { if (f2.exists()) {
w = new Workspace(workspaceRoot); w = loadWorkspaceFromJson(workspaceRoot, f2);
w.refreshTransients();
} else { } else {
w = (Workspace) SettingsSave.loadInstance(f, "Workspace"); Notification.addInfo("Could not find json workspace file. Checking for binary file");
if (w == null) { File f = new File(workspaceRoot, WS_SETTINGS_FILE);
if (!workspaceRoot.exists() || !f.exists()) {
w = new Workspace(workspaceRoot); w = new Workspace(workspaceRoot);
} else { } else {
w.refreshTransients(); w = (Workspace) SettingsSave.loadInstance(f, "Workspace");
if (w == null) {
w = new Workspace(workspaceRoot);
} else {
w.settingsFile = f2;
w.baseFolder = workspaceRoot;
Notification.addInfo("Switched workspace to json format.");
w.refreshTransients();
}
w.save();
} }
} }
activeWorkspace = w; activeWorkspace = w;
} }
private static Workspace loadWorkspaceFromJson(File workspaceRoot, File settingsFile) {
Workspace w = w = new Workspace(workspaceRoot);
Map json = FileUtils.mapFromJsonFile(settingsFile);
if (json!= null) {
w.fromMap(json);
}
return w;
}
public static void saveActive() { public static void saveActive() {
activeWorkspace.save(); activeWorkspace.save();
} }
public void save() { public void save() {
settings.save(); settings.save();
SettingsSave.saveInstance(this, settingsFile, "Workspace"); FileUtils.writeStringToFile(FileUtils.toJsonString(this), settingsFile, "Workspace");
} }
@Override @Override
@@ -356,5 +420,4 @@ public class Workspace implements ProjectTreeNode, Serializable {
} }
return false; return false;
} }
} }

View File

@@ -1,8 +1,7 @@
package com.gpl.rpg.atcontentstudio.model; package com.gpl.rpg.atcontentstudio.model;
import com.gpl.rpg.atcontentstudio.Notification; import com.gpl.rpg.atcontentstudio.Notification;
import com.gpl.rpg.atcontentstudio.io.JsonPrettyWriter; import com.gpl.rpg.atcontentstudio.utils.FileUtils;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser; import org.json.simple.parser.JSONParser;
import java.io.*; import java.io.*;
@@ -108,22 +107,8 @@ public class WorkspaceSettings {
} }
json.put(VERSION_KEY, SETTINGS_VERSION); json.put(VERSION_KEY, SETTINGS_VERSION);
StringWriter writer = new JsonPrettyWriter(); String toWrite = FileUtils.toJsonString(json);
try { FileUtils.writeStringToFile(toWrite, file, "Workspace settings");
JSONObject.writeJSONString(json, writer);
} catch (IOException e) {
//Impossible with a StringWriter
}
String toWrite = writer.toString();
try {
FileWriter w = new FileWriter(file);
w.write(toWrite);
w.close();
Notification.addSuccess("Workspace settings saved.");
} catch (IOException e) {
Notification.addError("Error while saving workspace settings : " + e.getMessage());
e.printStackTrace();
}
} }
public void resetDefault() { public void resetDefault() {

View File

@@ -5,6 +5,7 @@ import com.gpl.rpg.atcontentstudio.io.JsonPrettyWriter;
import com.gpl.rpg.atcontentstudio.model.*; import com.gpl.rpg.atcontentstudio.model.*;
import com.gpl.rpg.atcontentstudio.model.GameSource.Type; import com.gpl.rpg.atcontentstudio.model.GameSource.Type;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons; import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
import com.gpl.rpg.atcontentstudio.utils.FileUtils;
import org.json.simple.JSONArray; import org.json.simple.JSONArray;
import javax.swing.tree.TreeNode; import javax.swing.tree.TreeNode;
@@ -157,26 +158,13 @@ public class GameDataCategory<E extends JSONElement> extends ArrayList<E> implem
return; return;
} }
StringWriter writer = new JsonPrettyWriter();
try { String toWrite = FileUtils.toJsonString(dataToSave);
JSONArray.writeJSONString(dataToSave, writer); if(FileUtils.writeStringToFile(toWrite, jsonFile, "JSON file '"+jsonFile.getAbsolutePath()+"'")){
} catch (IOException e) {
//Impossible with a StringWriter
}
String toWrite = writer.toString();
try {
FileWriter w = new FileWriter(jsonFile);
w.write(toWrite);
w.close();
for (E element : this) { for (E element : this) {
element.state = GameDataElement.State.saved; element.state = GameDataElement.State.saved;
} }
Notification.addSuccess("Json file " + jsonFile.getAbsolutePath() + " saved.");
} catch (IOException e) {
Notification.addError("Error while writing json file " + jsonFile.getAbsolutePath() + " : " + e.getMessage());
e.printStackTrace();
} }
} }

View File

@@ -4,6 +4,7 @@ import com.gpl.rpg.atcontentstudio.Notification;
import com.gpl.rpg.atcontentstudio.io.JsonPrettyWriter; import com.gpl.rpg.atcontentstudio.io.JsonPrettyWriter;
import com.gpl.rpg.atcontentstudio.model.GameDataElement; import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.SaveEvent; import com.gpl.rpg.atcontentstudio.model.SaveEvent;
import com.gpl.rpg.atcontentstudio.utils.FileUtils;
import org.json.simple.JSONObject; import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser; import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException; import org.json.simple.parser.ParseException;
@@ -73,16 +74,10 @@ public abstract class JSONElement extends GameDataElement {
public abstract Map toJson(); public abstract Map toJson();
public String toJsonString() { public String toJsonString() {
StringWriter writer = new JsonPrettyWriter(); Map json = this.toJson();
try { return FileUtils.toJsonString(json);
JSONObject.writeJSONString(this.toJson(), writer);
} catch (IOException e) {
//Impossible with a StringWriter
}
return writer.toString();
} }
@Override @Override
public GameDataSet getDataSet() { public GameDataSet getDataSet() {
if (parent == null) { if (parent == null) {

View File

@@ -1,185 +0,0 @@
package com.gpl.rpg.atcontentstudio.model.saves;
import com.gpl.rpg.andorstrainer.io.SavedGameIO;
import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.GameSource.Type;
import com.gpl.rpg.atcontentstudio.model.Project;
import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode;
import com.gpl.rpg.atcontentstudio.model.SaveEvent;
import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
import javax.swing.tree.TreeNode;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
public class SavedGame extends GameDataElement {
private static final long serialVersionUID = -6443495534761084990L;
public File savedFile;
transient public com.gpl.rpg.andorstrainer.model.SavedGame loadedSave = null;
transient public SavedGamesSet parent;
public SavedGame(SavedGamesSet parent, File f) throws IOException {
savedFile = f;
refreshTransients(parent);
}
public void refreshTransients(SavedGamesSet parent) throws IOException {
this.parent = parent;
this.loadedSave = SavedGameIO.loadFile(savedFile);
if (this.loadedSave == null) {
throw new IOException("Unable to load save: " + savedFile.getAbsolutePath());
}
}
@Override
public Enumeration<ProjectTreeNode> children() {
return null;
}
@Override
public boolean getAllowsChildren() {
return false;
}
@Override
public TreeNode getChildAt(int arg0) {
return null;
}
@Override
public int getChildCount() {
return 0;
}
@Override
public int getIndex(TreeNode arg0) {
return 0;
}
@Override
public TreeNode getParent() {
return parent;
}
@Override
public boolean isLeaf() {
return true;
}
@Override
public void childrenAdded(List<ProjectTreeNode> path) {
path.add(0, this);
parent.childrenAdded(path);
}
@Override
public void childrenChanged(List<ProjectTreeNode> path) {
path.add(0, this);
parent.childrenChanged(path);
}
@Override
public void childrenRemoved(List<ProjectTreeNode> path) {
path.add(0, this);
parent.childrenRemoved(path);
}
@Override
public void notifyCreated() {
childrenAdded(new ArrayList<ProjectTreeNode>());
}
@Override
public String getDesc() {
return (needsSaving() ? "*" : "") + loadedSave.displayInfo;
}
@Override
public Project getProject() {
return parent.getProject();
}
@Override
public Image getIcon() {
return DefaultIcons.getHeroIcon();
}
@Override
public Image getLeafIcon() {
return DefaultIcons.getHeroIcon();
}
@Override
public Image getClosedIcon() {
return null;
}
@Override
public Image getOpenIcon() {
return null;
}
@Override
public GameDataSet getDataSet() {
return null;
}
@Override
public Type getDataType() {
return null;
}
@Override
public boolean isEmpty() {
return false;
}
@Override
public void parse() {
// TODO Auto-generated method stub
}
@Override
public void link() {
// TODO Auto-generated method stub
}
@Override
public GameDataElement clone() {
// TODO Auto-generated method stub
return null;
}
@Override
public void elementChanged(GameDataElement oldOne, GameDataElement newOne) {
// TODO Auto-generated method stub
}
@Override
public String getProjectFilename() {
// TODO Auto-generated method stub
return null;
}
@Override
public void save() {
// TODO Auto-generated method stub
}
@Override
public List<SaveEvent> attemptSave() {
// TODO Auto-generated method stub
return null;
}
}

View File

@@ -1,188 +0,0 @@
package com.gpl.rpg.atcontentstudio.model.saves;
import com.gpl.rpg.atcontentstudio.Notification;
import com.gpl.rpg.atcontentstudio.model.GameSource.Type;
import com.gpl.rpg.atcontentstudio.model.Project;
import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode;
import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
import javax.swing.tree.TreeNode;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Vector;
public class SavedGamesSet implements ProjectTreeNode, Serializable {
private static final long serialVersionUID = -6565834239789184087L;
public Vector<SavedGame> saves; //For simulations.
public Project parent;
public SavedGamesSet(Project parent) {
this.parent = parent;
saves = new Vector<SavedGame>();
}
public void refreshTransients() {
for (SavedGame save : saves) {
try {
save.refreshTransients(this);
} catch (IOException e) {
Notification.addError(e.getMessage());
}
}
}
public void addSave(File f) {
try {
ProjectTreeNode higherEmptyParent = this;
while (higherEmptyParent != null) {
if (higherEmptyParent.getParent() != null && ((ProjectTreeNode) higherEmptyParent.getParent()).isEmpty())
higherEmptyParent = (ProjectTreeNode) higherEmptyParent.getParent();
else break;
}
if (higherEmptyParent == this && !this.isEmpty()) higherEmptyParent = null;
SavedGame node = new SavedGame(this, f);
saves.add(node);
if (higherEmptyParent != null) higherEmptyParent.notifyCreated();
else node.notifyCreated();
} catch (IOException e) {
Notification.addError(e.getMessage());
}
}
public SavedGame getSave(File f) {
for (SavedGame save : saves) {
if (save.savedFile.equals(f)) return save;
}
return null;
}
@Override
public Enumeration<? extends ProjectTreeNode> children() {
return saves.elements();
}
@Override
public boolean getAllowsChildren() {
return true;
}
@Override
public TreeNode getChildAt(int arg0) {
return saves.elementAt(arg0);
}
@Override
public int getChildCount() {
return saves.size();
}
@Override
public int getIndex(TreeNode arg0) {
return saves.indexOf(arg0);
}
@Override
public TreeNode getParent() {
return parent;
}
@Override
public boolean isLeaf() {
return false;
}
@Override
public void childrenAdded(List<ProjectTreeNode> path) {
path.add(0, this);
parent.childrenAdded(path);
}
@Override
public void childrenChanged(List<ProjectTreeNode> path) {
path.add(0, this);
parent.childrenChanged(path);
}
@Override
public void childrenRemoved(List<ProjectTreeNode> path) {
if (path.size() == 1 && this.getChildCount() == 1) {
childrenRemoved(new ArrayList<ProjectTreeNode>());
} else {
path.add(0, this);
parent.childrenRemoved(path);
}
}
@Override
public void notifyCreated() {
childrenAdded(new ArrayList<ProjectTreeNode>());
for (SavedGame s : saves) {
s.notifyCreated();
}
}
@Override
public String getDesc() {
return (needsSaving() ? "*" : "") + "Saved games";
}
@Override
public Project getProject() {
return parent.getProject();
}
@Override
public Image getIcon() {
return getOpenIcon();
}
@Override
public Image getClosedIcon() {
return DefaultIcons.getSavClosedIcon();
}
@Override
public Image getLeafIcon() {
return DefaultIcons.getSavClosedIcon();
}
@Override
public Image getOpenIcon() {
return DefaultIcons.getSavOpenIcon();
}
@Override
public GameDataSet getDataSet() {
return null;
}
@Override
public Type getDataType() {
return null;
}
@Override
public boolean isEmpty() {
return saves.isEmpty();
}
@Override
public boolean needsSaving() {
for (ProjectTreeNode node : saves) {
if (node.needsSaving()) return true;
}
return false;
}
}

View File

@@ -10,9 +10,7 @@ import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
import javax.swing.tree.TreeNode; import javax.swing.tree.TreeNode;
import java.awt.*; import java.awt.*;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.*;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List; import java.util.List;
public class SpriteSheetSet implements ProjectTreeNode { public class SpriteSheetSet implements ProjectTreeNode {
@@ -44,6 +42,7 @@ public class SpriteSheetSet implements ProjectTreeNode {
} }
} }
} }
spritesheets.sort(Comparator.comparing(s -> s.id));
} }
@Override @Override

View File

@@ -145,16 +145,12 @@ public class ResourcesCompactor {
private Minify jsonMinifier = new Minify(); private Minify jsonMinifier = new Minify();
private void writeJson(List<Map> dataToSave, File target) { private void writeJson(List<Map> dataToSave, File target) {
StringWriter writer = new JsonPrettyWriter(); String toWrite = FileUtils.toJsonString(dataToSave);
try { toWrite = jsonMinifier.minify(toWrite);
JSONArray.writeJSONString(dataToSave, writer); FileUtils.writeStringToFile(toWrite, target, null);
} catch (IOException e) {
//Impossible with a StringWriter
}
String toWrite = writer.toString();
try { try {
FileWriter w = new FileWriter(target); FileWriter w = new FileWriter(target);
w.write(jsonMinifier.minify(toWrite)); w.write(toWrite);
w.close(); w.close();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();

View File

@@ -6,6 +6,7 @@ import com.gpl.rpg.atcontentstudio.model.*;
import com.gpl.rpg.atcontentstudio.model.GameSource.Type; import com.gpl.rpg.atcontentstudio.model.GameSource.Type;
import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet; import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons; import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
import com.gpl.rpg.atcontentstudio.utils.FileUtils;
import org.json.simple.JSONArray; import org.json.simple.JSONArray;
import org.json.simple.parser.JSONParser; import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException; import org.json.simple.parser.ParseException;
@@ -155,24 +156,12 @@ public class WriterModeDataSet implements ProjectTreeNode, Serializable {
return; return;
} }
StringWriter writer = new JsonPrettyWriter();
try { String toWrite = FileUtils.toJsonString(dataToSave);
JSONArray.writeJSONString(dataToSave, writer); if(FileUtils.writeStringToFile(toWrite, writerFile, "Json file " + writerFile.getAbsolutePath())) {
} catch (IOException e) {
//Impossible with a StringWriter
}
String toWrite = writer.toString();
try {
FileWriter w = new FileWriter(writerFile);
w.write(toWrite);
w.close();
for (WriterModeData element : writerModeDataList) { for (WriterModeData element : writerModeDataList) {
element.state = GameDataElement.State.saved; element.state = GameDataElement.State.saved;
} }
Notification.addSuccess("Json file " + writerFile.getAbsolutePath() + " saved.");
} catch (IOException e) {
Notification.addError("Error while writing json file " + writerFile.getAbsolutePath() + " : " + e.getMessage());
e.printStackTrace();
} }
} }

View File

@@ -4,13 +4,11 @@ import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode;
import com.gpl.rpg.atcontentstudio.model.gamedata.*; import com.gpl.rpg.atcontentstudio.model.gamedata.*;
import com.gpl.rpg.atcontentstudio.model.maps.TMXMap; import com.gpl.rpg.atcontentstudio.model.maps.TMXMap;
import com.gpl.rpg.atcontentstudio.model.maps.WorldmapSegment; import com.gpl.rpg.atcontentstudio.model.maps.WorldmapSegment;
import com.gpl.rpg.atcontentstudio.model.saves.SavedGame;
import com.gpl.rpg.atcontentstudio.model.sprites.Spritesheet; import com.gpl.rpg.atcontentstudio.model.sprites.Spritesheet;
import com.gpl.rpg.atcontentstudio.model.tools.writermode.WriterModeData; import com.gpl.rpg.atcontentstudio.model.tools.writermode.WriterModeData;
import com.gpl.rpg.atcontentstudio.ui.gamedataeditors.*; import com.gpl.rpg.atcontentstudio.ui.gamedataeditors.*;
import com.gpl.rpg.atcontentstudio.ui.map.TMXMapEditor; import com.gpl.rpg.atcontentstudio.ui.map.TMXMapEditor;
import com.gpl.rpg.atcontentstudio.ui.map.WorldMapEditor; import com.gpl.rpg.atcontentstudio.ui.map.WorldMapEditor;
import com.gpl.rpg.atcontentstudio.ui.saves.SavedGameEditor;
import com.gpl.rpg.atcontentstudio.ui.sprites.SpritesheetEditor; import com.gpl.rpg.atcontentstudio.ui.sprites.SpritesheetEditor;
import com.gpl.rpg.atcontentstudio.ui.tools.writermode.WriterModeEditor; import com.gpl.rpg.atcontentstudio.ui.tools.writermode.WriterModeEditor;
import com.jidesoft.swing.JideTabbedPane; import com.jidesoft.swing.JideTabbedPane;
@@ -129,15 +127,6 @@ public class EditorsArea extends JPanel {
} }
public void openEditor(SavedGame save) {
if (editors.containsKey(save)) {
tabHolder.setSelectedComponent(editors.get(save));
return;
}
openEditor(new SavedGameEditor(save));
}
public void openEditor(WorldmapSegment node) { public void openEditor(WorldmapSegment node) {
if (editors.containsKey(node)) { if (editors.containsKey(node)) {
tabHolder.setSelectedComponent(editors.get(node)); tabHolder.setSelectedComponent(editors.get(node));

View File

@@ -1,6 +1,5 @@
package com.gpl.rpg.atcontentstudio.ui; package com.gpl.rpg.atcontentstudio.ui;
import com.gpl.rpg.andorstrainer.AndorsTrainer;
import com.gpl.rpg.atcontentstudio.ATContentStudio; import com.gpl.rpg.atcontentstudio.ATContentStudio;
import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode; import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode;
import com.gpl.rpg.atcontentstudio.model.Workspace; import com.gpl.rpg.atcontentstudio.model.Workspace;
@@ -8,7 +7,6 @@ import com.gpl.rpg.atcontentstudio.model.bookmarks.BookmarkEntry;
import com.gpl.rpg.atcontentstudio.model.gamedata.JSONElement; import com.gpl.rpg.atcontentstudio.model.gamedata.JSONElement;
import com.gpl.rpg.atcontentstudio.model.maps.TMXMap; import com.gpl.rpg.atcontentstudio.model.maps.TMXMap;
import com.gpl.rpg.atcontentstudio.model.maps.WorldmapSegment; import com.gpl.rpg.atcontentstudio.model.maps.WorldmapSegment;
import com.gpl.rpg.atcontentstudio.model.saves.SavedGame;
import com.gpl.rpg.atcontentstudio.model.sprites.Spritesheet; import com.gpl.rpg.atcontentstudio.model.sprites.Spritesheet;
import com.gpl.rpg.atcontentstudio.model.tools.writermode.WriterModeData; import com.gpl.rpg.atcontentstudio.model.tools.writermode.WriterModeData;
import com.jidesoft.swing.TreeSearchable; import com.jidesoft.swing.TreeSearchable;
@@ -36,12 +34,6 @@ public class ProjectsTree extends JPanel {
private JPopupMenu popupMenu; private JPopupMenu popupMenu;
private Thread konamiTimeout = null;
private boolean exit = false;
private int timeout = 200;
private Integer[] konamiBuffer = new Integer[]{null, null, null, null, null, null, null, null, null, null};
private boolean konamiCodeEntered = false;
public ProjectsTree() { public ProjectsTree() {
super(); super();
setLayout(new BorderLayout()); setLayout(new BorderLayout());
@@ -68,22 +60,6 @@ public class ProjectsTree extends JPanel {
if (projectsTree.getSelectionPath() != null) { if (projectsTree.getSelectionPath() != null) {
itemAction((ProjectTreeNode) projectsTree.getSelectionPath().getLastPathComponent()); itemAction((ProjectTreeNode) projectsTree.getSelectionPath().getLastPathComponent());
} }
} else {
if (konamiTimeout == null) {
startKonamiCount();
}
int i = 0;
while (i < konamiBuffer.length && konamiBuffer[i] != null) {
i++;
}
if (i < konamiBuffer.length) {
konamiBuffer[i] = e.getKeyCode();
if (!compareBuffers()) {
exit = true;
} else {
resetTimeout();
}
}
} }
} }
}); });
@@ -198,10 +174,6 @@ public class ProjectsTree extends JPanel {
addNextSeparator = true; addNextSeparator = true;
popupMenu.add(new JMenuItem(actions.createWorldmap)); popupMenu.add(new JMenuItem(actions.createWorldmap));
} }
if (actions.loadSave.isEnabled()) {
addNextSeparator = true;
popupMenu.add(new JMenuItem(actions.loadSave));
}
if (addNextSeparator) { if (addNextSeparator) {
popupMenu.add(new JSeparator()); popupMenu.add(new JSeparator());
addNextSeparator = false; addNextSeparator = false;
@@ -245,311 +217,6 @@ public class ProjectsTree extends JPanel {
popupMenu.add(new JSeparator()); popupMenu.add(new JSeparator());
addNextSeparator = false; addNextSeparator = false;
} }
if (konamiCodeEntered) {
JMenuItem openTrainer = new JMenuItem("Start Andor's Trainer...");
popupMenu.add(openTrainer);
popupMenu.addSeparator();
openTrainer.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
new Thread() {
public void run() {
AndorsTrainer.startApp(false);
}
}.start();
}
});
}
// if (projectsTree.getSelectionPath() == null || projectsTree.getSelectionPath().getLastPathComponent() == null) {
// JMenuItem addProject = new JMenuItem("Create project...");
// popupMenu.add(addProject);
// addProject.addActionListener(new ActionListener() {
// @Override
// public void actionPerformed(ActionEvent e) {
// new ProjectCreationWizard().setVisible(true);
// }
// });
// popupMenu.addSeparator();
// } else if (projectsTree.getSelectionPaths().length > 1) {
// boolean deleteAll = false;
// final List<GameDataElement> elementsToDelete = new ArrayList<GameDataElement>();
// for (TreePath selected : projectsTree.getSelectionPaths()) {
// if (selected.getLastPathComponent() instanceof GameDataElement && ((GameDataElement)selected.getLastPathComponent()).writable) {
// elementsToDelete.add((GameDataElement) selected.getLastPathComponent());
// deleteAll = true;
// } else {
// deleteAll = false;
// break;
// }
// }
// if (deleteAll) {
// JMenuItem deleteItems = new JMenuItem("Delete all selected elements");
// popupMenu.add(deleteItems);
// deleteItems.addActionListener(new ActionListener() {
// @Override
// public void actionPerformed(ActionEvent e) {
// final Map<GameDataCategory<JSONElement>, Set<File>> impactedCategories = new IdentityHashMap<GameDataCategory<JSONElement>, Set<File>>();
// for (GameDataElement element : elementsToDelete) {
// ATContentStudio.frame.closeEditor(element);
// element.childrenRemoved(new ArrayList<ProjectTreeNode>());
// if (element instanceof JSONElement) {
// @SuppressWarnings("unchecked")
// GameDataCategory<JSONElement> category = (GameDataCategory<JSONElement>) element.getParent();
// category.remove(element);
// if (impactedCategories.get(category) == null) {
// impactedCategories.put(category, new HashSet<File>());
// }
// impactedCategories.get(category).add(((JSONElement) element).jsonFile);
// } else if (element instanceof TMXMap) {
// TMXMapSet parent = (TMXMapSet) element.getParent();
// parent.tmxMaps.remove(element);
// }
// }
// new Thread() {
// @Override
// public void run() {
// final List<SaveEvent> events = new ArrayList<SaveEvent>();
// List<SaveEvent> catEvents = null;
// for (GameDataCategory<JSONElement> category : impactedCategories.keySet()) {
// for (File f : impactedCategories.get(category)) {
// catEvents = category.attemptSave(true, f.getName());
// if (catEvents.isEmpty()) {
// category.save(f);
// } else {
// events.addAll(catEvents);
// }
// }
// }
// if (!events.isEmpty()) {
// new SaveItemsWizard(events, null).setVisible(true);
// }
// }
// }.start();
// }
// });
// }
//
// popupMenu.addSeparator();
// } else {
// final ProjectTreeNode selected = (ProjectTreeNode) projectsTree.getSelectionPath().getLastPathComponent();
// if (selected instanceof Project) {
// JMenuItem closeProject = new JMenuItem("Close Project...");
// JMenuItem deleteProject = new JMenuItem("Delete Project...");
// popupMenu.add(closeProject);
// popupMenu.add(deleteProject);
// popupMenu.addSeparator();
// closeProject.addActionListener(new ActionListener() {
// @Override
// public void actionPerformed(ActionEvent e) {
// Workspace.closeProject((Project) selected);
// }
// });
// deleteProject.addActionListener(new ActionListener() {
// @Override
// public void actionPerformed(ActionEvent e) {
// int confirm = JOptionPane.showConfirmDialog(ProjectsTree.this, "Are you sure you wish to delete this project ?\nAll files created for it will be deleted too...", "Delete this project ?", JOptionPane.OK_CANCEL_OPTION);
// if (confirm == JOptionPane.OK_OPTION) {
// Workspace.deleteProject(((Project)projectsTree.getSelectionPath().getLastPathComponent()));
// }
// }
// });
// }
// if (selected instanceof ClosedProject) {
// JMenuItem openProject = new JMenuItem("Open Project...");
// JMenuItem deleteProject = new JMenuItem("Delete Project...");
// popupMenu.add(openProject);
// popupMenu.add(deleteProject);
// popupMenu.addSeparator();
// openProject.addActionListener(new ActionListener() {
// @Override
// public void actionPerformed(ActionEvent e) {
// Workspace.openProject(((ClosedProject)selected));
// }
// });
// deleteProject.addActionListener(new ActionListener() {
// @Override
// public void actionPerformed(ActionEvent e) {
// int confirm = JOptionPane.showConfirmDialog(ProjectsTree.this, "Are you sure you wish to delete this project ?\nAll files created for it will be deleted too...", "Delete this project ?", JOptionPane.OK_CANCEL_OPTION);
// if (confirm == JOptionPane.OK_OPTION) {
// Workspace.deleteProject(((ClosedProject)selected));
// }
// }
// });
// }
// if (selected.getProject() != null) {
// final Project proj = ((ProjectTreeNode)selected).getProject();
// JMenuItem createGDE = new JMenuItem("Create Game Data Element (JSON)");
// popupMenu.add(createGDE);
// createGDE.addActionListener(new ActionListener() {
// @Override
// public void actionPerformed(ActionEvent e) {
// new JSONCreationWizard(proj).setVisible(true);
// }
// });
// JMenuItem importJson = new JMenuItem("Import JSON data");
// popupMenu.add(importJson);
// importJson.addActionListener(new ActionListener() {
// @Override
// public void actionPerformed(ActionEvent e) {
// new JSONImportWizard(proj).setVisible(true);
// }
// });
// //TODO move somewhere else
// JMenu compareElementsMenu = new JMenu("Open comparator for...");
// JMenuItem compareItems = new JMenuItem("Items");
// compareElementsMenu.add(compareItems);
// compareItems.addActionListener(new ActionListener() {
// @Override
// public void actionPerformed(ActionEvent e) {
// ATContentStudio.frame.editors.openEditor(new ItemsTableView(selected.getProject()));
// }
// });
// JMenuItem compareNPCs = new JMenuItem("NPCs");
// compareElementsMenu.add(compareNPCs);
// compareNPCs.addActionListener(new ActionListener() {
// @Override
// public void actionPerformed(ActionEvent e) {
// ATContentStudio.frame.editors.openEditor(new NPCsTableView(selected.getProject()));
// }
// });
// popupMenu.add(compareElementsMenu);
//
// JMenuItem exportProjectPackage = new JMenuItem("Export project");
// exportProjectPackage.addActionListener(new ActionListener() {
// @Override
// public void actionPerformed(ActionEvent e) {
// JFileChooser chooser = new JFileChooser() {
// private static final long serialVersionUID = 8039332384370636746L;
// public boolean accept(File f) {
// return f.isDirectory() || f.getName().endsWith(".zip") || f.getName().endsWith(".ZIP");
// }
// };
// chooser.setMultiSelectionEnabled(false);
// int result = chooser.showSaveDialog(ATContentStudio.frame);
// if (result == JFileChooser.APPROVE_OPTION) {
// selected.getProject().generateExportPackage(chooser.getSelectedFile());
// }
// }
// });
// popupMenu.add(exportProjectPackage);
// popupMenu.addSeparator();
// }
// if (selected instanceof GameDataElement) {
// final GameDataElement node = ((GameDataElement)selected);
// if (node.state == GameDataElement.State.modified){
// JMenuItem saveItem = new JMenuItem("Save this element");
// saveItem.addActionListener(new ActionListener() {
// @Override
// public void actionPerformed(ActionEvent e) {
// node.save();
// ATContentStudio.frame.nodeChanged(node);
// }
// });
// popupMenu.add(saveItem);
// }
//
// JMenuItem deleteItem = null;
// if (node.getDataType() == GameSource.Type.created) {
// deleteItem = new JMenuItem("Delete this element");
// } else if (node.getDataType() == GameSource.Type.altered) {
// deleteItem = new JMenuItem("Revert to original");
// }
// if (deleteItem != null) {
// popupMenu.add(deleteItem);
// deleteItem.addActionListener(new ActionListener() {
// @SuppressWarnings("unchecked")
// @Override
// public void actionPerformed(ActionEvent e) {
// ATContentStudio.frame.closeEditor(node);
// new Thread() {
// @Override
// public void run() {
// node.childrenRemoved(new ArrayList<ProjectTreeNode>());
// if (node.getParent() instanceof GameDataCategory<?>) {
// ((GameDataCategory<?>)node.getParent()).remove(node);
// List<SaveEvent> events = node.attemptSave();
// if (events == null || events.isEmpty()) {
// node.save();
// } else {
// new SaveItemsWizard(events, null).setVisible(true);
// }
// }
// }
// }.start();
// }
// });
// }
// popupMenu.addSeparator();
//
// }
// if (selected instanceof Project || selected instanceof SavedGamesSet) {
// JMenuItem addSave = new JMenuItem("Load saved game...");
// popupMenu.add(addSave);
// popupMenu.addSeparator();
// addSave.addActionListener(new ActionListener() {
// @Override
// public void actionPerformed(ActionEvent e) {
// JFileChooser chooser = new JFileChooser("Select an Andor's Trail save file");
// if (chooser.showOpenDialog(ATContentStudio.frame) == JFileChooser.APPROVE_OPTION) {
// selected.getProject().addSave(chooser.getSelectedFile());
// selected.getProject().save();
// }
// }
// });
//
// }
// }
// if (konamiCodeEntered) {
// JMenuItem openTrainer = new JMenuItem("Start Andor's Trainer...");
// popupMenu.add(openTrainer);
// popupMenu.addSeparator();
// openTrainer.addActionListener(new ActionListener() {
// @Override
// public void actionPerformed(ActionEvent e) {
// new Thread() {
// public void run() {
// AndorsTrainer.startApp(false);
// }
// }.start();
// }
// });
// }
// JMenu changeLaF = new JMenu("Change Look and Feel");
// for (final LookAndFeelInfo i : UIManager.getInstalledLookAndFeels()) {
// final JMenuItem lafItem = new JMenuItem("Switch to "+i.getName());
// changeLaF.add(lafItem);
// lafItem.addActionListener(new ActionListener() {
// @Override
// public void actionPerformed(ActionEvent e) {
// try {
// UIManager.setLookAndFeel(i.getClassName());
// SwingUtilities.updateComponentTreeUI(ATContentStudio.frame);
// ConfigCache.setFavoriteLaFClassName(i.getClassName());
// } catch (ClassNotFoundException e1) {
// e1.printStackTrace();
// } catch (InstantiationException e1) {
// e1.printStackTrace();
// } catch (IllegalAccessException e1) {
// e1.printStackTrace();
// } catch (UnsupportedLookAndFeelException e1) {
// e1.printStackTrace();
// }
// }
// });
// }
// popupMenu.add(changeLaF);
// popupMenu.addSeparator();
// JMenuItem showAbout = new JMenuItem("About...");
// popupMenu.add(showAbout);
// popupMenu.addSeparator();
// showAbout.addActionListener(new ActionListener() {
// @Override
// public void actionPerformed(ActionEvent e) {
// ATContentStudio.frame.showAbout();
// }
// });
} }
public void popupActivated(MouseEvent e) { public void popupActivated(MouseEvent e) {
@@ -584,10 +251,6 @@ public class ProjectsTree extends JPanel {
ATContentStudio.frame.openEditor((WriterModeData) node); ATContentStudio.frame.openEditor((WriterModeData) node);
} else if (node instanceof BookmarkEntry) { } else if (node instanceof BookmarkEntry) {
ATContentStudio.frame.openEditor(((BookmarkEntry) node).bookmarkedElement); ATContentStudio.frame.openEditor(((BookmarkEntry) node).bookmarkedElement);
} else if (node instanceof SavedGame) {
if (konamiCodeEntered) {
ATContentStudio.frame.openEditor((SavedGame) node);
}
} }
} }
@@ -704,65 +367,4 @@ public class ProjectsTree extends JPanel {
projectsTree.scrollPathToVisible(tp); projectsTree.scrollPathToVisible(tp);
} }
protected void startKonamiCount() {
resetTimeout();
exit = false;
konamiTimeout = new Thread() {
@Override
public void run() {
while (!exit && timeout > 0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
timeout -= 10;
}
konamiTimeout = null;
konamiBuffer = new Integer[]{null, null, null, null, null, null, null, null, null, null};
}
};
konamiTimeout.start();
}
protected void resetTimeout() {
timeout = 400;
}
protected boolean compareBuffers() {
if (konamiBuffer[0] == null) return true;
else if (konamiBuffer[0] != KeyEvent.VK_UP) return false;
if (konamiBuffer[1] == null) return true;
else if (konamiBuffer[1] != KeyEvent.VK_UP) return false;
if (konamiBuffer[2] == null) return true;
else if (konamiBuffer[2] != KeyEvent.VK_DOWN) return false;
if (konamiBuffer[3] == null) return true;
else if (konamiBuffer[3] != KeyEvent.VK_DOWN) return false;
if (konamiBuffer[4] == null) return true;
else if (konamiBuffer[4] != KeyEvent.VK_LEFT) return false;
if (konamiBuffer[5] == null) return true;
else if (konamiBuffer[5] != KeyEvent.VK_RIGHT) return false;
if (konamiBuffer[6] == null) return true;
else if (konamiBuffer[6] != KeyEvent.VK_LEFT) return false;
if (konamiBuffer[7] == null) return true;
else if (konamiBuffer[7] != KeyEvent.VK_RIGHT) return false;
if (konamiBuffer[8] == null) return true;
else if (konamiBuffer[8] != KeyEvent.VK_B) return false;
if (konamiBuffer[9] == null) return true;
else if (konamiBuffer[9] != KeyEvent.VK_A) return false;
konamiCodeEntered = true;
exit = true;
return true;
}
} }

View File

@@ -8,7 +8,6 @@ import com.gpl.rpg.atcontentstudio.model.Workspace;
import com.gpl.rpg.atcontentstudio.model.gamedata.JSONElement; import com.gpl.rpg.atcontentstudio.model.gamedata.JSONElement;
import com.gpl.rpg.atcontentstudio.model.maps.TMXMap; import com.gpl.rpg.atcontentstudio.model.maps.TMXMap;
import com.gpl.rpg.atcontentstudio.model.maps.WorldmapSegment; import com.gpl.rpg.atcontentstudio.model.maps.WorldmapSegment;
import com.gpl.rpg.atcontentstudio.model.saves.SavedGame;
import com.gpl.rpg.atcontentstudio.model.sprites.Spritesheet; import com.gpl.rpg.atcontentstudio.model.sprites.Spritesheet;
import com.gpl.rpg.atcontentstudio.model.tools.writermode.WriterModeData; import com.gpl.rpg.atcontentstudio.model.tools.writermode.WriterModeData;
@@ -127,7 +126,6 @@ public class StudioFrame extends JFrame {
projectMenu.add(new JMenuItem(actions.importJSON)); projectMenu.add(new JMenuItem(actions.importJSON));
projectMenu.add(new JMenuItem(actions.createMap)); projectMenu.add(new JMenuItem(actions.createMap));
projectMenu.add(new JMenuItem(actions.createWorldmap)); projectMenu.add(new JMenuItem(actions.createWorldmap));
projectMenu.add(new JMenuItem(actions.loadSave));
getJMenuBar().add(projectMenu); getJMenuBar().add(projectMenu);
JMenu toolsMenu = new JMenu("Tools"); JMenu toolsMenu = new JMenu("Tools");
@@ -204,10 +202,6 @@ public class StudioFrame extends JFrame {
} }
} }
public void openEditor(SavedGame save) {
editors.openEditor(save);
}
public void openEditor(WorldmapSegment node) { public void openEditor(WorldmapSegment node) {
editors.openEditor(node); editors.openEditor(node);
} }

View File

@@ -6,7 +6,6 @@ import com.gpl.rpg.atcontentstudio.model.gamedata.*;
import com.gpl.rpg.atcontentstudio.model.maps.TMXMap; import com.gpl.rpg.atcontentstudio.model.maps.TMXMap;
import com.gpl.rpg.atcontentstudio.model.maps.Worldmap; import com.gpl.rpg.atcontentstudio.model.maps.Worldmap;
import com.gpl.rpg.atcontentstudio.model.maps.WorldmapSegment; import com.gpl.rpg.atcontentstudio.model.maps.WorldmapSegment;
import com.gpl.rpg.atcontentstudio.model.saves.SavedGamesSet;
import com.gpl.rpg.atcontentstudio.model.tools.writermode.WriterModeData; import com.gpl.rpg.atcontentstudio.model.tools.writermode.WriterModeData;
import com.gpl.rpg.atcontentstudio.model.tools.writermode.WriterModeDataSet; import com.gpl.rpg.atcontentstudio.model.tools.writermode.WriterModeDataSet;
import com.gpl.rpg.atcontentstudio.ui.tools.BeanShellView; import com.gpl.rpg.atcontentstudio.ui.tools.BeanShellView;
@@ -315,22 +314,6 @@ public class WorkspaceActions {
} }
}; };
public ATCSAction loadSave = new ATCSAction("Load saved game...", "Opens the saved game loading wizard") {
public void actionPerformed(ActionEvent e) {
if (!(selectedNode instanceof Project || selectedNode instanceof SavedGamesSet)) return;
JFileChooser chooser = new JFileChooser("Select an Andor's Trail save file");
if (chooser.showOpenDialog(ATContentStudio.frame) == JFileChooser.APPROVE_OPTION) {
selectedNode.getProject().addSave(chooser.getSelectedFile());
selectedNode.getProject().save();
}
}
public void selectionChanged(ProjectTreeNode selectedNode, TreePath[] selectedPaths) {
setEnabled(selectedNode instanceof Project || selectedNode instanceof SavedGamesSet);
}
};
public ATCSAction compareItems = new ATCSAction("Items comparator", "Opens an editor showing all the items of the project in a table") { public ATCSAction compareItems = new ATCSAction("Items comparator", "Opens an editor showing all the items of the project in a table") {
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
if (selectedNode == null || selectedNode.getProject() == null) return; if (selectedNode == null || selectedNode.getProject() == null) return;
@@ -466,7 +449,6 @@ public class WorkspaceActions {
actions.add(createGDE); actions.add(createGDE);
actions.add(createMap); actions.add(createMap);
actions.add(importJSON); actions.add(importJSON);
actions.add(loadSave);
actions.add(compareItems); actions.add(compareItems);
actions.add(compareNPCs); actions.add(compareNPCs);
actions.add(exportProject); actions.add(exportProject);

View File

@@ -1,30 +0,0 @@
package com.gpl.rpg.atcontentstudio.ui.saves;
import com.gpl.rpg.atcontentstudio.ATContentStudio;
import com.gpl.rpg.atcontentstudio.model.saves.SavedGame;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
import com.gpl.rpg.atcontentstudio.ui.Editor;
import javax.swing.*;
import java.awt.*;
public class SavedGameEditor extends Editor {
private static final long serialVersionUID = 6055910379650778737L;
public SavedGameEditor(SavedGame save) {
this.name = save.loadedSave.displayInfo;
this.icon = new ImageIcon(DefaultIcons.getHeroIcon());
this.target = save;
setLayout(new BorderLayout());
add(new JScrollPane(new com.gpl.rpg.andorstrainer.ui.SavedGameEditor(save.loadedSave, ATContentStudio.frame)), BorderLayout.CENTER);
}
@Override
public void targetUpdated() {
// TODO Auto-generated method stub
}
}

View File

@@ -53,9 +53,14 @@ public class SpritesheetEditor extends Editor {
public SpritesheetEditor(Spritesheet sheet) { public SpritesheetEditor(Spritesheet sheet) {
super(); super();
this.icon = new ImageIcon(sheet.getIcon(0));
this.name = sheet.id; this.name = sheet.id;
this.target = sheet; this.target = sheet;
Image icon = sheet.getIcon(0);
if (icon == null) {
Notification.addError("Unable to open spritesheet " + sheet.id + " because the image is missing. This might be because its an UI spritesheet, which is not supported in ATCS");
return;
}
this.icon = new ImageIcon(icon);
JPanel pane = new JPanel(); JPanel pane = new JPanel();

View File

@@ -1,219 +1,309 @@
package com.gpl.rpg.atcontentstudio.utils; package com.gpl.rpg.atcontentstudio.utils;
import java.io.*; import com.gpl.rpg.atcontentstudio.Notification;
import java.nio.file.Files; import com.gpl.rpg.atcontentstudio.io.JsonPrettyWriter;
import java.nio.file.Path; import com.gpl.rpg.atcontentstudio.io.JsonSerializable;
import java.nio.file.Paths; import org.json.simple.JSONArray;
import java.nio.file.StandardCopyOption; import org.json.simple.JSONObject;
import java.util.zip.ZipEntry; import org.json.simple.parser.JSONParser;
import java.util.zip.ZipOutputStream; import org.json.simple.parser.ParseException;
public class FileUtils { import java.io.*;
import java.nio.file.Files;
public static void deleteDir(File dir) { import java.nio.file.Path;
if (dir.exists()) { import java.nio.file.Paths;
for (File f : dir.listFiles()) { import java.nio.file.StandardCopyOption;
if (f.isDirectory()) { import java.util.List;
deleteDir(f); import java.util.Map;
} else { import java.util.zip.ZipEntry;
f.delete(); import java.util.zip.ZipOutputStream;
}
} public class FileUtils {
dir.delete(); public static String toJsonString(JsonSerializable jsonSerializable) {
} return toJsonString(jsonSerializable.toMap());
} }
public static String toJsonString(Map json) {
public static void copyFile(File sourceLocation, File targetLocation) { StringWriter writer = new JsonPrettyWriter();
try { try {
InputStream in = new FileInputStream(sourceLocation); JSONObject.writeJSONString(json, writer);
OutputStream out = new FileOutputStream(targetLocation); } catch (IOException e) {
//Impossible with a StringWriter
// Copy the bits from instream to outstream }
byte[] buf = new byte[1024]; return writer.toString();
int len; }
try { public static String toJsonString(List json) {
while ((len = in.read(buf)) > 0) { StringWriter writer = new JsonPrettyWriter();
out.write(buf, 0, len); try {
} JSONArray.writeJSONString(json, writer);
} catch (IOException e) { } catch (IOException e) {
// TODO Auto-generated catch block //Impossible with a StringWriter
} finally { }
try { return writer.toString();
in.close(); }
} catch (IOException e) {
// TODO Auto-generated catch block public static Object fromJsonString(String json) {
} Object o;
try { try {
out.close(); JSONParser parser = new JSONParser();
} catch (IOException e) { o = parser.parse(json);
// TODO Auto-generated catch block } catch (ParseException e) {
} throw new RuntimeException(e);
} }
} catch (FileNotFoundException e1) { return o;
// TODO Auto-generated catch block }
}
} public static Map mapFromJsonFile(File file){
String json = readFileToString(file);
private static final int BUFFER = 2048; if (json == null) {
return null;
public static void writeToZip(File folder, File target) { }
try { Map map = (Map)FileUtils.fromJsonString(json);
FileOutputStream dest = new FileOutputStream(target); return map;
ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(dest)); }
zipDir(folder, "", out);
out.flush(); public static boolean writeStringToFile(String toWrite, File file, String type) {
out.close(); return writeStringToFile(toWrite, file, type, true);
} catch (Exception e) { }
// TODO Auto-generated catch block public static boolean writeStringToFile(String toWrite, File file, String type, boolean notifyOnSuccess) {
e.printStackTrace(); try {
} FileWriter w = new FileWriter(file);
w.write(toWrite);
} w.close();
if(type != null) {
/** Notification.addSuccess(type + " saved.");
* cp sourceFolder/* targetFolder/ }
* return true;
* @param sourceFolder } catch (IOException e) {
* @param targetFolder if(type != null) {
*/ Notification.addError("Error while saving " + type + " : " + e.getMessage());
public static void copyOver(File sourceFolder, File targetFolder) { }
if (!sourceFolder.isDirectory() || !targetFolder.isDirectory()) return; e.printStackTrace();
for (File f : sourceFolder.listFiles()) { return false;
if (Files.isSymbolicLink(f.toPath())) { }
//Skip symlinks }
continue;
} else if (f.isDirectory()) { public static String readFileToString(File settingsFile) {
File dest = new File(targetFolder, f.getName()); String json;
if (!dest.exists()) { try{
dest.mkdir(); FileReader file = new FileReader(settingsFile);
} BufferedReader reader = new BufferedReader(file);
copyOver(f, dest); StringBuilder builder = new StringBuilder();
} else { int c;
copyFile(f, new File(targetFolder, f.getName())); while ((c = reader.read()) != -1) {
} builder.append((char) c);
} }
} json = builder.toString();
}catch (IOException e){
private static void zipDir(File dir, String prefix, ZipOutputStream zos) { json = null;
if (prefix != "") { e.printStackTrace();
prefix = prefix + File.separator; }
} return json;
for (File f : dir.listFiles()) { }
if (f.isDirectory()) {
zipDir(f, prefix + f.getName(), zos); public static void deleteDir(File dir) {
} else { if (dir.exists()) {
FileInputStream fis; for (File f : dir.listFiles()) {
try { if (f.isDirectory()) {
fis = new FileInputStream(f); deleteDir(f);
BufferedInputStream origin = new BufferedInputStream(fis, BUFFER); } else {
ZipEntry entry = new ZipEntry(prefix + f.getName()); f.delete();
try { }
zos.putNextEntry(entry); }
int count; dir.delete();
byte data[] = new byte[BUFFER]; }
while ((count = origin.read(data, 0, BUFFER)) != -1) { }
zos.write(data, 0, count);
zos.flush(); public static void copyFile(File sourceLocation, File targetLocation) {
} try {
} catch (IOException e) { InputStream in = new FileInputStream(sourceLocation);
// TODO Auto-generated catch block OutputStream out = new FileOutputStream(targetLocation);
e.printStackTrace();
} finally { // Copy the bits from instream to outstream
try { byte[] buf = new byte[1024];
origin.close(); int len;
} catch (IOException e) { try {
// TODO Auto-generated catch block while ((len = in.read(buf)) > 0) {
e.printStackTrace(); out.write(buf, 0, len);
} }
} } catch (IOException e) {
} catch (FileNotFoundException e) { // TODO Auto-generated catch block
// TODO Auto-generated catch block } finally {
e.printStackTrace(); try {
} in.close();
} } catch (IOException e) {
} // TODO Auto-generated catch block
} }
try {
public static boolean makeSymlink(File targetFile, File linkFile) { out.close();
Path target = Paths.get(targetFile.getAbsolutePath()); } catch (IOException e) {
Path link = Paths.get(linkFile.getAbsolutePath()); // TODO Auto-generated catch block
if (!Files.exists(link)) { }
try { }
Files.createSymbolicLink(link, target); } catch (FileNotFoundException e1) {
} catch (Exception e) { // TODO Auto-generated catch block
System.err.println("Failed to create symbolic link to target \"" + targetFile.getAbsolutePath() + "\" as \"" + linkFile.getAbsolutePath() + "\" the java.nio way:"); }
e.printStackTrace(); }
switch (DesktopIntegration.detectedOS) {
case Windows: private static final int BUFFER = 2048;
System.err.println("Trying the Windows way with mklink");
try { public static void writeToZip(File folder, File target) {
Runtime.getRuntime().exec( try {
"cmd.exe /C mklink " + (targetFile.isDirectory() ? "/J " : "") + "\"" + linkFile.getAbsolutePath() + "\" \"" + targetFile.getAbsolutePath() + "\""); FileOutputStream dest = new FileOutputStream(target);
} catch (IOException e1) { ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(dest));
e1.printStackTrace(); zipDir(folder, "", out);
} out.flush();
if (!linkFile.exists()) { out.close();
System.err.println("Attempting UAC elevation through VBS script."); } catch (Exception e) {
runWithUac("cmd.exe /C mklink " + (targetFile.isDirectory() ? "/J " : "") + "\"" + linkFile.getAbsolutePath() + "\" \"" + targetFile.getAbsolutePath() + "\"", 3, linkFile); // TODO Auto-generated catch block
} e.printStackTrace();
break; }
case MacOS:
case NIX: }
case Other:
System.err.println("Trying the unix way with ln -s"); /**
try { * cp sourceFolder/* targetFolder/
Runtime.getRuntime().exec("ln -s " + targetFile.getAbsolutePath() + " " + linkFile.getAbsolutePath()); *
} catch (IOException e1) { * @param sourceFolder
e1.printStackTrace(); * @param targetFolder
} */
break; public static void copyOver(File sourceFolder, File targetFolder) {
default: if (!sourceFolder.isDirectory() || !targetFolder.isDirectory()) return;
System.out.println("Unrecognized OS. Please contact ATCS dev."); for (File f : sourceFolder.listFiles()) {
break; if (Files.isSymbolicLink(f.toPath())) {
//Skip symlinks
} continue;
} } else if (f.isDirectory()) {
} File dest = new File(targetFolder, f.getName());
if (!Files.exists(link)) { if (!dest.exists()) {
System.err.println("Failed to create link \"" + linkFile.getAbsolutePath() + "\" targetting \"" + targetFile.getAbsolutePath() + "\""); dest.mkdir();
System.err.println("You can try running ATCS with administrative privileges once, or create the symbolic link manually."); }
} copyOver(f, dest);
return true; } else {
} copyFile(f, new File(targetFolder, f.getName()));
}
public static File backupFile(File f) { }
try { }
Path returned = Files.copy(Paths.get(f.getAbsolutePath()), Paths.get(f.getAbsolutePath() + ".bak"), StandardCopyOption.REPLACE_EXISTING);
return returned.toFile(); private static void zipDir(File dir, String prefix, ZipOutputStream zos) {
} catch (IOException e) { if (prefix != "") {
e.printStackTrace(); prefix = prefix + File.separator;
} }
return null; for (File f : dir.listFiles()) {
} if (f.isDirectory()) {
zipDir(f, prefix + f.getName(), zos);
static final String uacBatName = "ATCS_elevateWithUac.bat"; } else {
FileInputStream fis;
public static void runWithUac(String command, int tries, File checkExists) { try {
File tmpFolder = new File(System.getProperty("java.io.tmpdir")); fis = new FileInputStream(f);
File batFile = new File(tmpFolder, uacBatName); BufferedInputStream origin = new BufferedInputStream(fis, BUFFER);
batFile.deleteOnExit(); ZipEntry entry = new ZipEntry(prefix + f.getName());
FileWriter writer; try {
try { zos.putNextEntry(entry);
writer = new FileWriter(batFile, false); int count;
writer.write( byte data[] = new byte[BUFFER];
"@echo Set objShell = CreateObject(\"Shell.Application\") > %temp%\\sudo.tmp.vbs\r\n" while ((count = origin.read(data, 0, BUFFER)) != -1) {
+ "@echo args = Right(\"%*\", (Len(\"%*\") - Len(\"%1\"))) >> %temp%\\sudo.tmp.vbs\r\n" zos.write(data, 0, count);
+ "@echo objShell.ShellExecute \"%1\", args, \"\", \"runas\" >> %temp%\\sudo.tmp.vbs\r\n" zos.flush();
+ "@cscript %temp%\\sudo.tmp.vbs\r\n" }
+ "del /f %temp%\\sudo.tmp.vbs\r\n"); } catch (IOException e) {
writer.close(); // TODO Auto-generated catch block
while (!checkExists.exists() && tries-- > 0) { e.printStackTrace();
Runtime.getRuntime().exec(new String[]{"cmd.exe", "/C", batFile.getAbsolutePath() + " " + command}); } finally {
} try {
} catch (IOException e) { origin.close();
e.printStackTrace(); } catch (IOException e) {
} // TODO Auto-generated catch block
e.printStackTrace();
} }
}
} } catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public static boolean makeSymlink(File targetFile, File linkFile) {
Path target = Paths.get(targetFile.getAbsolutePath());
Path link = Paths.get(linkFile.getAbsolutePath());
if (!Files.exists(link)) {
try {
Files.createSymbolicLink(link, target);
} catch (Exception e) {
System.err.println("Failed to create symbolic link to target \"" + targetFile.getAbsolutePath() + "\" as \"" + linkFile.getAbsolutePath() + "\" the java.nio way:");
e.printStackTrace();
switch (DesktopIntegration.detectedOS) {
case Windows:
System.err.println("Trying the Windows way with mklink");
try {
Runtime.getRuntime().exec(
"cmd.exe /C mklink " + (targetFile.isDirectory() ? "/J " : "") + "\"" + linkFile.getAbsolutePath() + "\" \"" + targetFile.getAbsolutePath() + "\"");
} catch (IOException e1) {
e1.printStackTrace();
}
if (!linkFile.exists()) {
System.err.println("Attempting UAC elevation through VBS script.");
runWithUac("cmd.exe /C mklink " + (targetFile.isDirectory() ? "/J " : "") + "\"" + linkFile.getAbsolutePath() + "\" \"" + targetFile.getAbsolutePath() + "\"", 3, linkFile);
}
break;
case MacOS:
case NIX:
case Other:
System.err.println("Trying the unix way with ln -s");
try {
Runtime.getRuntime().exec("ln -s " + targetFile.getAbsolutePath() + " " + linkFile.getAbsolutePath());
} catch (IOException e1) {
e1.printStackTrace();
}
break;
default:
System.out.println("Unrecognized OS. Please contact ATCS dev.");
break;
}
}
}
if (!Files.exists(link)) {
System.err.println("Failed to create link \"" + linkFile.getAbsolutePath() + "\" targetting \"" + targetFile.getAbsolutePath() + "\"");
System.err.println("You can try running ATCS with administrative privileges once, or create the symbolic link manually.");
}
return true;
}
public static File backupFile(File f) {
try {
Path returned = Files.copy(Paths.get(f.getAbsolutePath()), Paths.get(f.getAbsolutePath() + ".bak"), StandardCopyOption.REPLACE_EXISTING);
return returned.toFile();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
static final String uacBatName = "ATCS_elevateWithUac.bat";
public static void runWithUac(String command, int tries, File checkExists) {
File tmpFolder = new File(System.getProperty("java.io.tmpdir"));
File batFile = new File(tmpFolder, uacBatName);
batFile.deleteOnExit();
FileWriter writer;
try {
writer = new FileWriter(batFile, false);
writer.write(
"@echo Set objShell = CreateObject(\"Shell.Application\") > %temp%\\sudo.tmp.vbs\r\n"
+ "@echo args = Right(\"%*\", (Len(\"%*\") - Len(\"%1\"))) >> %temp%\\sudo.tmp.vbs\r\n"
+ "@echo objShell.ShellExecute \"%1\", args, \"\", \"runas\" >> %temp%\\sudo.tmp.vbs\r\n"
+ "@cscript %temp%\\sudo.tmp.vbs\r\n"
+ "del /f %temp%\\sudo.tmp.vbs\r\n");
writer.close();
while (!checkExists.exists() && tries-- > 0) {
Runtime.getRuntime().exec(new String[]{"cmd.exe", "/C", batFile.getAbsolutePath() + " " + command});
}
} catch (IOException e) {
e.printStackTrace();
}
}
}