aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/ExportBot/Commands
diff options
context:
space:
mode:
authorgareth2007-05-08 00:10:04 +0000
committergareth2007-05-08 00:10:04 +0000
commit5b6afeafbc249ba88dcc20d1fbc98ce12418b21b (patch)
tree78861e5f6ae871d63c83b4ab1cc4c55ea184ed6d /ExportBot/Commands
parentZOMG! (diff)
downloadopensim-SC-5b6afeafbc249ba88dcc20d1fbc98ce12418b21b.zip
opensim-SC-5b6afeafbc249ba88dcc20d1fbc98ce12418b21b.tar.gz
opensim-SC-5b6afeafbc249ba88dcc20d1fbc98ce12418b21b.tar.bz2
opensim-SC-5b6afeafbc249ba88dcc20d1fbc98ce12418b21b.tar.xz
Brought in TestClient code for teh fork
Diffstat (limited to 'ExportBot/Commands')
-rw-r--r--ExportBot/Commands/AppearanceCommand.cs29
-rw-r--r--ExportBot/Commands/CloneProfileCommand.cs131
-rw-r--r--ExportBot/Commands/Communication/EchoMasterCommand.cs42
-rw-r--r--ExportBot/Commands/Communication/IMCommand.cs71
-rw-r--r--ExportBot/Commands/Communication/SayCommand.cs44
-rw-r--r--ExportBot/Commands/Communication/ShoutCommand.cs49
-rw-r--r--ExportBot/Commands/Communication/TtsCommand.cs51
-rw-r--r--ExportBot/Commands/Communication/WhisperCommand.cs49
-rw-r--r--ExportBot/Commands/DebugCommand.cs37
-rw-r--r--ExportBot/Commands/DilationCommand.cs22
-rw-r--r--ExportBot/Commands/DumpOutfitCommand.cs98
-rw-r--r--ExportBot/Commands/ExportCommand.cs209
-rw-r--r--ExportBot/Commands/ExportOutfitCommand.cs66
-rw-r--r--ExportBot/Commands/ExportParticlesCommand.cs119
-rw-r--r--ExportBot/Commands/FindSimCommand.cs43
-rw-r--r--ExportBot/Commands/HelpCommand.cs29
-rw-r--r--ExportBot/Commands/ImportCommand.cs246
-rw-r--r--ExportBot/Commands/ImportOutfitCommand.cs66
-rw-r--r--ExportBot/Commands/Inventory/BalanceCommand.cs21
-rw-r--r--ExportBot/Commands/Inventory/DeleteFolderCommand.cs43
-rw-r--r--ExportBot/Commands/Inventory/GiveAllCommand.cs27
-rw-r--r--ExportBot/Commands/Inventory/InventoryCommand.cs62
-rw-r--r--ExportBot/Commands/Inventory/WearCommand.cs43
-rw-r--r--ExportBot/Commands/LoadCommand.cs28
-rw-r--r--ExportBot/Commands/LoginCommand.cs34
-rw-r--r--ExportBot/Commands/LogoutCommand.cs24
-rw-r--r--ExportBot/Commands/MD5Command.cs22
-rw-r--r--ExportBot/Commands/Movement/FollowCommand.cs90
-rw-r--r--ExportBot/Commands/Movement/GotoCommand.cs53
-rw-r--r--ExportBot/Commands/Movement/JumpCommand.cs34
-rw-r--r--ExportBot/Commands/Movement/LocationCommand.cs23
-rw-r--r--ExportBot/Commands/Movement/MoveToCommand.cs24
-rw-r--r--ExportBot/Commands/Movement/SitCommand.cs52
-rw-r--r--ExportBot/Commands/Movement/SitOnCommand.cs54
-rw-r--r--ExportBot/Commands/Movement/StandCommand.cs47
-rw-r--r--ExportBot/Commands/PacketLogCommand.cs84
-rw-r--r--ExportBot/Commands/ParcelInfoCommand.cs62
-rw-r--r--ExportBot/Commands/PrimCountCommand.cs32
-rw-r--r--ExportBot/Commands/QuitCommand.cs24
-rw-r--r--ExportBot/Commands/RegionInfoCommand.cs45
-rw-r--r--ExportBot/Commands/SetMasterCommand.cs73
-rw-r--r--ExportBot/Commands/SetMasterKeyCommand.cs35
-rw-r--r--ExportBot/Commands/ShowEffectsCommand.cs76
-rw-r--r--ExportBot/Commands/StatsCommand.cs39
-rw-r--r--ExportBot/Commands/TouchCommand.cs55
-rw-r--r--ExportBot/Commands/TreeCommand.cs51
-rw-r--r--ExportBot/Commands/UptimeCommand.cs25
-rw-r--r--ExportBot/Commands/WhoCommand.cs29
48 files changed, 2712 insertions, 0 deletions
diff --git a/ExportBot/Commands/AppearanceCommand.cs b/ExportBot/Commands/AppearanceCommand.cs
new file mode 100644
index 0000000..6f003a7
--- /dev/null
+++ b/ExportBot/Commands/AppearanceCommand.cs
@@ -0,0 +1,29 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4using libsecondlife;
5using libsecondlife.Packets;
6
7namespace libsecondlife.TestClient
8{
9 public class AppearanceCommand : Command
10 {
11 Utilities.Assets.AssetManager Assets;
12 Utilities.Appearance.AppearanceManager Appearance;
13
14 public AppearanceCommand(TestClient testClient)
15 {
16 Name = "appearance";
17 Description = "Set your current appearance to your last saved appearance";
18
19 Assets = new libsecondlife.Utilities.Assets.AssetManager(testClient);
20 Appearance = new libsecondlife.Utilities.Appearance.AppearanceManager(testClient, Assets);
21 }
22
23 public override string Execute(string[] args, LLUUID fromAgentID)
24 {
25 Appearance.SetPreviousAppearance();
26 return "Done.";
27 }
28 }
29}
diff --git a/ExportBot/Commands/CloneProfileCommand.cs b/ExportBot/Commands/CloneProfileCommand.cs
new file mode 100644
index 0000000..d7fb5fc
--- /dev/null
+++ b/ExportBot/Commands/CloneProfileCommand.cs
@@ -0,0 +1,131 @@
1using System;
2using System.Collections.Generic;
3using System.Threading;
4using libsecondlife;
5using libsecondlife.Packets;
6
7namespace libsecondlife.TestClient
8{
9 public class CloneProfileCommand : Command
10 {
11 Avatar.AvatarProperties Properties;
12 Avatar.Interests Interests;
13 List<LLUUID> Groups = new List<LLUUID>();
14 bool ReceivedProperties = false;
15 bool ReceivedInterests = false;
16 bool ReceivedGroups = false;
17 ManualResetEvent ReceivedProfileEvent = new ManualResetEvent(false);
18
19 public CloneProfileCommand(TestClient testClient)
20 {
21 testClient.Avatars.OnAvatarInterests += new AvatarManager.AvatarInterestsCallback(Avatars_OnAvatarInterests);
22 testClient.Avatars.OnAvatarProperties += new AvatarManager.AvatarPropertiesCallback(Avatars_OnAvatarProperties);
23 testClient.Avatars.OnAvatarGroups += new AvatarManager.AvatarGroupsCallback(Avatars_OnAvatarGroups);
24 testClient.Self.OnJoinGroup += new MainAvatar.JoinGroupCallback(Self_OnJoinGroup);
25
26 Name = "cloneprofile";
27 Description = "Clones another avatars profile as closely as possible. WARNING: This command will " +
28 "destroy your existing profile! Usage: cloneprofile [targetuuid]";
29 }
30
31 public override string Execute(string[] args, LLUUID fromAgentID)
32 {
33 if (args.Length != 1)
34 return Description;
35
36 LLUUID targetID;
37 ReceivedProperties = false;
38 ReceivedInterests = false;
39 ReceivedGroups = false;
40
41 try
42 {
43 targetID = new LLUUID(args[0]);
44 }
45 catch (Exception)
46 {
47 return Description;
48 }
49
50 // Request all of the packets that make up an avatar profile
51 Client.Avatars.RequestAvatarProperties(targetID);
52
53 // Wait for all the packets to arrive
54 ReceivedProfileEvent.Reset();
55 ReceivedProfileEvent.WaitOne(5000, false);
56
57 // Check if everything showed up
58 if (!ReceivedInterests || !ReceivedProperties || !ReceivedGroups)
59 return "Failed to retrieve a complete profile for that UUID";
60
61 // Synchronize our profile
62 Client.Self.ProfileInterests = Interests;
63 Client.Self.ProfileProperties = Properties;
64 Client.Self.SetAvatarInformation();
65
66 // TODO: Leave all the groups we're currently a member of? This could
67 // break TestClient connectivity that might be relying on group authentication
68
69 // Attempt to join all the groups
70 foreach (LLUUID groupID in Groups)
71 {
72 Client.Self.RequestJoinGroup(groupID);
73 }
74
75 return "Synchronized our profile to the profile of " + targetID.ToStringHyphenated();
76 }
77
78 void Avatars_OnAvatarProperties(LLUUID avatarID, Avatar.AvatarProperties properties)
79 {
80 lock (ReceivedProfileEvent)
81 {
82 Properties = properties;
83 ReceivedProperties = true;
84
85 if (ReceivedInterests && ReceivedProperties && ReceivedGroups)
86 ReceivedProfileEvent.Set();
87 }
88 }
89
90 void Avatars_OnAvatarInterests(LLUUID avatarID, Avatar.Interests interests)
91 {
92 lock (ReceivedProfileEvent)
93 {
94 Interests = interests;
95 ReceivedInterests = true;
96
97 if (ReceivedInterests && ReceivedProperties && ReceivedGroups)
98 ReceivedProfileEvent.Set();
99 }
100 }
101
102 void Avatars_OnAvatarGroups(LLUUID avatarID, AvatarGroupsReplyPacket.GroupDataBlock[] groups)
103 {
104 lock (ReceivedProfileEvent)
105 {
106 foreach (AvatarGroupsReplyPacket.GroupDataBlock block in groups)
107 {
108 Groups.Add(block.GroupID);
109 }
110
111 ReceivedGroups = true;
112
113 if (ReceivedInterests && ReceivedProperties && ReceivedGroups)
114 ReceivedProfileEvent.Set();
115 }
116 }
117
118 void Self_OnJoinGroup(LLUUID groupID, bool success)
119 {
120 Console.WriteLine(Client.ToString() + (success ? " joined " : " failed to join ") +
121 groupID.ToStringHyphenated());
122
123 if (success)
124 {
125 Console.WriteLine(Client.ToString() + " setting " + groupID.ToStringHyphenated() +
126 " as the active group");
127 Client.Self.ActivateGroup(groupID);
128 }
129 }
130 }
131}
diff --git a/ExportBot/Commands/Communication/EchoMasterCommand.cs b/ExportBot/Commands/Communication/EchoMasterCommand.cs
new file mode 100644
index 0000000..2e426a8
--- /dev/null
+++ b/ExportBot/Commands/Communication/EchoMasterCommand.cs
@@ -0,0 +1,42 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4using libsecondlife;
5using libsecondlife.Packets;
6
7namespace libsecondlife.TestClient
8{
9 public class EchoMasterCommand: Command
10 {
11 public EchoMasterCommand(TestClient testClient)
12 {
13 Name = "echoMaster";
14 Description = "Repeat everything that master says.";
15 }
16
17 public override string Execute(string[] args, LLUUID fromAgentID)
18 {
19 if (!Active)
20 {
21 Active = true;
22 Client.Self.OnChat += new MainAvatar.ChatCallback(Self_OnChat);
23 return "Echoing is now on.";
24 }
25 else
26 {
27 Active = false;
28 Client.Self.OnChat -= new MainAvatar.ChatCallback(Self_OnChat);
29 return "Echoing is now off.";
30 }
31 }
32
33 void Self_OnChat(string message, MainAvatar.ChatAudibleLevel audible, MainAvatar.ChatType type,
34 MainAvatar.ChatSourceType sourcetype, string fromName, LLUUID id, LLUUID ownerid, LLVector3 position)
35 {
36 if (message.Length > 0 && Client.MasterKey == id)
37 {
38 Client.Self.Chat(message, 0, MainAvatar.ChatType.Normal);
39 }
40 }
41 }
42}
diff --git a/ExportBot/Commands/Communication/IMCommand.cs b/ExportBot/Commands/Communication/IMCommand.cs
new file mode 100644
index 0000000..32d7fff
--- /dev/null
+++ b/ExportBot/Commands/Communication/IMCommand.cs
@@ -0,0 +1,71 @@
1using System;
2using System.Collections.Generic;
3using System.Threading;
4using libsecondlife;
5using libsecondlife.Packets;
6
7namespace libsecondlife.TestClient
8{
9 public class ImCommand : Command
10 {
11 string ToAvatarName = String.Empty;
12 ManualResetEvent NameSearchEvent = new ManualResetEvent(false);
13 Dictionary<string, LLUUID> Name2Key = new Dictionary<string, LLUUID>();
14
15 public ImCommand(TestClient testClient)
16 {
17 testClient.Avatars.OnAvatarNameSearch += new AvatarManager.AvatarNameSearchCallback(Avatars_OnAvatarNameSearch);
18
19 Name = "im";
20 Description = "Instant message someone. Usage: im [firstname] [lastname] [message]";
21 }
22
23 public override string Execute(string[] args, LLUUID fromAgentID)
24 {
25 if (args.Length < 3)
26 return "Usage: im [firstname] [lastname] [message]";
27
28 ToAvatarName = args[0] + " " + args[1];
29
30 // Build the message
31 string message = String.Empty;
32 for (int ct = 2; ct < args.Length; ct++)
33 message += args[ct] + " ";
34 message = message.TrimEnd();
35 if (message.Length > 1023) message = message.Remove(1023);
36
37 if (!Name2Key.ContainsKey(ToAvatarName.ToLower()))
38 {
39 // Send the Query
40 Client.Avatars.RequestAvatarNameSearch(ToAvatarName, LLUUID.Random());
41
42 NameSearchEvent.WaitOne(6000, false);
43 }
44
45 if (Name2Key.ContainsKey(ToAvatarName.ToLower()))
46 {
47 LLUUID id = Name2Key[ToAvatarName.ToLower()];
48
49 Client.Self.InstantMessage(id, message, id);
50 return "Instant Messaged " + id.ToStringHyphenated() + " with message: " + message;
51 }
52 else
53 {
54 return "Name lookup for " + ToAvatarName + " failed";
55 }
56 }
57
58 void Avatars_OnAvatarNameSearch(LLUUID queryID, Dictionary<LLUUID, string> avatars)
59 {
60 foreach (KeyValuePair<LLUUID, string> kvp in avatars)
61 {
62 if (kvp.Value.ToLower() == ToAvatarName.ToLower())
63 {
64 Name2Key[ToAvatarName.ToLower()] = kvp.Key;
65 NameSearchEvent.Set();
66 return;
67 }
68 }
69 }
70 }
71}
diff --git a/ExportBot/Commands/Communication/SayCommand.cs b/ExportBot/Commands/Communication/SayCommand.cs
new file mode 100644
index 0000000..d5717a6
--- /dev/null
+++ b/ExportBot/Commands/Communication/SayCommand.cs
@@ -0,0 +1,44 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4using libsecondlife;
5
6namespace libsecondlife.TestClient
7{
8 public class SayCommand: Command
9 {
10 public SayCommand(TestClient testClient)
11 {
12 Name = "say";
13 Description = "Say something. (usage: say (optional channel) whatever)";
14 }
15
16 public override string Execute(string[] args, LLUUID fromAgentID)
17 {
18 int channel = 0;
19 int startIndex = 0;
20
21 if (args.Length < 1)
22 {
23 return "usage: say (optional channel) whatever";
24 }
25 else if (args.Length > 1)
26 {
27 if (Int32.TryParse(args[0], out channel))
28 startIndex = 1;
29 }
30
31 StringBuilder message = new StringBuilder();
32
33 for (int i = startIndex; i < args.Length; i++)
34 {
35 message.Append(args[i]);
36 if (i != args.Length - 1) message.Append(" ");
37 }
38
39 Client.Self.Chat(message.ToString(), channel, MainAvatar.ChatType.Normal);
40
41 return "Said " + message.ToString();
42 }
43 }
44}
diff --git a/ExportBot/Commands/Communication/ShoutCommand.cs b/ExportBot/Commands/Communication/ShoutCommand.cs
new file mode 100644
index 0000000..cf4b6c5
--- /dev/null
+++ b/ExportBot/Commands/Communication/ShoutCommand.cs
@@ -0,0 +1,49 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4using libsecondlife;
5using libsecondlife.Packets;
6
7namespace libsecondlife.TestClient
8{
9 public class ShoutCommand : Command
10 {
11 public ShoutCommand(TestClient testClient)
12 {
13 Name = "shout";
14 Description = "Shout something.";
15 }
16
17 public override string Execute(string[] args, LLUUID fromAgentID)
18 {
19 int channel = 0;
20 int startIndex = 0;
21 string message = String.Empty;
22 if (args.Length < 1)
23 {
24 return "usage: shout (optional channel) whatever";
25 }
26 else if (args.Length > 1)
27 {
28 try
29 {
30 channel = Convert.ToInt32(args[0]);
31 startIndex = 1;
32 }
33 catch (FormatException)
34 {
35 channel = 0;
36 }
37 }
38
39 for (int i = startIndex; i < args.Length; i++)
40 {
41 message += args[i] + " ";
42 }
43
44 Client.Self.Chat(message, channel, MainAvatar.ChatType.Shout);
45
46 return "Shouted " + message;
47 }
48 }
49}
diff --git a/ExportBot/Commands/Communication/TtsCommand.cs b/ExportBot/Commands/Communication/TtsCommand.cs
new file mode 100644
index 0000000..e8bd122
--- /dev/null
+++ b/ExportBot/Commands/Communication/TtsCommand.cs
@@ -0,0 +1,51 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4using System.Speech.Synthesis;
5using libsecondlife;
6using libsecondlife.Packets;
7using libsecondlife.AssetSystem;
8
9
10// Since this requires .Net 3.0 I've left it out of the project by default.
11// To use this: include it in the project and add a reference to the System.Speech.dll
12
13namespace libsecondlife.TestClient
14{
15 public class TtsCommand : Command
16 {
17 SpeechSynthesizer _speechSynthesizer;
18
19 public TtsCommand(TestClient testClient)
20 {
21 Name = "tts";
22 Description = "Text To Speech. When activated, client will echo all recieved chat messages out thru the computer's speakers.";
23 }
24
25 public override string Execute(string[] args, LLUUID fromAgentID)
26 {
27 if (!Active)
28 {
29 if (_speechSynthesizer == null)
30 _speechSynthesizer = new SpeechSynthesizer();
31 Active = true;
32 Client.Self.OnChat += new MainAvatar.ChatCallback(Self_OnChat);
33 return "TTS is now on.";
34 }
35 else
36 {
37 Active = false;
38 Client.Self.OnChat -= new MainAvatar.ChatCallback(Self_OnChat);
39 return "TTS is now off.";
40 }
41 }
42
43 void Self_OnChat(string message, byte audible, byte type, byte sourcetype, string fromName, LLUUID id, LLUUID ownerid, LLVector3 position)
44 {
45 if (message.Length > 0)
46 {
47 _speechSynthesizer.SpeakAsync(message);
48 }
49 }
50 }
51} \ No newline at end of file
diff --git a/ExportBot/Commands/Communication/WhisperCommand.cs b/ExportBot/Commands/Communication/WhisperCommand.cs
new file mode 100644
index 0000000..89ba0f3
--- /dev/null
+++ b/ExportBot/Commands/Communication/WhisperCommand.cs
@@ -0,0 +1,49 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4using libsecondlife;
5using libsecondlife.Packets;
6
7namespace libsecondlife.TestClient
8{
9 public class WhisperCommand : Command
10 {
11 public WhisperCommand(TestClient testClient)
12 {
13 Name = "whisper";
14 Description = "Whisper something.";
15 }
16
17 public override string Execute(string[] args, LLUUID fromAgentID)
18 {
19 int channel = 0;
20 int startIndex = 0;
21 string message = String.Empty;
22 if (args.Length < 1)
23 {
24 return "usage: whisper (optional channel) whatever";
25 }
26 else if (args.Length > 1)
27 {
28 try
29 {
30 channel = Convert.ToInt32(args[0]);
31 startIndex = 1;
32 }
33 catch (FormatException)
34 {
35 channel = 0;
36 }
37 }
38
39 for (int i = startIndex; i < args.Length; i++)
40 {
41 message += args[i] + " ";
42 }
43
44 Client.Self.Chat(message, channel, MainAvatar.ChatType.Whisper);
45
46 return "Whispered " + message;
47 }
48 }
49}
diff --git a/ExportBot/Commands/DebugCommand.cs b/ExportBot/Commands/DebugCommand.cs
new file mode 100644
index 0000000..fbfde7c
--- /dev/null
+++ b/ExportBot/Commands/DebugCommand.cs
@@ -0,0 +1,37 @@
1using System;
2using System.Collections.Generic;
3using libsecondlife;
4using libsecondlife.Packets;
5
6namespace libsecondlife.TestClient
7{
8 public class DebugCommand : Command
9 {
10 public DebugCommand(TestClient testClient)
11 {
12 Name = "debug";
13 Description = "Turn debug messages on or off. Usage: debug [on/off]";
14 }
15
16 public override string Execute(string[] args, LLUUID fromAgentID)
17 {
18 if (args.Length != 1)
19 return "Usage: debug [on/off]";
20
21 if (args[0].ToLower() == "on")
22 {
23 Client.Settings.DEBUG = true;
24 return "Debug logging is on";
25 }
26 else if (args[0].ToLower() == "off")
27 {
28 Client.Settings.DEBUG = false;
29 return "Debug logging is off";
30 }
31 else
32 {
33 return "Usage: debug [on/off]";
34 }
35 }
36 }
37}
diff --git a/ExportBot/Commands/DilationCommand.cs b/ExportBot/Commands/DilationCommand.cs
new file mode 100644
index 0000000..c1d3c04
--- /dev/null
+++ b/ExportBot/Commands/DilationCommand.cs
@@ -0,0 +1,22 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4using libsecondlife;
5using libsecondlife.Packets;
6
7namespace libsecondlife.TestClient
8{
9 public class DilationCommand : Command
10 {
11 public DilationCommand(TestClient testClient)
12 {
13 Name = "dilation";
14 Description = "Shows time dilation for current sim.";
15 }
16
17 public override string Execute(string[] args, LLUUID fromAgentID)
18 {
19 return "Dilation is " + Client.Network.CurrentSim.Dilation.ToString();
20 }
21 }
22} \ No newline at end of file
diff --git a/ExportBot/Commands/DumpOutfitCommand.cs b/ExportBot/Commands/DumpOutfitCommand.cs
new file mode 100644
index 0000000..2d3d0d8
--- /dev/null
+++ b/ExportBot/Commands/DumpOutfitCommand.cs
@@ -0,0 +1,98 @@
1using System;
2using System.Text;
3using System.IO;
4using System.Collections.Generic;
5using libsecondlife;
6using libsecondlife.Utilities.Assets;
7using libsecondlife.Utilities.Appearance;
8
9namespace libsecondlife.TestClient
10{
11 public class DumpOutfitCommand : Command
12 {
13 libsecondlife.Utilities.Assets.AssetManager Assets;
14 List<LLUUID> OutfitAssets = new List<LLUUID>();
15
16 public DumpOutfitCommand(TestClient testClient)
17 {
18 Name = "dumpoutfit";
19 Description = "Dumps all of the textures from an avatars outfit to the hard drive. Usage: dumpoutfit [avatar-uuid]";
20
21 Assets = new AssetManager(testClient);
22 Assets.OnImageReceived += new AssetManager.ImageReceivedCallback(Assets_OnImageReceived);
23 }
24
25 public override string Execute(string[] args, LLUUID fromAgentID)
26 {
27 if (args.Length != 1)
28 return "Usage: dumpoutfit [avatar-uuid]";
29
30 LLUUID target;
31
32 if (!LLUUID.TryParse(args[0], out target))
33 return "Usage: dumpoutfit [avatar-uuid]";
34
35 lock (Client.AvatarList)
36 {
37 foreach (Avatar avatar in Client.AvatarList.Values)
38 {
39 if (avatar.ID == target)
40 {
41 StringBuilder output = new StringBuilder("Downloading ");
42
43 lock (OutfitAssets) OutfitAssets.Clear();
44
45 foreach (KeyValuePair<uint, LLObject.TextureEntryFace> face in avatar.Textures.FaceTextures)
46 {
47 ImageType type = ImageType.Normal;
48
49 switch ((AppearanceManager.TextureIndex)face.Key)
50 {
51 case AppearanceManager.TextureIndex.HeadBaked:
52 case AppearanceManager.TextureIndex.EyesBaked:
53 case AppearanceManager.TextureIndex.UpperBaked:
54 case AppearanceManager.TextureIndex.LowerBaked:
55 case AppearanceManager.TextureIndex.SkirtBaked:
56 type = ImageType.Baked;
57 break;
58 }
59
60 Assets.RequestImage(face.Value.TextureID, type, 100000.0f, 0);
61
62 output.Append(((AppearanceManager.TextureIndex)face.Key).ToString());
63 output.Append(" ");
64 }
65
66 return output.ToString();
67 }
68 }
69 }
70
71 return "Couldn't find avatar " + target.ToStringHyphenated();
72 }
73
74 private void Assets_OnImageReceived(ImageDownload image)
75 {
76 if (image.Success)
77 {
78 try
79 {
80 File.WriteAllBytes(image.ID.ToStringHyphenated() + ".jp2", image.AssetData);
81 Console.WriteLine("Wrote JPEG2000 image " + image.ID.ToStringHyphenated() + ".jp2");
82
83 byte[] tgaFile = OpenJPEGNet.OpenJPEG.DecodeToTGA(image.AssetData);
84 File.WriteAllBytes(image.ID.ToStringHyphenated() + ".tga", tgaFile);
85 Console.WriteLine("Wrote TGA image " + image.ID.ToStringHyphenated() + ".tga");
86 }
87 catch (Exception e)
88 {
89 Console.WriteLine(e.ToString());
90 }
91 }
92 else
93 {
94 Console.WriteLine("Failed to download image " + image.ID.ToStringHyphenated());
95 }
96 }
97 }
98}
diff --git a/ExportBot/Commands/ExportCommand.cs b/ExportBot/Commands/ExportCommand.cs
new file mode 100644
index 0000000..2baac1a
--- /dev/null
+++ b/ExportBot/Commands/ExportCommand.cs
@@ -0,0 +1,209 @@
1using System;
2using System.Collections.Generic;
3using System.IO;
4using System.Xml;
5using System.Text;
6using System.Threading;
7using libsecondlife;
8using libsecondlife.Packets;
9
10namespace libsecondlife.TestClient
11{
12 public class ExportCommand : Command
13 {
14 AutoResetEvent GotPermissionsEvent = new AutoResetEvent(false);
15 LLObject.ObjectPropertiesFamily Properties;
16 bool GotPermissions = false;
17 LLUUID SelectedObject = LLUUID.Zero;
18
19 Dictionary<LLUUID, Primitive> PrimsWaiting = new Dictionary<LLUUID, Primitive>();
20 AutoResetEvent AllPropertiesReceived = new AutoResetEvent(false);
21
22 public ExportCommand(TestClient testClient)
23 {
24 testClient.Objects.OnObjectPropertiesFamily += new ObjectManager.ObjectPropertiesFamilyCallback(Objects_OnObjectPropertiesFamily);
25 testClient.Objects.OnObjectProperties += new ObjectManager.ObjectPropertiesCallback(Objects_OnObjectProperties);
26 testClient.Avatars.OnPointAt += new AvatarManager.PointAtCallback(Avatars_OnPointAt);
27
28 Name = "export";
29 Description = "Exports an object to an xml file. Usage: export uuid outputfile.xml";
30 }
31
32 public override string Execute(string[] args, LLUUID fromAgentID)
33 {
34 if (args.Length != 2 && !(args.Length == 1 && SelectedObject != LLUUID.Zero))
35 return "Usage: export uuid outputfile.xml";
36
37 LLUUID id;
38 uint localid = 0;
39 int count = 0;
40 string file;
41
42 if (args.Length == 2)
43 {
44 file = args[1];
45 if (!LLUUID.TryParse(args[0], out id))
46 return "Usage: export uuid outputfile.xml";
47 }
48 else
49 {
50 file = args[0];
51 id = SelectedObject;
52 }
53
54 lock (Client.SimPrims)
55 {
56 if (Client.SimPrims.ContainsKey(Client.Network.CurrentSim))
57 {
58 foreach (Primitive prim in Client.SimPrims[Client.Network.CurrentSim].Values)
59 {
60 if (prim.ID == id)
61 {
62 if (prim.ParentID != 0)
63 localid = prim.ParentID;
64 else
65 localid = prim.LocalID;
66
67 break;
68 }
69 }
70 }
71 }
72
73 if (localid != 0)
74 {
75 // Check for export permission first
76 Client.Objects.RequestObjectPropertiesFamily(Client.Network.CurrentSim, id);
77 GotPermissionsEvent.WaitOne(8000, false);
78
79 if (!GotPermissions)
80 {
81 return "Couldn't fetch permissions for the requested object, try again";
82 }
83 else
84 {
85 GotPermissions = false;
86 if (Properties.OwnerID != Client.Network.AgentID &&
87 Properties.OwnerID != Client.MasterKey &&
88 Client.Network.AgentID != Client.Self.ID)
89 {
90 return "That object is owned by " + Properties.OwnerID + ", we don't have permission " +
91 "to export it";
92 }
93 }
94
95 try
96 {
97 XmlWriterSettings settings = new XmlWriterSettings();
98 settings.Indent = true;
99 XmlWriter writer = XmlWriter.Create(file, settings);
100
101 try
102 {
103 List<Primitive> prims = new List<Primitive>();
104
105 lock (Client.SimPrims)
106 {
107 if (Client.SimPrims.ContainsKey(Client.Network.CurrentSim))
108 {
109 foreach (Primitive prim in Client.SimPrims[Client.Network.CurrentSim].Values)
110 {
111 if (prim.LocalID == localid || prim.ParentID == localid)
112 {
113 prims.Add(prim);
114 count++;
115 }
116 }
117 }
118 }
119
120 bool complete = RequestObjectProperties(prims, 250);
121
122 //Serialize it!
123 Helpers.PrimListToXml(prims, writer);
124
125 if (!complete) {
126 Console.WriteLine("Warning: Unable to retrieve full properties for:");
127 foreach (LLUUID uuid in PrimsWaiting.Keys)
128 Console.WriteLine(uuid);
129 }
130 }
131 finally
132 {
133 writer.Close();
134 }
135 }
136 catch (Exception e)
137 {
138 string ret = "Failed to write to " + file + ":" + e.ToString();
139 if (ret.Length > 1000)
140 {
141 ret = ret.Remove(1000);
142 }
143 return ret;
144 }
145 return "Exported " + count + " prims to " + file;
146 }
147 else
148 {
149 return "Couldn't find UUID " + id.ToString() + " in the " +
150 Client.SimPrims[Client.Network.CurrentSim].Count +
151 "objects currently indexed in the current simulator";
152 }
153 }
154
155 private bool RequestObjectProperties(List<Primitive> objects, int msPerRequest)
156 {
157 // Create an array of the local IDs of all the prims we are requesting properties for
158 uint[] localids = new uint[objects.Count];
159
160 lock (PrimsWaiting)
161 {
162 PrimsWaiting.Clear();
163
164 for (int i = 0; i < objects.Count; ++i)
165 {
166 localids[i] = objects[i].LocalID;
167 PrimsWaiting.Add(objects[i].ID, objects[i]);
168 }
169 }
170
171 Client.Objects.SelectObjects(Client.Network.CurrentSim, localids);
172
173 return AllPropertiesReceived.WaitOne(2000 + msPerRequest * objects.Count, false);
174 }
175
176 void Avatars_OnPointAt(LLUUID sourceID, LLUUID targetID, LLVector3d targetPos,
177 MainAvatar.PointAtType pointType, float duration, LLUUID id)
178 {
179 if (sourceID == Client.MasterKey)
180 {
181 //Client.DebugLog("Master is now selecting " + targetID.ToStringHyphenated());
182 SelectedObject = targetID;
183 }
184 }
185
186 void Objects_OnObjectPropertiesFamily(Simulator simulator, LLObject.ObjectPropertiesFamily properties)
187 {
188 Properties = properties;
189 GotPermissions = true;
190 GotPermissionsEvent.Set();
191 }
192
193 void Objects_OnObjectProperties(Simulator simulator, LLObject.ObjectProperties properties)
194 {
195 lock (PrimsWaiting)
196 {
197 Primitive prim;
198 if (PrimsWaiting.TryGetValue(properties.ObjectID, out prim))
199 {
200 prim.Properties = properties;
201 }
202 PrimsWaiting.Remove(properties.ObjectID);
203
204 if (PrimsWaiting.Count == 0)
205 AllPropertiesReceived.Set();
206 }
207 }
208 }
209}
diff --git a/ExportBot/Commands/ExportOutfitCommand.cs b/ExportBot/Commands/ExportOutfitCommand.cs
new file mode 100644
index 0000000..6ec2776
--- /dev/null
+++ b/ExportBot/Commands/ExportOutfitCommand.cs
@@ -0,0 +1,66 @@
1using System;
2using System.Collections.Generic;
3using System.IO;
4using System.Xml;
5using libsecondlife;
6using libsecondlife.Packets;
7
8namespace libsecondlife.TestClient
9{
10 public class ExportOutfitCommand : Command
11 {
12 public ExportOutfitCommand(TestClient testClient)
13 {
14 Name = "exportoutfit";
15 Description = "Exports an avatars outfit to an xml file. Usage: exportoutfit avataruuid outputfile.xml";
16 }
17
18 public override string Execute(string[] args, LLUUID fromAgentID)
19 {
20 if (args.Length != 2)
21 return "Usage: exportoutfit avataruuid outputfile.xml";
22
23 LLUUID id;
24
25 try
26 {
27 id = new LLUUID(args[0]);
28 }
29 catch (Exception)
30 {
31 return "Usage: exportoutfit avataruuid outputfile.xml";
32 }
33
34 lock (Client.Appearances)
35 {
36 if (Client.Appearances.ContainsKey(id))
37 {
38 try
39 {
40 XmlWriterSettings settings = new XmlWriterSettings();
41 settings.Indent = true;
42 XmlWriter writer = XmlWriter.Create(args[1], settings);
43 try
44 {
45 Client.Appearances[id].ToXml(writer);
46 }
47 finally
48 {
49 writer.Close();
50 }
51 }
52 catch (Exception e)
53 {
54 return e.ToString();
55 }
56
57 return "Exported appearance for avatar " + id.ToString() + " to " + args[1];
58 }
59 else
60 {
61 return "Couldn't find an appearance for avatar " + id.ToString();
62 }
63 }
64 }
65 }
66} \ No newline at end of file
diff --git a/ExportBot/Commands/ExportParticlesCommand.cs b/ExportBot/Commands/ExportParticlesCommand.cs
new file mode 100644
index 0000000..4b2c322
--- /dev/null
+++ b/ExportBot/Commands/ExportParticlesCommand.cs
@@ -0,0 +1,119 @@
1using System;
2using System.Collections.Generic;
3using System.IO;
4using System.Text;
5using libsecondlife;
6
7namespace libsecondlife.TestClient
8{
9 public class ExportParticlesCommand : Command
10 {
11 public ExportParticlesCommand(TestClient testClient)
12 {
13 Name = "exportparticles";
14 Description = "Reverse engineers a prim with a particle system to an LSL script. Usage: exportscript [prim-uuid]";
15 }
16
17 public override string Execute(string[] args, LLUUID fromAgentID)
18 {
19 if (args.Length != 1)
20 return "Usage: exportparticles [prim-uuid]";
21
22 LLUUID id;
23 if (!LLUUID.TryParse(args[0], out id))
24 return "Usage: exportparticles [prim-uuid]";
25
26 lock (Client.SimPrims)
27 {
28 if (Client.SimPrims.ContainsKey(Client.Network.CurrentSim))
29 {
30 foreach (Primitive prim in Client.SimPrims[Client.Network.CurrentSim].Values)
31 {
32 if (prim.ID == id)
33 {
34 if (prim.ParticleSys.CRC != 0)
35 {
36 StringBuilder lsl = new StringBuilder();
37
38 lsl.Append("default" + Environment.NewLine);
39 lsl.Append("{" + Environment.NewLine);
40 lsl.Append(" state_entry()" + Environment.NewLine);
41 lsl.Append(" {" + Environment.NewLine);
42 lsl.Append(" llParticleSystem([" + Environment.NewLine);
43
44 lsl.Append(" PSYS_PART_FLAGS, 0");
45
46 if ((prim.ParticleSys.PartDataFlags & Primitive.ParticleSystem.ParticleDataFlags.InterpColor) != 0)
47 lsl.Append(" | PSYS_PART_INTERP_COLOR_MASK");
48 if ((prim.ParticleSys.PartDataFlags & Primitive.ParticleSystem.ParticleDataFlags.InterpScale) != 0)
49 lsl.Append(" | PSYS_PART_INTERP_SCALE_MASK");
50 if ((prim.ParticleSys.PartDataFlags & Primitive.ParticleSystem.ParticleDataFlags.Bounce) != 0)
51 lsl.Append(" | PSYS_PART_BOUNCE_MASK");
52 if ((prim.ParticleSys.PartDataFlags & Primitive.ParticleSystem.ParticleDataFlags.Wind) != 0)
53 lsl.Append(" | PSYS_PART_WIND_MASK");
54 if ((prim.ParticleSys.PartDataFlags & Primitive.ParticleSystem.ParticleDataFlags.FollowSrc) != 0)
55 lsl.Append(" | PSYS_PART_FOLLOW_SRC_MASK");
56 if ((prim.ParticleSys.PartDataFlags & Primitive.ParticleSystem.ParticleDataFlags.FollowVelocity) != 0)
57 lsl.Append(" | PSYS_PART_FOLLOW_VELOCITY_MASK");
58 if ((prim.ParticleSys.PartDataFlags & Primitive.ParticleSystem.ParticleDataFlags.TargetPos) != 0)
59 lsl.Append(" | PSYS_PART_TARGET_POS_MASK");
60 if ((prim.ParticleSys.PartDataFlags & Primitive.ParticleSystem.ParticleDataFlags.TargetLinear) != 0)
61 lsl.Append(" | PSYS_PART_TARGET_LINEAR_MASK");
62 if ((prim.ParticleSys.PartDataFlags & Primitive.ParticleSystem.ParticleDataFlags.Emissive) != 0)
63 lsl.Append(" | PSYS_PART_EMISSIVE_MASK");
64
65 lsl.Append(","); lsl.Append(Environment.NewLine);
66 lsl.Append(" PSYS_SRC_PATTERN, 0");
67
68 if ((prim.ParticleSys.Pattern & Primitive.ParticleSystem.SourcePattern.Drop) != 0)
69 lsl.Append(" | PSYS_SRC_PATTERN_DROP");
70 if ((prim.ParticleSys.Pattern & Primitive.ParticleSystem.SourcePattern.Explode) != 0)
71 lsl.Append(" | PSYS_SRC_PATTERN_EXPLODE");
72 if ((prim.ParticleSys.Pattern & Primitive.ParticleSystem.SourcePattern.Angle) != 0)
73 lsl.Append(" | PSYS_SRC_PATTERN_ANGLE");
74 if ((prim.ParticleSys.Pattern & Primitive.ParticleSystem.SourcePattern.AngleCone) != 0)
75 lsl.Append(" | PSYS_SRC_PATTERN_ANGLE_CONE");
76 if ((prim.ParticleSys.Pattern & Primitive.ParticleSystem.SourcePattern.AngleConeEmpty) != 0)
77 lsl.Append(" | PSYS_SRC_PATTERN_ANGLE_CONE_EMPTY");
78
79 lsl.Append("," + Environment.NewLine);
80
81 lsl.Append(" PSYS_PART_START_ALPHA, " + String.Format("{0:0.00000}", prim.ParticleSys.PartStartColor.A) + "," + Environment.NewLine);
82 lsl.Append(" PSYS_PART_END_ALPHA, " + String.Format("{0:0.00000}", prim.ParticleSys.PartEndColor.A) + "," + Environment.NewLine);
83 lsl.Append(" PSYS_PART_START_COLOR, " + prim.ParticleSys.PartStartColor.ToStringRGB() + "," + Environment.NewLine);
84 lsl.Append(" PSYS_PART_END_COLOR, " + prim.ParticleSys.PartEndColor.ToStringRGB() + "," + Environment.NewLine);
85 lsl.Append(" PSYS_PART_START_SCALE, <" + String.Format("{0:0.00000}", prim.ParticleSys.PartStartScaleX) + ", " + String.Format("{0:0.00000}", prim.ParticleSys.PartStartScaleY) + ", 0>, " + Environment.NewLine);
86 lsl.Append(" PSYS_PART_END_SCALE, <" + String.Format("{0:0.00000}", prim.ParticleSys.PartEndScaleX) + ", " + String.Format("{0:0.00000}", prim.ParticleSys.PartEndScaleY) + ", 0>, " + Environment.NewLine);
87 lsl.Append(" PSYS_PART_MAX_AGE, " + String.Format("{0:0.00000}", prim.ParticleSys.PartMaxAge) + "," + Environment.NewLine);
88 lsl.Append(" PSYS_SRC_MAX_AGE, " + String.Format("{0:0.00000}", prim.ParticleSys.MaxAge) + "," + Environment.NewLine);
89 lsl.Append(" PSYS_SRC_ACCEL, " + prim.ParticleSys.PartAcceleration.ToString() + "," + Environment.NewLine);
90 lsl.Append(" PSYS_SRC_BURST_PART_COUNT, " + String.Format("{0:0}", prim.ParticleSys.BurstPartCount) + "," + Environment.NewLine);
91 lsl.Append(" PSYS_SRC_BURST_RADIUS, " + String.Format("{0:0.00000}", prim.ParticleSys.BurstRadius) + "," + Environment.NewLine);
92 lsl.Append(" PSYS_SRC_BURST_RATE, " + String.Format("{0:0.00000}", prim.ParticleSys.BurstRate) + "," + Environment.NewLine);
93 lsl.Append(" PSYS_SRC_BURST_SPEED_MIN, " + String.Format("{0:0.00000}", prim.ParticleSys.BurstSpeedMin) + "," + Environment.NewLine);
94 lsl.Append(" PSYS_SRC_BURST_SPEED_MAX, " + String.Format("{0:0.00000}", prim.ParticleSys.BurstSpeedMax) + "," + Environment.NewLine);
95 lsl.Append(" PSYS_SRC_INNERANGLE, " + String.Format("{0:0.00000}", prim.ParticleSys.InnerAngle) + "," + Environment.NewLine);
96 lsl.Append(" PSYS_SRC_OUTERANGLE, " + String.Format("{0:0.00000}", prim.ParticleSys.OuterAngle) + "," + Environment.NewLine);
97 lsl.Append(" PSYS_SRC_OMEGA, " + prim.ParticleSys.AngularVelocity.ToString() + "," + Environment.NewLine);
98 lsl.Append(" PSYS_SRC_TEXTURE, (key)\"" + prim.ParticleSys.Texture.ToStringHyphenated() + "\"," + Environment.NewLine);
99 lsl.Append(" PSYS_SRC_TARGET_KEY, (key)\"" + prim.ParticleSys.Target.ToStringHyphenated() + "\"" + Environment.NewLine);
100
101 lsl.Append(" ]);" + Environment.NewLine);
102 lsl.Append(" }" + Environment.NewLine);
103 lsl.Append("}" + Environment.NewLine);
104
105 return lsl.ToString();
106 }
107 else
108 {
109 return "Prim " + prim.LocalID + " does not have a particle system";
110 }
111 }
112 }
113 }
114 }
115
116 return "Couldn't find prim " + id.ToStringHyphenated();
117 }
118 }
119}
diff --git a/ExportBot/Commands/FindSimCommand.cs b/ExportBot/Commands/FindSimCommand.cs
new file mode 100644
index 0000000..c6cc9c4
--- /dev/null
+++ b/ExportBot/Commands/FindSimCommand.cs
@@ -0,0 +1,43 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4using libsecondlife;
5using libsecondlife.Packets;
6
7namespace libsecondlife.TestClient
8{
9 public class FindSimCommand : Command
10 {
11 public FindSimCommand(TestClient testClient)
12 {
13 Name = "findsim";
14 Description = "Searches for a simulator and returns information about it. Usage: findsim [Simulator Name]";
15 }
16
17 public override string Execute(string[] args, LLUUID fromAgentID)
18 {
19 if (args.Length < 1)
20 return "Usage: findsim [Simulator Name]";
21
22 // Build the simulator name from the args list
23 string simName = string.Empty;
24 for (int i = 0; i < args.Length; i++)
25 simName += args[i] + " ";
26 simName = simName.TrimEnd().ToLower();
27
28 //if (!GridDataCached[Client])
29 //{
30 // Client.Grid.RequestAllSims(GridManager.MapLayerType.Objects);
31 // System.Threading.Thread.Sleep(5000);
32 // GridDataCached[Client] = true;
33 //}
34
35 GridRegion region;
36
37 if (Client.Grid.GetGridRegion(simName, out region))
38 return String.Format("{0}: handle={1} ({2},{3})", region.Name, region.RegionHandle, region.X, region.Y);
39 else
40 return "Lookup of " + simName + " failed";
41 }
42 }
43}
diff --git a/ExportBot/Commands/HelpCommand.cs b/ExportBot/Commands/HelpCommand.cs
new file mode 100644
index 0000000..5cbdcb2
--- /dev/null
+++ b/ExportBot/Commands/HelpCommand.cs
@@ -0,0 +1,29 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4using libsecondlife;
5using libsecondlife.Packets;
6
7namespace libsecondlife.TestClient
8{
9 public class HelpCommand: Command
10 {
11 public HelpCommand(TestClient testClient)
12 {
13 Name = "help";
14 Description = "Lists available commands.";
15 }
16
17 public override string Execute(string[] args, LLUUID fromAgentID)
18 {
19 StringBuilder result = new StringBuilder();
20 result.AppendFormat("\n\nHELP\nClient accept teleport lures from master and group members.\n");
21 foreach (Command c in Client.Commands.Values)
22 {
23 result.AppendFormat(" * {0} - {1}\n", c.Name, c.Description);
24 }
25
26 return result.ToString();
27 }
28 }
29}
diff --git a/ExportBot/Commands/ImportCommand.cs b/ExportBot/Commands/ImportCommand.cs
new file mode 100644
index 0000000..4cdcaee
--- /dev/null
+++ b/ExportBot/Commands/ImportCommand.cs
@@ -0,0 +1,246 @@
1using System;
2using System.Collections.Generic;
3using System.Xml;
4using System.Xml.Serialization;
5using System.Threading;
6using System.IO;
7using libsecondlife;
8
9namespace libsecondlife.TestClient
10{
11 enum ImporterState
12 {
13 RezzingParent,
14 RezzingChildren,
15 Linking,
16 Idle
17 }
18
19 public class Linkset
20 {
21 public Primitive RootPrim;
22 public List<Primitive> Children = new List<Primitive>();
23
24 public Linkset()
25 {
26 RootPrim = new Primitive();
27 }
28
29 public Linkset(Primitive rootPrim)
30 {
31 RootPrim = rootPrim;
32 }
33 }
34
35 public class ImportCommand : Command
36 {
37 Primitive currentPrim;
38 LLVector3 currentPosition;
39 SecondLife currentClient;
40 AutoResetEvent primDone;
41 List<Primitive> primsCreated;
42 List<uint> linkQueue;
43 uint rootLocalID = 0;
44 bool registeredCreateEvent = false;
45
46 ImporterState state = ImporterState.Idle;
47
48 public ImportCommand(TestClient testClient)
49 {
50 Name = "import";
51 Description = "Import prims from an exported xml file. Usage: import inputfile.xml";
52 primDone = new AutoResetEvent(false);
53 registeredCreateEvent = false;
54 }
55
56 public override string Execute(string[] args, LLUUID fromAgentID)
57 {
58 if (args.Length != 1)
59 return "Usage: import inputfile.xml";
60
61 string filename = args[0];
62 Dictionary<uint, Primitive> prims;
63
64 currentClient = Client;
65
66 try
67 {
68 XmlReader reader = XmlReader.Create(filename);
69 List<Primitive> listprims = Helpers.PrimListFromXml(reader);
70 reader.Close();
71
72 // Create a dictionary indexed by the old local ID of the prims
73 prims = new Dictionary<uint, Primitive>();
74 foreach (Primitive prim in listprims)
75 {
76 prims.Add(prim.LocalID, prim);
77 }
78 }
79 catch (Exception)
80 {
81 return "Failed to import the object XML file, maybe it doesn't exist or is in the wrong format?";
82 }
83
84 if (!registeredCreateEvent)
85 {
86 Client.OnPrimCreated += new TestClient.PrimCreatedCallback(TestClient_OnPrimCreated);
87 registeredCreateEvent = true;
88 }
89
90 // Build an organized structure from the imported prims
91 Dictionary<uint, Linkset> linksets = new Dictionary<uint, Linkset>();
92 foreach (Primitive prim in prims.Values)
93 {
94 if (prim.ParentID == 0)
95 {
96 if (linksets.ContainsKey(prim.LocalID))
97 linksets[prim.LocalID].RootPrim = prim;
98 else
99 linksets[prim.LocalID] = new Linkset(prim);
100 }
101 else
102 {
103 if (!linksets.ContainsKey(prim.ParentID))
104 linksets[prim.ParentID] = new Linkset();
105
106 linksets[prim.ParentID].Children.Add(prim);
107 }
108 }
109
110 primsCreated = new List<Primitive>();
111 Console.WriteLine("Importing " + linksets.Count + " structures.");
112
113 foreach (Linkset linkset in linksets.Values)
114 {
115 if (linkset.RootPrim.LocalID != 0)
116 {
117 state = ImporterState.RezzingParent;
118 currentPrim = linkset.RootPrim;
119 // HACK: Offset the root prim position so it's not lying on top of the original
120 // We need a more elaborate solution for importing with relative or absolute offsets
121 linkset.RootPrim.Position = Client.Self.Position;
122 linkset.RootPrim.Position.Z += 3.0f;
123 currentPosition = linkset.RootPrim.Position;
124 // A better solution would move the bot to the desired position.
125 // or to check if we are within a certain distance of the desired position.
126
127 // Rez the root prim with no rotation
128 LLQuaternion rootRotation = linkset.RootPrim.Rotation;
129 linkset.RootPrim.Rotation = LLQuaternion.Identity;
130
131 Client.Objects.AddPrim(Client.Network.CurrentSim, linkset.RootPrim.Data, LLUUID.Zero,
132 linkset.RootPrim.Position, linkset.RootPrim.Scale, linkset.RootPrim.Rotation);
133
134 if (!primDone.WaitOne(10000, false))
135 return "Rez failed, timed out while creating the root prim.";
136
137 state = ImporterState.RezzingChildren;
138
139 // Rez the child prims
140 foreach (Primitive prim in linkset.Children)
141 {
142 currentPrim = prim;
143 currentPosition = prim.Position + linkset.RootPrim.Position;
144
145 Client.Objects.AddPrim(Client.Network.CurrentSim, prim.Data, LLUUID.Zero, currentPosition,
146 prim.Scale, prim.Rotation);
147
148 if (!primDone.WaitOne(10000, false))
149 return "Rez failed, timed out while creating child prim.";
150 }
151
152 if (linkset.Children.Count != 0)
153 {
154 // Create a list of the local IDs of the newly created prims
155 List<uint> primIDs = new List<uint>(primsCreated.Count);
156 primIDs.Add(rootLocalID); // Root prim is first in list.
157 foreach (Primitive prim in primsCreated)
158 {
159 if (prim.LocalID != rootLocalID)
160 primIDs.Add(prim.LocalID);
161 }
162 linkQueue = new List<uint>(primIDs.Count);
163 linkQueue.AddRange(primIDs);
164
165 // Link and set the permissions + rotation
166 state = ImporterState.Linking;
167 Client.Objects.LinkPrims(Client.Network.CurrentSim, linkQueue);
168 if (primDone.WaitOne(100000 * linkset.Children.Count, false))
169 {
170 Client.Objects.SetPermissions(Client.Network.CurrentSim, primIDs,
171 Helpers.PermissionWho.Everyone | Helpers.PermissionWho.Group | Helpers.PermissionWho.NextOwner,
172 Helpers.PermissionType.Copy | Helpers.PermissionType.Modify | Helpers.PermissionType.Move |
173 Helpers.PermissionType.Transfer, true);
174
175 Client.Objects.SetRotation(Client.Network.CurrentSim, rootLocalID, rootRotation);
176 }
177 else
178 {
179 Console.WriteLine("Warning: Failed to link {0} prims", linkQueue.Count);
180 }
181 }
182 else
183 {
184 Client.Objects.SetRotation(Client.Network.CurrentSim, rootLocalID, rootRotation);
185 }
186 state = ImporterState.Idle;
187 }
188 else
189 {
190 // Skip linksets with a missing root prim
191 Console.WriteLine("WARNING: Skipping a linkset with a missing root prim");
192 }
193
194 // Reset everything for the next linkset
195 primsCreated.Clear();
196 }
197
198 return "Import complete.";
199 }
200
201 void TestClient_OnPrimCreated(Simulator simulator, Primitive prim)
202 {
203 if ((prim.Flags & LLObject.ObjectFlags.CreateSelected) == 0)
204 return; // We received an update for an object we didn't create
205
206 switch (state)
207 {
208 case ImporterState.RezzingParent:
209 rootLocalID = prim.LocalID;
210 goto case ImporterState.RezzingChildren;
211 case ImporterState.RezzingChildren:
212 if (!primsCreated.Contains(prim))
213 {
214 Console.WriteLine("Setting properties for " + prim.LocalID);
215 // TODO: Is there a way to set all of this at once, and update more ObjectProperties stuff?
216 currentClient.Objects.SetPosition(simulator, prim.LocalID, currentPosition);
217 currentClient.Objects.SetTextures(simulator, prim.LocalID, currentPrim.Textures);
218 currentClient.Objects.SetLight(simulator, prim.LocalID, currentPrim.Light);
219 currentClient.Objects.SetFlexible(simulator, prim.LocalID, currentPrim.Flexible);
220
221 if (!String.IsNullOrEmpty(currentPrim.Properties.Name))
222 currentClient.Objects.SetName(simulator, prim.LocalID, currentPrim.Properties.Name);
223 if (!String.IsNullOrEmpty(currentPrim.Properties.Description))
224 currentClient.Objects.SetDescription(simulator, prim.LocalID,
225 currentPrim.Properties.Description);
226
227 primsCreated.Add(prim);
228 primDone.Set();
229 }
230 break;
231 case ImporterState.Linking:
232 lock (linkQueue)
233 {
234 int index = linkQueue.IndexOf(prim.LocalID);
235 if (index != -1)
236 {
237 linkQueue.RemoveAt(index);
238 if (linkQueue.Count == 0)
239 primDone.Set();
240 }
241 }
242 break;
243 }
244 }
245 }
246}
diff --git a/ExportBot/Commands/ImportOutfitCommand.cs b/ExportBot/Commands/ImportOutfitCommand.cs
new file mode 100644
index 0000000..5ac7b8a
--- /dev/null
+++ b/ExportBot/Commands/ImportOutfitCommand.cs
@@ -0,0 +1,66 @@
1using System;
2using System.Collections.Generic;
3using System.IO;
4using System.Xml;
5using System.Xml.Serialization;
6using libsecondlife;
7using libsecondlife.Packets;
8
9namespace libsecondlife.TestClient
10{
11 public class ImportOutfitCommand : Command
12 {
13 private uint SerialNum = 1;
14
15 public ImportOutfitCommand(TestClient testClient)
16 {
17 Name = "importoutfit";
18 Description = "Imports an appearance from an xml file. Usage: importoutfit inputfile.xml";
19 }
20
21 public override string Execute(string[] args, LLUUID fromAgentID)
22 {
23 if (args.Length != 1)
24 return "Usage: importoutfit inputfile.xml";
25
26 try
27 {
28 XmlReader reader = XmlReader.Create(args[0]);
29 XmlSerializer serializer = new XmlSerializer(typeof(Packet));
30 AvatarAppearancePacket appearance = (AvatarAppearancePacket)serializer.Deserialize(reader);
31 reader.Close();
32
33 AgentSetAppearancePacket set = new AgentSetAppearancePacket();
34
35 set.AgentData.AgentID = Client.Network.AgentID;
36 set.AgentData.SessionID = Client.Network.SessionID;
37 set.AgentData.SerialNum = SerialNum++;
38
39 float AV_Height_Range = 2.025506f - 1.50856f;
40 float AV_Height = 1.50856f + (((float)appearance.VisualParam[25].ParamValue / 255.0f) * AV_Height_Range);
41 set.AgentData.Size = new LLVector3(0.45f, 0.6f, AV_Height);
42
43 set.ObjectData.TextureEntry = appearance.ObjectData.TextureEntry;
44 set.VisualParam = new AgentSetAppearancePacket.VisualParamBlock[appearance.VisualParam.Length];
45
46 int i = 0;
47 foreach (AvatarAppearancePacket.VisualParamBlock block in appearance.VisualParam)
48 {
49 set.VisualParam[i] = new AgentSetAppearancePacket.VisualParamBlock();
50 set.VisualParam[i].ParamValue = block.ParamValue;
51 i++;
52 }
53
54 set.WearableData = new AgentSetAppearancePacket.WearableDataBlock[0];
55
56 Client.Network.SendPacket(set);
57 }
58 catch (Exception)
59 {
60 return "Failed to import the appearance XML file, maybe it doesn't exist or is in the wrong format?";
61 }
62
63 return "Imported " + args[0] + " and sent an AgentSetAppearance packet";
64 }
65 }
66}
diff --git a/ExportBot/Commands/Inventory/BalanceCommand.cs b/ExportBot/Commands/Inventory/BalanceCommand.cs
new file mode 100644
index 0000000..92e9b39
--- /dev/null
+++ b/ExportBot/Commands/Inventory/BalanceCommand.cs
@@ -0,0 +1,21 @@
1using System;
2using System.Collections.Generic;
3using libsecondlife;
4using libsecondlife.Packets;
5
6namespace libsecondlife.TestClient
7{
8 public class BalanceCommand: Command
9 {
10 public BalanceCommand(TestClient testClient)
11 {
12 Name = "balance";
13 Description = "Shows the amount of L$.";
14 }
15
16 public override string Execute(string[] args, LLUUID fromAgentID)
17 {
18 return Client.ToString() + " has L$: " + Client.Self.Balance;
19 }
20 }
21}
diff --git a/ExportBot/Commands/Inventory/DeleteFolderCommand.cs b/ExportBot/Commands/Inventory/DeleteFolderCommand.cs
new file mode 100644
index 0000000..ddbb86c
--- /dev/null
+++ b/ExportBot/Commands/Inventory/DeleteFolderCommand.cs
@@ -0,0 +1,43 @@
1using System;
2using System.Collections.Generic;
3using System.IO;
4using System.Text;
5using System.Threading;
6using System.Xml;
7using System.Xml.Serialization;
8
9using libsecondlife;
10using libsecondlife.Packets;
11using libsecondlife.InventorySystem;
12
13namespace libsecondlife.TestClient
14{
15 public class DeleteFolderCommand : Command
16 {
17 public DeleteFolderCommand(TestClient testClient)
18 {
19 Name = "deleteFolder";
20 Description = "Deletes a folder from inventory.";
21 }
22
23 public override string Execute(string[] args, LLUUID fromAgentID)
24 {
25 return "Broken until someone fixes me";
26
27 //string target = String.Empty;
28 //for (int ct = 0; ct < args.Length; ct++)
29 // target = target + args[ct] + " ";
30 //target = target.TrimEnd();
31
32 //Client.Inventory.DownloadInventory();
33 //InventoryFolder folder = Client.Inventory.getFolder(target);
34 //if (folder != null)
35 //{
36 // folder.Delete();
37 // return "Folder " + target + " deleted.";
38 //}
39
40 //return "Unable to find: " + target;
41 }
42 }
43} \ No newline at end of file
diff --git a/ExportBot/Commands/Inventory/GiveAllCommand.cs b/ExportBot/Commands/Inventory/GiveAllCommand.cs
new file mode 100644
index 0000000..fe42fce
--- /dev/null
+++ b/ExportBot/Commands/Inventory/GiveAllCommand.cs
@@ -0,0 +1,27 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4using libsecondlife;
5using libsecondlife.Packets;
6
7namespace libsecondlife.TestClient
8{
9 public class GiveAllCommand: Command
10 {
11 public GiveAllCommand(TestClient testClient)
12 {
13 Name = "giveAll";
14 Description = "Gives you all it's money.";
15 }
16
17 public override string Execute(string[] args, LLUUID fromAgentID)
18 {
19 if (fromAgentID == null)
20 return "Unable to send money to console. This command only works when IMed.";
21
22 int amount = Client.Self.Balance;
23 Client.Self.GiveMoney(fromAgentID, Client.Self.Balance, String.Empty);
24 return "Gave $" + amount + " to " + fromAgentID;
25 }
26 }
27}
diff --git a/ExportBot/Commands/Inventory/InventoryCommand.cs b/ExportBot/Commands/Inventory/InventoryCommand.cs
new file mode 100644
index 0000000..7b01bb1
--- /dev/null
+++ b/ExportBot/Commands/Inventory/InventoryCommand.cs
@@ -0,0 +1,62 @@
1using System;
2using System.Collections.Generic;
3using System.IO;
4using System.Text;
5using System.Threading;
6using System.Xml;
7using System.Xml.Serialization;
8
9using libsecondlife;
10using libsecondlife.Packets;
11using libsecondlife.InventorySystem;
12
13namespace libsecondlife.TestClient
14{
15 public class InventoryCommand : Command
16 {
17 public InventoryCommand(TestClient testClient)
18 {
19 Name = "i";
20 Description = "Prints out inventory.";
21 }
22
23 public override string Execute(string[] args, LLUUID fromAgentID)
24 {
25 return "Broken until someone fixes me";
26
27 //Client.Inventory.DownloadInventory();
28 //StringBuilder result = new StringBuilder();
29 //PrintFolder(Client.Inventory.GetRootFolder(), result, 0);
30 //return result.ToString();
31 }
32
33 //void PrintFolder(InventoryFolder folder, StringBuilder output, int indenting)
34 //{
35 // Indent(output, indenting);
36 // output.Append(folder.Name);
37 // output.Append("\n");
38 // foreach (InventoryBase b in folder.GetContents())
39 // {
40 // InventoryItem item = b as InventoryItem;
41 // if (item != null)
42 // {
43 // Indent(output, indenting + 1);
44 // output.Append(item.Name);
45 // output.Append("\n");
46 // continue;
47 // }
48 // InventoryFolder subFolder = b as InventoryFolder;
49 // if (subFolder != null)
50 // PrintFolder(subFolder, output, indenting + 1);
51 // }
52 //}
53
54 //void Indent(StringBuilder output, int indenting)
55 //{
56 // for (int count = 0; count < indenting; count++)
57 // {
58 // output.Append(" ");
59 // }
60 //}
61 }
62} \ No newline at end of file
diff --git a/ExportBot/Commands/Inventory/WearCommand.cs b/ExportBot/Commands/Inventory/WearCommand.cs
new file mode 100644
index 0000000..d1bc32c
--- /dev/null
+++ b/ExportBot/Commands/Inventory/WearCommand.cs
@@ -0,0 +1,43 @@
1using System;
2using System.Collections.Generic;
3using System.IO;
4using System.Text;
5using System.Threading;
6using System.Xml;
7using System.Xml.Serialization;
8
9using libsecondlife;
10using libsecondlife.Packets;
11using libsecondlife.InventorySystem;
12
13namespace libsecondlife.TestClient
14{
15 public class WearCommand : Command
16 {
17 public WearCommand(TestClient testClient)
18 {
19 Name = "wear";
20 Description = "Wear an outfit folder from inventory.";
21 }
22
23 public override string Execute(string[] args, LLUUID fromAgentID)
24 {
25 return "Broken until someone fixes me";
26
27 //string target = String.Empty;
28 //for (int ct = 0; ct < args.Length; ct++)
29 // target = target + args[ct] + " ";
30 //target = target.TrimEnd();
31
32 //Client.Inventory.DownloadInventory();
33 //InventoryFolder folder = Client.Inventory.getFolder(target);
34 //if (folder != null)
35 //{
36 // Client.Appearance.WearOutfit(folder);
37 // return "Outfit " + target + " worn.";
38 //}
39
40 //return "Unable to find: " + target;
41 }
42 }
43} \ No newline at end of file
diff --git a/ExportBot/Commands/LoadCommand.cs b/ExportBot/Commands/LoadCommand.cs
new file mode 100644
index 0000000..70dada4
--- /dev/null
+++ b/ExportBot/Commands/LoadCommand.cs
@@ -0,0 +1,28 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4using System.Reflection;
5using libsecondlife;
6using libsecondlife.Packets;
7
8namespace libsecondlife.TestClient
9{
10 public class LoadCommand: Command
11 {
12 public LoadCommand(TestClient testClient)
13 {
14 Name = "load";
15 Description = "Loads commands from a dll. (Usage: load AssemblyNameWithoutExtension)";
16 }
17
18 public override string Execute(string[] args, LLUUID fromAgentID)
19 {
20 if (args.Length < 1)
21 return "Usage: load AssemblyNameWithoutExtension";
22
23 string filename = AppDomain.CurrentDomain.BaseDirectory + args[0] + ".dll";
24 Client.RegisterAllCommands(Assembly.LoadFile(filename));
25 return "Assembly " + filename + " loaded.";
26 }
27 }
28}
diff --git a/ExportBot/Commands/LoginCommand.cs b/ExportBot/Commands/LoginCommand.cs
new file mode 100644
index 0000000..64675f5
--- /dev/null
+++ b/ExportBot/Commands/LoginCommand.cs
@@ -0,0 +1,34 @@
1using System;
2using System.Collections.Generic;
3using System.Reflection;
4using libsecondlife;
5using libsecondlife.Packets;
6
7namespace libsecondlife.TestClient
8{
9 public class LoginCommand : Command
10 {
11 public LoginCommand(TestClient testClient)
12 {
13 Name = "login";
14 Description = "Logs in another avatar";
15 }
16
17 public override string Execute(string[] args, LLUUID fromAgentID)
18 {
19 if (args.Length != 3 && args.Length != 4)
20 return "usage: login firstname lastname password [simname]";
21
22 SecondLife newClient = Client.ClientManager.Login(args);
23
24 if (newClient.Network.Connected)
25 {
26 return "Logged in " + newClient.ToString();
27 }
28 else
29 {
30 return "Failed to login: " + newClient.Network.LoginStatusMessage;
31 }
32 }
33 }
34}
diff --git a/ExportBot/Commands/LogoutCommand.cs b/ExportBot/Commands/LogoutCommand.cs
new file mode 100644
index 0000000..cdb5bde
--- /dev/null
+++ b/ExportBot/Commands/LogoutCommand.cs
@@ -0,0 +1,24 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4using libsecondlife;
5using libsecondlife.Packets;
6
7namespace libsecondlife.TestClient
8{
9 public class LogoutCommand : Command
10 {
11 public LogoutCommand(TestClient testClient)
12 {
13 Name = "logout";
14 Description = "Log this avatar out";
15 }
16
17 public override string Execute(string[] args, LLUUID fromAgentID)
18 {
19 string name = Client.ToString();
20 Client.ClientManager.Logout(Client);
21 return "Logged " + name + " out";
22 }
23 }
24}
diff --git a/ExportBot/Commands/MD5Command.cs b/ExportBot/Commands/MD5Command.cs
new file mode 100644
index 0000000..0a2ee5d
--- /dev/null
+++ b/ExportBot/Commands/MD5Command.cs
@@ -0,0 +1,22 @@
1using System;
2using libsecondlife;
3
4namespace libsecondlife.TestClient
5{
6 public class MD5Command : Command
7 {
8 public MD5Command(TestClient testClient)
9 {
10 Name = "md5";
11 Description = "Creates an MD5 hash from a given password. Usage: md5 [password]";
12 }
13
14 public override string Execute(string[] args, LLUUID fromAgentID)
15 {
16 if (args.Length == 1)
17 return Helpers.MD5(args[0]);
18 else
19 return "Usage: md5 [password]";
20 }
21 }
22}
diff --git a/ExportBot/Commands/Movement/FollowCommand.cs b/ExportBot/Commands/Movement/FollowCommand.cs
new file mode 100644
index 0000000..f5074a3
--- /dev/null
+++ b/ExportBot/Commands/Movement/FollowCommand.cs
@@ -0,0 +1,90 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4using libsecondlife;
5using libsecondlife.Packets;
6
7namespace libsecondlife.TestClient
8{
9 public class FollowCommand: Command
10 {
11 public FollowCommand(TestClient testClient)
12 {
13 Name = "follow";
14 Description = "Follow another avatar. (usage: follow [FirstName LastName]) If no target is set then will follow master.";
15 }
16
17 public override string Execute(string[] args, LLUUID fromAgentID)
18 {
19 string target = String.Empty;
20 for (int ct = 0; ct < args.Length; ct++)
21 target = target + args[ct] + " ";
22 target = target.TrimEnd();
23
24 if (target.Length > 0)
25 {
26 if (Follow(target))
27 return "Following " + target;
28 else
29 return "Unable to follow " + target + ". Client may not be able to see that avatar.";
30 }
31 else
32 {
33 if (Follow(Client.MasterKey))
34 return "Following " + Client.MasterKey;
35 else
36 return "No target specified and no master not found. usage: follow [FirstName LastName])";
37 }
38 }
39
40 const float DISTANCE_BUFFER = 3.0f;
41 Avatar followAvatar;
42
43 bool Follow(string name)
44 {
45 foreach (Avatar av in Client.AvatarList.Values)
46 {
47 if (av.Name == name)
48 {
49 followAvatar = av;
50 Active = true;
51 return true;
52 }
53 }
54 return false;
55 }
56
57 bool Follow(LLUUID id)
58 {
59 foreach (Avatar av in Client.AvatarList.Values)
60 {
61 if (av.ID == id)
62 {
63 followAvatar = av;
64 Active = true;
65 return true;
66 }
67 }
68 return false;
69 }
70
71 public override void Think()
72 {
73 if (Helpers.VecDist(followAvatar.Position, Client.Self.Position) > DISTANCE_BUFFER)
74 {
75 //move toward target
76 LLVector3 avPos = followAvatar.Position;
77 Client.Self.AutoPilot((ulong)avPos.X + (ulong)Client.regionX, (ulong)avPos.Y + (ulong)Client.regionY, avPos.Z);
78 }
79 //else
80 //{
81 // //stop at current position
82 // LLVector3 myPos = client.Self.Position;
83 // client.Self.AutoPilot((ulong)myPos.x, (ulong)myPos.y, myPos.Z);
84 //}
85
86 base.Think();
87 }
88
89 }
90}
diff --git a/ExportBot/Commands/Movement/GotoCommand.cs b/ExportBot/Commands/Movement/GotoCommand.cs
new file mode 100644
index 0000000..df2b8a7
--- /dev/null
+++ b/ExportBot/Commands/Movement/GotoCommand.cs
@@ -0,0 +1,53 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4using libsecondlife;
5using libsecondlife.Packets;
6
7namespace libsecondlife.TestClient
8{
9 public class GotoCommand: Command
10 {
11 public GotoCommand(TestClient testClient)
12 {
13 Name = "goto";
14 Description = "Teleport to a location (e.g. \"goto Hooper/100/100/30\")";
15 }
16
17 public override string Execute(string[] args, LLUUID fromAgentID)
18 {
19 if (args.Length < 1)
20 return "usage: Destination should be specified as sim/x/y/z";
21
22 string destination = String.Empty;
23
24 // Handle multi-word sim names by combining the arguments
25 foreach (string arg in args)
26 {
27 destination += arg + " ";
28 }
29 destination = destination.Trim();
30
31 string[] tokens = destination.Split(new char[] { '/' });
32 if (tokens.Length != 4)
33 return "usage: Destination should be specified as sim/x/y/z";
34
35 string sim = tokens[0];
36 float x = Client.Self.Position.X;
37 float y = Client.Self.Position.Y;
38 float z = Client.Self.Position.Z;
39 float.TryParse(tokens[1], out x);
40 float.TryParse(tokens[2], out y);
41 float.TryParse(tokens[3], out z);
42
43 if (Client.Self.Teleport(sim, new LLVector3(x, y, z)))
44 {
45 return "Teleported to " + Client.Network.CurrentSim;
46 }
47 else
48 {
49 return "Teleport failed: " + Client.Self.TeleportMessage;
50 }
51 }
52 }
53}
diff --git a/ExportBot/Commands/Movement/JumpCommand.cs b/ExportBot/Commands/Movement/JumpCommand.cs
new file mode 100644
index 0000000..29b11a0
--- /dev/null
+++ b/ExportBot/Commands/Movement/JumpCommand.cs
@@ -0,0 +1,34 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4using libsecondlife;
5using libsecondlife.Packets;
6
7namespace libsecondlife.TestClient
8{
9 public class JumpCommand: Command
10 {
11 public JumpCommand(TestClient testClient)
12 {
13 Name = "jump";
14 Description = "Teleports to the specified height. (e.g. \"jump 1000\")";
15 }
16
17 public override string Execute(string[] args, LLUUID fromAgentID)
18 {
19 if (args.Length != 1)
20 return "usage: jump 1000";
21
22 float height = 0;
23 float.TryParse(args[0], out height);
24
25 Client.Self.Teleport
26 (
27 Client.Network.CurrentSim.Name,
28 new LLVector3(Client.Self.Position.X, Client.Self.Position.Y, Client.Self.Position.Z + height)
29 );
30
31 return "Jumped " + height;
32 }
33 }
34}
diff --git a/ExportBot/Commands/Movement/LocationCommand.cs b/ExportBot/Commands/Movement/LocationCommand.cs
new file mode 100644
index 0000000..2fd62bb
--- /dev/null
+++ b/ExportBot/Commands/Movement/LocationCommand.cs
@@ -0,0 +1,23 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4using libsecondlife;
5using libsecondlife.Packets;
6
7namespace libsecondlife.TestClient
8{
9 public class LocationCommand: Command
10 {
11 public LocationCommand(TestClient testClient)
12 {
13 Name = "location";
14 Description = "Show the location.";
15 }
16
17 public override string Execute(string[] args, LLUUID fromAgentID)
18 {
19 return "CurrentSim: '" + Client.Network.CurrentSim.ToString() + "' Position: " +
20 Client.Self.Position.ToString();
21 }
22 }
23}
diff --git a/ExportBot/Commands/Movement/MoveToCommand.cs b/ExportBot/Commands/Movement/MoveToCommand.cs
new file mode 100644
index 0000000..6d0a225
--- /dev/null
+++ b/ExportBot/Commands/Movement/MoveToCommand.cs
@@ -0,0 +1,24 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4
5namespace libsecondlife.TestClient.Commands.Movement {
6 class MovetoCommand : Command {
7 public MovetoCommand(TestClient client) {
8 Name = "moveto";
9 Description = "Moves the avatar to the specified global position using simulator autopilot.";
10 }
11 public override string Execute(string[] args, LLUUID fromAgentID) {
12 if (args.Length != 3)
13 return "usage: moveto x y z";
14 float x = Client.Self.Position.X + Client.regionX;
15 float y = Client.Self.Position.Y + Client.regionY;
16 float z = Client.Self.Position.Z;
17 float.TryParse(args[0], out x);
18 float.TryParse(args[1], out y);
19 float.TryParse(args[2], out z);
20 Client.Self.AutoPilot((ulong)x, (ulong)y, z);
21 return "Attempting to move to <" + x + ", " + y + ", " + z + ">";
22 }
23 }
24}
diff --git a/ExportBot/Commands/Movement/SitCommand.cs b/ExportBot/Commands/Movement/SitCommand.cs
new file mode 100644
index 0000000..b9ef6be
--- /dev/null
+++ b/ExportBot/Commands/Movement/SitCommand.cs
@@ -0,0 +1,52 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4using libsecondlife;
5using libsecondlife.Packets;
6
7namespace libsecondlife.TestClient
8{
9 public class SitCommand: Command
10 {
11 public SitCommand(TestClient testClient)
12 {
13 Name = "sit";
14 Description = "Attempt to sit on the closest prim";
15 }
16
17 public override string Execute(string[] args, LLUUID fromAgentID)
18 {
19 Primitive closest = null;
20 double closestDistance = Double.MaxValue;
21
22 lock (Client.SimPrims)
23 {
24 if (Client.SimPrims.ContainsKey(Client.Network.CurrentSim))
25 {
26 foreach (Primitive p in Client.SimPrims[Client.Network.CurrentSim].Values)
27 {
28 float distance = Helpers.VecDist(Client.Self.Position, p.Position);
29
30 if (closest == null || distance < closestDistance)
31 {
32 closest = p;
33 closestDistance = distance;
34 }
35 }
36 }
37 }
38
39 if (closest != null)
40 {
41 Client.Self.RequestSit(closest.ID, LLVector3.Zero);
42 Client.Self.Sit();
43
44 return "Sat on " + closest.ID + ". Distance: " + closestDistance;
45 }
46 else
47 {
48 return "Couldn't find a nearby prim to sit on";
49 }
50 }
51 }
52}
diff --git a/ExportBot/Commands/Movement/SitOnCommand.cs b/ExportBot/Commands/Movement/SitOnCommand.cs
new file mode 100644
index 0000000..ec9d201
--- /dev/null
+++ b/ExportBot/Commands/Movement/SitOnCommand.cs
@@ -0,0 +1,54 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4using libsecondlife;
5using libsecondlife.Packets;
6
7namespace libsecondlife.TestClient
8{
9 public class SitOnCommand: Command
10 {
11 public SitOnCommand(TestClient testClient)
12 {
13 Name = "siton";
14 Description = "Attempt to sit on a particular prim, with specified UUID";
15 }
16
17 public override string Execute(string[] args, LLUUID fromAgentID)
18 {
19 LLObject targetSeat = null;
20
21 lock (Client.SimPrims)
22 {
23 if (Client.SimPrims.ContainsKey(Client.Network.CurrentSim))
24 {
25 foreach (LLObject p in Client.SimPrims[Client.Network.CurrentSim].Values)
26 {
27 try
28 {
29 if (p.ID == args[0])
30 targetSeat = p;
31 }
32 catch
33 {
34 // handle exception
35 return "Sorry, I don't think " + args[0] + " is a valid UUID. I'm unable to sit there.";
36 }
37 }
38 }
39 }
40
41 if (targetSeat != null)
42 {
43 Client.Self.RequestSit(targetSeat.ID, LLVector3.Zero);
44 Client.Self.Sit();
45
46 return "Sat on prim " + targetSeat.ID + ".";
47 }
48 else
49 {
50 return "Couldn't find specified prim to sit on";
51 }
52 }
53 }
54} \ No newline at end of file
diff --git a/ExportBot/Commands/Movement/StandCommand.cs b/ExportBot/Commands/Movement/StandCommand.cs
new file mode 100644
index 0000000..8a00552
--- /dev/null
+++ b/ExportBot/Commands/Movement/StandCommand.cs
@@ -0,0 +1,47 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4using libsecondlife;
5using libsecondlife.Packets;
6
7namespace libsecondlife.TestClient
8{
9 public class StandCommand: Command
10 {
11 public StandCommand(TestClient testClient)
12 {
13 Name = "stand";
14 Description = "Stand";
15 }
16
17 public override string Execute(string[] args, LLUUID fromAgentID)
18 {
19 Client.Self.Status.StandUp = true;
20 stand(Client);
21 return "Standing up.";
22 }
23
24 void stand(SecondLife client)
25 {
26 SendAgentUpdate(client, (uint)MainAvatar.ControlFlags.AGENT_CONTROL_STAND_UP);
27 }
28
29 const float DRAW_DISTANCE = 96.0f;
30 void SendAgentUpdate(SecondLife client, uint ControlID)
31 {
32 AgentUpdatePacket p = new AgentUpdatePacket();
33 p.AgentData.Far = DRAW_DISTANCE;
34 //LLVector3 myPos = client.Self.Position;
35 p.AgentData.CameraCenter = new LLVector3(0, 0, 0);
36 p.AgentData.CameraAtAxis = new LLVector3(0, 0, 0);
37 p.AgentData.CameraLeftAxis = new LLVector3(0, 0, 0);
38 p.AgentData.CameraUpAxis = new LLVector3(0, 0, 0);
39 p.AgentData.HeadRotation = new LLQuaternion(0, 0, 0, 1); ;
40 p.AgentData.BodyRotation = new LLQuaternion(0, 0, 0, 1); ;
41 p.AgentData.AgentID = client.Network.AgentID;
42 p.AgentData.SessionID = client.Network.SessionID;
43 p.AgentData.ControlFlags = ControlID;
44 client.Network.SendPacket(p);
45 }
46 }
47}
diff --git a/ExportBot/Commands/PacketLogCommand.cs b/ExportBot/Commands/PacketLogCommand.cs
new file mode 100644
index 0000000..827b147
--- /dev/null
+++ b/ExportBot/Commands/PacketLogCommand.cs
@@ -0,0 +1,84 @@
1using System;
2using System.Collections.Generic;
3using System.Xml;
4using libsecondlife;
5using libsecondlife.Packets;
6
7namespace libsecondlife.TestClient
8{
9 public class PacketLogCommand : Command
10 {
11 List<Packet> Packets = new List<Packet>();
12 bool Done = false;
13 int Count = 0;
14 int Total = 0;
15
16 public PacketLogCommand(TestClient testClient)
17 {
18 Name = "packetlog";
19 Description = "Logs a given number of packets to an xml file. Usage: packetlog 10 tenpackets.xml";
20 }
21
22 public override string Execute(string[] args, LLUUID fromAgentID)
23 {
24 if (args.Length != 2)
25 return "Usage: packetlog 10 tenpackets.xml";
26
27 XmlWriter writer;
28 NetworkManager.PacketCallback callback = new NetworkManager.PacketCallback(OnPacket);
29
30 Packets.Clear();
31 Done = false;
32 Count = 0;
33
34 try
35 {
36 Total = Int32.Parse(args[0]);
37 writer = XmlWriter.Create(args[1]);
38
39 Client.Network.RegisterCallback(PacketType.Default, callback);
40 }
41 catch (Exception e)
42 {
43 return "Usage: packetlog 10 tenpackets.xml (" + e + ")";
44 }
45
46 while (!Done)
47 {
48 System.Threading.Thread.Sleep(100);
49 }
50
51 Client.Network.UnregisterCallback(PacketType.Default, callback);
52
53 try
54 {
55 Helpers.PacketListToXml(Packets, writer);
56 }
57 catch (Exception e)
58 {
59 return "Serialization failed: " + e.ToString();
60 }
61
62 writer.Close();
63 Packets.Clear();
64
65 return "Exported " + Count + " packets to " + args[1];
66 }
67
68 private void OnPacket(Packet packet, Simulator simulator)
69 {
70 lock (Packets)
71 {
72 if (Count >= Total)
73 {
74 Done = true;
75 }
76 else
77 {
78 Packets.Add(packet);
79 Count++;
80 }
81 }
82 }
83 }
84}
diff --git a/ExportBot/Commands/ParcelInfoCommand.cs b/ExportBot/Commands/ParcelInfoCommand.cs
new file mode 100644
index 0000000..e4108a9
--- /dev/null
+++ b/ExportBot/Commands/ParcelInfoCommand.cs
@@ -0,0 +1,62 @@
1using System;
2using System.Collections.Generic;
3using System.Threading;
4using libsecondlife;
5using libsecondlife.Utilities;
6
7namespace libsecondlife.TestClient
8{
9 public class ParcelInfoCommand : Command
10 {
11 private ParcelDownloader ParcelDownloader;
12 private ManualResetEvent ParcelsDownloaded = new ManualResetEvent(false);
13 private int ParcelCount = 0;
14
15 public ParcelInfoCommand(TestClient testClient)
16 {
17 Name = "parcelinfo";
18 Description = "Prints out info about all the parcels in this simulator";
19
20 ParcelDownloader = new ParcelDownloader(testClient);
21 ParcelDownloader.OnParcelsDownloaded += new ParcelDownloader.ParcelsDownloadedCallback(Parcels_OnParcelsDownloaded);
22 testClient.Network.OnDisconnected += new NetworkManager.DisconnectedCallback(Network_OnDisconnected);
23 }
24
25 public override string Execute(string[] args, LLUUID fromAgentID)
26 {
27 ParcelDownloader.DownloadSimParcels(Client.Network.CurrentSim);
28
29 ParcelsDownloaded.Reset();
30 ParcelsDownloaded.WaitOne(20000, false);
31
32 if (Client.Network.CurrentSim != null)
33 return "Downloaded information for " + ParcelCount + " parcels in " + Client.Network.CurrentSim.Name;
34 else
35 return String.Empty;
36 }
37
38 void Parcels_OnParcelsDownloaded(Simulator simulator, Dictionary<int, Parcel> Parcels, int[,] map)
39 {
40 foreach (KeyValuePair<int, Parcel> parcel in Parcels)
41 {
42 WaterType type = ParcelDownloader.GetWaterType(map, parcel.Value.LocalID);
43 float delta = ParcelDownloader.GetHeightRange(map, parcel.Value.LocalID);
44 int deviation = ParcelDownloader.GetRectangularDeviation(parcel.Value.AABBMin, parcel.Value.AABBMax,
45 parcel.Value.Area);
46
47 Console.WriteLine("Parcels[{0}]: Name: \"{1}\", Description: \"{2}\" ACL Count: {3}, " +
48 "Location: {4}, Height Range: {5}, Shape Deviation: {6}", parcel.Key, parcel.Value.Name,
49 parcel.Value.Desc, parcel.Value.AccessList.Count, type.ToString(), delta, deviation);
50 }
51
52 ParcelCount = Parcels.Count;
53
54 ParcelsDownloaded.Set();
55 }
56
57 void Network_OnDisconnected(NetworkManager.DisconnectType reason, string message)
58 {
59 ParcelsDownloaded.Set();
60 }
61 }
62}
diff --git a/ExportBot/Commands/PrimCountCommand.cs b/ExportBot/Commands/PrimCountCommand.cs
new file mode 100644
index 0000000..8adc563
--- /dev/null
+++ b/ExportBot/Commands/PrimCountCommand.cs
@@ -0,0 +1,32 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4using libsecondlife;
5using libsecondlife.Packets;
6
7namespace libsecondlife.TestClient
8{
9 public class PrimCountCommand: Command
10 {
11 public PrimCountCommand(TestClient testClient)
12 {
13 Name = "primcount";
14 Description = "Shows the number of prims that have been received.";
15 }
16
17 public override string Execute(string[] args, LLUUID fromAgentID)
18 {
19 int count = 0;
20
21 lock (Client.SimPrims)
22 {
23 foreach (Dictionary<uint, Primitive> prims in Client.SimPrims.Values)
24 {
25 count += prims.Count;
26 }
27 }
28
29 return count.ToString();
30 }
31 }
32}
diff --git a/ExportBot/Commands/QuitCommand.cs b/ExportBot/Commands/QuitCommand.cs
new file mode 100644
index 0000000..4cd7209
--- /dev/null
+++ b/ExportBot/Commands/QuitCommand.cs
@@ -0,0 +1,24 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4using libsecondlife;
5using libsecondlife.Packets;
6
7namespace libsecondlife.TestClient
8{
9 public class QuitCommand: Command
10 {
11 public QuitCommand(TestClient testClient)
12 {
13 Name = "quit";
14 Description = "Log all avatars out and shut down";
15 }
16
17 public override string Execute(string[] args, LLUUID fromAgentID)
18 {
19 Client.ClientManager.LogoutAll();
20 Client.ClientManager.Running = false;
21 return "All avatars logged out";
22 }
23 }
24}
diff --git a/ExportBot/Commands/RegionInfoCommand.cs b/ExportBot/Commands/RegionInfoCommand.cs
new file mode 100644
index 0000000..7581137
--- /dev/null
+++ b/ExportBot/Commands/RegionInfoCommand.cs
@@ -0,0 +1,45 @@
1using System;
2using System.Text;
3using libsecondlife;
4
5namespace libsecondlife.TestClient
6{
7 public class RegionInfoCommand : Command
8 {
9 public RegionInfoCommand(TestClient testClient)
10 {
11 Name = "regioninfo";
12 Description = "Prints out info about all the current region";
13 }
14
15 public override string Execute(string[] args, LLUUID fromAgentID)
16 {
17 StringBuilder output = new StringBuilder();
18 output.AppendLine(Client.Network.CurrentSim.ToString());
19 output.Append("Access: ");
20 output.AppendLine(Client.Network.CurrentSim.Access.ToString());
21 output.Append("Flags: ");
22 output.AppendLine(Client.Network.CurrentSim.Flags.ToString());
23 output.Append("TerrainBase0: ");
24 output.AppendLine(Client.Network.CurrentSim.TerrainBase0.ToStringHyphenated());
25 output.Append("TerrainBase1: ");
26 output.AppendLine(Client.Network.CurrentSim.TerrainBase1.ToStringHyphenated());
27 output.Append("TerrainBase2: ");
28 output.AppendLine(Client.Network.CurrentSim.TerrainBase2.ToStringHyphenated());
29 output.Append("TerrainBase3: ");
30 output.AppendLine(Client.Network.CurrentSim.TerrainBase3.ToStringHyphenated());
31 output.Append("TerrainDetail0: ");
32 output.AppendLine(Client.Network.CurrentSim.TerrainDetail0.ToStringHyphenated());
33 output.Append("TerrainDetail1: ");
34 output.AppendLine(Client.Network.CurrentSim.TerrainDetail1.ToStringHyphenated());
35 output.Append("TerrainDetail2: ");
36 output.AppendLine(Client.Network.CurrentSim.TerrainDetail2.ToStringHyphenated());
37 output.Append("TerrainDetail3: ");
38 output.AppendLine(Client.Network.CurrentSim.TerrainDetail3.ToStringHyphenated());
39 output.Append("Water Height: ");
40 output.AppendLine(Client.Network.CurrentSim.WaterHeight.ToString());
41
42 return output.ToString();
43 }
44 }
45}
diff --git a/ExportBot/Commands/SetMasterCommand.cs b/ExportBot/Commands/SetMasterCommand.cs
new file mode 100644
index 0000000..a6ecbdc
--- /dev/null
+++ b/ExportBot/Commands/SetMasterCommand.cs
@@ -0,0 +1,73 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4using System.Threading;
5using libsecondlife;
6using libsecondlife.Packets;
7
8namespace libsecondlife.TestClient
9{
10 public class SetMasterCommand: Command
11 {
12 public DateTime Created = DateTime.Now;
13 private LLUUID resolvedMasterKey = LLUUID.Zero;
14 private ManualResetEvent keyResolution = new ManualResetEvent(false);
15 private LLUUID query = LLUUID.Zero;
16
17 public SetMasterCommand(TestClient testClient)
18 {
19 Name = "setMaster";
20 Description = "Sets the user name of the master user. The master user can IM to run commands.";
21
22 }
23
24 public override string Execute(string[] args, LLUUID fromAgentID)
25 {
26 string masterName = String.Empty;
27 for (int ct = 0; ct < args.Length;ct++)
28 masterName = masterName + args[ct] + " ";
29 masterName = masterName.TrimEnd();
30
31 if (masterName.Length == 0)
32 return "Usage setMaster name";
33
34 DirectoryManager.DirPeopleReplyCallback callback = new DirectoryManager.DirPeopleReplyCallback(KeyResolvHandler);
35 Client.Directory.OnDirPeopleReply += callback;
36 query = Client.Directory.StartPeopleSearch(DirectoryManager.DirFindFlags.People, masterName);
37 if (keyResolution.WaitOne(TimeSpan.FromMinutes(1), false))
38 {
39 Client.MasterKey = resolvedMasterKey;
40 keyResolution.Reset();
41 Client.Directory.OnDirPeopleReply -= callback;
42 }
43 else
44 {
45 keyResolution.Reset();
46 Client.Directory.OnDirPeopleReply -= callback;
47 return "Unable to obtain UUID for \"" + masterName + "\". Master unchanged.";
48 }
49
50
51 foreach (Avatar av in Client.AvatarList.Values)
52 {
53 if (av.ID == Client.MasterKey)
54 {
55 Client.Self.InstantMessage(av.ID, "You are now my master. IM me with \"help\" for a command list.");
56 break;
57 }
58 }
59
60 return "Master set to " + masterName + " (" + Client.MasterKey.ToStringHyphenated() + ")";
61 }
62
63 private void KeyResolvHandler(LLUUID queryid, List<DirectoryManager.AgentSearchData> matches)
64 {
65 if (query != queryid)
66 return;
67 // We can't handle ambiguities here as nicely as we can in ClientManager.
68 resolvedMasterKey = matches[0].AgentID;
69 keyResolution.Set();
70 query = LLUUID.Zero;
71 }
72 }
73}
diff --git a/ExportBot/Commands/SetMasterKeyCommand.cs b/ExportBot/Commands/SetMasterKeyCommand.cs
new file mode 100644
index 0000000..0085f79
--- /dev/null
+++ b/ExportBot/Commands/SetMasterKeyCommand.cs
@@ -0,0 +1,35 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4using libsecondlife;
5using libsecondlife.Packets;
6
7namespace libsecondlife.TestClient
8{
9 public class SetMasterKeyCommand : Command
10 {
11 public DateTime Created = DateTime.Now;
12
13 public SetMasterKeyCommand(TestClient testClient)
14 {
15 Name = "setMasterKey";
16 Description = "Sets the key of the master user. The master user can IM to run commands.";
17 }
18
19 public override string Execute(string[] args, LLUUID fromAgentID)
20 {
21 Client.MasterKey = LLUUID.Parse(args[0]);
22
23 foreach (Avatar av in Client.AvatarList.Values)
24 {
25 if (av.ID == Client.MasterKey)
26 {
27 Client.Self.InstantMessage(av.ID, "You are now my master. IM me with \"help\" for a command list.");
28 break;
29 }
30 }
31
32 return "Master set to " + Client.MasterKey;
33 }
34 }
35}
diff --git a/ExportBot/Commands/ShowEffectsCommand.cs b/ExportBot/Commands/ShowEffectsCommand.cs
new file mode 100644
index 0000000..c0b20a7
--- /dev/null
+++ b/ExportBot/Commands/ShowEffectsCommand.cs
@@ -0,0 +1,76 @@
1using System;
2using libsecondlife;
3
4namespace libsecondlife.TestClient
5{
6 public class ShowEffectsCommand : Command
7 {
8 bool ShowEffects = false;
9
10 public ShowEffectsCommand(TestClient testClient)
11 {
12 Name = "showeffects";
13 Description = "Prints out information for every viewer effect that is received. Usage: showeffects [on/off]";
14
15 testClient.Avatars.OnEffect += new AvatarManager.EffectCallback(Avatars_OnEffect);
16 testClient.Avatars.OnLookAt += new AvatarManager.LookAtCallback(Avatars_OnLookAt);
17 testClient.Avatars.OnPointAt += new AvatarManager.PointAtCallback(Avatars_OnPointAt);
18 }
19
20 public override string Execute(string[] args, LLUUID fromAgentID)
21 {
22 if (args.Length == 0)
23 {
24 ShowEffects = true;
25 return "Viewer effects will be shown on the console";
26 }
27 else if (args.Length == 1)
28 {
29 if (args[0] == "on")
30 {
31 ShowEffects = true;
32 return "Viewer effects will be shown on the console";
33 }
34 else
35 {
36 ShowEffects = false;
37 return "Viewer effects will not be shown";
38 }
39 }
40 else
41 {
42 return "Usage: showeffects [on/off]";
43 }
44 }
45
46 private void Avatars_OnPointAt(LLUUID sourceID, LLUUID targetID, LLVector3d targetPos,
47 MainAvatar.PointAtType pointType, float duration, LLUUID id)
48 {
49 if (ShowEffects)
50 Console.WriteLine(
51 "ViewerEffect [PointAt]: SourceID: {0} TargetID: {1} TargetPos: {2} Type: {3} Duration: {4} ID: {5}",
52 sourceID.ToStringHyphenated(), targetID.ToStringHyphenated(), targetPos, pointType, duration,
53 id.ToStringHyphenated());
54 }
55
56 private void Avatars_OnLookAt(LLUUID sourceID, LLUUID targetID, LLVector3d targetPos,
57 MainAvatar.LookAtType lookType, float duration, LLUUID id)
58 {
59 if (ShowEffects)
60 Console.WriteLine(
61 "ViewerEffect [LookAt]: SourceID: {0} TargetID: {1} TargetPos: {2} Type: {3} Duration: {4} ID: {5}",
62 sourceID.ToStringHyphenated(), targetID.ToStringHyphenated(), targetPos, lookType, duration,
63 id.ToStringHyphenated());
64 }
65
66 private void Avatars_OnEffect(MainAvatar.EffectType type, LLUUID sourceID, LLUUID targetID,
67 LLVector3d targetPos, float duration, LLUUID id)
68 {
69 if (ShowEffects)
70 Console.WriteLine(
71 "ViewerEffect [{0}]: SourceID: {1} TargetID: {2} TargetPos: {3} Duration: {4} ID: {5}",
72 type, sourceID.ToStringHyphenated(), targetID.ToStringHyphenated(), targetPos, duration,
73 id.ToStringHyphenated());
74 }
75 }
76}
diff --git a/ExportBot/Commands/StatsCommand.cs b/ExportBot/Commands/StatsCommand.cs
new file mode 100644
index 0000000..7835ec8
--- /dev/null
+++ b/ExportBot/Commands/StatsCommand.cs
@@ -0,0 +1,39 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4using libsecondlife;
5using libsecondlife.Packets;
6
7namespace libsecondlife.TestClient
8{
9 public class StatsCommand : Command
10 {
11 public StatsCommand(TestClient testClient)
12 {
13 Name = "stats";
14 Description = "Provide connection figures and statistics";
15 }
16
17 public override string Execute(string[] args, LLUUID fromAgentID)
18 {
19 StringBuilder output = new StringBuilder();
20
21 lock (Client.Network.Simulators)
22 {
23 for (int i = 0; i < Client.Network.Simulators.Count; i++)
24 {
25 Simulator sim = Client.Network.Simulators[i];
26
27 output.AppendLine(String.Format(
28 "[{0}] Dilation: {1} InBPS: {2} OutBPS: {3} ResentOut: {4} ResentIn: {5}",
29 sim.ToString(), sim.Dilation, sim.IncomingBPS, sim.OutgoingBPS, sim.ResentPackets,
30 sim.ReceivedResends));
31 }
32 }
33
34 output.Append("Packets in the queue: " + Client.Network.InboxCount);
35
36 return output.ToString();
37 }
38 }
39}
diff --git a/ExportBot/Commands/TouchCommand.cs b/ExportBot/Commands/TouchCommand.cs
new file mode 100644
index 0000000..4103d21
--- /dev/null
+++ b/ExportBot/Commands/TouchCommand.cs
@@ -0,0 +1,55 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4using libsecondlife;
5using libsecondlife.Packets;
6
7namespace libsecondlife.TestClient
8{
9 public class TouchCommand: Command
10 {
11 public TouchCommand(TestClient testClient)
12 {
13 Name = "touch";
14 Description = "Attempt to touch a prim with specified UUID";
15 }
16
17 public override string Execute(string[] args, LLUUID fromAgentID)
18 {
19 Primitive target = null;
20
21 lock (Client.SimPrims)
22 {
23 if (Client.SimPrims.ContainsKey(Client.Network.CurrentSim))
24 {
25 foreach (Primitive p in Client.SimPrims[Client.Network.CurrentSim].Values)
26 {
27 if (args.Length == 0)
28 return "You must specify a UUID of the prim.";
29
30 try
31 {
32 if (p.ID == args[0])
33 target = p;
34 }
35 catch
36 {
37 // handle exception
38 return "Sorry, I don't think " + args[0] + " is a valid UUID. I'm unable to touch it.";
39 }
40 }
41 }
42 }
43
44 if (target != null)
45 {
46 Client.Self.Touch(target.LocalID);
47 return "Touched prim " + target.ID + ".";
48 }
49 else
50 {
51 return "Couldn't find that prim.";
52 }
53 }
54 }
55} \ No newline at end of file
diff --git a/ExportBot/Commands/TreeCommand.cs b/ExportBot/Commands/TreeCommand.cs
new file mode 100644
index 0000000..2029e37
--- /dev/null
+++ b/ExportBot/Commands/TreeCommand.cs
@@ -0,0 +1,51 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4using libsecondlife;
5using libsecondlife.Packets;
6
7namespace libsecondlife.TestClient
8{
9 public class TreeCommand: Command
10 {
11 public TreeCommand(TestClient testClient)
12 {
13 Name = "tree";
14 Description = "Rez a tree.";
15 }
16
17 public override string Execute(string[] args, LLUUID fromAgentID)
18 {
19 if (args.Length == 1)
20 {
21 try
22 {
23 string treeName = args[0].Trim(new char[] { ' ' });
24 ObjectManager.Tree tree = (ObjectManager.Tree)Enum.Parse(typeof(ObjectManager.Tree), treeName);
25
26 LLVector3 treePosition = new LLVector3(Client.Self.Position.X, Client.Self.Position.Y,
27 Client.Self.Position.Z);
28 treePosition.Z += 3.0f;
29
30 Client.Objects.AddTree(Client.Network.CurrentSim, new LLVector3(0.5f, 0.5f, 0.5f),
31 LLQuaternion.Identity, treePosition, tree, Client.GroupID, false);
32
33 return "Attempted to rez a " + treeName + " tree";
34 }
35 catch (Exception)
36 {
37 return "Type !tree for usage";
38 }
39 }
40
41 string usage = "Usage: !tree [";
42 foreach (string value in Enum.GetNames(typeof(ObjectManager.Tree)))
43 {
44 usage += value + ",";
45 }
46 usage = usage.TrimEnd(new char[] { ',' });
47 usage += "]";
48 return usage;
49 }
50 }
51}
diff --git a/ExportBot/Commands/UptimeCommand.cs b/ExportBot/Commands/UptimeCommand.cs
new file mode 100644
index 0000000..3edec73
--- /dev/null
+++ b/ExportBot/Commands/UptimeCommand.cs
@@ -0,0 +1,25 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4using libsecondlife;
5using libsecondlife.Packets;
6
7namespace libsecondlife.TestClient
8{
9 public class UptimeCommand : Command
10 {
11 public DateTime Created = DateTime.Now;
12
13 public UptimeCommand(TestClient testClient)
14 {
15 Name = "uptime";
16 Description = "Shows the login name, login time and length of time logged on.";
17 }
18
19 public override string Execute(string[] args, LLUUID fromAgentID)
20 {
21 string name = Client.ToString();
22 return "I am " + name + ", Up Since: " + Created + " (" + (DateTime.Now - Created) + ")";
23 }
24 }
25} \ No newline at end of file
diff --git a/ExportBot/Commands/WhoCommand.cs b/ExportBot/Commands/WhoCommand.cs
new file mode 100644
index 0000000..83d8610
--- /dev/null
+++ b/ExportBot/Commands/WhoCommand.cs
@@ -0,0 +1,29 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4using libsecondlife;
5using libsecondlife.Packets;
6
7namespace libsecondlife.TestClient
8{
9 public class WhoCommand: Command
10 {
11 public WhoCommand(TestClient testClient)
12 {
13 Name = "who";
14 Description = "Lists seen avatars.";
15 }
16
17 public override string Execute(string[] args, LLUUID fromAgentID)
18 {
19 StringBuilder result = new StringBuilder();
20 foreach (Avatar av in Client.AvatarList.Values)
21 {
22 result.AppendFormat("\n{0} {1} {2}/{3} ID: {4}", av.Name, av.GroupName,
23 (av.CurrentSim != null ? av.CurrentSim.Name : String.Empty), av.Position, av.ID);
24 }
25
26 return result.ToString();
27 }
28 }
29}