From e93869c7a785a4f375685ffa33c913033ed1c85a Mon Sep 17 00:00:00 2001 From: Adam Frisby Date: Thu, 21 Jun 2007 17:08:21 +0000 Subject: * Importing Ming's mass test client --- tools/mass test client/TestClient.cs | 324 +++++++++++++++++++++++++++++++++++ 1 file changed, 324 insertions(+) create mode 100644 tools/mass test client/TestClient.cs (limited to 'tools/mass test client/TestClient.cs') diff --git a/tools/mass test client/TestClient.cs b/tools/mass test client/TestClient.cs new file mode 100644 index 0000000..cee218c --- /dev/null +++ b/tools/mass test client/TestClient.cs @@ -0,0 +1,324 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Xml; +using libsecondlife; +using libsecondlife.Packets; +using libsecondlife.AssetSystem; + +namespace libsecondlife.TestClient +{ + public class TestClient : SecondLife + { + public delegate void PrimCreatedCallback(Simulator simulator, Primitive prim); + + public event PrimCreatedCallback OnPrimCreated; + + public Dictionary> SimPrims; + public LLUUID GroupID = LLUUID.Zero; + public Dictionary GroupMembers; + public Dictionary AvatarList = new Dictionary(); + public Dictionary Appearances = new Dictionary(); + public Dictionary Commands = new Dictionary(); + public bool Running = true; + public string MasterName = String.Empty; + public LLUUID MasterKey = LLUUID.Zero; + public ClientManager ClientManager; + public int regionX; + public int regionY; + + //internal libsecondlife.InventorySystem.InventoryFolder currentDirectory; + + private System.Timers.Timer updateTimer; + + + /// + /// + /// + public TestClient(ClientManager manager) + { + ClientManager = manager; + + updateTimer = new System.Timers.Timer(1000); + updateTimer.Elapsed += new System.Timers.ElapsedEventHandler(updateTimer_Elapsed); + + RegisterAllCommands(Assembly.GetExecutingAssembly()); + + Settings.DEBUG = true; + Settings.STORE_LAND_PATCHES = true; + Settings.ALWAYS_REQUEST_OBJECTS = true; + + Network.RegisterCallback(PacketType.AgentDataUpdate, new NetworkManager.PacketCallback(AgentDataUpdateHandler)); + + Objects.OnNewPrim += new ObjectManager.NewPrimCallback(Objects_OnNewPrim); + Objects.OnObjectUpdated += new ObjectManager.ObjectUpdatedCallback(Objects_OnObjectUpdated); + Objects.OnObjectKilled += new ObjectManager.KillObjectCallback(Objects_OnObjectKilled); + Objects.OnNewAvatar += new ObjectManager.NewAvatarCallback(Objects_OnNewAvatar); + Self.OnInstantMessage += new MainAvatar.InstantMessageCallback(Self_OnInstantMessage); + Groups.OnGroupMembers += new GroupManager.GroupMembersCallback(GroupMembersHandler); + this.OnLogMessage += new LogCallback(TestClient_OnLogMessage); + + Network.RegisterCallback(PacketType.AvatarAppearance, new NetworkManager.PacketCallback(AvatarAppearanceHandler)); + + updateTimer.Start(); + } + + public void RegisterAllCommands(Assembly assembly) + { + foreach (Type t in assembly.GetTypes()) + { + try + { + if (t.IsSubclassOf(typeof(Command))) + { + ConstructorInfo info = t.GetConstructor(new Type[] { typeof(TestClient) }); + Command command = (Command)info.Invoke(new object[] { this }); + RegisterCommand(command); + } + } + catch (Exception e) + { + Console.WriteLine(e.ToString()); + } + } + } + + public void RegisterCommand(Command command) + { + command.Client = this; + if (!Commands.ContainsKey(command.Name.ToLower())) + { + Commands.Add(command.Name.ToLower(), command); + } + } + + //breaks up large responses to deal with the max IM size + private void SendResponseIM(SecondLife client, LLUUID fromAgentID, string data, LLUUID imSessionID) + { + for ( int i = 0 ; i < data.Length ; i += 1024 ) { + int y; + if ((i + 1023) > data.Length) + { + y = data.Length - i; + } + else + { + y = 1023; + } + string message = data.Substring(i, y); + client.Self.InstantMessage(fromAgentID, message, imSessionID); + } + } + + public void DoCommand(string cmd, LLUUID fromAgentID, LLUUID imSessionID) + { + string[] tokens = Parsing.ParseArguments(cmd); + + if (tokens.Length == 0) + return; + + string firstToken = tokens[0].ToLower(); + + // "all balance" will send the balance command to all currently logged in bots + if (firstToken == "all" && tokens.Length > 1) + { + cmd = String.Empty; + + // Reserialize all of the arguments except for "all" + for (int i = 1; i < tokens.Length; i++) + { + cmd += tokens[i] + " "; + } + + ClientManager.DoCommandAll(cmd, fromAgentID, imSessionID); + + return; + } + + if (Commands.ContainsKey(firstToken)) + { + string[] args = new string[tokens.Length - 1]; + Array.Copy(tokens, 1, args, 0, args.Length); + string response = Commands[firstToken].Execute(args, fromAgentID); + + if (response.Length > 0) + { + Console.WriteLine(response); + + if (fromAgentID != null && Network.Connected) + { + // IMs don't like \r\n line endings, clean them up first + response = response.Replace("\r", ""); + SendResponseIM(this, fromAgentID, response, imSessionID); + } + } + } + } + + private void updateTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) + { + foreach (Command c in Commands.Values) + if (c.Active) + c.Think(); + } + + private void AgentDataUpdateHandler(Packet packet, Simulator sim) + { + AgentDataUpdatePacket p = (AgentDataUpdatePacket)packet; + if (p.AgentData.AgentID == sim.Client.Network.AgentID) + { + Console.WriteLine("Got the group ID for " + sim.Client.ToString() + ", requesting group members..."); + GroupID = p.AgentData.ActiveGroupID; + + sim.Client.Groups.BeginGetGroupMembers(GroupID); + } + } + + private void TestClient_OnLogMessage(string message, Helpers.LogLevel level) + { + Console.WriteLine("<" + this.ToString() + "> " + level.ToString() + ": " + message); + } + + private void GroupMembersHandler(Dictionary members) + { + Console.WriteLine("Got " + members.Count + " group members."); + GroupMembers = members; + } + + private void Objects_OnObjectKilled(Simulator simulator, uint objectID) + { + lock (SimPrims) + { + if (SimPrims.ContainsKey(simulator) && SimPrims[simulator].ContainsKey(objectID)) + SimPrims[simulator].Remove(objectID); + } + + lock (AvatarList) + { + if (AvatarList.ContainsKey(objectID)) + AvatarList.Remove(objectID); + } + } + + private void Objects_OnObjectUpdated(Simulator simulator, ObjectUpdate update, ulong regionHandle, ushort timeDilation) + { + regionX = (int)(regionHandle >> 32); + regionY = (int)(regionHandle & 0xFFFFFFFF); + + if (update.Avatar) + { + lock (AvatarList) + { + // TODO: We really need a solid avatar and object tracker in Utilities to use here + if (AvatarList.ContainsKey(update.LocalID)) + { + AvatarList[update.LocalID].CollisionPlane = update.CollisionPlane; + AvatarList[update.LocalID].Position = update.Position; + AvatarList[update.LocalID].Velocity = update.Velocity; + AvatarList[update.LocalID].Acceleration = update.Acceleration; + AvatarList[update.LocalID].Rotation = update.Rotation; + AvatarList[update.LocalID].AngularVelocity = update.AngularVelocity; + AvatarList[update.LocalID].Textures = update.Textures; + } + } + } + else + { + lock (SimPrims) + { + if (SimPrims.ContainsKey(simulator) && SimPrims[simulator].ContainsKey(update.LocalID)) + { + SimPrims[simulator][update.LocalID].Position = update.Position; + SimPrims[simulator][update.LocalID].Velocity = update.Velocity; + SimPrims[simulator][update.LocalID].Acceleration = update.Acceleration; + SimPrims[simulator][update.LocalID].Rotation = update.Rotation; + SimPrims[simulator][update.LocalID].AngularVelocity = update.AngularVelocity; + SimPrims[simulator][update.LocalID].Textures = update.Textures; + } + } + } + } + + private void Objects_OnNewPrim(Simulator simulator, Primitive prim, ulong regionHandle, ushort timeDilation) + { + lock (SimPrims) + { + if (!SimPrims.ContainsKey(simulator)) + { + SimPrims[simulator] = new Dictionary(10000); + } + + SimPrims[simulator][prim.LocalID] = prim; + } + + if ((prim.Flags & LLObject.ObjectFlags.CreateSelected) != 0 && OnPrimCreated != null) + { + OnPrimCreated(simulator, prim); + } + } + + private void Objects_OnNewAvatar(Simulator simulator, Avatar avatar, ulong regionHandle, ushort timeDilation) + { + lock (AvatarList) + { + AvatarList[avatar.LocalID] = avatar; + } + } + + private void AvatarAppearanceHandler(Packet packet, Simulator simulator) + { + AvatarAppearancePacket appearance = (AvatarAppearancePacket)packet; + + lock (Appearances) Appearances[appearance.Sender.ID] = appearance; + } + + private void Self_OnInstantMessage(LLUUID fromAgentID, string fromAgentName, LLUUID toAgentID, + uint parentEstateID, LLUUID regionID, LLVector3 position, MainAvatar.InstantMessageDialog dialog, + bool groupIM, LLUUID imSessionID, DateTime timestamp, string message, + MainAvatar.InstantMessageOnline offline, byte[] binaryBucket) + { + if (MasterKey != LLUUID.Zero) + { + if (fromAgentID != MasterKey) + { + // Received an IM from someone that is not the bot's master, ignore + Console.WriteLine("" + fromAgentName + " (not master): " + message + "@" + regionID.ToString() + ":" + position.ToString() ); + return; + } + } + else + { + if (GroupMembers != null && !GroupMembers.ContainsKey(fromAgentID)) + { + // Received an IM from someone outside the bot's group, ignore + Console.WriteLine("" + fromAgentName + " (not in group): " + message + "@" + regionID.ToString() + ":" + position.ToString()); + return; + } + } + + Console.WriteLine("" + fromAgentName + ": " + message); + + if (dialog == MainAvatar.InstantMessageDialog.RequestTeleport) + { + Console.WriteLine("Accepting teleport lure."); + Self.TeleportLureRespond(fromAgentID, true); + } + else + { + if (dialog == MainAvatar.InstantMessageDialog.InventoryOffered) + { + Console.WriteLine("Accepting inventory offer."); + + Self.InstantMessage(Self.FirstName + " " + Self.LastName, fromAgentID, String.Empty, + imSessionID, MainAvatar.InstantMessageDialog.InventoryAccepted, + MainAvatar.InstantMessageOnline.Offline, Self.Position, LLUUID.Zero, + Self.InventoryRootFolderUUID.GetBytes()); + } + else + { + DoCommand(message, fromAgentID, imSessionID); + } + } + } + } +} -- cgit v1.1