aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/ExportBot/ClientManager.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--ExportBot/ClientManager.cs307
1 files changed, 307 insertions, 0 deletions
diff --git a/ExportBot/ClientManager.cs b/ExportBot/ClientManager.cs
new file mode 100644
index 0000000..0e43142
--- /dev/null
+++ b/ExportBot/ClientManager.cs
@@ -0,0 +1,307 @@
1using System;
2using System.Collections.Generic;
3using System.Reflection;
4using System.Xml;
5using System.Threading;
6using libsecondlife;
7using libsecondlife.Packets;
8using libsecondlife.AssetSystem;
9
10namespace libsecondlife.TestClient
11{
12 public class LoginDetails
13 {
14 public string FirstName;
15 public string LastName;
16 public string Password;
17 public string StartLocation;
18 public string MasterName;
19 public LLUUID MasterKey;
20 }
21
22 public class StartPosition
23 {
24 public string sim;
25 public int x;
26 public int y;
27 public int z;
28
29 public StartPosition()
30 {
31 this.sim = null;
32 this.x = 0;
33 this.y = 0;
34 this.z = 0;
35 }
36 }
37
38 public class ClientManager
39 {
40 public Dictionary<LLUUID, SecondLife> Clients = new Dictionary<LLUUID, SecondLife>();
41 public Dictionary<Simulator, Dictionary<uint, Primitive>> SimPrims = new Dictionary<Simulator, Dictionary<uint, Primitive>>();
42
43 public bool Running = true;
44
45 string contactPerson = String.Empty;
46 private LLUUID resolvedMasterKey = LLUUID.Zero;
47 private ManualResetEvent keyResolution = new ManualResetEvent(false);
48
49 /// <summary>
50 ///
51 /// </summary>
52 /// <param name="accounts"></param>
53 public ClientManager(List<LoginDetails> accounts, string c)
54 {
55 this.contactPerson = c;
56 foreach (LoginDetails account in accounts)
57 Login(account);
58 }
59
60 public ClientManager(List<LoginDetails> accounts, string c, string s)
61 {
62 this.contactPerson = c;
63 char sep = '/';
64 string[] startbits = s.Split(sep);
65
66 foreach (LoginDetails account in accounts)
67 {
68 account.StartLocation = NetworkManager.StartLocation(startbits[0], Int32.Parse(startbits[1]),
69 Int32.Parse(startbits[2]), Int32.Parse(startbits[3]));
70 Login(account);
71 }
72 }
73 /// <summary>
74 ///
75 /// </summary>
76 /// <param name="account"></param>
77 /// <returns></returns>
78 public TestClient Login(LoginDetails account)
79 {
80 // Check if this client is already logged in
81 foreach (TestClient c in Clients.Values)
82 {
83 if (c.Self.FirstName == account.FirstName && c.Self.LastName == account.LastName)
84 {
85 Logout(c);
86 break;
87 }
88 }
89
90 TestClient client = new TestClient(this);
91
92 // Optimize the throttle
93 client.Throttle.Wind = 0;
94 client.Throttle.Cloud = 0;
95 client.Throttle.Land = 1000000;
96 client.Throttle.Task = 1000000;
97
98 client.SimPrims = SimPrims;
99 client.MasterName = account.MasterName;
100 client.MasterKey = account.MasterKey;
101
102 if (!String.IsNullOrEmpty(account.StartLocation))
103 {
104 if (!client.Network.Login(account.FirstName, account.LastName, account.Password, "TestClient",
105 account.StartLocation, contactPerson))
106 {
107 Console.WriteLine("Failed to login " + account.FirstName + " " + account.LastName + ": " +
108 client.Network.LoginMessage);
109 }
110 }
111 else
112 {
113 if (!client.Network.Login(account.FirstName, account.LastName, account.Password, "TestClient",
114 contactPerson))
115 {
116 Console.WriteLine("Failed to login " + account.FirstName + " " + account.LastName + ": " +
117 client.Network.LoginStatusMessage);
118 }
119 }
120
121 if (client.Network.Connected)
122 {
123 if (account.MasterKey == LLUUID.Zero && !String.IsNullOrEmpty(account.MasterName))
124 {
125 Console.WriteLine("Resolving {0}'s UUID", account.MasterName);
126 // Find master's key from name
127 DirectoryManager.DirPeopleReplyCallback callback = new DirectoryManager.DirPeopleReplyCallback(KeyResolvHandler);
128 client.Directory.OnDirPeopleReply += callback;
129 client.Directory.StartPeopleSearch(DirectoryManager.DirFindFlags.People, account.MasterName);
130 if (keyResolution.WaitOne(TimeSpan.FromMinutes(1), false))
131 {
132 account.MasterKey = resolvedMasterKey;
133 Console.WriteLine("\"{0}\" resolved to {1}", account.MasterName, account.MasterKey);
134 }
135 else
136 {
137 Console.WriteLine("Unable to obtain UUID for \"{0}\". No master will be used. Try specifying a key with --masterkey.", account.MasterName);
138 }
139 client.Directory.OnDirPeopleReply -= callback;
140 keyResolution.Reset();
141 }
142
143 client.MasterKey = account.MasterKey;
144
145 Clients[client.Network.AgentID] = client;
146
147 Console.WriteLine("Logged in " + client.ToString());
148 }
149
150 return client;
151 }
152
153 private void KeyResolvHandler(LLUUID queryid, List<DirectoryManager.AgentSearchData> matches)
154 {
155 LLUUID master = matches[0].AgentID;
156 if (matches.Count > 1)
157 {
158 Console.WriteLine("Possible masters:");
159 for (int i = 0; i < matches.Count; ++i)
160 {
161 Console.WriteLine("{0}: {1}", i, matches[i].FirstName + " " + matches[i].LastName);
162 }
163 Console.Write("Ambiguous master, choose one:");
164 string read = Console.ReadLine();
165 while (read != null)
166 {
167 int choice = 0;
168 if (int.TryParse(read, out choice))
169 {
170 master = matches[choice].AgentID;
171 break;
172 }
173 else
174 {
175 Console.WriteLine("Responce misunderstood.");
176 Console.Write("Type the corresponding number:");
177 }
178 read = Console.ReadLine();
179 }
180 }
181 resolvedMasterKey = master;
182 keyResolution.Set();
183 }
184
185 /// <summary>
186 ///
187 /// </summary>
188 /// <param name="args"></param>
189 /// <returns></returns>
190 public TestClient Login(string[] args)
191 {
192 LoginDetails account = new LoginDetails();
193 account.FirstName = args[0];
194 account.LastName = args[1];
195 account.Password = args[2];
196
197 if (args.Length == 4)
198 {
199 account.StartLocation = NetworkManager.StartLocation(args[3], 128, 128, 40);
200 }
201
202 return Login(account);
203 }
204
205 /// <summary>
206 ///
207 /// </summary>
208 public void Run()
209 {
210 Console.WriteLine("Type quit to exit. Type help for a command list.");
211
212 while (Running)
213 {
214 PrintPrompt();
215 string input = Console.ReadLine();
216 DoCommandAll(input, null, null);
217 }
218
219 foreach (SecondLife client in Clients.Values)
220 {
221 if (client.Network.Connected)
222 client.Network.Logout();
223 }
224 }
225
226 private void PrintPrompt()
227 {
228 int online = 0;
229
230 foreach (SecondLife client in Clients.Values)
231 {
232 if (client.Network.Connected) online++;
233 }
234
235 Console.Write(online + " avatars online> ");
236 }
237
238 /// <summary>
239 ///
240 /// </summary>
241 /// <param name="cmd"></param>
242 /// <param name="fromAgentID"></param>
243 /// <param name="imSessionID"></param>
244 public void DoCommandAll(string cmd, LLUUID fromAgentID, LLUUID imSessionID)
245 {
246 string[] tokens = cmd.Trim().Split(new char[] { ' ', '\t' });
247 string firstToken = tokens[0].ToLower();
248
249 if (tokens.Length == 0)
250 return;
251
252 if (firstToken == "login")
253 {
254 // Special login case: Only call it once, and allow it with
255 // no logged in avatars
256 string[] args = new string[tokens.Length - 1];
257 Array.Copy(tokens, 1, args, 0, args.Length);
258 Login(args);
259 }
260 else if (firstToken == "quit")
261 {
262 Quit();
263 Console.WriteLine("All clients logged out and program finished running.");
264 }
265 else
266 {
267 // make a copy of the clients list so that it can be iterated without fear of being changed during iteration
268 Dictionary<LLUUID, SecondLife> clientsCopy = new Dictionary<LLUUID, SecondLife>(Clients);
269
270 foreach (TestClient client in clientsCopy.Values)
271 client.DoCommand(cmd, fromAgentID, imSessionID);
272 }
273 }
274
275 /// <summary>
276 ///
277 /// </summary>
278 /// <param name="client"></param>
279 public void Logout(TestClient client)
280 {
281 Clients.Remove(client.Network.AgentID);
282 client.Network.Logout();
283 }
284
285 /// <summary>
286 ///
287 /// </summary>
288 public void LogoutAll()
289 {
290 // make a copy of the clients list so that it can be iterated without fear of being changed during iteration
291 Dictionary<LLUUID, SecondLife> clientsCopy = new Dictionary<LLUUID, SecondLife>(Clients);
292
293 foreach (TestClient client in clientsCopy.Values)
294 Logout(client);
295 }
296
297 /// <summary>
298 ///
299 /// </summary>
300 public void Quit()
301 {
302 LogoutAll();
303 Running = false;
304 // TODO: It would be really nice if we could figure out a way to abort the ReadLine here in so that Run() will exit.
305 }
306 }
307}