Skip to content

Commit a2c6a80

Browse files
committed
Quickly switch between your Elite: Dangerous accounts
1 parent c22c379 commit a2c6a80

4 files changed

Lines changed: 325 additions & 0 deletions

File tree

ED Account Switcher.exe

911 KB
Binary file not shown.

README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
v1.0.0
2+
3+
If you have multiple Elite: Dangerous you probably know this too well:
4+
- open the launcher and log in using another set of login credentials
5+
- firing up your email client waiting for the verification code
6+
- pasting the verification code into the launcher
7+
Repeat every time you switch accounts.
8+
9+
Well, no more. With E:D Account Switcher you only need to log into the launcher once per account to set up your accounts database. Once that's done, you can switch between accounts with just a couple of mouse button clicks.
10+
11+
- Log into your account via the Elite Dangerous launcher, so that the "play" button appears
12+
- Fire up E:D Account Switcher or click the "Add New Account" button
13+
- fill in the account name as you see fit
14+
15+
Repeat steps 1 through 3 for every game account you want to be able to quickly switch between. This is a one time process. After you've added your accounts to the database you can switch between accounts like this:
16+
17+
- close the Elite: Dangerous launcher
18+
- fire up E:D Account Switcher, select your saved account and click "Apply"
19+
- start the Elite: Dangerous launcher
20+
21+
22+
23+
Noteworthy stuff:
24+
25+
The account data that E:D Account Switcher saves in its database is tied to the computer that you logged into the account with. While you can copy this database between computers, the machine token which is part of the account data is individually calculated by the launcher for every account and computer. What this means is that chances are relatively high you need to go through the accounts set up process again if you want to use E:D Account Switcher and your game accounts on another computer.
26+
27+
If you have different editions (https://support.elitedangerous.com/kb/faq.php?id=108) of the game switching between accounts still works, so no worries there, however ED's launcher may still want to reinstall the game. If you're a bit tech savvy you can read up on soft links, symbolic links and junctions here: http://schinagl.priv.at/nt/hardlinkshellext/linkshellextension.html#introduction . If you don't have an idea of what to do after reading the info on the site I think it's best if you just let the Elite Dangerous launcher run its course.

source/ED Account Switcher.au3

Lines changed: 298 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,298 @@
1+
#NoTrayIcon
2+
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
3+
#AutoIt3Wrapper_Icon=arrows.ico
4+
#AutoIt3Wrapper_Compression=4
5+
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
6+
#include <array.au3>
7+
#include <file.au3>
8+
#include <GUIConstantsEx.au3>
9+
#include <GuiComboBox.au3>
10+
11+
Global $title = "E:D Account Switcher 1.0.0"
12+
13+
$Form1 = GUICreate($title, 370, 135)
14+
15+
$Group1 = GUICtrlCreateGroup("Switch Account", 5, 10, 360, 50)
16+
Global $Combo1 = GUICtrlCreateCombo("", 15, 30, 200, 25, BitOR($GUI_SS_DEFAULT_COMBO, $CBS_DROPDOWNLIST))
17+
_GUICtrlComboBox_SetCueBanner($Combo1, "Choose Account")
18+
19+
$apply = GUICtrlCreateButton("Apply", 260, 29, 80, 23)
20+
GUICtrlCreateGroup("", -99, -99, 1, 1)
21+
22+
$Group2 = GUICtrlCreateGroup("Add Currently Active Account to DB", 5, 80, 360, 50)
23+
$makeNewAcc = GUICtrlCreateButton("Add New Account", 120, 100, 130, 23)
24+
GUICtrlCreateGroup("", -99, -99, 1, 1)
25+
GUISetState(@SW_SHOW)
26+
27+
Global $aAccountsDataDB[1][8]
28+
_CurrentToDB(1)
29+
30+
While 1
31+
$nMsg = GUIGetMsg()
32+
Switch $nMsg
33+
Case $GUI_EVENT_CLOSE
34+
Exit
35+
Case $apply
36+
$combo = GUICtrlRead($Combo1)
37+
_SwitchToAccount($combo)
38+
Case $makeNewAcc
39+
_CurrentToDB()
40+
EndSwitch
41+
WEnd
42+
43+
Func _SwitchToAccount($account)
44+
If $account = "" Then Return -1
45+
46+
Local $hFile = FileOpen($aAccountsDataDB[0][0], 0)
47+
Local $content = FileRead($hFile)
48+
FileClose($hFile)
49+
50+
For $i = 1 To UBound($aAccountsDataDB) - 1
51+
If $aAccountsDataDB[$i][0] == $account Then ExitLoop
52+
Next
53+
54+
; the values for these settings should always be present in the launcher's config file
55+
$content = StringRegExpReplace($content, '(?Ui)(.*"userSettings".*PublicKeyToken=)(.*)(".*)', "${1}" & $aAccountsDataDB[$i][1] & "${3}")
56+
$content = StringRegExpReplace($content, '(?Ui)(.*"FORCServerSupport.Properties.Settings".*PublicKeyToken=)(.*)(".*)', "${1}" & $aAccountsDataDB[$i][2] & "${3}")
57+
$content = StringRegExpReplace($content, '(?Ui)(.*"ClientSupport.Properties.Settings".*PublicKeyToken=)(.*)(".*)', "${1}" & $aAccountsDataDB[$i][3] & "${3}")
58+
$content = StringRegExpReplace($content, '(?Ui)(.*"CBViewModel.Properties.Settings".*PublicKeyToken=)(.*)(".*)', "${1}" & $aAccountsDataDB[$i][4] & "${3}")
59+
$content = StringRegExpReplace($content, '(?Ui)(.*"MachineToken".*\s*?<value>)(.*)(</value>)', "${1}" & $aAccountsDataDB[$i][5] & "${3}")
60+
61+
62+
; however users may or may not have chosen to save these values:
63+
64+
; username
65+
$valuestyleUN = StringRegExp($content, '(?Uism)<setting name="UserName".*>\s.*(?:<value>(.*)</value>|<value />)', 1)
66+
If $aAccountsDataDB[$i][6] <> "none" Then
67+
If Not IsArray($valuestyleUN) Then
68+
; malformed launcher config
69+
EndIf
70+
If Not StringInStr($valuestyleUN[0], "<value />") Then
71+
$content = StringRegExpReplace($content, '(?Ui)(.*"UserName".*\s*?<value>)(.*)(</value>)', "${1}" & $aAccountsDataDB[$i][6] & "${3}")
72+
Else
73+
$content = StringRegExpReplace($content, '(?Ui)(.*"UserName".*\s*?)(<value />)', "${1}" & '<value>' & $aAccountsDataDB[$i][6] & '</value>')
74+
EndIf
75+
Else
76+
If Not StringInStr($valuestyleUN[0], "<value />") Then
77+
$content = StringRegExpReplace($content, '(?Ui)(.*"UserName".*\s*?)(<value>.*</value>)', "${1}" & '<value />')
78+
EndIf
79+
EndIf
80+
81+
; password
82+
$valuestylePW = StringRegExp($content, '(?Uism)<setting name="Password".*>\s.*(?:<value>(.*)</value>|<value />)', 1)
83+
If $aAccountsDataDB[$i][7] <> "none" Then
84+
If Not IsArray($valuestylePW) Then
85+
; malformed launcher config
86+
EndIf
87+
If Not StringInStr($valuestylePW[0], "<value />") Then
88+
$content = StringRegExpReplace($content, '(?Ui)(.*"Password".*\s*?<value>)(.*)(</value>)', "${1}" & $aAccountsDataDB[$i][7] & "${3}")
89+
Else
90+
$content = StringRegExpReplace($content, '(?Ui)(.*"Password".*\s*?)(<value />)', "${1}" & '<value>' & $aAccountsDataDB[$i][7] & '</value>')
91+
EndIf
92+
Else
93+
If Not StringInStr($valuestylePW[0], "<value />") Then
94+
$content = StringRegExpReplace($content, '(?Ui)(.*"Password".*\s*?)(<value>.*</value>)', "${1}" & '<value />')
95+
EndIf
96+
EndIf
97+
98+
Local $hFile = FileOpen($aAccountsDataDB[0][0], 2)
99+
FileWrite($hFile, $content)
100+
FileClose($hFile)
101+
EndFunc ;==>_SwitchToAccount
102+
103+
Func _SetCombo()
104+
;_arraydisplay($aAccountsDataDB, "_setCombo() start")
105+
If UBound($aAccountsDataDB) >= 2 Then
106+
For $i = 1 To UBound($aAccountsDataDB) - 1
107+
If $aAccountsDataDB[0][1] == $aAccountsDataDB[$i][1] And _
108+
$aAccountsDataDB[0][2] == $aAccountsDataDB[$i][2] And _
109+
$aAccountsDataDB[0][3] == $aAccountsDataDB[$i][3] And _
110+
$aAccountsDataDB[0][4] == $aAccountsDataDB[$i][4] And _
111+
$aAccountsDataDB[0][5] == $aAccountsDataDB[$i][5] And _
112+
$aAccountsDataDB[0][6] == $aAccountsDataDB[$i][6] And _
113+
$aAccountsDataDB[0][7] == $aAccountsDataDB[$i][7] Then
114+
_GUICtrlComboBox_SetCurSel($Combo1, $i - 1)
115+
Return 1
116+
EndIf
117+
Next
118+
EndIf
119+
EndFunc ;==>_SetCombo
120+
121+
Func _AccountsDataFromDB()
122+
Local $sIniname = @ScriptDir & "\accounts.ini"
123+
124+
; assume new account DB if there are no saved accounts or accounts.ini was cleaned
125+
If Not FileExists($sIniname) Then Return 0
126+
Local $aSectionnames = IniReadSectionNames($sIniname)
127+
If Not IsArray($aSectionnames) Then Return 0
128+
129+
_ArraySort($aSectionnames, 0, 1)
130+
131+
For $i = 1 To $aSectionnames[0]
132+
133+
$aSection = IniReadSection($sIniname, $aSectionnames[$i])
134+
If Not IsArray($aSection) Then ContinueLoop
135+
136+
; make sure DB entry keys exist before adding them to the array
137+
$idx1 = _ArraySearch($aSection, "userSettings", 1)
138+
$idx2 = _ArraySearch($aSection, "FORCServerSupport.Properties.Settings", 1)
139+
$idx3 = _ArraySearch($aSection, "ClientSupport.Properties.Settings", 1)
140+
$idx4 = _ArraySearch($aSection, "CBViewModel.Properties.Settings", 1)
141+
$idx5 = _ArraySearch($aSection, "MachineToken", 1)
142+
$idx6 = _ArraySearch($aSection, "UserName", 1)
143+
$idx7 = _ArraySearch($aSection, "Password", 1)
144+
If $idx1 = -1 Or $idx2 = -1 Or $idx3 = -1 Or $idx4 = -1 Or $idx5 = -1 Or $idx6 = -1 Or $idx7 = -1 Then ContinueLoop
145+
146+
; we also need to make sure the value for every key at least contains something
147+
If StringStripWS($aSection[$idx1][1], 8) = "" _
148+
Or StringStripWS($aSection[$idx2][1], 8) = "" _
149+
Or StringStripWS($aSection[$idx3][1], 8) = "" _
150+
Or StringStripWS($aSection[$idx4][1], 8) = "" _
151+
Or StringStripWS($aSection[$idx5][1], 8) = "" _
152+
Or StringStripWS($aSection[$idx6][1], 8) = "" _
153+
Or StringStripWS($aSection[$idx7][1], 8) = "" Then ContinueLoop
154+
155+
;anything that's left at this point is for the launcher to check for validity. It's good enough for us though, so we add it to our DB array
156+
ReDim $aAccountsDataDB[UBound($aAccountsDataDB) + 1][8]
157+
$aAccountsDataDB[UBound($aAccountsDataDB) - 1][0] = $aSectionnames[$i]
158+
$aAccountsDataDB[UBound($aAccountsDataDB) - 1][1] = $aSection[$idx1][1]
159+
$aAccountsDataDB[UBound($aAccountsDataDB) - 1][2] = $aSection[$idx2][1]
160+
$aAccountsDataDB[UBound($aAccountsDataDB) - 1][3] = $aSection[$idx3][1]
161+
$aAccountsDataDB[UBound($aAccountsDataDB) - 1][4] = $aSection[$idx4][1]
162+
$aAccountsDataDB[UBound($aAccountsDataDB) - 1][5] = $aSection[$idx5][1]
163+
$aAccountsDataDB[UBound($aAccountsDataDB) - 1][6] = $aSection[$idx6][1]
164+
$aAccountsDataDB[UBound($aAccountsDataDB) - 1][7] = $aSection[$idx7][1]
165+
Next
166+
;_arraydisplay($aAccountsDataDB)
167+
EndFunc ;==>_AccountsDataFromDB
168+
169+
Func _AccountDataFromLauncher()
170+
Local $sFile = _getMostCurrentUserConfigPath()
171+
If $sFile = -1 Then
172+
MsgBox(16, $title, "Launcher settings not found. Make sure E:D is installed and you have logged in at least once.")
173+
Exit
174+
EndIf
175+
176+
Local $hFile = FileOpen($sFile, 0)
177+
Local $content = FileRead($hFile)
178+
FileClose($hFile)
179+
180+
$_1 = _getPublicKeyToken($content, "userSettings")
181+
$_2 = _getPublicKeyToken($content, "FORCServerSupport.Properties.Settings")
182+
$_3 = _getPublicKeyToken($content, "ClientSupport.Properties.Settings")
183+
$_4 = _getPublicKeyToken($content, "CBViewModel.Properties.Settings")
184+
$_5 = _getSetting($content, "MachineToken")
185+
$_6 = _getSetting($content, "UserName")
186+
If $_6 = -1 Then $_6 = "none"
187+
$_7 = _getSetting($content, "Password")
188+
If $_7 = -1 Then $_7 = "none"
189+
;msgbox(0, "test", $_6 & @crlf & $_7)
190+
191+
If $_1 = -1 Or $_2 = -1 Or $_3 = -1 Or $_4 = -1 Or $_5 = -1 Then
192+
MsgBox(16, $title, "Unexpected launcher settings. Either the configuration file has been updated to a new layout or it was corrupted." & @CRLF & @CRLF & "Cannot continue." & @CRLF & @CRLF & "Exiting.")
193+
Exit
194+
EndIf
195+
196+
$aAccountsDataDB[UBound($aAccountsDataDB) - 1][0] = $sFile
197+
$aAccountsDataDB[UBound($aAccountsDataDB) - 1][1] = $_1
198+
$aAccountsDataDB[UBound($aAccountsDataDB) - 1][2] = $_2
199+
$aAccountsDataDB[UBound($aAccountsDataDB) - 1][3] = $_3
200+
$aAccountsDataDB[UBound($aAccountsDataDB) - 1][4] = $_4
201+
$aAccountsDataDB[UBound($aAccountsDataDB) - 1][5] = $_5
202+
$aAccountsDataDB[UBound($aAccountsDataDB) - 1][6] = $_6
203+
$aAccountsDataDB[UBound($aAccountsDataDB) - 1][7] = $_7
204+
;_arraydisplay($aAccountsDataDB)
205+
EndFunc ;==>_AccountDataFromLauncher
206+
207+
Func _CurrentToDB($startup = 0)
208+
; make sure we got up to date data from all data sources
209+
Dim $aAccountsDataDB[1][8]
210+
_AccountDataFromLauncher()
211+
_AccountsDataFromDB()
212+
_DBtoCombo()
213+
_SetCombo()
214+
215+
If UBound($aAccountsDataDB) >= 2 Then
216+
For $i = 1 To UBound($aAccountsDataDB) - 1
217+
If $aAccountsDataDB[0][1] = $aAccountsDataDB[$i][1] And _
218+
$aAccountsDataDB[0][2] = $aAccountsDataDB[$i][2] And _
219+
$aAccountsDataDB[0][3] = $aAccountsDataDB[$i][3] And _
220+
$aAccountsDataDB[0][4] = $aAccountsDataDB[$i][4] And _
221+
$aAccountsDataDB[0][5] = $aAccountsDataDB[$i][5] And _
222+
$aAccountsDataDB[0][6] = $aAccountsDataDB[$i][6] And _
223+
$aAccountsDataDB[0][7] = $aAccountsDataDB[$i][7] Then
224+
If $startup = 0 Then MsgBox(64, $title, "The launcher's current account settings are already saved in the accounts DB as:" & @CRLF & @CRLF & $aAccountsDataDB[$i][0])
225+
Return 0
226+
EndIf
227+
Next
228+
EndIf
229+
230+
If $startup = 1 And MsgBox(36, $title, "Current E:D account not found in account switcher DB. Shall I add it?") = 7 Then Return 0
231+
232+
Local $sIniname = @ScriptDir & "\accounts.ini"
233+
234+
$sSectionName = InputBox($title, "Enter a name for your new account", "Account " & UBound($aAccountsDataDB))
235+
If $sSectionName = "" Then
236+
MsgBox(48, $title, "Account name must not be empty.")
237+
Return 0
238+
EndIf
239+
;_arraydisplay($aAccountsDataDB)
240+
IniWrite($sIniname, $sSectionName, "userSettings", $aAccountsDataDB[0][1])
241+
IniWrite($sIniname, $sSectionName, "FORCServerSupport.Properties.Settings", $aAccountsDataDB[0][2])
242+
IniWrite($sIniname, $sSectionName, "ClientSupport.Properties.Settings", $aAccountsDataDB[0][3])
243+
IniWrite($sIniname, $sSectionName, "CBViewModel.Properties.Settings", $aAccountsDataDB[0][4])
244+
IniWrite($sIniname, $sSectionName, "MachineToken", $aAccountsDataDB[0][5])
245+
IniWrite($sIniname, $sSectionName, "UserName", $aAccountsDataDB[0][6])
246+
IniWrite($sIniname, $sSectionName, "Password", $aAccountsDataDB[0][7])
247+
248+
; rebuild the DB array with all data available and make the appropriate changes to the GUI
249+
Dim $aAccountsDataDB[1][8]
250+
_AccountDataFromLauncher()
251+
_AccountsDataFromDB()
252+
_DBtoCombo()
253+
_SetCombo()
254+
;_arraydisplay($aAccountsDataDB)
255+
EndFunc ;==>_CurrentToDB
256+
257+
Func _DBtoCombo()
258+
Local $sComboContent = ""
259+
For $i = 1 To UBound($aAccountsDataDB) - 1
260+
$sComboContent &= $aAccountsDataDB[$i][0] & "|"
261+
Next
262+
_GUICtrlComboBox_ResetContent($Combo1)
263+
GUICtrlSetData($Combo1, $sComboContent)
264+
EndFunc ;==>_DBtoCombo
265+
266+
Func _getPublicKeyToken($content, $section)
267+
Local $regex = StringRegExp($content, '(?Uis:' & $section & '.*publickeytoken=(.*)")', 1)
268+
If IsArray($regex) Then
269+
Return $regex[0]
270+
EndIf
271+
Return -1
272+
EndFunc ;==>_getPublicKeyToken
273+
274+
Func _getSetting($content, $setting)
275+
Local $regex = StringRegExp($content, '(?i)<setting name="' & $setting & '".*\s{1,}?.*<value>(.*)</value>', 1)
276+
If IsArray($regex) Then
277+
Return $regex[0]
278+
EndIf
279+
Return -1
280+
EndFunc ;==>_getSetting
281+
282+
Func _getMostCurrentUserConfigPath()
283+
Local $aFiles = _FileListToArrayRec("C:\Users\" & @UserName & "\AppData\Local\Frontier_Developments\", "user.config", 1, 1, 0, 2)
284+
If $aFiles = "" Then Return -1
285+
Local $aTest[0], $fullpath, $versionpath
286+
For $i = 1 To UBound($aFiles) - 1
287+
$fullpath = $aFiles[$i]
288+
$versionpath = StringRegExp($fullpath, "(?i:.*\\(.*\\user.config))", 1)
289+
If IsArray($versionpath) Then
290+
ReDim $aTest[UBound($aTest) + 1]
291+
$aTest[UBound($aTest) - 1] = $versionpath[0]
292+
EndIf
293+
Next
294+
_ArraySort($aTest, 1, 0)
295+
Local $idx = _ArraySearch($aFiles, $aTest[0], 0, 0, 1, 1)
296+
;_arraydisplay($aFiles, $idx)
297+
Return $aFiles[$idx]
298+
EndFunc ;==>_getMostCurrentUserConfigPath

source/arrows.ico

1.21 KB
Binary file not shown.

0 commit comments

Comments
 (0)