OSDN Git Service

Moved libopenmetavrse outside the radegast folder, now we expected it to be in ....
[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 Radegast.Netcom;\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         /// <summary>\r
74         /// Grid client's user dir for settings and logs\r
75         /// </summary>\r
76         public string ClientDir\r
77         {\r
78             get\r
79             {\r
80                 if (client != null && client.Self != null && !string.IsNullOrEmpty(client.Self.Name))\r
81                 {\r
82                     return Path.Combine(userDir, client.Self.Name);\r
83                 }\r
84                 else\r
85                 {\r
86                     return Environment.CurrentDirectory;\r
87                 }\r
88             }\r
89         }\r
90 \r
91         public string InventoryCacheFileName { get { return Path.Combine(ClientDir, "inventory.cache"); } }\r
92 \r
93         private string animCacheDir;\r
94         public string AnimCacheDir { get { return animCacheDir; } }\r
95 \r
96         private string globalLogFile;\r
97         public string GlobalLogFile { get { return globalLogFile; } }\r
98 \r
99         private bool monoRuntime;\r
100         public bool MonoRuntime { get { return monoRuntime; } }\r
101 \r
102         private Dictionary<UUID, Group> groups;\r
103         public Dictionary<UUID, Group> Groups { get { return groups; } }\r
104 \r
105         //public delegate void AvatarNameCallback(UUID agentID, string agentName);\r
106         //public event AvatarNameCallback OnAvatarName;\r
107 \r
108         public Dictionary<UUID, string> nameCache = new Dictionary<UUID,string>();\r
109 \r
110         public const string INCOMPLETE_NAME = "Loading...";\r
111 \r
112         public readonly bool advancedDebugging = false;\r
113 \r
114         private RadegastInstance()\r
115         {\r
116             InitializeLoggingAndConfig();\r
117 \r
118             Settings.USE_INTERPOLATION_TIMER = false;\r
119             \r
120             client = new GridClient();\r
121             client.Settings.ALWAYS_REQUEST_OBJECTS = true;\r
122             client.Settings.ALWAYS_DECODE_OBJECTS = true;\r
123             client.Settings.OBJECT_TRACKING = true;\r
124             client.Settings.ENABLE_SIMSTATS = true;\r
125             client.Settings.FETCH_MISSING_INVENTORY = true;\r
126             client.Settings.MULTIPLE_SIMS = true;\r
127             client.Settings.SEND_AGENT_THROTTLE = true;\r
128             client.Settings.SEND_AGENT_UPDATES = true;\r
129 \r
130             client.Settings.USE_ASSET_CACHE = true;\r
131             client.Settings.ASSET_CACHE_DIR = Path.Combine(userDir,  "cache");\r
132             client.Assets.Cache.AutoPruneEnabled = false;\r
133     \r
134             client.Throttle.Texture = 2446000.0f;\r
135             client.Throttle.Asset = 2446000.0f;\r
136             client.Settings.THROTTLE_OUTGOING_PACKETS = true;\r
137             client.Settings.LOGIN_TIMEOUT = 120 * 1000;\r
138             client.Settings.SIMULATOR_TIMEOUT = 120 * 1000;\r
139             client.Settings.MAX_CONCURRENT_TEXTURE_DOWNLOADS = 20;\r
140 \r
141             netcom = new RadegastNetcom(client);\r
142             imageCache = new ImageCache();\r
143             state = new StateManager(this);\r
144 \r
145             InitializeConfigLegacy();\r
146 \r
147             mainForm = new frmMain(this);\r
148             mainForm.InitializeControls();\r
149             tabsConsole = mainForm.TabConsole;\r
150 \r
151             Application.ApplicationExit += new EventHandler(Application_ApplicationExit);\r
152             groups = new Dictionary<UUID, Group>();\r
153          \r
154             client.Groups.OnCurrentGroups += new GroupManager.CurrentGroupsCallback(Groups_OnCurrentGroups);\r
155             client.Groups.OnGroupLeft += new GroupManager.GroupLeftCallback(Groups_OnGroupLeft);\r
156             client.Groups.OnGroupDropped += new GroupManager.GroupDroppedCallback(Groups_OnGroupDropped);\r
157             client.Groups.OnGroupJoined += new GroupManager.GroupJoinedCallback(Groups_OnGroupJoined);\r
158             client.Avatars.OnAvatarNames += new AvatarManager.AvatarNamesCallback(Avatars_OnAvatarNames);\r
159         }\r
160 \r
161         public void CleanUp()\r
162         {\r
163             if (client != null)\r
164             {\r
165                 client.Groups.OnCurrentGroups -= new GroupManager.CurrentGroupsCallback(Groups_OnCurrentGroups);\r
166                 client.Groups.OnGroupLeft -= new GroupManager.GroupLeftCallback(Groups_OnGroupLeft);\r
167                 client.Groups.OnGroupDropped -= new GroupManager.GroupDroppedCallback(Groups_OnGroupDropped);\r
168                 client.Groups.OnGroupJoined -= new GroupManager.GroupJoinedCallback(Groups_OnGroupJoined);\r
169                 client.Avatars.OnAvatarNames -= new AvatarManager.AvatarNamesCallback(Avatars_OnAvatarNames);\r
170             }\r
171 \r
172             if (MonoRuntime)\r
173             {\r
174                 Environment.Exit(0);\r
175             }\r
176 \r
177             state.Dispose();\r
178         }\r
179 \r
180         void Avatars_OnAvatarNames(Dictionary<UUID, string> names)\r
181         {\r
182             lock (nameCache)\r
183             {\r
184                 foreach (KeyValuePair<UUID, string> av in names)\r
185                 {\r
186                     //if (OnAvatarName != null) try { OnAvatarName(av.Key, av.Value); }\r
187                     //    catch (Exception) { };\r
188 \r
189                     if (!nameCache.ContainsKey(av.Key))\r
190                     {\r
191                         nameCache.Add(av.Key, av.Value);\r
192                     }\r
193                 }\r
194             }\r
195         }\r
196 \r
197         public string getAvatarName(UUID key)\r
198         {\r
199             lock (nameCache)\r
200             {\r
201                 if (key == UUID.Zero)\r
202                 {\r
203                     return "(???) (???)";\r
204                 }\r
205                 if (nameCache.ContainsKey(key))\r
206                 {\r
207                     return nameCache[key];\r
208                 }\r
209                 else\r
210                 {\r
211                     client.Avatars.RequestAvatarName(key);\r
212                     return INCOMPLETE_NAME;\r
213                 }\r
214             }\r
215         }\r
216 \r
217         public void getAvatarNames(List<UUID> keys)\r
218         {\r
219             lock (nameCache)\r
220             {\r
221                 List<UUID> newNames = new List<UUID>();\r
222                 foreach (UUID key in keys)\r
223                 {\r
224                     if (!nameCache.ContainsKey(key))\r
225                     {\r
226                         newNames.Add(key);\r
227                     }\r
228                 }\r
229                 if (newNames.Count > 0)\r
230                 {\r
231                     client.Avatars.RequestAvatarNames(newNames);\r
232                 }\r
233             }\r
234         }\r
235 \r
236         public bool haveAvatarName(UUID key)\r
237         {\r
238             lock (nameCache)\r
239             {\r
240                 if (nameCache.ContainsKey(key))\r
241                     return true;\r
242                 else\r
243                     return false;\r
244             }\r
245         }\r
246 \r
247         void Groups_OnGroupJoined(UUID groupID, bool success)\r
248         {\r
249             client.Groups.RequestCurrentGroups();\r
250         }\r
251 \r
252         void Groups_OnGroupLeft(UUID groupID, bool success)\r
253         {\r
254             client.Groups.RequestCurrentGroups();\r
255         }\r
256 \r
257         void Groups_OnGroupDropped(UUID groupID)\r
258         {\r
259             client.Groups.RequestCurrentGroups();\r
260         }\r
261 \r
262         public void LogClientMessage(string fileName, string message)\r
263         {\r
264             lock (this)\r
265             {\r
266                 try\r
267                 {\r
268                     foreach (char lDisallowed in System.IO.Path.GetInvalidFileNameChars())\r
269                     {\r
270                         fileName = fileName.Replace(lDisallowed.ToString(), "_");\r
271                     }\r
272 \r
273                     StreamWriter logfile = File.AppendText(Path.Combine(ClientDir, fileName));\r
274                     logfile.WriteLine(DateTime.Now.ToString("yyyy-MM-dd [HH:mm:ss] ") + message);\r
275                     logfile.Close();\r
276                     logfile.Dispose();\r
277                 }\r
278                 catch (Exception) { }\r
279             }\r
280         }\r
281 \r
282         void Groups_OnCurrentGroups(Dictionary<UUID, Group> gr)\r
283         {\r
284             this.groups = gr;\r
285         }\r
286 \r
287         private void Application_ApplicationExit(object sender, EventArgs e)\r
288         {\r
289             config.SaveCurrentConfig();\r
290         }\r
291 \r
292         private void InitializeLoggingAndConfig()\r
293         {\r
294             // Are we running mono?\r
295             if (null == Type.GetType("Mono.Runtime"))\r
296             {\r
297                 monoRuntime = false;\r
298             }\r
299             else\r
300             {\r
301                 monoRuntime = true;\r
302             }\r
303 \r
304             try\r
305             {\r
306                 userDir = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.ApplicationData), Properties.Resources.ProgramName);\r
307                 if (!Directory.Exists(userDir))\r
308                 {\r
309                     Directory.CreateDirectory(userDir);\r
310                 }\r
311             }\r
312             catch (Exception)\r
313             {\r
314                 userDir = System.Environment.CurrentDirectory;\r
315             };\r
316 \r
317             animCacheDir = Path.Combine(userDir, @"anim_cache");\r
318             globalLogFile = Path.Combine(userDir, Properties.Resources.ProgramName + ".log");\r
319         }\r
320 \r
321         private void InitializeConfigLegacy()\r
322         {\r
323             config = new ConfigManager(this);\r
324             config.ApplyDefault();\r
325 \r
326             netcom.LoginOptions.FirstName = config.CurrentConfig.FirstName;\r
327             netcom.LoginOptions.LastName = config.CurrentConfig.LastName;\r
328             netcom.LoginOptions.Password = config.CurrentConfig.PasswordMD5;\r
329             netcom.LoginOptions.IsPasswordMD5 = true;\r
330         }\r
331 \r
332         public GridClient Client\r
333         {\r
334             get { return client; }\r
335         }\r
336 \r
337         public RadegastNetcom Netcom\r
338         {\r
339             get { return netcom; }\r
340         }\r
341 \r
342         public ImageCache ImageCache\r
343         {\r
344             get { return imageCache; }\r
345         }\r
346 \r
347         public StateManager State\r
348         {\r
349             get { return state; }\r
350         }\r
351 \r
352         public ConfigManager Config\r
353         {\r
354             get { return config; }\r
355         }\r
356 \r
357         public frmMain MainForm\r
358         {\r
359             get { return mainForm; }\r
360         }\r
361 \r
362         public TabsConsole TabConsole\r
363         {\r
364             get { return tabsConsole; }\r
365         }\r
366     }\r
367 }\r