diff --git a/libsecondlife/examples/GUITestClient/GUITestClient.cs b/libsecondlife/examples/GUITestClient/GUITestClient.cs
new file mode 100644
index 00000000..d3d9b2b1
--- /dev/null
+++ b/libsecondlife/examples/GUITestClient/GUITestClient.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Windows.Forms;
+
+namespace libsecondlife.GUITestClient
+{
+ static class Program
+ {
+ ///
+ /// The main entry point for the application.
+ ///
+ [STAThread]
+ static void Main()
+ {
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault(false);
+ Application.Run(new frmTestClient());
+ }
+ }
+}
\ No newline at end of file
diff --git a/libsecondlife/examples/GUITestClient/GUITestClient.csproj b/libsecondlife/examples/GUITestClient/GUITestClient.csproj
new file mode 100644
index 00000000..5b0eed25
--- /dev/null
+++ b/libsecondlife/examples/GUITestClient/GUITestClient.csproj
@@ -0,0 +1,87 @@
+
+
+ Debug
+ AnyCPU
+ 8.0.50727
+ 2.0
+ {9E0EE72D-AAA7-42EC-8E59-2C3EA5ED6D98}
+ WinExe
+ Properties
+ GUITestClient
+ GUITestClient
+
+
+ true
+ full
+ false
+ ..\..\..\bin\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ ..\..\..\bin\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+ Form
+
+
+ frmTestClient.cs
+
+
+
+
+
+
+ Designer
+ frmTestClient.cs
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+ Designer
+
+
+ True
+ Resources.resx
+ True
+
+
+ SettingsSingleFileGenerator
+ Settings.Designer.cs
+
+
+ True
+ Settings.settings
+ True
+
+
+
+
+ {D9CDEDFB-8169-4B03-B57F-0DF638F044EC}
+ libsecondlife
+
+
+
+
+
\ No newline at end of file
diff --git a/libsecondlife/examples/GUITestClient/Interface.cs b/libsecondlife/examples/GUITestClient/Interface.cs
new file mode 100644
index 00000000..c935dd0f
--- /dev/null
+++ b/libsecondlife/examples/GUITestClient/Interface.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Windows.Forms;
+using System.Collections.Generic;
+
+namespace libsecondlife.GUITestClient
+{
+ public abstract class Interface
+ {
+ public string Name;
+ public string Description;
+ public SecondLife Client;
+ public TabPage TabPage;
+
+ public abstract void Initialize();
+
+ public abstract void Paint(object sender, PaintEventArgs e);
+
+ ///
+ /// When set to true, think will be called.
+ ///
+ public bool Active;
+ }
+}
diff --git a/libsecondlife/examples/GUITestClient/Interfaces/HeightmapInterface.cs b/libsecondlife/examples/GUITestClient/Interfaces/HeightmapInterface.cs
new file mode 100644
index 00000000..4cf37378
--- /dev/null
+++ b/libsecondlife/examples/GUITestClient/Interfaces/HeightmapInterface.cs
@@ -0,0 +1,86 @@
+using System;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.Windows.Forms;
+using libsecondlife;
+
+namespace libsecondlife.GUITestClient
+{
+ public class HeightmapInterface : Interface
+ {
+ private PictureBox[,] Boxes = new PictureBox[16, 16];
+
+ public HeightmapInterface(frmTestClient testClient)
+ {
+ Name = "Heightmap";
+ Description = "Displays a graphical heightmap of the current simulator";
+ }
+
+ public override void Initialize()
+ {
+ Client.Terrain.OnLandPatch += new TerrainManager.LandPatchCallback(Terrain_OnLandPatch);
+ Client.Settings.STORE_LAND_PATCHES = true;
+
+ for (int y = 0; y < 16; y++)
+ {
+ for (int x = 0; x < 16; x++)
+ {
+ Boxes[x, y] = new System.Windows.Forms.PictureBox();
+ PictureBox box = Boxes[x, y];
+ ((System.ComponentModel.ISupportInitialize)(box)).BeginInit();
+ box.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+ box.Name = x + "," + y;
+ box.Location = new System.Drawing.Point(x * 16, y * 16);
+ box.Size = new System.Drawing.Size(16, 16);
+ box.Visible = true;
+ //box.MouseUp += new MouseEventHandler(box_MouseUp);
+ ((System.ComponentModel.ISupportInitialize)(box)).EndInit();
+
+ TabPage.Controls.Add(box);
+ }
+ }
+ }
+
+ public override void Paint(object sender, PaintEventArgs e)
+ {
+ ;
+ }
+
+ void Terrain_OnLandPatch(Simulator simulator, int x, int y, int width, float[] data)
+ {
+ if (x >= 16 || y >= 16)
+ {
+ Console.WriteLine("Bad patch coordinates, x = " + x + ", y = " + y);
+ return;
+ }
+
+ if (width != 16)
+ {
+ Console.WriteLine("Unhandled patch size " + width + "x" + width);
+ return;
+ }
+
+ Bitmap patch = new Bitmap(16, 16, PixelFormat.Format24bppRgb);
+
+ for (int yp = 0; yp < 16; yp++)
+ {
+ for (int xp = 0; xp < 16; xp++)
+ {
+ float height = data[yp * 16 + xp];
+ int colorVal = Helpers.FloatToByte(height, 0.0f, 60.0f);
+ int lesserVal = (int)((float)colorVal * 0.75f);
+ Color color;
+
+ if (height >= simulator.WaterHeight)
+ color = Color.FromArgb(lesserVal, colorVal, lesserVal);
+ else
+ color = Color.FromArgb(lesserVal, lesserVal, colorVal);
+
+ patch.SetPixel(xp, yp, color);
+ }
+ }
+
+ Boxes[x, y].Image = (Image)patch;
+ }
+ }
+}
diff --git a/libsecondlife/examples/GUITestClient/Properties/AssemblyInfo.cs b/libsecondlife/examples/GUITestClient/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000..77d43fdc
--- /dev/null
+++ b/libsecondlife/examples/GUITestClient/Properties/AssemblyInfo.cs
@@ -0,0 +1,33 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("GUITestClient")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Metaverse Industries LLC")]
+[assembly: AssemblyProduct("GUITestClient")]
+[assembly: AssemblyCopyright("Copyright © Metaverse Industries LLC 2007")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("07b6c35c-78c2-4850-8ece-d99e1284959f")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/libsecondlife/examples/GUITestClient/Properties/Resources.Designer.cs b/libsecondlife/examples/GUITestClient/Properties/Resources.Designer.cs
new file mode 100644
index 00000000..07df7ab5
--- /dev/null
+++ b/libsecondlife/examples/GUITestClient/Properties/Resources.Designer.cs
@@ -0,0 +1,63 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.42
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace GUITestClient.Properties {
+ using System;
+
+
+ ///
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ ///
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources() {
+ }
+
+ ///
+ /// Returns the cached ResourceManager instance used by this class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("GUITestClient.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/libsecondlife/examples/GUITestClient/Properties/Resources.resx b/libsecondlife/examples/GUITestClient/Properties/Resources.resx
new file mode 100644
index 00000000..ffecec85
--- /dev/null
+++ b/libsecondlife/examples/GUITestClient/Properties/Resources.resx
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/libsecondlife/examples/GUITestClient/Properties/Settings.Designer.cs b/libsecondlife/examples/GUITestClient/Properties/Settings.Designer.cs
new file mode 100644
index 00000000..a3ead552
--- /dev/null
+++ b/libsecondlife/examples/GUITestClient/Properties/Settings.Designer.cs
@@ -0,0 +1,26 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.42
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace GUITestClient.Properties {
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "8.0.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default {
+ get {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/libsecondlife/examples/GUITestClient/Properties/Settings.settings b/libsecondlife/examples/GUITestClient/Properties/Settings.settings
new file mode 100644
index 00000000..abf36c5d
--- /dev/null
+++ b/libsecondlife/examples/GUITestClient/Properties/Settings.settings
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/libsecondlife/examples/GUITestClient/frmTestClient.Designer.cs b/libsecondlife/examples/GUITestClient/frmTestClient.Designer.cs
new file mode 100644
index 00000000..15db6661
--- /dev/null
+++ b/libsecondlife/examples/GUITestClient/frmTestClient.Designer.cs
@@ -0,0 +1,154 @@
+namespace libsecondlife.GUITestClient
+{
+ partial class frmTestClient
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.tabControl = new System.Windows.Forms.TabControl();
+ this.tabLogin = new System.Windows.Forms.TabPage();
+ this.cmdConnect = new System.Windows.Forms.Button();
+ this.label3 = new System.Windows.Forms.Label();
+ this.txtPassword = new System.Windows.Forms.TextBox();
+ this.label2 = new System.Windows.Forms.Label();
+ this.txtLastName = new System.Windows.Forms.TextBox();
+ this.label1 = new System.Windows.Forms.Label();
+ this.txtFirstName = new System.Windows.Forms.TextBox();
+ this.tabControl.SuspendLayout();
+ this.tabLogin.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // tabControl
+ //
+ this.tabControl.Controls.Add(this.tabLogin);
+ this.tabControl.Location = new System.Drawing.Point(12, 12);
+ this.tabControl.Name = "tabControl";
+ this.tabControl.SelectedIndex = 0;
+ this.tabControl.Size = new System.Drawing.Size(400, 400);
+ this.tabControl.TabIndex = 0;
+ //
+ // tabLogin
+ //
+ this.tabLogin.Controls.Add(this.cmdConnect);
+ this.tabLogin.Controls.Add(this.label3);
+ this.tabLogin.Controls.Add(this.txtPassword);
+ this.tabLogin.Controls.Add(this.label2);
+ this.tabLogin.Controls.Add(this.txtLastName);
+ this.tabLogin.Controls.Add(this.label1);
+ this.tabLogin.Controls.Add(this.txtFirstName);
+ this.tabLogin.Location = new System.Drawing.Point(4, 22);
+ this.tabLogin.Name = "tabLogin";
+ this.tabLogin.Padding = new System.Windows.Forms.Padding(3);
+ this.tabLogin.Size = new System.Drawing.Size(392, 374);
+ this.tabLogin.TabIndex = 0;
+ this.tabLogin.Text = "Login";
+ this.tabLogin.UseVisualStyleBackColor = true;
+ //
+ // cmdConnect
+ //
+ this.cmdConnect.Location = new System.Drawing.Point(257, 181);
+ this.cmdConnect.Name = "cmdConnect";
+ this.cmdConnect.Size = new System.Drawing.Size(120, 24);
+ this.cmdConnect.TabIndex = 59;
+ this.cmdConnect.Text = "Connect";
+ this.cmdConnect.Click += new System.EventHandler(this.cmdConnect_Click);
+ //
+ // label3
+ //
+ this.label3.Location = new System.Drawing.Point(257, 139);
+ this.label3.Name = "label3";
+ this.label3.Size = new System.Drawing.Size(120, 16);
+ this.label3.TabIndex = 58;
+ this.label3.Text = "Password";
+ //
+ // txtPassword
+ //
+ this.txtPassword.Location = new System.Drawing.Point(257, 155);
+ this.txtPassword.Name = "txtPassword";
+ this.txtPassword.PasswordChar = '*';
+ this.txtPassword.Size = new System.Drawing.Size(120, 20);
+ this.txtPassword.TabIndex = 57;
+ //
+ // label2
+ //
+ this.label2.Location = new System.Drawing.Point(138, 139);
+ this.label2.Name = "label2";
+ this.label2.Size = new System.Drawing.Size(120, 16);
+ this.label2.TabIndex = 56;
+ this.label2.Text = "Last Name";
+ //
+ // txtLastName
+ //
+ this.txtLastName.Location = new System.Drawing.Point(138, 155);
+ this.txtLastName.Name = "txtLastName";
+ this.txtLastName.Size = new System.Drawing.Size(112, 20);
+ this.txtLastName.TabIndex = 55;
+ //
+ // label1
+ //
+ this.label1.Location = new System.Drawing.Point(12, 139);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(120, 16);
+ this.label1.TabIndex = 54;
+ this.label1.Text = "First Name";
+ //
+ // txtFirstName
+ //
+ this.txtFirstName.Location = new System.Drawing.Point(12, 155);
+ this.txtFirstName.Name = "txtFirstName";
+ this.txtFirstName.Size = new System.Drawing.Size(120, 20);
+ this.txtFirstName.TabIndex = 53;
+ //
+ // frmTestClient
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(427, 420);
+ this.Controls.Add(this.tabControl);
+ this.Name = "frmTestClient";
+ this.Text = "GUI Test Client";
+ this.Paint += new System.Windows.Forms.PaintEventHandler(this.frmTestClient_Paint);
+ this.tabControl.ResumeLayout(false);
+ this.tabLogin.ResumeLayout(false);
+ this.tabLogin.PerformLayout();
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.TabControl tabControl;
+ private System.Windows.Forms.TabPage tabLogin;
+ private System.Windows.Forms.Button cmdConnect;
+ private System.Windows.Forms.Label label3;
+ private System.Windows.Forms.TextBox txtPassword;
+ private System.Windows.Forms.Label label2;
+ private System.Windows.Forms.TextBox txtLastName;
+ private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.TextBox txtFirstName;
+ }
+}
+
diff --git a/libsecondlife/examples/GUITestClient/frmTestClient.cs b/libsecondlife/examples/GUITestClient/frmTestClient.cs
new file mode 100644
index 00000000..fbc05c70
--- /dev/null
+++ b/libsecondlife/examples/GUITestClient/frmTestClient.cs
@@ -0,0 +1,125 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using System.Reflection;
+using libsecondlife;
+
+namespace libsecondlife.GUITestClient
+{
+ public partial class frmTestClient : Form
+ {
+ private SecondLife Client = new SecondLife();
+ private Dictionary Interfaces = new Dictionary();
+
+ public frmTestClient()
+ {
+ Client.Settings.MULTIPLE_SIMS = false;
+
+ InitializeComponent();
+
+ RegisterAllPlugins(Assembly.GetExecutingAssembly());
+ EnablePlugins(false);
+ }
+
+ private void cmdConnect_Click(object sender, EventArgs e)
+ {
+ if (cmdConnect.Text == "Connect")
+ {
+ cmdConnect.Text = "Disconnect";
+ txtFirstName.Enabled = txtLastName.Enabled = txtPassword.Enabled = false;
+
+ if (Client.Network.Login(txtFirstName.Text, txtLastName.Text, txtPassword.Text, "GUITestClient",
+ "jhurliman@wsu.edu"))
+ {
+ EnablePlugins(true);
+ }
+ else
+ {
+ MessageBox.Show(this, String.Format("Error logging in ({0}): {1}", Client.Network.LoginErrorKey,
+ Client.Network.LoginMessage));
+ cmdConnect.Text = "Connect";
+ txtFirstName.Enabled = txtLastName.Enabled = txtPassword.Enabled = true;
+ EnablePlugins(false);
+ }
+ }
+ else
+ {
+ Client.Network.Logout();
+ cmdConnect.Text = "Connect";
+ txtFirstName.Enabled = txtLastName.Enabled = txtPassword.Enabled = true;
+ EnablePlugins(false);
+ }
+ }
+
+ private void EnablePlugins(bool enable)
+ {
+ tabControl.TabPages.Clear();
+ tabControl.TabPages.Add(tabLogin);
+
+ if (enable)
+ {
+ lock (Interfaces)
+ {
+ foreach (TabPage page in Interfaces.Values)
+ {
+ tabControl.TabPages.Add(page);
+ }
+ }
+ }
+ }
+
+ private void RegisterAllPlugins(Assembly assembly)
+ {
+ foreach (Type t in assembly.GetTypes())
+ {
+ try
+ {
+ if (t.IsSubclassOf(typeof(Interface)))
+ {
+ ConstructorInfo[] infos = t.GetConstructors();
+ Interface iface = (Interface)infos[0].Invoke(new object[] { this });
+ RegisterPlugin(iface);
+ }
+ }
+ catch (Exception e)
+ {
+ MessageBox.Show(e.ToString());
+ }
+ }
+ }
+
+ private void RegisterPlugin(Interface iface)
+ {
+ TabPage page = new TabPage();
+ tabControl.TabPages.Add(page);
+
+ iface.Client = Client;
+ iface.TabPage = page;
+
+ if (!Interfaces.ContainsKey(iface))
+ {
+ lock(Interfaces) Interfaces.Add(iface, page);
+ }
+
+ iface.Initialize();
+
+ page.Text = iface.Name;
+ page.ToolTipText = iface.Description;
+ }
+
+ private void frmTestClient_Paint(object sender, PaintEventArgs e)
+ {
+ lock (Interfaces)
+ {
+ foreach (Interface iface in Interfaces.Keys)
+ {
+ iface.Paint(sender, e);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/libsecondlife/examples/GUITestClient/frmTestClient.resx b/libsecondlife/examples/GUITestClient/frmTestClient.resx
new file mode 100644
index 00000000..ff31a6db
--- /dev/null
+++ b/libsecondlife/examples/GUITestClient/frmTestClient.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file