aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/tools/mass test client/TestClient.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--tools/mass test client/TestClient.cs324
1 files changed, 324 insertions, 0 deletions
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 @@
1using System;
2using System.Collections.Generic;
3using System.Reflection;
4using System.Xml;
5using libsecondlife;
6using libsecondlife.Packets;
7using libsecondlife.AssetSystem;
8
9namespace libsecondlife.TestClient
10{
11 public class TestClient : SecondLife
12 {
13 public delegate void PrimCreatedCallback(Simulator simulator, Primitive prim);
14
15 public event PrimCreatedCallback OnPrimCreated;
16
17 public Dictionary<Simulator, Dictionary<uint, Primitive>> SimPrims;
18 public LLUUID GroupID = LLUUID.Zero;
19 public Dictionary<LLUUID, GroupMember> GroupMembers;
20 public Dictionary<uint, Avatar> AvatarList = new Dictionary<uint,Avatar>();
21 public Dictionary<LLUUID, AvatarAppearancePacket> Appearances = new Dictionary<LLUUID, AvatarAppearancePacket>();
22 public Dictionary<string, Command> Commands = new Dictionary<string,Command>();
23 public bool Running = true;
24 public string MasterName = String.Empty;
25 public LLUUID MasterKey = LLUUID.Zero;
26 public ClientManager ClientManager;
27 public int regionX;
28 public int regionY;
29
30 //internal libsecondlife.InventorySystem.InventoryFolder currentDirectory;
31
32 private System.Timers.Timer updateTimer;
33
34
35 /// <summary>
36 ///
37 /// </summary>
38 public TestClient(ClientManager manager)
39 {
40 ClientManager = manager;
41
42 updateTimer = new System.Timers.Timer(1000);
43 updateTimer.Elapsed += new System.Timers.ElapsedEventHandler(updateTimer_Elapsed);
44
45 RegisterAllCommands(Assembly.GetExecutingAssembly());
46
47 Settings.DEBUG = true;
48 Settings.STORE_LAND_PATCHES = true;
49 Settings.ALWAYS_REQUEST_OBJECTS = true;
50
51 Network.RegisterCallback(PacketType.AgentDataUpdate, new NetworkManager.PacketCallback(AgentDataUpdateHandler));
52
53 Objects.OnNewPrim += new ObjectManager.NewPrimCallback(Objects_OnNewPrim);
54 Objects.OnObjectUpdated += new ObjectManager.ObjectUpdatedCallback(Objects_OnObjectUpdated);
55 Objects.OnObjectKilled += new ObjectManager.KillObjectCallback(Objects_OnObjectKilled);
56 Objects.OnNewAvatar += new ObjectManager.NewAvatarCallback(Objects_OnNewAvatar);
57 Self.OnInstantMessage += new MainAvatar.InstantMessageCallback(Self_OnInstantMessage);
58 Groups.OnGroupMembers += new GroupManager.GroupMembersCallback(GroupMembersHandler);
59 this.OnLogMessage += new LogCallback(TestClient_OnLogMessage);
60
61 Network.RegisterCallback(PacketType.AvatarAppearance, new NetworkManager.PacketCallback(AvatarAppearanceHandler));
62
63 updateTimer.Start();
64 }
65
66 public void RegisterAllCommands(Assembly assembly)
67 {
68 foreach (Type t in assembly.GetTypes())
69 {
70 try
71 {
72 if (t.IsSubclassOf(typeof(Command)))
73 {
74 ConstructorInfo info = t.GetConstructor(new Type[] { typeof(TestClient) });
75 Command command = (Command)info.Invoke(new object[] { this });
76 RegisterCommand(command);
77 }
78 }
79 catch (Exception e)
80 {
81 Console.WriteLine(e.ToString());
82 }
83 }
84 }
85
86 public void RegisterCommand(Command command)
87 {
88 command.Client = this;
89 if (!Commands.ContainsKey(command.Name.ToLower()))
90 {
91 Commands.Add(command.Name.ToLower(), command);
92 }
93 }
94
95 //breaks up large responses to deal with the max IM size
96 private void SendResponseIM(SecondLife client, LLUUID fromAgentID, string data, LLUUID imSessionID)
97 {
98 for ( int i = 0 ; i < data.Length ; i += 1024 ) {
99 int y;
100 if ((i + 1023) > data.Length)
101 {
102 y = data.Length - i;
103 }
104 else
105 {
106 y = 1023;
107 }
108 string message = data.Substring(i, y);
109 client.Self.InstantMessage(fromAgentID, message, imSessionID);
110 }
111 }
112
113 public void DoCommand(string cmd, LLUUID fromAgentID, LLUUID imSessionID)
114 {
115 string[] tokens = Parsing.ParseArguments(cmd);
116
117 if (tokens.Length == 0)
118 return;
119
120 string firstToken = tokens[0].ToLower();
121
122 // "all balance" will send the balance command to all currently logged in bots
123 if (firstToken == "all" && tokens.Length > 1)
124 {
125 cmd = String.Empty;
126
127 // Reserialize all of the arguments except for "all"
128 for (int i = 1; i < tokens.Length; i++)
129 {
130 cmd += tokens[i] + " ";
131 }
132
133 ClientManager.DoCommandAll(cmd, fromAgentID, imSessionID);
134
135 return;
136 }
137
138 if (Commands.ContainsKey(firstToken))
139 {
140 string[] args = new string[tokens.Length - 1];
141 Array.Copy(tokens, 1, args, 0, args.Length);
142 string response = Commands[firstToken].Execute(args, fromAgentID);
143
144 if (response.Length > 0)
145 {
146 Console.WriteLine(response);
147
148 if (fromAgentID != null && Network.Connected)
149 {
150 // IMs don't like \r\n line endings, clean them up first
151 response = response.Replace("\r", "");
152 SendResponseIM(this, fromAgentID, response, imSessionID);
153 }
154 }
155 }
156 }
157
158 private void updateTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
159 {
160 foreach (Command c in Commands.Values)
161 if (c.Active)
162 c.Think();
163 }
164
165 private void AgentDataUpdateHandler(Packet packet, Simulator sim)
166 {
167 AgentDataUpdatePacket p = (AgentDataUpdatePacket)packet;
168 if (p.AgentData.AgentID == sim.Client.Network.AgentID)
169 {
170 Console.WriteLine("Got the group ID for " + sim.Client.ToString() + ", requesting group members...");
171 GroupID = p.AgentData.ActiveGroupID;
172
173 sim.Client.Groups.BeginGetGroupMembers(GroupID);
174 }
175 }
176
177 private void TestClient_OnLogMessage(string message, Helpers.LogLevel level)
178 {
179 Console.WriteLine("<" + this.ToString() + "> " + level.ToString() + ": " + message);
180 }
181
182 private void GroupMembersHandler(Dictionary<LLUUID, GroupMember> members)
183 {
184 Console.WriteLine("Got " + members.Count + " group members.");
185 GroupMembers = members;
186 }
187
188 private void Objects_OnObjectKilled(Simulator simulator, uint objectID)
189 {
190 lock (SimPrims)
191 {
192 if (SimPrims.ContainsKey(simulator) && SimPrims[simulator].ContainsKey(objectID))
193 SimPrims[simulator].Remove(objectID);
194 }
195
196 lock (AvatarList)
197 {
198 if (AvatarList.ContainsKey(objectID))
199 AvatarList.Remove(objectID);
200 }
201 }
202
203 private void Objects_OnObjectUpdated(Simulator simulator, ObjectUpdate update, ulong regionHandle, ushort timeDilation)
204 {
205 regionX = (int)(regionHandle >> 32);
206 regionY = (int)(regionHandle & 0xFFFFFFFF);
207
208 if (update.Avatar)
209 {
210 lock (AvatarList)
211 {
212 // TODO: We really need a solid avatar and object tracker in Utilities to use here
213 if (AvatarList.ContainsKey(update.LocalID))
214 {
215 AvatarList[update.LocalID].CollisionPlane = update.CollisionPlane;
216 AvatarList[update.LocalID].Position = update.Position;
217 AvatarList[update.LocalID].Velocity = update.Velocity;
218 AvatarList[update.LocalID].Acceleration = update.Acceleration;
219 AvatarList[update.LocalID].Rotation = update.Rotation;
220 AvatarList[update.LocalID].AngularVelocity = update.AngularVelocity;
221 AvatarList[update.LocalID].Textures = update.Textures;
222 }
223 }
224 }
225 else
226 {
227 lock (SimPrims)
228 {
229 if (SimPrims.ContainsKey(simulator) && SimPrims[simulator].ContainsKey(update.LocalID))
230 {
231 SimPrims[simulator][update.LocalID].Position = update.Position;
232 SimPrims[simulator][update.LocalID].Velocity = update.Velocity;
233 SimPrims[simulator][update.LocalID].Acceleration = update.Acceleration;
234 SimPrims[simulator][update.LocalID].Rotation = update.Rotation;
235 SimPrims[simulator][update.LocalID].AngularVelocity = update.AngularVelocity;
236 SimPrims[simulator][update.LocalID].Textures = update.Textures;
237 }
238 }
239 }
240 }
241
242 private void Objects_OnNewPrim(Simulator simulator, Primitive prim, ulong regionHandle, ushort timeDilation)
243 {
244 lock (SimPrims)
245 {
246 if (!SimPrims.ContainsKey(simulator))
247 {
248 SimPrims[simulator] = new Dictionary<uint, Primitive>(10000);
249 }
250
251 SimPrims[simulator][prim.LocalID] = prim;
252 }
253
254 if ((prim.Flags & LLObject.ObjectFlags.CreateSelected) != 0 && OnPrimCreated != null)
255 {
256 OnPrimCreated(simulator, prim);
257 }
258 }
259
260 private void Objects_OnNewAvatar(Simulator simulator, Avatar avatar, ulong regionHandle, ushort timeDilation)
261 {
262 lock (AvatarList)
263 {
264 AvatarList[avatar.LocalID] = avatar;
265 }
266 }
267
268 private void AvatarAppearanceHandler(Packet packet, Simulator simulator)
269 {
270 AvatarAppearancePacket appearance = (AvatarAppearancePacket)packet;
271
272 lock (Appearances) Appearances[appearance.Sender.ID] = appearance;
273 }
274
275 private void Self_OnInstantMessage(LLUUID fromAgentID, string fromAgentName, LLUUID toAgentID,
276 uint parentEstateID, LLUUID regionID, LLVector3 position, MainAvatar.InstantMessageDialog dialog,
277 bool groupIM, LLUUID imSessionID, DateTime timestamp, string message,
278 MainAvatar.InstantMessageOnline offline, byte[] binaryBucket)
279 {
280 if (MasterKey != LLUUID.Zero)
281 {
282 if (fromAgentID != MasterKey)
283 {
284 // Received an IM from someone that is not the bot's master, ignore
285 Console.WriteLine("<IM>" + fromAgentName + " (not master): " + message + "@" + regionID.ToString() + ":" + position.ToString() );
286 return;
287 }
288 }
289 else
290 {
291 if (GroupMembers != null && !GroupMembers.ContainsKey(fromAgentID))
292 {
293 // Received an IM from someone outside the bot's group, ignore
294 Console.WriteLine("<IM>" + fromAgentName + " (not in group): " + message + "@" + regionID.ToString() + ":" + position.ToString());
295 return;
296 }
297 }
298
299 Console.WriteLine("<IM>" + fromAgentName + ": " + message);
300
301 if (dialog == MainAvatar.InstantMessageDialog.RequestTeleport)
302 {
303 Console.WriteLine("Accepting teleport lure.");
304 Self.TeleportLureRespond(fromAgentID, true);
305 }
306 else
307 {
308 if (dialog == MainAvatar.InstantMessageDialog.InventoryOffered)
309 {
310 Console.WriteLine("Accepting inventory offer.");
311
312 Self.InstantMessage(Self.FirstName + " " + Self.LastName, fromAgentID, String.Empty,
313 imSessionID, MainAvatar.InstantMessageDialog.InventoryAccepted,
314 MainAvatar.InstantMessageOnline.Offline, Self.Position, LLUUID.Zero,
315 Self.InventoryRootFolderUUID.GetBytes());
316 }
317 else
318 {
319 DoCommand(message, fromAgentID, imSessionID);
320 }
321 }
322 }
323 }
324}