OSDN Git Service

More inventory improvements
[radegast/radegast.git] / Radegast / Core / RadegastInstance.cs
1 // \r
2 // Radegast Metaverse Client\r
3 // Copyright (c) 2009, Radegast Development Team\r
4 // All rights reserved.\r
5 // \r
6 // Redistribution and use in source and binary forms, with or without\r
7 // modification, are permitted provided that the following conditions are met:\r
8 // \r
9 //     * Redistributions of source code must retain the above copyright notice,\r
10 //       this list of conditions and the following disclaimer.\r
11 //     * Redistributions in binary form must reproduce the above copyright\r
12 //       notice, this list of conditions and the following disclaimer in the\r
13 //       documentation and/or other materials provided with the distribution.\r
14 //     * Neither the name of the application "Radegast", nor the names of its\r
15 //       contributors may be used to endorse or promote products derived from\r
16 //       this software without specific prior written permission.\r
17 // \r
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
19 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
20 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
21 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\r
22 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
23 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
24 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\r
25 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\r
26 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
28 //\r
29 // $Id$\r
30 //\r
31 using System;\r
32 using System.Collections.Generic;\r
33 using System.IO;\r
34 using System.Text;\r
35 using System.Windows.Forms;\r
36 using RadegastNc;\r
37 using OpenMetaverse;\r
38 \r
39 namespace Radegast\r
40 {\r
41     public class RadegastInstance\r
42     {\r
43         private GridClient client;\r
44         private RadegastNetcom netcom;\r
45 \r
46         private ImageCache imageCache;\r
47         private StateManager state;\r
48         private ConfigManager config;\r
49 \r
50         private frmMain mainForm;\r
51         private TabsConsole tabsConsole;\r
52 \r
53         // Singleton, there can be only one instance\r
54         private static RadegastInstance globalInstance = null;\r
55         public static RadegastInstance GlobalInstance\r
56         {\r
57             get\r
58             {\r
59                 if (globalInstance == null)\r
60                 {\r
61                     globalInstance = new RadegastInstance();\r
62                 }\r
63                 return globalInstance;\r
64             }\r
65         }\r
66 \r
67         private string userDir;\r
68         /// <summary>\r
69         /// System (not grid!) user's dir\r
70         /// </summary>\r
71         public string UserDir { get { return userDir; } }\r
72 \r
73         private string clientDir;\r
74         /// <summary>\r
75         /// Grid client's user dir for settings and logs\r
76         /// </summary>\r
77         public string ClientDir { get { return clientDir; } }\r
78 \r
79         private string animCacheDir;\r
80         public string AnimCacheDir { get { return animCacheDir; } }\r
81 \r
82         private string globalLogFile;\r
83         public string GlobalLogFile { get { return globalLogFile; } }\r
84 \r
85         private bool monoRuntime;\r
86         public bool MonoRuntime { get { return monoRuntime; } }\r
87 \r
88         public Dictionary<UUID, Group> groups;\r
89         public Dictionary<UUID, string> nameCache = new Dictionary<UUID,string>();\r
90 \r
91         public delegate void OnAvatarNameCallBack(UUID agentID, string agentName);\r
92         public event OnAvatarNameCallBack OnAvatarName;\r
93 \r
94         public readonly bool advancedDebugging = false;\r
95 \r
96         private RadegastInstance()\r
97         {\r
98             InitializeLoggingAndConfig();\r
99 \r
100             // Settings.PIPELINE_REFRESH_INTERVAL = 2000.0f;\r
101 \r
102             client = new GridClient();\r
103             client.Settings.ALWAYS_REQUEST_OBJECTS = true;\r
104             client.Settings.ALWAYS_DECODE_OBJECTS = true;\r
105             client.Settings.OBJECT_TRACKING = true;\r
106             client.Settings.ENABLE_SIMSTATS = true;\r
107             client.Settings.FETCH_MISSING_INVENTORY = true;\r
108             client.Settings.MULTIPLE_SIMS = false;\r
109             client.Settings.SEND_AGENT_THROTTLE = true;\r
110             client.Settings.SEND_AGENT_UPDATES = true;\r
111 \r
112             client.Settings.USE_TEXTURE_CACHE = true;\r
113             client.Settings.TEXTURE_CACHE_DIR = Path.Combine(userDir,  "cache");\r
114             client.Assets.Cache.AutoPruneEnabled = false;\r
115     \r
116             client.Throttle.Texture = 2446000.0f;\r
117             client.Throttle.Asset = 2446000.0f;\r
118             client.Settings.THROTTLE_OUTGOING_PACKETS = true;\r
119             client.Settings.LOGIN_TIMEOUT = 120 * 1000;\r
120             client.Settings.SIMULATOR_TIMEOUT = 120 * 1000;\r
121             client.Settings.USE_INTERPOLATION_TIMER = false;\r
122             client.Settings.MAX_CONCURRENT_TEXTURE_DOWNLOADS = 20;\r
123 \r
124             netcom = new RadegastNetcom(client);\r
125             imageCache = new ImageCache();\r
126             state = new StateManager(this);\r
127 \r
128             InitializeConfigLegacy();\r
129 \r
130             mainForm = new frmMain(this);\r
131             mainForm.InitializeControls();\r
132             tabsConsole = mainForm.TabConsole;\r
133 \r
134             Application.ApplicationExit += new EventHandler(Application_ApplicationExit);\r
135             groups = new Dictionary<UUID, Group>();\r
136          \r
137             client.Groups.OnCurrentGroups += new GroupManager.CurrentGroupsCallback(Groups_OnCurrentGroups);\r
138             client.Groups.OnGroupLeft += new GroupManager.GroupLeftCallback(Groups_OnGroupLeft);\r
139             client.Groups.OnGroupDropped += new GroupManager.GroupDroppedCallback(Groups_OnGroupDropped);\r
140             client.Groups.OnGroupJoined += new GroupManager.GroupJoinedCallback(Groups_OnGroupJoined);\r
141             client.Groups.OnGroupProfile += new GroupManager.GroupProfileCallback(Groups_OnGroupProfile);\r
142             client.Avatars.OnAvatarNames += new AvatarManager.AvatarNamesCallback(Avatars_OnAvatarNames);\r
143             client.Network.OnLogin += new NetworkManager.LoginCallback(Network_OnLogin);\r
144             client.Network.OnDisconnected += new NetworkManager.DisconnectedCallback(Network_OnDisconnected);\r
145         }\r
146 \r
147         public void CleanUp()\r
148         {\r
149             if (client != null)\r
150             {\r
151                 client.Groups.OnCurrentGroups -= new GroupManager.CurrentGroupsCallback(Groups_OnCurrentGroups);\r
152                 client.Groups.OnGroupLeft -= new GroupManager.GroupLeftCallback(Groups_OnGroupLeft);\r
153                 client.Groups.OnGroupDropped -= new GroupManager.GroupDroppedCallback(Groups_OnGroupDropped);\r
154                 client.Groups.OnGroupJoined -= new GroupManager.GroupJoinedCallback(Groups_OnGroupJoined);\r
155                 client.Groups.OnGroupProfile -= new GroupManager.GroupProfileCallback(Groups_OnGroupProfile);\r
156                 client.Avatars.OnAvatarNames -= new AvatarManager.AvatarNamesCallback(Avatars_OnAvatarNames);\r
157                 client.Network.OnLogin -= new NetworkManager.LoginCallback(Network_OnLogin);\r
158                 client.Network.OnDisconnected -= new NetworkManager.DisconnectedCallback(Network_OnDisconnected);\r
159             }\r
160 \r
161             if (MonoRuntime)\r
162             {\r
163                 Environment.Exit(0);\r
164             }\r
165 \r
166         }\r
167 \r
168         void Avatars_OnAvatarNames(Dictionary<UUID, string> names)\r
169         {\r
170             lock (nameCache)\r
171             {\r
172                 foreach (KeyValuePair<UUID, string> av in names)\r
173                 {\r
174                     if (OnAvatarName != null) try { OnAvatarName(av.Key, av.Value); }\r
175                         catch (Exception) { };\r
176 \r
177                     if (!nameCache.ContainsKey(av.Key))\r
178                     {\r
179                         nameCache.Add(av.Key, av.Value);\r
180                     }\r
181                 }\r
182             }\r
183         }\r
184 \r
185         public string getAvatarName(UUID key)\r
186         {\r
187             if (nameCache.ContainsKey(key))\r
188             {\r
189                 return nameCache[key];\r
190             }\r
191             else\r
192             {\r
193                 client.Avatars.RequestAvatarName(key);\r
194                 return "Loading...";\r
195             }\r
196         }\r
197 \r
198         void Groups_OnGroupProfile(Group group)\r
199         {\r
200             if (groups.ContainsKey(group.ID))\r
201             {\r
202                 groups[group.ID] = group;\r
203             }\r
204         }\r
205 \r
206         void Groups_OnGroupJoined(UUID groupID, bool success)\r
207         {\r
208             if (success && !groups.ContainsKey(groupID))\r
209             {\r
210                 groups.Add(groupID, new Group());\r
211                 client.Groups.RequestGroupProfile(groupID);\r
212             }\r
213         }\r
214 \r
215         void Groups_OnGroupLeft(UUID groupID, bool success)\r
216         {\r
217             if (groups.ContainsKey(groupID))\r
218             {\r
219                 groups.Remove(groupID);\r
220             }\r
221         }\r
222 \r
223         void Groups_OnGroupDropped(UUID groupID)\r
224         {\r
225             if (groups.ContainsKey(groupID))\r
226             {\r
227                 groups.Remove(groupID);\r
228             }\r
229         }\r
230 \r
231         void Network_OnDisconnected(NetworkManager.DisconnectType reason, string message)\r
232         {\r
233             clientDir = null;\r
234         }\r
235 \r
236         void Network_OnLogin(LoginStatus login, string message)\r
237         {\r
238             if (login != LoginStatus.Success)\r
239                 return;\r
240 \r
241             clientDir = Path.Combine(userDir, client.Self.Name);\r
242             try\r
243             {\r
244                 if (!Directory.Exists(clientDir))\r
245                 {\r
246                     Directory.CreateDirectory(clientDir);\r
247                 }\r
248             }\r
249             catch (Exception)\r
250             {\r
251                 clientDir = Directory.GetCurrentDirectory();\r
252             }\r
253 \r
254         }\r
255 \r
256         public void LogClientMessage(string fileName, string message)\r
257         {\r
258             if (clientDir == null) return;\r
259 \r
260             lock (this)\r
261             {\r
262                 try\r
263                 {\r
264                     foreach (char lDisallowed in System.IO.Path.GetInvalidFileNameChars())\r
265                     {\r
266                         fileName = fileName.Replace(lDisallowed.ToString(), "_");\r
267                     }\r
268 \r
269                     StreamWriter logfile = File.AppendText(Path.Combine(clientDir, fileName));\r
270                     logfile.WriteLine(DateTime.Now.ToString("yyyy-MM-dd [HH:mm:ss] ") + message);\r
271                     logfile.Close();\r
272                     logfile.Dispose();\r
273                 }\r
274                 catch (Exception) { }\r
275             }\r
276         }\r
277 \r
278         void Groups_OnCurrentGroups(Dictionary<UUID, Group> gr)\r
279         {\r
280             this.groups = gr;\r
281         }\r
282 \r
283         private void Application_ApplicationExit(object sender, EventArgs e)\r
284         {\r
285             config.SaveCurrentConfig();\r
286         }\r
287 \r
288         private void InitializeLoggingAndConfig()\r
289         {\r
290             // Are we running mono?\r
291             if (null == Type.GetType("Mono.Runtime"))\r
292             {\r
293                 monoRuntime = false;\r
294             }\r
295             else\r
296             {\r
297                 monoRuntime = true;\r
298             }\r
299 \r
300             try\r
301             {\r
302                 userDir = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.ApplicationData), Properties.Resources.ProgramName);\r
303                 if (!Directory.Exists(userDir))\r
304                 {\r
305                     Directory.CreateDirectory(userDir);\r
306                 }\r
307             }\r
308             catch (Exception)\r
309             {\r
310                 userDir = System.Environment.CurrentDirectory;\r
311             };\r
312 \r
313             animCacheDir = Path.Combine(userDir, @"anim_cache");\r
314             globalLogFile = Path.Combine(userDir, Properties.Resources.ProgramName + ".log");\r
315         }\r
316 \r
317         private void InitializeConfigLegacy()\r
318         {\r
319             config = new ConfigManager(this);\r
320             config.ApplyDefault();\r
321 \r
322             netcom.LoginOptions.FirstName = config.CurrentConfig.FirstName;\r
323             netcom.LoginOptions.LastName = config.CurrentConfig.LastName;\r
324             netcom.LoginOptions.Password = config.CurrentConfig.PasswordMD5;\r
325             netcom.LoginOptions.IsPasswordMD5 = true;\r
326         }\r
327 \r
328         public GridClient Client\r
329         {\r
330             get { return client; }\r
331         }\r
332 \r
333         public RadegastNetcom Netcom\r
334         {\r
335             get { return netcom; }\r
336         }\r
337 \r
338         public ImageCache ImageCache\r
339         {\r
340             get { return imageCache; }\r
341         }\r
342 \r
343         public StateManager State\r
344         {\r
345             get { return state; }\r
346         }\r
347 \r
348         public ConfigManager Config\r
349         {\r
350             get { return config; }\r
351         }\r
352 \r
353         public frmMain MainForm\r
354         {\r
355             get { return mainForm; }\r
356         }\r
357 \r
358         public TabsConsole TabConsole\r
359         {\r
360             get { return tabsConsole; }\r
361         }\r
362     }\r
363 }\r