OSDN Git Service

27b5e715a3281dbaa4b2a6182dd3fa5b5c6830bb
[radegast/radegast.git] / Radegast / GUI / Consoles / LoginConsole.cs
1 // 
2 // Radegast Metaverse Client
3 // Copyright (c) 2009-2013, Radegast Development Team
4 // All rights reserved.
5 // 
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are met:
8 // 
9 //     * Redistributions of source code must retain the above copyright notice,
10 //       this list of conditions and the following disclaimer.
11 //     * Redistributions in binary form must reproduce the above copyright
12 //       notice, this list of conditions and the following disclaimer in the
13 //       documentation and/or other materials provided with the distribution.
14 //     * Neither the name of the application "Radegast", nor the names of its
15 //       contributors may be used to endorse or promote products derived from
16 //       this software without specific prior written permission.
17 // 
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 //
29 // $Id$
30 //
31 using System;
32 using System.Drawing;
33 using System.Windows.Forms;
34 using OpenMetaverse;
35 using OpenMetaverse.StructuredData;
36 using Radegast.Netcom;
37
38 namespace Radegast
39 {
40     public partial class LoginConsole : UserControl, IRadegastTabControl
41     {
42         private RadegastInstance instance;
43         private RadegastNetcom netcom { get { return instance.Netcom; } }
44
45         public LoginConsole(RadegastInstance instance)
46         {
47             InitializeComponent();
48             Disposed += new EventHandler(MainConsole_Disposed);
49
50             this.instance = instance;
51             AddNetcomEvents();
52
53             if (instance.GlobalSettings["hide_login_graphics"].AsBoolean())
54                 pnlSplash.BackgroundImage = null;
55             else
56                 pnlSplash.BackgroundImage = Properties.Resources.radegast_main_screen2;
57
58             if (!instance.GlobalSettings.ContainsKey("remember_login"))
59             {
60                 instance.GlobalSettings["remember_login"] = true;
61             }
62
63             instance.GlobalSettings.OnSettingChanged += new Settings.SettingChangedCallback(GlobalSettings_OnSettingChanged);
64
65             lblVersion.Text = Properties.Resources.RadegastTitle + "." + RadegastBuild.CurrentRev;
66
67             Load += new EventHandler(LoginConsole_Load);
68
69         }
70
71         private void MainConsole_Disposed(object sender, EventArgs e)
72         {
73             instance.GlobalSettings.OnSettingChanged -= new Settings.SettingChangedCallback(GlobalSettings_OnSettingChanged);
74             RemoveNetcomEvents();
75         }
76
77         void LoginConsole_Load(object sender, EventArgs e)
78         {
79             if (instance.PlainColors)
80                 panel1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(210)))), ((int)(((byte)(210)))), ((int)(((byte)(225)))));
81
82             cbxLocation.SelectedIndex = 0;
83             cbxUsername.SelectedIndexChanged += cbxUsername_SelectedIndexChanged;
84             InitializeConfig();
85         }
86
87         private void AddNetcomEvents()
88         {
89             netcom.ClientLoggingIn += new EventHandler<OverrideEventArgs>(netcom_ClientLoggingIn);
90             netcom.ClientLoginStatus += new EventHandler<LoginProgressEventArgs>(netcom_ClientLoginStatus);
91             netcom.ClientLoggingOut += new EventHandler<OverrideEventArgs>(netcom_ClientLoggingOut);
92             netcom.ClientLoggedOut += new EventHandler(netcom_ClientLoggedOut);
93         }
94
95         private void RemoveNetcomEvents()
96         {
97             netcom.ClientLoggingIn -= new EventHandler<OverrideEventArgs>(netcom_ClientLoggingIn);
98             netcom.ClientLoginStatus -= new EventHandler<LoginProgressEventArgs>(netcom_ClientLoginStatus);
99             netcom.ClientLoggingOut -= new EventHandler<OverrideEventArgs>(netcom_ClientLoggingOut);
100             netcom.ClientLoggedOut -= new EventHandler(netcom_ClientLoggedOut);
101         }
102
103         void GlobalSettings_OnSettingChanged(object sender, SettingsEventArgs e)
104         {
105             if (e.Key == "hide_login_graphics")
106             {
107                 if (e.Value.AsBoolean())
108                     pnlSplash.BackgroundImage = null;
109                 else
110                     pnlSplash.BackgroundImage = Properties.Resources.radegast_main_screen2;
111             }
112         }
113
114         private void SaveConfig()
115         {
116             Settings s = instance.GlobalSettings;
117             SavedLogin sl = new SavedLogin();
118
119             string username = cbxUsername.Text;
120
121             if (cbxUsername.SelectedIndex > 0 && cbxUsername.SelectedItem is SavedLogin)
122             {
123                 username = ((SavedLogin)cbxUsername.SelectedItem).Username;
124             }
125
126             if (cbxGrid.SelectedIndex == cbxGrid.Items.Count - 1) // custom login uri
127             {
128                 sl.GridID = "custom_login_uri";
129                 sl.CustomURI = txtCustomLoginUri.Text;
130             }
131             else
132             {
133                 sl.GridID = (cbxGrid.SelectedItem as Grid).ID;
134                 sl.CustomURI = string.Empty;
135             }
136
137             string savedLoginsKey = string.Format("{0}%{1}", username, sl.GridID);
138
139             if (!(s["saved_logins"] is OSDMap))
140             {
141                 s["saved_logins"] = new OSDMap();
142             }
143
144             if (cbRemember.Checked)
145             {
146
147                 sl.Username = s["username"] = username;
148
149                 if (LoginOptions.IsPasswordMD5(txtPassword.Text))
150                 {
151                     sl.Password = txtPassword.Text;
152                     s["password"] = txtPassword.Text;
153                 }
154                 else
155                 {
156                     sl.Password =Utils.MD5(txtPassword.Text);
157                     s["password"] = Utils.MD5(txtPassword.Text);
158                 }
159                 if (cbxLocation.SelectedIndex == -1)
160                 {
161                     sl.CustomStartLocation = cbxLocation.Text;
162                 }
163                 else
164                 {
165                     sl.CustomStartLocation = string.Empty;
166                 }
167                 sl.StartLocationType = cbxLocation.SelectedIndex;
168                 ((OSDMap)s["saved_logins"])[savedLoginsKey] = sl.ToOSD();
169             }
170             else if (((OSDMap)s["saved_logins"]).ContainsKey(savedLoginsKey))
171             {
172                 ((OSDMap)s["saved_logins"]).Remove(savedLoginsKey);
173             }
174
175             s["login_location_type"] = OSD.FromInteger(cbxLocation.SelectedIndex);
176             s["login_location"] = OSD.FromString(cbxLocation.Text);
177
178             s["login_grid"] = OSD.FromInteger(cbxGrid.SelectedIndex);
179             s["login_uri"] = OSD.FromString(txtCustomLoginUri.Text);
180             s["remember_login"] = cbRemember.Checked;
181         }
182
183         private void ClearConfig()
184         {
185             Settings s = instance.GlobalSettings;
186             s["username"] = string.Empty;
187             s["password"] = string.Empty;
188         }
189
190         private void InitializeConfig()
191         {
192             // Initilize grid dropdown
193             int gridIx = -1;
194
195             cbxGrid.Items.Clear();
196             for (int i = 0; i < instance.GridManger.Count; i++)
197             {
198                 cbxGrid.Items.Add(instance.GridManger[i]);
199                 if (MainProgram.CommandLine.Grid == instance.GridManger[i].ID)
200                     gridIx = i;
201             }
202             cbxGrid.Items.Add("Custom");
203
204             if (gridIx != -1)
205             {
206                 cbxGrid.SelectedIndex = gridIx;
207             }
208
209
210             Settings s = instance.GlobalSettings;
211             cbRemember.Checked = s["remember_login"];
212
213             // Setup login name
214             string savedUsername;
215
216             if (string.IsNullOrEmpty(MainProgram.CommandLine.Username))
217             {
218                 savedUsername = s["username"];
219             }
220             else
221             {
222                 savedUsername = MainProgram.CommandLine.Username;
223             }
224
225             cbxUsername.Items.Add(savedUsername);
226
227             try
228             {
229                 if (s["saved_logins"] is OSDMap)
230                 {
231                     OSDMap savedLogins = (OSDMap)s["saved_logins"];
232                     foreach (string loginKey in savedLogins.Keys)
233                     {
234                         SavedLogin sl = SavedLogin.FromOSD(savedLogins[loginKey]);
235                         cbxUsername.Items.Add(sl);
236                     }
237                 }
238             }
239             catch
240             {
241                 cbxUsername.Items.Clear();
242                 cbxUsername.Text = string.Empty;
243             }
244
245             cbxUsername.SelectedIndex = 0;
246
247             // Fill in saved password or use one specified on the command line
248             if (string.IsNullOrEmpty(MainProgram.CommandLine.Password))
249             {
250                 txtPassword.Text = s["password"].AsString();
251             }
252             else
253             {
254                 txtPassword.Text = MainProgram.CommandLine.Password;
255             }
256
257
258             // Setup login location either from the last used or
259             // override from the command line
260             if (string.IsNullOrEmpty(MainProgram.CommandLine.Location))
261             {
262                 // Use last location as default
263                 if (s["login_location_type"].Type == OSDType.Unknown)
264                 {
265                     cbxLocation.SelectedIndex = 1;
266                     s["login_location_type"] = OSD.FromInteger(1);
267                 }
268                 else
269                 {
270                     cbxLocation.SelectedIndex = s["login_location_type"].AsInteger();
271                     cbxLocation.Text = s["login_location"].AsString();
272                 }
273             }
274             else
275             {
276                 switch (MainProgram.CommandLine.Location)
277                 {
278                     case "home":
279                         cbxLocation.SelectedIndex = 0;
280                         break;
281
282                     case "last":
283                         cbxLocation.SelectedIndex = 1;
284                         break;
285
286                     default:
287                         cbxLocation.SelectedIndex = -1;
288                         cbxLocation.Text = MainProgram.CommandLine.Location;
289                         break;
290                 }
291             }
292
293
294             // Set grid dropdown to last used, or override from command line
295             if (string.IsNullOrEmpty(MainProgram.CommandLine.Grid))
296             {
297                 cbxGrid.SelectedIndex = s["login_grid"].AsInteger();
298             }
299             else if (gridIx == -1) // --grid specified but not found
300             {
301                 MessageBox.Show(string.Format("Grid specified with --grid {0} not found", MainProgram.CommandLine.Grid),
302                     "Grid not found",
303                     MessageBoxButtons.OK,
304                     MessageBoxIcon.Warning
305                     );
306             }
307
308             // Restore login uri from settings, or command line
309             if (string.IsNullOrEmpty(MainProgram.CommandLine.LoginUri))
310             {
311                 txtCustomLoginUri.Text = s["login_uri"].AsString();
312             }
313             else
314             {
315                 txtCustomLoginUri.Text = MainProgram.CommandLine.LoginUri;
316                 cbxGrid.SelectedIndex = cbxGrid.Items.Count - 1;
317             }
318
319             // Start logging in if autologin enabled from command line
320             if (MainProgram.CommandLine.AutoLogin)
321             {
322                 BeginLogin();
323             }
324         }
325
326         private void netcom_ClientLoginStatus(object sender, LoginProgressEventArgs e)
327         {
328             switch (e.Status)
329             {
330                 case LoginStatus.ConnectingToLogin:
331                     lblLoginStatus.Text = "Connecting to login server...";
332                     lblLoginStatus.ForeColor = Color.Black;
333                     break;
334
335                 case LoginStatus.ConnectingToSim:
336                     lblLoginStatus.Text = "Connecting to region...";
337                     lblLoginStatus.ForeColor = Color.Black;
338                     break;
339
340                 case LoginStatus.Redirecting:
341                     lblLoginStatus.Text = "Redirecting...";
342                     lblLoginStatus.ForeColor = Color.Black;
343                     break;
344
345                 case LoginStatus.ReadingResponse:
346                     lblLoginStatus.Text = "Reading response...";
347                     lblLoginStatus.ForeColor = Color.Black;
348                     break;
349
350                 case LoginStatus.Success:
351                     lblLoginStatus.Text = "Logged in as " + netcom.LoginOptions.FullName;
352                     lblLoginStatus.ForeColor = Color.FromArgb(0, 128, 128, 255);
353                     proLogin.Visible = false;
354
355                     btnLogin.Text = "Logout";
356                     btnLogin.Enabled = true;
357                     instance.Client.Groups.RequestCurrentGroups();
358                     break;
359
360                 case LoginStatus.Failed:
361                     lblLoginStatus.ForeColor = Color.Red;
362                     if (e.FailReason == "tos")
363                     {
364                         lblLoginStatus.Text = "Must agree to Terms of Service before logging in";
365                         pnlTos.Visible = true;
366                         txtTOS.Text = e.Message.Replace("\n", "\r\n");
367                         btnLogin.Enabled = false;
368                     }
369                     else
370                     {
371                         lblLoginStatus.Text = e.Message;
372                         btnLogin.Enabled = true;
373                     }
374                     proLogin.Visible = false;
375
376                     btnLogin.Text = "Retry";
377                     break;
378             }
379         }
380
381         private void netcom_ClientLoggedOut(object sender, EventArgs e)
382         {
383             pnlLoginPrompt.Visible = true;
384             pnlLoggingIn.Visible = false;
385
386             btnLogin.Text = "Exit";
387             btnLogin.Enabled = true;
388         }
389
390         private void netcom_ClientLoggingOut(object sender, OverrideEventArgs e)
391         {
392             btnLogin.Enabled = false;
393
394             lblLoginStatus.Text = "Logging out...";
395             lblLoginStatus.ForeColor = Color.FromKnownColor(KnownColor.ControlText);
396
397             proLogin.Visible = true;
398         }
399
400         private void netcom_ClientLoggingIn(object sender, OverrideEventArgs e)
401         {
402             lblLoginStatus.Text = "Logging in...";
403             lblLoginStatus.ForeColor = Color.FromKnownColor(KnownColor.ControlText);
404
405             proLogin.Visible = true;
406             pnlLoggingIn.Visible = true;
407             pnlLoginPrompt.Visible = false;
408
409             btnLogin.Enabled = false;
410         }
411
412         private void BeginLogin()
413         {
414             string username = cbxUsername.Text;
415
416             if (cbxUsername.SelectedIndex > 0 && cbxUsername.SelectedItem is SavedLogin)
417             {
418                 username = ((SavedLogin)cbxUsername.SelectedItem).Username;
419             }
420
421             string[] parts = System.Text.RegularExpressions.Regex.Split(username.Trim(), @"[. ]+");
422
423             if (parts.Length == 2)
424             {
425                 netcom.LoginOptions.FirstName = parts[0];
426                 netcom.LoginOptions.LastName = parts[1];
427             }
428             else
429             {
430                 netcom.LoginOptions.FirstName = username.Trim();
431                 netcom.LoginOptions.LastName = "Resident";
432             }
433
434             netcom.LoginOptions.Password = txtPassword.Text;
435             netcom.LoginOptions.Channel = Properties.Resources.ProgramName; // Channel
436             netcom.LoginOptions.Version = Properties.Resources.RadegastTitle; // Version
437             netcom.AgreeToTos = cbTOS.Checked;
438
439             switch (cbxLocation.SelectedIndex)
440             {
441                 case -1: //Custom
442                     netcom.LoginOptions.StartLocation = StartLocationType.Custom;
443                     netcom.LoginOptions.StartLocationCustom = cbxLocation.Text;
444                     break;
445
446                 case 0: //Home
447                     netcom.LoginOptions.StartLocation = StartLocationType.Home;
448                     break;
449
450                 case 1: //Last
451                     netcom.LoginOptions.StartLocation = StartLocationType.Last;
452                     break;
453             }
454
455             if (cbxGrid.SelectedIndex == cbxGrid.Items.Count - 1) // custom login uri
456             {
457                 if (txtCustomLoginUri.TextLength == 0 || txtCustomLoginUri.Text.Trim().Length == 0)
458                 {
459                     MessageBox.Show("You must specify the Login Uri to connect to a custom grid.", Properties.Resources.ProgramName, MessageBoxButtons.OK, MessageBoxIcon.Error);
460                     return;
461                 }
462
463                 netcom.LoginOptions.Grid = new Grid("custom", "Custom", txtCustomLoginUri.Text);
464                 netcom.LoginOptions.GridCustomLoginUri = txtCustomLoginUri.Text;
465             }
466             else
467             {
468                 netcom.LoginOptions.Grid = cbxGrid.SelectedItem as Grid;
469             }
470
471             if (netcom.LoginOptions.Grid.Platform != "SecondLife")
472             {
473                 instance.Client.Settings.MULTIPLE_SIMS = true;
474             }
475
476             instance.Client.Settings.HTTP_INVENTORY = !instance.GlobalSettings["disable_http_inventory"];
477             netcom.Login();
478             SaveConfig();
479         }
480
481         private void btnLogin_Click(object sender, EventArgs e)
482         {
483             switch (btnLogin.Text)
484             {
485                 case "Login": BeginLogin(); break;
486
487                 case "Retry":
488                     pnlLoginPrompt.Visible = true;
489                     pnlLoggingIn.Visible = false;
490                     btnLogin.Text = "Login";
491                     break;
492             }
493         }
494
495         #region IRadegastTabControl Members
496
497         public void RegisterTab(RadegastTab tab)
498         {
499             tab.DefaultControlButton = btnLogin;
500         }
501
502         #endregion
503
504         private void cbxGrid_SelectedIndexChanged(object sender, EventArgs e)
505         {
506             if (cbxGrid.SelectedIndex == cbxGrid.Items.Count - 1) //Custom option is selected
507             {
508                 txtCustomLoginUri.Enabled = true;
509                 txtCustomLoginUri.Select();
510             }
511             else
512             {
513                 txtCustomLoginUri.Enabled = false;
514             }
515         }
516
517         private void cbTOS_CheckedChanged(object sender, EventArgs e)
518         {
519             btnLogin.Enabled = cbTOS.Checked;
520         }
521
522         private void cbRemember_CheckedChanged(object sender, EventArgs e)
523         {
524             instance.GlobalSettings["remember_login"] = cbRemember.Checked;
525             if (!cbRemember.Checked)
526             {
527                 ClearConfig();
528             }
529         }
530
531         private void cbxUsername_SelectedIndexChanged(object sender, EventArgs e)
532         {
533             cbxUsername.SelectedIndexChanged -= cbxUsername_SelectedIndexChanged;
534
535             if (cbxUsername.SelectedIndex > 0
536                 && cbxUsername.SelectedItem is SavedLogin)
537             {
538                 SavedLogin sl = (SavedLogin)cbxUsername.SelectedItem;
539                 cbxUsername.Text = sl.Username;
540                 cbxUsername.Items[0] = sl.Username;
541                 cbxUsername.SelectedIndex = 0;
542                 txtPassword.Text = sl.Password;
543                 cbxLocation.SelectedIndex = sl.StartLocationType;
544                 if (sl.StartLocationType == -1)
545                 {
546                     cbxLocation.Text = sl.CustomStartLocation;
547                 }
548                 if (sl.GridID == "custom_login_uri")
549                 {
550                     cbxGrid.SelectedIndex = cbxGrid.Items.Count - 1;
551                     txtCustomLoginUri.Text = sl.CustomURI;
552                 }
553                 else
554                 {
555                     foreach (var item in cbxGrid.Items)
556                     {
557                         if (item is Grid && ((Grid)item).ID == sl.GridID)
558                         {
559                             cbxGrid.SelectedItem = item;
560                             break;
561                         }
562                     }
563                 }
564             }
565
566             cbxUsername.SelectedIndexChanged += cbxUsername_SelectedIndexChanged;
567         }
568     }
569
570     public class SavedLogin
571     {
572         public string Username;
573         public string Password;
574         public string GridID;
575         public string CustomURI;
576         public int StartLocationType;
577         public string CustomStartLocation;
578
579         public OSDMap ToOSD()
580         {
581             OSDMap ret = new OSDMap(4);
582             ret["username"] = Username;
583             ret["password"] = Password;
584             ret["grid"] = GridID;
585             ret["custom_url"] = CustomURI;
586             ret["location_type"] = StartLocationType;
587             ret["custom_location"] = CustomStartLocation;
588             return ret;
589         }
590
591         public static SavedLogin FromOSD(OSD data)
592         {
593             if (!(data is OSDMap)) return null;
594             OSDMap map = (OSDMap)data;
595             SavedLogin ret = new SavedLogin();
596             ret.Username = map["username"];
597             ret.Password = map["password"];
598             ret.GridID = map["grid"];
599             ret.CustomURI = map["custom_url"];
600             if (map.ContainsKey("location_type"))
601             {
602                 ret.StartLocationType = map["location_type"];
603             }
604             else
605             {
606                 ret.StartLocationType = 1;
607             }
608             ret.CustomStartLocation = map["custom_location"];
609             return ret;
610         }
611
612         public override string ToString()
613         {
614             RadegastInstance instance = RadegastInstance.GlobalInstance;
615             string gridName;
616             if (GridID == "custom_login_uri")
617             {
618                 gridName = "Custom Login URI";
619             }
620             else if (instance.GridManger.KeyExists(GridID))
621             {
622                 gridName = instance.GridManger[GridID].Name;
623             }
624             else
625             {
626                 gridName = GridID;
627             }
628             return string.Format("{0} -- {1}", Username, gridName);
629         }
630     }
631 }