diff --git a/Form1.cs b/Form1.cs
index b658522..7ddc958 100644
--- a/Form1.cs
+++ b/Form1.cs
@@ -148,10 +148,17 @@ namespace SCJMapper_V2
///
private void InitActionTree( )
{
+ // default profile handling
+ // TODO ?? change the data path away from the app directory as this is not Win policy if installed in "Program Files"
+ String dataPath = "";
+ SCDefaultProfile SD = new SCDefaultProfile( );
+ SD.GetDefaultProfile( dataPath );
+ String defProf = SD.DefaultProfileName; // either "" or a valid full filename
+
// build TreeView and the ActionMaps
m_AT = new ActionTree( );
m_AT.Ctrl = treeView1; // the ActionTree owns the TreeView control
- m_AT.LoadTree( ); // Init
+ m_AT.LoadTree( defProf ); // Init with default profile filepath
// default JS to Joystick mapping - can be changed and reloaded from XML
if ( tc1.TabCount > 0 ) { cbJs1.SelectedIndex = 0; m_AT.ActionMaps.js1 = cbJs1.Text; }
diff --git a/Joystick/ActionTree.cs b/Joystick/ActionTree.cs
index 02a1e57..f9747c3 100644
--- a/Joystick/ActionTree.cs
+++ b/Joystick/ActionTree.cs
@@ -15,7 +15,7 @@ namespace SCJMapper_V2
// Load MappingVars.csv into the ActionList and create the Control TreeView
- public void LoadTree( )
+ public void LoadTree( String defaultProfile )
{
TreeNode tn = null;
TreeNode[] cnl = { };
@@ -33,14 +33,24 @@ namespace SCJMapper_V2
DProfileReader dpReader = new DProfileReader( ); // we may read a profile
TextReader txReader = null;
- // 1st choice is a user given MappingVars.csv file in the appdir
+ // 1st choice is a user given MappingVars.csv file in the appdir - this is only compatibilty and testing
if ( File.Exists( "MappingVars.csv" ) ) {
txReader = new StreamReader( "MappingVars.csv" );
}
- // second choice a defaultProfile.xml in the app dir
+ // second choice a defaultProfile.xml in given path
+ else if ( File.Exists( defaultProfile ) ) {
+ using ( StreamReader sr = new StreamReader( defaultProfile ) ) {
+ String buff = sr.ReadToEnd( );
+ dpReader.fromXML( buff );
+ }
+ if ( dpReader.ValidContent ) {
+ txReader = new StringReader( dpReader.CSVMap );
+ }
+ }
+ // third choice a defaultProfile.xml in the app dir distributed with the application ??? to be deleted ???
else {
- if ( File.Exists( "defaultProfile.xml" ) ) {
- using ( StreamReader sr = new StreamReader( "defaultProfile.xml" ) ) {
+ if ( File.Exists( SCPath.DefaultProfileName ) ) {
+ using ( StreamReader sr = new StreamReader( SCPath.DefaultProfileName ) ) {
String buff = sr.ReadToEnd( );
dpReader.fromXML( buff );
}
@@ -78,7 +88,7 @@ namespace SCJMapper_V2
}
}//for
tn = new TreeNode( acm.name, cnl ); tn.Name = acm.name; // name it to find it..
- tn.ImageIndex = 0; tn.NodeFont = new Font( Ctrl.Font, FontStyle.Bold );
+ tn.ImageIndex = 0; tn.NodeFont = new Font( Ctrl.Font, FontStyle.Bold );
Ctrl.BackColor = Ctrl.BackColor; // fix for defect TreeView (cut off bold text)
Ctrl.Nodes.Add( tn ); // add to control
if ( topNode == null ) topNode = tn; // once to keep the start of list
@@ -203,7 +213,7 @@ namespace SCJMapper_V2
if ( !String.IsNullOrEmpty( ActionMaps.js6 ) ) repList += String.Format( "** js6 = {0}\n", ActionMaps.js6 );
if ( !String.IsNullOrEmpty( ActionMaps.js7 ) ) repList += String.Format( "** js7 = {0}\n", ActionMaps.js7 );
if ( !String.IsNullOrEmpty( ActionMaps.js8 ) ) repList += String.Format( "** js8 = {0}\n", ActionMaps.js8 );
- repList += String.Format( "\n");
+ repList += String.Format( "\n" );
foreach ( ActionMapCls acm in ActionMaps ) {
String rep = String.Format( "*** {0}\n", acm.name );
repList += rep;
diff --git a/Packages.dgml b/Packages.dgml
new file mode 100644
index 0000000..f76e2a3
--- /dev/null
+++ b/Packages.dgml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SC/SCDefaultProfile.cs b/SC/SCDefaultProfile.cs
new file mode 100644
index 0000000..3c34d7b
--- /dev/null
+++ b/SC/SCDefaultProfile.cs
@@ -0,0 +1,76 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Ionic.Zip;
+using System.IO;
+
+namespace SCJMapper_V2
+{
+
+ ///
+ /// Finds and returns the DefaultProfile from SC GameData.pak
+ /// it is located in GameData.pak \Libs\Config
+ ///
+ class SCDefaultProfile
+ {
+ private Boolean m_valid = false;
+ public Boolean IsValid { get { return m_valid; } }
+
+ private String m_fileName = "";
+ public String DefaultProfileName { get { return m_fileName; } }
+
+ ///
+ /// Extracts the file to destPath
+ /// the subpath will be retained
+ ///
+ /// Destination path to extract to
+ private void ExtractDefaultProfile( String destPath )
+ {
+ String scp = SCPath.SCClientDataPath;
+ if ( String.IsNullOrEmpty( scp ) ) return; // sorry did not work
+
+ using ( ZipFile zip = ZipFile.Read( SCPath.SCGameData_pak ) ) {
+ zip.CaseSensitiveRetrieval = false;
+
+ ICollection gdpak = zip.SelectEntries( "name = " + SCPath.DefaultProfileName, SCPath.DefaultProfilePath_rel );
+ if ( gdpak != null ) {
+ gdpak.FirstOrDefault( ).Extract( destPath, ExtractExistingFileAction.OverwriteSilently );
+ m_fileName = Path.Combine( destPath, SCPath.DefaultProfilePath_rel );
+ m_fileName = Path.Combine( m_fileName, SCPath.DefaultProfileName );
+ m_valid = true;
+ }
+ }
+ }
+
+
+ ///
+ /// Deletes the extracted version of the defaultProfile
+ ///
+ /// Destination path to delete from
+ public void ClearDefaultProfile( String destPath )
+ {
+ try {
+ String p = Path.Combine( destPath, SCPath.DefaultProfilePath_rel );
+ File.Delete( Path.Combine( p, SCPath.DefaultProfileName ) );
+ m_fileName = "";
+ m_valid = false;
+ }
+ catch { }
+ }
+
+ ///
+ /// Retrieves the newest defaultProfile from GameData.pak
+ /// It deletes the last retrieved one first
+ ///
+ /// Destination path to extract to
+ /// True if successfull; if false there is no old file left in the path
+ public Boolean GetDefaultProfile( String destPath )
+ {
+ ClearDefaultProfile( destPath );
+ ExtractDefaultProfile( destPath );
+ return m_valid;
+ }
+
+ }
+}
diff --git a/SC/SCPath.cs b/SC/SCPath.cs
new file mode 100644
index 0000000..bf33985
--- /dev/null
+++ b/SC/SCPath.cs
@@ -0,0 +1,156 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.IO;
+using Microsoft.Win32;
+
+namespace SCJMapper_V2
+{
+ ///
+ /// Find the SC pathes and folders
+ ///
+ class SCPath
+ {
+
+ ///
+ /// Try to locate the launcher under "App Paths"
+ ///
+ static private String SCLauncherPath1
+ {
+ get
+ {
+ String scpath = ( String )Registry.GetValue( @"HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\App Paths\StarCitizen Launcher.exe", "", null );
+ if ( scpath != null ) {
+ return scpath;
+ }
+ return "";
+ }
+ }
+
+ ///
+ /// Try to locate the launcher under "Uninstall"
+ ///
+ static private String SCLauncherPath2
+ {
+ get
+ {
+ String scpath = ( String )Registry.GetValue( @"HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\StarCitizen", "DisplayIcon", null );
+ if ( scpath != null ) {
+ return scpath;
+ }
+ return "";
+ }
+ }
+
+
+ ///
+ /// Returns the base SC install path from something like "E:\G\StarCitizen\Launcher\StarCitizenLauncher.exe"
+ ///
+ static private String SCBasePath
+ {
+ get
+ {
+ String scp = SCLauncherPath1;
+ if ( String.IsNullOrEmpty( scp ) ) {
+ scp = SCLauncherPath2;
+ if ( String.IsNullOrEmpty( scp ) ) {
+ return ""; // sorry did not found a thing..
+ }
+ }
+ // found the launcher
+ scp = Path.GetDirectoryName( scp ); // "E:\G\StarCitizen\Launcher"
+ scp = Path.GetDirectoryName( scp ); // "E:\G\StarCitizen"
+ return scp;
+ }
+ }
+
+
+
+ ///
+ /// Returns the SC installation path
+ ///
+ static public String SCInstallPath
+ {
+ get
+ {
+ return SCBasePath;
+ }
+ }
+
+
+ ///
+ /// Returns the SC ClientData path e.g. "E:\G\StarCitizen\CitizenClient\Data"
+ ///
+ static public String SCClientDataPath
+ {
+ get
+ {
+ String scp = SCBasePath;
+ if ( String.IsNullOrEmpty( scp ) ) return "";
+ //
+ scp = Path.Combine( scp, "CitizenClient" );
+ scp = Path.Combine( scp, "Data" );
+ return scp;
+ }
+ }
+
+
+ ///
+ /// Returns the SC ClientData path e.g. "E:\G\StarCitizen\CitizenClient\USER"
+ ///
+ static public String SCClientUSERPath
+ {
+ get
+ {
+ String scp = SCBasePath;
+ if ( String.IsNullOrEmpty( scp ) ) return "";
+ //
+ scp = Path.Combine( scp, "CitizenClient" );
+ scp = Path.Combine( scp, "USER" );
+ return scp;
+ }
+ }
+
+
+ ///
+ /// Returns the SC GameData.pak file path e.g. "E:\G\StarCitizen\CitizenClient\Data\GameData.pak"
+ ///
+ static public String SCGameData_pak
+ {
+ get
+ {
+ String scp = SCClientDataPath;
+ if ( String.IsNullOrEmpty( scp ) ) return "";
+ //
+ scp = Path.Combine( scp, "GameData.pak" );
+ return scp;
+ }
+ }
+
+
+ ///
+ /// Returns the relative path of DefaultProfile.xml
+ ///
+ static public String DefaultProfilePath_rel
+ {
+ get
+ {
+ return @"Libs\Config";
+ }
+ }
+
+ ///
+ /// Returns the name of the DefaultProfile.xml
+ ///
+ static public String DefaultProfileName
+ {
+ get
+ {
+ return @"defaultProfile.xml";
+ }
+ }
+
+
+ }
+}
diff --git a/SCJMapper-V2.csproj b/SCJMapper-V2.csproj
index 0b0f1c3..b087cf7 100644
--- a/SCJMapper-V2.csproj
+++ b/SCJMapper-V2.csproj
@@ -42,6 +42,9 @@
SCJMapper_V2.Program
+
+ packages\DotNetZip.Reduced.1.9.1.8\lib\net20\Ionic.Zip.Reduced.dll
+
$(SharpDXPackageBinDir)\SharpDX.dll
@@ -81,6 +84,8 @@
+
+
Form1.cs
diff --git a/packages.config b/packages.config
index 191e35d..e5778dd 100644
--- a/packages.config
+++ b/packages.config
@@ -1,5 +1,6 @@
+
\ No newline at end of file
diff --git a/packages/DotNetZip.Reduced.1.9.1.8/DotNetZip.Reduced.1.9.1.8.nupkg b/packages/DotNetZip.Reduced.1.9.1.8/DotNetZip.Reduced.1.9.1.8.nupkg
new file mode 100644
index 0000000..5dbbf5f
Binary files /dev/null and b/packages/DotNetZip.Reduced.1.9.1.8/DotNetZip.Reduced.1.9.1.8.nupkg differ
diff --git a/packages/DotNetZip.Reduced.1.9.1.8/lib/net20/Ionic.Zip.Reduced.dll b/packages/DotNetZip.Reduced.1.9.1.8/lib/net20/Ionic.Zip.Reduced.dll
new file mode 100644
index 0000000..9622cc5
Binary files /dev/null and b/packages/DotNetZip.Reduced.1.9.1.8/lib/net20/Ionic.Zip.Reduced.dll differ