diff --git a/ATCS_JAR.jardesc b/ATCS_JAR.jardesc
new file mode 100644
index 0000000..7edd0c3
--- /dev/null
+++ b/ATCS_JAR.jardesc
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/com/gpl/rpg/atcontentstudio/model/GameDataElement.java b/src/com/gpl/rpg/atcontentstudio/model/GameDataElement.java
index 736256e..5497372 100644
--- a/src/com/gpl/rpg/atcontentstudio/model/GameDataElement.java
+++ b/src/com/gpl/rpg/atcontentstudio/model/GameDataElement.java
@@ -4,10 +4,10 @@ import java.awt.Image;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Enumeration;
-import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
import javax.swing.tree.TreeNode;
@@ -32,7 +32,7 @@ public abstract class GameDataElement implements ProjectTreeNode, Serializable {
public boolean writable = false;
//List of objects whose transition to "linked" state made them point to this instance.
- private Map backlinks = new LinkedHashMap();
+ private Map backlinks = new ConcurrentHashMap();
public String id = null;
diff --git a/src/com/gpl/rpg/atcontentstudio/model/maps/ContainerArea.java b/src/com/gpl/rpg/atcontentstudio/model/maps/ContainerArea.java
index 175ef90..a5e94f5 100644
--- a/src/com/gpl/rpg/atcontentstudio/model/maps/ContainerArea.java
+++ b/src/com/gpl/rpg/atcontentstudio/model/maps/ContainerArea.java
@@ -31,7 +31,7 @@ public class ContainerArea extends MapObject {
if (oldOne == droplist) {
oldOne.removeBacklink(parentMap);
droplist = (Droplist) newOne;
- newOne.addBacklink(parentMap);
+ if (newOne != null) newOne.addBacklink(parentMap);
}
}
diff --git a/src/com/gpl/rpg/atcontentstudio/model/maps/KeyArea.java b/src/com/gpl/rpg/atcontentstudio/model/maps/KeyArea.java
index feeaf96..53a60aa 100644
--- a/src/com/gpl/rpg/atcontentstudio/model/maps/KeyArea.java
+++ b/src/com/gpl/rpg/atcontentstudio/model/maps/KeyArea.java
@@ -62,7 +62,7 @@ public class KeyArea extends MapObject {
if (oldOne == dialogue) {
oldOne.removeBacklink(parentMap);
dialogue = (Dialogue) newOne;
- newOne.addBacklink(parentMap);
+ if (newOne != null) newOne.addBacklink(parentMap);
}
requirement.elementChanged(oldOne, newOne);
}
diff --git a/src/com/gpl/rpg/atcontentstudio/model/maps/MapChange.java b/src/com/gpl/rpg/atcontentstudio/model/maps/MapChange.java
index 1f77d5d..f0e93bd 100644
--- a/src/com/gpl/rpg/atcontentstudio/model/maps/MapChange.java
+++ b/src/com/gpl/rpg/atcontentstudio/model/maps/MapChange.java
@@ -39,7 +39,7 @@ public class MapChange extends MapObject {
if (oldOne == map) {
oldOne.removeBacklink(parentMap);
map = (TMXMap) newOne;
- newOne.addBacklink(parentMap);
+ if (newOne != null) newOne.addBacklink(parentMap);
}
}
diff --git a/src/com/gpl/rpg/atcontentstudio/model/maps/ScriptArea.java b/src/com/gpl/rpg/atcontentstudio/model/maps/ScriptArea.java
index 34e904d..50bb2a2 100644
--- a/src/com/gpl/rpg/atcontentstudio/model/maps/ScriptArea.java
+++ b/src/com/gpl/rpg/atcontentstudio/model/maps/ScriptArea.java
@@ -44,7 +44,7 @@ public class ScriptArea extends MapObject {
if (oldOne == dialogue) {
oldOne.removeBacklink(parentMap);
dialogue = (Dialogue) newOne;
- newOne.addBacklink(parentMap);
+ if (newOne != null) newOne.addBacklink(parentMap);
}
}
diff --git a/src/com/gpl/rpg/atcontentstudio/model/maps/SignArea.java b/src/com/gpl/rpg/atcontentstudio/model/maps/SignArea.java
index d97d2e6..d968a30 100644
--- a/src/com/gpl/rpg/atcontentstudio/model/maps/SignArea.java
+++ b/src/com/gpl/rpg/atcontentstudio/model/maps/SignArea.java
@@ -33,7 +33,7 @@ public class SignArea extends MapObject {
if (oldOne == dialogue) {
oldOne.removeBacklink(parentMap);
dialogue = (Dialogue) newOne;
- newOne.addBacklink(parentMap);
+ if (newOne != null) newOne.addBacklink(parentMap);
}
}
diff --git a/src/com/gpl/rpg/atcontentstudio/model/maps/SpawnArea.java b/src/com/gpl/rpg/atcontentstudio/model/maps/SpawnArea.java
index 0a31904..f04b3ac 100644
--- a/src/com/gpl/rpg/atcontentstudio/model/maps/SpawnArea.java
+++ b/src/com/gpl/rpg/atcontentstudio/model/maps/SpawnArea.java
@@ -66,7 +66,7 @@ public class SpawnArea extends MapObject {
if (replacedIndex >= 0) {
oldOne.removeBacklink(parentMap);
spawnGroup.set(replacedIndex, (NPC) newOne);
- newOne.addBacklink(parentMap);
+ if (newOne != null) newOne.addBacklink(parentMap);
}
}
diff --git a/src/com/gpl/rpg/atcontentstudio/ui/ProjectCreationWizard.java b/src/com/gpl/rpg/atcontentstudio/ui/ProjectCreationWizard.java
index 0a5ee20..a630dff 100644
--- a/src/com/gpl/rpg/atcontentstudio/ui/ProjectCreationWizard.java
+++ b/src/com/gpl/rpg/atcontentstudio/ui/ProjectCreationWizard.java
@@ -56,7 +56,7 @@ public class ProjectCreationWizard extends JDialog {
atSourceSelectionCombo = new JComboBox();
resourceSetToUse = new JComboBox(new ComboBoxModel() {
- Project.ResourceSet selected = Project.ResourceSet.allFiles;
+ Project.ResourceSet selected = Project.ResourceSet.gameData;
@Override
public int getSize() {
diff --git a/src/com/gpl/rpg/atcontentstudio/ui/map/TMXMapEditor.java b/src/com/gpl/rpg/atcontentstudio/ui/map/TMXMapEditor.java
index 2b0f407..8f5d26d 100644
--- a/src/com/gpl/rpg/atcontentstudio/ui/map/TMXMapEditor.java
+++ b/src/com/gpl/rpg/atcontentstudio/ui/map/TMXMapEditor.java
@@ -1615,10 +1615,13 @@ public class TMXMapEditor extends Editor implements TMXMap.MapChangedOnDiskListe
gdeIcon.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
- if (map.state == GameDataElement.State.modified) {
- int confirm = JOptionPane.showConfirmDialog(TMXMapEditor.this, "You modified this map in ATCS.\nYou'd better save your changes in ATCS before opening this map with the external editor.\nDo you want to save before opening the file?", "Save before opening?", JOptionPane.YES_NO_CANCEL_OPTION);
+ if (map.state == GameDataElement.State.modified || map.state == GameDataElement.State.created) {
+ int confirm = JOptionPane.showConfirmDialog(TMXMapEditor.this, "You have unsaved changes in ATCS.\nYou'd better save your changes in ATCS before opening this map with the external editor.\nDo you want to save before opening the file?", "Save before opening?", JOptionPane.YES_NO_CANCEL_OPTION);
if (confirm == JOptionPane.CANCEL_OPTION) return;
- if (confirm == JOptionPane.YES_OPTION) map.save();
+ if (confirm == JOptionPane.YES_OPTION) {
+ map.save();
+ ATContentStudio.frame.nodeChanged(map);
+ }
}
DesktopIntegration.openTmxMap(map.tmxFile);
}
diff --git a/src/com/gpl/rpg/atcontentstudio/utils/FileUtils.java b/src/com/gpl/rpg/atcontentstudio/utils/FileUtils.java
index 0025e93..e0ce74c 100644
--- a/src/com/gpl/rpg/atcontentstudio/utils/FileUtils.java
+++ b/src/com/gpl/rpg/atcontentstudio/utils/FileUtils.java
@@ -6,6 +6,7 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
+import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -128,10 +129,14 @@ public class FileUtils {
case Windows:
System.err.println("Trying the Windows way with mklink");
try {
- Runtime.getRuntime().exec("mklink "+(targetFile.isDirectory() ? "/J " : "")+linkFile.getAbsolutePath()+" "+targetFile.getAbsolutePath());
+ Runtime.getRuntime().exec("cmd.exe /C mklink "+(targetFile.isDirectory() ? "/J " : "")+linkFile.getAbsolutePath()+" "+targetFile.getAbsolutePath());
} catch (IOException e1) {
e1.printStackTrace();
}
+ System.err.println("Attempting UAC elevation through VBS script.");
+ if (!linkFile.exists()) {
+ runWithUac("cmd.exe /C mklink "+(targetFile.isDirectory() ? "/J " : "")+linkFile.getAbsolutePath()+" "+targetFile.getAbsolutePath(), 3, linkFile);
+ }
break;
case MacOS:
case NIX:
@@ -167,4 +172,28 @@ public class FileUtils {
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();
+ }
+
+ }
+
}