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