From c17074a64546db27084e76ccd1f57143bbd04ae5 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Sat, 25 Nov 2006 20:25:02 +0000 Subject: [PATCH] primexport: * Supports libprims and prim.blender output formats now * Less noisy output, doesn't warn about missing parent prims for attachments libsecondlife: * Cleaned up the AgentThrottle class, it's now accessible through SecondLife.Throttle * Fixed PrimObject null members * Fixed PrimFlexibleData invalid XML * Fixed invalid TextureAnimation XML * Speckled documentation here and there git-svn-id: http://libopenmetaverse.googlecode.com/svn/trunk@632 52acb1d6-8a22-11de-b505-999d5b087335 --- libsecondlife-cs/NetworkManager.cs | 50 +- libsecondlife-cs/ObjectManager.cs | 34 +- libsecondlife-cs/Prims.cs | 20 +- libsecondlife-cs/SecondLife.cs | 6 +- libsecondlife-cs/Textures.cs | 21 +- .../examples/primexport/frmPrimExport.cs | 487 ++++++++++++------ libsecondlife-cs/examples/sldump/sldump.cs | 11 +- 7 files changed, 431 insertions(+), 198 deletions(-) diff --git a/libsecondlife-cs/NetworkManager.cs b/libsecondlife-cs/NetworkManager.cs index 1c651dff..99570ec1 100644 --- a/libsecondlife-cs/NetworkManager.cs +++ b/libsecondlife-cs/NetworkManager.cs @@ -1441,22 +1441,29 @@ namespace libsecondlife /// public class AgentThrottle { - /// Maximum data rates for each type of data. Note that these are - /// actually in bytes per second, and not kbytes per second, as displayed - /// by the original client. + /// Maximum bytes per second for resending unacknowledged packets public float Resend; + /// Maximum bytes per second for LayerData terrain public float Land; + /// Maximum bytes per second for LayerData wind data public float Wind; + /// Maximum bytes per second for LayerData clouds public float Cloud; + /// Unknown, includes object data public float Task; + /// Maximum bytes per second for textures public float Texture; + /// Maximum bytes per second for downloaded assets public float Asset; + /// Maximum bytes per second the entire connection, divided up + /// between invidiual streams using default multipliers public float Total { get { return Resend + Land + Wind + Cloud + Task + Texture + Asset; } set { + // These sane initial values were pulled from the Second Life client Resend = (value * 0.1f); Land = (float)(value * 0.52f / 3f); Wind = (float)(value * 0.05f); @@ -1467,13 +1474,28 @@ namespace libsecondlife } } + private SecondLife Client; + /// - /// + /// Default constructor, uses a default high total of 1500 KBps (1536000) /// - public AgentThrottle(float total_val) + public AgentThrottle(SecondLife client) { - // note that the client itself never seems to go below 75k, even if you tell it to - Total = total_val; + Client = client; + Total = 1536000.0f; + } + + /// + /// Sets the total KBps throttle + /// The total kilobytes per second for the connection. + /// This will be divided up between the various stream types using the + /// default multipliers + /// + public AgentThrottle(SecondLife client, float total) + { + Client = client; + // Note that the client itself never seems to go below 75k, even if you tell it to + Total = total; } /// @@ -1497,15 +1519,19 @@ namespace libsecondlife Asset = BitConverter.ToSingle(data, pos); } - public void Send(SecondLife client) + /// + /// Send an AgentThrottle packet to the server using the current values + /// + public void Set() { AgentThrottlePacket throttle = new AgentThrottlePacket(); - throttle.AgentData.AgentID = client.Network.AgentID; - throttle.AgentData.SessionID = client.Network.SessionID; - throttle.AgentData.CircuitCode = client.Network.CurrentSim.CircuitCode; + throttle.AgentData.AgentID = Client.Network.AgentID; + throttle.AgentData.SessionID = Client.Network.SessionID; + throttle.AgentData.CircuitCode = Client.Network.CurrentSim.CircuitCode; throttle.Throttle.GenCounter = 0; throttle.Throttle.Throttles = this.ToBytes(); - client.Network.SendPacket(throttle); + + Client.Network.SendPacket(throttle); } /// diff --git a/libsecondlife-cs/ObjectManager.cs b/libsecondlife-cs/ObjectManager.cs index e868862c..41b853cb 100644 --- a/libsecondlife-cs/ObjectManager.cs +++ b/libsecondlife-cs/ObjectManager.cs @@ -765,7 +765,8 @@ namespace libsecondlife foreach (ObjectUpdatePacket.ObjectDataBlock block in update.ObjectData) { - switch (block.PCode) + byte pcode = block.PCode; + switch (pcode) { case (byte)PCode.Grass: case (byte)PCode.Tree: @@ -1044,7 +1045,6 @@ namespace libsecondlife (block.Data[i++] << 16) + (block.Data[i++] << 24)); byte pcode = block.Data[i++]; - if (pcode == (byte)PCode.Prim) { #region Prim @@ -1066,12 +1066,15 @@ namespace libsecondlife if ((flags & CompressedFlags.Tree) != 0) { - // FIXME: Are we sure this is a Tree/Foliage flag? Wouldn't the PCode be - // different if it was? - byte TreeData = block.Data[i++]; + // FIXME: I don't think this is even Tree data, as it would have + // a different PCode. Figure out what this flag is and how to + // decode it + byte Unknown1 = block.Data[i++]; + byte Unknown2 = block.Data[i++]; - // TODO: Unknown byte - i++; + Client.Log("Compressed object with Tree flag set: " + Environment.NewLine + + "Unknown byte 1: " + Unknown1 + Environment.NewLine + + "Unknown byte 2: " + Unknown2, Helpers.LogLevel.Debug); } if ((flags & CompressedFlags.HasParent) != 0) @@ -1163,6 +1166,7 @@ namespace libsecondlife if ((flags & CompressedFlags.Unknown1) != 0) { + // TODO: Is this even a valid flag? Client.Log("Compressed object with Unknown1 flag set: " + Environment.NewLine + "Flags: " + flags.ToString() + Environment.NewLine + Helpers.FieldToString(block.Data), Helpers.LogLevel.Debug); @@ -1170,9 +1174,10 @@ namespace libsecondlife if ((flags & CompressedFlags.Unknown2) != 0) { - Client.Log("Compressed object with Unknown2 flag set: " + Environment.NewLine + - "Flags: " + flags.ToString() + Environment.NewLine + - Helpers.FieldToString(block.Data), Helpers.LogLevel.Debug); + // FIXME: Implement CompressedFlags.Unknown2 + //Client.Log("Compressed object with Unknown2 flag set: " + Environment.NewLine + + // "Flags: " + flags.ToString() + Environment.NewLine + + // Helpers.FieldToString(block.Data), Helpers.LogLevel.Debug); } prim.PathCurve = (uint)block.Data[i++]; @@ -1232,15 +1237,14 @@ namespace libsecondlife } #endregion Prim } - else if (pcode == (byte)PCode.Grass || pcode == (byte)PCode.Tree) + else if (pcode == (byte)PCode.Grass || pcode == (byte)PCode.Tree || pcode == (byte)PCode.NewTree) { - // TODO: Add new_tree and any other tree-like prims - Client.Log("######### Got an ObjectUpdateCompressed for grass/tree, implement this! #########", - Helpers.LogLevel.Debug); + // FIXME: Implement this + //Client.Log("######### Got an ObjectUpdateCompressed for grass/tree, implement this! #########", + // Helpers.LogLevel.Debug); } else { - // TODO: ... Client.Log("######### Got an ObjectUpdateCompressed for PCode=" + pcode.ToString() + ", implement this! #########", Helpers.LogLevel.Debug); } diff --git a/libsecondlife-cs/Prims.cs b/libsecondlife-cs/Prims.cs index eb56abac..f378236f 100644 --- a/libsecondlife-cs/Prims.cs +++ b/libsecondlife-cs/Prims.cs @@ -65,7 +65,7 @@ namespace libsecondlife /// public string Name = ""; /// - public string Description; + public string Description = ""; /// public float PathShearX = 0; /// @@ -122,6 +122,10 @@ namespace libsecondlife Light = new PrimLightData(); ParticleSys = new ParticleSystem(); Textures = new TextureEntry(); + TextureAnim = new TextureAnimation(); + Flexible = new PrimFlexibleData(); + Light = new PrimLightData(); + ParticleSys = new ParticleSystem(); } /// @@ -411,7 +415,7 @@ namespace libsecondlife /// public string GetXml() { - string xml = ""; + string xml = ""; xml += ""; xml += ""; xml += ""; @@ -449,7 +453,7 @@ namespace libsecondlife xml += Flexible.GetXml("Flexible"); xml += Light.GetXml("Light"); xml += ParticleSys.GetXml("ParticleSys"); - xml += ""; + xml += ""; return xml; } @@ -587,11 +591,11 @@ namespace libsecondlife public string GetXml(string name) { string xml = "<" + name + ">"; - xml += ""; - xml += ""; - xml += ""; - xml += ""; - xml += ""; + xml += ""; + xml += ""; + xml += ""; + xml += ""; + xml += ""; xml += ""; return xml; diff --git a/libsecondlife-cs/SecondLife.cs b/libsecondlife-cs/SecondLife.cs index 46d65d52..affce339 100644 --- a/libsecondlife-cs/SecondLife.cs +++ b/libsecondlife-cs/SecondLife.cs @@ -62,6 +62,8 @@ namespace libsecondlife public ObjectManager Objects; /// Group Subsystem public GroupManager Groups; + /// Throttling Subsystem + public AgentThrottle Throttle; /// Image Subsystem private ImageManager _ImageManager; @@ -89,7 +91,7 @@ namespace libsecondlife /// public event LogCallback OnLogMessage; /// Debug flag - public bool Debug; + public bool Debug = true; /// /// Constructor. @@ -103,7 +105,7 @@ namespace libsecondlife Grid = new GridManager(this); Objects = new ObjectManager(this); Groups = new GroupManager(this); - Debug = true; + Throttle = new AgentThrottle(this); } /// diff --git a/libsecondlife-cs/Textures.cs b/libsecondlife-cs/Textures.cs index dcb18f85..6a363116 100644 --- a/libsecondlife-cs/Textures.cs +++ b/libsecondlife-cs/Textures.cs @@ -792,6 +792,13 @@ namespace libsecondlife /// public float Rate; + /// + /// Default constructor + /// + public TextureAnimation() + { + } + /// /// /// @@ -821,13 +828,13 @@ namespace libsecondlife public string GetXml(string name) { string xml = ""; - xml += "" + Flags + ""; - xml += "" + Face + ""; - xml += "" + SizeX + ""; - xml += "" + SizeY + ""; - xml += "" + Start + ""; - xml += "" + Length + ""; - xml += "" + Rate + ""; + xml += ""; + xml += ""; + xml += ""; + xml += ""; + xml += ""; + xml += ""; + xml += ""; xml += ""; return xml; diff --git a/libsecondlife-cs/examples/primexport/frmPrimExport.cs b/libsecondlife-cs/examples/primexport/frmPrimExport.cs index 22db002a..9cba3372 100644 --- a/libsecondlife-cs/examples/primexport/frmPrimExport.cs +++ b/libsecondlife-cs/examples/primexport/frmPrimExport.cs @@ -22,16 +22,24 @@ namespace primexport private TextBox txtFirstName; private Button cmdExport; private TextBox txtLog; - /// - /// Required designer variable. - /// + private Label label4; + private Label label5; + private Panel panel1; + private RadioButton radObjects; + private RadioButton radEntireSim; + private Panel panel2; + private RadioButton radPrimBlender; + private RadioButton radLibPrims; private System.ComponentModel.IContainer components = null; + // private SecondLife client; - private ObjectManager.NewPrimCallback primCallback; - private string currentText; - private Dictionary Prims; + private Dictionary Prims = new Dictionary(); + private List Avatars = new List(); + private List Attachments = new List(); + private string CurrentText = ""; private string Filename = ""; + private bool EntireSim = true; /// /// Clean up any resources being used. @@ -64,7 +72,17 @@ namespace primexport this.txtFirstName = new System.Windows.Forms.TextBox(); this.cmdExport = new System.Windows.Forms.Button(); this.txtLog = new System.Windows.Forms.TextBox(); + this.label4 = new System.Windows.Forms.Label(); + this.label5 = new System.Windows.Forms.Label(); + this.panel1 = new System.Windows.Forms.Panel(); + this.radObjects = new System.Windows.Forms.RadioButton(); + this.radEntireSim = new System.Windows.Forms.RadioButton(); + this.panel2 = new System.Windows.Forms.Panel(); + this.radPrimBlender = new System.Windows.Forms.RadioButton(); + this.radLibPrims = new System.Windows.Forms.RadioButton(); this.grpLogin.SuspendLayout(); + this.panel1.SuspendLayout(); + this.panel2.SuspendLayout(); this.SuspendLayout(); // // grpLogin @@ -77,7 +95,7 @@ namespace primexport this.grpLogin.Controls.Add(this.cmdConnect); this.grpLogin.Controls.Add(this.txtFirstName); this.grpLogin.Enabled = false; - this.grpLogin.Location = new System.Drawing.Point(12, 204); + this.grpLogin.Location = new System.Drawing.Point(12, 322); this.grpLogin.Name = "grpLogin"; this.grpLogin.Size = new System.Drawing.Size(560, 80); this.grpLogin.TabIndex = 51; @@ -140,36 +158,125 @@ namespace primexport // // cmdExport // - this.cmdExport.Location = new System.Drawing.Point(12, 12); + this.cmdExport.Location = new System.Drawing.Point(452, 33); this.cmdExport.Name = "cmdExport"; - this.cmdExport.Size = new System.Drawing.Size(560, 49); + this.cmdExport.Size = new System.Drawing.Size(120, 24); this.cmdExport.TabIndex = 52; this.cmdExport.Text = "Export Prims"; this.cmdExport.Click += new System.EventHandler(this.cmdExport_Click); // // txtLog // - this.txtLog.Location = new System.Drawing.Point(12, 67); + this.txtLog.Location = new System.Drawing.Point(12, 63); this.txtLog.Multiline = true; this.txtLog.Name = "txtLog"; this.txtLog.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; - this.txtLog.Size = new System.Drawing.Size(560, 131); + this.txtLog.Size = new System.Drawing.Size(560, 253); this.txtLog.TabIndex = 53; // + // label4 + // + this.label4.AutoSize = true; + this.label4.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label4.Location = new System.Drawing.Point(12, 9); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(40, 13); + this.label4.TabIndex = 56; + this.label4.Text = "Export:"; + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label5.Location = new System.Drawing.Point(12, 40); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(42, 13); + this.label5.TabIndex = 59; + this.label5.Text = "Format:"; + // + // panel1 + // + this.panel1.Controls.Add(this.radObjects); + this.panel1.Controls.Add(this.radEntireSim); + this.panel1.Location = new System.Drawing.Point(67, 0); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(194, 31); + this.panel1.TabIndex = 60; + // + // radObjects + // + this.radObjects.AutoSize = true; + this.radObjects.Enabled = false; + this.radObjects.Location = new System.Drawing.Point(81, 8); + this.radObjects.Name = "radObjects"; + this.radObjects.Size = new System.Drawing.Size(97, 17); + this.radObjects.TabIndex = 57; + this.radObjects.Text = "Object/Linkjset"; + this.radObjects.UseVisualStyleBackColor = true; + // + // radEntireSim + // + this.radEntireSim.AutoSize = true; + this.radEntireSim.Checked = true; + this.radEntireSim.Location = new System.Drawing.Point(3, 8); + this.radEntireSim.Name = "radEntireSim"; + this.radEntireSim.Size = new System.Drawing.Size(72, 17); + this.radEntireSim.TabIndex = 56; + this.radEntireSim.TabStop = true; + this.radEntireSim.Text = "Entire Sim"; + this.radEntireSim.UseVisualStyleBackColor = true; + // + // panel2 + // + this.panel2.Controls.Add(this.radPrimBlender); + this.panel2.Controls.Add(this.radLibPrims); + this.panel2.Location = new System.Drawing.Point(67, 31); + this.panel2.Name = "panel2"; + this.panel2.Size = new System.Drawing.Size(288, 31); + this.panel2.TabIndex = 61; + // + // radPrimBlender + // + this.radPrimBlender.AutoSize = true; + this.radPrimBlender.Location = new System.Drawing.Point(68, 7); + this.radPrimBlender.Name = "radPrimBlender"; + this.radPrimBlender.Size = new System.Drawing.Size(168, 17); + this.radPrimBlender.TabIndex = 60; + this.radPrimBlender.Text = "prim.Blender (currently broken)"; + this.radPrimBlender.UseVisualStyleBackColor = true; + // + // radLibPrims + // + this.radLibPrims.AutoSize = true; + this.radLibPrims.Checked = true; + this.radLibPrims.Location = new System.Drawing.Point(3, 7); + this.radLibPrims.Name = "radLibPrims"; + this.radLibPrims.Size = new System.Drawing.Size(59, 17); + this.radLibPrims.TabIndex = 59; + this.radLibPrims.TabStop = true; + this.radLibPrims.Text = "libprims"; + this.radLibPrims.UseVisualStyleBackColor = true; + // // frmPrimExport // - this.ClientSize = new System.Drawing.Size(587, 299); + this.ClientSize = new System.Drawing.Size(587, 414); + this.Controls.Add(this.panel2); + this.Controls.Add(this.panel1); + this.Controls.Add(this.label5); + this.Controls.Add(this.label4); this.Controls.Add(this.txtLog); this.Controls.Add(this.cmdExport); this.Controls.Add(this.grpLogin); this.MaximizeBox = false; - this.MaximumSize = new System.Drawing.Size(595, 326); - this.MinimumSize = new System.Drawing.Size(595, 326); this.Name = "frmPrimExport"; this.Text = "Prim Exporter"; this.TopMost = true; this.grpLogin.ResumeLayout(false); this.grpLogin.PerformLayout(); + this.panel1.ResumeLayout(false); + this.panel1.PerformLayout(); + this.panel2.ResumeLayout(false); + this.panel2.PerformLayout(); this.ResumeLayout(false); this.PerformLayout(); @@ -191,25 +298,24 @@ namespace primexport { InitializeComponent(); - primCallback = new ObjectManager.NewPrimCallback(PrimSeen); - Prims = new Dictionary(); - client = new SecondLife(); client.OnLogMessage += new LogCallback(client_OnLogMessage); client.Objects.RequestAllObjects = true; - client.Objects.OnNewPrim += primCallback; + client.Objects.OnNewPrim += new ObjectManager.NewPrimCallback(PrimSeen); + client.Objects.OnNewAvatar += new ObjectManager.NewAvatarCallback(AvatarSeen); + client.Objects.OnNewAttachment += new ObjectManager.NewAttachmentCallback(AttachmentSeen); grpLogin.Enabled = true; } void client_OnLogMessage(string message, Helpers.LogLevel level) { - Log("libsl: " + level.ToString() + ": " + message); + Log("libsl: " + level.ToString() + ": " + message + Environment.NewLine); } private void Log(string text) { - currentText = text; + CurrentText = text; lock (txtLog) { @@ -226,7 +332,7 @@ namespace primexport private void UpdateLog() { - txtLog.AppendText(currentText + Environment.NewLine); + txtLog.AppendText(CurrentText); } private void PrimSeen(Simulator simulator, PrimObject prim, ulong regionHandle, ushort timeDilation) @@ -239,7 +345,23 @@ namespace primexport } Prims.Add(prim.LocalID, prim); - Log("Saw prim " + prim.ID.ToString()); + Log("."); + } + } + + void AttachmentSeen(Simulator simulator, PrimObject prim, ulong regionHandle, ushort timeDilation) + { + lock (Attachments) + { + Attachments.Add(prim.LocalID); + } + } + + void AvatarSeen(Simulator simulator, Avatar avatar, ulong regionHandle, ushort timeDilation) + { + lock (Avatars) + { + Avatars.Add(avatar.LocalID); } } @@ -253,137 +375,20 @@ namespace primexport file = new FileStream(Filename, FileMode.Create); stream = new StreamWriter(file); - uint type = 0; - string output; - - stream.WriteLine(""); - - lock (Prims) + if (radLibPrims.Checked) { - foreach (PrimObject prim in Prims.Values) - { - LLVector3 position = prim.Position; - LLQuaternion rotation = prim.Rotation; - - output = ""; - - if (prim.ParentID != 0) - { - // This prim is part of a linkset, we need to adjust it's position and rotation - if (Prims.ContainsKey(prim.ParentID)) - { - // The child prim only stores a relative position, add the world position of the parent prim - position += Prims[prim.ParentID].Position; - - // The child prim only stores a relative rotation, start with the parent prim rotation - rotation = rotation * Prims[prim.ParentID].Rotation; - } - else - { - // We don't have the base position for this child prim, can't render it - Log("Couldn't export child prim " + prim.ID.ToString() + ", parent prim is missing"); - continue; - } - } - - output += "" + Environment.NewLine; - output += "falsefalsefalse" + Environment.NewLine; - output += "" + Environment.NewLine + - "" + Environment.NewLine; - - switch (prim.ProfileCurve + prim.PathCurve) - { - case 17: - // PRIM_TYPE_BOX - type = 0; - break; - case 16: - // PRIM_TYPE_CYLINDER - type = 1; - break; - case 19: - // PRIM_TYPE_PRISM - type = 2; - break; - case 37: - // PRIM_TYPE_SPHERE - type = 3; - break; - case 32: - // PRIM_TYPE_TORUS - type = 4; - break; - case 33: - // PRIM_TYPE_TUBE - type = 5; - break; - case 35: - // PRIM_TYPE_RING - type = 6; - break; - default: - Log("Not exporting an unhandled prim, ProfileCurve=" + - prim.ProfileCurve + ", PathCurve=" + prim.PathCurve); - continue; - } - - output += "" + Environment.NewLine; - output += "" + Environment.NewLine; - output += "" + Environment.NewLine; - output += "" + Environment.NewLine; - - if (type == 1) - { - output += "" + Environment.NewLine; - output += "" + Environment.NewLine; - } - else - { - output += "" + Environment.NewLine; - output += "" + Environment.NewLine; - } - - output += "" + Environment.NewLine; - output += "" + Environment.NewLine; - output += "" + Environment.NewLine; - output += "" + Environment.NewLine; - output += "" + Environment.NewLine; - output += "" + Environment.NewLine; - output += "" + Environment.NewLine; - output += "" + Environment.NewLine; - output += "" + Environment.NewLine; - output += "" + Environment.NewLine; - output += "" + Environment.NewLine; - // TODO: Hollowshape. 16-21 = circle, 32-37 = square, 48-53 = triangle - output += "" + Environment.NewLine; - - output += "" + - "" + - "" + - "" + Environment.NewLine + - "" + Environment.NewLine + - "" + Environment.NewLine; - - stream.WriteLine(output); - } + ExportLibPrims(stream); + } + else + { + ExportPrimBlender(stream); } - - stream.WriteLine(""); } catch (Exception e) { MessageBox.Show("There was an error writing the prims file, check the log for details", "primexport Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - Log("Error writing prims to " + Filename + ": " + e.ToString()); + Log("Error writing prims to " + Filename + ": " + e.ToString() + Environment.NewLine); } finally { @@ -393,6 +398,171 @@ namespace primexport } } + private void ExportPrimBlender(StreamWriter stream) + { + uint type = 0; + string output; + + lock (Prims) + { + stream.WriteLine(""); + + foreach (PrimObject prim in Prims.Values) + { + LLVector3 position = prim.Position; + LLQuaternion rotation = prim.Rotation; + + output = ""; + + if (prim.ParentID != 0) + { + // This prim is part of a linkset, we need to adjust it's position and rotation + if (Prims.ContainsKey(prim.ParentID)) + { + // The child prim only stores a relative position, add the world position of the parent prim + position += Prims[prim.ParentID].Position; + + // The child prim only stores a relative rotation, start with the parent prim rotation + rotation = rotation * Prims[prim.ParentID].Rotation; + } + else if (Avatars.Contains(prim.ParentID) || Attachments.Contains(prim.ParentID)) + { + // Skip this + } + else + { + // We don't have the base position for this child prim, can't render it + Log("Couldn't export child prim " + prim.ID.ToString() + ", parent prim is missing" + + Environment.NewLine); + continue; + } + } + + output += "" + Environment.NewLine; + output += "falsefalsefalse" + Environment.NewLine; + output += "" + Environment.NewLine + + "" + Environment.NewLine; + + switch (prim.ProfileCurve + prim.PathCurve) + { + case 17: + // PRIM_TYPE_BOX + type = 0; + break; + case 16: + // PRIM_TYPE_CYLINDER + type = 1; + break; + case 19: + // PRIM_TYPE_PRISM + type = 2; + break; + case 37: + // PRIM_TYPE_SPHERE + type = 3; + break; + case 32: + // PRIM_TYPE_TORUS + type = 4; + break; + case 33: + // PRIM_TYPE_TUBE + type = 5; + break; + case 35: + // PRIM_TYPE_RING + type = 6; + break; + default: + Log("Not exporting an unhandled prim, ProfileCurve=" + + prim.ProfileCurve + ", PathCurve=" + prim.PathCurve + Environment.NewLine); + continue; + } + + output += "" + Environment.NewLine; + output += "" + Environment.NewLine; + output += "" + Environment.NewLine; + output += "" + Environment.NewLine; + + if (type == 1) + { + output += "" + Environment.NewLine; + output += "" + Environment.NewLine; + } + else + { + output += "" + Environment.NewLine; + output += "" + Environment.NewLine; + } + + output += "" + Environment.NewLine; + output += "" + Environment.NewLine; + output += "" + Environment.NewLine; + output += "" + Environment.NewLine; + output += "" + Environment.NewLine; + output += "" + Environment.NewLine; + output += "" + Environment.NewLine; + output += "" + Environment.NewLine; + output += "" + Environment.NewLine; + output += "" + Environment.NewLine; + output += "" + Environment.NewLine; + // FIXME: Hollowshape. 16-21 = circle, 32-37 = square, 48-53 = triangle + output += "" + Environment.NewLine; + + output += "" + + "" + + "" + + "" + Environment.NewLine + + "" + Environment.NewLine + + "" + Environment.NewLine; + + stream.WriteLine(output); + } + } + + stream.WriteLine(""); + } + + private void ExportLibPrims(StreamWriter stream) + { + lock (Prims) + { + stream.WriteLine(""); + + foreach (PrimObject prim in Prims.Values) + { + if (prim.ParentID != 0) + { + // This prim is part of a linkset, we need to adjust it's position and rotation + if (Prims.ContainsKey(prim.ParentID)) + { + stream.WriteLine(prim.GetXml()); + } + else if (Avatars.Contains(prim.ParentID) || Attachments.Contains(prim.ParentID)) + { + // Skip this + } + else + { + // We don't have the base position for this child prim, can't render it + Log("Couldn't export child prim " + prim.ID.ToString() + ", parent prim is missing" + + Environment.NewLine); + } + } + } + + stream.WriteLine(""); + } + } + private void cmdConnect_Click(object sender, EventArgs e) { if (cmdConnect.Text == "Connect") @@ -400,8 +570,17 @@ namespace primexport cmdConnect.Text = "Disconnect"; txtFirstName.Enabled = txtLastName.Enabled = txtPassword.Enabled = false; - if (!client.Network.Login(txtFirstName.Text, txtLastName.Text, txtPassword.Text, + if (client.Network.Login(txtFirstName.Text, txtLastName.Text, txtPassword.Text, "primexport", "jhurliman@wsu.edu")) + { + client.Throttle.Asset = 0; + client.Throttle.Cloud = 0; + client.Throttle.Land = 0; + client.Throttle.Texture = 0; + client.Throttle.Wind = 0; + client.Throttle.Set(); + } + else { MessageBox.Show(this, "Error logging in: " + client.Network.LoginError); cmdConnect.Text = "Connect"; @@ -411,6 +590,7 @@ namespace primexport else { client.Network.Logout(); + cmdConnect.Text = "Connect"; txtFirstName.Enabled = txtLastName.Enabled = txtPassword.Enabled = true; } @@ -419,11 +599,22 @@ namespace primexport private void cmdExport_Click(object sender, EventArgs e) { SaveFileDialog save = new SaveFileDialog(); - save.Filter = "Prim.Blender files (*.prims)|*.prims"; + + if (radLibPrims.Checked) + { + save.Filter = "libprims files (*.xml)|*.xml"; + } + else + { + save.Filter = "Prim.Blender files (*.prims)|*.prims"; + } + save.RestoreDirectory = true; if (save.ShowDialog() == DialogResult.OK) { + EntireSim = radEntireSim.Checked; + Filename = save.FileName; cmdExport.Enabled = false; Invoke(new MethodInvoker(ExportPrims)); diff --git a/libsecondlife-cs/examples/sldump/sldump.cs b/libsecondlife-cs/examples/sldump/sldump.cs index 67fbea0e..35cffa5a 100644 --- a/libsecondlife-cs/examples/sldump/sldump.cs +++ b/libsecondlife-cs/examples/sldump/sldump.cs @@ -117,12 +117,11 @@ namespace sldump Console.WriteLine("Message of the day: " + client.Network.LoginValues["message"]); // Throttle packets that we don't want all the way down - AgentThrottle throttle = new AgentThrottle(50000); - throttle.Land = 0; - throttle.Wind = 0; - throttle.Cloud = 0; - throttle.Texture = 0; - throttle.Send(client); + client.Throttle.Land = 0; + client.Throttle.Wind = 0; + client.Throttle.Cloud = 0; + client.Throttle.Texture = 0; + client.Throttle.Set(); int start = Environment.TickCount; int milliseconds = Int32.Parse(args[3]) * 1000;