Moved programs into the Programs folder
git-svn-id: http://libopenmetaverse.googlecode.com/svn/trunk@1958 52acb1d6-8a22-11de-b505-999d5b087335
This commit is contained in:
33
Programs/SLImageUpload/Properties/AssemblyInfo.cs
Normal file
33
Programs/SLImageUpload/Properties/AssemblyInfo.cs
Normal file
@@ -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("SLImageUpload")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Metaverse Industries LLC")]
|
||||
[assembly: AssemblyProduct("SLImageUpload")]
|
||||
[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("d8a0ec17-daf9-4a17-b72f-d32ed7f6962a")]
|
||||
|
||||
// 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")]
|
||||
71
Programs/SLImageUpload/Properties/Resources.Designer.cs
generated
Normal file
71
Programs/SLImageUpload/Properties/Resources.Designer.cs
generated
Normal file
@@ -0,0 +1,71 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// 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.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace SLImageUpload.Properties
|
||||
{
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// 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()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager
|
||||
{
|
||||
get
|
||||
{
|
||||
if ((resourceMan == null))
|
||||
{
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SLImageUpload.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture
|
||||
{
|
||||
get
|
||||
{
|
||||
return resourceCulture;
|
||||
}
|
||||
set
|
||||
{
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
117
Programs/SLImageUpload/Properties/Resources.resx
Normal file
117
Programs/SLImageUpload/Properties/Resources.resx
Normal file
@@ -0,0 +1,117 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
30
Programs/SLImageUpload/Properties/Settings.Designer.cs
generated
Normal file
30
Programs/SLImageUpload/Properties/Settings.Designer.cs
generated
Normal file
@@ -0,0 +1,30 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// 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.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace SLImageUpload.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
7
Programs/SLImageUpload/Properties/Settings.settings
Normal file
7
Programs/SLImageUpload/Properties/Settings.settings
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
|
||||
<Profiles>
|
||||
<Profile Name="(Default)" />
|
||||
</Profiles>
|
||||
<Settings />
|
||||
</SettingsFile>
|
||||
84
Programs/SLImageUpload/SLImageUpload.build
Normal file
84
Programs/SLImageUpload/SLImageUpload.build
Normal file
@@ -0,0 +1,84 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<project name="libsecondlife" default="build">
|
||||
|
||||
<!-- global framework settings -->
|
||||
<property name="target.framework" value="${framework::get-target-framework()}" />
|
||||
<property name="assembly.dir" value="${framework::get-assembly-directory(target.framework)}" />
|
||||
|
||||
<!-- global project settings -->
|
||||
<xmlpeek
|
||||
file="../libsecondlife.build"
|
||||
xpath="/project/property[@name = 'project.version']/@value"
|
||||
property="project.version" />
|
||||
<property name="build.number"
|
||||
value="${math::abs(math::floor(timespan::get-total-days(datetime::now()
|
||||
- datetime::parse('01/01/2002'))))}" />
|
||||
<property name="assembly" value="SLImageUpload"/>
|
||||
<property name="bin_dir" value="../bin" />
|
||||
|
||||
<!-- default configuration -->
|
||||
<property name="project.config" value="debug" /> <!-- debug|release -->
|
||||
|
||||
<!-- named configurations -->
|
||||
<target name="init" description="Initializes build properties">
|
||||
<call target="${project.config}" />
|
||||
</target>
|
||||
|
||||
<target name="debug" description="configures a debug build">
|
||||
<property name="build.debug" value="true" />
|
||||
<property name="package.name"
|
||||
value="${project::get-name()}-${project.version}-${project.config}" />
|
||||
<property name="assembly.configuration"
|
||||
value="${framework::get-target-framework()}.${platform::get-name()} [${project.config}]" />
|
||||
</target>
|
||||
|
||||
<target name="release" description="configures a release build">
|
||||
<property name="project.config" value="release" />
|
||||
<property name="build.debug" value="false" />
|
||||
<property name="package.name"
|
||||
value="${project::get-name()}-${project.version}" />
|
||||
<property name="assembly.configuration"
|
||||
value="${framework::get-target-framework()}.${platform::get-name()}" />
|
||||
</target>
|
||||
|
||||
<!-- build tasks -->
|
||||
<target name="build" depends="build-main"
|
||||
description="Main build target">
|
||||
</target>
|
||||
|
||||
<target name="build-main" depends="init"
|
||||
description="Builds the binaries for the current configuration">
|
||||
<echo message="Build Directory is ${bin_dir}/" />
|
||||
<mkdir dir="${bin_dir}" failonerror="false" />
|
||||
<csc
|
||||
target="exe"
|
||||
debug="${build.debug}"
|
||||
output="${bin_dir}/SLImageUpload.exe">
|
||||
<sources failonempty="true">
|
||||
<include name="*.cs" />
|
||||
</sources>
|
||||
<references basedir="${bin_dir}/">
|
||||
<include name="libsecondlife.dll"/>
|
||||
<include name="System.Data.dll" />
|
||||
<include name="System.Drawing.dll" />
|
||||
<include name="System.Windows.Forms.dll" />
|
||||
</references>
|
||||
</csc>
|
||||
</target>
|
||||
|
||||
<target name="clean" depends="init"
|
||||
description="Deletes the current configuration">
|
||||
<delete failonerror="false">
|
||||
<fileset basedir="${bin_dir}/">
|
||||
<include name="SLImageUpload.exe" />
|
||||
</fileset>
|
||||
</delete>
|
||||
</target>
|
||||
|
||||
<target
|
||||
name="*"
|
||||
description="Handles unknown targets">
|
||||
<echo message="skipping unknown target" />
|
||||
</target>
|
||||
</project>
|
||||
20
Programs/SLImageUpload/SLImageUpload.cs
Normal file
20
Programs/SLImageUpload/SLImageUpload.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace SLImageUpload
|
||||
{
|
||||
static class SLImageUpload
|
||||
{
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static void Main()
|
||||
{
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.Run(new frmSLImageUpload());
|
||||
}
|
||||
}
|
||||
}
|
||||
95
Programs/SLImageUpload/SLImageUpload.csproj
Normal file
95
Programs/SLImageUpload/SLImageUpload.csproj
Normal file
@@ -0,0 +1,95 @@
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.50727</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{F3BDC0BC-74EB-451E-8FFE-AA162474F2F2}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>SLImageUpload</RootNamespace>
|
||||
<AssemblyName>SLImageUpload</AssemblyName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>..\bin\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\bin\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release-docs|AnyCPU' ">
|
||||
<OutputPath>bin\Release-docs\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<CodeAnalysisRuleAssemblies>C:\Program Files\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop\\rules</CodeAnalysisRuleAssemblies>
|
||||
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
|
||||
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Deployment" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="frmSLImageUpload.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="frmSLImageUpload.Designer.cs">
|
||||
<DependentUpon>frmSLImageUpload.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="SLImageUpload.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<EmbeddedResource Include="frmSLImageUpload.resx">
|
||||
<SubType>Designer</SubType>
|
||||
<DependentUpon>frmSLImageUpload.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<Compile Include="Properties\Settings.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\libsecondlife\OpenMetaverse.csproj">
|
||||
<Project>{D9CDEDFB-8169-4B03-B57F-0DF638F044EC}</Project>
|
||||
<Name>OpenMetaverse</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
279
Programs/SLImageUpload/frmSLImageUpload.Designer.cs
generated
Normal file
279
Programs/SLImageUpload/frmSLImageUpload.Designer.cs
generated
Normal file
@@ -0,0 +1,279 @@
|
||||
namespace SLImageUpload
|
||||
{
|
||||
partial class frmSLImageUpload
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.grpLogin = new System.Windows.Forms.GroupBox();
|
||||
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.grpUpload = new System.Windows.Forms.GroupBox();
|
||||
this.txtAssetID = new System.Windows.Forms.TextBox();
|
||||
this.label4 = new System.Windows.Forms.Label();
|
||||
this.lblSize = new System.Windows.Forms.Label();
|
||||
this.prgUpload = new System.Windows.Forms.ProgressBar();
|
||||
this.picPreview = new System.Windows.Forms.PictureBox();
|
||||
this.cmdLoad = new System.Windows.Forms.Button();
|
||||
this.txtSendtoName = new System.Windows.Forms.TextBox();
|
||||
this.label6 = new System.Windows.Forms.Label();
|
||||
this.chkLossless = new System.Windows.Forms.CheckBox();
|
||||
this.cmdUpload = new System.Windows.Forms.Button();
|
||||
this.grpLogin.SuspendLayout();
|
||||
this.grpUpload.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picPreview)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// grpLogin
|
||||
//
|
||||
this.grpLogin.Controls.Add(this.cmdConnect);
|
||||
this.grpLogin.Controls.Add(this.label3);
|
||||
this.grpLogin.Controls.Add(this.txtPassword);
|
||||
this.grpLogin.Controls.Add(this.label2);
|
||||
this.grpLogin.Controls.Add(this.txtLastName);
|
||||
this.grpLogin.Controls.Add(this.label1);
|
||||
this.grpLogin.Controls.Add(this.txtFirstName);
|
||||
this.grpLogin.Location = new System.Drawing.Point(11, 260);
|
||||
this.grpLogin.Name = "grpLogin";
|
||||
this.grpLogin.Size = new System.Drawing.Size(379, 101);
|
||||
this.grpLogin.TabIndex = 67;
|
||||
this.grpLogin.TabStop = false;
|
||||
//
|
||||
// cmdConnect
|
||||
//
|
||||
this.cmdConnect.Location = new System.Drawing.Point(251, 62);
|
||||
this.cmdConnect.Name = "cmdConnect";
|
||||
this.cmdConnect.Size = new System.Drawing.Size(120, 24);
|
||||
this.cmdConnect.TabIndex = 3;
|
||||
this.cmdConnect.Text = "Connect";
|
||||
this.cmdConnect.Click += new System.EventHandler(this.cmdConnect_Click);
|
||||
//
|
||||
// label3
|
||||
//
|
||||
this.label3.Location = new System.Drawing.Point(251, 20);
|
||||
this.label3.Name = "label3";
|
||||
this.label3.Size = new System.Drawing.Size(120, 16);
|
||||
this.label3.TabIndex = 72;
|
||||
this.label3.Text = "Password";
|
||||
//
|
||||
// txtPassword
|
||||
//
|
||||
this.txtPassword.Location = new System.Drawing.Point(251, 36);
|
||||
this.txtPassword.Name = "txtPassword";
|
||||
this.txtPassword.PasswordChar = '*';
|
||||
this.txtPassword.Size = new System.Drawing.Size(120, 20);
|
||||
this.txtPassword.TabIndex = 2;
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.Location = new System.Drawing.Point(132, 20);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(120, 16);
|
||||
this.label2.TabIndex = 70;
|
||||
this.label2.Text = "Last Name";
|
||||
//
|
||||
// txtLastName
|
||||
//
|
||||
this.txtLastName.Location = new System.Drawing.Point(132, 36);
|
||||
this.txtLastName.Name = "txtLastName";
|
||||
this.txtLastName.Size = new System.Drawing.Size(112, 20);
|
||||
this.txtLastName.TabIndex = 1;
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.Location = new System.Drawing.Point(6, 20);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(120, 16);
|
||||
this.label1.TabIndex = 68;
|
||||
this.label1.Text = "First Name";
|
||||
//
|
||||
// txtFirstName
|
||||
//
|
||||
this.txtFirstName.Location = new System.Drawing.Point(6, 36);
|
||||
this.txtFirstName.Name = "txtFirstName";
|
||||
this.txtFirstName.Size = new System.Drawing.Size(120, 20);
|
||||
this.txtFirstName.TabIndex = 0;
|
||||
//
|
||||
// grpUpload
|
||||
//
|
||||
this.grpUpload.Controls.Add(this.txtAssetID);
|
||||
this.grpUpload.Controls.Add(this.label4);
|
||||
this.grpUpload.Controls.Add(this.lblSize);
|
||||
this.grpUpload.Controls.Add(this.prgUpload);
|
||||
this.grpUpload.Controls.Add(this.picPreview);
|
||||
this.grpUpload.Controls.Add(this.cmdLoad);
|
||||
this.grpUpload.Controls.Add(this.txtSendtoName);
|
||||
this.grpUpload.Controls.Add(this.label6);
|
||||
this.grpUpload.Controls.Add(this.chkLossless);
|
||||
this.grpUpload.Controls.Add(this.cmdUpload);
|
||||
this.grpUpload.Location = new System.Drawing.Point(12, 12);
|
||||
this.grpUpload.Name = "grpUpload";
|
||||
this.grpUpload.Size = new System.Drawing.Size(379, 242);
|
||||
this.grpUpload.TabIndex = 68;
|
||||
this.grpUpload.TabStop = false;
|
||||
//
|
||||
// txtAssetID
|
||||
//
|
||||
this.txtAssetID.Location = new System.Drawing.Point(90, 204);
|
||||
this.txtAssetID.Name = "txtAssetID";
|
||||
this.txtAssetID.ReadOnly = true;
|
||||
this.txtAssetID.Size = new System.Drawing.Size(280, 20);
|
||||
this.txtAssetID.TabIndex = 8;
|
||||
this.txtAssetID.TabStop = false;
|
||||
//
|
||||
// label4
|
||||
//
|
||||
this.label4.AutoSize = true;
|
||||
this.label4.Location = new System.Drawing.Point(6, 207);
|
||||
this.label4.Name = "label4";
|
||||
this.label4.Size = new System.Drawing.Size(66, 13);
|
||||
this.label4.TabIndex = 79;
|
||||
this.label4.Text = "Asset UUID:";
|
||||
//
|
||||
// lblSize
|
||||
//
|
||||
this.lblSize.AutoSize = true;
|
||||
this.lblSize.Location = new System.Drawing.Point(79, 96);
|
||||
this.lblSize.Name = "lblSize";
|
||||
this.lblSize.Size = new System.Drawing.Size(0, 13);
|
||||
this.lblSize.TabIndex = 77;
|
||||
//
|
||||
// prgUpload
|
||||
//
|
||||
this.prgUpload.Location = new System.Drawing.Point(9, 175);
|
||||
this.prgUpload.Name = "prgUpload";
|
||||
this.prgUpload.Size = new System.Drawing.Size(362, 23);
|
||||
this.prgUpload.TabIndex = 76;
|
||||
//
|
||||
// picPreview
|
||||
//
|
||||
this.picPreview.Location = new System.Drawing.Point(9, 96);
|
||||
this.picPreview.Name = "picPreview";
|
||||
this.picPreview.Size = new System.Drawing.Size(64, 64);
|
||||
this.picPreview.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
|
||||
this.picPreview.TabIndex = 75;
|
||||
this.picPreview.TabStop = false;
|
||||
//
|
||||
// cmdLoad
|
||||
//
|
||||
this.cmdLoad.Location = new System.Drawing.Point(160, 136);
|
||||
this.cmdLoad.Name = "cmdLoad";
|
||||
this.cmdLoad.Size = new System.Drawing.Size(102, 24);
|
||||
this.cmdLoad.TabIndex = 6;
|
||||
this.cmdLoad.Text = "Load Texture";
|
||||
this.cmdLoad.UseVisualStyleBackColor = true;
|
||||
this.cmdLoad.Click += new System.EventHandler(this.cmdLoad_Click);
|
||||
//
|
||||
// txtSendtoName
|
||||
//
|
||||
this.txtSendtoName.Location = new System.Drawing.Point(131, 64);
|
||||
this.txtSendtoName.Name = "txtSendtoName";
|
||||
this.txtSendtoName.Size = new System.Drawing.Size(239, 20);
|
||||
this.txtSendtoName.TabIndex = 5;
|
||||
//
|
||||
// label6
|
||||
//
|
||||
this.label6.AutoSize = true;
|
||||
this.label6.Location = new System.Drawing.Point(6, 67);
|
||||
this.label6.Name = "label6";
|
||||
this.label6.Size = new System.Drawing.Size(112, 13);
|
||||
this.label6.TabIndex = 71;
|
||||
this.label6.Text = "Send Copy To Avatar:";
|
||||
//
|
||||
// chkLossless
|
||||
//
|
||||
this.chkLossless.Location = new System.Drawing.Point(9, 19);
|
||||
this.chkLossless.Name = "chkLossless";
|
||||
this.chkLossless.Size = new System.Drawing.Size(362, 37);
|
||||
this.chkLossless.TabIndex = 4;
|
||||
this.chkLossless.Text = "Single Layer Lossless (only useful for pixel perfect reproductions of small image" +
|
||||
"s, such as sculpt maps)";
|
||||
this.chkLossless.UseVisualStyleBackColor = true;
|
||||
this.chkLossless.CheckedChanged += new System.EventHandler(this.chkLossless_CheckedChanged);
|
||||
//
|
||||
// cmdUpload
|
||||
//
|
||||
this.cmdUpload.Enabled = false;
|
||||
this.cmdUpload.Location = new System.Drawing.Point(268, 136);
|
||||
this.cmdUpload.Name = "cmdUpload";
|
||||
this.cmdUpload.Size = new System.Drawing.Size(103, 24);
|
||||
this.cmdUpload.TabIndex = 7;
|
||||
this.cmdUpload.Text = "Upload Texture";
|
||||
this.cmdUpload.UseVisualStyleBackColor = true;
|
||||
this.cmdUpload.Click += new System.EventHandler(this.cmdUpload_Click);
|
||||
//
|
||||
// frmSLImageUpload
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(402, 373);
|
||||
this.Controls.Add(this.grpUpload);
|
||||
this.Controls.Add(this.grpLogin);
|
||||
this.MaximizeBox = false;
|
||||
this.MaximumSize = new System.Drawing.Size(410, 400);
|
||||
this.MinimumSize = new System.Drawing.Size(410, 400);
|
||||
this.Name = "frmSLImageUpload";
|
||||
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
|
||||
this.Text = "SL Image Upload";
|
||||
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.frmSLImageUpload_FormClosed);
|
||||
this.grpLogin.ResumeLayout(false);
|
||||
this.grpLogin.PerformLayout();
|
||||
this.grpUpload.ResumeLayout(false);
|
||||
this.grpUpload.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picPreview)).EndInit();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.GroupBox grpLogin;
|
||||
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;
|
||||
private System.Windows.Forms.GroupBox grpUpload;
|
||||
private System.Windows.Forms.Button cmdUpload;
|
||||
private System.Windows.Forms.CheckBox chkLossless;
|
||||
private System.Windows.Forms.TextBox txtSendtoName;
|
||||
private System.Windows.Forms.Label label6;
|
||||
private System.Windows.Forms.PictureBox picPreview;
|
||||
private System.Windows.Forms.Button cmdLoad;
|
||||
private System.Windows.Forms.ProgressBar prgUpload;
|
||||
private System.Windows.Forms.Label lblSize;
|
||||
private System.Windows.Forms.TextBox txtAssetID;
|
||||
private System.Windows.Forms.Label label4;
|
||||
}
|
||||
}
|
||||
|
||||
390
Programs/SLImageUpload/frmSLImageUpload.cs
Normal file
390
Programs/SLImageUpload/frmSLImageUpload.cs
Normal file
@@ -0,0 +1,390 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.Threading;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.Capabilities;
|
||||
using OpenMetaverse.Imaging;
|
||||
|
||||
namespace SLImageUpload
|
||||
{
|
||||
public partial class frmSLImageUpload : Form
|
||||
{
|
||||
private GridClient Client;
|
||||
private byte[] UploadData = null;
|
||||
private int Transferred = 0;
|
||||
private string FileName = String.Empty;
|
||||
private LLUUID SendToID;
|
||||
private LLUUID AssetID;
|
||||
|
||||
public frmSLImageUpload()
|
||||
{
|
||||
InitializeComponent();
|
||||
InitClient();
|
||||
}
|
||||
|
||||
private void InitClient()
|
||||
{
|
||||
Client = new GridClient();
|
||||
Client.Network.OnEventQueueRunning += new NetworkManager.EventQueueRunningCallback(Network_OnEventQueueRunning);
|
||||
Client.Network.OnLogin += new NetworkManager.LoginCallback(Network_OnLogin);
|
||||
|
||||
// Turn almost everything off since we are only interested in uploading textures
|
||||
Settings.LOG_LEVEL = Helpers.LogLevel.None;
|
||||
Client.Settings.ALWAYS_DECODE_OBJECTS = false;
|
||||
Client.Settings.ALWAYS_REQUEST_OBJECTS = false;
|
||||
Client.Settings.SEND_AGENT_UPDATES = true;
|
||||
Client.Settings.OBJECT_TRACKING = false;
|
||||
Client.Settings.STORE_LAND_PATCHES = false;
|
||||
Client.Settings.MULTIPLE_SIMS = false;
|
||||
Client.Self.Movement.Camera.Far = 32.0f;
|
||||
Client.Throttle.Cloud = 0.0f;
|
||||
Client.Throttle.Land = 0.0f;
|
||||
Client.Throttle.Wind = 0.0f;
|
||||
|
||||
Client.Throttle.Texture = 446000.0f;
|
||||
}
|
||||
|
||||
private void EnableUpload()
|
||||
{
|
||||
if (UploadData != null)
|
||||
{
|
||||
if (this.InvokeRequired)
|
||||
BeginInvoke(new MethodInvoker(EnableUpload));
|
||||
else
|
||||
cmdUpload.Enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void DisableUpload()
|
||||
{
|
||||
if (this.InvokeRequired)
|
||||
BeginInvoke(new MethodInvoker(DisableUpload));
|
||||
else
|
||||
cmdUpload.Enabled = false;
|
||||
}
|
||||
|
||||
private void UpdateAssetID()
|
||||
{
|
||||
if (this.InvokeRequired)
|
||||
BeginInvoke(new MethodInvoker(UpdateAssetID));
|
||||
else
|
||||
txtAssetID.Text = AssetID.ToString();
|
||||
}
|
||||
|
||||
private void LoadImage()
|
||||
{
|
||||
if (FileName == null || FileName == "")
|
||||
return;
|
||||
|
||||
string lowfilename = FileName.ToLower();
|
||||
Bitmap bitmap = null;
|
||||
|
||||
try
|
||||
{
|
||||
if (lowfilename.EndsWith(".jp2") || lowfilename.EndsWith(".j2c"))
|
||||
{
|
||||
Image image;
|
||||
ManagedImage managedImage;
|
||||
|
||||
// Upload JPEG2000 images untouched
|
||||
UploadData = System.IO.File.ReadAllBytes(FileName);
|
||||
|
||||
OpenJPEG.DecodeToImage(UploadData, out managedImage, out image);
|
||||
bitmap = (Bitmap)image;
|
||||
|
||||
Logger.Log("Loaded raw JPEG2000 data " + FileName, Helpers.LogLevel.Info, Client);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lowfilename.EndsWith(".tga"))
|
||||
bitmap = LoadTGAClass.LoadTGA(FileName);
|
||||
else
|
||||
bitmap = (Bitmap)System.Drawing.Image.FromFile(FileName);
|
||||
|
||||
Logger.Log("Loaded image " + FileName, Helpers.LogLevel.Info, Client);
|
||||
|
||||
int oldwidth = bitmap.Width;
|
||||
int oldheight = bitmap.Height;
|
||||
|
||||
if (!IsPowerOfTwo((uint)oldwidth) || !IsPowerOfTwo((uint)oldheight))
|
||||
{
|
||||
Logger.Log("Image has irregular dimensions " + oldwidth + "x" + oldheight + ", resizing to 256x256",
|
||||
Helpers.LogLevel.Info, Client);
|
||||
|
||||
Bitmap resized = new Bitmap(256, 256, bitmap.PixelFormat);
|
||||
Graphics graphics = Graphics.FromImage(resized);
|
||||
|
||||
graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
|
||||
graphics.InterpolationMode =
|
||||
System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
|
||||
graphics.DrawImage(bitmap, 0, 0, 256, 256);
|
||||
|
||||
bitmap.Dispose();
|
||||
bitmap = resized;
|
||||
|
||||
oldwidth = 256;
|
||||
oldheight = 256;
|
||||
}
|
||||
|
||||
// Handle resizing to prevent excessively large images
|
||||
if (oldwidth > 1024 || oldheight > 1024)
|
||||
{
|
||||
int newwidth = (oldwidth > 1024) ? 1024 : oldwidth;
|
||||
int newheight = (oldheight > 1024) ? 1024 : oldheight;
|
||||
|
||||
Logger.Log("Image has oversized dimensions " + oldwidth + "x" + oldheight + ", resizing to " +
|
||||
newwidth + "x" + newheight, Helpers.LogLevel.Info, Client);
|
||||
|
||||
Bitmap resized = new Bitmap(newwidth, newheight, bitmap.PixelFormat);
|
||||
Graphics graphics = Graphics.FromImage(resized);
|
||||
|
||||
graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
|
||||
graphics.InterpolationMode =
|
||||
System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
|
||||
graphics.DrawImage(bitmap, 0, 0, newwidth, newheight);
|
||||
|
||||
bitmap.Dispose();
|
||||
bitmap = resized;
|
||||
}
|
||||
|
||||
Logger.Log("Encoding image...", Helpers.LogLevel.Info, Client);
|
||||
|
||||
UploadData = OpenJPEG.EncodeFromImage(bitmap, chkLossless.Checked);
|
||||
|
||||
Logger.Log("Finished encoding", Helpers.LogLevel.Info, Client);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
UploadData = null;
|
||||
cmdUpload.Enabled = false;
|
||||
MessageBox.Show(ex.ToString(), "SL Image Upload", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
picPreview.Image = bitmap;
|
||||
lblSize.Text = Math.Round((double)UploadData.Length / 1024.0d, 2) + "KB";
|
||||
prgUpload.Maximum = UploadData.Length;
|
||||
if (Client.Network.Connected) cmdUpload.Enabled = true;
|
||||
}
|
||||
|
||||
private void cmdConnect_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (cmdConnect.Text == "Connect") {
|
||||
cmdConnect.Text = "Disconnect";
|
||||
txtFirstName.Enabled = txtLastName.Enabled = txtPassword.Enabled = false;
|
||||
LoginParams lp = new LoginParams();
|
||||
lp.FirstName = txtFirstName.Text;
|
||||
lp.LastName = txtLastName.Text;
|
||||
lp.Password = txtPassword.Text;
|
||||
lp.URI = Client.Settings.LOGIN_SERVER;
|
||||
lp.Start = "last";
|
||||
cmdConnect.Enabled = false;
|
||||
Client.Network.BeginLogin(lp);
|
||||
return;
|
||||
} else {
|
||||
Client.Network.Logout();
|
||||
cmdConnect.Text = "Connect";
|
||||
txtFirstName.Enabled = txtLastName.Enabled = txtPassword.Enabled = true;
|
||||
DisableUpload();
|
||||
InitClient();
|
||||
}
|
||||
}
|
||||
|
||||
void Network_OnLogin(LoginStatus login, string message)
|
||||
{
|
||||
if (InvokeRequired) {
|
||||
BeginInvoke(new MethodInvoker(
|
||||
delegate()
|
||||
{
|
||||
Network_OnLogin(login, message);
|
||||
}
|
||||
));
|
||||
return;
|
||||
}
|
||||
if (login == LoginStatus.Success) {
|
||||
MessageBox.Show("Connected: " + message);
|
||||
cmdConnect.Enabled = true;
|
||||
} else if (login == LoginStatus.Failed) {
|
||||
MessageBox.Show(this, String.Format("Error logging in ({0}): {1}", Client.Network.LoginErrorKey,
|
||||
Client.Network.LoginMessage));
|
||||
cmdConnect.Text = "Connect";
|
||||
cmdConnect.Enabled = true;
|
||||
txtFirstName.Enabled = txtLastName.Enabled = txtPassword.Enabled = true;
|
||||
DisableUpload();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void cmdLoad_Click(object sender, EventArgs e)
|
||||
{
|
||||
OpenFileDialog dialog = new OpenFileDialog();
|
||||
dialog.Filter =
|
||||
"Image Files (*.jp2,*.j2c,*.jpg,*.jpeg,*.gif,*.png,*.bmp,*.tga,*.tif,*.tiff,*.ico,*.wmf,*.emf)|" +
|
||||
"*.jp2;*.j2c;*.jpg;*.jpeg;*.gif;*.png;*.bmp;*.tga;*.tif;*.tiff;*.ico;*.wmf;*.emf;";
|
||||
|
||||
if (dialog.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
FileName = dialog.FileName;
|
||||
LoadImage();
|
||||
}
|
||||
}
|
||||
|
||||
private void cmdUpload_Click(object sender, EventArgs e)
|
||||
{
|
||||
SendToID = LLUUID.Zero;
|
||||
string sendTo = txtSendtoName.Text.Trim();
|
||||
|
||||
if (sendTo.Length > 0)
|
||||
{
|
||||
AutoResetEvent lookupEvent = new AutoResetEvent(false);
|
||||
LLUUID thisQueryID = LLUUID.Random();
|
||||
bool lookupSuccess = false;
|
||||
|
||||
DirectoryManager.DirPeopleReplyCallback callback =
|
||||
delegate(LLUUID queryID, List<DirectoryManager.AgentSearchData> matchedPeople)
|
||||
{
|
||||
if (queryID == thisQueryID)
|
||||
{
|
||||
if (matchedPeople.Count > 0)
|
||||
{
|
||||
SendToID = matchedPeople[0].AgentID;
|
||||
lookupSuccess = true;
|
||||
}
|
||||
|
||||
lookupEvent.Set();
|
||||
}
|
||||
};
|
||||
|
||||
Client.Directory.OnDirPeopleReply += callback;
|
||||
Client.Directory.StartPeopleSearch(DirectoryManager.DirFindFlags.People, sendTo, 0, thisQueryID);
|
||||
|
||||
bool eventSuccess = lookupEvent.WaitOne(10 * 1000, false);
|
||||
Client.Directory.OnDirPeopleReply -= callback;
|
||||
|
||||
if (eventSuccess && lookupSuccess)
|
||||
{
|
||||
Logger.Log("Will send uploaded image to avatar " + SendToID.ToString(), Helpers.LogLevel.Info, Client);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Could not find avatar \"" + sendTo + "\", upload cancelled");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (UploadData != null)
|
||||
{
|
||||
prgUpload.Value = 0;
|
||||
cmdLoad.Enabled = false;
|
||||
cmdUpload.Enabled = false;
|
||||
grpLogin.Enabled = false;
|
||||
|
||||
string name = System.IO.Path.GetFileNameWithoutExtension(FileName);
|
||||
|
||||
Client.Inventory.RequestCreateItemFromAsset(UploadData, name, "Uploaded with SL Image Upload", AssetType.Texture,
|
||||
InventoryType.Texture, Client.Inventory.FindFolderForType(AssetType.Texture),
|
||||
|
||||
delegate(CapsClient client, long bytesReceived, long bytesSent, long totalBytesToReceive, long totalBytesToSend)
|
||||
{
|
||||
if (bytesSent > 0)
|
||||
{
|
||||
Transferred = (int)bytesSent;
|
||||
BeginInvoke((MethodInvoker)delegate() { SetProgress(); });
|
||||
}
|
||||
},
|
||||
|
||||
delegate(bool success, string status, LLUUID itemID, LLUUID assetID)
|
||||
{
|
||||
if (this.InvokeRequired)
|
||||
BeginInvoke(new MethodInvoker(EnableControls));
|
||||
else
|
||||
EnableControls();
|
||||
|
||||
if (success)
|
||||
{
|
||||
AssetID = assetID;
|
||||
UpdateAssetID();
|
||||
|
||||
// Fix the permissions on the new upload since they are fscked by default
|
||||
InventoryItem item = Client.Inventory.FetchItem(itemID, Client.Self.AgentID, 1000 * 15);
|
||||
|
||||
Transferred = UploadData.Length;
|
||||
BeginInvoke((MethodInvoker)delegate() { SetProgress(); });
|
||||
|
||||
if (item != null)
|
||||
{
|
||||
item.Permissions.EveryoneMask = PermissionMask.All;
|
||||
item.Permissions.NextOwnerMask = PermissionMask.All;
|
||||
Client.Inventory.RequestUpdateItem(item);
|
||||
|
||||
Logger.Log("Created inventory item " + itemID.ToString(), Helpers.LogLevel.Info, Client);
|
||||
MessageBox.Show("Created inventory item " + itemID.ToString());
|
||||
|
||||
// FIXME: We should be watching the callback for RequestUpdateItem instead of a dumb sleep
|
||||
System.Threading.Thread.Sleep(2000);
|
||||
|
||||
if (SendToID != LLUUID.Zero)
|
||||
{
|
||||
Logger.Log("Sending item to " + SendToID.ToString(), Helpers.LogLevel.Info, Client);
|
||||
Client.Inventory.GiveItem(itemID, name, AssetType.Texture, SendToID, true);
|
||||
MessageBox.Show("Sent item to " + SendToID.ToString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.DebugLog("Created inventory item " + itemID.ToString() + " but failed to fetch it," +
|
||||
" cannot update permissions or send to another avatar", Client);
|
||||
MessageBox.Show("Created inventory item " + itemID.ToString() + " but failed to fetch it," +
|
||||
" cannot update permissions or send to another avatar");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Asset upload failed: " + status);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetProgress()
|
||||
{
|
||||
prgUpload.Value = Transferred;
|
||||
}
|
||||
|
||||
private void Network_OnEventQueueRunning(Simulator simulator)
|
||||
{
|
||||
Logger.DebugLog("Event queue is running for " + simulator.ToString() + ", enabling uploads", Client);
|
||||
EnableUpload();
|
||||
}
|
||||
|
||||
private void EnableControls()
|
||||
{
|
||||
cmdLoad.Enabled = true;
|
||||
cmdUpload.Enabled = true;
|
||||
grpLogin.Enabled = true;
|
||||
}
|
||||
|
||||
private void frmSLImageUpload_FormClosed(object sender, FormClosedEventArgs e)
|
||||
{
|
||||
if (Client.Network.Connected)
|
||||
Client.Network.Logout();
|
||||
}
|
||||
|
||||
private void chkLossless_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
LoadImage();
|
||||
}
|
||||
|
||||
private bool IsPowerOfTwo(uint n)
|
||||
{
|
||||
return (n & (n - 1)) == 0 && n != 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
120
Programs/SLImageUpload/frmSLImageUpload.resx
Normal file
120
Programs/SLImageUpload/frmSLImageUpload.resx
Normal file
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
732
Programs/SLProxy/Analyst.cs
Normal file
732
Programs/SLProxy/Analyst.cs
Normal file
@@ -0,0 +1,732 @@
|
||||
/*
|
||||
* Analyst.cs: proxy that makes packet inspection and modifcation interactive
|
||||
* See the README for usage instructions.
|
||||
*
|
||||
* Copyright (c) 2006 Austin Jennings
|
||||
* Modified by "qode" and "mcortez" on December 21st, 2006 to work with the new
|
||||
* pregen
|
||||
* All rights reserved.
|
||||
*
|
||||
* - Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* - Neither the name of the openmetaverse.org nor the names
|
||||
* of its contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using SLProxy;
|
||||
using OpenMetaverse;
|
||||
using Nwc.XmlRpc;
|
||||
using OpenMetaverse.Packets;
|
||||
using System.Reflection;
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
public class Analyst : ProxyPlugin
|
||||
{
|
||||
private ProxyFrame frame;
|
||||
private Proxy proxy;
|
||||
private Hashtable loggedPackets = new Hashtable();
|
||||
private string logGrep = null;
|
||||
private Hashtable modifiedPackets = new Hashtable();
|
||||
private Assembly openmvAssembly;
|
||||
|
||||
public Analyst(ProxyFrame frame)
|
||||
{
|
||||
this.frame = frame;
|
||||
this.proxy = frame.proxy;
|
||||
}
|
||||
|
||||
public override void Init()
|
||||
{
|
||||
openmvAssembly = Assembly.Load("OpenMetaverse");
|
||||
if (openmvAssembly == null) throw new Exception("Assembly load exception");
|
||||
|
||||
// build the table of /command delegates
|
||||
InitializeCommandDelegates();
|
||||
|
||||
// handle command line arguments
|
||||
foreach (string arg in frame.Args)
|
||||
if (arg == "--log-all")
|
||||
LogAll();
|
||||
|
||||
Console.WriteLine("Analyst loaded");
|
||||
}
|
||||
|
||||
// InitializeCommandDelegates: configure Analyst's commands
|
||||
private void InitializeCommandDelegates()
|
||||
{
|
||||
frame.AddCommand("/log", new ProxyFrame.CommandDelegate(CmdLog));
|
||||
frame.AddCommand("/-log", new ProxyFrame.CommandDelegate(CmdNoLog));
|
||||
frame.AddCommand("/grep", new ProxyFrame.CommandDelegate(CmdGrep));
|
||||
frame.AddCommand("/set", new ProxyFrame.CommandDelegate(CmdSet));
|
||||
frame.AddCommand("/-set", new ProxyFrame.CommandDelegate(CmdNoSet));
|
||||
frame.AddCommand("/inject", new ProxyFrame.CommandDelegate(CmdInject));
|
||||
frame.AddCommand("/in", new ProxyFrame.CommandDelegate(CmdInject));
|
||||
}
|
||||
|
||||
private static PacketType packetTypeFromName(string name)
|
||||
{
|
||||
Type packetTypeType = typeof(PacketType);
|
||||
System.Reflection.FieldInfo f = packetTypeType.GetField(name);
|
||||
if (f == null) throw new ArgumentException("Bad packet type");
|
||||
return (PacketType)Enum.ToObject(packetTypeType, (int)f.GetValue(packetTypeType));
|
||||
}
|
||||
|
||||
// CmdLog: handle a /log command
|
||||
private void CmdLog(string[] words)
|
||||
{
|
||||
if (words.Length != 2)
|
||||
SayToUser("Usage: /log <packet name>");
|
||||
else if (words[1] == "*")
|
||||
{
|
||||
LogAll();
|
||||
SayToUser("logging all packets");
|
||||
}
|
||||
else
|
||||
{
|
||||
PacketType pType;
|
||||
try
|
||||
{
|
||||
pType = packetTypeFromName(words[1]);
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
SayToUser("Bad packet name: " + words[1]);
|
||||
return;
|
||||
}
|
||||
loggedPackets[pType] = null;
|
||||
proxy.AddDelegate(pType, Direction.Incoming, new PacketDelegate(LogPacketIn));
|
||||
proxy.AddDelegate(pType, Direction.Outgoing, new PacketDelegate(LogPacketOut));
|
||||
SayToUser("logging " + words[1]);
|
||||
}
|
||||
}
|
||||
|
||||
// CmdNoLog: handle a /-log command
|
||||
private void CmdNoLog(string[] words)
|
||||
{
|
||||
if (words.Length != 2)
|
||||
SayToUser("Usage: /-log <packet name>");
|
||||
else if (words[1] == "*")
|
||||
{
|
||||
NoLogAll();
|
||||
SayToUser("stopped logging all packets");
|
||||
}
|
||||
else
|
||||
{
|
||||
PacketType pType = packetTypeFromName(words[1]);
|
||||
loggedPackets.Remove(pType);
|
||||
|
||||
proxy.RemoveDelegate(pType, Direction.Incoming, new PacketDelegate(LogPacketIn));
|
||||
proxy.RemoveDelegate(pType, Direction.Outgoing, new PacketDelegate(LogPacketOut));
|
||||
SayToUser("stopped logging " + words[1]);
|
||||
}
|
||||
}
|
||||
|
||||
// CmdGrep: handle a /grep command
|
||||
private void CmdGrep(string[] words) {
|
||||
if (words.Length == 1) {
|
||||
logGrep = null;
|
||||
SayToUser("stopped filtering logs");
|
||||
} else {
|
||||
string[] regexArray = new string[words.Length - 1];
|
||||
Array.Copy(words, 1, regexArray, 0, words.Length - 1);
|
||||
logGrep = String.Join(" ", regexArray);
|
||||
SayToUser("filtering log with " + logGrep);
|
||||
}
|
||||
}
|
||||
|
||||
// CmdSet: handle a /set command
|
||||
private void CmdSet(string[] words)
|
||||
{
|
||||
if (words.Length < 5)
|
||||
SayToUser("Usage: /set <packet name> <block> <field> <value>");
|
||||
else
|
||||
{
|
||||
PacketType pType;
|
||||
try
|
||||
{
|
||||
pType = packetTypeFromName(words[1]);
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
SayToUser("Bad packet name: " + words[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
string[] valueArray = new string[words.Length - 4];
|
||||
Array.Copy(words, 4, valueArray, 0, words.Length - 4);
|
||||
string valueString = String.Join(" ", valueArray);
|
||||
object value;
|
||||
try
|
||||
{
|
||||
value = MagicCast(words[1], words[2], words[3], valueString);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
SayToUser(e.Message);
|
||||
return;
|
||||
}
|
||||
|
||||
Hashtable fields;
|
||||
if (modifiedPackets.Contains(pType))
|
||||
fields = (Hashtable)modifiedPackets[pType];
|
||||
else
|
||||
fields = new Hashtable();
|
||||
|
||||
fields[new BlockField(words[2], words[3])] = value;
|
||||
modifiedPackets[pType] = fields;
|
||||
|
||||
proxy.AddDelegate(pType, Direction.Incoming, new PacketDelegate(ModifyIn));
|
||||
proxy.AddDelegate(pType, Direction.Outgoing, new PacketDelegate(ModifyOut));
|
||||
|
||||
SayToUser("setting " + words[1] + "." + words[2] + "." + words[3] + " = " + valueString);
|
||||
}
|
||||
}
|
||||
|
||||
// CmdNoSet: handle a /-set command
|
||||
private void CmdNoSet(string[] words)
|
||||
{
|
||||
if (words.Length == 2 && words[1] == "*")
|
||||
{
|
||||
foreach (PacketType pType in modifiedPackets.Keys)
|
||||
{
|
||||
proxy.RemoveDelegate(pType, Direction.Incoming, new PacketDelegate(ModifyIn));
|
||||
proxy.RemoveDelegate(pType, Direction.Outgoing, new PacketDelegate(ModifyOut));
|
||||
}
|
||||
modifiedPackets = new Hashtable();
|
||||
|
||||
SayToUser("stopped setting all fields");
|
||||
}
|
||||
else if (words.Length == 4)
|
||||
{
|
||||
PacketType pType;
|
||||
try
|
||||
{
|
||||
pType = packetTypeFromName(words[1]);
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
SayToUser("Bad packet name: " + words[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (modifiedPackets.Contains(pType))
|
||||
{
|
||||
Hashtable fields = (Hashtable)modifiedPackets[pType];
|
||||
fields.Remove(new BlockField(words[2], words[3]));
|
||||
|
||||
if (fields.Count == 0)
|
||||
{
|
||||
modifiedPackets.Remove(pType);
|
||||
|
||||
proxy.RemoveDelegate(pType, Direction.Incoming, new PacketDelegate(ModifyIn));
|
||||
proxy.RemoveDelegate(pType, Direction.Outgoing, new PacketDelegate(ModifyOut));
|
||||
}
|
||||
}
|
||||
|
||||
SayToUser("stopped setting " + words[1] + "." + words[2] + "." + words[3]);
|
||||
}
|
||||
else
|
||||
SayToUser("Usage: /-set <packet name> <block> <field>");
|
||||
}
|
||||
|
||||
|
||||
// CmdInject: handle an /inject command
|
||||
private void CmdInject(string[] words)
|
||||
{
|
||||
if (words.Length < 2)
|
||||
SayToUser("Usage: /inject <packet file> [value]");
|
||||
else
|
||||
{
|
||||
string[] valueArray = new string[words.Length - 2];
|
||||
Array.Copy(words, 2, valueArray, 0, words.Length - 2);
|
||||
string value = String.Join(" ", valueArray);
|
||||
|
||||
FileStream fs = null;
|
||||
StreamReader sr = null;
|
||||
Direction direction = Direction.Incoming;
|
||||
string name = null;
|
||||
string block = null;
|
||||
object blockObj = null;
|
||||
Type packetClass = null;
|
||||
Packet packet = null;
|
||||
|
||||
try
|
||||
{
|
||||
fs = File.OpenRead(words[1] + ".packet");
|
||||
sr = new StreamReader(fs);
|
||||
|
||||
string line;
|
||||
while ((line = sr.ReadLine()) != null)
|
||||
{
|
||||
Match match;
|
||||
|
||||
if (name == null)
|
||||
{
|
||||
match = (new Regex(@"^\s*(in|out)\s+(\w+)\s*$")).Match(line);
|
||||
if (!match.Success)
|
||||
{
|
||||
SayToUser("expecting direction and packet name, got: " + line);
|
||||
return;
|
||||
}
|
||||
|
||||
string lineDir = match.Groups[1].Captures[0].ToString();
|
||||
string lineName = match.Groups[2].Captures[0].ToString();
|
||||
|
||||
if (lineDir == "in")
|
||||
direction = Direction.Incoming;
|
||||
else if (lineDir == "out")
|
||||
direction = Direction.Outgoing;
|
||||
else
|
||||
{
|
||||
SayToUser("expecting 'in' or 'out', got: " + line);
|
||||
return;
|
||||
}
|
||||
|
||||
name = lineName;
|
||||
packetClass = openmvAssembly.GetType("OpenMetaverse.Packets." + name + "Packet");
|
||||
if (packetClass == null) throw new Exception("Couldn't get class " + name + "Packet");
|
||||
ConstructorInfo ctr = packetClass.GetConstructor(new Type[] { });
|
||||
if (ctr == null) throw new Exception("Couldn't get suitable constructor for " + name + "Packet");
|
||||
packet = (Packet)ctr.Invoke(new object[] { });
|
||||
//Console.WriteLine("Created new " + name + "Packet");
|
||||
}
|
||||
else
|
||||
{
|
||||
match = (new Regex(@"^\s*\[(\w+)\]\s*$")).Match(line);
|
||||
if (match.Success)
|
||||
{
|
||||
block = match.Groups[1].Captures[0].ToString();
|
||||
FieldInfo blockField = packetClass.GetField(block);
|
||||
if (blockField == null) throw new Exception("Couldn't get " + name + "Packet." + block);
|
||||
Type blockClass = blockField.FieldType;
|
||||
if (blockClass.IsArray)
|
||||
{
|
||||
blockClass = blockClass.GetElementType();
|
||||
ConstructorInfo ctr = blockClass.GetConstructor(new Type[] { });
|
||||
if (ctr == null) throw new Exception("Couldn't get suitable constructor for " + blockClass.Name);
|
||||
blockObj = ctr.Invoke(new object[] { });
|
||||
object[] arr = (object[])blockField.GetValue(packet);
|
||||
object[] narr = (object[])Array.CreateInstance(blockClass, arr.Length + 1);
|
||||
Array.Copy(arr, narr, arr.Length);
|
||||
narr[arr.Length] = blockObj;
|
||||
blockField.SetValue(packet, narr);
|
||||
//Console.WriteLine("Added block "+block);
|
||||
}
|
||||
else
|
||||
{
|
||||
blockObj = blockField.GetValue(packet);
|
||||
}
|
||||
if (blockObj == null) throw new Exception("Got " + name + "Packet." + block + " == null");
|
||||
//Console.WriteLine("Got block " + name + "Packet." + block);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (block == null)
|
||||
{
|
||||
SayToUser("expecting block name, got: " + line);
|
||||
return;
|
||||
}
|
||||
|
||||
match = (new Regex(@"^\s*(\w+)\s*=\s*(.*)$")).Match(line);
|
||||
if (match.Success)
|
||||
{
|
||||
string lineField = match.Groups[1].Captures[0].ToString();
|
||||
string lineValue = match.Groups[2].Captures[0].ToString();
|
||||
object fval;
|
||||
|
||||
//FIXME: use of MagicCast inefficient
|
||||
if (lineValue == "$Value")
|
||||
fval = MagicCast(name, block, lineField, value);
|
||||
else if (lineValue == "$UUID")
|
||||
fval = LLUUID.Random();
|
||||
else if (lineValue == "$AgentID")
|
||||
fval = frame.AgentID;
|
||||
else if (lineValue == "$SessionID")
|
||||
fval = frame.SessionID;
|
||||
else
|
||||
fval = MagicCast(name, block, lineField, lineValue);
|
||||
|
||||
MagicSetField(blockObj, lineField, fval);
|
||||
continue;
|
||||
}
|
||||
|
||||
SayToUser("expecting block name or field, got: " + line);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (name == null)
|
||||
{
|
||||
SayToUser("expecting direction and packet name, got EOF");
|
||||
return;
|
||||
}
|
||||
|
||||
packet.Header.Flags |= Helpers.MSG_RELIABLE;
|
||||
//if (protocolManager.Command(name).Encoded)
|
||||
// packet.Header.Flags |= Helpers.MSG_ZEROCODED;
|
||||
proxy.InjectPacket(packet, direction);
|
||||
|
||||
SayToUser("injected " + words[1]);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
SayToUser("failed to inject " + words[1] + ": " + e.Message);
|
||||
Console.WriteLine("failed to inject " + words[1] + ": " + e.Message + "\n" + e.StackTrace);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (fs != null)
|
||||
fs.Close();
|
||||
if (sr != null)
|
||||
sr.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SayToUser: send a message to the user as in-world chat
|
||||
private void SayToUser(string message)
|
||||
{
|
||||
ChatFromSimulatorPacket packet = new ChatFromSimulatorPacket();
|
||||
packet.ChatData.FromName = Helpers.StringToField("Analyst");
|
||||
packet.ChatData.SourceID = LLUUID.Random();
|
||||
packet.ChatData.OwnerID = frame.AgentID;
|
||||
packet.ChatData.SourceType = (byte)2;
|
||||
packet.ChatData.ChatType = (byte)1;
|
||||
packet.ChatData.Audible = (byte)1;
|
||||
packet.ChatData.Position = new LLVector3(0, 0, 0);
|
||||
packet.ChatData.Message = Helpers.StringToField(message);
|
||||
proxy.InjectPacket(packet, Direction.Incoming);
|
||||
}
|
||||
|
||||
// BlockField: product type for a block name and field name
|
||||
private struct BlockField
|
||||
{
|
||||
public string block;
|
||||
public string field;
|
||||
|
||||
|
||||
public BlockField(string block, string field)
|
||||
{
|
||||
this.block = block;
|
||||
this.field = field;
|
||||
}
|
||||
}
|
||||
|
||||
private static void MagicSetField(object obj, string field, object val)
|
||||
{
|
||||
Type cls = obj.GetType();
|
||||
|
||||
FieldInfo fieldInf = cls.GetField(field);
|
||||
if (fieldInf == null)
|
||||
{
|
||||
PropertyInfo prop = cls.GetProperty(field);
|
||||
if (prop == null) throw new Exception("Couldn't find field " + cls.Name + "." + field);
|
||||
prop.SetValue(obj, val, null);
|
||||
//throw new Exception("FIXME: can't set properties");
|
||||
}
|
||||
else
|
||||
{
|
||||
fieldInf.SetValue(obj, val);
|
||||
}
|
||||
}
|
||||
|
||||
// MagicCast: given a packet/block/field name and a string, convert the string to a value of the appropriate type
|
||||
private object MagicCast(string name, string block, string field, string value)
|
||||
{
|
||||
Type packetClass = openmvAssembly.GetType("OpenMetaverse.Packets." + name + "Packet");
|
||||
if (packetClass == null) throw new Exception("Couldn't get class " + name + "Packet");
|
||||
|
||||
FieldInfo blockField = packetClass.GetField(block);
|
||||
if (blockField == null) throw new Exception("Couldn't get " + name + "Packet." + block);
|
||||
Type blockClass = blockField.FieldType;
|
||||
if (blockClass.IsArray) blockClass = blockClass.GetElementType();
|
||||
// Console.WriteLine("DEBUG: " + blockClass.Name);
|
||||
|
||||
FieldInfo fieldField = blockClass.GetField(field); PropertyInfo fieldProp = null;
|
||||
Type fieldClass = null;
|
||||
if (fieldField == null)
|
||||
{
|
||||
fieldProp = blockClass.GetProperty(field);
|
||||
if (fieldProp == null) throw new Exception("Couldn't get " + name + "Packet." + block + "." + field);
|
||||
fieldClass = fieldProp.PropertyType;
|
||||
}
|
||||
else
|
||||
{
|
||||
fieldClass = fieldField.FieldType;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (fieldClass == typeof(byte))
|
||||
{
|
||||
return Convert.ToByte(value);
|
||||
}
|
||||
else if (fieldClass == typeof(ushort))
|
||||
{
|
||||
return Convert.ToUInt16(value);
|
||||
}
|
||||
else if (fieldClass == typeof(uint))
|
||||
{
|
||||
return Convert.ToUInt32(value);
|
||||
}
|
||||
else if (fieldClass == typeof(ulong))
|
||||
{
|
||||
return Convert.ToUInt64(value);
|
||||
}
|
||||
else if (fieldClass == typeof(sbyte))
|
||||
{
|
||||
return Convert.ToSByte(value);
|
||||
}
|
||||
else if (fieldClass == typeof(short))
|
||||
{
|
||||
return Convert.ToInt16(value);
|
||||
}
|
||||
else if (fieldClass == typeof(int))
|
||||
{
|
||||
return Convert.ToInt32(value);
|
||||
}
|
||||
else if (fieldClass == typeof(long))
|
||||
{
|
||||
return Convert.ToInt64(value);
|
||||
}
|
||||
else if (fieldClass == typeof(float))
|
||||
{
|
||||
return Convert.ToSingle(value);
|
||||
}
|
||||
else if (fieldClass == typeof(double))
|
||||
{
|
||||
return Convert.ToDouble(value);
|
||||
}
|
||||
else if (fieldClass == typeof(LLUUID))
|
||||
{
|
||||
return new LLUUID(value);
|
||||
}
|
||||
else if (fieldClass == typeof(bool))
|
||||
{
|
||||
if (value.ToLower() == "true")
|
||||
return true;
|
||||
else if (value.ToLower() == "false")
|
||||
return false;
|
||||
else
|
||||
throw new Exception();
|
||||
}
|
||||
else if (fieldClass == typeof(byte[]))
|
||||
{
|
||||
return Helpers.StringToField(value);
|
||||
}
|
||||
else if (fieldClass == typeof(LLVector3))
|
||||
{
|
||||
LLVector3 result;
|
||||
if(LLVector3.TryParse(value, out result))
|
||||
return result;
|
||||
else
|
||||
throw new Exception();
|
||||
}
|
||||
else if (fieldClass == typeof(LLVector3d))
|
||||
{
|
||||
LLVector3d result;
|
||||
if (LLVector3d.TryParse(value, out result))
|
||||
return result;
|
||||
else
|
||||
throw new Exception();
|
||||
}
|
||||
else if (fieldClass == typeof(LLVector4))
|
||||
{
|
||||
LLVector4 result;
|
||||
if (LLVector4.TryParse(value, out result))
|
||||
return result;
|
||||
else
|
||||
throw new Exception();
|
||||
}
|
||||
else if (fieldClass == typeof(LLQuaternion))
|
||||
{
|
||||
LLQuaternion result;
|
||||
if (LLQuaternion.TryParse(value, out result))
|
||||
return result;
|
||||
else
|
||||
throw new Exception();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("unsupported field type " + fieldClass);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw new Exception("unable to interpret " + value + " as " + fieldClass);
|
||||
}
|
||||
}
|
||||
|
||||
// ModifyIn: modify an incoming packet
|
||||
private Packet ModifyIn(Packet packet, IPEndPoint endPoint)
|
||||
{
|
||||
return Modify(packet, endPoint, Direction.Incoming);
|
||||
}
|
||||
|
||||
// ModifyOut: modify an outgoing packet
|
||||
private Packet ModifyOut(Packet packet, IPEndPoint endPoint)
|
||||
{
|
||||
return Modify(packet, endPoint, Direction.Outgoing);
|
||||
}
|
||||
|
||||
// Modify: modify a packet
|
||||
private Packet Modify(Packet packet, IPEndPoint endPoint, Direction direction)
|
||||
{
|
||||
if (modifiedPackets.Contains(packet.Type))
|
||||
{
|
||||
try
|
||||
{
|
||||
Hashtable changes = (Hashtable)modifiedPackets[packet.Type];
|
||||
Type packetClass = packet.GetType();
|
||||
|
||||
foreach (BlockField bf in changes.Keys)
|
||||
{
|
||||
//FIXME: support variable blocks
|
||||
|
||||
FieldInfo blockField = packetClass.GetField(bf.block);
|
||||
//Type blockClass = blockField.FieldType;
|
||||
object blockObject = blockField.GetValue(packet);
|
||||
MagicSetField(blockObject, bf.field, changes[blockField]);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine("failed to modify " + packet.Type + ": " + e.Message);
|
||||
Console.WriteLine(e.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
return packet;
|
||||
}
|
||||
|
||||
// LogPacketIn: log an incoming packet
|
||||
private Packet LogPacketIn(Packet packet, IPEndPoint endPoint)
|
||||
{
|
||||
LogPacket(packet, endPoint, Direction.Incoming);
|
||||
return packet;
|
||||
}
|
||||
|
||||
// LogPacketOut: log an outgoing packet
|
||||
private Packet LogPacketOut(Packet packet, IPEndPoint endPoint)
|
||||
{
|
||||
LogPacket(packet, endPoint, Direction.Outgoing);
|
||||
return packet;
|
||||
}
|
||||
|
||||
// LogAll: register logging delegates for all packets
|
||||
private void LogAll()
|
||||
{
|
||||
Type packetTypeType = typeof(PacketType);
|
||||
System.Reflection.MemberInfo[] packetTypes = packetTypeType.GetMembers();
|
||||
|
||||
for (int i = 0; i < packetTypes.Length; i++)
|
||||
{
|
||||
if (packetTypes[i].MemberType == System.Reflection.MemberTypes.Field && packetTypes[i].DeclaringType == packetTypeType)
|
||||
{
|
||||
string name = packetTypes[i].Name;
|
||||
PacketType pType;
|
||||
|
||||
try
|
||||
{
|
||||
pType = packetTypeFromName(name);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
loggedPackets[pType] = null;
|
||||
|
||||
proxy.AddDelegate(pType, Direction.Incoming, new PacketDelegate(LogPacketIn));
|
||||
proxy.AddDelegate(pType, Direction.Outgoing, new PacketDelegate(LogPacketOut));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NoLogAll: unregister logging delegates for all packets
|
||||
private void NoLogAll()
|
||||
{
|
||||
Type packetTypeType = typeof(PacketType);
|
||||
System.Reflection.MemberInfo[] packetTypes = packetTypeType.GetMembers();
|
||||
|
||||
for (int i = 0; i < packetTypes.Length; i++)
|
||||
{
|
||||
if (packetTypes[i].MemberType == System.Reflection.MemberTypes.Field && packetTypes[i].DeclaringType == packetTypeType)
|
||||
{
|
||||
string name = packetTypes[i].Name;
|
||||
PacketType pType;
|
||||
|
||||
try
|
||||
{
|
||||
pType = packetTypeFromName(name);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
loggedPackets.Remove(pType);
|
||||
|
||||
proxy.RemoveDelegate(pType, Direction.Incoming, new PacketDelegate(LogPacketIn));
|
||||
proxy.RemoveDelegate(pType, Direction.Outgoing, new PacketDelegate(LogPacketOut));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// LogPacket: dump a packet to the console
|
||||
private void LogPacket(Packet packet, IPEndPoint endPoint, Direction direction)
|
||||
{
|
||||
string packetText = packet.ToString();
|
||||
|
||||
if (logGrep == null || (logGrep != null && Regex.IsMatch(packetText, logGrep)))
|
||||
{
|
||||
Console.WriteLine("{0} {1,21} {2,5} {3}{4}{5}"
|
||||
, direction == Direction.Incoming ? "<--" : "-->"
|
||||
, endPoint
|
||||
, packet.Header.Sequence
|
||||
, InterpretOptions(packet.Header.Flags)
|
||||
, Environment.NewLine
|
||||
, packetText
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// InterpretOptions: produce a string representing a packet's header options
|
||||
private static string InterpretOptions(byte options)
|
||||
{
|
||||
return "["
|
||||
+ ((options & Helpers.MSG_APPENDED_ACKS) != 0 ? "Ack" : " ")
|
||||
+ " "
|
||||
+ ((options & Helpers.MSG_RESENT) != 0 ? "Res" : " ")
|
||||
+ " "
|
||||
+ ((options & Helpers.MSG_RELIABLE) != 0 ? "Rel" : " ")
|
||||
+ " "
|
||||
+ ((options & Helpers.MSG_ZEROCODED) != 0 ? "Zer" : " ")
|
||||
+ "]"
|
||||
;
|
||||
}
|
||||
}
|
||||
107
Programs/SLProxy/ChatConsole.cs
Normal file
107
Programs/SLProxy/ChatConsole.cs
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* ChatConsole.cs: sample SLProxy appliation that writes chat to the console.
|
||||
* Typing on the console will send chat to the grid.
|
||||
*
|
||||
* Copyright (c) 2006 Austin Jennings
|
||||
* Modified by Andrew Ortman ("qode") on Decemeber 21, 2006 to work with the new pregen proxy.
|
||||
* All rights reserved.
|
||||
*
|
||||
* - Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* - Neither the name of the openmetaverse.org nor the names
|
||||
* of its contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using SLProxy;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.Packets;
|
||||
using Nwc.XmlRpc;
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
|
||||
public class ChatConsole {
|
||||
private static Proxy proxy;
|
||||
private static LLUUID agentID;
|
||||
private static LLUUID sessionID;
|
||||
|
||||
public static void Main(string[] args) {
|
||||
// configure the proxy
|
||||
ProxyConfig proxyConfig = new ProxyConfig("ChatConsole V2", "Austin Jennings / Andrew Ortman", args);
|
||||
proxy = new Proxy(proxyConfig);
|
||||
|
||||
// set a delegate for when the client logs in
|
||||
proxy.SetLoginResponseDelegate(new XmlRpcResponseDelegate(Login));
|
||||
|
||||
// add a delegate for incoming chat
|
||||
proxy.AddDelegate(PacketType.ChatFromSimulator, Direction.Incoming, new PacketDelegate(ChatFromSimulator));
|
||||
|
||||
// start the proxy
|
||||
proxy.Start();
|
||||
}
|
||||
|
||||
private static void Login(XmlRpcResponse response) {
|
||||
Hashtable values = (Hashtable)response.Value;
|
||||
if (values.Contains("agent_id") && values.Contains("session_id")) {
|
||||
// remember our agentID and sessionID
|
||||
agentID = new LLUUID((string)values["agent_id"]);
|
||||
sessionID = new LLUUID((string)values["session_id"]);
|
||||
|
||||
// start a new thread that reads lines from the console
|
||||
(new Thread(new ThreadStart(ReadFromConsole))).Start();
|
||||
}
|
||||
}
|
||||
|
||||
private static void ReadFromConsole() {
|
||||
// send text from the console in an infinite loop
|
||||
for (;;) {
|
||||
// read a line from the console
|
||||
string message = Console.ReadLine();
|
||||
|
||||
// construct a ChatFromViewer packet
|
||||
ChatFromViewerPacket chat = new ChatFromViewerPacket();
|
||||
chat.ChatData.Channel = 0;
|
||||
chat.ChatData.Message = Helpers.StringToField(message);
|
||||
chat.ChatData.Type = (byte)1;
|
||||
|
||||
chat.AgentData.AgentID = agentID;
|
||||
chat.AgentData.SessionID = sessionID;
|
||||
// inject the packet
|
||||
proxy.InjectPacket((Packet)chat, Direction.Outgoing);
|
||||
}
|
||||
}
|
||||
|
||||
private static Packet ChatFromSimulator(Packet packet, IPEndPoint sim) {
|
||||
// deconstruct the packet
|
||||
ChatFromSimulatorPacket chat = (ChatFromSimulatorPacket)packet;
|
||||
string message = Helpers.FieldToUTF8String(chat.ChatData.Message);
|
||||
string name = Helpers.FieldToUTF8String(chat.ChatData.FromName);
|
||||
byte audible = chat.ChatData.Audible;
|
||||
byte type = chat.ChatData.ChatType;
|
||||
|
||||
// if this was a normal, audible message, write it to the console
|
||||
if (audible != 0 && (type == 0 || type == 1 || type == 2))
|
||||
Console.WriteLine(name + ": " + message);
|
||||
|
||||
// return the packet unmodified
|
||||
return packet;
|
||||
}
|
||||
}
|
||||
121
Programs/SLProxy/ChatConsole.csproj
Normal file
121
Programs/SLProxy/ChatConsole.csproj
Normal file
@@ -0,0 +1,121 @@
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<ProjectType>Local</ProjectType>
|
||||
<ProductVersion>8.0.50727</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{D8ECCBE1-AC71-4054-AAA6-2D50E5629504}</ProjectGuid>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ApplicationIcon>
|
||||
</ApplicationIcon>
|
||||
<AssemblyKeyContainerName>
|
||||
</AssemblyKeyContainerName>
|
||||
<AssemblyName>ChatConsole</AssemblyName>
|
||||
<AssemblyOriginatorKeyFile>
|
||||
</AssemblyOriginatorKeyFile>
|
||||
<DefaultClientScript>JScript</DefaultClientScript>
|
||||
<DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
|
||||
<DefaultTargetSchema>IE50</DefaultTargetSchema>
|
||||
<DelaySign>false</DelaySign>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>ChatConsole</RootNamespace>
|
||||
<RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
|
||||
<StartupObject>
|
||||
</StartupObject>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<UpgradeBackupLocation>
|
||||
</UpgradeBackupLocation>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<OutputPath>..\bin\</OutputPath>
|
||||
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
|
||||
<BaseAddress>285212672</BaseAddress>
|
||||
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
|
||||
<ConfigurationOverrideFile>
|
||||
</ConfigurationOverrideFile>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DocumentationFile>
|
||||
</DocumentationFile>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<FileAlignment>4096</FileAlignment>
|
||||
<NoStdLib>false</NoStdLib>
|
||||
<NoWarn>
|
||||
</NoWarn>
|
||||
<Optimize>false</Optimize>
|
||||
<RegisterForComInterop>false</RegisterForComInterop>
|
||||
<RemoveIntegerChecks>false</RemoveIntegerChecks>
|
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<DebugType>full</DebugType>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<OutputPath>..\..\bin\</OutputPath>
|
||||
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
|
||||
<BaseAddress>285212672</BaseAddress>
|
||||
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
|
||||
<ConfigurationOverrideFile>
|
||||
</ConfigurationOverrideFile>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<DocumentationFile>
|
||||
</DocumentationFile>
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
<FileAlignment>4096</FileAlignment>
|
||||
<NoStdLib>false</NoStdLib>
|
||||
<NoWarn>
|
||||
</NoWarn>
|
||||
<Optimize>true</Optimize>
|
||||
<RegisterForComInterop>false</RegisterForComInterop>
|
||||
<RemoveIntegerChecks>false</RemoveIntegerChecks>
|
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<DebugType>none</DebugType>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release-docs|AnyCPU' ">
|
||||
<OutputPath>bin\Release-docs\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<BaseAddress>285212672</BaseAddress>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>
|
||||
</DebugType>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<CodeAnalysisRuleAssemblies>C:\Program Files\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop\\rules</CodeAnalysisRuleAssemblies>
|
||||
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
|
||||
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System">
|
||||
<Name>System</Name>
|
||||
</Reference>
|
||||
<Reference Include="System.Data">
|
||||
<Name>System.Data</Name>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml">
|
||||
<Name>System.XML</Name>
|
||||
</Reference>
|
||||
<ProjectReference Include="..\libsecondlife\OpenMetaverse.csproj">
|
||||
<Project>{D9CDEDFB-8169-4B03-B57F-0DF638F044EC}</Project>
|
||||
<Name>OpenMetaverse</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="SLProxy.csproj">
|
||||
<Name>SLProxy</Name>
|
||||
<Project>{E4115DC9-FC88-47D6-B3B6-2400AD19B80D}</Project>
|
||||
<Package>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</Package>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ChatConsole.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
<PreBuildEvent>
|
||||
</PreBuildEvent>
|
||||
<PostBuildEvent>
|
||||
</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
809
Programs/SLProxy/ClientAO/ClientAO/ClientAO.cs
Normal file
809
Programs/SLProxy/ClientAO/ClientAO/ClientAO.cs
Normal file
@@ -0,0 +1,809 @@
|
||||
/*
|
||||
* ClientAO.cs: SLProxy application that acts as a client side animation overrider.
|
||||
* The application will start and stop animations corresponding to the movements
|
||||
* of the avatar on screen.
|
||||
*
|
||||
* Copyright (c) 2007 Gilbert Roulot
|
||||
* All rights reserved.
|
||||
*
|
||||
* - Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* - Neither the name of the Second Life Reverse Engineering Team nor the names
|
||||
* of its contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using SLProxy;
|
||||
using libsecondlife;
|
||||
using libsecondlife.Packets;
|
||||
using libsecondlife.StructuredData;
|
||||
using Nwc.XmlRpc;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
|
||||
|
||||
public class ClientAO : ProxyPlugin
|
||||
{
|
||||
private ProxyFrame frame;
|
||||
private Proxy proxy;
|
||||
private LLUUID[] wetikonanims = {
|
||||
Animations.WALK,
|
||||
Animations.RUN,
|
||||
Animations.CROUCHWALK,
|
||||
Animations.FLY,
|
||||
Animations.TURNLEFT,
|
||||
Animations.TURNRIGHT,
|
||||
Animations.JUMP,
|
||||
Animations.HOVER_UP,
|
||||
Animations.CROUCH,
|
||||
Animations.HOVER_DOWN,
|
||||
Animations.STAND,
|
||||
Animations.STAND_1,
|
||||
Animations.STAND_2,
|
||||
Animations.STAND_3,
|
||||
Animations.STAND_4,
|
||||
Animations.HOVER,
|
||||
Animations.SIT,
|
||||
Animations.PRE_JUMP,
|
||||
Animations.FALLDOWN,
|
||||
Animations.LAND,
|
||||
Animations.STANDUP,
|
||||
Animations.FLYSLOW,
|
||||
Animations.SIT_GROUND_staticRAINED,
|
||||
LLUUID.Zero, //swimming doesnt exist
|
||||
LLUUID.Zero,
|
||||
LLUUID.Zero,
|
||||
LLUUID.Zero
|
||||
};
|
||||
|
||||
private string[] wetikonanimnames = {
|
||||
"walk",
|
||||
"run",
|
||||
"crouch walk",
|
||||
"fly",
|
||||
"turn left",
|
||||
"turn right",
|
||||
"jump",
|
||||
"hover up",
|
||||
"crouch",
|
||||
"hover down",
|
||||
"stand",
|
||||
"stand 2",
|
||||
"stand 3",
|
||||
"stand 4",
|
||||
"stand 5",
|
||||
"hover",
|
||||
"sit",
|
||||
"pre jump",
|
||||
"fall down",
|
||||
"land",
|
||||
"stand up",
|
||||
"fly slow",
|
||||
"sit on ground",
|
||||
"swim (ignored)", //swimming doesnt exist
|
||||
"swim (ignored)",
|
||||
"swim (ignored)",
|
||||
"swim (ignored)"
|
||||
};
|
||||
|
||||
private Dictionary<LLUUID, string> animuid2name;
|
||||
|
||||
//private Assembly libslAssembly;
|
||||
|
||||
#region Packet delegates members
|
||||
private PacketDelegate _packetDelegate;
|
||||
private PacketDelegate packetDelegate
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_packetDelegate == null)
|
||||
{
|
||||
_packetDelegate = new PacketDelegate(AnimationPacketHandler);
|
||||
}
|
||||
return _packetDelegate;
|
||||
}
|
||||
}
|
||||
|
||||
private PacketDelegate _inventoryPacketDelegate;
|
||||
private PacketDelegate inventoryPacketDelegate
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_inventoryPacketDelegate == null)
|
||||
{
|
||||
_inventoryPacketDelegate = new PacketDelegate(InventoryDescendentsHandler);
|
||||
}
|
||||
return _inventoryPacketDelegate;
|
||||
}
|
||||
}
|
||||
|
||||
private PacketDelegate _transferPacketDelegate;
|
||||
private PacketDelegate transferPacketDelegate
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_transferPacketDelegate == null)
|
||||
{
|
||||
_transferPacketDelegate = new PacketDelegate(TransferPacketHandler);
|
||||
}
|
||||
return _transferPacketDelegate;
|
||||
}
|
||||
}
|
||||
|
||||
private PacketDelegate _transferInfoDelegate;
|
||||
private PacketDelegate transferInfoDelegate
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_transferInfoDelegate == null)
|
||||
{
|
||||
_transferInfoDelegate = new PacketDelegate(TransferInfoHandler);
|
||||
}
|
||||
return _transferInfoDelegate;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
//map of built in SL animations and their overrides
|
||||
private Dictionary<LLUUID,LLUUID> overrides = new Dictionary<LLUUID,LLUUID>();
|
||||
|
||||
//list of animations currently running
|
||||
private Dictionary<LLUUID, int> SignaledAnimations = new Dictionary<LLUUID, int>();
|
||||
|
||||
//playing status of animations'override animation
|
||||
private Dictionary<LLUUID, bool> overrideanimationisplaying;
|
||||
|
||||
//Current inventory path search
|
||||
string[] searchPath;
|
||||
//Search level
|
||||
int searchLevel;
|
||||
//Current folder
|
||||
LLUUID currentFolder;
|
||||
// Number of directory descendents received
|
||||
int nbdescendantsreceived;
|
||||
//List of items in the current folder
|
||||
Dictionary<string,InventoryItem> currentFolderItems;
|
||||
//Asset download request ID
|
||||
LLUUID assetdownloadID;
|
||||
//Downloaded bytes so far
|
||||
int downloadedbytes;
|
||||
//size of download
|
||||
int downloadsize;
|
||||
//data buffer
|
||||
byte[] buffer;
|
||||
|
||||
|
||||
public ClientAO(ProxyFrame frame)
|
||||
{
|
||||
this.frame = frame;
|
||||
this.proxy = frame.proxy;
|
||||
}
|
||||
|
||||
//Initialise the plugin
|
||||
public override void Init()
|
||||
{
|
||||
//libslAssembly = Assembly.Load("libsecondlife");
|
||||
//if (libslAssembly == null) throw new Exception("Assembly load exception");
|
||||
|
||||
// build the table of /command delegates
|
||||
InitializeCommandDelegates();
|
||||
|
||||
SayToUser("ClientAO loaded");
|
||||
}
|
||||
|
||||
// InitializeCommandDelegates: configure ClientAO's commands
|
||||
private void InitializeCommandDelegates()
|
||||
{
|
||||
//The ClientAO responds to command beginning with /ao
|
||||
frame.AddCommand("/ao", new ProxyFrame.CommandDelegate(CmdAO));
|
||||
}
|
||||
|
||||
//Process commands from the user
|
||||
private void CmdAO(string[] words) {
|
||||
if (words.Length < 2)
|
||||
{
|
||||
SayToUser("Usage: /ao on/off/notecard path");
|
||||
}
|
||||
else if (words[1] == "on")
|
||||
{
|
||||
//Turn AO on
|
||||
AOOn();
|
||||
SayToUser("AO started");
|
||||
}
|
||||
else if (words[1] == "off")
|
||||
{
|
||||
//Turn AO off
|
||||
AOOff();
|
||||
SayToUser("AO stopped");
|
||||
}
|
||||
else
|
||||
{
|
||||
//Load notecard from path
|
||||
//exemple: /ao Objects/My AOs/wetikon/config.txt
|
||||
string[] tmp = new string[words.Length - 1];
|
||||
//join the arguments together with spaces, to
|
||||
//take care of folder and item names with spaces in them
|
||||
for (int i = 1; i < words.Length; i++)
|
||||
{
|
||||
tmp[i - 1] = words[i];
|
||||
}
|
||||
// add a delegate to monitor inventory infos
|
||||
proxy.AddDelegate(PacketType.InventoryDescendents, Direction.Incoming, this.inventoryPacketDelegate);
|
||||
RequestFindObjectByPath(frame.InventoryRoot, String.Join(" ", tmp));
|
||||
}
|
||||
}
|
||||
|
||||
private void AOOn()
|
||||
{
|
||||
// add a delegate to track agent movements
|
||||
proxy.AddDelegate(PacketType.AvatarAnimation, Direction.Incoming, this.packetDelegate);
|
||||
}
|
||||
|
||||
private void AOOff()
|
||||
{
|
||||
// remove the delegate to track agent movements
|
||||
proxy.RemoveDelegate(PacketType.AvatarAnimation, Direction.Incoming, this.packetDelegate);
|
||||
//Stop all override animations
|
||||
foreach (LLUUID tmp in overrides.Values)
|
||||
{
|
||||
Animate(tmp, false);
|
||||
}
|
||||
}
|
||||
|
||||
// Inventory functions
|
||||
|
||||
//start requesting an item by its path
|
||||
public void RequestFindObjectByPath(LLUUID baseFolder, string path)
|
||||
{
|
||||
if (path == null || path.Length == 0)
|
||||
throw new ArgumentException("Empty path is not supported");
|
||||
currentFolder = baseFolder;
|
||||
//split path by '/'
|
||||
searchPath = path.Split('/');
|
||||
//search for first element in the path
|
||||
searchLevel = 0;
|
||||
|
||||
// Start the search
|
||||
RequestFolderContents(baseFolder,
|
||||
true,
|
||||
(searchPath.Length == 1) ? true : false,
|
||||
InventorySortOrder.ByName);
|
||||
}
|
||||
|
||||
//request a folder content
|
||||
public void RequestFolderContents(LLUUID folder, bool folders, bool items,
|
||||
InventorySortOrder order)
|
||||
{
|
||||
//empty the dictionnary containing current folder items by name
|
||||
currentFolderItems = new Dictionary<string, InventoryItem>();
|
||||
//reset the number of descendants received
|
||||
nbdescendantsreceived = 0;
|
||||
//build a packet to request the content
|
||||
FetchInventoryDescendentsPacket fetch = new FetchInventoryDescendentsPacket();
|
||||
fetch.AgentData.AgentID = frame.AgentID;
|
||||
fetch.AgentData.SessionID = frame.SessionID;
|
||||
|
||||
fetch.InventoryData.FetchFolders = folders;
|
||||
fetch.InventoryData.FetchItems = items;
|
||||
fetch.InventoryData.FolderID = folder;
|
||||
fetch.InventoryData.OwnerID = frame.AgentID; //is it correct?
|
||||
fetch.InventoryData.SortOrder = (int)order;
|
||||
|
||||
//send packet to SL
|
||||
proxy.InjectPacket(fetch, Direction.Outgoing);
|
||||
}
|
||||
|
||||
//process the reply from SL
|
||||
private Packet InventoryDescendentsHandler(Packet packet, IPEndPoint sim)
|
||||
{
|
||||
bool intercept = false;
|
||||
InventoryDescendentsPacket reply = (InventoryDescendentsPacket)packet;
|
||||
|
||||
if (reply.AgentData.Descendents > 0
|
||||
&& reply.AgentData.FolderID == currentFolder)
|
||||
{
|
||||
//SayToUser("nb descendents: " + reply.AgentData.Descendents);
|
||||
//this packet concerns the folder we asked for
|
||||
if (reply.FolderData[0].FolderID != LLUUID.Zero
|
||||
&& searchLevel < searchPath.Length - 1)
|
||||
{
|
||||
nbdescendantsreceived += reply.FolderData.Length;
|
||||
//SayToUser("nb received: " + nbdescendantsreceived);
|
||||
//folders are present, and we are not at end of path.
|
||||
//look at them
|
||||
for (int i = 0; i < reply.FolderData.Length; i++)
|
||||
{
|
||||
//SayToUser("Folder: " + Helpers.FieldToUTF8String(reply.FolderData[i].Name));
|
||||
if (searchPath[searchLevel] == Helpers.FieldToUTF8String(reply.FolderData[i].Name)) {
|
||||
//We found the next folder in the path
|
||||
currentFolder = reply.FolderData[i].FolderID;
|
||||
if (searchLevel < searchPath.Length - 1)
|
||||
{
|
||||
// ask for next item in path
|
||||
searchLevel++;
|
||||
RequestFolderContents(currentFolder,
|
||||
true,
|
||||
(searchLevel < searchPath.Length - 1) ? false : true,
|
||||
InventorySortOrder.ByName);
|
||||
//Jump to end
|
||||
goto End;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nbdescendantsreceived >= reply.AgentData.Descendents)
|
||||
{
|
||||
//We have not found the folder. The user probably mistyped it
|
||||
SayToUser("Didn't find folder " + searchPath[searchLevel]);
|
||||
//Stop looking at packets
|
||||
proxy.RemoveDelegate(PacketType.InventoryDescendents, Direction.Incoming, this.inventoryPacketDelegate);
|
||||
}
|
||||
}
|
||||
else if (searchLevel < searchPath.Length - 1)
|
||||
{
|
||||
//There are no folders in the packet ; but we are looking for one!
|
||||
//We have not found the folder. The user probably mistyped it
|
||||
SayToUser("Didn't find folder " + searchPath[searchLevel]);
|
||||
//Stop looking at packets
|
||||
proxy.RemoveDelegate(PacketType.InventoryDescendents, Direction.Incoming, this.inventoryPacketDelegate);
|
||||
}
|
||||
else
|
||||
{
|
||||
//There are folders in the packet. And we are at the end of
|
||||
//the path, count their number in nbdescendantsreceived
|
||||
nbdescendantsreceived += reply.FolderData.Length;
|
||||
//SayToUser("nb received: " + nbdescendantsreceived);
|
||||
}
|
||||
if (reply.ItemData[0].ItemID != LLUUID.Zero
|
||||
&& searchLevel == searchPath.Length - 1)
|
||||
{
|
||||
//there are items returned and we are looking for one
|
||||
//(end of search path)
|
||||
//count them
|
||||
nbdescendantsreceived += reply.ItemData.Length;
|
||||
//SayToUser("nb received: " + nbdescendantsreceived);
|
||||
for (int i = 0; i < reply.ItemData.Length; i++)
|
||||
{
|
||||
//we are going to store info on all items. we'll need
|
||||
//it to get the asset ID of animations refered to by the
|
||||
//configuration notecard
|
||||
if (reply.ItemData[i].ItemID != LLUUID.Zero)
|
||||
{
|
||||
InventoryItem item = CreateInventoryItem((InventoryType)reply.ItemData[i].InvType, reply.ItemData[i].ItemID);
|
||||
item.ParentUUID = reply.ItemData[i].FolderID;
|
||||
item.CreatorID = reply.ItemData[i].CreatorID;
|
||||
item.AssetType = (AssetType)reply.ItemData[i].Type;
|
||||
item.AssetUUID = reply.ItemData[i].AssetID;
|
||||
item.CreationDate = Helpers.UnixTimeToDateTime((uint)reply.ItemData[i].CreationDate);
|
||||
item.Description = Helpers.FieldToUTF8String(reply.ItemData[i].Description);
|
||||
item.Flags = (uint)reply.ItemData[i].Flags;
|
||||
item.Name = Helpers.FieldToUTF8String(reply.ItemData[i].Name);
|
||||
item.GroupID = reply.ItemData[i].GroupID;
|
||||
item.GroupOwned = reply.ItemData[i].GroupOwned;
|
||||
item.Permissions = new Permissions(
|
||||
reply.ItemData[i].BaseMask,
|
||||
reply.ItemData[i].EveryoneMask,
|
||||
reply.ItemData[i].GroupMask,
|
||||
reply.ItemData[i].NextOwnerMask,
|
||||
reply.ItemData[i].OwnerMask);
|
||||
item.SalePrice = reply.ItemData[i].SalePrice;
|
||||
item.SaleType = (SaleType)reply.ItemData[i].SaleType;
|
||||
item.OwnerID = reply.AgentData.OwnerID;
|
||||
|
||||
//SayToUser("item in folder: " + item.Name);
|
||||
|
||||
//Add the item to the name -> item hash
|
||||
currentFolderItems.Add(item.Name, item);
|
||||
}
|
||||
}
|
||||
if (nbdescendantsreceived >= reply.AgentData.Descendents)
|
||||
{
|
||||
//We have received all the items in the last folder
|
||||
//Let's look for the item we are looking for
|
||||
if (currentFolderItems.ContainsKey(searchPath[searchLevel]))
|
||||
{
|
||||
//We found what we where looking for
|
||||
//Stop looking at packets
|
||||
proxy.RemoveDelegate(PacketType.InventoryDescendents, Direction.Incoming, this.inventoryPacketDelegate);
|
||||
//Download the notecard
|
||||
assetdownloadID = RequestInventoryAsset(currentFolderItems[searchPath[searchLevel]]);
|
||||
}
|
||||
else
|
||||
{
|
||||
//We didnt find the item, the user probably mistyped its name
|
||||
SayToUser("Didn't find notecard " + searchPath[searchLevel]);
|
||||
//TODO: keep looking for a moment, or else reply packets may still
|
||||
//come in case of a very large inventory folder
|
||||
//Stop looking at packets
|
||||
proxy.RemoveDelegate(PacketType.InventoryDescendents, Direction.Incoming, this.inventoryPacketDelegate);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (searchLevel == searchPath.Length - 1 && nbdescendantsreceived >= reply.AgentData.Descendents)
|
||||
{
|
||||
//There are no items in the packet, but we are looking for one!
|
||||
//We didnt find the item, the user probably mistyped its name
|
||||
SayToUser("Didn't find notecard " + searchPath[searchLevel]);
|
||||
//TODO: keep looking for a moment, or else reply packets may still
|
||||
//come in case of a very large inventory folder
|
||||
//Stop looking at packets
|
||||
proxy.RemoveDelegate(PacketType.InventoryDescendents, Direction.Incoming, this.inventoryPacketDelegate);
|
||||
}
|
||||
//Intercept the packet, it was a reply to our request. No need
|
||||
//to confuse the actual SL client
|
||||
intercept = true;
|
||||
}
|
||||
End:
|
||||
if (intercept)
|
||||
{
|
||||
//stop packet
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
//let packet go to client
|
||||
return packet;
|
||||
}
|
||||
}
|
||||
|
||||
public static InventoryItem CreateInventoryItem(InventoryType type, LLUUID id)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case InventoryType.Texture: return new InventoryTexture(id);
|
||||
case InventoryType.Sound: return new InventorySound(id);
|
||||
case InventoryType.CallingCard: return new InventoryCallingCard(id);
|
||||
case InventoryType.Landmark: return new InventoryLandmark(id);
|
||||
case InventoryType.Object: return new InventoryObject(id);
|
||||
case InventoryType.Notecard: return new InventoryNotecard(id);
|
||||
case InventoryType.Category: return new InventoryCategory(id);
|
||||
case InventoryType.LSL: return new InventoryLSL(id);
|
||||
case InventoryType.Snapshot: return new InventorySnapshot(id);
|
||||
case InventoryType.Attachment: return new InventoryAttachment(id);
|
||||
case InventoryType.Wearable: return new InventoryWearable(id);
|
||||
case InventoryType.Animation: return new InventoryAnimation(id);
|
||||
case InventoryType.Gesture: return new InventoryGesture(id);
|
||||
default: return new InventoryItem(type, id);
|
||||
}
|
||||
}
|
||||
|
||||
//Ask for download of an item
|
||||
public LLUUID RequestInventoryAsset(InventoryItem item)
|
||||
{
|
||||
// Build the request packet and send it
|
||||
TransferRequestPacket request = new TransferRequestPacket();
|
||||
request.TransferInfo.ChannelType = (int)ChannelType.Asset;
|
||||
request.TransferInfo.Priority = 101.0f;
|
||||
request.TransferInfo.SourceType = (int)SourceType.SimInventoryItem;
|
||||
LLUUID transferID = LLUUID.Random();
|
||||
request.TransferInfo.TransferID = transferID;
|
||||
|
||||
byte[] paramField = new byte[100];
|
||||
Buffer.BlockCopy(frame.AgentID.GetBytes(), 0, paramField, 0, 16);
|
||||
Buffer.BlockCopy(frame.SessionID.GetBytes(), 0, paramField, 16, 16);
|
||||
Buffer.BlockCopy(item.OwnerID.GetBytes(), 0, paramField, 32, 16);
|
||||
Buffer.BlockCopy(LLUUID.Zero.GetBytes(), 0, paramField, 48, 16);
|
||||
Buffer.BlockCopy(item.UUID.GetBytes(), 0, paramField, 64, 16);
|
||||
Buffer.BlockCopy(item.AssetUUID.GetBytes(), 0, paramField, 80, 16);
|
||||
Buffer.BlockCopy(Helpers.IntToBytes((int)item.AssetType), 0, paramField, 96, 4);
|
||||
request.TransferInfo.Params = paramField;
|
||||
|
||||
// add a delegate to monitor configuration notecards download
|
||||
proxy.AddDelegate(PacketType.TransferPacket, Direction.Incoming, this.transferPacketDelegate);
|
||||
|
||||
//send packet to SL
|
||||
proxy.InjectPacket(request, Direction.Outgoing);
|
||||
|
||||
//so far we downloaded 0 bytes
|
||||
downloadedbytes = 0;
|
||||
//the total size of the download is yet unknown
|
||||
downloadsize = 0;
|
||||
//A 100K buffer should be enough for everyone
|
||||
buffer = new byte[1024 * 100];
|
||||
//Return the transfer ID
|
||||
return transferID;
|
||||
}
|
||||
|
||||
// SayToUser: send a message to the user as in-world chat
|
||||
private void SayToUser(string message)
|
||||
{
|
||||
ChatFromSimulatorPacket packet = new ChatFromSimulatorPacket();
|
||||
packet.ChatData.FromName = Helpers.StringToField("ClientAO");
|
||||
packet.ChatData.SourceID = LLUUID.Random();
|
||||
packet.ChatData.OwnerID = frame.AgentID;
|
||||
packet.ChatData.SourceType = (byte)2;
|
||||
packet.ChatData.ChatType = (byte)1;
|
||||
packet.ChatData.Audible = (byte)1;
|
||||
packet.ChatData.Position = new LLVector3(0, 0, 0);
|
||||
packet.ChatData.Message = Helpers.StringToField(message);
|
||||
proxy.InjectPacket(packet, Direction.Incoming);
|
||||
}
|
||||
|
||||
//start or stop an animation
|
||||
public void Animate(LLUUID animationuuid, bool run)
|
||||
{
|
||||
AgentAnimationPacket animate = new AgentAnimationPacket();
|
||||
animate.Header.Reliable = true;
|
||||
animate.AgentData.AgentID = frame.AgentID;
|
||||
animate.AgentData.SessionID = frame.SessionID;
|
||||
//We send one animation
|
||||
animate.AnimationList = new AgentAnimationPacket.AnimationListBlock[1];
|
||||
animate.AnimationList[0] = new AgentAnimationPacket.AnimationListBlock();
|
||||
animate.AnimationList[0].AnimID = animationuuid;
|
||||
animate.AnimationList[0].StartAnim = run;
|
||||
|
||||
//SayToUser("anim " + animname(animationuuid) + " " + run);
|
||||
proxy.InjectPacket(animate, Direction.Outgoing);
|
||||
}
|
||||
|
||||
//return the name of an animation by its UUID
|
||||
private string animname(LLUUID arg)
|
||||
{
|
||||
return animuid2name[arg];
|
||||
}
|
||||
|
||||
//handle animation packets from simulator
|
||||
private Packet AnimationPacketHandler(Packet packet, IPEndPoint sim) {
|
||||
AvatarAnimationPacket animation = (AvatarAnimationPacket)packet;
|
||||
|
||||
if (animation.Sender.ID == frame.AgentID)
|
||||
{
|
||||
//the received animation packet is about our Agent, handle it
|
||||
lock (SignaledAnimations)
|
||||
{
|
||||
// Reset the signaled animation list
|
||||
SignaledAnimations.Clear();
|
||||
//fill it with the fresh list from simulator
|
||||
for (int i = 0; i < animation.AnimationList.Length; i++)
|
||||
{
|
||||
LLUUID animID = animation.AnimationList[i].AnimID;
|
||||
int sequenceID = animation.AnimationList[i].AnimSequenceID;
|
||||
|
||||
// Add this animation to the list of currently signaled animations
|
||||
SignaledAnimations[animID] = sequenceID;
|
||||
//SayToUser("Animation: " + animname(animID));
|
||||
}
|
||||
}
|
||||
|
||||
//we now have a list of currently running animations
|
||||
//Start override animations if necessary
|
||||
foreach (LLUUID key in overrides.Keys)
|
||||
{
|
||||
//For each overriden animation key, test if its override is running
|
||||
if (SignaledAnimations.ContainsKey(key) && (!overrideanimationisplaying[key] ))
|
||||
{
|
||||
//An overriden animation is present and its override animation
|
||||
//isnt currently playing
|
||||
//Start the override animation
|
||||
//SayToUser("animation " + animname(key) + " started, will override with " + animname(overrides[key]));
|
||||
overrideanimationisplaying[key] = true;
|
||||
Animate(overrides[key], true);
|
||||
}
|
||||
else if ((!SignaledAnimations.ContainsKey(key)) && overrideanimationisplaying[key])
|
||||
{
|
||||
//an override animation is currently playing, but it's overriden
|
||||
//animation is not.
|
||||
//stop the override animation
|
||||
//SayToUser("animation " + animname(key) + " stopped, will override with " + animname(overrides[key]));
|
||||
overrideanimationisplaying[key] = false;
|
||||
Animate(overrides[key], false);
|
||||
}
|
||||
}
|
||||
}
|
||||
//Let the packet go to the client
|
||||
return packet;
|
||||
}
|
||||
|
||||
//handle packets that contain info about the notecard data transfer
|
||||
private Packet TransferInfoHandler(Packet packet, IPEndPoint simulator)
|
||||
{
|
||||
TransferInfoPacket info = (TransferInfoPacket)packet;
|
||||
|
||||
if (info.TransferInfo.TransferID == assetdownloadID)
|
||||
{
|
||||
//this is our requested tranfer, handle it
|
||||
downloadsize = info.TransferInfo.Size;
|
||||
|
||||
if ((StatusCode)info.TransferInfo.Status != StatusCode.OK)
|
||||
{
|
||||
SayToUser("Failed to read notecard");
|
||||
}
|
||||
if (downloadedbytes >= downloadsize)
|
||||
{
|
||||
//Download already completed!
|
||||
downloadCompleted();
|
||||
}
|
||||
//intercept packet
|
||||
return null;
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
|
||||
//handle packets which contain the notecard data
|
||||
private Packet TransferPacketHandler(Packet packet, IPEndPoint simulator)
|
||||
{
|
||||
TransferPacketPacket asset = (TransferPacketPacket)packet;
|
||||
|
||||
if (asset.TransferData.TransferID == assetdownloadID) {
|
||||
Buffer.BlockCopy(asset.TransferData.Data, 0, buffer, 1000 * asset.TransferData.Packet,
|
||||
asset.TransferData.Data.Length);
|
||||
downloadedbytes += asset.TransferData.Data.Length;
|
||||
|
||||
// Check if we downloaded the full asset
|
||||
if (downloadedbytes >= downloadsize)
|
||||
{
|
||||
downloadCompleted();
|
||||
}
|
||||
//Intercept packet
|
||||
return null;
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
|
||||
private void downloadCompleted()
|
||||
{
|
||||
//We have the notecard.
|
||||
//Stop looking at transfer packets
|
||||
proxy.RemoveDelegate(PacketType.TransferPacket, Direction.Incoming, this.transferPacketDelegate);
|
||||
//crop the buffer size
|
||||
byte[] tmp = new byte[downloadedbytes];
|
||||
Buffer.BlockCopy(buffer, 0, tmp, 0, downloadedbytes);
|
||||
buffer = tmp;
|
||||
String notecardtext = getNotecardText(Helpers.FieldToUTF8String(buffer));
|
||||
|
||||
//Load config, wetikon format
|
||||
loadWetIkon(notecardtext);
|
||||
}
|
||||
|
||||
private void loadWetIkon(string config)
|
||||
{
|
||||
//Reinitialise override table
|
||||
overrides = new Dictionary<LLUUID,LLUUID>();
|
||||
overrideanimationisplaying = new Dictionary<LLUUID, bool>();
|
||||
|
||||
animuid2name = new Dictionary<LLUUID,string>();
|
||||
foreach (LLUUID key in wetikonanims )
|
||||
{
|
||||
animuid2name[key] = wetikonanimnames[Array.IndexOf(wetikonanims, key)];
|
||||
}
|
||||
|
||||
//list of animations in wetikon
|
||||
|
||||
//read every second line in the config
|
||||
char[] sep = { '\n' };
|
||||
string[] lines = config.Split(sep);
|
||||
int length = lines.Length;
|
||||
int i = 1;
|
||||
while (i < length) {
|
||||
//Read animation name and look it up
|
||||
string animname = lines[i].Trim();
|
||||
//SayToUser("anim: " + animname);
|
||||
if (animname != "")
|
||||
{
|
||||
if (currentFolderItems.ContainsKey(animname))
|
||||
{
|
||||
LLUUID over = currentFolderItems[animname].AssetUUID;
|
||||
LLUUID orig = wetikonanims[((i + 1) / 2) - 1];
|
||||
//put it in overrides
|
||||
animuid2name[over] = animname;
|
||||
overrides[orig] = over;
|
||||
overrideanimationisplaying[orig] = false;
|
||||
//SayToUser(wetikonanimnames[((i + 1) / 2) - 1] + " overriden by " + animname + " ( " + over + ")");
|
||||
}
|
||||
else
|
||||
{
|
||||
//Not found
|
||||
SayToUser(animname + " not found.");
|
||||
}
|
||||
}
|
||||
i += 2;
|
||||
}
|
||||
SayToUser("Notecard read, " + overrides.Count + " animations found");
|
||||
}
|
||||
|
||||
private string getNotecardText(string data)
|
||||
{
|
||||
// Version 1 format:
|
||||
// Linden text version 1
|
||||
// {
|
||||
// <EmbeddedItemList chunk>
|
||||
// Text length
|
||||
// <ASCII text; 0x80 | index = embedded item>
|
||||
// }
|
||||
|
||||
// Version 2 format: (NOTE: Imports identically to version 1)
|
||||
// Linden text version 2
|
||||
// {
|
||||
// <EmbeddedItemList chunk>
|
||||
// Text length
|
||||
// <UTF8 text; FIRST_EMBEDDED_CHAR + index = embedded item>
|
||||
// }
|
||||
int i = 0;
|
||||
char[] sep = { '\n' };
|
||||
string[] lines = data.Split(sep);
|
||||
int length = lines.Length;
|
||||
string result = "";
|
||||
|
||||
//check format
|
||||
if (!lines[i].StartsWith("Linden text version "))
|
||||
{
|
||||
SayToUser("error");
|
||||
return "";
|
||||
}
|
||||
|
||||
//{
|
||||
i++;
|
||||
if (lines[i] != "{")
|
||||
{
|
||||
SayToUser("error");
|
||||
return "";
|
||||
}
|
||||
|
||||
i++;
|
||||
if (lines[i] != "LLEmbeddedItems version 1")
|
||||
{
|
||||
SayToUser("error");
|
||||
return "";
|
||||
}
|
||||
|
||||
//{
|
||||
i++;
|
||||
if (lines[i] != "{")
|
||||
{
|
||||
SayToUser("error");
|
||||
return "";
|
||||
}
|
||||
|
||||
//count ...
|
||||
i++;
|
||||
if (!lines[i].StartsWith("count "))
|
||||
{
|
||||
SayToUser("error");
|
||||
return "";
|
||||
}
|
||||
|
||||
//}
|
||||
i++;
|
||||
if (lines[i] != "}")
|
||||
{
|
||||
SayToUser("error");
|
||||
return "";
|
||||
}
|
||||
|
||||
//Text length ...
|
||||
i++;
|
||||
if (!lines[i].StartsWith("Text length "))
|
||||
{
|
||||
SayToUser("error");
|
||||
return "";
|
||||
}
|
||||
|
||||
i++;
|
||||
while (i < length)
|
||||
{
|
||||
result += lines[i] + "\n";
|
||||
i++;
|
||||
}
|
||||
result = result.Substring(0, result.Length - 3);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
57
Programs/SLProxy/ClientAO/ClientAO/ClientAO.csproj
Normal file
57
Programs/SLProxy/ClientAO/ClientAO/ClientAO.csproj
Normal file
@@ -0,0 +1,57 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.50727</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{173E70E4-44EE-440C-AD59-1CCD0BF03AC1}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>ClientAO</RootNamespace>
|
||||
<AssemblyName>ClientAO</AssemblyName>
|
||||
<StartupObject>
|
||||
</StartupObject>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>..\..\..\bin\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\..\..\bin\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
<ItemGroup>
|
||||
<Compile Include="ClientAO.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="libsecondlife, Version=0.9.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\bin\libsecondlife.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\SLProxy.csproj">
|
||||
<Project>{E4115DC9-FC88-47D6-B3B6-2400AD19B80D}</Project>
|
||||
<Name>SLProxy</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
35
Programs/SLProxy/ClientAO/README.txt
Normal file
35
Programs/SLProxy/ClientAO/README.txt
Normal file
@@ -0,0 +1,35 @@
|
||||
ClientAO by Issarlk Chatnoir
|
||||
|
||||
|
||||
|
||||
What is it?
|
||||
***********
|
||||
|
||||
ClientAO is an implementation of an animation overrider running as a plugin for SLProxy.
|
||||
Since it runs on the local computer and not on SL's server, this AO has no impact on sim
|
||||
performance and lag. Also, it reacts to animation changes instantly instead of having to
|
||||
poll the avatar state every so often, like inworld AO.
|
||||
|
||||
Instead of using an object like a regular AO, you point it to a folder in your inventory
|
||||
containing the animations and a configuration notecard.
|
||||
|
||||
The AO understands "wetikon" type notecards (see sample)
|
||||
|
||||
|
||||
How to use
|
||||
**********
|
||||
- Run SLProxy and start your SecondLife client so that it connects through the Proxy
|
||||
(ex: SecondLife.exe ...(usual options here)... -loginuri http://localhost:8080/ )
|
||||
|
||||
- Login like usual
|
||||
|
||||
- once logged in, load the ClientAO plugin: /load ClientAO.dll
|
||||
|
||||
- Point it to a folder where you have previously put animations and a configuration
|
||||
notecard, ex: /ao Objects/MyAO/*Default Anims
|
||||
|
||||
The AO will load the notecard.
|
||||
|
||||
- start the AO: /ao on
|
||||
|
||||
The AO should now replace your animations.
|
||||
54
Programs/SLProxy/ClientAO/configuration sample.txt
Normal file
54
Programs/SLProxy/ClientAO/configuration sample.txt
Normal file
@@ -0,0 +1,54 @@
|
||||
:: [ Walking (also Striding) ] ::
|
||||
|
||||
:: [ Running ] ::
|
||||
|
||||
:: [ CrouchWalking ] ::
|
||||
|
||||
:: [ Flying (also FlyingSlow) ] ::
|
||||
|
||||
:: [ Turning Left ] ::
|
||||
|
||||
:: [ Turning Right ] ::
|
||||
|
||||
:: [ Jumping ] ::
|
||||
|
||||
:: [ Hovering Up ] ::
|
||||
|
||||
:: [ Crouching ] ::
|
||||
|
||||
:: [ Fly Down ] ::
|
||||
|
||||
:: [ Standing 1 ] ::
|
||||
|
||||
:: [ Standing 2 ] ::
|
||||
|
||||
:: [ Standing 3 ] ::
|
||||
|
||||
:: [ Standing 4 ] ::
|
||||
|
||||
:: [ Standing 5 ] ::
|
||||
|
||||
:: [ Hovering ] ::
|
||||
|
||||
:: [ Sitting ] ::
|
||||
|
||||
:: [ PreJumping ] ::
|
||||
|
||||
:: [ Falling ] ::
|
||||
|
||||
:: [ Soft Landing/Landing ] ::
|
||||
|
||||
:: [ Standing Up (That anim you play after you fall when you stand up and brush yourself off) ] ::
|
||||
|
||||
:: [ FlyingSlow ] ::
|
||||
|
||||
:: [ Sitting on Ground ] ::
|
||||
|
||||
:: [ Floating (Hovering underwater) ] ::
|
||||
|
||||
:: [ Swimming Forward (Flying underwater) ] ::
|
||||
|
||||
:: [ Swimming Up (Hover Up underwater) ] ::
|
||||
|
||||
:: [ Swimming Down (Fly Down underwater) ] ::
|
||||
|
||||
1
Programs/SLProxy/README.txt
Normal file
1
Programs/SLProxy/README.txt
Normal file
@@ -0,0 +1 @@
|
||||
All information about SLProxy can be found on the libsecondlife wiki at http://www.libsecondlife.org/wiki/SLProxy
|
||||
153
Programs/SLProxy/SLProxy.build
Normal file
153
Programs/SLProxy/SLProxy.build
Normal file
@@ -0,0 +1,153 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<project name="libsecondlife" default="build">
|
||||
|
||||
<!-- global framework settings -->
|
||||
<property name="target.framework" value="${framework::get-target-framework()}" />
|
||||
<property name="assembly.dir" value="${framework::get-assembly-directory(target.framework)}" />
|
||||
|
||||
<!-- global project settings -->
|
||||
<xmlpeek
|
||||
file="../libsecondlife.build"
|
||||
xpath="/project/property[@name = 'project.version']/@value"
|
||||
property="project.version" />
|
||||
<property name="build.number"
|
||||
value="${math::abs(math::floor(timespan::get-total-days(datetime::now()
|
||||
- datetime::parse('01/01/2002'))))}" />
|
||||
<property name="assembly" value="SLProxy"/>
|
||||
<property name="bin_dir" value="../bin" />
|
||||
|
||||
<!-- default configuration -->
|
||||
<property name="project.config" value="debug" /> <!-- debug|release -->
|
||||
|
||||
<!-- named configurations -->
|
||||
<target name="init" description="Initializes build properties">
|
||||
<call target="${project.config}" />
|
||||
</target>
|
||||
|
||||
<target name="debug" description="configures a debug build">
|
||||
<property name="build.debug" value="true" />
|
||||
<property name="package.name"
|
||||
value="${project::get-name()}-${project.version}-${project.config}" />
|
||||
<property name="assembly.configuration"
|
||||
value="${framework::get-target-framework()}.${platform::get-name()} [${project.config}]" />
|
||||
</target>
|
||||
|
||||
<target name="release" description="configures a release build">
|
||||
<property name="project.config" value="release" />
|
||||
<property name="build.debug" value="false" />
|
||||
<property name="package.name"
|
||||
value="${project::get-name()}-${project.version}" />
|
||||
<property name="assembly.configuration"
|
||||
value="${framework::get-target-framework()}.${platform::get-name()}" />
|
||||
</target>
|
||||
|
||||
<!-- build tasks -->
|
||||
<!-- target name="build" depends="build-analyst build-chatconsole build-main"
|
||||
description="build analyst and chatconsole"
|
||||
FIXME: Analyst's build is broken and Analyst and SLProxyLoader have
|
||||
circular dependencies. Skipping Analyst for now. -axial -->
|
||||
<target name="build" depends="build-analyst build-slproxy build-chatconsole build-main"
|
||||
description="build SLProxy and chatconsole">
|
||||
</target>
|
||||
|
||||
<target name="build-slproxy" depends="init"
|
||||
description="Builds the binaries for the current configuration">
|
||||
<echo message="Build Directory is ${bin_dir}/" />
|
||||
<mkdir dir="${bin_dir}" failonerror="false" />
|
||||
<csc
|
||||
target="library"
|
||||
debug="${build.debug}"
|
||||
output="${bin_dir}/SLProxy.dll">
|
||||
<sources failonempty="true">
|
||||
<include name="SLProxy.cs" />
|
||||
<include name="XmlRpcCS/*.cs" />
|
||||
<include name="SLProxyLoader.cs" />
|
||||
<!-- <include name="legacy/*.cs" /> -->
|
||||
</sources>
|
||||
<references basedir="${bin_dir}/">
|
||||
<include name="libsecondlife.dll"/>
|
||||
</references>
|
||||
</csc>
|
||||
</target>
|
||||
|
||||
<target name="build-analyst" depends="init build-slproxy"
|
||||
description="Builds the binaries for the current configuration">
|
||||
<echo message="Build Directory is ${bin_dir}/" />
|
||||
<mkdir dir="${bin_dir}" failonerror="false" />
|
||||
<csc
|
||||
target="library"
|
||||
debug="${build.debug}"
|
||||
output="${bin_dir}/Analyst.dll">
|
||||
<sources failonempty="true">
|
||||
<include name="Analyst.cs" />
|
||||
<!-- <include name="legacy/*.cs" /> -->
|
||||
</sources>
|
||||
<references basedir="${bin_dir}/">
|
||||
<include name="libsecondlife.dll"/>
|
||||
<include name="SLProxy.dll"/>
|
||||
</references>
|
||||
</csc>
|
||||
</target>
|
||||
|
||||
<!-- Note - please, please, PLEASE, refrain from calling the executable
|
||||
SLProxy.exe, as the name conflict with SLProxy.dll confuses Mono -->
|
||||
<target name="build-main"
|
||||
depends="init build-slproxy"
|
||||
description="build SLProxy main">
|
||||
<echo message="Build Directory is ${bin_dir}/" />
|
||||
<mkdir dir="${bin_dir}" failonerror="false" />
|
||||
<csc
|
||||
target="exe"
|
||||
debug="${build.debug}"
|
||||
output="${bin_dir}/SLProxyMain.exe">
|
||||
<sources failonempty="true">
|
||||
<include name="SLProxyMain.cs" />
|
||||
</sources>
|
||||
<references basedir="${bin_dir}/">
|
||||
<include name="libsecondlife.dll"/>
|
||||
<include name="SLProxy.dll"/>
|
||||
<include name="Analyst.dll"/>
|
||||
</references>
|
||||
</csc>
|
||||
</target>
|
||||
|
||||
<target name="build-chatconsole"
|
||||
depends="init build-slproxy"
|
||||
description="build SLProxy ChatConsole">
|
||||
<echo message="Build Directory is ${bin_dir}/" />
|
||||
<mkdir dir="${bin_dir}" failonerror="false" />
|
||||
<csc
|
||||
target="exe"
|
||||
debug="${build.debug}"
|
||||
output="${bin_dir}/ChatConsole.exe">
|
||||
<sources failonempty="true">
|
||||
<include name="ChatConsole.cs" />
|
||||
</sources>
|
||||
<references basedir="${bin_dir}/">
|
||||
<include name="libsecondlife.dll"/>
|
||||
<include name="SLProxy.dll"/>
|
||||
</references>
|
||||
</csc>
|
||||
</target>
|
||||
|
||||
<target name="clean" depends="init"
|
||||
description="Deletes the current configuration">
|
||||
<delete failonerror="false">
|
||||
<fileset basedir="${bin_dir}/">
|
||||
<include name="SLProxy.dll" />
|
||||
<include name="SLProxy.dll.mdb" />
|
||||
<include name="ChatConsole.exe" />
|
||||
<include name="ChatConsole.exe.mdb" />
|
||||
<include name="Analyst.exe" />
|
||||
<include name="Analyst.exe.mdb" />
|
||||
</fileset>
|
||||
</delete>
|
||||
</target>
|
||||
|
||||
<target
|
||||
name="*"
|
||||
description="Handles unknown targets">
|
||||
<echo message="skipping unknown target" />
|
||||
</target>
|
||||
</project>
|
||||
2127
Programs/SLProxy/SLProxy.cs
Normal file
2127
Programs/SLProxy/SLProxy.cs
Normal file
File diff suppressed because it is too large
Load Diff
140
Programs/SLProxy/SLProxy.csproj
Normal file
140
Programs/SLProxy/SLProxy.csproj
Normal file
@@ -0,0 +1,140 @@
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<ProjectType>Local</ProjectType>
|
||||
<ProductVersion>8.0.50727</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{E4115DC9-FC88-47D6-B3B6-2400AD19B80D}</ProjectGuid>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ApplicationIcon>
|
||||
</ApplicationIcon>
|
||||
<AssemblyKeyContainerName>
|
||||
</AssemblyKeyContainerName>
|
||||
<AssemblyName>SLProxy</AssemblyName>
|
||||
<AssemblyOriginatorKeyFile>
|
||||
</AssemblyOriginatorKeyFile>
|
||||
<DefaultClientScript>JScript</DefaultClientScript>
|
||||
<DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
|
||||
<DefaultTargetSchema>IE50</DefaultTargetSchema>
|
||||
<DelaySign>false</DelaySign>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>SLProxy</RootNamespace>
|
||||
<RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
|
||||
<StartupObject>ProxyMain</StartupObject>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<UpgradeBackupLocation>
|
||||
</UpgradeBackupLocation>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<OutputPath>..\bin\</OutputPath>
|
||||
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
|
||||
<BaseAddress>285212672</BaseAddress>
|
||||
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
|
||||
<ConfigurationOverrideFile>
|
||||
</ConfigurationOverrideFile>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DocumentationFile>
|
||||
</DocumentationFile>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<FileAlignment>4096</FileAlignment>
|
||||
<NoStdLib>false</NoStdLib>
|
||||
<NoWarn>
|
||||
</NoWarn>
|
||||
<Optimize>false</Optimize>
|
||||
<RegisterForComInterop>false</RegisterForComInterop>
|
||||
<RemoveIntegerChecks>false</RemoveIntegerChecks>
|
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<DebugType>full</DebugType>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<OutputPath>..\bin\</OutputPath>
|
||||
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
|
||||
<BaseAddress>285212672</BaseAddress>
|
||||
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
|
||||
<ConfigurationOverrideFile>
|
||||
</ConfigurationOverrideFile>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<DocumentationFile>
|
||||
</DocumentationFile>
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
<FileAlignment>4096</FileAlignment>
|
||||
<NoStdLib>false</NoStdLib>
|
||||
<NoWarn>
|
||||
</NoWarn>
|
||||
<Optimize>true</Optimize>
|
||||
<RegisterForComInterop>false</RegisterForComInterop>
|
||||
<RemoveIntegerChecks>false</RemoveIntegerChecks>
|
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<DebugType>none</DebugType>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release-docs|AnyCPU' ">
|
||||
<OutputPath>bin\Release-docs\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<BaseAddress>285212672</BaseAddress>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>
|
||||
</DebugType>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<CodeAnalysisRuleAssemblies>C:\Program Files\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop\\rules</CodeAnalysisRuleAssemblies>
|
||||
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
|
||||
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System">
|
||||
<Name>System</Name>
|
||||
</Reference>
|
||||
<Reference Include="System.Data">
|
||||
<Name>System.Data</Name>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml">
|
||||
<Name>System.XML</Name>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Analyst.cs" />
|
||||
<Compile Include="SLProxy.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="SLProxyLoader.cs" />
|
||||
<Compile Include="SLProxyMain.cs" />
|
||||
<Compile Include="XmlRpcCS\Logger.cs" />
|
||||
<Compile Include="XmlRpcCS\SimpleHttpRequest.cs" />
|
||||
<Compile Include="XmlRpcCS\XmlRpcBoxcarRequest.cs" />
|
||||
<Compile Include="XmlRpcCS\XmlRpcClientProxy.cs" />
|
||||
<Compile Include="XmlRpcCS\XmlRpcDeserializer.cs" />
|
||||
<Compile Include="XmlRpcCS\XmlRpcErrorCodes.cs" />
|
||||
<Compile Include="XmlRpcCS\XmlRpcException.cs" />
|
||||
<Compile Include="XmlRpcCS\XmlRpcExposedAttribute.cs" />
|
||||
<Compile Include="XmlRpcCS\XmlRpcRequest.cs" />
|
||||
<Compile Include="XmlRpcCS\XmlRpcRequestDeserializer.cs" />
|
||||
<Compile Include="XmlRpcCS\XmlRpcRequestSerializer.cs" />
|
||||
<Compile Include="XmlRpcCS\XmlRpcResponder.cs" />
|
||||
<Compile Include="XmlRpcCS\XmlRpcResponse.cs" />
|
||||
<Compile Include="XmlRpcCS\XmlRpcResponseDeserializer.cs" />
|
||||
<Compile Include="XmlRpcCS\XmlRpcResponseSerializer.cs" />
|
||||
<Compile Include="XmlRpcCS\XmlRpcSerializer.cs" />
|
||||
<Compile Include="XmlRpcCS\XmlRpcServer.cs" />
|
||||
<Compile Include="XmlRpcCS\XmlRpcSystemObject.cs" />
|
||||
<Compile Include="XmlRpcCS\XmlRpcXmlTokens.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\libsecondlife\OpenMetaverse.csproj">
|
||||
<Project>{D9CDEDFB-8169-4B03-B57F-0DF638F044EC}</Project>
|
||||
<Name>OpenMetaverse</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
<PreBuildEvent>
|
||||
</PreBuildEvent>
|
||||
<PostBuildEvent>
|
||||
</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
210
Programs/SLProxy/SLProxyLoader.cs
Normal file
210
Programs/SLProxy/SLProxyLoader.cs
Normal file
@@ -0,0 +1,210 @@
|
||||
using SLProxy;
|
||||
using OpenMetaverse;
|
||||
using Nwc.XmlRpc;
|
||||
using OpenMetaverse.Packets;
|
||||
using System.Reflection;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
|
||||
namespace SLProxy
|
||||
{
|
||||
public class ProxyFrame
|
||||
{
|
||||
public Proxy proxy;
|
||||
private Dictionary<string, CommandDelegate> commandDelegates = new Dictionary<string, CommandDelegate>();
|
||||
private LLUUID agentID;
|
||||
private LLUUID sessionID;
|
||||
private LLUUID inventoryRoot;
|
||||
private bool logLogin = false;
|
||||
private string[] args;
|
||||
|
||||
public delegate void CommandDelegate(string[] words);
|
||||
|
||||
public string[] Args
|
||||
{
|
||||
get { return args; }
|
||||
}
|
||||
|
||||
public LLUUID AgentID
|
||||
{
|
||||
get { return agentID; }
|
||||
}
|
||||
|
||||
public LLUUID SessionID
|
||||
{
|
||||
get { return sessionID; }
|
||||
}
|
||||
|
||||
public LLUUID InventoryRoot
|
||||
{
|
||||
get { return inventoryRoot; }
|
||||
}
|
||||
|
||||
public void AddCommand(string cmd, CommandDelegate deleg)
|
||||
{
|
||||
commandDelegates[cmd] = deleg;
|
||||
}
|
||||
|
||||
public ProxyFrame(string[] args)
|
||||
{
|
||||
//bool externalPlugin = false;
|
||||
this.args = args;
|
||||
|
||||
ProxyConfig proxyConfig = new ProxyConfig("SLProxy", "Austin Jennings / Andrew Ortman", args);
|
||||
proxy = new Proxy(proxyConfig);
|
||||
|
||||
// add delegates for login
|
||||
proxy.SetLoginRequestDelegate(new XmlRpcRequestDelegate(LoginRequest));
|
||||
proxy.SetLoginResponseDelegate(new XmlRpcResponseDelegate(LoginResponse));
|
||||
|
||||
// add a delegate for outgoing chat
|
||||
proxy.AddDelegate(PacketType.ChatFromViewer, Direction.Outgoing, new PacketDelegate(ChatFromViewerOut));
|
||||
|
||||
// handle command line arguments
|
||||
foreach (string arg in args)
|
||||
if (arg == "--log-login")
|
||||
logLogin = true;
|
||||
else if (arg.Substring(0, 2) == "--")
|
||||
{
|
||||
int ipos = arg.IndexOf("=");
|
||||
if (ipos != -1)
|
||||
{
|
||||
string sw = arg.Substring(0, ipos);
|
||||
string val = arg.Substring(ipos + 1);
|
||||
Console.WriteLine("arg '" + sw + "' val '" + val + "'");
|
||||
if (sw == "--load")
|
||||
{
|
||||
//externalPlugin = true;
|
||||
LoadPlugin(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
commandDelegates["/load"] = new CommandDelegate(CmdLoad);
|
||||
}
|
||||
|
||||
private void CmdLoad(string[] words)
|
||||
{
|
||||
if (words.Length != 2)
|
||||
SayToUser("Usage: /load <plugin name>");
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
LoadPlugin(words[1]);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void LoadPlugin(string name)
|
||||
{
|
||||
|
||||
Assembly assembly = Assembly.LoadFile(Path.GetFullPath(name));
|
||||
foreach (Type t in assembly.GetTypes())
|
||||
{
|
||||
try
|
||||
{
|
||||
if (t.IsSubclassOf(typeof(ProxyPlugin)))
|
||||
{
|
||||
ConstructorInfo info = t.GetConstructor(new Type[] { typeof(ProxyFrame) });
|
||||
ProxyPlugin plugin = (ProxyPlugin)info.Invoke(new object[] { this });
|
||||
plugin.Init();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// LoginRequest: dump a login request to the console
|
||||
private void LoginRequest(XmlRpcRequest request)
|
||||
{
|
||||
if (logLogin)
|
||||
{
|
||||
Console.WriteLine("==> Login Request");
|
||||
Console.WriteLine(request);
|
||||
}
|
||||
}
|
||||
|
||||
// Loginresponse: dump a login response to the console
|
||||
private void LoginResponse(XmlRpcResponse response)
|
||||
{
|
||||
System.Collections.Hashtable values = (System.Collections.Hashtable)response.Value;
|
||||
if (values.Contains("agent_id"))
|
||||
agentID = new LLUUID((string)values["agent_id"]);
|
||||
if (values.Contains("session_id"))
|
||||
sessionID = new LLUUID((string)values["session_id"]);
|
||||
if (values.Contains("inventory-root"))
|
||||
{
|
||||
inventoryRoot = new LLUUID(
|
||||
(string)((System.Collections.Hashtable)(((System.Collections.ArrayList)values["inventory-root"])[0]))["folder_id"]
|
||||
);
|
||||
Console.WriteLine("inventory root: " + inventoryRoot);
|
||||
}
|
||||
|
||||
if (logLogin)
|
||||
{
|
||||
Console.WriteLine("<== Login Response");
|
||||
Console.WriteLine(response);
|
||||
}
|
||||
}
|
||||
|
||||
// ChatFromViewerOut: outgoing ChatFromViewer delegate; check for Analyst commands
|
||||
private Packet ChatFromViewerOut(Packet packet, IPEndPoint sim)
|
||||
{
|
||||
// deconstruct the packet
|
||||
ChatFromViewerPacket cpacket = (ChatFromViewerPacket)packet;
|
||||
string message = System.Text.Encoding.UTF8.GetString(cpacket.ChatData.Message).Replace("\0", "");
|
||||
|
||||
if (message.Length > 1 && message[0] == '/')
|
||||
{
|
||||
string[] words = message.Split(' ');
|
||||
if (commandDelegates.ContainsKey(words[0]))
|
||||
{
|
||||
// this is an Analyst command; act on it and drop the chat packet
|
||||
((CommandDelegate)commandDelegates[words[0]])(words);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return packet;
|
||||
}
|
||||
|
||||
// SayToUser: send a message to the user as in-world chat
|
||||
public void SayToUser(string message)
|
||||
{
|
||||
ChatFromSimulatorPacket packet = new ChatFromSimulatorPacket();
|
||||
packet.ChatData.FromName = Helpers.StringToField("SLProxy");
|
||||
packet.ChatData.SourceID = LLUUID.Random();
|
||||
packet.ChatData.OwnerID = agentID;
|
||||
packet.ChatData.SourceType = (byte)2;
|
||||
packet.ChatData.ChatType = (byte)1;
|
||||
packet.ChatData.Audible = (byte)1;
|
||||
packet.ChatData.Position = new LLVector3(0, 0, 0);
|
||||
packet.ChatData.Message = Helpers.StringToField(message);
|
||||
proxy.InjectPacket(packet, Direction.Incoming);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public abstract class ProxyPlugin : MarshalByRefObject
|
||||
{
|
||||
// public abstract ProxyPlugin(ProxyFrame main);
|
||||
public abstract void Init();
|
||||
}
|
||||
|
||||
}
|
||||
14
Programs/SLProxy/SLProxyMain.cs
Normal file
14
Programs/SLProxy/SLProxyMain.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using SLProxy;
|
||||
|
||||
class ProxyMain
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
ProxyFrame p = new ProxyFrame(args);
|
||||
ProxyPlugin analyst = new Analyst(p);
|
||||
analyst.Init();
|
||||
p.proxy.Start();
|
||||
}
|
||||
}
|
||||
46
Programs/SLProxy/XmlRpcCS/Logger.cs
Normal file
46
Programs/SLProxy/XmlRpcCS/Logger.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
namespace Nwc.XmlRpc
|
||||
{
|
||||
using System;
|
||||
|
||||
/// <summary>Define levels of logging.</summary><remarks> This duplicates
|
||||
/// similar enumerations in System.Diagnostics.EventLogEntryType. The
|
||||
/// duplication was merited because .NET Compact Framework lacked the EventLogEntryType enum.</remarks>
|
||||
public enum LogLevel
|
||||
{
|
||||
/// <summary>Information level, log entry for informational reasons only.</summary>
|
||||
Information,
|
||||
/// <summary>Warning level, indicates a possible problem.</summary>
|
||||
Warning,
|
||||
/// <summary>Error level, implies a significant problem.</summary>
|
||||
Error
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Logging singleton with swappable output delegate.
|
||||
///</summary>
|
||||
///<remarks>
|
||||
///This singleton provides a centralized log. The actual WriteEntry calls are passed
|
||||
///off to a delegate however. Having a delegate do the actual logginh allows you to
|
||||
///implement different logging mechanism and have them take effect throughout the system.
|
||||
///</remarks>
|
||||
public class Logger
|
||||
{
|
||||
///<summary>Delegate definition for logging.</summary>
|
||||
///<param name="message">The message <c>String</c> to log.</param>
|
||||
///<param name="level">The <c>LogLevel</c> of your message.</param>
|
||||
public delegate void LoggerDelegate(String message, LogLevel level);
|
||||
///<summary>The LoggerDelegate that will recieve WriteEntry requests.</summary>
|
||||
static public LoggerDelegate Delegate = null;
|
||||
|
||||
///<summary>
|
||||
///Method logging events are sent to.
|
||||
///</summary>
|
||||
///<param name="message">The message <c>String</c> to log.</param>
|
||||
///<param name="level">The <c>LogLevel</c> of your message.</param>
|
||||
static public void WriteEntry(String message, LogLevel level)
|
||||
{
|
||||
if (Delegate != null)
|
||||
Delegate(message, level);
|
||||
}
|
||||
}
|
||||
}
|
||||
204
Programs/SLProxy/XmlRpcCS/SimpleHttpRequest.cs
Normal file
204
Programs/SLProxy/XmlRpcCS/SimpleHttpRequest.cs
Normal file
@@ -0,0 +1,204 @@
|
||||
namespace Nwc.XmlRpc
|
||||
{
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net.Sockets;
|
||||
using System.Collections;
|
||||
|
||||
///<summary>Very basic HTTP request handler.</summary>
|
||||
///<remarks>This class is designed to accept a TcpClient and treat it as an HTTP request.
|
||||
/// It will do some basic header parsing and manage the input and output streams associated
|
||||
/// with the request.</remarks>
|
||||
public class SimpleHttpRequest
|
||||
{
|
||||
private String _httpMethod = null;
|
||||
private String _protocol;
|
||||
private String _filePathFile = null;
|
||||
private String _filePathDir = null;
|
||||
private String __filePath;
|
||||
private TcpClient _client;
|
||||
private StreamReader _input;
|
||||
private StreamWriter _output;
|
||||
private Hashtable _headers;
|
||||
|
||||
/// <summary>A constructor which accepts the TcpClient.</summary>
|
||||
/// <remarks>It creates the associated input and output streams, determines the request type,
|
||||
/// and parses the remaining HTTP header.</remarks>
|
||||
/// <param name="client">The <c>TcpClient</c> associated with the HTTP connection.</param>
|
||||
public SimpleHttpRequest(TcpClient client)
|
||||
{
|
||||
_client = client;
|
||||
_output = new StreamWriter(client.GetStream());
|
||||
_input = new StreamReader(client.GetStream());
|
||||
GetRequestMethod();
|
||||
GetRequestHeaders();
|
||||
}
|
||||
|
||||
/// <summary>The output <c>StreamWriter</c> associated with the request.</summary>
|
||||
public StreamWriter Output
|
||||
{
|
||||
get { return _output; }
|
||||
}
|
||||
|
||||
/// <summary>The input <c>StreamReader</c> associated with the request.</summary>
|
||||
public StreamReader Input
|
||||
{
|
||||
get { return _input; }
|
||||
}
|
||||
|
||||
/// <summary>The <c>TcpClient</c> with the request.</summary>
|
||||
public TcpClient Client
|
||||
{
|
||||
get { return _client; }
|
||||
}
|
||||
|
||||
private String _filePath
|
||||
{
|
||||
get { return __filePath; }
|
||||
set
|
||||
{
|
||||
__filePath = value;
|
||||
_filePathDir = null;
|
||||
_filePathFile = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>The type of HTTP request (i.e. PUT, GET, etc.).</summary>
|
||||
public String HttpMethod
|
||||
{
|
||||
get { return _httpMethod; }
|
||||
}
|
||||
|
||||
/// <summary>The level of the HTTP protocol.</summary>
|
||||
public String Protocol
|
||||
{
|
||||
get { return _protocol; }
|
||||
}
|
||||
|
||||
/// <summary>The "path" which is part of any HTTP request.</summary>
|
||||
public String FilePath
|
||||
{
|
||||
get { return _filePath; }
|
||||
}
|
||||
|
||||
/// <summary>The file portion of the "path" which is part of any HTTP request.</summary>
|
||||
public String FilePathFile
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_filePathFile != null)
|
||||
return _filePathFile;
|
||||
|
||||
int i = FilePath.LastIndexOf("/");
|
||||
|
||||
if (i == -1)
|
||||
return "";
|
||||
|
||||
i++;
|
||||
_filePathFile = FilePath.Substring(i, FilePath.Length - i);
|
||||
return _filePathFile;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>The directory portion of the "path" which is part of any HTTP request.</summary>
|
||||
public String FilePathDir
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_filePathDir != null)
|
||||
return _filePathDir;
|
||||
|
||||
int i = FilePath.LastIndexOf("/");
|
||||
|
||||
if (i == -1)
|
||||
return "";
|
||||
|
||||
i++;
|
||||
_filePathDir = FilePath.Substring(0, i);
|
||||
return _filePathDir;
|
||||
}
|
||||
}
|
||||
|
||||
private void GetRequestMethod()
|
||||
{
|
||||
string req = _input.ReadLine();
|
||||
if (req == null)
|
||||
throw new ApplicationException("Void request.");
|
||||
|
||||
if (0 == String.Compare("GET ", req.Substring(0, 4), true))
|
||||
_httpMethod = "GET";
|
||||
else if (0 == String.Compare("POST ", req.Substring(0, 5), true))
|
||||
_httpMethod = "POST";
|
||||
else
|
||||
throw new InvalidOperationException("Unrecognized method in query: " + req);
|
||||
|
||||
req = req.TrimEnd();
|
||||
int idx = req.IndexOf(' ') + 1;
|
||||
if (idx >= req.Length)
|
||||
throw new ApplicationException("What do you want?");
|
||||
|
||||
string page_protocol = req.Substring(idx);
|
||||
int idx2 = page_protocol.IndexOf(' ');
|
||||
if (idx2 == -1)
|
||||
idx2 = page_protocol.Length;
|
||||
|
||||
_filePath = page_protocol.Substring(0, idx2).Trim();
|
||||
_protocol = page_protocol.Substring(idx2).Trim();
|
||||
}
|
||||
|
||||
private void GetRequestHeaders()
|
||||
{
|
||||
String line;
|
||||
int idx;
|
||||
|
||||
_headers = new Hashtable();
|
||||
|
||||
while ((line = _input.ReadLine()) != "")
|
||||
{
|
||||
if (line == null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
idx = line.IndexOf(':');
|
||||
if (idx == -1 || idx == line.Length - 1)
|
||||
{
|
||||
Logger.WriteEntry("Malformed header line: " + line, LogLevel.Information);
|
||||
continue;
|
||||
}
|
||||
|
||||
String key = line.Substring(0, idx);
|
||||
String value = line.Substring(idx + 1);
|
||||
|
||||
try
|
||||
{
|
||||
_headers.Add(key, value);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Logger.WriteEntry("Duplicate header key in line: " + line, LogLevel.Information);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Format the object contents into a useful string representation.
|
||||
/// </summary>
|
||||
///<returns><c>String</c> representation of the <c>SimpleHttpRequest</c> as the <i>HttpMethod FilePath Protocol</i>.</returns>
|
||||
override public String ToString()
|
||||
{
|
||||
return HttpMethod + " " + FilePath + " " + Protocol;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Close the <c>SimpleHttpRequest</c>. This flushes and closes all associated io streams.
|
||||
/// </summary>
|
||||
public void Close()
|
||||
{
|
||||
_output.Flush();
|
||||
_output.Close();
|
||||
_input.Close();
|
||||
_client.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
51
Programs/SLProxy/XmlRpcCS/XmlRpcBoxcarRequest.cs
Normal file
51
Programs/SLProxy/XmlRpcCS/XmlRpcBoxcarRequest.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
namespace Nwc.XmlRpc
|
||||
{
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Reflection;
|
||||
|
||||
/// <summary>Class that collects individual <c>XmlRpcRequest</c> objects and submits them as a <i>boxcarred</i> request.</summary>
|
||||
/// <remarks>A boxcared request is when a number of request are collected before being sent via XML-RPC, and then are sent via
|
||||
/// a single HTTP connection. This results in a speed up from reduced connection time. The results are then retuned collectively
|
||||
/// as well.
|
||||
///</remarks>
|
||||
/// <seealso cref="XmlRpcRequest"/>
|
||||
public class XmlRpcBoxcarRequest : XmlRpcRequest
|
||||
{
|
||||
/// <summary>ArrayList to collect the requests to boxcar.</summary>
|
||||
public IList Requests = new ArrayList();
|
||||
|
||||
/// <summary>Basic constructor.</summary>
|
||||
public XmlRpcBoxcarRequest()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>Returns the <c>String</c> "system.multiCall" which is the server method that handles boxcars.</summary>
|
||||
public override String MethodName
|
||||
{
|
||||
get { return "system.multiCall"; }
|
||||
}
|
||||
|
||||
/// <summary>The <c>ArrayList</c> of boxcarred <paramref>Requests</paramref> as properly formed parameters.</summary>
|
||||
public override IList Params
|
||||
{
|
||||
get {
|
||||
_params.Clear();
|
||||
ArrayList reqArray = new ArrayList();
|
||||
foreach (XmlRpcRequest request in Requests)
|
||||
{
|
||||
Hashtable requestEntry = new Hashtable();
|
||||
requestEntry.Add(XmlRpcXmlTokens.METHOD_NAME, request.MethodName);
|
||||
requestEntry.Add(XmlRpcXmlTokens.PARAMS, request.Params);
|
||||
reqArray.Add(requestEntry);
|
||||
}
|
||||
_params.Add(reqArray);
|
||||
return _params;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
61
Programs/SLProxy/XmlRpcCS/XmlRpcClientProxy.cs
Normal file
61
Programs/SLProxy/XmlRpcCS/XmlRpcClientProxy.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
namespace Nwc.XmlRpc
|
||||
{
|
||||
using System;
|
||||
using System.Runtime.Remoting.Proxies;
|
||||
using System.Runtime.Remoting.Messaging;
|
||||
|
||||
/// <summary>This class provides support for creating local proxies of XML-RPC remote objects</summary>
|
||||
/// <remarks>
|
||||
/// To create a local proxy you need to create a local C# interface and then, via <i>createProxy</i>
|
||||
/// associate that interface with a remote object at a given URL.
|
||||
/// </remarks>
|
||||
public class XmlRpcClientProxy : RealProxy
|
||||
{
|
||||
private String _remoteObjectName;
|
||||
private String _url;
|
||||
private XmlRpcRequest _client = new XmlRpcRequest();
|
||||
|
||||
/// <summary>Factory method to create proxies.</summary>
|
||||
/// <remarks>
|
||||
/// To create a local proxy you need to create a local C# interface with methods that mirror those of the server object.
|
||||
/// Next, pass that interface into <c>createProxy</c> along with the object name and URL of the remote object and
|
||||
/// cast the resulting object to the specifice interface.
|
||||
/// </remarks>
|
||||
/// <param name="remoteObjectName"><c>String</c> The name of the remote object.</param>
|
||||
/// <param name="url"><c>String</c> The URL of the remote object.</param>
|
||||
/// <param name="anInterface"><c>Type</c> The typeof() of a C# interface.</param>
|
||||
/// <returns><c>Object</c> A proxy for your specified interface. Cast to appropriate type.</returns>
|
||||
public static Object createProxy(String remoteObjectName, String url, Type anInterface)
|
||||
{
|
||||
return new XmlRpcClientProxy(remoteObjectName, url, anInterface).GetTransparentProxy();
|
||||
}
|
||||
|
||||
private XmlRpcClientProxy(String remoteObjectName, String url, Type t) : base(t)
|
||||
{
|
||||
_remoteObjectName = remoteObjectName;
|
||||
_url = url;
|
||||
}
|
||||
|
||||
/// <summary>The local method dispatcher - do not invoke.</summary>
|
||||
override public IMessage Invoke(IMessage msg)
|
||||
{
|
||||
IMethodCallMessage methodMessage = (IMethodCallMessage)msg;
|
||||
|
||||
_client.MethodName = _remoteObjectName + "." + methodMessage.MethodName;
|
||||
_client.Params.Clear();
|
||||
foreach (Object o in methodMessage.Args)
|
||||
_client.Params.Add(o);
|
||||
|
||||
try
|
||||
{
|
||||
Object ret = _client.Invoke(_url);
|
||||
return new ReturnMessage(ret,null,0,
|
||||
methodMessage.LogicalCallContext, methodMessage);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return new ReturnMessage(e, methodMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
195
Programs/SLProxy/XmlRpcCS/XmlRpcDeserializer.cs
Normal file
195
Programs/SLProxy/XmlRpcCS/XmlRpcDeserializer.cs
Normal file
@@ -0,0 +1,195 @@
|
||||
namespace Nwc.XmlRpc
|
||||
{
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using System.Globalization;
|
||||
|
||||
/// <summary>Parser context, we maintain contexts in a stack to avoiding recursion. </summary>
|
||||
struct Context
|
||||
{
|
||||
public String Name;
|
||||
public Object Container;
|
||||
}
|
||||
|
||||
/// <summary>Basic XML-RPC data deserializer.</summary>
|
||||
/// <remarks>Uses <c>XmlTextReader</c> to parse the XML data. This level of the class
|
||||
/// only handles the tokens common to both Requests and Responses. This class is not useful in and of itself
|
||||
/// but is designed to be subclassed.</remarks>
|
||||
public class XmlRpcDeserializer : XmlRpcXmlTokens
|
||||
{
|
||||
private static DateTimeFormatInfo _dateFormat = new DateTimeFormatInfo();
|
||||
|
||||
private Object _container;
|
||||
private Stack _containerStack;
|
||||
|
||||
/// <summary>Protected reference to last text.</summary>
|
||||
protected String _text;
|
||||
/// <summary>Protected reference to last deserialized value.</summary>
|
||||
protected Object _value;
|
||||
/// <summary>Protected reference to last name field.</summary>
|
||||
protected String _name;
|
||||
|
||||
|
||||
/// <summary>Basic constructor.</summary>
|
||||
public XmlRpcDeserializer()
|
||||
{
|
||||
Reset();
|
||||
_dateFormat.FullDateTimePattern = ISO_DATETIME;
|
||||
}
|
||||
|
||||
/// <summary>Static method that parses XML data into a response using the Singleton.</summary>
|
||||
/// <param name="xmlData"><c>StreamReader</c> containing an XML-RPC response.</param>
|
||||
/// <returns><c>Object</c> object resulting from the deserialization.</returns>
|
||||
virtual public Object Deserialize(TextReader xmlData)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>Protected method to parse a node in an XML-RPC XML stream.</summary>
|
||||
/// <remarks>Method deals with elements common to all XML-RPC data, subclasses of
|
||||
/// this object deal with request/response spefic elements.</remarks>
|
||||
/// <param name="reader"><c>XmlTextReader</c> of the in progress parsing data stream.</param>
|
||||
protected void DeserializeNode(XmlTextReader reader)
|
||||
{
|
||||
switch (reader.NodeType)
|
||||
{
|
||||
case XmlNodeType.Element:
|
||||
if (Logger.Delegate != null)
|
||||
Logger.WriteEntry("START " + reader.Name, LogLevel.Information);
|
||||
switch (reader.Name)
|
||||
{
|
||||
case VALUE:
|
||||
_value = null;
|
||||
_text = null;
|
||||
break;
|
||||
case STRUCT:
|
||||
PushContext();
|
||||
_container = new Hashtable();
|
||||
break;
|
||||
case ARRAY:
|
||||
PushContext();
|
||||
_container = new ArrayList();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case XmlNodeType.EndElement:
|
||||
if (Logger.Delegate != null)
|
||||
Logger.WriteEntry("END " + reader.Name, LogLevel.Information);
|
||||
switch (reader.Name)
|
||||
{
|
||||
case BASE64:
|
||||
_value = Convert.FromBase64String(_text);
|
||||
break;
|
||||
case BOOLEAN:
|
||||
int val = Int16.Parse(_text);
|
||||
if (val == 0)
|
||||
_value = false;
|
||||
else if (val == 1)
|
||||
_value = true;
|
||||
break;
|
||||
case STRING:
|
||||
_value = _text;
|
||||
break;
|
||||
case DOUBLE:
|
||||
_value = Double.Parse(_text);
|
||||
break;
|
||||
case INT:
|
||||
case ALT_INT:
|
||||
_value = Int32.Parse(_text);
|
||||
break;
|
||||
case DATETIME:
|
||||
#if __MONO__
|
||||
_value = DateParse(_text);
|
||||
#else
|
||||
_value = DateTime.ParseExact(_text, "F", _dateFormat);
|
||||
#endif
|
||||
break;
|
||||
case NAME:
|
||||
_name = _text;
|
||||
break;
|
||||
case VALUE:
|
||||
if (_value == null)
|
||||
_value = _text; // some kits don't use <string> tag, they just do <value>
|
||||
|
||||
if ((_container != null) && (_container is IList)) // in an array? If so add value to it.
|
||||
((IList)_container).Add(_value);
|
||||
break;
|
||||
case MEMBER:
|
||||
if ((_container != null) && (_container is IDictionary)) // in an struct? If so add value to it.
|
||||
((IDictionary)_container).Add(_name, _value);
|
||||
break;
|
||||
case ARRAY:
|
||||
case STRUCT:
|
||||
_value = _container;
|
||||
PopContext();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case XmlNodeType.Text:
|
||||
if (Logger.Delegate != null)
|
||||
Logger.WriteEntry("Text " + reader.Value, LogLevel.Information);
|
||||
_text = reader.Value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Static method that parses XML in a <c>String</c> into a
|
||||
/// request using the Singleton.</summary>
|
||||
/// <param name="xmlData"><c>String</c> containing an XML-RPC request.</param>
|
||||
/// <returns><c>XmlRpcRequest</c> object resulting from the parse.</returns>
|
||||
public Object Deserialize(String xmlData)
|
||||
{
|
||||
StringReader sr = new StringReader(xmlData);
|
||||
return Deserialize(sr);
|
||||
}
|
||||
|
||||
/// <summary>Pop a Context of the stack, an Array or Struct has closed.</summary>
|
||||
private void PopContext()
|
||||
{
|
||||
Context c = (Context)_containerStack.Pop();
|
||||
_container = c.Container;
|
||||
_name = c.Name;
|
||||
}
|
||||
|
||||
/// <summary>Push a Context on the stack, an Array or Struct has opened.</summary>
|
||||
private void PushContext()
|
||||
{
|
||||
Context context;
|
||||
|
||||
context.Container = _container;
|
||||
context.Name = _name;
|
||||
|
||||
_containerStack.Push(context);
|
||||
}
|
||||
|
||||
/// <summary>Reset the internal state of the deserializer.</summary>
|
||||
protected void Reset()
|
||||
{
|
||||
_text = null;
|
||||
_value = null;
|
||||
_name = null;
|
||||
_container = null;
|
||||
_containerStack = new Stack();
|
||||
}
|
||||
|
||||
#if __MONO__
|
||||
private DateTime DateParse(String str)
|
||||
{
|
||||
int year = Int32.Parse(str.Substring(0,4));
|
||||
int month = Int32.Parse(str.Substring(4,2));
|
||||
int day = Int32.Parse(str.Substring(6,2));
|
||||
int hour = Int32.Parse(str.Substring(9,2));
|
||||
int min = Int32.Parse(str.Substring(12,2));
|
||||
int sec = Int32.Parse(str.Substring(15,2));
|
||||
return new DateTime(year,month,day,hour,min,sec);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
51
Programs/SLProxy/XmlRpcCS/XmlRpcErrorCodes.cs
Normal file
51
Programs/SLProxy/XmlRpcCS/XmlRpcErrorCodes.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
namespace Nwc.XmlRpc
|
||||
{
|
||||
using System;
|
||||
|
||||
/// <summary>Standard XML-RPC error codes.</summary>
|
||||
public class XmlRpcErrorCodes
|
||||
{
|
||||
/// <summary></summary>
|
||||
public const int PARSE_ERROR_MALFORMED = -32700;
|
||||
/// <summary></summary>
|
||||
public const String PARSE_ERROR_MALFORMED_MSG = "Parse Error, not well formed";
|
||||
|
||||
/// <summary></summary>
|
||||
public const int PARSE_ERROR_ENCODING = -32701;
|
||||
/// <summary></summary>
|
||||
public const String PARSE_ERROR_ENCODING_MSG = "Parse Error, unsupported encoding";
|
||||
|
||||
//
|
||||
// -32702 ---> parse error. invalid character for encoding
|
||||
// -32600 ---> server error. invalid xml-rpc. not conforming to spec.
|
||||
//
|
||||
|
||||
/// <summary></summary>
|
||||
public const int SERVER_ERROR_METHOD = -32601;
|
||||
/// <summary></summary>
|
||||
public const String SERVER_ERROR_METHOD_MSG = "Server Error, requested method not found";
|
||||
|
||||
/// <summary></summary>
|
||||
public const int SERVER_ERROR_PARAMS = -32602;
|
||||
/// <summary></summary>
|
||||
public const String SERVER_ERROR_PARAMS_MSG = "Server Error, invalid method parameters";
|
||||
|
||||
//
|
||||
// -32603 ---> server error. internal xml-rpc error
|
||||
//
|
||||
|
||||
/// <summary></summary>
|
||||
public const int APPLICATION_ERROR = -32500;
|
||||
/// <summary></summary>
|
||||
public const String APPLICATION_ERROR_MSG = "Application Error";
|
||||
|
||||
//
|
||||
// -32400 ---> system error
|
||||
//
|
||||
|
||||
/// <summary></summary>
|
||||
public const int TRANSPORT_ERROR = -32300;
|
||||
/// <summary></summary>
|
||||
public const String TRANSPORT_ERROR_MSG = "Transport Layer Error";
|
||||
}
|
||||
}
|
||||
39
Programs/SLProxy/XmlRpcCS/XmlRpcException.cs
Normal file
39
Programs/SLProxy/XmlRpcCS/XmlRpcException.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
namespace Nwc.XmlRpc
|
||||
{
|
||||
using System;
|
||||
|
||||
/// <summary>An XML-RPC Exception.</summary>
|
||||
/// <remarks>Maps a C# exception to an XML-RPC fault. Normal exceptions
|
||||
/// include a message so this adds the code needed by XML-RPC.</remarks>
|
||||
public class XmlRpcException : Exception
|
||||
{
|
||||
private int _code;
|
||||
|
||||
/// <summary>Instantiate an <c>XmlRpcException</c> with a code and message.</summary>
|
||||
/// <param name="code"><c>Int</c> faultCode associated with this exception.</param>
|
||||
/// <param name="message"><c>String</c> faultMessage associated with this exception.</param>
|
||||
public XmlRpcException(int code, String message)
|
||||
: base(message)
|
||||
{
|
||||
_code = code;
|
||||
}
|
||||
|
||||
/// <summary>The value of the faults message, i.e. the faultString.</summary>
|
||||
public String FaultString
|
||||
{
|
||||
get { return Message; }
|
||||
}
|
||||
|
||||
/// <summary>The value of the faults code, i.e. the faultCode.</summary>
|
||||
public int FaultCode
|
||||
{
|
||||
get { return _code; }
|
||||
}
|
||||
|
||||
/// <summary>Format the message to include the code.</summary>
|
||||
override public String ToString()
|
||||
{
|
||||
return "Code: " + FaultCode + " Message: " + base.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
60
Programs/SLProxy/XmlRpcCS/XmlRpcExposedAttribute.cs
Normal file
60
Programs/SLProxy/XmlRpcCS/XmlRpcExposedAttribute.cs
Normal file
@@ -0,0 +1,60 @@
|
||||
namespace Nwc.XmlRpc
|
||||
{
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
/// <summary>
|
||||
/// Simple tagging attribute to indicate participation is XML-RPC exposure.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If present at the class level it indicates that this class does explicitly
|
||||
/// expose methods. If present at the method level it denotes that the method
|
||||
/// is exposed.
|
||||
/// </remarks>
|
||||
[AttributeUsage(
|
||||
AttributeTargets.Class | AttributeTargets.Method,
|
||||
AllowMultiple = false,
|
||||
Inherited = true
|
||||
)]
|
||||
public class XmlRpcExposedAttribute : Attribute
|
||||
{
|
||||
/// <summary>Check if <paramref>obj</paramref> is an object utilizing the XML-RPC exposed Attribute.</summary>
|
||||
/// <param name="obj"><c>Object</c> of a class or method to check for attribute.</param>
|
||||
/// <returns><c>Boolean</c> true if attribute present.</returns>
|
||||
public static Boolean ExposedObject(Object obj)
|
||||
{
|
||||
return IsExposed(obj.GetType());
|
||||
}
|
||||
|
||||
/// <summary>Check if <paramref>obj</paramref>.<paramref>methodName</paramref> is an XML-RPC exposed method.</summary>
|
||||
/// <remarks>A method is considered to be exposed if it exists and, either, the object does not use the XmlRpcExposed attribute,
|
||||
/// or the object does use the XmlRpcExposed attribute and the method has the XmlRpcExposed attribute as well.</remarks>
|
||||
/// <returns><c>Boolean</c> true if the method is exposed.</returns>
|
||||
public static Boolean ExposedMethod(Object obj, String methodName)
|
||||
{
|
||||
Type type = obj.GetType();
|
||||
MethodInfo method = type.GetMethod(methodName);
|
||||
|
||||
if (method == null)
|
||||
throw new MissingMethodException("Method " + methodName + " not found.");
|
||||
|
||||
if (!IsExposed(type))
|
||||
return true;
|
||||
|
||||
return IsExposed(method);
|
||||
}
|
||||
|
||||
/// <summary>Check if <paramref>mi</paramref> is XML-RPC exposed.</summary>
|
||||
/// <param name="mi"><c>MemberInfo</c> of a class or method to check for attribute.</param>
|
||||
/// <returns><c>Boolean</c> true if attribute present.</returns>
|
||||
public static Boolean IsExposed(MemberInfo mi)
|
||||
{
|
||||
foreach (Attribute attr in mi.GetCustomAttributes(true))
|
||||
{
|
||||
if (attr is XmlRpcExposedAttribute)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
150
Programs/SLProxy/XmlRpcCS/XmlRpcRequest.cs
Normal file
150
Programs/SLProxy/XmlRpcCS/XmlRpcRequest.cs
Normal file
@@ -0,0 +1,150 @@
|
||||
namespace Nwc.XmlRpc
|
||||
{
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Reflection;
|
||||
using System.Net.Security;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
internal class AcceptAllCertificatePolicy : ICertificatePolicy
|
||||
{
|
||||
public AcceptAllCertificatePolicy()
|
||||
{
|
||||
}
|
||||
|
||||
public bool CheckValidationResult(ServicePoint sPoint,
|
||||
System.Security.Cryptography.X509Certificates.X509Certificate cert,
|
||||
WebRequest wRequest, int certProb)
|
||||
{
|
||||
// Always accept
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Class supporting the request side of an XML-RPC transaction.</summary>
|
||||
public class XmlRpcRequest
|
||||
{
|
||||
private String _methodName = null;
|
||||
private Encoding _encoding = new ASCIIEncoding();
|
||||
private XmlRpcRequestSerializer _serializer = new XmlRpcRequestSerializer();
|
||||
private XmlRpcResponseDeserializer _deserializer = new XmlRpcResponseDeserializer();
|
||||
|
||||
/// <summary><c>ArrayList</c> containing the parameters.</summary>
|
||||
protected IList _params = null;
|
||||
|
||||
/// <summary>Instantiate an <c>XmlRpcRequest</c></summary>
|
||||
public XmlRpcRequest()
|
||||
{
|
||||
_params = new ArrayList();
|
||||
}
|
||||
|
||||
/// <summary>Instantiate an <c>XmlRpcRequest</c> for a specified method and parameters.</summary>
|
||||
/// <param name="methodName"><c>String</c> designating the <i>object.method</i> on the server the request
|
||||
/// should be directed to.</param>
|
||||
/// <param name="parameters"><c>ArrayList</c> of XML-RPC type parameters to invoke the request with.</param>
|
||||
public XmlRpcRequest(String methodName, IList parameters)
|
||||
{
|
||||
MethodName = methodName;
|
||||
_params = parameters;
|
||||
}
|
||||
|
||||
/// <summary><c>ArrayList</c> conntaining the parameters for the request.</summary>
|
||||
public virtual IList Params
|
||||
{
|
||||
get { return _params; }
|
||||
}
|
||||
|
||||
/// <summary><c>String</c> conntaining the method name, both object and method, that the request will be sent to.</summary>
|
||||
public virtual String MethodName
|
||||
{
|
||||
get { return _methodName; }
|
||||
set { _methodName = value; }
|
||||
}
|
||||
|
||||
/// <summary><c>String</c> object name portion of the method name.</summary>
|
||||
public String MethodNameObject
|
||||
{
|
||||
get
|
||||
{
|
||||
int index = MethodName.IndexOf(".");
|
||||
|
||||
if (index == -1)
|
||||
return MethodName;
|
||||
|
||||
return MethodName.Substring(0, index);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary><c>String</c> method name portion of the object.method name.</summary>
|
||||
public String MethodNameMethod
|
||||
{
|
||||
get
|
||||
{
|
||||
int index = MethodName.IndexOf(".");
|
||||
|
||||
if (index == -1)
|
||||
return MethodName;
|
||||
|
||||
return MethodName.Substring(index + 1, MethodName.Length - index - 1);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Invoke this request on the server.</summary>
|
||||
/// <param name="url"><c>String</c> The url of the XML-RPC server.</param>
|
||||
/// <returns><c>Object</c> The value returned from the method invocation on the server.</returns>
|
||||
/// <exception cref="XmlRpcException">If an exception generated on the server side.</exception>
|
||||
public Object Invoke(String url)
|
||||
{
|
||||
XmlRpcResponse res = Send(url, 10000);
|
||||
|
||||
if (res.IsFault)
|
||||
throw new XmlRpcException(res.FaultCode, res.FaultString);
|
||||
|
||||
return res.Value;
|
||||
}
|
||||
|
||||
/// <summary>Send the request to the server.</summary>
|
||||
/// <param name="url"><c>String</c> The url of the XML-RPC server.</param>
|
||||
/// <param name="timeout">Milliseconds before the connection times out.</param>
|
||||
/// <returns><c>XmlRpcResponse</c> The response generated.</returns>
|
||||
public XmlRpcResponse Send(String url, int timeout)
|
||||
{
|
||||
// Override SSL authentication mechanisms
|
||||
ServicePointManager.CertificatePolicy = new AcceptAllCertificatePolicy();
|
||||
|
||||
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
|
||||
if (request == null)
|
||||
throw new XmlRpcException(XmlRpcErrorCodes.TRANSPORT_ERROR,
|
||||
XmlRpcErrorCodes.TRANSPORT_ERROR_MSG + ": Could not create request with " + url);
|
||||
request.Method = "POST";
|
||||
request.ContentType = "text/xml";
|
||||
request.AllowWriteStreamBuffering = true;
|
||||
request.Timeout = timeout;
|
||||
|
||||
Stream stream = request.GetRequestStream();
|
||||
XmlTextWriter xml = new XmlTextWriter(stream, _encoding);
|
||||
_serializer.Serialize(xml, this);
|
||||
xml.Flush();
|
||||
xml.Close();
|
||||
|
||||
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
|
||||
StreamReader input = new StreamReader(response.GetResponseStream());
|
||||
|
||||
XmlRpcResponse resp = (XmlRpcResponse)_deserializer.Deserialize(input);
|
||||
input.Close();
|
||||
response.Close();
|
||||
return resp;
|
||||
}
|
||||
|
||||
/// <summary>Produce <c>String</c> representation of the object.</summary>
|
||||
/// <returns><c>String</c> representation of the object.</returns>
|
||||
override public String ToString()
|
||||
{
|
||||
return _serializer.Serialize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
64
Programs/SLProxy/XmlRpcCS/XmlRpcRequestDeserializer.cs
Normal file
64
Programs/SLProxy/XmlRpcCS/XmlRpcRequestDeserializer.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
namespace Nwc.XmlRpc
|
||||
{
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
|
||||
/// <summary>Class to deserialize XML data representing a request.</summary>
|
||||
public class XmlRpcRequestDeserializer : XmlRpcDeserializer
|
||||
{
|
||||
static private XmlRpcRequestDeserializer _singleton;
|
||||
/// <summary>A static singleton instance of this deserializer.</summary>
|
||||
[Obsolete("This object is now thread safe, just use an instance.", false)]
|
||||
static public XmlRpcRequestDeserializer Singleton
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_singleton == null)
|
||||
_singleton = new XmlRpcRequestDeserializer();
|
||||
|
||||
return _singleton;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Static method that parses XML data into a request using the Singleton.</summary>
|
||||
/// <param name="xmlData"><c>StreamReader</c> containing an XML-RPC request.</param>
|
||||
/// <returns><c>XmlRpcRequest</c> object resulting from the parse.</returns>
|
||||
override public Object Deserialize(TextReader xmlData)
|
||||
{
|
||||
XmlTextReader reader = new XmlTextReader(xmlData);
|
||||
XmlRpcRequest request = new XmlRpcRequest();
|
||||
bool done = false;
|
||||
|
||||
lock (this)
|
||||
{
|
||||
Reset();
|
||||
while (!done && reader.Read())
|
||||
{
|
||||
DeserializeNode(reader); // Parent parse...
|
||||
switch (reader.NodeType)
|
||||
{
|
||||
case XmlNodeType.EndElement:
|
||||
switch (reader.Name)
|
||||
{
|
||||
case METHOD_NAME:
|
||||
request.MethodName = _text;
|
||||
break;
|
||||
case METHOD_CALL:
|
||||
done = true;
|
||||
break;
|
||||
case PARAM:
|
||||
request.Params.Add(_value);
|
||||
_text = null;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return request;
|
||||
}
|
||||
}
|
||||
}
|
||||
51
Programs/SLProxy/XmlRpcCS/XmlRpcRequestSerializer.cs
Normal file
51
Programs/SLProxy/XmlRpcCS/XmlRpcRequestSerializer.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
namespace Nwc.XmlRpc
|
||||
{
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Xml;
|
||||
using System.IO;
|
||||
|
||||
/// <summary>Class responsible for serializing an XML-RPC request.</summary>
|
||||
/// <remarks>This class handles the request envelope, depending on <c>XmlRpcSerializer</c>
|
||||
/// to serialize the payload.</remarks>
|
||||
/// <seealso cref="XmlRpcSerializer"/>
|
||||
public class XmlRpcRequestSerializer : XmlRpcSerializer
|
||||
{
|
||||
static private XmlRpcRequestSerializer _singleton;
|
||||
/// <summary>A static singleton instance of this deserializer.</summary>
|
||||
static public XmlRpcRequestSerializer Singleton
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_singleton == null)
|
||||
_singleton = new XmlRpcRequestSerializer();
|
||||
|
||||
return _singleton;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Serialize the <c>XmlRpcRequest</c> to the output stream.</summary>
|
||||
/// <param name="output">An <c>XmlTextWriter</c> stream to write data to.</param>
|
||||
/// <param name="obj">An <c>XmlRpcRequest</c> to serialize.</param>
|
||||
/// <seealso cref="XmlRpcRequest"/>
|
||||
override public void Serialize(XmlTextWriter output, Object obj)
|
||||
{
|
||||
XmlRpcRequest request = (XmlRpcRequest)obj;
|
||||
output.WriteStartDocument();
|
||||
output.WriteStartElement(METHOD_CALL);
|
||||
output.WriteElementString(METHOD_NAME, request.MethodName);
|
||||
output.WriteStartElement(PARAMS);
|
||||
foreach (Object param in request.Params)
|
||||
{
|
||||
output.WriteStartElement(PARAM);
|
||||
output.WriteStartElement(VALUE);
|
||||
SerializeObject(output, param);
|
||||
output.WriteEndElement();
|
||||
output.WriteEndElement();
|
||||
}
|
||||
|
||||
output.WriteEndElement();
|
||||
output.WriteEndElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
98
Programs/SLProxy/XmlRpcCS/XmlRpcResponder.cs
Normal file
98
Programs/SLProxy/XmlRpcCS/XmlRpcResponder.cs
Normal file
@@ -0,0 +1,98 @@
|
||||
namespace Nwc.XmlRpc
|
||||
{
|
||||
using System;
|
||||
using System.Xml;
|
||||
using System.Net.Sockets;
|
||||
|
||||
/// <summary>The class is a container of the context of an XML-RPC dialog on the server side.</summary>
|
||||
/// <remarks>Instances of this class maintain the context for an individual XML-RPC server
|
||||
/// side dialog. Namely they manage an inbound deserializer and an outbound serializer. </remarks>
|
||||
public class XmlRpcResponder
|
||||
{
|
||||
private XmlRpcRequestDeserializer _deserializer = new XmlRpcRequestDeserializer();
|
||||
private XmlRpcResponseSerializer _serializer = new XmlRpcResponseSerializer();
|
||||
private XmlRpcServer _server;
|
||||
private TcpClient _client;
|
||||
private SimpleHttpRequest _httpReq;
|
||||
|
||||
/// <summary>The SimpleHttpRequest based on the TcpClient.</summary>
|
||||
public SimpleHttpRequest HttpReq
|
||||
{
|
||||
get { return _httpReq; }
|
||||
}
|
||||
|
||||
/// <summary>Basic constructor.</summary>
|
||||
/// <param name="server">XmlRpcServer that this XmlRpcResponder services.</param>
|
||||
/// <param name="client">TcpClient with the connection.</param>
|
||||
public XmlRpcResponder(XmlRpcServer server, TcpClient client)
|
||||
{
|
||||
_server = server;
|
||||
_client = client;
|
||||
_httpReq = new SimpleHttpRequest(_client);
|
||||
}
|
||||
|
||||
/// <summary>Call close to insure proper shutdown.</summary>
|
||||
~XmlRpcResponder()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
///<summary>Respond using this responders HttpReq.</summary>
|
||||
public void Respond()
|
||||
{
|
||||
Respond(HttpReq);
|
||||
}
|
||||
|
||||
/// <summary>Handle an HTTP request containing an XML-RPC request.</summary>
|
||||
/// <remarks>This method deserializes the XML-RPC request, invokes the
|
||||
/// described method, serializes the response (or fault) and sends the XML-RPC response
|
||||
/// back as a valid HTTP page.
|
||||
/// </remarks>
|
||||
/// <param name="httpReq"><c>SimpleHttpRequest</c> containing the request.</param>
|
||||
public void Respond(SimpleHttpRequest httpReq)
|
||||
{
|
||||
XmlRpcRequest xmlRpcReq = (XmlRpcRequest)_deserializer.Deserialize(httpReq.Input);
|
||||
XmlRpcResponse xmlRpcResp = new XmlRpcResponse();
|
||||
|
||||
try
|
||||
{
|
||||
xmlRpcResp.Value = _server.Invoke(xmlRpcReq);
|
||||
}
|
||||
catch (XmlRpcException e)
|
||||
{
|
||||
xmlRpcResp.SetFault(e.FaultCode, e.FaultString);
|
||||
}
|
||||
catch (Exception e2)
|
||||
{
|
||||
xmlRpcResp.SetFault(XmlRpcErrorCodes.APPLICATION_ERROR,
|
||||
XmlRpcErrorCodes.APPLICATION_ERROR_MSG + ": " + e2.Message);
|
||||
}
|
||||
|
||||
if (Logger.Delegate != null)
|
||||
Logger.WriteEntry(xmlRpcResp.ToString(), LogLevel.Information);
|
||||
|
||||
XmlRpcServer.HttpHeader(httpReq.Protocol, "text/xml", 0, " 200 OK", httpReq.Output);
|
||||
httpReq.Output.Flush();
|
||||
XmlTextWriter xml = new XmlTextWriter(httpReq.Output);
|
||||
_serializer.Serialize(xml, xmlRpcResp);
|
||||
xml.Flush();
|
||||
httpReq.Output.Flush();
|
||||
}
|
||||
|
||||
///<summary>Close all contained resources, both the HttpReq and client.</summary>
|
||||
public void Close()
|
||||
{
|
||||
if (_httpReq != null)
|
||||
{
|
||||
_httpReq.Close();
|
||||
_httpReq = null;
|
||||
}
|
||||
|
||||
if (_client != null)
|
||||
{
|
||||
_client.Close();
|
||||
_client = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
85
Programs/SLProxy/XmlRpcCS/XmlRpcResponse.cs
Normal file
85
Programs/SLProxy/XmlRpcCS/XmlRpcResponse.cs
Normal file
@@ -0,0 +1,85 @@
|
||||
namespace Nwc.XmlRpc
|
||||
{
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
|
||||
/// <summary>Class designed to represent an XML-RPC response.</summary>
|
||||
public class XmlRpcResponse
|
||||
{
|
||||
private Object _value;
|
||||
/// <summary><c>bool</c> indicating if this response represents a fault.</summary>
|
||||
public bool IsFault;
|
||||
|
||||
/// <summary>Basic constructor</summary>
|
||||
public XmlRpcResponse()
|
||||
{
|
||||
Value = null;
|
||||
IsFault = false;
|
||||
}
|
||||
|
||||
/// <summary>Constructor for a fault.</summary>
|
||||
/// <param name="code"><c>int</c> the numeric faultCode value.</param>
|
||||
/// <param name="message"><c>String</c> the faultString value.</param>
|
||||
public XmlRpcResponse(int code, String message)
|
||||
: this()
|
||||
{
|
||||
SetFault(code, message);
|
||||
}
|
||||
|
||||
/// <summary>The data value of the response, may be fault data.</summary>
|
||||
public Object Value
|
||||
{
|
||||
get { return _value; }
|
||||
set
|
||||
{
|
||||
IsFault = false;
|
||||
_value = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>The faultCode if this is a fault.</summary>
|
||||
public int FaultCode
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!IsFault)
|
||||
return 0;
|
||||
else
|
||||
return (int)((Hashtable)_value)[XmlRpcXmlTokens.FAULT_CODE];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>The faultString if this is a fault.</summary>
|
||||
public String FaultString
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!IsFault)
|
||||
return "";
|
||||
else
|
||||
return (String)((Hashtable)_value)[XmlRpcXmlTokens.FAULT_STRING];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Set this response to be a fault.</summary>
|
||||
/// <param name="code"><c>int</c> the numeric faultCode value.</param>
|
||||
/// <param name="message"><c>String</c> the faultString value.</param>
|
||||
public void SetFault(int code, String message)
|
||||
{
|
||||
Hashtable fault = new Hashtable();
|
||||
fault.Add("faultCode", code);
|
||||
fault.Add("faultString", message);
|
||||
Value = fault;
|
||||
IsFault = true;
|
||||
}
|
||||
|
||||
/// <summary>Form a useful string representation of the object, in this case the XML response.</summary>
|
||||
/// <returns><c>String</c> The XML serialized XML-RPC response.</returns>
|
||||
override public String ToString()
|
||||
{
|
||||
return XmlRpcResponseSerializer.Singleton.Serialize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
65
Programs/SLProxy/XmlRpcCS/XmlRpcResponseDeserializer.cs
Normal file
65
Programs/SLProxy/XmlRpcCS/XmlRpcResponseDeserializer.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
namespace Nwc.XmlRpc
|
||||
{
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
|
||||
/// <summary>Class to deserialize XML data representing a response.</summary>
|
||||
public class XmlRpcResponseDeserializer : XmlRpcDeserializer
|
||||
{
|
||||
static private XmlRpcResponseDeserializer _singleton;
|
||||
/// <summary>A static singleton instance of this deserializer.</summary>
|
||||
[Obsolete("This object is now thread safe, just use an instance.", false)]
|
||||
static public XmlRpcResponseDeserializer Singleton
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_singleton == null)
|
||||
_singleton = new XmlRpcResponseDeserializer();
|
||||
|
||||
return _singleton;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Static method that parses XML data into a response using the Singleton.</summary>
|
||||
/// <param name="xmlData"><c>StreamReader</c> containing an XML-RPC response.</param>
|
||||
/// <returns><c>XmlRpcResponse</c> object resulting from the parse.</returns>
|
||||
override public Object Deserialize(TextReader xmlData)
|
||||
{
|
||||
XmlTextReader reader = new XmlTextReader(xmlData);
|
||||
XmlRpcResponse response = new XmlRpcResponse();
|
||||
bool done = false;
|
||||
|
||||
lock (this)
|
||||
{
|
||||
Reset();
|
||||
|
||||
while (!done && reader.Read())
|
||||
{
|
||||
DeserializeNode(reader); // Parent parse...
|
||||
switch (reader.NodeType)
|
||||
{
|
||||
case XmlNodeType.EndElement:
|
||||
switch (reader.Name)
|
||||
{
|
||||
case FAULT:
|
||||
response.Value = _value;
|
||||
response.IsFault = true;
|
||||
break;
|
||||
case PARAM:
|
||||
response.Value = _value;
|
||||
_value = null;
|
||||
_text = null;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return response;
|
||||
}
|
||||
}
|
||||
}
|
||||
57
Programs/SLProxy/XmlRpcCS/XmlRpcResponseSerializer.cs
Normal file
57
Programs/SLProxy/XmlRpcCS/XmlRpcResponseSerializer.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
namespace Nwc.XmlRpc
|
||||
{
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Xml;
|
||||
|
||||
/// <summary>Class responsible for serializing an XML-RPC response.</summary>
|
||||
/// <remarks>This class handles the response envelope, depending on XmlRpcSerializer
|
||||
/// to serialize the payload.</remarks>
|
||||
/// <seealso cref="XmlRpcSerializer"/>
|
||||
public class XmlRpcResponseSerializer : XmlRpcSerializer
|
||||
{
|
||||
static private XmlRpcResponseSerializer _singleton;
|
||||
/// <summary>A static singleton instance of this deserializer.</summary>
|
||||
static public XmlRpcResponseSerializer Singleton
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_singleton == null)
|
||||
_singleton = new XmlRpcResponseSerializer();
|
||||
|
||||
return _singleton;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Serialize the <c>XmlRpcResponse</c> to the output stream.</summary>
|
||||
/// <param name="output">An <c>XmlTextWriter</c> stream to write data to.</param>
|
||||
/// <param name="obj">An <c>Object</c> to serialize.</param>
|
||||
/// <seealso cref="XmlRpcResponse"/>
|
||||
override public void Serialize(XmlTextWriter output, Object obj)
|
||||
{
|
||||
XmlRpcResponse response = (XmlRpcResponse)obj;
|
||||
|
||||
output.WriteStartDocument();
|
||||
output.WriteStartElement(METHOD_RESPONSE);
|
||||
|
||||
if (response.IsFault)
|
||||
output.WriteStartElement(FAULT);
|
||||
else
|
||||
{
|
||||
output.WriteStartElement(PARAMS);
|
||||
output.WriteStartElement(PARAM);
|
||||
}
|
||||
|
||||
output.WriteStartElement(VALUE);
|
||||
|
||||
SerializeObject(output, response.Value);
|
||||
|
||||
output.WriteEndElement();
|
||||
|
||||
output.WriteEndElement();
|
||||
if (!response.IsFault)
|
||||
output.WriteEndElement();
|
||||
output.WriteEndElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
109
Programs/SLProxy/XmlRpcCS/XmlRpcSerializer.cs
Normal file
109
Programs/SLProxy/XmlRpcCS/XmlRpcSerializer.cs
Normal file
@@ -0,0 +1,109 @@
|
||||
namespace Nwc.XmlRpc
|
||||
{
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
|
||||
/// <summary>Base class of classes serializing data to XML-RPC's XML format.</summary>
|
||||
/// <remarks>This class handles the basic type conversions like Integer to <i4>. </remarks>
|
||||
/// <seealso cref="XmlRpcXmlTokens"/>
|
||||
public class XmlRpcSerializer : XmlRpcXmlTokens
|
||||
{
|
||||
|
||||
/// <summary>Serialize the <c>XmlRpcRequest</c> to the output stream.</summary>
|
||||
/// <param name="output">An <c>XmlTextWriter</c> stream to write data to.</param>
|
||||
/// <param name="obj">An <c>Object</c> to serialize.</param>
|
||||
/// <seealso cref="XmlRpcRequest"/>
|
||||
virtual public void Serialize(XmlTextWriter output, Object obj)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>Serialize the <c>XmlRpcRequest</c> to a String.</summary>
|
||||
/// <remarks>Note this may represent a real memory hog for a large request.</remarks>
|
||||
/// <param name="obj">An <c>Object</c> to serialize.</param>
|
||||
/// <returns><c>String</c> containing XML-RPC representation of the request.</returns>
|
||||
/// <seealso cref="XmlRpcRequest"/>
|
||||
public String Serialize(Object obj)
|
||||
{
|
||||
StringWriter strBuf = new StringWriter();
|
||||
XmlTextWriter xml = new XmlTextWriter(strBuf);
|
||||
xml.Formatting = Formatting.Indented;
|
||||
xml.Indentation = 4;
|
||||
Serialize(xml, obj);
|
||||
xml.Flush();
|
||||
String returns = strBuf.ToString();
|
||||
xml.Close();
|
||||
return returns;
|
||||
}
|
||||
|
||||
/// <remarks>Serialize the object to the output stream.</remarks>
|
||||
/// <param name="output">An <c>XmlTextWriter</c> stream to write data to.</param>
|
||||
/// <param name="obj">An <c>Object</c> to serialize.</param>
|
||||
public void SerializeObject(XmlTextWriter output, Object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
return;
|
||||
|
||||
if (obj is byte[])
|
||||
{
|
||||
byte[] ba = (byte[])obj;
|
||||
output.WriteStartElement(BASE64);
|
||||
output.WriteBase64(ba, 0, ba.Length);
|
||||
output.WriteEndElement();
|
||||
}
|
||||
else if (obj is String)
|
||||
{
|
||||
output.WriteElementString(STRING, obj.ToString());
|
||||
}
|
||||
else if (obj is Int32)
|
||||
{
|
||||
output.WriteElementString(INT, obj.ToString());
|
||||
}
|
||||
else if (obj is DateTime)
|
||||
{
|
||||
output.WriteElementString(DATETIME, ((DateTime)obj).ToString(ISO_DATETIME));
|
||||
}
|
||||
else if (obj is Double)
|
||||
{
|
||||
output.WriteElementString(DOUBLE, obj.ToString());
|
||||
}
|
||||
else if (obj is Boolean)
|
||||
{
|
||||
output.WriteElementString(BOOLEAN, ((((Boolean)obj) == true) ? "1" : "0"));
|
||||
}
|
||||
else if (obj is IList)
|
||||
{
|
||||
output.WriteStartElement(ARRAY);
|
||||
output.WriteStartElement(DATA);
|
||||
if (((ArrayList)obj).Count > 0)
|
||||
{
|
||||
foreach (Object member in ((IList)obj))
|
||||
{
|
||||
output.WriteStartElement(VALUE);
|
||||
SerializeObject(output, member);
|
||||
output.WriteEndElement();
|
||||
}
|
||||
}
|
||||
output.WriteEndElement();
|
||||
output.WriteEndElement();
|
||||
}
|
||||
else if (obj is IDictionary)
|
||||
{
|
||||
IDictionary h = (IDictionary)obj;
|
||||
output.WriteStartElement(STRUCT);
|
||||
foreach (String key in h.Keys)
|
||||
{
|
||||
output.WriteStartElement(MEMBER);
|
||||
output.WriteElementString(NAME, key);
|
||||
output.WriteStartElement(VALUE);
|
||||
SerializeObject(output, h[key]);
|
||||
output.WriteEndElement();
|
||||
output.WriteEndElement();
|
||||
}
|
||||
output.WriteEndElement();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
239
Programs/SLProxy/XmlRpcCS/XmlRpcServer.cs
Normal file
239
Programs/SLProxy/XmlRpcCS/XmlRpcServer.cs
Normal file
@@ -0,0 +1,239 @@
|
||||
namespace Nwc.XmlRpc
|
||||
{
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Xml;
|
||||
|
||||
/// <summary>A restricted HTTP server for use with XML-RPC.</summary>
|
||||
/// <remarks>It only handles POST requests, and only POSTs representing XML-RPC calls.
|
||||
/// In addition to dispatching requests it also provides a registry for request handlers.
|
||||
/// </remarks>
|
||||
public class XmlRpcServer : IEnumerable
|
||||
{
|
||||
#pragma warning disable 0414 // disable "private field assigned but not used"
|
||||
const int RESPONDER_COUNT = 10;
|
||||
private TcpListener _myListener;
|
||||
private int _port;
|
||||
private IPAddress _address;
|
||||
private IDictionary _handlers;
|
||||
private XmlRpcSystemObject _system;
|
||||
private WaitCallback _wc;
|
||||
#pragma warning restore 0414
|
||||
|
||||
///<summary>Constructor with port and address.</summary>
|
||||
///<remarks>This constructor sets up a TcpListener listening on the
|
||||
///given port and address. It also calls a Thread on the method StartListen().</remarks>
|
||||
///<param name="address"><c>IPAddress</c> value of the address to listen on.</param>
|
||||
///<param name="port"><c>Int</c> value of the port to listen on.</param>
|
||||
public XmlRpcServer(IPAddress address, int port)
|
||||
{
|
||||
_port = port;
|
||||
_address = address;
|
||||
_handlers = new Hashtable();
|
||||
_system = new XmlRpcSystemObject(this);
|
||||
_wc = new WaitCallback(WaitCallback);
|
||||
}
|
||||
|
||||
///<summary>Basic constructor.</summary>
|
||||
///<remarks>This constructor sets up a TcpListener listening on the
|
||||
///given port. It also calls a Thread on the method StartListen(). IPAddress.Any
|
||||
///is assumed as the address here.</remarks>
|
||||
///<param name="port"><c>Int</c> value of the port to listen on.</param>
|
||||
public XmlRpcServer(int port) : this(IPAddress.Any, port) { }
|
||||
|
||||
/// <summary>Start the server.</summary>
|
||||
public void Start()
|
||||
{
|
||||
try
|
||||
{
|
||||
Stop();
|
||||
//start listing on the given port
|
||||
// IPAddress addr = IPAddress.Parse("127.0.0.1");
|
||||
lock (this)
|
||||
{
|
||||
_myListener = new TcpListener(IPAddress.Any, _port);
|
||||
_myListener.Start();
|
||||
//start the thread which calls the method 'StartListen'
|
||||
Thread th = new Thread(new ThreadStart(StartListen));
|
||||
th.Start();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.WriteEntry("An Exception Occurred while Listening :" + e.ToString(), LogLevel.Error);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Stop the server.</summary>
|
||||
public void Stop()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_myListener != null)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
_myListener.Stop();
|
||||
_myListener = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.WriteEntry("An Exception Occurred while stopping :" +
|
||||
e.ToString(), LogLevel.Error);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Get an enumeration of my XML-RPC handlers.</summary>
|
||||
/// <returns><c>IEnumerable</c> the handler enumeration.</returns>
|
||||
public IEnumerator GetEnumerator()
|
||||
{
|
||||
return _handlers.GetEnumerator();
|
||||
}
|
||||
|
||||
/// <summary>Retrieve a handler by name.</summary>
|
||||
/// <param name="name"><c>String</c> naming a handler</param>
|
||||
/// <returns><c>Object</c> that is the handler.</returns>
|
||||
public Object this[String name]
|
||||
{
|
||||
get { return _handlers[name]; }
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///This method Accepts new connections and dispatches them when appropriate.
|
||||
///</summary>
|
||||
public void StartListen()
|
||||
{
|
||||
while (true && _myListener != null)
|
||||
{
|
||||
//Accept a new connection
|
||||
XmlRpcResponder responder = new XmlRpcResponder(this, _myListener.AcceptTcpClient());
|
||||
ThreadPool.QueueUserWorkItem(_wc, responder);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///<summary>
|
||||
///Add an XML-RPC handler object by name.
|
||||
///</summary>
|
||||
///<param name="name"><c>String</c> XML-RPC dispatch name of this object.</param>
|
||||
///<param name="obj"><c>Object</c> The object that is the XML-RPC handler.</param>
|
||||
public void Add(String name, Object obj)
|
||||
{
|
||||
_handlers.Add(name, obj);
|
||||
}
|
||||
|
||||
///<summary>Return a C# object.method name for and XML-RPC object.method name pair.</summary>
|
||||
///<param name="methodName">The XML-RPC object.method.</param>
|
||||
///<returns><c>String</c> of form object.method for the underlying C# method.</returns>
|
||||
public String MethodName(String methodName)
|
||||
{
|
||||
int dotAt = methodName.LastIndexOf('.');
|
||||
|
||||
if (dotAt == -1)
|
||||
{
|
||||
throw new XmlRpcException(XmlRpcErrorCodes.SERVER_ERROR_METHOD,
|
||||
XmlRpcErrorCodes.SERVER_ERROR_METHOD_MSG + ": Bad method name " + methodName);
|
||||
}
|
||||
|
||||
String objectName = methodName.Substring(0, dotAt);
|
||||
Object target = _handlers[objectName];
|
||||
|
||||
if (target == null)
|
||||
{
|
||||
throw new XmlRpcException(XmlRpcErrorCodes.SERVER_ERROR_METHOD,
|
||||
XmlRpcErrorCodes.SERVER_ERROR_METHOD_MSG + ": Object " + objectName + " not found");
|
||||
}
|
||||
|
||||
return target.GetType().FullName + "." + methodName.Substring(dotAt + 1);
|
||||
}
|
||||
|
||||
///<summary>Invoke a method described in a request.</summary>
|
||||
///<param name="req"><c>XmlRpcRequest</c> containing a method descriptions.</param>
|
||||
/// <seealso cref="XmlRpcSystemObject.Invoke"/>
|
||||
/// <seealso cref="XmlRpcServer.Invoke(String,String,IList)"/>
|
||||
public Object Invoke(XmlRpcRequest req)
|
||||
{
|
||||
return Invoke(req.MethodNameObject, req.MethodNameMethod, req.Params);
|
||||
}
|
||||
|
||||
///<summary>Invoke a method on a named handler.</summary>
|
||||
///<param name="objectName"><c>String</c> The name of the handler.</param>
|
||||
///<param name="methodName"><c>String</c> The name of the method to invoke on the handler.</param>
|
||||
///<param name="parameters"><c>IList</c> The parameters to invoke the method with.</param>
|
||||
/// <seealso cref="XmlRpcSystemObject.Invoke"/>
|
||||
public Object Invoke(String objectName, String methodName, IList parameters)
|
||||
{
|
||||
Object target = _handlers[objectName];
|
||||
|
||||
if (target == null)
|
||||
{
|
||||
throw new XmlRpcException(XmlRpcErrorCodes.SERVER_ERROR_METHOD,
|
||||
XmlRpcErrorCodes.SERVER_ERROR_METHOD_MSG + ": Object " + objectName + " not found");
|
||||
}
|
||||
|
||||
return XmlRpcSystemObject.Invoke(target, methodName, parameters);
|
||||
}
|
||||
|
||||
/// <summary>The method the thread pool invokes when a thread is available to handle an HTTP request.</summary>
|
||||
/// <param name="responder">TcpClient from the socket accept.</param>
|
||||
public void WaitCallback(object responder)
|
||||
{
|
||||
XmlRpcResponder resp = (XmlRpcResponder)responder;
|
||||
|
||||
if (resp.HttpReq.HttpMethod == "POST")
|
||||
{
|
||||
try
|
||||
{
|
||||
resp.Respond();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.WriteEntry("Failed on post: " + e, LogLevel.Error);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.WriteEntry("Only POST methods are supported: " + resp.HttpReq.HttpMethod +
|
||||
" ignored", LogLevel.Error);
|
||||
}
|
||||
|
||||
resp.Close();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function send the Header Information to the client (Browser)
|
||||
/// </summary>
|
||||
/// <param name="sHttpVersion">HTTP Version</param>
|
||||
/// <param name="sMIMEHeader">Mime Type</param>
|
||||
/// <param name="iTotBytes">Total Bytes to be sent in the body</param>
|
||||
/// <param name="sStatusCode"></param>
|
||||
/// <param name="output">Socket reference</param>
|
||||
static public void HttpHeader(string sHttpVersion, string sMIMEHeader, long iTotBytes, string sStatusCode, TextWriter output)
|
||||
{
|
||||
String sBuffer = "";
|
||||
|
||||
// if Mime type is not provided set default to text/html
|
||||
if (sMIMEHeader.Length == 0)
|
||||
{
|
||||
sMIMEHeader = "text/html"; // Default Mime Type is text/html
|
||||
}
|
||||
|
||||
sBuffer += sHttpVersion + sStatusCode + "\r\n";
|
||||
sBuffer += "Connection: close\r\n";
|
||||
if (iTotBytes > 0)
|
||||
sBuffer += "Content-Length: " + iTotBytes + "\r\n";
|
||||
sBuffer += "Server: XmlRpcServer \r\n";
|
||||
sBuffer += "Content-Type: " + sMIMEHeader + "\r\n";
|
||||
sBuffer += "\r\n";
|
||||
|
||||
output.Write(sBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
252
Programs/SLProxy/XmlRpcCS/XmlRpcSystemObject.cs
Normal file
252
Programs/SLProxy/XmlRpcCS/XmlRpcSystemObject.cs
Normal file
@@ -0,0 +1,252 @@
|
||||
namespace Nwc.XmlRpc
|
||||
{
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Reflection;
|
||||
|
||||
/// <summary> XML-RPC System object implementation of extended specifications.</summary>
|
||||
[XmlRpcExposed]
|
||||
public class XmlRpcSystemObject
|
||||
{
|
||||
private XmlRpcServer _server;
|
||||
static private IDictionary _methodHelp = new Hashtable();
|
||||
|
||||
/// <summary>Static <c>IDictionary</c> to hold mappings of method name to associated documentation String</summary>
|
||||
static public IDictionary MethodHelp
|
||||
{
|
||||
get { return _methodHelp; }
|
||||
}
|
||||
|
||||
/// <summary>Constructor.</summary>
|
||||
/// <param name="server"><c>XmlRpcServer</c> server to be the system object for.</param>
|
||||
public XmlRpcSystemObject(XmlRpcServer server)
|
||||
{
|
||||
_server = server;
|
||||
server.Add("system", this);
|
||||
_methodHelp.Add(this.GetType().FullName + ".methodHelp", "Return a string description.");
|
||||
}
|
||||
|
||||
/// <summary>Invoke a method on a given object.</summary>
|
||||
/// <remarks>Using reflection, and respecting the <c>XmlRpcExposed</c> attribute,
|
||||
/// invoke the <paramref>methodName</paramref> method on the <paramref>target</paramref>
|
||||
/// instance with the <paramref>parameters</paramref> provided. All this packages other <c>Invoke</c> methods
|
||||
/// end up calling this.</remarks>
|
||||
/// <returns><c>Object</c> the value the invoked method returns.</returns>
|
||||
/// <exception cref="XmlRpcException">If method does not exist, is not exposed, parameters invalid, or invocation
|
||||
/// results in an exception. Note, the <c>XmlRpcException.Code</c> will indicate cause.</exception>
|
||||
static public Object Invoke(Object target, String methodName, IList parameters)
|
||||
{
|
||||
if (target == null)
|
||||
throw new XmlRpcException(XmlRpcErrorCodes.SERVER_ERROR_METHOD,
|
||||
XmlRpcErrorCodes.SERVER_ERROR_METHOD_MSG + ": Invalid target object.");
|
||||
|
||||
Type type = target.GetType();
|
||||
MethodInfo method = type.GetMethod(methodName);
|
||||
|
||||
try
|
||||
{
|
||||
if (!XmlRpcExposedAttribute.ExposedMethod(target, methodName))
|
||||
throw new XmlRpcException(XmlRpcErrorCodes.SERVER_ERROR_METHOD,
|
||||
XmlRpcErrorCodes.SERVER_ERROR_METHOD_MSG + ": Method " + methodName + " is not exposed.");
|
||||
}
|
||||
catch (MissingMethodException me)
|
||||
{
|
||||
throw new XmlRpcException(XmlRpcErrorCodes.SERVER_ERROR_METHOD,
|
||||
XmlRpcErrorCodes.SERVER_ERROR_METHOD_MSG + ": " + me.Message);
|
||||
}
|
||||
|
||||
Object[] args = new Object[parameters.Count];
|
||||
|
||||
int index = 0;
|
||||
foreach (Object arg in parameters)
|
||||
{
|
||||
args[index] = arg;
|
||||
index++;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Object retValue = method.Invoke(target, args);
|
||||
if (retValue == null)
|
||||
throw new XmlRpcException(XmlRpcErrorCodes.APPLICATION_ERROR,
|
||||
XmlRpcErrorCodes.APPLICATION_ERROR_MSG + ": Method returned NULL.");
|
||||
return retValue;
|
||||
}
|
||||
catch (XmlRpcException e)
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
catch (ArgumentException ae)
|
||||
{
|
||||
Logger.WriteEntry(XmlRpcErrorCodes.SERVER_ERROR_PARAMS_MSG + ": " + ae.Message,
|
||||
LogLevel.Information);
|
||||
String call = methodName + "( ";
|
||||
foreach (Object o in args)
|
||||
{
|
||||
call += o.GetType().Name;
|
||||
call += " ";
|
||||
}
|
||||
call += ")";
|
||||
throw new XmlRpcException(XmlRpcErrorCodes.SERVER_ERROR_PARAMS,
|
||||
XmlRpcErrorCodes.SERVER_ERROR_PARAMS_MSG + ": Arguement type mismatch invoking " + call);
|
||||
}
|
||||
catch (TargetParameterCountException tpce)
|
||||
{
|
||||
Logger.WriteEntry(XmlRpcErrorCodes.SERVER_ERROR_PARAMS_MSG + ": " + tpce.Message,
|
||||
LogLevel.Information);
|
||||
throw new XmlRpcException(XmlRpcErrorCodes.SERVER_ERROR_PARAMS,
|
||||
XmlRpcErrorCodes.SERVER_ERROR_PARAMS_MSG + ": Arguement count mismatch invoking " + methodName);
|
||||
}
|
||||
catch (TargetInvocationException tie)
|
||||
{
|
||||
throw new XmlRpcException(XmlRpcErrorCodes.APPLICATION_ERROR,
|
||||
XmlRpcErrorCodes.APPLICATION_ERROR_MSG + " Invoked method " + methodName + ": " + tie.Message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>List methods available on all handlers of this server.</summary>
|
||||
/// <returns><c>IList</c> An array of <c>Strings</c>, each <c>String</c> will have form "object.method".</returns>
|
||||
[XmlRpcExposed]
|
||||
public IList listMethods()
|
||||
{
|
||||
IList methods = new ArrayList();
|
||||
Boolean considerExposure;
|
||||
|
||||
foreach (DictionaryEntry handlerEntry in _server)
|
||||
{
|
||||
considerExposure = XmlRpcExposedAttribute.IsExposed(handlerEntry.Value.GetType());
|
||||
|
||||
foreach (MemberInfo mi in handlerEntry.Value.GetType().GetMembers())
|
||||
{
|
||||
if (mi.MemberType != MemberTypes.Method)
|
||||
continue;
|
||||
|
||||
if (!((MethodInfo)mi).IsPublic)
|
||||
continue;
|
||||
|
||||
if (considerExposure && !XmlRpcExposedAttribute.IsExposed(mi))
|
||||
continue;
|
||||
|
||||
methods.Add(handlerEntry.Key + "." + mi.Name);
|
||||
}
|
||||
}
|
||||
|
||||
return methods;
|
||||
}
|
||||
|
||||
/// <summary>Given a method name return the possible signatures for it.</summary>
|
||||
/// <param name="name"><c>String</c> The object.method name to look up.</param>
|
||||
/// <returns><c>IList</c> Of arrays of signatures.</returns>
|
||||
[XmlRpcExposed]
|
||||
public IList methodSignature(String name)
|
||||
{
|
||||
IList signatures = new ArrayList();
|
||||
int index = name.IndexOf('.');
|
||||
|
||||
if (index < 0)
|
||||
return signatures;
|
||||
|
||||
String oName = name.Substring(0, index);
|
||||
Object obj = _server[oName];
|
||||
|
||||
if (obj == null)
|
||||
return signatures;
|
||||
|
||||
MemberInfo[] mi = obj.GetType().GetMember(name.Substring(index + 1));
|
||||
|
||||
if (mi == null || mi.Length != 1) // for now we want a single signature
|
||||
return signatures;
|
||||
|
||||
MethodInfo method;
|
||||
|
||||
try
|
||||
{
|
||||
method = (MethodInfo)mi[0];
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.WriteEntry("Attempted methodSignature call on " + mi[0] + " caused: " + e,
|
||||
LogLevel.Information);
|
||||
return signatures;
|
||||
}
|
||||
|
||||
if (!method.IsPublic)
|
||||
return signatures;
|
||||
|
||||
IList signature = new ArrayList();
|
||||
signature.Add(method.ReturnType.Name);
|
||||
|
||||
foreach (ParameterInfo param in method.GetParameters())
|
||||
{
|
||||
signature.Add(param.ParameterType.Name);
|
||||
}
|
||||
|
||||
|
||||
signatures.Add(signature);
|
||||
|
||||
return signatures;
|
||||
}
|
||||
|
||||
/// <summary>Help for given method signature. Not implemented yet.</summary>
|
||||
/// <param name="name"><c>String</c> The object.method name to look up.</param>
|
||||
/// <returns><c>String</c> help text. Rich HTML text.</returns>
|
||||
[XmlRpcExposed]
|
||||
public String methodHelp(String name)
|
||||
{
|
||||
String help = null;
|
||||
|
||||
try
|
||||
{
|
||||
help = (String)_methodHelp[_server.MethodName(name)];
|
||||
}
|
||||
catch (XmlRpcException e)
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
catch (Exception) { /* ignored */ };
|
||||
|
||||
if (help == null)
|
||||
help = "No help available for: " + name;
|
||||
|
||||
return help;
|
||||
}
|
||||
|
||||
/// <summary>Boxcarring support method.</summary>
|
||||
/// <param name="calls"><c>IList</c> of calls</param>
|
||||
/// <returns><c>ArrayList</c> of results/faults.</returns>
|
||||
[XmlRpcExposed]
|
||||
public IList multiCall(IList calls)
|
||||
{
|
||||
IList responses = new ArrayList();
|
||||
XmlRpcResponse fault = new XmlRpcResponse();
|
||||
|
||||
foreach (IDictionary call in calls)
|
||||
{
|
||||
try
|
||||
{
|
||||
XmlRpcRequest req = new XmlRpcRequest((String)call[XmlRpcXmlTokens.METHOD_NAME],
|
||||
(ArrayList)call[XmlRpcXmlTokens.PARAMS]);
|
||||
Object results = _server.Invoke(req);
|
||||
IList response = new ArrayList();
|
||||
response.Add(results);
|
||||
responses.Add(response);
|
||||
}
|
||||
catch (XmlRpcException e)
|
||||
{
|
||||
fault.SetFault(e.FaultCode, e.FaultString);
|
||||
responses.Add(fault.Value);
|
||||
}
|
||||
catch (Exception e2)
|
||||
{
|
||||
fault.SetFault(XmlRpcErrorCodes.APPLICATION_ERROR,
|
||||
XmlRpcErrorCodes.APPLICATION_ERROR_MSG + ": " + e2.Message);
|
||||
responses.Add(fault.Value);
|
||||
}
|
||||
}
|
||||
|
||||
return responses;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
76
Programs/SLProxy/XmlRpcCS/XmlRpcXmlTokens.cs
Normal file
76
Programs/SLProxy/XmlRpcCS/XmlRpcXmlTokens.cs
Normal file
@@ -0,0 +1,76 @@
|
||||
namespace Nwc.XmlRpc
|
||||
{
|
||||
using System;
|
||||
|
||||
/// <summary>Class collecting <c>String</c> tokens that are part of XML-RPC files.</summary>
|
||||
public class XmlRpcXmlTokens
|
||||
{
|
||||
/// <summary>C# formatting string to describe an ISO 8601 date.</summary>
|
||||
public const String ISO_DATETIME = "yyyyMMdd\\THH\\:mm\\:ss";
|
||||
/// <summary>Base64 field indicator.</summary>
|
||||
/// <remarks>Corresponds to the <base64> tag.</remarks>
|
||||
public const String BASE64 = "base64";
|
||||
/// <summary>String field indicator.</summary>
|
||||
/// <remarks>Corresponds to the <string> tag.</remarks>
|
||||
public const String STRING = "string";
|
||||
/// <summary>Integer field integer.</summary>
|
||||
/// <remarks>Corresponds to the <i4> tag.</remarks>
|
||||
public const String INT = "i4";
|
||||
/// <summary>Alternate integer field indicator.</summary>
|
||||
/// <remarks>Corresponds to the <int> tag.</remarks>
|
||||
public const String ALT_INT = "int";
|
||||
/// <summary>Date field indicator.</summary>
|
||||
/// <remarks>Corresponds to the <dateTime.iso8601> tag.</remarks>
|
||||
public const String DATETIME = "dateTime.iso8601";
|
||||
/// <summary>Boolean field indicator.</summary>
|
||||
/// <remarks>Corresponds to the <boolean> tag.</remarks>
|
||||
public const String BOOLEAN = "boolean";
|
||||
/// <summary>Value token.</summary>
|
||||
/// <remarks>Corresponds to the <value> tag.</remarks>
|
||||
public const String VALUE = "value";
|
||||
/// <summary>Name token.</summary>
|
||||
/// <remarks>Corresponds to the <name> tag.</remarks>
|
||||
public const String NAME = "name";
|
||||
/// <summary>Array field indicator..</summary>
|
||||
/// <remarks>Corresponds to the <array> tag.</remarks>
|
||||
public const String ARRAY = "array";
|
||||
/// <summary>Data token.</summary>
|
||||
/// <remarks>Corresponds to the <data> tag.</remarks>
|
||||
public const String DATA = "data";
|
||||
/// <summary>Member token.</summary>
|
||||
/// <remarks>Corresponds to the <member> tag.</remarks>
|
||||
public const String MEMBER = "member";
|
||||
/// <summary>Stuct field indicator.</summary>
|
||||
/// <remarks>Corresponds to the <struct> tag.</remarks>
|
||||
public const String STRUCT = "struct";
|
||||
/// <summary>Double field indicator.</summary>
|
||||
/// <remarks>Corresponds to the <double> tag.</remarks>
|
||||
public const String DOUBLE = "double";
|
||||
/// <summary>Param token.</summary>
|
||||
/// <remarks>Corresponds to the <param> tag.</remarks>
|
||||
public const String PARAM = "param";
|
||||
/// <summary>Params token.</summary>
|
||||
/// <remarks>Corresponds to the <params> tag.</remarks>
|
||||
public const String PARAMS = "params";
|
||||
/// <summary>MethodCall token.</summary>
|
||||
/// <remarks>Corresponds to the <methodCall> tag.</remarks>
|
||||
public const String METHOD_CALL = "methodCall";
|
||||
/// <summary>MethodName token.</summary>
|
||||
/// <remarks>Corresponds to the <methodName> tag.</remarks>
|
||||
public const String METHOD_NAME = "methodName";
|
||||
/// <summary>MethodResponse token</summary>
|
||||
/// <remarks>Corresponds to the <methodResponse> tag.</remarks>
|
||||
public const String METHOD_RESPONSE = "methodResponse";
|
||||
/// <summary>Fault response token.</summary>
|
||||
/// <remarks>Corresponds to the <fault> tag.</remarks>
|
||||
public const String FAULT = "fault";
|
||||
/// <summary>FaultCode token.</summary>
|
||||
/// <remarks>Corresponds to the <faultCode> tag.</remarks>
|
||||
public const String FAULT_CODE = "faultCode";
|
||||
/// <summary>FaultString token.</summary>
|
||||
/// <remarks>Corresponds to the <faultString> tag.</remarks>
|
||||
public const String FAULT_STRING = "faultString";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
33
Programs/SecondGlance/Properties/AssemblyInfo.cs
Normal file
33
Programs/SecondGlance/Properties/AssemblyInfo.cs
Normal file
@@ -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("SecondGlance")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("SecondGlance")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2006")]
|
||||
[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("02456c47-f074-4302-a3a3-01a719de9d20")]
|
||||
|
||||
// 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")]
|
||||
71
Programs/SecondGlance/Properties/Resources.Designer.cs
generated
Normal file
71
Programs/SecondGlance/Properties/Resources.Designer.cs
generated
Normal file
@@ -0,0 +1,71 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:2.0.50727.308
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace SecondGlance.Properties
|
||||
{
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// 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()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager
|
||||
{
|
||||
get
|
||||
{
|
||||
if ((resourceMan == null))
|
||||
{
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SecondGlance.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture
|
||||
{
|
||||
get
|
||||
{
|
||||
return resourceCulture;
|
||||
}
|
||||
set
|
||||
{
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
117
Programs/SecondGlance/Properties/Resources.resx
Normal file
117
Programs/SecondGlance/Properties/Resources.resx
Normal file
@@ -0,0 +1,117 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
30
Programs/SecondGlance/Properties/Settings.Designer.cs
generated
Normal file
30
Programs/SecondGlance/Properties/Settings.Designer.cs
generated
Normal file
@@ -0,0 +1,30 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:2.0.50727.308
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace SecondGlance.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
7
Programs/SecondGlance/Properties/Settings.settings
Normal file
7
Programs/SecondGlance/Properties/Settings.settings
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
|
||||
<Profiles>
|
||||
<Profile Name="(Default)" />
|
||||
</Profiles>
|
||||
<Settings />
|
||||
</SettingsFile>
|
||||
20
Programs/SecondGlance/SecondGlance.cs
Normal file
20
Programs/SecondGlance/SecondGlance.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace SecondGlance
|
||||
{
|
||||
static class SecondGlance
|
||||
{
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static void Main()
|
||||
{
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.Run(new frmSecondGlance());
|
||||
}
|
||||
}
|
||||
}
|
||||
98
Programs/SecondGlance/SecondGlance.csproj
Normal file
98
Programs/SecondGlance/SecondGlance.csproj
Normal file
@@ -0,0 +1,98 @@
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.50727</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{D72C92D1-559A-48A7-93F5-99F4E99F3F98}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>SecondGlance</RootNamespace>
|
||||
<AssemblyName>SecondGlance</AssemblyName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\..\bin\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release-docs|AnyCPU' ">
|
||||
<OutputPath>bin\Release-docs\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<CodeAnalysisRuleAssemblies>C:\Program Files\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop\\rules</CodeAnalysisRuleAssemblies>
|
||||
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
|
||||
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="frmSecondGlance.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="frmSecondGlance.Designer.cs">
|
||||
<DependentUpon>frmSecondGlance.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="SecondGlance.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<EmbeddedResource Include="frmSecondGlance.resx">
|
||||
<SubType>Designer</SubType>
|
||||
<DependentUpon>frmSecondGlance.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<Compile Include="Properties\Settings.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\libsecondlife\OpenMetaverse.csproj">
|
||||
<Project>{D9CDEDFB-8169-4B03-B57F-0DF638F044EC}</Project>
|
||||
<Name>OpenMetaverse</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\SLProxy\SLProxy.csproj">
|
||||
<Project>{E4115DC9-FC88-47D6-B3B6-2400AD19B80D}</Project>
|
||||
<Name>SLProxy</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
232
Programs/SecondGlance/frmSecondGlance.Designer.cs
generated
Normal file
232
Programs/SecondGlance/frmSecondGlance.Designer.cs
generated
Normal file
@@ -0,0 +1,232 @@
|
||||
namespace SecondGlance
|
||||
{
|
||||
partial class frmSecondGlance
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.panel1 = new System.Windows.Forms.Panel();
|
||||
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
|
||||
this.menuStrip1 = new System.Windows.Forms.MenuStrip();
|
||||
this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.newToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.openToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.saveToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.cboToLog = new System.Windows.Forms.ComboBox();
|
||||
this.cmdAddLogger = new System.Windows.Forms.Button();
|
||||
this.cmdDontLog = new System.Windows.Forms.Button();
|
||||
this.cboLogged = new System.Windows.Forms.ComboBox();
|
||||
this.lstPackets = new System.Windows.Forms.ListBox();
|
||||
this.panel1.SuspendLayout();
|
||||
this.splitContainer1.Panel1.SuspendLayout();
|
||||
this.splitContainer1.SuspendLayout();
|
||||
this.menuStrip1.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
this.panel1.Controls.Add(this.splitContainer1);
|
||||
this.panel1.Location = new System.Drawing.Point(29, 100);
|
||||
this.panel1.Name = "panel1";
|
||||
this.panel1.Size = new System.Drawing.Size(664, 333);
|
||||
this.panel1.TabIndex = 0;
|
||||
//
|
||||
// splitContainer1
|
||||
//
|
||||
this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.splitContainer1.Location = new System.Drawing.Point(0, 0);
|
||||
this.splitContainer1.Name = "splitContainer1";
|
||||
//
|
||||
// splitContainer1.Panel1
|
||||
//
|
||||
this.splitContainer1.Panel1.Controls.Add(this.lstPackets);
|
||||
this.splitContainer1.Size = new System.Drawing.Size(664, 333);
|
||||
this.splitContainer1.SplitterDistance = 294;
|
||||
this.splitContainer1.TabIndex = 0;
|
||||
//
|
||||
// menuStrip1
|
||||
//
|
||||
this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.fileToolStripMenuItem,
|
||||
this.aboutToolStripMenuItem});
|
||||
this.menuStrip1.Location = new System.Drawing.Point(0, 0);
|
||||
this.menuStrip1.Name = "menuStrip1";
|
||||
this.menuStrip1.Size = new System.Drawing.Size(705, 24);
|
||||
this.menuStrip1.TabIndex = 1;
|
||||
this.menuStrip1.Text = "menuStrip1";
|
||||
//
|
||||
// fileToolStripMenuItem
|
||||
//
|
||||
this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.newToolStripMenuItem,
|
||||
this.openToolStripMenuItem,
|
||||
this.toolStripMenuItem1,
|
||||
this.saveToolStripMenuItem,
|
||||
this.toolStripMenuItem2,
|
||||
this.exitToolStripMenuItem});
|
||||
this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
|
||||
this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
|
||||
this.fileToolStripMenuItem.Text = "File";
|
||||
//
|
||||
// newToolStripMenuItem
|
||||
//
|
||||
this.newToolStripMenuItem.Name = "newToolStripMenuItem";
|
||||
this.newToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.N)));
|
||||
this.newToolStripMenuItem.Size = new System.Drawing.Size(188, 22);
|
||||
this.newToolStripMenuItem.Text = "New Session";
|
||||
//
|
||||
// openToolStripMenuItem
|
||||
//
|
||||
this.openToolStripMenuItem.Name = "openToolStripMenuItem";
|
||||
this.openToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.O)));
|
||||
this.openToolStripMenuItem.Size = new System.Drawing.Size(188, 22);
|
||||
this.openToolStripMenuItem.Text = "Open Session";
|
||||
//
|
||||
// toolStripMenuItem1
|
||||
//
|
||||
this.toolStripMenuItem1.Name = "toolStripMenuItem1";
|
||||
this.toolStripMenuItem1.Size = new System.Drawing.Size(185, 6);
|
||||
//
|
||||
// saveToolStripMenuItem
|
||||
//
|
||||
this.saveToolStripMenuItem.Name = "saveToolStripMenuItem";
|
||||
this.saveToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.S)));
|
||||
this.saveToolStripMenuItem.Size = new System.Drawing.Size(188, 22);
|
||||
this.saveToolStripMenuItem.Text = "Save Session";
|
||||
//
|
||||
// toolStripMenuItem2
|
||||
//
|
||||
this.toolStripMenuItem2.Name = "toolStripMenuItem2";
|
||||
this.toolStripMenuItem2.Size = new System.Drawing.Size(185, 6);
|
||||
//
|
||||
// exitToolStripMenuItem
|
||||
//
|
||||
this.exitToolStripMenuItem.Name = "exitToolStripMenuItem";
|
||||
this.exitToolStripMenuItem.Size = new System.Drawing.Size(188, 22);
|
||||
this.exitToolStripMenuItem.Text = "Exit";
|
||||
//
|
||||
// aboutToolStripMenuItem
|
||||
//
|
||||
this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem";
|
||||
this.aboutToolStripMenuItem.Size = new System.Drawing.Size(52, 20);
|
||||
this.aboutToolStripMenuItem.Text = "About";
|
||||
//
|
||||
// cboToLog
|
||||
//
|
||||
this.cboToLog.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.cboToLog.FormattingEnabled = true;
|
||||
this.cboToLog.Location = new System.Drawing.Point(12, 27);
|
||||
this.cboToLog.Name = "cboToLog";
|
||||
this.cboToLog.Size = new System.Drawing.Size(150, 21);
|
||||
this.cboToLog.TabIndex = 4;
|
||||
//
|
||||
// cmdAddLogger
|
||||
//
|
||||
this.cmdAddLogger.Location = new System.Drawing.Point(168, 25);
|
||||
this.cmdAddLogger.Name = "cmdAddLogger";
|
||||
this.cmdAddLogger.Size = new System.Drawing.Size(75, 23);
|
||||
this.cmdAddLogger.TabIndex = 5;
|
||||
this.cmdAddLogger.Text = "Log";
|
||||
this.cmdAddLogger.UseVisualStyleBackColor = true;
|
||||
this.cmdAddLogger.Click += new System.EventHandler(this.cmdAddLogger_Click);
|
||||
//
|
||||
// cmdDontLog
|
||||
//
|
||||
this.cmdDontLog.Location = new System.Drawing.Point(430, 25);
|
||||
this.cmdDontLog.Name = "cmdDontLog";
|
||||
this.cmdDontLog.Size = new System.Drawing.Size(75, 23);
|
||||
this.cmdDontLog.TabIndex = 7;
|
||||
this.cmdDontLog.Text = "Don\'t Log";
|
||||
this.cmdDontLog.UseVisualStyleBackColor = true;
|
||||
this.cmdDontLog.Click += new System.EventHandler(this.cmdDontLog_Click);
|
||||
//
|
||||
// cboLogged
|
||||
//
|
||||
this.cboLogged.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.cboLogged.FormattingEnabled = true;
|
||||
this.cboLogged.Location = new System.Drawing.Point(274, 27);
|
||||
this.cboLogged.Name = "cboLogged";
|
||||
this.cboLogged.Size = new System.Drawing.Size(150, 21);
|
||||
this.cboLogged.TabIndex = 6;
|
||||
//
|
||||
// lstPackets
|
||||
//
|
||||
this.lstPackets.FormattingEnabled = true;
|
||||
this.lstPackets.Location = new System.Drawing.Point(26, 40);
|
||||
this.lstPackets.Name = "lstPackets";
|
||||
this.lstPackets.Size = new System.Drawing.Size(243, 277);
|
||||
this.lstPackets.TabIndex = 1;
|
||||
//
|
||||
// frmSecondGlance
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(705, 498);
|
||||
this.Controls.Add(this.cmdDontLog);
|
||||
this.Controls.Add(this.cboLogged);
|
||||
this.Controls.Add(this.cmdAddLogger);
|
||||
this.Controls.Add(this.cboToLog);
|
||||
this.Controls.Add(this.panel1);
|
||||
this.Controls.Add(this.menuStrip1);
|
||||
this.MainMenuStrip = this.menuStrip1;
|
||||
this.Name = "frmSecondGlance";
|
||||
this.Text = "Second Glance";
|
||||
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.frmSecondGlance_FormClosing);
|
||||
this.panel1.ResumeLayout(false);
|
||||
this.splitContainer1.Panel1.ResumeLayout(false);
|
||||
this.splitContainer1.ResumeLayout(false);
|
||||
this.menuStrip1.ResumeLayout(false);
|
||||
this.menuStrip1.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Panel panel1;
|
||||
private System.Windows.Forms.SplitContainer splitContainer1;
|
||||
private System.Windows.Forms.MenuStrip menuStrip1;
|
||||
private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem newToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem openToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1;
|
||||
private System.Windows.Forms.ToolStripMenuItem saveToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem2;
|
||||
private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem;
|
||||
private System.Windows.Forms.ComboBox cboToLog;
|
||||
private System.Windows.Forms.Button cmdAddLogger;
|
||||
private System.Windows.Forms.Button cmdDontLog;
|
||||
private System.Windows.Forms.ComboBox cboLogged;
|
||||
private System.Windows.Forms.ListBox lstPackets;
|
||||
}
|
||||
}
|
||||
|
||||
154
Programs/SecondGlance/frmSecondGlance.cs
Normal file
154
Programs/SecondGlance/frmSecondGlance.cs
Normal file
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2007 openmetaverse.org
|
||||
* All rights reserved.
|
||||
*
|
||||
* - Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* - Neither the name of the openmetaverse.org nor the names
|
||||
* of its contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Net;
|
||||
using System.Windows.Forms;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.Packets;
|
||||
using SLProxy;
|
||||
|
||||
namespace SecondGlance
|
||||
{
|
||||
public partial class frmSecondGlance : Form
|
||||
{
|
||||
private Proxy Proxy;
|
||||
private Queue<LoggedPacket> Inbox = new Queue<LoggedPacket>();
|
||||
private System.Timers.Timer DisplayTimer = new System.Timers.Timer(200);
|
||||
|
||||
public frmSecondGlance()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
PacketType[] types = (PacketType[])Enum.GetValues(typeof(PacketType));
|
||||
|
||||
// Fill up the "To Log" combo box with options
|
||||
foreach (PacketType type in types)
|
||||
{
|
||||
if (type != PacketType.Default) cboToLog.Items.Add(type);
|
||||
}
|
||||
|
||||
// Set the default selection to the first entry
|
||||
cboToLog.SelectedIndex = 0;
|
||||
|
||||
// Setup the proxy
|
||||
ProxyConfig proxyConfig = new ProxyConfig("Second Glance", "John Hurliman <jhurliman@wsu.edu>",
|
||||
new string[0]);
|
||||
Proxy = new Proxy(proxyConfig);
|
||||
|
||||
Proxy.Start();
|
||||
|
||||
// Start the timer that moves packets from the queue and displays them
|
||||
DisplayTimer.Elapsed += new System.Timers.ElapsedEventHandler(DisplayTimer_Elapsed);
|
||||
DisplayTimer.Start();
|
||||
}
|
||||
|
||||
void DisplayTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
|
||||
{
|
||||
this.BeginInvoke(new MethodInvoker(UpdateDisplay));
|
||||
}
|
||||
|
||||
void UpdateDisplay()
|
||||
{
|
||||
lock (Inbox)
|
||||
{
|
||||
while (Inbox.Count > 0)
|
||||
{
|
||||
lstPackets.Items.Add(Inbox.Dequeue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void frmSecondGlance_FormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
DisplayTimer.Stop();
|
||||
Proxy.Stop();
|
||||
}
|
||||
|
||||
private void cmdAddLogger_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (!cboLogged.Items.Contains(cboToLog.SelectedItem))
|
||||
{
|
||||
PacketType type = (PacketType)cboToLog.SelectedItem;
|
||||
|
||||
cboLogged.Items.Add(type);
|
||||
|
||||
Proxy.AddDelegate(type, Direction.Incoming, new PacketDelegate(IncomingPacketHandler));
|
||||
Proxy.AddDelegate(type, Direction.Outgoing, new PacketDelegate(OutgoingPacketHandler));
|
||||
}
|
||||
}
|
||||
|
||||
private void cmdDontLog_Click(object sender, EventArgs e)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
private Packet IncomingPacketHandler(Packet packet, IPEndPoint sim)
|
||||
{
|
||||
return PacketHandler(packet, sim, Direction.Incoming);
|
||||
}
|
||||
|
||||
private Packet OutgoingPacketHandler(Packet packet, IPEndPoint sim)
|
||||
{
|
||||
return PacketHandler(packet, sim, Direction.Outgoing);
|
||||
}
|
||||
|
||||
private Packet PacketHandler(Packet packet, IPEndPoint sim, Direction direction)
|
||||
{
|
||||
LoggedPacket logged = new LoggedPacket();
|
||||
logged.Packet = packet;
|
||||
logged.Sim = sim;
|
||||
logged.Direction = direction;
|
||||
|
||||
lock (Inbox)
|
||||
Inbox.Enqueue(logged);
|
||||
|
||||
// TODO: Packet modifications
|
||||
|
||||
return packet;
|
||||
}
|
||||
}
|
||||
|
||||
public class LoggedPacket
|
||||
{
|
||||
public Packet Packet;
|
||||
public IPEndPoint Sim;
|
||||
public Direction Direction;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string text = (Direction == Direction.Incoming) ? "<-- " : "--> ";
|
||||
text += Sim.ToString() + " " + Packet.Type.ToString();
|
||||
|
||||
return text;
|
||||
}
|
||||
}
|
||||
}
|
||||
123
Programs/SecondGlance/frmSecondGlance.resx
Normal file
123
Programs/SecondGlance/frmSecondGlance.resx
Normal file
@@ -0,0 +1,123 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="menuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
</root>
|
||||
80
Programs/VoiceTest/VoiceTest.build
Normal file
80
Programs/VoiceTest/VoiceTest.build
Normal file
@@ -0,0 +1,80 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<project name="libsecondlife" default="build">
|
||||
|
||||
<!-- global framework settings -->
|
||||
<property name="target.framework" value="${framework::get-target-framework()}" />
|
||||
<property name="assembly.dir" value="${framework::get-assembly-directory(target.framework)}" />
|
||||
|
||||
<!-- global project settings -->
|
||||
<xmlpeek
|
||||
file="../libsecondlife.build"
|
||||
xpath="/project/property[@name = 'project.version']/@value"
|
||||
property="project.version" />
|
||||
<property name="build.number"
|
||||
value="${math::abs(math::floor(timespan::get-total-days(datetime::now()
|
||||
- datetime::parse('01/01/2002'))))}" />
|
||||
<property name="assembly" value="SLProxy"/>
|
||||
<property name="bin_dir" value="../bin" />
|
||||
|
||||
<!-- default configuration -->
|
||||
<property name="project.config" value="debug" /> <!-- debug|release -->
|
||||
|
||||
<!-- named configurations -->
|
||||
<target name="init" description="Initializes build properties">
|
||||
<call target="${project.config}" />
|
||||
</target>
|
||||
|
||||
<target name="debug" description="configures a debug build">
|
||||
<property name="build.debug" value="true" />
|
||||
<property name="package.name"
|
||||
value="${project::get-name()}-${project.version}-${project.config}" />
|
||||
<property name="assembly.configuration"
|
||||
value="${framework::get-target-framework()}.${platform::get-name()} [${project.config}]" />
|
||||
</target>
|
||||
|
||||
<target name="release" description="configures a release build">
|
||||
<property name="project.config" value="release" />
|
||||
<property name="build.debug" value="false" />
|
||||
<property name="package.name"
|
||||
value="${project::get-name()}-${project.version}" />
|
||||
<property name="assembly.configuration"
|
||||
value="${framework::get-target-framework()}.${platform::get-name()}" />
|
||||
</target>
|
||||
|
||||
<!-- build tasks -->
|
||||
<target name="build"
|
||||
depends="init"
|
||||
description="build VoiceTest">
|
||||
<echo message="Build Directory is ${bin_dir}/" />
|
||||
<mkdir dir="${bin_dir}" failonerror="false" />
|
||||
<csc
|
||||
target="exe"
|
||||
debug="${build.debug}"
|
||||
output="${bin_dir}/VoiceTest.exe">
|
||||
<sources failonempty="true">
|
||||
<include name="VoiceTest.cs" />
|
||||
</sources>
|
||||
<references basedir="${bin_dir}/">
|
||||
<include name="libsecondlife.dll"/>
|
||||
</references>
|
||||
</csc>
|
||||
</target>
|
||||
|
||||
<target name="clean" depends="init"
|
||||
description="Deletes the current configuration">
|
||||
<delete failonerror="false">
|
||||
<fileset basedir="${bin_dir}/">
|
||||
<include name="VoiceTest.exe" />
|
||||
<include name="VoiceTest.exe.mdb" />
|
||||
</fileset>
|
||||
</delete>
|
||||
</target>
|
||||
|
||||
<target
|
||||
name="*"
|
||||
description="Handles unknown targets">
|
||||
<echo message="skipping unknown target" />
|
||||
</target>
|
||||
</project>
|
||||
|
||||
202
Programs/VoiceTest/VoiceTest.cs
Normal file
202
Programs/VoiceTest/VoiceTest.cs
Normal file
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2008, openmetaverse.org
|
||||
* All rights reserved.
|
||||
*
|
||||
* - Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* - Neither the name of the openmetaverse.org nor the names
|
||||
* of its contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.Utilities;
|
||||
|
||||
namespace VoiceTest
|
||||
{
|
||||
public class VoiceException: Exception
|
||||
{
|
||||
public bool LoggedIn = false;
|
||||
|
||||
public VoiceException(string msg): base(msg)
|
||||
{
|
||||
}
|
||||
|
||||
public VoiceException(string msg, bool loggedIn): base(msg)
|
||||
{
|
||||
LoggedIn = loggedIn;
|
||||
}
|
||||
}
|
||||
|
||||
class VoiceTest
|
||||
{
|
||||
static AutoResetEvent EventQueueRunningEvent = new AutoResetEvent(false);
|
||||
static AutoResetEvent ProvisionEvent = new AutoResetEvent(false);
|
||||
static AutoResetEvent ParcelVoiceInfoEvent = new AutoResetEvent(false);
|
||||
static string VoiceAccount = String.Empty;
|
||||
static string VoicePassword = String.Empty;
|
||||
static string VoiceRegionName = String.Empty;
|
||||
static int VoiceLocalID = 0;
|
||||
static string VoiceChannelURI = String.Empty;
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
if (args.Length < 3)
|
||||
{
|
||||
Console.WriteLine("Usage: VoiceTest.exe [firstname] [lastname] [password]");
|
||||
return;
|
||||
}
|
||||
|
||||
string firstName = args[0];
|
||||
string lastName = args[1];
|
||||
string password = args[2];
|
||||
|
||||
|
||||
GridClient client = new GridClient();
|
||||
client.Settings.MULTIPLE_SIMS = false;
|
||||
Settings.LOG_LEVEL = Helpers.LogLevel.None;
|
||||
client.Settings.LOG_RESENDS = false;
|
||||
client.Settings.STORE_LAND_PATCHES = true;
|
||||
client.Settings.ALWAYS_DECODE_OBJECTS = true;
|
||||
client.Settings.ALWAYS_REQUEST_OBJECTS = true;
|
||||
client.Settings.SEND_AGENT_UPDATES = true;
|
||||
|
||||
string loginURI = client.Settings.LOGIN_SERVER;
|
||||
if (4 == args.Length) {
|
||||
loginURI = args[3];
|
||||
}
|
||||
|
||||
VoiceManager voice = new VoiceManager(client);
|
||||
voice.OnProvisionAccount += voice_OnProvisionAccount;
|
||||
voice.OnParcelVoiceInfo += voice_OnParcelVoiceInfo;
|
||||
|
||||
client.Network.OnEventQueueRunning += client_OnEventQueueRunning;
|
||||
|
||||
try {
|
||||
if (!voice.ConnectToDaemon()) throw new VoiceException("Failed to connect to the voice daemon");
|
||||
|
||||
List<string> captureDevices = voice.CaptureDevices();
|
||||
|
||||
Console.WriteLine("Capture Devices:");
|
||||
for (int i = 0; i < captureDevices.Count; i++)
|
||||
Console.WriteLine(String.Format("{0}. \"{1}\"", i, captureDevices[i]));
|
||||
Console.WriteLine();
|
||||
|
||||
List<string> renderDevices = voice.RenderDevices();
|
||||
|
||||
Console.WriteLine("Render Devices:");
|
||||
for (int i = 0; i < renderDevices.Count; i++)
|
||||
Console.WriteLine(String.Format("{0}. \"{1}\"", i, renderDevices[i]));
|
||||
Console.WriteLine();
|
||||
|
||||
|
||||
// Login
|
||||
Console.WriteLine("Logging into the grid as " + firstName + " " + lastName + "...");
|
||||
LoginParams loginParams =
|
||||
client.Network.DefaultLoginParams(firstName, lastName, password, "Voice Test", "1.0.0");
|
||||
loginParams.URI = loginURI;
|
||||
if (!client.Network.Login(loginParams))
|
||||
throw new VoiceException("Login to SL failed: " + client.Network.LoginMessage);
|
||||
Console.WriteLine("Logged in: " + client.Network.LoginMessage);
|
||||
|
||||
|
||||
Console.WriteLine("Creating voice connector...");
|
||||
int status;
|
||||
string connectorHandle = voice.CreateConnector(out status);
|
||||
if (String.IsNullOrEmpty(connectorHandle))
|
||||
throw new VoiceException("Failed to create a voice connector, error code: " + status, true);
|
||||
Console.WriteLine("Voice connector handle: " + connectorHandle);
|
||||
|
||||
|
||||
Console.WriteLine("Waiting for OnEventQueueRunning");
|
||||
if (!EventQueueRunningEvent.WaitOne(45 * 1000, false))
|
||||
throw new VoiceException("EventQueueRunning event did not occur", true);
|
||||
Console.WriteLine("EventQueue running");
|
||||
|
||||
|
||||
Console.WriteLine("Asking the current simulator to create a provisional account...");
|
||||
if (!voice.RequestProvisionAccount())
|
||||
throw new VoiceException("Failed to request a provisional account", true);
|
||||
if (!ProvisionEvent.WaitOne(120 * 1000, false))
|
||||
throw new VoiceException("Failed to create a provisional account", true);
|
||||
Console.WriteLine("Provisional account created. Username: " + VoiceAccount +
|
||||
", Password: " + VoicePassword);
|
||||
|
||||
|
||||
Console.WriteLine("Logging in to voice server " + voice.VoiceServer);
|
||||
string accountHandle = voice.Login(VoiceAccount, VoicePassword, connectorHandle, out status);
|
||||
if (String.IsNullOrEmpty(accountHandle))
|
||||
throw new VoiceException("Login failed, error code: " + status, true);
|
||||
Console.WriteLine("Login succeeded, account handle: " + accountHandle);
|
||||
|
||||
|
||||
if (!voice.RequestParcelVoiceInfo())
|
||||
throw new Exception("Failed to request parcel voice info");
|
||||
if (!ParcelVoiceInfoEvent.WaitOne(45 * 1000, false))
|
||||
throw new VoiceException("Failed to obtain parcel info voice", true);
|
||||
|
||||
|
||||
Console.WriteLine("Parcel Voice Info obtained. Region name {0}, local parcel ID {1}, channel URI {2}",
|
||||
VoiceRegionName, VoiceLocalID, VoiceChannelURI);
|
||||
|
||||
client.Network.Logout();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Console.WriteLine(e.Message);
|
||||
if (e is VoiceException && (e as VoiceException).LoggedIn)
|
||||
{
|
||||
client.Network.Logout();
|
||||
}
|
||||
|
||||
}
|
||||
Console.WriteLine("Press any key to continue...");
|
||||
Console.ReadKey();
|
||||
}
|
||||
|
||||
static void client_OnEventQueueRunning(Simulator sim) {
|
||||
EventQueueRunningEvent.Set();
|
||||
}
|
||||
|
||||
static void client_OnLogMessage(string message, Helpers.LogLevel level)
|
||||
{
|
||||
if (level == Helpers.LogLevel.Warning || level == Helpers.LogLevel.Error)
|
||||
Console.WriteLine(level.ToString() + ": " + message);
|
||||
}
|
||||
|
||||
static void voice_OnProvisionAccount(string username, string password)
|
||||
{
|
||||
VoiceAccount = username;
|
||||
VoicePassword = password;
|
||||
|
||||
ProvisionEvent.Set();
|
||||
}
|
||||
|
||||
static void voice_OnParcelVoiceInfo(string regionName, int localID, string channelURI)
|
||||
{
|
||||
VoiceRegionName = regionName;
|
||||
VoiceLocalID = localID;
|
||||
VoiceChannelURI = channelURI;
|
||||
|
||||
ParcelVoiceInfoEvent.Set();
|
||||
}
|
||||
}
|
||||
}
|
||||
70
Programs/VoiceTest/VoiceTest.csproj
Normal file
70
Programs/VoiceTest/VoiceTest.csproj
Normal file
@@ -0,0 +1,70 @@
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.50727</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{B69597A7-5DC5-4564-9089-727D0348EB4E}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>VoiceTest</RootNamespace>
|
||||
<AssemblyName>VoiceTest</AssemblyName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>..\bin\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\bin\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release-docs|AnyCPU' ">
|
||||
<OutputPath>bin\Release-docs\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<CodeAnalysisRuleAssemblies>C:\Program Files\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop\\rules</CodeAnalysisRuleAssemblies>
|
||||
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
|
||||
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="VoiceTest.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\libsecondlife\OpenMetaverse.csproj">
|
||||
<Project>{D9CDEDFB-8169-4B03-B57F-0DF638F044EC}</Project>
|
||||
<Name>OpenMetaverse</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\libsecondlife\libsecondlife.Utilities\OpenMetaverse.Utilities.csproj">
|
||||
<Project>{CE5E06C2-2428-416B-ADC1-F1FE16A0FB27}</Project>
|
||||
<Name>OpenMetaverse.Utilities</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Properties\" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
81
Programs/importprimscript/importprimscript.build
Normal file
81
Programs/importprimscript/importprimscript.build
Normal file
@@ -0,0 +1,81 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<project name="libsecondlife" default="build">
|
||||
|
||||
<!-- global framework settings -->
|
||||
<property name="target.framework" value="${framework::get-target-framework()}" />
|
||||
<property name="assembly.dir" value="${framework::get-assembly-directory(target.framework)}" />
|
||||
|
||||
<!-- global project settings -->
|
||||
<xmlpeek
|
||||
file="../libsecondlife.build"
|
||||
xpath="/project/property[@name = 'project.version']/@value"
|
||||
property="project.version" />
|
||||
<property name="build.number"
|
||||
value="${math::abs(math::floor(timespan::get-total-days(datetime::now()
|
||||
- datetime::parse('01/01/2002'))))}" />
|
||||
<property name="assembly" value="importprimscript"/>
|
||||
<property name="bin_dir" value="../bin" />
|
||||
|
||||
<!-- default configuration -->
|
||||
<property name="project.config" value="debug" /> <!-- debug|release -->
|
||||
|
||||
<!-- named configurations -->
|
||||
<target name="init" description="Initializes build properties">
|
||||
<call target="${project.config}" />
|
||||
</target>
|
||||
|
||||
<target name="debug" description="configures a debug build">
|
||||
<property name="build.debug" value="true" />
|
||||
<property name="package.name"
|
||||
value="${project::get-name()}-${project.version}-${project.config}" />
|
||||
<property name="assembly.configuration"
|
||||
value="${framework::get-target-framework()}.${platform::get-name()} [${project.config}]" />
|
||||
</target>
|
||||
|
||||
<target name="release" description="configures a release build">
|
||||
<property name="project.config" value="release" />
|
||||
<property name="build.debug" value="false" />
|
||||
<property name="package.name"
|
||||
value="${project::get-name()}-${project.version}" />
|
||||
<property name="assembly.configuration"
|
||||
value="${framework::get-target-framework()}.${platform::get-name()}" />
|
||||
</target>
|
||||
|
||||
<!-- build tasks -->
|
||||
<target name="build"
|
||||
depends="init"
|
||||
description="build importprimscript">
|
||||
<echo message="Build Directory is ${bin_dir}/" />
|
||||
<mkdir dir="${bin_dir}" failonerror="false" />
|
||||
<csc
|
||||
target="exe"
|
||||
debug="${build.debug}"
|
||||
output="${bin_dir}/importprimscript.exe">
|
||||
<sources failonempty="true">
|
||||
<include name="importprimscript.cs" />
|
||||
</sources>
|
||||
<references basedir="${bin_dir}/">
|
||||
<include name="libsecondlife.dll"/>
|
||||
<include name="System.Drawing.dll"/>
|
||||
</references>
|
||||
</csc>
|
||||
</target>
|
||||
|
||||
<target name="clean" depends="init"
|
||||
description="Deletes the current configuration">
|
||||
<delete failonerror="false">
|
||||
<fileset basedir="${bin_dir}/">
|
||||
<include name="importprimscript.exe" />
|
||||
<include name="importprimscript.exe.mdb" />
|
||||
</fileset>
|
||||
</delete>
|
||||
</target>
|
||||
|
||||
<target
|
||||
name="*"
|
||||
description="Handles unknown targets">
|
||||
<echo message="skipping unknown target" />
|
||||
</target>
|
||||
</project>
|
||||
|
||||
386
Programs/importprimscript/importprimscript.cs
Normal file
386
Programs/importprimscript/importprimscript.cs
Normal file
@@ -0,0 +1,386 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.IO;
|
||||
using System.Drawing;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.Capabilities;
|
||||
using OpenMetaverse.Imaging;
|
||||
|
||||
namespace importprimscript
|
||||
{
|
||||
class Sculpt
|
||||
{
|
||||
public string Name;
|
||||
public string TextureFile;
|
||||
public LLUUID TextureID;
|
||||
public string SculptFile;
|
||||
public LLUUID SculptID;
|
||||
public LLVector3 Scale;
|
||||
public LLVector3 Offset;
|
||||
}
|
||||
|
||||
class importprimscript
|
||||
{
|
||||
static GridClient Client = new GridClient();
|
||||
static Sculpt CurrentSculpt = null;
|
||||
static AutoResetEvent RezzedEvent = new AutoResetEvent(false);
|
||||
static LLVector3 RootPosition = LLVector3.Zero;
|
||||
static List<uint> RezzedPrims = new List<uint>();
|
||||
static LLUUID UploadFolderID = LLUUID.Zero;
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
if (args.Length != 8 && args.Length != 9)
|
||||
{
|
||||
Console.WriteLine("Usage: importprimscript.exe [firstname] [lastname] [password] " +
|
||||
"[loginuri] [Simulator] [x] [y] [z] [input.primscript]" +
|
||||
Environment.NewLine + "Example: importprimscript.exe My Bot password " +
|
||||
"Hooper 128 128 40 maya-export" + Path.DirectorySeparatorChar + "ant.primscript" +
|
||||
Environment.NewLine + "(the loginuri is optional and only used for logging in to another grid)");
|
||||
Environment.Exit(-1);
|
||||
}
|
||||
|
||||
// Strip quotes from any arguments
|
||||
for (int i = 0; i < args.Length; i++)
|
||||
args[i] = args[i].Trim(new char[] { '"' });
|
||||
|
||||
// Parse the primscript file
|
||||
string scriptfilename = args[args.Length - 1];
|
||||
string error;
|
||||
List<Sculpt> sculpties = ParsePrimscript(scriptfilename, out error);
|
||||
scriptfilename = Path.GetFileNameWithoutExtension(scriptfilename);
|
||||
|
||||
// Check for parsing errors
|
||||
if (error != String.Empty)
|
||||
{
|
||||
Console.WriteLine("An error was encountered reading the input file: " + error);
|
||||
Environment.Exit(-2);
|
||||
}
|
||||
else if (sculpties.Count == 0)
|
||||
{
|
||||
Console.WriteLine("No primitives were read from the input file");
|
||||
Environment.Exit(-3);
|
||||
}
|
||||
|
||||
// Add callback handlers for asset uploads finishing. new prims spotted, and logging
|
||||
Client.Objects.OnNewPrim += new ObjectManager.NewPrimCallback(Objects_OnNewPrim);
|
||||
Logger.OnLogMessage += new Logger.LogCallback(Client_OnLogMessage);
|
||||
|
||||
// Optimize the connection for our purposes
|
||||
Client.Self.Movement.Camera.Far = 64f;
|
||||
Client.Settings.MULTIPLE_SIMS = false;
|
||||
Client.Settings.SEND_AGENT_UPDATES = true;
|
||||
Client.Settings.DISABLE_AGENT_UPDATE_DUPLICATE_CHECK = true;
|
||||
Settings.LOG_LEVEL = Helpers.LogLevel.None;
|
||||
Client.Settings.ALWAYS_REQUEST_OBJECTS = true;
|
||||
Client.Settings.ALWAYS_DECODE_OBJECTS = true;
|
||||
Client.Throttle.Land = 0;
|
||||
Client.Throttle.Wind = 0;
|
||||
Client.Throttle.Cloud = 0;
|
||||
// Not sure if Asset or Texture will help with uploads, but it won't hurt
|
||||
Client.Throttle.Asset = 220000.0f;
|
||||
Client.Throttle.Texture = 446000.0f;
|
||||
Client.Throttle.Task = 446000.0f;
|
||||
|
||||
// Create a handler for the event queue connecting, so we know when
|
||||
// it is safe to start uploading
|
||||
AutoResetEvent eventQueueEvent = new AutoResetEvent(false);
|
||||
NetworkManager.EventQueueRunningCallback eventQueueCallback =
|
||||
delegate(Simulator simulator)
|
||||
{
|
||||
if (simulator == Client.Network.CurrentSim)
|
||||
eventQueueEvent.Set();
|
||||
};
|
||||
Client.Network.OnEventQueueRunning += eventQueueCallback;
|
||||
|
||||
int x = Int32.Parse(args[args.Length - 4]);
|
||||
int y = Int32.Parse(args[args.Length - 3]);
|
||||
int z = Int32.Parse(args[args.Length - 2]);
|
||||
string start = NetworkManager.StartLocation(args[args.Length - 5], x, y, z);
|
||||
|
||||
LoginParams loginParams = Client.Network.DefaultLoginParams(args[0], args[1], args[2],
|
||||
"importprimscript", "1.4.0");
|
||||
loginParams.Start = start;
|
||||
if (args.Length == 9) loginParams.URI = args[3];
|
||||
|
||||
// Attempt to login
|
||||
if (!Client.Network.Login(loginParams))
|
||||
{
|
||||
Console.WriteLine("Login failed: " + Client.Network.LoginMessage);
|
||||
Environment.Exit(-4);
|
||||
}
|
||||
|
||||
// Need to be connected to the event queue before we can upload
|
||||
Console.WriteLine("Login succeeded, waiting for the event handler to connect...");
|
||||
if (!eventQueueEvent.WaitOne(1000 * 90, false))
|
||||
{
|
||||
Console.WriteLine("Event queue connection timed out, disconnecting...");
|
||||
Client.Network.Logout();
|
||||
Environment.Exit(-5);
|
||||
}
|
||||
|
||||
// Don't need this anymore
|
||||
Client.Network.OnEventQueueRunning -= eventQueueCallback;
|
||||
|
||||
// Set the root position for the import
|
||||
RootPosition = Client.Self.SimPosition;
|
||||
RootPosition.Z += 3.0f;
|
||||
|
||||
// TODO: Check if our account balance is high enough to upload everything
|
||||
//
|
||||
|
||||
// Create a folder to hold all of our texture uploads
|
||||
UploadFolderID = Client.Inventory.CreateFolder(Client.Inventory.Store.RootFolder.UUID, scriptfilename);
|
||||
|
||||
// Loop through each sculpty and do what we need to do
|
||||
for (int i = 0; i < sculpties.Count; i++)
|
||||
{
|
||||
// Upload the sculpt map and texture
|
||||
sculpties[i].SculptID = UploadImage(sculpties[i].SculptFile, true);
|
||||
sculpties[i].TextureID = UploadImage(sculpties[i].TextureFile, false);
|
||||
|
||||
// Check for failed uploads
|
||||
if (sculpties[i].SculptID == LLUUID.Zero)
|
||||
{
|
||||
Console.WriteLine("Sculpt map " + sculpties[i].SculptFile + " failed to upload, skipping " + sculpties[i].Name);
|
||||
continue;
|
||||
}
|
||||
else if (sculpties[i].TextureID == LLUUID.Zero)
|
||||
{
|
||||
Console.WriteLine("Texture " + sculpties[i].TextureFile + " failed to upload, skipping " + sculpties[i].Name);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Create basic spherical volume parameters. It will be set to
|
||||
// a scultpy in the callback for new objects being created
|
||||
LLObject.ObjectData volume = new LLObject.ObjectData();
|
||||
volume.PCode = PCode.Prim;
|
||||
volume.Material = LLObject.MaterialType.Wood;
|
||||
volume.PathScaleY = 0.5f;
|
||||
volume.PathCurve = LLObject.PathCurve.Circle;
|
||||
volume.ProfileCurve = LLObject.ProfileCurve.Circle;
|
||||
|
||||
// Rez this prim
|
||||
CurrentSculpt = sculpties[i];
|
||||
Client.Objects.AddPrim(Client.Network.CurrentSim, volume, LLUUID.Zero,
|
||||
RootPosition + CurrentSculpt.Offset, CurrentSculpt.Scale, LLQuaternion.Identity);
|
||||
|
||||
// Wait for the prim to rez and the properties be set for it
|
||||
if (!RezzedEvent.WaitOne(1000 * 10, false))
|
||||
{
|
||||
Console.WriteLine("Timed out waiting for prim " + CurrentSculpt.Name + " to rez, skipping");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
CurrentSculpt = null;
|
||||
|
||||
lock (RezzedPrims)
|
||||
{
|
||||
// Set full permissions for all of the objects
|
||||
Client.Objects.SetPermissions(Client.Network.CurrentSim, RezzedPrims, PermissionWho.All,
|
||||
PermissionMask.All, true);
|
||||
|
||||
// Link the entire object together
|
||||
Client.Objects.LinkPrims(Client.Network.CurrentSim, RezzedPrims);
|
||||
}
|
||||
|
||||
Console.WriteLine("Rezzed, textured, and linked " + RezzedPrims.Count + " sculpted prims, logging out...");
|
||||
|
||||
Client.Network.Logout();
|
||||
}
|
||||
|
||||
static void Client_OnLogMessage(object message, Helpers.LogLevel level)
|
||||
{
|
||||
if (level >= Helpers.LogLevel.Warning)
|
||||
Console.WriteLine(level + ": " + message);
|
||||
}
|
||||
|
||||
static LLUUID UploadImage(string filename, bool lossless)
|
||||
{
|
||||
LLUUID newAssetID = LLUUID.Zero;
|
||||
byte[] jp2data = null;
|
||||
|
||||
try
|
||||
{
|
||||
Bitmap image = (Bitmap)Bitmap.FromFile(filename);
|
||||
jp2data = OpenJPEG.EncodeFromImage(image, lossless);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Failed to encode image file " + filename + ": " + ex.ToString());
|
||||
return LLUUID.Zero;
|
||||
}
|
||||
|
||||
AutoResetEvent uploadEvent = new AutoResetEvent(false);
|
||||
Client.Inventory.RequestCreateItemFromAsset(jp2data, Path.GetFileNameWithoutExtension(filename),
|
||||
"Uploaded with importprimscript", AssetType.Texture, InventoryType.Texture, UploadFolderID,
|
||||
|
||||
delegate(CapsClient client, long bytesReceived, long bytesSent, long totalBytesToReceive, long totalBytesToSend)
|
||||
{
|
||||
// FIXME: Do something with progress?
|
||||
},
|
||||
|
||||
delegate(bool success, string status, LLUUID itemID, LLUUID assetID)
|
||||
{
|
||||
if (success)
|
||||
{
|
||||
Console.WriteLine("Finished uploading image " + filename + ", AssetID: " + assetID.ToString());
|
||||
newAssetID = assetID;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Failed to upload image file " + filename + ": " + status);
|
||||
}
|
||||
|
||||
uploadEvent.Set();
|
||||
}
|
||||
);
|
||||
|
||||
// The images are small, 60 seconds should be plenty
|
||||
uploadEvent.WaitOne(1000 * 60, false);
|
||||
|
||||
return newAssetID;
|
||||
}
|
||||
|
||||
static void Objects_OnNewPrim(Simulator simulator, Primitive prim, ulong regionHandle, ushort timeDilation)
|
||||
{
|
||||
if (CurrentSculpt != null && (prim.Flags & LLObject.ObjectFlags.CreateSelected) != 0 &&
|
||||
!RezzedPrims.Contains(prim.LocalID))
|
||||
{
|
||||
lock (RezzedPrims) RezzedPrims.Add(prim.LocalID);
|
||||
|
||||
Console.WriteLine("Rezzed prim " + CurrentSculpt.Name + ", setting properties");
|
||||
|
||||
// Deselect the prim
|
||||
Client.Objects.DeselectObject(Client.Network.CurrentSim, prim.LocalID);
|
||||
|
||||
// Set the prim position
|
||||
Client.Objects.SetPosition(Client.Network.CurrentSim, prim.LocalID,
|
||||
RootPosition + CurrentSculpt.Offset);
|
||||
|
||||
// Set the texture
|
||||
LLObject.TextureEntry textures = new LLObject.TextureEntry(CurrentSculpt.TextureID);
|
||||
Client.Objects.SetTextures(Client.Network.CurrentSim, prim.LocalID, textures);
|
||||
|
||||
// Turn it in to a sculpted prim
|
||||
Primitive.SculptData sculpt = new Primitive.SculptData();
|
||||
sculpt.SculptTexture = CurrentSculpt.SculptID;
|
||||
sculpt.Type = Primitive.SculptType.Sphere;
|
||||
Client.Objects.SetSculpt(Client.Network.CurrentSim, prim.LocalID, sculpt);
|
||||
|
||||
// Set the prim name
|
||||
if (!String.IsNullOrEmpty(CurrentSculpt.Name))
|
||||
Client.Objects.SetName(Client.Network.CurrentSim, prim.LocalID, CurrentSculpt.Name);
|
||||
|
||||
RezzedEvent.Set();
|
||||
}
|
||||
}
|
||||
|
||||
static List<Sculpt> ParsePrimscript(string primscriptfile, out string error)
|
||||
{
|
||||
string line;
|
||||
Sculpt current = null;
|
||||
List<Sculpt> sculpties = new List<Sculpt>();
|
||||
error = String.Empty;
|
||||
StreamReader primscript = null;
|
||||
|
||||
// Parse a directory out of the primscriptfile string, if one exists
|
||||
string path = Path.GetDirectoryName(primscriptfile);
|
||||
if (!String.IsNullOrEmpty(path))
|
||||
path += Path.DirectorySeparatorChar;
|
||||
else
|
||||
path = String.Empty;
|
||||
|
||||
try
|
||||
{
|
||||
primscript = File.OpenText(primscriptfile);
|
||||
|
||||
while ((line = primscript.ReadLine()) != null)
|
||||
{
|
||||
string[] words = line.Split(new char[] { ' ' });
|
||||
|
||||
if (words.Length > 0)
|
||||
{
|
||||
if (current != null)
|
||||
{
|
||||
switch (words[0])
|
||||
{
|
||||
case "newPrim":
|
||||
if (current.Scale != LLVector3.Zero &&
|
||||
!String.IsNullOrEmpty(current.SculptFile) &&
|
||||
!String.IsNullOrEmpty(current.TextureFile))
|
||||
{
|
||||
// Add the previous prim to the list as it is now finalized
|
||||
sculpties.Add(current);
|
||||
}
|
||||
|
||||
// Start a new prim
|
||||
current = new Sculpt();
|
||||
|
||||
break;
|
||||
case "prim":
|
||||
// The only useful bit of information here is the prim name
|
||||
if (words.Length >= 3)
|
||||
current.Name = words[2];
|
||||
break;
|
||||
case "shape":
|
||||
// This line has the name of the sculpt texture
|
||||
if (words.Length >= 3)
|
||||
current.SculptFile = path + words[2] + ".bmp";
|
||||
break;
|
||||
case "texture":
|
||||
// This line has the name of the actual texture
|
||||
if (words.Length >= 3)
|
||||
current.TextureFile = path + words[2] + ".bmp";
|
||||
break;
|
||||
case "transform":
|
||||
// Get some primitive params
|
||||
if (words.Length >= 9)
|
||||
{
|
||||
float x, y, z;
|
||||
x = Single.Parse(words[2]);
|
||||
y = Single.Parse(words[3]);
|
||||
z = Single.Parse(words[4]);
|
||||
current.Scale = new LLVector3(x, y, z);
|
||||
|
||||
x = Single.Parse(words[6]);
|
||||
y = Single.Parse(words[7]);
|
||||
z = Single.Parse(words[8]);
|
||||
current.Offset = new LLVector3(x, y, z);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (words[0] == "newPrim")
|
||||
{
|
||||
// Start a new prim
|
||||
current = new Sculpt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add the final prim
|
||||
if (current != null && current.Scale != LLVector3.Zero &&
|
||||
!String.IsNullOrEmpty(current.SculptFile) &&
|
||||
!String.IsNullOrEmpty(current.TextureFile))
|
||||
{
|
||||
// Add the previous prim to the list as it is now finalized
|
||||
sculpties.Add(current);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
error = ex.ToString();
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (primscript != null)
|
||||
primscript.Close();
|
||||
}
|
||||
|
||||
return sculpties;
|
||||
}
|
||||
}
|
||||
}
|
||||
67
Programs/importprimscript/importprimscript.csproj
Normal file
67
Programs/importprimscript/importprimscript.csproj
Normal file
@@ -0,0 +1,67 @@
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.50727</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{32A7AA59-5129-4446-A6DC-2F581ED1A25C}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>importprimscript</RootNamespace>
|
||||
<AssemblyName>importprimscript</AssemblyName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>..\bin\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\bin\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release-docs|AnyCPU' ">
|
||||
<OutputPath>bin\Release-docs\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<CodeAnalysisRuleAssemblies>C:\Program Files\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop\\rules</CodeAnalysisRuleAssemblies>
|
||||
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
|
||||
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="importprimscript.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\libsecondlife\OpenMetaverse.csproj">
|
||||
<Project>{D9CDEDFB-8169-4B03-B57F-0DF638F044EC}</Project>
|
||||
<Name>OpenMetaverse</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Properties\" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
Reference in New Issue
Block a user