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(); + } + + } + }