OSDN Git Service

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