UAC dirty script for better windows integration to create symlinks. More

data using a thread-safe collection. Some NPEs fixed. 
More data protection in tiled integration functions (better state
checking, backup tiled-made file before saving ATCS-made data).
jardesc file added for convenience.
This commit is contained in:
Zukero
2017-03-02 18:10:03 +01:00
parent 97ae63693a
commit dfe3cc8480
11 changed files with 73 additions and 13 deletions

28
ATCS_JAR.jardesc Normal file
View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<jardesc>
<jar path="ATContentStudio/ATCS_v0.5.2.jar"/>
<options buildIfNeeded="true" compress="true" descriptionLocation="/ATContentStudio/ATCS_JAR.jardesc" exportErrors="true" exportWarnings="true" includeDirectoryEntries="false" overwrite="false" saveDescription="true" storeRefactorings="false" useSourceFolders="false"/>
<storedRefactorings deprecationInfo="true" structuralOnly="false"/>
<selectedProjects/>
<manifest generateManifest="true" manifestLocation="" manifestVersion="1.0" reuseManifest="false" saveManifest="false" usesManifest="true">
<sealing sealJar="false">
<packagesToSeal/>
<packagesToUnSeal/>
</sealing>
</manifest>
<selectedElements exportClassFiles="true" exportJavaFiles="true" exportOutputFolder="false">
<file path="/ATContentStudio/nsisHeaderBase2.xcf"/>
<file path="/ATContentStudio/ATCS_v0.5.1.jar"/>
<file path="/ATContentStudio/nsisBorderBannerBase.xcf"/>
<file path="/ATContentStudio/.project"/>
<javaElement handleIdentifier="=ATContentStudio/res"/>
<javaElement handleIdentifier="=ATContentStudio/src"/>
<file path="/ATContentStudio/folderIconBase.xcf"/>
<file path="/ATContentStudio/.gitignore"/>
<file path="/ATContentStudio/fileIconBase.xcf"/>
<javaElement handleIdentifier="=ATContentStudio/hacked-libtiled"/>
<file path="/ATContentStudio/arrows.xcf"/>
<file path="/ATContentStudio/.classpath"/>
<file path="/ATContentStudio/ATCS_v0.5.0.jar"/>
</selectedElements>
</jardesc>

View File

@@ -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<GameDataElement, Integer> backlinks = new LinkedHashMap<GameDataElement, Integer>();
private Map<GameDataElement, Integer> backlinks = new ConcurrentHashMap<GameDataElement, Integer>();
public String id = null;

View File

@@ -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);
}
}

View File

@@ -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);
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -56,7 +56,7 @@ public class ProjectCreationWizard extends JDialog {
atSourceSelectionCombo = new JComboBox<String>();
resourceSetToUse = new JComboBox<Project.ResourceSet>(new ComboBoxModel<Project.ResourceSet>() {
Project.ResourceSet selected = Project.ResourceSet.allFiles;
Project.ResourceSet selected = Project.ResourceSet.gameData;
@Override
public int getSize() {

View File

@@ -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);
}

View File

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