From 5b6afeafbc249ba88dcc20d1fbc98ce12418b21b Mon Sep 17 00:00:00 2001 From: gareth Date: Tue, 8 May 2007 00:10:04 +0000 Subject: Brought in TestClient code for teh fork --- ExportBot/ClientManager.cs | 307 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 307 insertions(+) create mode 100644 ExportBot/ClientManager.cs (limited to 'ExportBot/ClientManager.cs') 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 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Xml; +using System.Threading; +using libsecondlife; +using libsecondlife.Packets; +using libsecondlife.AssetSystem; + +namespace libsecondlife.TestClient +{ + public class LoginDetails + { + public string FirstName; + public string LastName; + public string Password; + public string StartLocation; + public string MasterName; + public LLUUID MasterKey; + } + + public class StartPosition + { + public string sim; + public int x; + public int y; + public int z; + + public StartPosition() + { + this.sim = null; + this.x = 0; + this.y = 0; + this.z = 0; + } + } + + public class ClientManager + { + public Dictionary Clients = new Dictionary(); + public Dictionary> SimPrims = new Dictionary>(); + + public bool Running = true; + + string contactPerson = String.Empty; + private LLUUID resolvedMasterKey = LLUUID.Zero; + private ManualResetEvent keyResolution = new ManualResetEvent(false); + + /// + /// + /// + /// + public ClientManager(List accounts, string c) + { + this.contactPerson = c; + foreach (LoginDetails account in accounts) + Login(account); + } + + public ClientManager(List accounts, string c, string s) + { + this.contactPerson = c; + char sep = '/'; + string[] startbits = s.Split(sep); + + foreach (LoginDetails account in accounts) + { + account.StartLocation = NetworkManager.StartLocation(startbits[0], Int32.Parse(startbits[1]), + Int32.Parse(startbits[2]), Int32.Parse(startbits[3])); + Login(account); + } + } + /// + /// + /// + /// + /// + public TestClient Login(LoginDetails account) + { + // Check if this client is already logged in + foreach (TestClient c in Clients.Values) + { + if (c.Self.FirstName == account.FirstName && c.Self.LastName == account.LastName) + { + Logout(c); + break; + } + } + + TestClient client = new TestClient(this); + + // Optimize the throttle + client.Throttle.Wind = 0; + client.Throttle.Cloud = 0; + client.Throttle.Land = 1000000; + client.Throttle.Task = 1000000; + + client.SimPrims = SimPrims; + client.MasterName = account.MasterName; + client.MasterKey = account.MasterKey; + + if (!String.IsNullOrEmpty(account.StartLocation)) + { + if (!client.Network.Login(account.FirstName, account.LastName, account.Password, "TestClient", + account.StartLocation, contactPerson)) + { + Console.WriteLine("Failed to login " + account.FirstName + " " + account.LastName + ": " + + client.Network.LoginMessage); + } + } + else + { + if (!client.Network.Login(account.FirstName, account.LastName, account.Password, "TestClient", + contactPerson)) + { + Console.WriteLine("Failed to login " + account.FirstName + " " + account.LastName + ": " + + client.Network.LoginStatusMessage); + } + } + + if (client.Network.Connected) + { + if (account.MasterKey == LLUUID.Zero && !String.IsNullOrEmpty(account.MasterName)) + { + Console.WriteLine("Resolving {0}'s UUID", account.MasterName); + // Find master's key from name + DirectoryManager.DirPeopleReplyCallback callback = new DirectoryManager.DirPeopleReplyCallback(KeyResolvHandler); + client.Directory.OnDirPeopleReply += callback; + client.Directory.StartPeopleSearch(DirectoryManager.DirFindFlags.People, account.MasterName); + if (keyResolution.WaitOne(TimeSpan.FromMinutes(1), false)) + { + account.MasterKey = resolvedMasterKey; + Console.WriteLine("\"{0}\" resolved to {1}", account.MasterName, account.MasterKey); + } + else + { + Console.WriteLine("Unable to obtain UUID for \"{0}\". No master will be used. Try specifying a key with --masterkey.", account.MasterName); + } + client.Directory.OnDirPeopleReply -= callback; + keyResolution.Reset(); + } + + client.MasterKey = account.MasterKey; + + Clients[client.Network.AgentID] = client; + + Console.WriteLine("Logged in " + client.ToString()); + } + + return client; + } + + private void KeyResolvHandler(LLUUID queryid, List matches) + { + LLUUID master = matches[0].AgentID; + if (matches.Count > 1) + { + Console.WriteLine("Possible masters:"); + for (int i = 0; i < matches.Count; ++i) + { + Console.WriteLine("{0}: {1}", i, matches[i].FirstName + " " + matches[i].LastName); + } + Console.Write("Ambiguous master, choose one:"); + string read = Console.ReadLine(); + while (read != null) + { + int choice = 0; + if (int.TryParse(read, out choice)) + { + master = matches[choice].AgentID; + break; + } + else + { + Console.WriteLine("Responce misunderstood."); + Console.Write("Type the corresponding number:"); + } + read = Console.ReadLine(); + } + } + resolvedMasterKey = master; + keyResolution.Set(); + } + + /// + /// + /// + /// + /// + public TestClient Login(string[] args) + { + LoginDetails account = new LoginDetails(); + account.FirstName = args[0]; + account.LastName = args[1]; + account.Password = args[2]; + + if (args.Length == 4) + { + account.StartLocation = NetworkManager.StartLocation(args[3], 128, 128, 40); + } + + return Login(account); + } + + /// + /// + /// + public void Run() + { + Console.WriteLine("Type quit to exit. Type help for a command list."); + + while (Running) + { + PrintPrompt(); + string input = Console.ReadLine(); + DoCommandAll(input, null, null); + } + + foreach (SecondLife client in Clients.Values) + { + if (client.Network.Connected) + client.Network.Logout(); + } + } + + private void PrintPrompt() + { + int online = 0; + + foreach (SecondLife client in Clients.Values) + { + if (client.Network.Connected) online++; + } + + Console.Write(online + " avatars online> "); + } + + /// + /// + /// + /// + /// + /// + public void DoCommandAll(string cmd, LLUUID fromAgentID, LLUUID imSessionID) + { + string[] tokens = cmd.Trim().Split(new char[] { ' ', '\t' }); + string firstToken = tokens[0].ToLower(); + + if (tokens.Length == 0) + return; + + if (firstToken == "login") + { + // Special login case: Only call it once, and allow it with + // no logged in avatars + string[] args = new string[tokens.Length - 1]; + Array.Copy(tokens, 1, args, 0, args.Length); + Login(args); + } + else if (firstToken == "quit") + { + Quit(); + Console.WriteLine("All clients logged out and program finished running."); + } + else + { + // make a copy of the clients list so that it can be iterated without fear of being changed during iteration + Dictionary clientsCopy = new Dictionary(Clients); + + foreach (TestClient client in clientsCopy.Values) + client.DoCommand(cmd, fromAgentID, imSessionID); + } + } + + /// + /// + /// + /// + public void Logout(TestClient client) + { + Clients.Remove(client.Network.AgentID); + client.Network.Logout(); + } + + /// + /// + /// + public void LogoutAll() + { + // make a copy of the clients list so that it can be iterated without fear of being changed during iteration + Dictionary clientsCopy = new Dictionary(Clients); + + foreach (TestClient client in clientsCopy.Values) + Logout(client); + } + + /// + /// + /// + public void Quit() + { + LogoutAll(); + Running = false; + // TODO: It would be really nice if we could figure out a way to abort the ReadLine here in so that Run() will exit. + } + } +} -- cgit v1.1