aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/tools/mass test client/ClientManager.cs
diff options
context:
space:
mode:
Diffstat (limited to 'tools/mass test client/ClientManager.cs')
-rw-r--r--tools/mass test client/ClientManager.cs323
1 files changed, 323 insertions, 0 deletions
diff --git a/tools/mass test client/ClientManager.cs b/tools/mass test client/ClientManager.cs
new file mode 100644
index 0000000..a6e784c
--- /dev/null
+++ b/tools/mass test client/ClientManager.cs
@@ -0,0 +1,323 @@
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 public string LoginURI;
21 }
22
23 public class StartPosition
24 {
25 public string sim;
26 public int x;
27 public int y;
28 public int z;
29
30 public StartPosition()
31 {
32 this.sim = null;
33 this.x = 0;
34 this.y = 0;
35 this.z = 0;
36 }
37 }
38
39 public class ClientManager
40 {
41 public Dictionary<LLUUID, SecondLife> Clients = new Dictionary<LLUUID, SecondLife>();
42 public Dictionary<Simulator, Dictionary<uint, Primitive>> SimPrims = new Dictionary<Simulator, Dictionary<uint, Primitive>>();
43
44 public bool Running = true;
45
46 string contactPerson = String.Empty;
47 private LLUUID resolvedMasterKey = LLUUID.Zero;
48 private ManualResetEvent keyResolution = new ManualResetEvent(false);
49
50 /// <summary>
51 ///
52 /// </summary>
53 /// <param name="accounts"></param>
54 public ClientManager(List<LoginDetails> accounts, string c)
55 {
56 this.contactPerson = c;
57 foreach (LoginDetails account in accounts)
58 Login(account);
59 }
60
61 public ClientManager(List<LoginDetails> accounts, string c, string s)
62 {
63 this.contactPerson = c;
64 char sep = '/';
65 string[] startbits = s.Split(sep);
66
67 foreach (LoginDetails account in accounts)
68 {
69 account.StartLocation = NetworkManager.StartLocation(startbits[0], Int32.Parse(startbits[1]),
70 Int32.Parse(startbits[2]), Int32.Parse(startbits[3]));
71 Login(account);
72 }
73 }
74 /// <summary>
75 ///
76 /// </summary>
77 /// <param name="account"></param>
78 /// <returns></returns>
79 public TestClient Login(LoginDetails account)
80 {
81
82 // Check if this client is already logged in
83 foreach (TestClient c in Clients.Values)
84 {
85 if (c.Self.FirstName == account.FirstName && c.Self.LastName == account.LastName)
86 {
87 Logout(c);
88 break;
89 }
90 }
91
92 TestClient client = new TestClient(this);
93
94 // Optimize the throttle
95 client.Throttle.Wind = 0;
96 client.Throttle.Cloud = 0;
97 client.Throttle.Land = 1000000;
98 client.Throttle.Task = 1000000;
99
100 client.SimPrims = SimPrims;
101 client.MasterName = account.MasterName;
102 client.MasterKey = account.MasterKey;
103
104 libsecondlife.NetworkManager.LoginParams loginParams = new NetworkManager.LoginParams();
105 loginParams.FirstName = account.FirstName;
106 loginParams.LastName = account.LastName;
107 loginParams.Password = account.Password;
108 loginParams.UserAgent = "MassTestClient";
109 loginParams.Start = account.StartLocation;
110 loginParams.Author = contactPerson;
111 loginParams.URI = account.LoginURI;
112
113
114 if (!client.Network.Login(loginParams))
115 {
116 Console.WriteLine("Failed to login " + account.FirstName + " " + account.LastName + ": " +
117 client.Network.LoginMessage);
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, 0);
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(List<string> massTestCommands)
209 {
210 Console.WriteLine("Type quit to exit. Type help for a command list.");
211
212 if (massTestCommands.Count == 0)
213 {
214 while (Running)
215 {
216 PrintPrompt();
217 string input = Console.ReadLine();
218 DoCommandAll(input, null, null);
219 }
220 }
221 else
222 {
223 int currentCommand = 0;
224 while (Running)
225 {
226 DoCommandAll(massTestCommands[currentCommand], null, null);
227 currentCommand++;
228 if (massTestCommands.Count >= currentCommand)
229 {
230 currentCommand = 0;
231 }
232 }
233 }
234
235 foreach (SecondLife client in Clients.Values)
236 {
237 if (client.Network.Connected)
238 client.Network.Logout();
239 }
240 }
241
242 private void PrintPrompt()
243 {
244 int online = 0;
245
246 foreach (SecondLife client in Clients.Values)
247 {
248 if (client.Network.Connected) online++;
249 }
250
251 Console.Write(online + " avatars online> ");
252 }
253
254 /// <summary>
255 ///
256 /// </summary>
257 /// <param name="cmd"></param>
258 /// <param name="fromAgentID"></param>
259 /// <param name="imSessionID"></param>
260 public void DoCommandAll(string cmd, LLUUID fromAgentID, LLUUID imSessionID)
261 {
262 string[] tokens = cmd.Trim().Split(new char[] { ' ', '\t' });
263 string firstToken = tokens[0].ToLower();
264
265 if (tokens.Length == 0)
266 return;
267
268 if (firstToken == "login")
269 {
270 // Special login case: Only call it once, and allow it with
271 // no logged in avatars
272 string[] args = new string[tokens.Length - 1];
273 Array.Copy(tokens, 1, args, 0, args.Length);
274 Login(args);
275 }
276 else if (firstToken == "quit")
277 {
278 Quit();
279 Console.WriteLine("All clients logged out and program finished running.");
280 }
281 else
282 {
283 // make a copy of the clients list so that it can be iterated without fear of being changed during iteration
284 Dictionary<LLUUID, SecondLife> clientsCopy = new Dictionary<LLUUID, SecondLife>(Clients);
285
286 foreach (TestClient client in clientsCopy.Values)
287 client.DoCommand(cmd, fromAgentID, imSessionID);
288 }
289 }
290
291 /// <summary>
292 ///
293 /// </summary>
294 /// <param name="client"></param>
295 public void Logout(TestClient client)
296 {
297 Clients.Remove(client.Network.AgentID);
298 client.Network.Logout();
299 }
300
301 /// <summary>
302 ///
303 /// </summary>
304 public void LogoutAll()
305 {
306 // make a copy of the clients list so that it can be iterated without fear of being changed during iteration
307 Dictionary<LLUUID, SecondLife> clientsCopy = new Dictionary<LLUUID, SecondLife>(Clients);
308
309 foreach (TestClient client in clientsCopy.Values)
310 Logout(client);
311 }
312
313 /// <summary>
314 ///
315 /// </summary>
316 public void Quit()
317 {
318 LogoutAll();
319 Running = false;
320 // TODO: It would be really nice if we could figure out a way to abort the ReadLine here in so that Run() will exit.
321 }
322 }
323}