Part #2 of previous commit.

rexserver_r830
mikkopa 2008-02-20 08:25:07 +00:00
parent 0ab3e9a399
commit 778092e075
1478 changed files with 329007 additions and 0 deletions

41
.nant/local.include Normal file
View File

@ -0,0 +1,41 @@
<property name="projectdir" value="opensim-0.4" />
<target name="distdir">
<delete dir="${projectdir}" />
<copy todir="${projectdir}">
<fileset basedir=".">
<include name="ThirdPartyLicenses/**" />
<include name="CONTRIBUTORS.txt" />
<include name="README" />
<include name="OpenSim/**/*.cs" />
<include name="**/*.build" />
<include name="**/*.csproj" />
<include name="**/*.csproj.user" />
<include name="**/*.sln" />
<include name="bin/*.dll" />
<include name="bin/*.so" />
<include name="bin/*.config" />
<include name="bin/assets/**" />
<include name="bin/data/**" />
<include name="bin/OpenSim*xml" />
<!-- the next is to exclude built libs -->
<exclude name="bin/OpenSim.*dll" />
<include name="bin/OpenSim.ini" />
<include name="bin/defaultstripe.png" />
</fileset>
</copy>
<touch file="${projectdir}/bin/startup_commands.txt" />
</target>
<target name="dist" depends="distdir">
<zip zipfile="${projectdir}.zip">
<fileset basedir=".">
<include name="${projectdir}/**" />
</fileset>
</zip>
<tar destfile="${projectdir}.tar.gz" compression="GZip">
<fileset basedir=".">
<include name="${projectdir}/**" />
</fileset>
</tar>
</target>

View File

@ -0,0 +1,106 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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 Mono.Addins;
using OpenSim.Framework;
using OpenSim.Framework.Console;
using OpenSim.Framework.RegionLoader.Filesystem;
using OpenSim.Framework.RegionLoader.Web;
[assembly : Addin]
[assembly : AddinDependency("OpenSim", "0.4")]
namespace OpenSim.ApplicationPlugins.LoadRegions
{
[Extension("/OpenSim/Startup")]
public class LoadRegionsPlugin : IApplicationPlugin
{
public void Initialise(OpenSimMain openSim)
{
MainLog.Instance.Notice("LOADREGIONS", "Load Regions addin being initialised");
IRegionLoader regionLoader;
if (openSim.ConfigSource.Configs["Startup"].GetString("region_info_source", "filesystem") == "filesystem")
{
MainLog.Instance.Notice("LOADREGIONS", "Loading Region Info from filesystem");
regionLoader = new RegionLoaderFileSystem();
}
else
{
MainLog.Instance.Notice("LOADREGIONSPLUGIN", "Loading Region Info from web");
regionLoader = new RegionLoaderWebServer();
}
regionLoader.SetIniConfigSource(openSim.ConfigSource);
RegionInfo[] regionsToLoad = regionLoader.LoadRegions();
openSim.ModuleLoader.LoadDefaultSharedModules();
for (int i = 0; i < regionsToLoad.Length; i++)
{
MainLog.Instance.Debug("LOADREGIONS", "Creating Region: " + regionsToLoad[i].RegionName + " (ThreadID: " + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString() + ")");
openSim.CreateRegion(regionsToLoad[i]);
}
openSim.ModuleLoader.PostInitialise();
openSim.ModuleLoader.ClearCache();
}
public void LoadRegionFromConfig(OpenSimMain openSim, ulong regionhandle)
{
MainLog.Instance.Notice("LOADREGIONS", "Load Regions addin being initialised");
IRegionLoader regionLoader;
if (openSim.ConfigSource.Configs["Startup"].GetString("region_info_source", "filesystem") == "filesystem")
{
MainLog.Instance.Notice("LOADREGIONS", "Loading Region Info from filesystem");
regionLoader = new RegionLoaderFileSystem();
}
else
{
MainLog.Instance.Notice("LOADREGIONS", "Loading Region Info from web");
regionLoader = new RegionLoaderWebServer();
}
regionLoader.SetIniConfigSource(openSim.ConfigSource);
RegionInfo[] regionsToLoad = regionLoader.LoadRegions();
for (int i = 0; i < regionsToLoad.Length; i++)
{
if (regionhandle == regionsToLoad[i].RegionHandle)
{
MainLog.Instance.Debug("LOADREGIONS", "Creating Region: " + regionsToLoad[i].RegionName + " (ThreadID: " + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString() + ")");
openSim.CreateRegion(regionsToLoad[i]);
}
}
}
public void Close()
{
}
}
}

View File

@ -0,0 +1,39 @@
using System.Reflection;
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("OpenSim.Addin")]
[assembly : AssemblyDescription("")]
[assembly : AssemblyConfiguration("")]
[assembly : AssemblyCompany("")]
[assembly : AssemblyProduct("OpenSim.Addin")]
[assembly : AssemblyCopyright("Copyright © 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("45b979d9-d8d4-42fd-9780-fe9ac7e86cb4")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly : AssemblyVersion("1.0.0.0")]
[assembly : AssemblyFileVersion("1.0.0.0")]

View File

@ -0,0 +1,250 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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;
using System.Net;
using System.Timers;
using libsecondlife;
using Mono.Addins;
using Nwc.XmlRpc;
using OpenSim.Framework;
using OpenSim.Framework.Console;
using OpenSim.Framework.Servers;
using OpenSim.Region.Environment.Scenes;
[assembly : Addin]
[assembly : AddinDependency("OpenSim", "0.4")]
namespace OpenSim.ApplicationPlugins.LoadRegions
{
[Extension("/OpenSim/Startup")]
public class RemoteAdminPlugin : IApplicationPlugin
{
private OpenSimMain m_app;
private BaseHttpServer m_httpd;
private string requiredPassword = "";
public void Initialise(OpenSimMain openSim)
{
try
{
if (openSim.ConfigSource.Configs["RemoteAdmin"].GetBoolean("enabled", false))
{
MainLog.Instance.Verbose("RADMIN", "Remote Admin Plugin Enabled");
requiredPassword = openSim.ConfigSource.Configs["RemoteAdmin"].GetString("access_password", "");
m_app = openSim;
m_httpd = openSim.HttpServer;
m_httpd.AddXmlRPCHandler("admin_create_region", XmlRpcCreateRegionMethod);
m_httpd.AddXmlRPCHandler("admin_shutdown", XmlRpcShutdownMethod);
m_httpd.AddXmlRPCHandler("admin_broadcast", XmlRpcAlertMethod);
m_httpd.AddXmlRPCHandler("admin_restart", XmlRpcRestartMethod);
}
}
catch (NullReferenceException)
{
// Ignore.
}
}
public XmlRpcResponse XmlRpcRestartMethod(XmlRpcRequest request)
{
XmlRpcResponse response = new XmlRpcResponse();
Hashtable requestData = (Hashtable) request.Params[0];
LLUUID regionID = new LLUUID((string) requestData["regionID"]);
Hashtable responseData = new Hashtable();
if (requiredPassword != "" &&
(!requestData.Contains("password") || (string) requestData["password"] != requiredPassword))
{
responseData["accepted"] = "false";
response.Value = responseData;
}
else
{
responseData["accepted"] = "true";
response.Value = responseData;
Scene RebootedScene;
if (m_app.SceneManager.TryGetScene(regionID, out RebootedScene))
{
responseData["rebooting"] = "true";
RebootedScene.Restart(30);
}
else
{
responseData["rebooting"] = "false";
}
}
return response;
}
public XmlRpcResponse XmlRpcAlertMethod(XmlRpcRequest request)
{
XmlRpcResponse response = new XmlRpcResponse();
Hashtable requestData = (Hashtable) request.Params[0];
Hashtable responseData = new Hashtable();
if (requiredPassword != "" &&
(!requestData.Contains("password") || (string) requestData["password"] != requiredPassword))
{
responseData["accepted"] = "false";
response.Value = responseData;
}
else
{
string message = (string) requestData["message"];
MainLog.Instance.Verbose("RADMIN", "Broadcasting: " + message);
responseData["accepted"] = "true";
response.Value = responseData;
m_app.SceneManager.SendGeneralMessage(message);
}
return response;
}
public XmlRpcResponse XmlRpcShutdownMethod(XmlRpcRequest request)
{
MainLog.Instance.Verbose("RADMIN", "Received Shutdown Administrator Request");
XmlRpcResponse response = new XmlRpcResponse();
Hashtable requestData = (Hashtable) request.Params[0];
Hashtable responseData = new Hashtable();
if (requiredPassword != "" &&
(!requestData.Contains("password") || (string) requestData["password"] != requiredPassword))
{
responseData["accepted"] = "false";
response.Value = responseData;
}
else
{
if ((string) requestData["shutdown"] == "delayed")
{
int timeout = (Int32) requestData["milliseconds"];
responseData["accepted"] = "true";
response.Value = responseData;
m_app.SceneManager.SendGeneralMessage("Region is going down in " + ((int) (timeout/1000)).ToString() +
" second(s). Please save what you are doing and log out.");
// Perform shutdown
Timer shutdownTimer = new Timer(timeout); // Wait before firing
shutdownTimer.AutoReset = false;
shutdownTimer.Elapsed += new ElapsedEventHandler(shutdownTimer_Elapsed);
shutdownTimer.Start();
return response;
}
else
{
responseData["accepted"] = "true";
response.Value = responseData;
m_app.SceneManager.SendGeneralMessage("Region is going down now.");
// Perform shutdown
Timer shutdownTimer = new Timer(2000); // Wait 2 seconds before firing
shutdownTimer.AutoReset = false;
shutdownTimer.Elapsed += new ElapsedEventHandler(shutdownTimer_Elapsed);
shutdownTimer.Start();
return response;
}
}
return response;
}
private void shutdownTimer_Elapsed(object sender, ElapsedEventArgs e)
{
m_app.Shutdown();
}
public XmlRpcResponse XmlRpcCreateRegionMethod(XmlRpcRequest request)
{
MainLog.Instance.Verbose("RADMIN", "Received Create Region Administrator Request");
XmlRpcResponse response = new XmlRpcResponse();
Hashtable requestData = (Hashtable) request.Params[0];
Hashtable responseData = new Hashtable();
if (requiredPassword != "" &&
(!requestData.Contains("password") || (string) requestData["password"] != requiredPassword))
{
responseData["created"] = "false";
response.Value = responseData;
}
else
{
RegionInfo newRegionData = new RegionInfo();
try
{
newRegionData.RegionID = (string) requestData["region_id"];
newRegionData.RegionName = (string) requestData["region_name"];
newRegionData.RegionLocX = Convert.ToUInt32((Int32) requestData["region_x"]);
newRegionData.RegionLocY = Convert.ToUInt32((Int32) requestData["region_y"]);
// Security risk
newRegionData.DataStore = (string) requestData["datastore"];
newRegionData.InternalEndPoint = new IPEndPoint(
IPAddress.Parse((string) requestData["listen_ip"]), 0);
newRegionData.InternalEndPoint.Port = (Int32) requestData["listen_port"];
newRegionData.ExternalHostName = (string) requestData["external_address"];
newRegionData.MasterAvatarFirstName = (string) requestData["region_master_first"];
newRegionData.MasterAvatarLastName = (string) requestData["region_master_last"];
m_app.CreateRegion(newRegionData);
responseData["created"] = "true";
response.Value = responseData;
}
catch (Exception e)
{
responseData["created"] = "false";
responseData["error"] = e.ToString();
response.Value = responseData;
}
}
return response;
}
public void Close()
{
}
}
}

263
OpenSim/Framework/ACL.cs Normal file
View File

@ -0,0 +1,263 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS 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 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;
namespace OpenSim.Framework
{
// ACL Class
// Modelled after the structure of the Zend ACL Framework Library
// with one key difference - the tree will search for all matching
// permissions rather than just the first. Deny permissions will
// override all others.
#region ACL Core Class
/// <summary>
/// Access Control List Engine
/// </summary>
public class ACL
{
private Dictionary<string, Role> Roles = new Dictionary<string, Role>();
private Dictionary<string, Resource> Resources = new Dictionary<string, Resource>();
public ACL AddRole(Role role)
{
if (Roles.ContainsKey(role.Name))
throw new AlreadyContainsRoleException(role);
Roles.Add(role.Name, role);
return this;
}
public ACL AddResource(Resource resource)
{
Resources.Add(resource.Name, resource);
return this;
}
public Permission HasPermission(string role, string resource)
{
if (!Roles.ContainsKey(role))
throw new KeyNotFoundException();
if (!Resources.ContainsKey(resource))
throw new KeyNotFoundException();
return Roles[role].RequestPermission(resource);
}
public ACL GrantPermission(string role, string resource)
{
if (!Roles.ContainsKey(role))
throw new KeyNotFoundException();
if (!Resources.ContainsKey(resource))
throw new KeyNotFoundException();
Roles[role].GivePermission(resource, Permission.Allow);
return this;
}
public ACL DenyPermission(string role, string resource)
{
if (!Roles.ContainsKey(role))
throw new KeyNotFoundException();
if (!Resources.ContainsKey(resource))
throw new KeyNotFoundException();
Roles[role].GivePermission(resource, Permission.Deny);
return this;
}
public ACL ResetPermission(string role, string resource)
{
if (!Roles.ContainsKey(role))
throw new KeyNotFoundException();
if (!Resources.ContainsKey(resource))
throw new KeyNotFoundException();
Roles[role].GivePermission(resource, Permission.None);
return this;
}
}
#endregion
#region Exceptions
/// <summary>
/// Thrown when an ACL attempts to add a duplicate role.
/// </summary>
public class AlreadyContainsRoleException : Exception
{
protected Role m_role;
public Role ErrorRole
{
get { return m_role; }
}
public AlreadyContainsRoleException(Role role)
{
m_role = role;
}
public override string ToString()
{
return "This ACL already contains a role called '" + m_role.Name + "'.";
}
}
#endregion
#region Roles and Resources
/// <summary>
/// Does this Role have permission to access a specified Resource?
/// </summary>
public enum Permission
{
Deny,
None,
Allow
} ;
/// <summary>
/// A role class, for use with Users or Groups
/// </summary>
public class Role
{
private string m_name;
private Role[] m_parents;
private Dictionary<string, Permission> m_resources = new Dictionary<string, Permission>();
public string Name
{
get { return m_name; }
}
public Permission RequestPermission(string resource)
{
return RequestPermission(resource, Permission.None);
}
public Permission RequestPermission(string resource, Permission current)
{
// Deny permissions always override any others
if (current == Permission.Deny)
return current;
Permission temp = Permission.None;
// Pickup non-None permissions
if (m_resources.ContainsKey(resource) && m_resources[resource] != Permission.None)
temp = m_resources[resource];
if (m_parents != null)
{
foreach (Role parent in m_parents)
{
temp = parent.RequestPermission(resource, temp);
}
}
return temp;
}
public void GivePermission(string resource, Permission perm)
{
m_resources[resource] = perm;
}
public Role(string name)
{
m_name = name;
m_parents = null;
}
public Role(string name, Role[] parents)
{
m_name = name;
m_parents = parents;
}
}
public class Resource
{
private string m_name;
public string Name
{
get { return m_name; }
}
public Resource(string name)
{
m_name = name;
}
}
#endregion
#region Tests
internal class ACLTester
{
public ACLTester()
{
ACL acl = new ACL();
Role Guests = new Role("Guests");
acl.AddRole(Guests);
Role[] parents = new Role[0];
parents[0] = Guests;
Role JoeGuest = new Role("JoeGuest", parents);
acl.AddRole(JoeGuest);
Resource CanBuild = new Resource("CanBuild");
acl.AddResource(CanBuild);
acl.GrantPermission("Guests", "CanBuild");
acl.HasPermission("JoeGuest", "CanBuild");
}
}
#endregion
}

View File

@ -0,0 +1,111 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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 libsecondlife;
namespace OpenSim.Framework
{
public class AgentCircuitData
{
public AgentCircuitData()
{
}
public AgentCircuitData(sAgentCircuitData cAgent)
{
AgentID = new LLUUID(cAgent.AgentID);
SessionID = new LLUUID(cAgent.SessionID);
SecureSessionID = new LLUUID(cAgent.SecureSessionID);
startpos = new LLVector3(cAgent.startposx, cAgent.startposy, cAgent.startposz);
firstname = cAgent.firstname;
lastname = cAgent.lastname;
circuitcode = cAgent.circuitcode;
child = cAgent.child;
InventoryFolder = new LLUUID(cAgent.InventoryFolder);
BaseFolder = new LLUUID(cAgent.BaseFolder);
CapsPath = cAgent.CapsPath;
ClientVersion = cAgent.ClientVersion; //rex
}
public LLUUID AgentID;
public LLUUID SessionID;
public LLUUID SecureSessionID;
public LLVector3 startpos;
public string firstname;
public string lastname;
public uint circuitcode;
public bool child;
public LLUUID InventoryFolder;
public LLUUID BaseFolder;
public string CapsPath = "";
public string ClientVersion = "not set"; //rex
public string authenticationAddr;
public string asAddress = "";
}
[Serializable]
public class sAgentCircuitData
{
public sAgentCircuitData()
{
}
public sAgentCircuitData(AgentCircuitData cAgent)
{
AgentID = cAgent.AgentID.UUID;
SessionID = cAgent.SessionID.UUID;
SecureSessionID = cAgent.SecureSessionID.UUID;
startposx = cAgent.startpos.X;
startposy = cAgent.startpos.Y;
startposz = cAgent.startpos.Z;
firstname = cAgent.firstname;
lastname = cAgent.lastname;
circuitcode = cAgent.circuitcode;
child = cAgent.child;
InventoryFolder = cAgent.InventoryFolder.UUID;
BaseFolder = cAgent.BaseFolder.UUID;
CapsPath = cAgent.CapsPath;
ClientVersion = cAgent.ClientVersion; //rex
}
public Guid AgentID;
public Guid SessionID;
public Guid SecureSessionID;
public float startposx;
public float startposy;
public float startposz;
public string firstname;
public string lastname;
public uint circuitcode;
public bool child;
public Guid InventoryFolder;
public Guid BaseFolder;
public string CapsPath = "";
public string ClientVersion = "not set"; //rex
}
}

View File

@ -0,0 +1,128 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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.Collections.Generic;
using libsecondlife;
namespace OpenSim.Framework
{
public class AgentCircuitManager
{
public Dictionary<uint, AgentCircuitData> AgentCircuits = new Dictionary<uint, AgentCircuitData>();
public AgentCircuitManager()
{
}
public virtual AuthenticateResponse AuthenticateSession(LLUUID sessionID, LLUUID agentID, uint circuitcode)
{
AgentCircuitData validcircuit = null;
if (AgentCircuits.ContainsKey(circuitcode))
{
validcircuit = AgentCircuits[circuitcode];
}
AuthenticateResponse user = new AuthenticateResponse();
if (validcircuit == null)
{
//don't have this circuit code in our list
user.Authorised = false;
return (user);
}
if ((sessionID == validcircuit.SessionID) && (agentID == validcircuit.AgentID))
{
user.Authorised = true;
user.LoginInfo = new Login();
user.LoginInfo.Agent = agentID;
user.LoginInfo.Session = sessionID;
user.LoginInfo.SecureSession = validcircuit.SecureSessionID;
user.LoginInfo.First = validcircuit.firstname;
user.LoginInfo.Last = validcircuit.lastname;
user.LoginInfo.InventoryFolder = validcircuit.InventoryFolder;
user.LoginInfo.BaseFolder = validcircuit.BaseFolder;
user.LoginInfo.ClientVersion = validcircuit.ClientVersion;//rex
}
else
{
// Invalid
user.Authorised = false;
}
return (user);
}
public virtual void AddNewCircuit(uint circuitCode, AgentCircuitData agentData)
{
if (AgentCircuits.ContainsKey(circuitCode))
{
AgentCircuits[circuitCode] = agentData;
}
else
{
AgentCircuits.Add(circuitCode, agentData);
}
}
public LLVector3 GetPosition(uint circuitCode)
{
LLVector3 vec = new LLVector3();
if (AgentCircuits.ContainsKey(circuitCode))
{
vec = AgentCircuits[circuitCode].startpos;
}
return vec;
}
public void UpdateAgentData(AgentCircuitData agentData)
{
if (AgentCircuits.ContainsKey((uint) agentData.circuitcode))
{
AgentCircuits[(uint) agentData.circuitcode].firstname = agentData.firstname;
AgentCircuits[(uint) agentData.circuitcode].lastname = agentData.lastname;
AgentCircuits[(uint) agentData.circuitcode].startpos = agentData.startpos;
// Console.WriteLine("update user start pos is " + agentData.startpos.X + " , " + agentData.startpos.Y + " , " + agentData.startpos.Z);
}
}
public void UpdateAgentChildStatus(uint circuitcode, bool childstatus)
{
if (AgentCircuits.ContainsKey(circuitcode))
{
AgentCircuits[circuitcode].child = childstatus;
}
}
public bool GetAgentChildStatus(uint circuitcode)
{
if (AgentCircuits.ContainsKey(circuitcode))
{
return AgentCircuits[circuitcode].child;
}
return false;
}
}
}

View File

@ -0,0 +1,258 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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.Collections.Generic;
using libsecondlife;
using libsecondlife.Packets;
namespace OpenSim.Framework
{
public class AgentInventory
{
//Holds the local copy of Inventory info for a agent
public Dictionary<LLUUID, InventoryFolder> InventoryFolders;
public Dictionary<LLUUID, InventoryItem> InventoryItems;
public InventoryFolder InventoryRoot;
public int LastCached; //maybe used by opensim app, time this was last stored/compared to user server
public LLUUID AgentID;
public AvatarWearable[] Wearables;
public AgentInventory()
{
InventoryFolders = new Dictionary<LLUUID, InventoryFolder>();
InventoryItems = new Dictionary<LLUUID, InventoryItem>();
Initialise();
}
public virtual void Initialise()
{
Wearables = new AvatarWearable[13];
for (int i = 0; i < 13; i++)
{
Wearables[i] = new AvatarWearable();
}
}
public bool CreateNewFolder(LLUUID folderID, ushort type)
{
InventoryFolder Folder = new InventoryFolder();
Folder.FolderID = folderID;
Folder.OwnerID = AgentID;
Folder.DefaultType = type;
InventoryFolders.Add(Folder.FolderID, Folder);
return (true);
}
public void CreateRootFolder(LLUUID newAgentID, bool createTextures)
{
AgentID = newAgentID;
InventoryRoot = new InventoryFolder();
InventoryRoot.FolderID = LLUUID.Random();
InventoryRoot.ParentID = LLUUID.Zero;
InventoryRoot.Version = 1;
InventoryRoot.DefaultType = 8;
InventoryRoot.OwnerID = AgentID;
InventoryRoot.FolderName = "My Inventory";
InventoryFolders.Add(InventoryRoot.FolderID, InventoryRoot);
InventoryRoot.OwnerID = AgentID;
if (createTextures)
{
CreateNewFolder(LLUUID.Random(), 0, "Textures", InventoryRoot.FolderID);
}
}
public bool CreateNewFolder(LLUUID folderID, ushort type, string folderName)
{
InventoryFolder Folder = new InventoryFolder();
Folder.FolderID = folderID;
Folder.OwnerID = AgentID;
Folder.DefaultType = type;
Folder.FolderName = folderName;
InventoryFolders.Add(Folder.FolderID, Folder);
return (true);
}
public bool CreateNewFolder(LLUUID folderID, ushort type, string folderName, LLUUID parentID)
{
if (!InventoryFolders.ContainsKey(folderID))
{
System.Console.WriteLine("creating new folder called " + folderName + " in agents inventory");
InventoryFolder Folder = new InventoryFolder();
Folder.FolderID = folderID;
Folder.OwnerID = AgentID;
Folder.DefaultType = type;
Folder.FolderName = folderName;
Folder.ParentID = parentID;
InventoryFolders.Add(Folder.FolderID, Folder);
}
return (true);
}
public bool HasFolder(LLUUID folderID)
{
if (InventoryFolders.ContainsKey(folderID))
{
return true;
}
return false;
}
public LLUUID GetFolderID(string folderName)
{
foreach (InventoryFolder inv in InventoryFolders.Values)
{
if (inv.FolderName == folderName)
{
return inv.FolderID;
}
}
return LLUUID.Zero;
}
public bool UpdateItemAsset(LLUUID itemID, AssetBase asset)
{
if (InventoryItems.ContainsKey(itemID))
{
InventoryItem Item = InventoryItems[itemID];
Item.AssetID = asset.FullID;
System.Console.WriteLine("updated inventory item " + itemID.ToString() +
" so it now is set to asset " + asset.FullID.ToString());
//TODO need to update the rest of the info
}
return true;
}
public bool UpdateItemDetails(LLUUID itemID, UpdateInventoryItemPacket.InventoryDataBlock packet)
{
System.Console.WriteLine("updating inventory item details");
if (InventoryItems.ContainsKey(itemID))
{
System.Console.WriteLine("changing name to " + Util.FieldToString(packet.Name));
InventoryItem Item = InventoryItems[itemID];
Item.Name = Util.FieldToString(packet.Name);
System.Console.WriteLine("updated inventory item " + itemID.ToString());
//TODO need to update the rest of the info
}
return true;
}
public LLUUID AddToInventory(LLUUID folderID, AssetBase asset)
{
if (InventoryFolders.ContainsKey(folderID))
{
LLUUID NewItemID = LLUUID.Random();
InventoryItem Item = new InventoryItem();
Item.FolderID = folderID;
Item.OwnerID = AgentID;
Item.AssetID = asset.FullID;
Item.ItemID = NewItemID;
Item.Type = asset.Type;
Item.Name = asset.Name;
Item.Description = asset.Description;
Item.InvType = asset.InvType;
InventoryItems.Add(Item.ItemID, Item);
InventoryFolder Folder = InventoryFolders[Item.FolderID];
Folder.Items.Add(Item);
return (Item.ItemID);
}
else
{
return (null);
}
}
public bool DeleteFromInventory(LLUUID itemID)
{
bool res = false;
if (InventoryItems.ContainsKey(itemID))
{
InventoryItem item = InventoryItems[itemID];
InventoryItems.Remove(itemID);
foreach (InventoryFolder fold in InventoryFolders.Values)
{
if (fold.Items.Contains(item))
{
fold.Items.Remove(item);
break;
}
}
res = true;
}
return res;
}
}
public class InventoryFolder
{
public List<InventoryItem> Items;
//public List<InventoryFolder> Subfolders;
public LLUUID FolderID;
public LLUUID OwnerID;
public LLUUID ParentID = LLUUID.Zero;
public string FolderName;
public ushort DefaultType;
public ushort Version;
public InventoryFolder()
{
Items = new List<InventoryItem>();
//Subfolders = new List<InventoryFolder>();
}
}
public class InventoryItem
{
public LLUUID FolderID;
public LLUUID OwnerID;
public LLUUID ItemID;
public LLUUID AssetID;
public LLUUID CreatorID;
public sbyte InvType;
public sbyte Type;
public string Name = "";
public string Description;
public InventoryItem()
{
CreatorID = LLUUID.Zero;
}
public string ExportString()
{
string typ = "notecard";
string result = "";
result += "\tinv_object\t0\n\t{\n";
result += "\t\tobj_id\t%s\n";
result += "\t\tparent_id\t" + ItemID.ToString() + "\n";
result += "\t\ttype\t" + typ + "\n";
result += "\t\tname\t" + Name + "|\n";
result += "\t}\n";
return result;
}
}
}

View File

@ -0,0 +1,36 @@
using System.Reflection;
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("OpenSim.FrameWork")]
[assembly : AssemblyDescription("")]
[assembly : AssemblyConfiguration("")]
[assembly : AssemblyCompany("")]
[assembly : AssemblyProduct("OpenSim.FrameWork")]
[assembly : AssemblyCopyright("Copyright © 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("a08e20c7-f191-4137-b1f0-9291408fa521")]
// 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")]

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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 libsecondlife;
namespace OpenSim.Framework
{
[Serializable]
public class AssetBase
{
public byte[] Data;
public LLUUID FullID;
public sbyte Type;
public sbyte InvType;
public string Name = "";
public string Description = "";
public string MediaURL = "";//rex
public bool Local = false;
public bool Temporary = false;
public AssetBase()
{
}
public AssetBase(LLUUID assetId, string name)
{
FullID = assetId;
Name = name;
}
}
}

View File

@ -0,0 +1,83 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS 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 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.
*
*/
namespace OpenSim.Framework
{
/// <summary>
/// UserConfig -- For User Server Configuration
/// </summary>
public class AssetConfig
{
public string DefaultStartupMsg = "";
public string DatabaseProvider = "";
public static uint DefaultHttpPort = 8003;
public uint HttpPort = DefaultHttpPort;
private ConfigurationMember configMember;
public AssetConfig(string description, string filename)
{
configMember =
new ConfigurationMember(filename, description, loadConfigurationOptions, handleIncomingConfiguration, true);
configMember.performConfigurationRetrieve();
}
public void loadConfigurationOptions()
{
configMember.addConfigurationOption("default_startup_message",
ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY,
"Default Startup Message", "Welcome to OGS", false);
configMember.addConfigurationOption("database_provider", ConfigurationOption.ConfigurationTypes.TYPE_STRING,
"DLL for database provider", "OpenSim.Framework.Data.MySQL.dll", false);
configMember.addConfigurationOption("http_port", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
"Http Listener port", DefaultHttpPort.ToString(), false);
}
public bool handleIncomingConfiguration(string configuration_key, object configuration_result)
{
switch (configuration_key)
{
case "default_startup_message":
DefaultStartupMsg = (string) configuration_result;
break;
case "database_provider":
DatabaseProvider = (string) configuration_result;
break;
case "http_port":
HttpPort = (uint) configuration_result;
break;
}
return true;
}
}
}

View File

@ -0,0 +1,60 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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.Text;
using libsecondlife;
namespace OpenSim.Framework
{
public class AssetLandmark : AssetBase
{
public int Version;
public LLVector3 Position;
public LLUUID RegionID;
public AssetLandmark(AssetBase a)
{
Data = a.Data;
FullID = a.FullID;
Type = a.Type;
InvType = a.InvType;
Name = a.Name;
Description = a.Description;
MediaURL = a.MediaURL; //rex
InternData();
}
private void InternData()
{
string temp = Encoding.UTF8.GetString(Data).Trim();
string[] parts = temp.Split('\n');
int.TryParse(parts[0].Substring(17, 1), out Version);
LLUUID.TryParse(parts[1].Substring(10, 36), out RegionID);
LLVector3.TryParse(parts[2].Substring(11, parts[2].Length - 11), out Position);
}
}
}

View File

@ -0,0 +1,164 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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.IO;
using System.Xml;
using libsecondlife;
using Nini.Config;
using OpenSim.Framework;
using OpenSim.Framework.Console;
/// <summary>
/// Loads assets from the filesystem location. Not yet a plugin, though it should be.
/// </summary>
namespace OpenSim.Framework.AssetLoader.Filesystem
{
public class AssetLoaderFileSystem : IAssetLoader
{
protected AssetBase CreateAsset(string assetIdStr, string name, string path, bool isImage)
{
AssetBase asset = new AssetBase(
new LLUUID(assetIdStr),
name
);
if (!String.IsNullOrEmpty(path))
{
MainLog.Instance.Verbose("ASSETS", "Loading: [{0}][{1}]", name, path);
LoadAsset(asset, isImage, path);
}
else
{
MainLog.Instance.Verbose("ASSETS", "Instantiated: [{0}]", name);
}
return asset;
}
protected void LoadAsset(AssetBase info, bool image, string path)
{
FileInfo fInfo = new FileInfo(path);
long numBytes = fInfo.Length;
FileStream fStream = new FileStream(path, FileMode.Open, FileAccess.Read);
byte[] idata = new byte[numBytes];
BinaryReader br = new BinaryReader(fStream);
idata = br.ReadBytes((int) numBytes);
br.Close();
fStream.Close();
info.Data = idata;
//info.loaded=true;
}
public void ForEachDefaultXmlAsset(Action<AssetBase> action)
{
string assetSetFilename = Path.Combine(Util.assetsDir(), "AssetSets.xml");
ForEachDefaultXmlAsset(assetSetFilename, action);
}
public void ForEachDefaultXmlAsset(string assetSetFilename, Action<AssetBase> action)
{
List<AssetBase> assets = new List<AssetBase>();
if (File.Exists(assetSetFilename))
{
string assetSetPath = "ERROR";
try
{
XmlConfigSource source = new XmlConfigSource(assetSetFilename);
for (int i = 0; i < source.Configs.Count; i++)
{
assetSetPath = source.Configs[i].GetString("file", "");
LoadXmlAssetSet(Path.Combine(Util.assetsDir(), assetSetPath), assets);
}
}
catch (XmlException e)
{
MainLog.Instance.Error("ASSETS", "Error loading {0} : {1}", assetSetPath, e);
}
}
else
{
MainLog.Instance.Error(
"ASSETS",
"Asset set control file assets/AssetSets.xml does not exist! No assets loaded.");
}
assets.ForEach(action);
}
/// <summary>
/// Use the asset set information at path to load assets
/// </summary>
/// <param name="path"></param>
/// <param name="assets"></param>
protected void LoadXmlAssetSet(string assetSetPath, List<AssetBase> assets)
{
MainLog.Instance.Verbose("ASSETS", "Loading asset set {0}", assetSetPath);
if (File.Exists(assetSetPath))
{
try
{
XmlConfigSource source = new XmlConfigSource(assetSetPath);
String dir = Path.GetDirectoryName(assetSetPath);
for (int i = 0; i < source.Configs.Count; i++)
{
string assetIdStr = source.Configs[i].GetString("assetID", LLUUID.Random().ToString());
string name = source.Configs[i].GetString("name", "");
sbyte type = (sbyte) source.Configs[i].GetInt("assetType", 0);
sbyte invType = (sbyte) source.Configs[i].GetInt("inventoryType", 0);
string assetPath = Path.Combine(dir, source.Configs[i].GetString("fileName", ""));
AssetBase newAsset = CreateAsset(assetIdStr, name, assetPath, false);
newAsset.Type = type;
newAsset.InvType = invType;
assets.Add(newAsset);
}
}
catch (XmlException e)
{
MainLog.Instance.Error("ASSETS", "Error loading {0} : {1}", assetSetPath, e);
}
}
else
{
MainLog.Instance.Error("ASSETS", "Asset set file {0} does not exist!", assetSetPath);
}
}
}
}

View File

@ -0,0 +1,10 @@
using libsecondlife;
namespace OpenSim.Framework
{
public struct AssetRequest
{
public LLUUID AssetID;
public bool IsTexture;
}
}

View File

@ -0,0 +1,48 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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 libsecondlife;
namespace OpenSim.Framework
{
public class AssetStorage
{
public AssetStorage()
{
}
public AssetStorage(LLUUID assetUUID)
{
UUID = assetUUID;
}
public byte[] Data;
public sbyte Type;
public string Name;
public LLUUID UUID;
}
}

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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.
*
*/
namespace OpenSim.Framework
{
public class AuthenticateResponse
{
public bool Authorised;
public Login LoginInfo;
public AuthenticateResponse()
{
}
}
}

View File

@ -0,0 +1,71 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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 libsecondlife;
namespace OpenSim.Framework
{
public class AvatarWearable
{
public LLUUID AssetID = new LLUUID("00000000-0000-0000-0000-000000000000");
public LLUUID ItemID = new LLUUID("00000000-0000-0000-0000-000000000000");
public AvatarWearable()
{
}
public AvatarWearable(LLUUID itemId, LLUUID assetId)
{
AssetID = assetId;
ItemID = itemId;
}
public static AvatarWearable[] DefaultWearables
{
get
{
AvatarWearable[] defaultWearables = new AvatarWearable[13]; //should be 13 of these
for (int i = 0; i < 13; i++)
{
defaultWearables[i] = new AvatarWearable();
}
defaultWearables[0].AssetID = new LLUUID("66c41e39-38f9-f75a-024e-585989bfab73");
defaultWearables[0].ItemID = new LLUUID("66c41e39-38f9-f75a-024e-585989bfaba9");
defaultWearables[1].ItemID = new LLUUID("77c41e39-38f9-f75a-024e-585989bfabc9");
defaultWearables[1].AssetID = new LLUUID("77c41e39-38f9-f75a-024e-585989bbabbb");
defaultWearables[4].ItemID = new LLUUID("77c41e39-38f9-f75a-0000-585989bf0000");
defaultWearables[4].AssetID = new LLUUID("00000000-38f9-1111-024e-222222111110");
defaultWearables[5].ItemID = new LLUUID("77c41e39-38f9-f75a-0000-5859892f1111");
defaultWearables[5].AssetID = new LLUUID("00000000-38f9-1111-024e-222222111120");
return defaultWearables;
}
}
}
}

View File

@ -0,0 +1,68 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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.Collections.Generic;
using System.Threading;
namespace OpenSim.Framework
{
public class BlockingQueue<T>
{
private readonly Queue<T> m_queue = new Queue<T>();
private readonly object m_queueSync = new object();
public void Enqueue(T value)
{
lock (m_queueSync)
{
m_queue.Enqueue(value);
Monitor.Pulse(m_queueSync);
}
}
public T Dequeue()
{
lock (m_queueSync)
{
if (m_queue.Count < 1)
{
Monitor.Wait(m_queueSync);
}
return m_queue.Dequeue();
}
}
public bool Contains(T item)
{
lock (m_queueSync)
{
return m_queue.Contains(item);
}
}
}
}

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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;
namespace OpenSim.Framework
{
[Serializable]
public class ChildAgentDataUpdate
{
public ChildAgentDataUpdate()
{
}
public sLLVector3 Position;
public ulong regionHandle;
public float drawdistance;
public sLLVector3 cameraPosition;
public sLLVector3 Velocity;
public float AVHeight;
public Guid AgentID;
public float godlevel;
public byte[] throttles;
}
}

View File

@ -0,0 +1,181 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS 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 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.Collections.Generic;
using libsecondlife;
using libsecondlife.Packets;
namespace OpenSim.Framework
{
public delegate void ForEachClientDelegate(IClientAPI client);
public class ClientManager
{
private Dictionary<uint, IClientAPI> m_clients;
public void ForEachClient(ForEachClientDelegate whatToDo)
{
// Wasteful, I know
IClientAPI[] LocalClients = new IClientAPI[0];
lock (m_clients)
{
LocalClients = new IClientAPI[m_clients.Count];
m_clients.Values.CopyTo(LocalClients, 0);
}
for (int i = 0; i < LocalClients.Length; i++)
{
try
{
whatToDo(LocalClients[i]);
}
catch (System.Exception e)
{
OpenSim.Framework.Console.MainLog.Instance.Warn("CLIENT", "Unable to do ForEachClient for one of the clients" + "\n Reason: " + e.ToString());
}
}
}
public ClientManager()
{
m_clients = new Dictionary<uint, IClientAPI>();
}
private void Remove(uint id)
{
m_clients.Remove(id);
}
public void Add(uint id, IClientAPI client)
{
m_clients.Add(id, client);
}
public void InPacket(uint circuitCode, Packet packet)
{
IClientAPI client;
if (m_clients.TryGetValue(circuitCode, out client))
{
client.InPacket(packet);
}
}
public void CloseAllAgents(uint circuitCode)
{
IClientAPI client;
if (m_clients.TryGetValue(circuitCode, out client))
{
CloseAllCircuits(client.AgentId);
}
}
public void CloseAllCircuits(LLUUID agentId)
{
uint[] circuits = GetAllCircuits(agentId);
// We're using a for loop here so changes to the circuits don't cause it to completely fail.
for (int i = 0; i < circuits.Length; i++)
{
IClientAPI client;
try
{
if (m_clients.TryGetValue(circuits[i], out client))
{
Remove(client.CircuitCode);
client.Close(false);
}
}
catch (System.Exception e)
{
OpenSim.Framework.Console.MainLog.Instance.Error("CLIENT", string.Format("Unable to shutdown circuit for: {0}\n Reason: {1}", agentId, e));
}
}
}
private uint[] GetAllCircuits(LLUUID agentId)
{
List<uint> circuits = new List<uint>();
// Wasteful, I know
IClientAPI[] LocalClients = new IClientAPI[0];
lock (m_clients)
{
LocalClients = new IClientAPI[m_clients.Count];
m_clients.Values.CopyTo(LocalClients, 0);
}
for (int i = 0; i < LocalClients.Length; i++ )
{
if (LocalClients[i].AgentId == agentId)
{
circuits.Add(LocalClients[i].CircuitCode);
}
}
return circuits.ToArray();
}
public void ViewerEffectHandler(IClientAPI sender, ViewerEffectPacket.EffectBlock[] effectBlock)
{
ViewerEffectPacket packet = (ViewerEffectPacket) PacketPool.Instance.GetPacket(PacketType.ViewerEffect);
// TODO: don't create new blocks if recycling an old packet
packet.Effect = effectBlock;
// Wasteful, I know
IClientAPI[] LocalClients = new IClientAPI[0];
lock (m_clients)
{
LocalClients = new IClientAPI[m_clients.Count];
m_clients.Values.CopyTo(LocalClients, 0);
}
for (int i = 0; i < LocalClients.Length; i++)
{
if (LocalClients[i].AgentId != sender.AgentId)
{
packet.AgentData.AgentID = LocalClients[i].AgentId;
packet.AgentData.SessionID = LocalClients[i].SessionId;
LocalClients[i].OutPacket(packet, ThrottleOutPacketType.Task);
}
}
}
public bool TryGetClient(uint circuitId, out IClientAPI user)
{
return m_clients.TryGetValue(circuitId, out user);
}
}
}

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS 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 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 OpenSim.Framework.Servers;
namespace OpenSim.Framework.Communications
{
public class CAPSService
{
private BaseHttpServer m_server;
public CAPSService(BaseHttpServer httpServer)
{
m_server = httpServer;
AddCapsSeedHandler("/CapsSeed/", CapsRequest);
}
private void AddCapsSeedHandler(string path, RestMethod restMethod)
{
m_server.AddStreamHandler(new RestStreamHandler("POST", path, restMethod));
}
public string CapsRequest(string request, string path, string param)
{
System.Console.WriteLine("new caps request " + request + " from path " + path);
return "";
}
}
}

View File

@ -0,0 +1,725 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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 libsecondlife;
using libsecondlife.Packets;
using OpenSim.Framework.Console;
namespace OpenSim.Framework.Communications.Cache
{
public delegate void AssetRequestCallback(LLUUID assetID, AssetBase asset);
/// <summary>
/// Manages local cache of assets and their sending to viewers.
/// </summary>
public class AssetCache : IAssetReceiver
{
public Dictionary<LLUUID, AssetInfo> Assets;
public Dictionary<LLUUID, TextureImage> Textures;
public List<AssetRequest> AssetRequests = new List<AssetRequest>(); //assets ready to be sent to viewers
public List<AssetRequest> TextureRequests = new List<AssetRequest>(); //textures ready to be sent
public Dictionary<LLUUID, AssetRequest> RequestedAssets = new Dictionary<LLUUID, AssetRequest>();
//Assets requested from the asset server
public Dictionary<LLUUID, AssetRequest> RequestedTextures = new Dictionary<LLUUID, AssetRequest>();
//Textures requested from the asset server
public Dictionary<LLUUID, AssetRequestsList> RequestLists = new Dictionary<LLUUID, AssetRequestsList>();
private readonly IAssetServer m_assetServer;
private readonly Thread m_assetCacheThread;
private readonly LogBase m_log;
/// <summary>
///
/// </summary>
public AssetCache(IAssetServer assetServer, LogBase log)
{
log.Verbose("ASSETSTORAGE", "Creating Asset cache");
m_assetServer = assetServer;
m_assetServer.SetReceiver(this);
Assets = new Dictionary<LLUUID, AssetInfo>();
Textures = new Dictionary<LLUUID, TextureImage>();
m_assetCacheThread = new Thread(new ThreadStart(RunAssetManager));
m_assetCacheThread.IsBackground = true;
m_assetCacheThread.Start();
m_log = log;
}
/// <summary>
///
/// </summary>
public void RunAssetManager()
{
while (true)
{
try
{
ProcessAssetQueue();
Thread.Sleep(500);
}
catch (Exception e)
{
m_log.Error("ASSETCACHE", e.ToString());
}
}
}
/// <summary>
/// Only get an asset if we already have it in the cache.
/// </summary>
/// <param name="assetID"></param></param>
/// <returns></returns>
private AssetBase GetCachedAsset(LLUUID assetID)
{
AssetBase asset = null;
if (Textures.ContainsKey(assetID))
{
asset = Textures[assetID];
}
else if (Assets.ContainsKey(assetID))
{
asset = Assets[assetID];
}
return asset;
}
public void GetAsset(LLUUID assetID, AssetRequestCallback callback)
{
AssetBase asset = null;
if (Textures.ContainsKey(assetID))
{
asset = Textures[assetID];
}
else if (Assets.ContainsKey(assetID))
{
asset = Assets[assetID];
}
if (asset != null)
{
callback(assetID, asset);
}
else
{
NewAssetRequest req = new NewAssetRequest(assetID, callback);
if (RequestLists.ContainsKey(assetID))
{
lock (RequestLists)
{
RequestLists[assetID].Requests.Add(req);
}
}
else
{
AssetRequestsList reqList = new AssetRequestsList(assetID);
reqList.Requests.Add(req);
lock (RequestLists)
{
RequestLists.Add(assetID, reqList);
}
}
m_assetServer.RequestAsset(assetID, false);
}
}
/// <summary>
/// Get an asset. If the asset isn't in the cache, a request will be made to the persistent store to
/// load it into the cache.
///
/// XXX We'll keep polling the cache until we get the asset or we exceed
/// the allowed number of polls. This isn't a very good way of doing things since a single thread
/// is processing inbound packets, so if the asset server is slow, we could block this for up to
/// the timeout period. What we might want to do is register asynchronous callbacks on asset
/// receipt in the same manner as the nascent (but not yet active) TextureDownloadModule. Of course,
/// a timeout before asset receipt usually isn't fatal, the operation will work on the retry when the
/// asset is much more likely to have made it into the cache.
/// </summary>
/// <param name="assetID"></param>
/// <param name="isTexture"></param>
/// <returns>null if the asset could not be retrieved</returns>
public AssetBase GetAsset(LLUUID assetID, bool isTexture)
{
// I'm not going over 3 seconds since this will be blocking processing of all the other inbound
// packets from the client.
int pollPeriod = 200;
int maxPolls = 15;
AssetBase asset = GetCachedAsset(assetID);
if (asset != null)
{
return asset;
}
m_assetServer.RequestAsset(assetID, isTexture);
do
{
Thread.Sleep(pollPeriod);
asset = GetCachedAsset(assetID);
if (asset != null)
{
return asset;
}
} while (--maxPolls > 0);
MainLog.Instance.Warn(
"ASSETCACHE", "Asset {0} was not received before the retrieval timeout was reached");
return null;
}
// rex, new function
public List<AssetBase> GetAssetList(int vAssetType)
{
return m_assetServer.GetAssetList(vAssetType);
}
// rex, new function
public AssetBase FetchAsset(LLUUID assetID)
{
return m_assetServer.FetchAsset(assetID);
}
/// <summary>
/// Add an asset to both the persistent store and the cache.
/// </summary>
/// <param name="asset"></param>
public void AddAsset(AssetBase asset)
{
string temporary = asset.Temporary ? "temporary" : "";
string type = asset.Type == 0 ? "texture" : "asset";
string result = "Ignored";
if (asset.Type == 0)
{
if (Textures.ContainsKey(asset.FullID))
{
result = "Duplicate ignored.";
}
else
{
TextureImage textur = new TextureImage(asset);
Textures.Add(textur.FullID, textur);
if (asset.Temporary)
{
result = "Added to cache";
}
else
{
m_assetServer.StoreAndCommitAsset(asset);
result = "Added to server";
}
}
}
else
{
if (Assets.ContainsKey(asset.FullID))
{
result = "Duplicate ignored.";
}
else
{
AssetInfo assetInf = new AssetInfo(asset);
Assets.Add(assetInf.FullID, assetInf);
if (asset.Temporary)
{
result = "Added to cache";
}
else
{
m_assetServer.StoreAndCommitAsset(asset);
result = "Added to server";
}
}
}
m_log.Verbose("ASSETCACHE", "Adding {0} {1} [{2}]: {3}.", temporary, type, asset.FullID, result);
}
// rex, new function for "replace asset" functionality
public void ReplaceAsset(AssetBase asset)
{
string temporary = asset.Temporary ? "temporary" : "";
string type = asset.Type == 0 ? "texture" : "asset";
string result = "Ignored";
if (asset.Type == 0)
{
if (Textures.ContainsKey(asset.FullID))
{
Textures.Remove(asset.FullID);
}
TextureImage textur = new TextureImage(asset);
Textures.Add(textur.FullID, textur);
if (asset.Temporary)
{
result = "Replaced old asset in cache";
}
else
{
m_assetServer.UpdateAsset(asset);
result = "Replaced old asset on server";
}
}
else
{
if (Assets.ContainsKey(asset.FullID))
{
Assets.Remove(asset.FullID);
}
AssetInfo assetInf = new AssetInfo(asset);
Assets.Add(assetInf.FullID, assetInf);
if (asset.Temporary)
{
result = "Replaced old asset in cache";
}
else
{
m_assetServer.UpdateAsset(asset);
result = "Replaced old asset on server";
}
}
m_log.Verbose("ASSETCACHE", "Adding {0} {1} [{2}]: {3}.", temporary, type, asset.FullID, result);
}
// rex new function
public bool ExistsAsset(LLUUID assetID)
{
if (Textures.ContainsKey(assetID))
return true;
if (Assets.ContainsKey(assetID))
return true;
return m_assetServer.ExistsAsset(assetID);
}
// rex new function for "replace asset" functionality
public LLUUID ExistsAsset(sbyte type, string name)
{
// First check locally cached assets
// Texture or other asset?
if (type == 0)
{
foreach (KeyValuePair<LLUUID, TextureImage> kvp in Textures)
{
TextureImage t = kvp.Value;
if (t != null)
{
if ((t.Name == name) && (t.Type == type))
{
return t.FullID;
}
}
}
}
else
{
foreach (KeyValuePair<LLUUID, AssetInfo> kvp in Assets)
{
AssetInfo a = kvp.Value;
if (a != null)
{
if ((a.Name == name) && (a.Type == type))
{
return a.FullID;
}
}
}
}
// Then have to check asset server
return m_assetServer.ExistsAsset(type, name);
}
public void DeleteAsset(LLUUID assetID)
{
// this.m_assetServer.DeleteAsset(assetID);
//Todo should delete it from memory too
}
public AssetBase CopyAsset(LLUUID assetID)
{
AssetBase asset = GetCachedAsset(assetID);
if (asset == null)
return null;
asset.FullID = LLUUID.Random(); // TODO: check for conflicts
AddAsset(asset);
return asset;
}
public void AssetReceived(AssetBase asset, bool IsTexture)
{
if (asset.FullID != LLUUID.Zero) // if it is set to zero then the asset wasn't found by the server
{
//check if it is a texture or not
//then add to the correct cache list
//then check for waiting requests for this asset/texture (in the Requested lists)
//and move those requests into the Requests list.
if (IsTexture)
{
//Console.WriteLine("asset received from asset server");
TextureImage image = new TextureImage(asset);
if (!Textures.ContainsKey(image.FullID))
{
Textures.Add(image.FullID, image);
if (RequestedTextures.ContainsKey(image.FullID))
{
AssetRequest req = RequestedTextures[image.FullID];
req.ImageInfo = image;
req.NumPackets = CalculateNumPackets(image.Data);
RequestedTextures.Remove(image.FullID);
TextureRequests.Add(req);
}
}
}
else
{
AssetInfo assetInf = new AssetInfo(asset);
if (!Assets.ContainsKey(assetInf.FullID))
{
Assets.Add(assetInf.FullID, assetInf);
if (RequestedAssets.ContainsKey(assetInf.FullID))
{
AssetRequest req = RequestedAssets[assetInf.FullID];
req.AssetInf = assetInf;
req.NumPackets = CalculateNumPackets(assetInf.Data);
RequestedAssets.Remove(assetInf.FullID);
AssetRequests.Add(req);
}
}
}
if (RequestLists.ContainsKey(asset.FullID))
{
AssetRequestsList reqList = RequestLists[asset.FullID];
foreach (NewAssetRequest req in reqList.Requests)
{
req.Callback(asset.FullID, asset);
}
lock (RequestLists)
{
RequestLists.Remove(asset.FullID);
reqList.Requests.Clear();
}
}
}
}
public void AssetNotFound(LLUUID assetID)
{
//if (this.RequestedTextures.ContainsKey(assetID))
//{
// MainLog.Instance.Warn("ASSET CACHE", "sending image not found for {0}", assetID);
// AssetRequest req = this.RequestedTextures[assetID];
// ImageNotInDatabasePacket notFound = new ImageNotInDatabasePacket();
// notFound.ImageID.ID = assetID;
// req.RequestUser.OutPacket(notFound);
// this.RequestedTextures.Remove(assetID);
//}
//else
//{
// MainLog.Instance.Error("ASSET CACHE", "Cound not send image not found for {0}", assetID);
//}
}
private int CalculateNumPackets(byte[] data)
{
const uint m_maxPacketSize = 600;
int numPackets = 1;
if (data.LongLength > m_maxPacketSize)
{
// over max number of bytes so split up file
long restData = data.LongLength - m_maxPacketSize;
int restPackets = (int) ((restData + m_maxPacketSize - 1)/m_maxPacketSize);
numPackets += restPackets;
}
return numPackets;
}
#region Assets
/// <summary>
///
/// </summary>
/// <param name="userInfo"></param>
/// <param name="transferRequest"></param>
public void AddAssetRequest(IClientAPI userInfo, TransferRequestPacket transferRequest)
{
LLUUID requestID = null;
byte source = 2;
if (transferRequest.TransferInfo.SourceType == 2)
{
//direct asset request
requestID = new LLUUID(transferRequest.TransferInfo.Params, 0);
}
else if (transferRequest.TransferInfo.SourceType == 3)
{
//inventory asset request
requestID = new LLUUID(transferRequest.TransferInfo.Params, 80);
source = 3;
//Console.WriteLine("asset request " + requestID);
}
//check to see if asset is in local cache, if not we need to request it from asset server.
//Console.WriteLine("asset request " + requestID);
if (!Assets.ContainsKey(requestID))
{
//not found asset
// so request from asset server
if (!RequestedAssets.ContainsKey(requestID))
{
AssetRequest request = new AssetRequest();
request.RequestUser = userInfo;
request.RequestAssetID = requestID;
request.TransferRequestID = transferRequest.TransferInfo.TransferID;
request.AssetRequestSource = source;
request.Params = transferRequest.TransferInfo.Params;
RequestedAssets.Add(requestID, request);
m_assetServer.RequestAsset(requestID, false);
}
return;
}
//it is in our cache
AssetInfo asset = Assets[requestID];
// add to the AssetRequests list
AssetRequest req = new AssetRequest();
req.RequestUser = userInfo;
req.RequestAssetID = requestID;
req.TransferRequestID = transferRequest.TransferInfo.TransferID;
req.AssetRequestSource = source;
req.Params = transferRequest.TransferInfo.Params;
req.AssetInf = asset;
req.NumPackets = CalculateNumPackets(asset.Data);
AssetRequests.Add(req);
}
/// <summary>
///
/// </summary>
private void ProcessAssetQueue()
{
//should move the asset downloading to a module, like has been done with texture downloading
if (AssetRequests.Count == 0)
{
//no requests waiting
return;
}
// if less than 5, do all of them
int num = Math.Min(5, AssetRequests.Count);
AssetRequest req;
for (int i = 0; i < num; i++)
{
req = (AssetRequest) AssetRequests[i];
//Console.WriteLine("sending asset " + req.RequestAssetID);
TransferInfoPacket Transfer = new TransferInfoPacket();
Transfer.TransferInfo.ChannelType = 2;
Transfer.TransferInfo.Status = 0;
Transfer.TransferInfo.TargetType = 0;
if (req.AssetRequestSource == 2)
{
Transfer.TransferInfo.Params = new byte[20];
Array.Copy(req.RequestAssetID.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16);
int assType = (int) req.AssetInf.Type;
Array.Copy(Helpers.IntToBytes(assType), 0, Transfer.TransferInfo.Params, 16, 4);
}
else if (req.AssetRequestSource == 3)
{
Transfer.TransferInfo.Params = req.Params;
// Transfer.TransferInfo.Params = new byte[100];
//Array.Copy(req.RequestUser.AgentId.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16);
//Array.Copy(req.RequestUser.SessionId.GetBytes(), 0, Transfer.TransferInfo.Params, 16, 16);
}
Transfer.TransferInfo.Size = (int) req.AssetInf.Data.Length;
Transfer.TransferInfo.TransferID = req.TransferRequestID;
req.RequestUser.OutPacket(Transfer, ThrottleOutPacketType.Asset);
if (req.NumPackets == 1)
{
TransferPacketPacket TransferPacket = new TransferPacketPacket();
TransferPacket.TransferData.Packet = 0;
TransferPacket.TransferData.ChannelType = 2;
TransferPacket.TransferData.TransferID = req.TransferRequestID;
TransferPacket.TransferData.Data = req.AssetInf.Data;
TransferPacket.TransferData.Status = 1;
req.RequestUser.OutPacket(TransferPacket, ThrottleOutPacketType.Asset);
}
else
{
int processedLength = 0;
// libsecondlife hardcodes 1500 as the maximum data chunk size
int maxChunkSize = 1500;
int packetNumber = 0;
while (processedLength < req.AssetInf.Data.Length)
{
TransferPacketPacket TransferPacket = new TransferPacketPacket();
TransferPacket.TransferData.Packet = packetNumber;
TransferPacket.TransferData.ChannelType = 2;
TransferPacket.TransferData.TransferID = req.TransferRequestID;
int chunkSize = Math.Min(req.AssetInf.Data.Length - processedLength, maxChunkSize);
byte[] chunk = new byte[chunkSize];
Array.Copy(req.AssetInf.Data, processedLength, chunk, 0, chunk.Length);
TransferPacket.TransferData.Data = chunk;
// 0 indicates more packets to come, 1 indicates last packet
if (req.AssetInf.Data.Length - processedLength > maxChunkSize)
{
TransferPacket.TransferData.Status = 0;
}
else
{
TransferPacket.TransferData.Status = 1;
}
req.RequestUser.OutPacket(TransferPacket, ThrottleOutPacketType.Asset);
processedLength += chunkSize;
packetNumber++;
}
}
}
//remove requests that have been completed
for (int i = 0; i < num; i++)
{
AssetRequests.RemoveAt(0);
}
}
#endregion
public class AssetRequest
{
public IClientAPI RequestUser;
public LLUUID RequestAssetID;
public AssetInfo AssetInf;
public TextureImage ImageInfo;
public LLUUID TransferRequestID;
public long DataPointer = 0;
public int NumPackets = 0;
public int PacketCounter = 0;
public bool IsTextureRequest;
public byte AssetRequestSource = 2;
public byte[] Params = null;
//public bool AssetInCache;
//public int TimeRequested;
public int DiscardLevel = -1;
public AssetRequest()
{
}
}
public class AssetInfo : AssetBase
{
public AssetInfo()
{
}
public AssetInfo(AssetBase aBase)
{
Data = aBase.Data;
FullID = aBase.FullID;
Type = aBase.Type;
InvType = aBase.InvType;
Name = aBase.Name;
Description = aBase.Description;
MediaURL = aBase.MediaURL; //rex
}
}
public class TextureImage : AssetBase
{
public TextureImage()
{
}
public TextureImage(AssetBase aBase)
{
Data = aBase.Data;
FullID = aBase.FullID;
Type = aBase.Type;
InvType = aBase.InvType;
Name = aBase.Name;
Description = aBase.Description;
MediaURL = aBase.MediaURL; //rex
}
}
public class AssetRequestsList
{
public LLUUID AssetID;
public List<NewAssetRequest> Requests = new List<NewAssetRequest>();
public AssetRequestsList(LLUUID assetID)
{
AssetID = assetID;
}
}
public class NewAssetRequest
{
public LLUUID AssetID;
public AssetRequestCallback Callback;
public NewAssetRequest(LLUUID assetID, AssetRequestCallback callback)
{
AssetID = assetID;
Callback = callback;
}
}
}
}

View File

@ -0,0 +1,234 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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.IO;
using Db4objects.Db4o;
using Db4objects.Db4o.Query;
using libsecondlife;
using OpenSim.Framework.Console;
namespace OpenSim.Framework.Communications.Cache
{
public class LocalAssetServer : AssetServerBase
{
private IObjectContainer db;
public LocalAssetServer()
{
bool yapfile;
yapfile = File.Exists(Path.Combine(Util.dataDir(), "regionassets.yap"));
db = Db4oFactory.OpenFile(Path.Combine(Util.dataDir(), "regionassets.yap"));
MainLog.Instance.Verbose("ASSETS", "Db4 Asset database creation");
if (!yapfile)
{
SetUpAssetDatabase();
}
}
public void CreateAndCommitAsset(AssetBase asset)
{
AssetStorage store = new AssetStorage();
store.Data = asset.Data;
store.Name = asset.Name;
store.UUID = asset.FullID;
db.Set(store);
db.Commit();
}
public override void Close()
{
base.Close();
if (db != null)
{
MainLog.Instance.Verbose("ASSETSERVER", "Closing local asset server database");
db.Close();
}
}
// rex new function for "replace assets" functionality
public override LLUUID ExistsAsset(sbyte assetType, string name)
{
IObjectSet result = db.Query(new AssetTypeNameQuery(assetType, name));
AssetStorage foundAsset = null;
if (result.Count > 0)
{
foundAsset = (AssetStorage)result.Next();
return foundAsset.UUID;
}
return LLUUID.Zero;
}
// rex new function
public override bool ExistsAsset(LLUUID assetID)
{
IObjectSet result = db.Query(new AssetUUIDQuery(assetID));
if (result.Count > 0)
return true;
else
return false;
}
// rex new function
public override AssetBase FetchAsset(LLUUID assetID)
{
byte[] idata = null;
bool found = false;
AssetStorage foundAsset = null;
IObjectSet result = db.Query(new AssetUUIDQuery(assetID));
if (result.Count > 0)
{
foundAsset = (AssetStorage)result.Next();
found = true;
}
AssetBase asset = new AssetBase();
if (found)
{
asset.FullID = foundAsset.UUID;
asset.Type = foundAsset.Type;
asset.InvType = foundAsset.Type;
asset.Name = foundAsset.Name;
idata = foundAsset.Data;
asset.Data = idata;
return asset;
}
else
{
return null;
}
}
protected override AssetBase GetAsset(AssetRequest req)
{
byte[] idata = null;
bool found = false;
AssetStorage foundAsset = null;
IObjectSet result = db.Query(new AssetUUIDQuery(req.AssetID));
if (result.Count > 0)
{
foundAsset = (AssetStorage) result.Next();
found = true;
}
AssetBase asset = new AssetBase();
if (found)
{
asset.FullID = foundAsset.UUID;
asset.Type = foundAsset.Type;
asset.InvType = foundAsset.Type;
asset.Name = foundAsset.Name;
idata = foundAsset.Data;
asset.Data = idata;
return asset;
}
else
{
return null;
}
}
protected override void StoreAsset(AssetBase asset)
{
AssetStorage store = new AssetStorage();
store.Data = asset.Data;
store.Name = asset.Name;
store.UUID = asset.FullID;
db.Set(store);
CommitAssets();
}
// rex overrided function for "replace assets" functionality to work with local assetserver
public override void UpdateAsset(AssetBase asset)
{
lock (m_syncLock)
{
IObjectSet result = db.Query(new AssetUUIDQuery(asset.FullID));
AssetStorage foundAsset = null;
int i;
for (i = 0; i < result.Count; i++)
{
foundAsset = (AssetStorage)result.Next();
db.Delete(foundAsset);
}
StoreAsset(asset);
}
}
protected override void CommitAssets()
{
db.Commit();
}
protected virtual void SetUpAssetDatabase()
{
MainLog.Instance.Verbose("LOCAL ASSET SERVER", "Setting up asset database");
base.LoadDefaultAssets();
}
}
public class AssetUUIDQuery : Predicate
{
private LLUUID _findID;
public AssetUUIDQuery(LLUUID find)
{
_findID = find;
}
public bool Match(AssetStorage asset)
{
return (asset.UUID == _findID);
}
}
// rex new class for "replace assets" functionality
public class AssetTypeNameQuery : Predicate
{
private sbyte _findType;
private string _findName;
public AssetTypeNameQuery(sbyte type, string name)
{
_findType = type;
_findName = name;
}
public bool Match(AssetStorage asset)
{
return ((asset.Type == _findType) && (asset.Name == _findName));
}
}
}

View File

@ -0,0 +1,193 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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 libsecondlife;
using OpenSim.Framework.Console;
using OpenSim.Framework.AssetLoader.Filesystem;
namespace OpenSim.Framework.Communications.Cache
{
public abstract class AssetServerBase : IAssetServer
{
protected IAssetReceiver m_receiver;
protected BlockingQueue<AssetRequest> m_assetRequests;
protected Thread m_localAssetServerThread;
protected IAssetProvider m_assetProvider;
protected object m_syncLock = new object();
// Temporarily hardcoded - should be a plugin
protected IAssetLoader assetLoader = new AssetLoaderFileSystem();
protected abstract void StoreAsset(AssetBase asset);
protected abstract void CommitAssets();
public abstract LLUUID ExistsAsset(sbyte assetType, string name); // rex new function for "replace assets" functionality
/// <summary>
/// This method must be implemented by a subclass to retrieve the asset named in the
/// AssetRequest. If the asset is not found, null should be returned.
/// </summary>
/// <param name="req"></param>
/// <returns></returns>
protected abstract AssetBase GetAsset(AssetRequest req);
/// <summary>
/// Process an asset request. This method will call GetAsset(AssetRequest req)
/// on the subclass.
/// </summary>
/// <param name="req"></param>
protected virtual void ProcessRequest(AssetRequest req)
{
AssetBase asset = GetAsset(req);
if (asset != null)
{
MainLog.Instance.Verbose(
"ASSET", "Asset {0} received from asset server", req.AssetID);
m_receiver.AssetReceived(asset, req.IsTexture);
}
else
{
MainLog.Instance.Error(
"ASSET", "Asset {0} not found by asset server", req.AssetID);
m_receiver.AssetNotFound(req.AssetID);
}
}
public virtual void LoadDefaultAssets()
{
MainLog.Instance.Verbose("ASSETSERVER", "Setting up asset database");
assetLoader.ForEachDefaultXmlAsset(StoreAsset);
CommitAssets();
}
public AssetServerBase()
{
MainLog.Instance.Verbose("ASSETSERVER", "Starting asset storage system");
m_assetRequests = new BlockingQueue<AssetRequest>();
m_localAssetServerThread = new Thread(RunRequests);
m_localAssetServerThread.IsBackground = true;
m_localAssetServerThread.Start();
}
private void RunRequests()
{
while (true) // Since it's a 'blocking queue'
{
try
{
AssetRequest req = m_assetRequests.Dequeue();
ProcessRequest(req);
}
catch (Exception e)
{
MainLog.Instance.Error("ASSETSERVER", e.Message);
}
}
}
public void SetReceiver(IAssetReceiver receiver)
{
m_receiver = receiver;
}
public void RequestAsset(LLUUID assetID, bool isTexture)
{
AssetRequest req = new AssetRequest();
req.AssetID = assetID;
req.IsTexture = isTexture;
m_assetRequests.Enqueue(req);
MainLog.Instance.Verbose("ASSET", "Added {0} to request queue", assetID);
}
public virtual void UpdateAsset(AssetBase asset)
{
lock (m_syncLock)
{
m_assetProvider.UpdateAsset(asset);
m_assetProvider.CommitAssets();
}
}
public void StoreAndCommitAsset(AssetBase asset)
{
lock (m_syncLock)
{
StoreAsset(asset);
CommitAssets();
}
}
// rex, new function
public List<AssetBase> GetAssetList(int vAssetType)
{
lock (m_syncLock)
{
return m_assetProvider.GetAssetList(vAssetType);
}
}
// rex, new function
public virtual AssetBase FetchAsset(LLUUID assetID)
{
lock (m_syncLock)
{
return m_assetProvider.FetchAsset(assetID);
}
}
// rex, new function
public virtual bool ExistsAsset(LLUUID assetID)
{
lock (m_syncLock)
{
return m_assetProvider.ExistsAsset(assetID);
}
}
public virtual void Close()
{
m_localAssetServerThread.Abort();
}
public void SetServerInfo(string ServerUrl, string ServerKey)
{
}
}
}

View File

@ -0,0 +1,109 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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.Collections.Generic;
using libsecondlife;
namespace OpenSim.Framework.Communications.Cache
{
public class AssetTransactionManager
{
// Fields
public CommunicationsManager CommsManager;
public Dictionary<LLUUID, AgentAssetTransactions> AgentTransactions =
new Dictionary<LLUUID, AgentAssetTransactions>();
private bool m_dumpAssetsToFile;
public AssetTransactionManager(CommunicationsManager commsManager, bool dumpAssetsToFile)
{
CommsManager = commsManager;
m_dumpAssetsToFile = dumpAssetsToFile;
}
// Methods
public AgentAssetTransactions AddUser(LLUUID userID)
{
lock (AgentTransactions)
{
if (!AgentTransactions.ContainsKey(userID))
{
AgentAssetTransactions transactions = new AgentAssetTransactions(userID, this, m_dumpAssetsToFile);
AgentTransactions.Add(userID, transactions);
return transactions;
}
}
return null;
}
public AgentAssetTransactions GetUserTransActions(LLUUID userID)
{
if (AgentTransactions.ContainsKey(userID))
{
return AgentTransactions[userID];
}
return null;
}
public void HandleInventoryFromTransaction(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID,
uint callbackID, string description, string name, sbyte invType,
sbyte type, byte wearableType, uint nextOwnerMask)
{
AgentAssetTransactions transactions = GetUserTransActions(remoteClient.AgentId);
if (transactions != null)
{
transactions.RequestCreateInventoryItem(remoteClient, transactionID, folderID, callbackID, description,
name, invType, type, wearableType, nextOwnerMask);
}
}
public void HandleUDPUploadRequest(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type,
byte[] data, bool storeLocal, bool tempFile)
{
// Console.WriteLine("asset upload of " + assetID);
AgentAssetTransactions transactions = GetUserTransActions(remoteClient.AgentId);
if (transactions != null)
{
AgentAssetTransactions.AssetXferUploader uploader = transactions.RequestXferUploader(transaction);
if (uploader != null)
{
uploader.Initialise(remoteClient, assetID, transaction, type, data, storeLocal, tempFile);
}
}
}
public void HandleXfer(IClientAPI remoteClient, ulong xferID, uint packetID, byte[] data)
{
AgentAssetTransactions transactions = GetUserTransActions(remoteClient.AgentId);
if (transactions != null)
{
transactions.HandleXfer(xferID, packetID, data);
}
}
}
}

View File

@ -0,0 +1,444 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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.IO;
using libsecondlife;
using libsecondlife.Packets;
using OpenSim.Framework.Servers;
using OpenSim.Region.Capabilities;
namespace OpenSim.Framework.Communications.Cache
{
public class AgentAssetTransactions
{
// Fields
public List<AssetCapsUploader> CapsUploaders = new List<AssetCapsUploader>();
public List<NoteCardCapsUpdate> NotecardUpdaters = new List<NoteCardCapsUpdate>();
public LLUUID UserID;
public Dictionary<LLUUID, AssetXferUploader> XferUploaders = new Dictionary<LLUUID, AssetXferUploader>();
public AssetTransactionManager Manager;
private bool m_dumpAssetsToFile;
// Methods
public AgentAssetTransactions(LLUUID agentID, AssetTransactionManager manager, bool dumpAssetsToFile)
{
UserID = agentID;
Manager = manager;
m_dumpAssetsToFile = dumpAssetsToFile;
}
public AssetCapsUploader RequestCapsUploader()
{
AssetCapsUploader uploader = new AssetCapsUploader();
CapsUploaders.Add(uploader);
return uploader;
}
public NoteCardCapsUpdate RequestNoteCardUpdater()
{
NoteCardCapsUpdate update = new NoteCardCapsUpdate();
NotecardUpdaters.Add(update);
return update;
}
public AssetXferUploader RequestXferUploader(LLUUID transactionID)
{
if (!XferUploaders.ContainsKey(transactionID))
{
AssetXferUploader uploader = new AssetXferUploader(this, m_dumpAssetsToFile);
XferUploaders.Add(transactionID, uploader);
return uploader;
}
return null;
}
public void HandleXfer(ulong xferID, uint packetID, byte[] data)
{
foreach (AssetXferUploader uploader in XferUploaders.Values)
{
if (uploader.XferID == xferID)
{
uploader.HandleXferPacket(xferID, packetID, data);
break;
}
}
}
public void RequestCreateInventoryItem(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID,
uint callbackID, string description, string name, sbyte invType,
sbyte type, byte wearableType, uint nextOwnerMask)
{
if (XferUploaders.ContainsKey(transactionID))
{
XferUploaders[transactionID].RequestCreateInventoryItem(remoteClient, transactionID, folderID,
callbackID, description, name, invType, type,
wearableType, nextOwnerMask);
}
}
public AssetBase GetTransactionAsset(LLUUID transactionID)
{
if (XferUploaders.ContainsKey(transactionID))
{
return XferUploaders[transactionID].GetAssetData();
}
return null;
}
// Nested Types
public class AssetXferUploader
{
// Fields
public bool AddToInventory;
public AssetBase Asset;
public LLUUID InventFolder = LLUUID.Zero;
private IClientAPI ourClient;
public LLUUID TransactionID = LLUUID.Zero;
public bool UploadComplete;
public ulong XferID;
private string m_name = "";
private string m_description = "";
private sbyte type = 0;
private sbyte invType = 0;
private uint nextPerm = 0;
private bool m_finished = false;
private bool m_createItem = false;
private AgentAssetTransactions m_userTransactions;
private bool m_storeLocal;
private bool m_dumpAssetToFile;
public AssetXferUploader(AgentAssetTransactions transactions, bool dumpAssetToFile)
{
m_userTransactions = transactions;
m_dumpAssetToFile = dumpAssetToFile;
}
// Methods
public void HandleXferPacket(ulong xferID, uint packetID, byte[] data)
{
if (XferID == xferID)
{
if (Asset.Data.Length > 1)
{
byte[] destinationArray = new byte[Asset.Data.Length + data.Length];
Array.Copy(Asset.Data, 0, destinationArray, 0, Asset.Data.Length);
Array.Copy(data, 0, destinationArray, Asset.Data.Length, data.Length);
Asset.Data = destinationArray;
}
else
{
byte[] buffer2 = new byte[data.Length - 4];
Array.Copy(data, 4, buffer2, 0, data.Length - 4);
Asset.Data = buffer2;
}
ConfirmXferPacketPacket newPack = new ConfirmXferPacketPacket();
newPack.XferID.ID = xferID;
newPack.XferID.Packet = packetID;
ourClient.OutPacket(newPack, ThrottleOutPacketType.Asset);
if ((packetID & 0x80000000) != 0)
{
SendCompleteMessage();
}
}
}
public void Initialise(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, byte[] data,
bool storeLocal, bool tempFile)
{
ourClient = remoteClient;
Asset = new AssetBase();
Asset.FullID = assetID;
Asset.InvType = type;
Asset.Type = type;
Asset.Data = data;
Asset.Name = "blank";
Asset.Description = "empty";
Asset.Local = storeLocal;
Asset.Temporary = tempFile;
TransactionID = transaction;
m_storeLocal = storeLocal;
if (Asset.Data.Length > 2)
{
SendCompleteMessage();
}
else
{
ReqestStartXfer();
}
}
protected void ReqestStartXfer()
{
UploadComplete = false;
XferID = Util.GetNextXferID();
RequestXferPacket newPack = new RequestXferPacket();
newPack.XferID.ID = XferID;
newPack.XferID.VFileType = Asset.Type;
newPack.XferID.VFileID = Asset.FullID;
newPack.XferID.FilePath = 0;
newPack.XferID.Filename = new byte[0];
ourClient.OutPacket(newPack, ThrottleOutPacketType.Asset);
}
protected void SendCompleteMessage()
{
UploadComplete = true;
AssetUploadCompletePacket newPack = new AssetUploadCompletePacket();
newPack.AssetBlock.Type = Asset.Type;
newPack.AssetBlock.Success = true;
newPack.AssetBlock.UUID = Asset.FullID;
ourClient.OutPacket(newPack, ThrottleOutPacketType.Asset);
m_finished = true;
if (m_createItem)
{
DoCreateItem();
}
else if (m_storeLocal)
{
m_userTransactions.Manager.CommsManager.AssetCache.AddAsset(Asset);
}
// Console.WriteLine("upload complete "+ this.TransactionID);
if (m_dumpAssetToFile)
{
DateTime now = DateTime.Now;
string filename =
String.Format("{6}_{7}_{0:d2}{1:d2}{2:d2}_{3:d2}{4:d2}{5:d2}.dat", now.Year, now.Month, now.Day,
now.Hour, now.Minute, now.Second, Asset.Name, Asset.Type);
SaveAssetToFile(filename, Asset.Data);
}
}
///Left this in and commented in case there are unforseen issues
//private void SaveAssetToFile(string filename, byte[] data)
//{
// FileStream fs = File.Create(filename);
// BinaryWriter bw = new BinaryWriter(fs);
// bw.Write(data);
// bw.Close();
// fs.Close();
//}
private void SaveAssetToFile(string filename, byte[] data)
{
string assetPath = "UserAssets";
if (!Directory.Exists(assetPath))
{
Directory.CreateDirectory(assetPath);
}
FileStream fs = File.Create(Path.Combine(assetPath, filename));
BinaryWriter bw = new BinaryWriter(fs);
bw.Write(data);
bw.Close();
fs.Close();
}
public void RequestCreateInventoryItem(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID,
uint callbackID, string description, string name, sbyte invType,
sbyte type, byte wearableType, uint nextOwnerMask)
{
if (TransactionID == transactionID)
{
InventFolder = folderID;
m_name = name;
m_description = description;
this.type = type;
this.invType = invType;
nextPerm = nextOwnerMask;
Asset.Name = name;
Asset.Description = description;
Asset.Type = type;
Asset.InvType = invType;
m_createItem = true;
if (m_finished)
{
DoCreateItem();
}
}
}
private void DoCreateItem()
{
//really need to fix this call, if lbsa71 saw this he would die.
m_userTransactions.Manager.CommsManager.AssetCache.AddAsset(Asset);
CachedUserInfo userInfo =
m_userTransactions.Manager.CommsManager.UserProfileCacheService.GetUserDetails(ourClient.AgentId);
if (userInfo != null)
{
InventoryItemBase item = new InventoryItemBase();
item.avatarID = ourClient.AgentId;
item.creatorsID = ourClient.AgentId;
item.inventoryID = LLUUID.Random();
item.assetID = Asset.FullID;
item.inventoryDescription = m_description;
item.inventoryName = m_name;
item.assetType = type;
item.invType = invType;
item.parentFolderID = InventFolder;
item.inventoryCurrentPermissions = 2147483647;
item.inventoryNextPermissions = nextPerm;
userInfo.AddItem(ourClient.AgentId, item);
ourClient.SendInventoryItemCreateUpdate(item);
}
}
public void UpdateInventoryItem(LLUUID itemID)
{
}
public AssetBase GetAssetData()
{
if (m_finished)
{
return Asset;
}
return null;
}
}
#region Nested Classes currently not in use (waiting for them to be enabled)
public class AssetCapsUploader
{
// Fields
private BaseHttpServer httpListener;
private LLUUID inventoryItemID;
private string m_assetDescription = "";
private string m_assetName = "";
private LLUUID m_folderID;
private LLUUID newAssetID;
private bool m_dumpImageToFile;
private string uploaderPath = "";
// Events
public event UpLoadedAsset OnUpLoad;
// Methods
public void Initialise(string assetName, string assetDescription, LLUUID assetID, LLUUID inventoryItem,
LLUUID folderID, string path, BaseHttpServer httpServer, bool dumpImageToFile)
{
m_assetName = assetName;
m_assetDescription = assetDescription;
m_folderID = folderID;
newAssetID = assetID;
inventoryItemID = inventoryItem;
uploaderPath = path;
httpListener = httpServer;
m_dumpImageToFile = dumpImageToFile;
}
private void SaveImageToFile(string filename, byte[] data)
{
FileStream output = File.Create(filename);
BinaryWriter writer = new BinaryWriter(output);
writer.Write(data);
writer.Close();
output.Close();
}
public string uploaderCaps(byte[] data, string path, string param)
{
LLUUID inventoryItemID = this.inventoryItemID;
string text = "";
LLSDAssetUploadComplete complete = new LLSDAssetUploadComplete();
complete.new_asset = newAssetID.ToString();
complete.new_inventory_item = inventoryItemID;
complete.state = "complete";
text = LLSDHelpers.SerialiseLLSDReply(complete);
httpListener.RemoveStreamHandler("POST", uploaderPath);
if (m_dumpImageToFile)
{
SaveImageToFile(m_assetName + ".jp2", data);
}
if (OnUpLoad != null)
{
OnUpLoad(m_assetName, "description", newAssetID, inventoryItemID, LLUUID.Zero, data, "", "");
}
return text;
}
}
public class NoteCardCapsUpdate
{
// Fields
private BaseHttpServer httpListener;
private LLUUID inventoryItemID;
private string m_assetName = "";
private LLUUID newAssetID;
private bool SaveImages = false;
private string uploaderPath = "";
// Events
public event UpLoadedAsset OnUpLoad;
// Methods
public void Initialise(LLUUID inventoryItem, string path, BaseHttpServer httpServer)
{
inventoryItemID = inventoryItem;
uploaderPath = path;
httpListener = httpServer;
newAssetID = LLUUID.Random();
}
private void SaveImageToFile(string filename, byte[] data)
{
FileStream output = File.Create(filename);
BinaryWriter writer = new BinaryWriter(output);
writer.Write(data);
writer.Close();
output.Close();
}
public string uploaderCaps(byte[] data, string path, string param)
{
LLUUID inventoryItemID = this.inventoryItemID;
string text = "";
LLSDAssetUploadComplete complete = new LLSDAssetUploadComplete();
complete.new_asset = newAssetID.ToString();
complete.new_inventory_item = inventoryItemID;
complete.state = "complete";
text = LLSDHelpers.SerialiseLLSDReply(complete);
httpListener.RemoveStreamHandler("POST", uploaderPath);
if (SaveImages)
{
SaveImageToFile(m_assetName + "notecard.txt", data);
}
if (OnUpLoad != null)
{
OnUpLoad(m_assetName, "description", newAssetID, inventoryItemID, LLUUID.Zero, data, "", "");
}
return text;
}
}
#endregion
}
}

View File

@ -0,0 +1,133 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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 libsecondlife;
namespace OpenSim.Framework.Communications.Cache
{
public class CachedUserInfo
{
private readonly CommunicationsManager m_parentCommsManager;
// Fields
public InventoryFolderImpl RootFolder = null;
public UserProfileData UserProfile = null;
public CachedUserInfo(CommunicationsManager commsManager)
{
m_parentCommsManager = commsManager;
}
// Methods
public void FolderReceive(LLUUID userID, InventoryFolderImpl folderInfo)
{
if (userID == UserProfile.UUID)
{
if (RootFolder == null)
{
if (folderInfo.parentID == LLUUID.Zero)
{
RootFolder = folderInfo;
}
}
else if (RootFolder.folderID == folderInfo.parentID)
{
if (!RootFolder.SubFolders.ContainsKey(folderInfo.folderID))
{
RootFolder.SubFolders.Add(folderInfo.folderID, folderInfo);
}
}
else
{
InventoryFolderImpl folder = RootFolder.HasSubFolder(folderInfo.parentID);
if (folder != null)
{
if (!folder.SubFolders.ContainsKey(folderInfo.folderID))
{
folder.SubFolders.Add(folderInfo.folderID, folderInfo);
}
}
}
}
}
public void ItemReceive(LLUUID userID, InventoryItemBase itemInfo)
{
if ((userID == UserProfile.UUID) && (RootFolder != null))
{
if (itemInfo.parentFolderID == RootFolder.folderID)
{
if (!RootFolder.Items.ContainsKey(itemInfo.inventoryID))
{
RootFolder.Items.Add(itemInfo.inventoryID, itemInfo);
}
}
else
{
InventoryFolderImpl folder = RootFolder.HasSubFolder(itemInfo.parentFolderID);
if (folder != null)
{
if (!folder.Items.ContainsKey(itemInfo.inventoryID))
{
folder.Items.Add(itemInfo.inventoryID, itemInfo);
}
}
}
}
}
public void AddItem(LLUUID userID, InventoryItemBase itemInfo)
{
if ((userID == UserProfile.UUID) && (RootFolder != null))
{
ItemReceive(userID, itemInfo);
m_parentCommsManager.InventoryService.AddNewInventoryItem(userID, itemInfo);
}
}
public void UpdateItem(LLUUID userID, InventoryItemBase itemInfo)
{
if ((userID == UserProfile.UUID) && (RootFolder != null))
{
m_parentCommsManager.InventoryService.AddNewInventoryItem(userID, itemInfo);
}
}
public bool DeleteItem(LLUUID userID, InventoryItemBase item)
{
bool result = false;
if ((userID == UserProfile.UUID) && (RootFolder != null))
{
result = RootFolder.DeleteItem(item.inventoryID);
if (result)
{
m_parentCommsManager.InventoryService.DeleteInventoryItem(userID, item);
}
}
return result;
}
}
}

View File

@ -0,0 +1,128 @@
/*
* Copyright (c) Contributors, http://www.openmetaverse.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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.IO;
using System.Xml.Serialization;
using OpenSim.Framework.Console;
using OpenSim.Framework.Servers;
namespace OpenSim.Framework.Communications.Cache
{
public class GridAssetClient : AssetServerBase
{
private string _assetServerUrl;
public GridAssetClient(string serverUrl)
{
_assetServerUrl = serverUrl;
}
#region IAssetServer Members
protected override AssetBase GetAsset(AssetRequest req)
{
Stream s = null;
try
{
MainLog.Instance.Debug("ASSETCACHE", "Querying for {0}", req.AssetID.ToString());
RestClient rc = new RestClient(_assetServerUrl);
rc.AddResourcePath("assets");
rc.AddResourcePath(req.AssetID.ToString());
if (req.IsTexture)
rc.AddQueryParameter("texture");
rc.RequestMethod = "GET";
s = rc.Request();
if (s.Length > 0)
{
XmlSerializer xs = new XmlSerializer(typeof (AssetBase));
return (AssetBase) xs.Deserialize(s);
}
}
catch (Exception e)
{
MainLog.Instance.Error("ASSETCACHE", e.Message);
MainLog.Instance.Debug("ASSETCACHE", "Getting asset {0}", req.AssetID.ToString());
MainLog.Instance.Error("ASSETCACHE", e.StackTrace);
}
return null;
}
public override void UpdateAsset(AssetBase asset)
{
throw new Exception("The method or operation is not implemented.");
}
protected override void StoreAsset(AssetBase asset)
{
try
{
// MemoryStream s = new MemoryStream();
// XmlSerializer xs = new XmlSerializer(typeof(AssetBase));
// xs.Serialize(s, asset);
// RestClient rc = new RestClient(_assetServerUrl);
MainLog.Instance.Verbose("ASSET", "Storing asset");
//rc.AddResourcePath("assets");
// rc.RequestMethod = "POST";
// rc.Request(s);
//MainLog.Instance.Verbose("ASSET", "Stored {0}", rc);
MainLog.Instance.Verbose("ASSET", "Sending to " + _assetServerUrl + "/assets/");
RestObjectPoster.BeginPostObject<AssetBase>(_assetServerUrl + "/assets/", asset);
}
catch (Exception e)
{
MainLog.Instance.Error("ASSETS", e.Message);
}
}
protected override void CommitAssets()
{
}
public override void Close()
{
throw new Exception("The method or operation is not implemented.");
}
// rex new function for "replace assets" functionality
// TODO: implementation by someone
public override libsecondlife.LLUUID ExistsAsset(sbyte assetType, string name)
{
throw new Exception("The method or operation is not implemented.");
}
#endregion
}
}

View File

@ -0,0 +1,184 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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.Collections.Generic;
using libsecondlife;
namespace OpenSim.Framework.Communications.Cache
{
public class InventoryFolderImpl : InventoryFolderBase
{
// Fields
public Dictionary<LLUUID, InventoryItemBase> Items = new Dictionary<LLUUID, InventoryItemBase>();
public Dictionary<LLUUID, InventoryFolderImpl> SubFolders = new Dictionary<LLUUID, InventoryFolderImpl>();
// Accessors
public int SubFoldersCount
{
get { return SubFolders.Count; }
}
// Constructors
public InventoryFolderImpl(InventoryFolderBase folderbase)
{
agentID = folderbase.agentID;
folderID = folderbase.folderID;
name = folderbase.name;
parentID = folderbase.parentID;
type = folderbase.type;
version = folderbase.version;
}
public InventoryFolderImpl()
{
}
// Methods
public InventoryFolderImpl CreateNewSubFolder(LLUUID folderID, string folderName, ushort type)
{
if (!SubFolders.ContainsKey(folderID))
{
InventoryFolderImpl subFold = new InventoryFolderImpl();
subFold.name = folderName;
subFold.folderID = folderID;
subFold.type = (short) type;
subFold.parentID = this.folderID;
subFold.agentID = agentID;
SubFolders.Add(subFold.folderID, subFold);
return subFold;
}
return null;
}
public InventoryItemBase HasItem(LLUUID itemID)
{
InventoryItemBase base2 = null;
if (Items.ContainsKey(itemID))
{
return Items[itemID];
}
foreach (InventoryFolderImpl folder in SubFolders.Values)
{
base2 = folder.HasItem(itemID);
if (base2 != null)
{
break;
}
}
return base2;
}
public bool DeleteItem(LLUUID itemID)
{
bool found = false;
if (Items.ContainsKey(itemID))
{
Items.Remove(itemID);
return true;
}
foreach (InventoryFolderImpl folder in SubFolders.Values)
{
found = folder.DeleteItem(itemID);
if (found == true)
{
break;
}
}
return found;
}
public InventoryFolderImpl HasSubFolder(LLUUID folderID)
{
InventoryFolderImpl returnFolder = null;
if (SubFolders.ContainsKey(folderID))
{
returnFolder = SubFolders[folderID];
}
else
{
foreach (InventoryFolderImpl folder in SubFolders.Values)
{
returnFolder = folder.HasSubFolder(folderID);
if (returnFolder != null)
{
break;
}
}
}
return returnFolder;
}
public List<InventoryItemBase> RequestListOfItems()
{
List<InventoryItemBase> itemList = new List<InventoryItemBase>();
foreach (InventoryItemBase item in Items.Values)
{
itemList.Add(item);
}
return itemList;
}
public List<InventoryFolderBase> RequestListOfFolders()
{
List<InventoryFolderBase> folderList = new List<InventoryFolderBase>();
foreach (InventoryFolderBase folder in SubFolders.Values)
{
folderList.Add(folder);
}
return folderList;
}
// rex, new function
public void ClearFolder()
{
Items.Clear();
SubFolders.Clear();
}
// rex, new function
public bool HasAssetID(LLUUID assetID)
{
foreach (InventoryItemBase item in Items.Values)
{
if (item.assetID == assetID)
return true;
}
foreach (InventoryFolderImpl folder in SubFolders.Values)
{
if (folder.name != "World Library")
{
if (folder.HasAssetID(assetID))
return true;
}
}
return false;
}
}
}

View File

@ -0,0 +1,281 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS 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 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.Collections.Generic;
using System.IO;
using System.Xml;
using libsecondlife;
using Nini.Config;
using OpenSim.Framework.Console;
namespace OpenSim.Framework.Communications.Cache
{
/// <summary>
/// Basically a hack to give us a Inventory library while we don't have a inventory server
/// once the server is fully implemented then should read the data from that
/// </summary>
public class LibraryRootFolder : InventoryFolderImpl
{
private LLUUID libOwner = new LLUUID("11111111-1111-0000-0000-000100bba000");
/// <summary>
/// Holds the root library folder and all its descendents. This is really only used during inventory
/// setup so that we don't have to repeatedly search the tree of library folders.
/// </summary>
protected Dictionary<LLUUID, InventoryFolderImpl> libraryFolders
= new Dictionary<LLUUID, InventoryFolderImpl>();
public LibraryRootFolder()
{
MainLog.Instance.Verbose("LIBRARYINVENTORY", "Loading library inventory");
agentID = libOwner;
folderID = new LLUUID("00000112-000f-0000-0000-000100bba000");
name = "OpenSim Library";
parentID = LLUUID.Zero;
type = (short) 8;
version = (ushort) 1;
libraryFolders.Add(folderID, this);
LoadLibraries(Path.Combine(Util.inventoryDir(), "Libraries.xml"));
// CreateLibraryItems();
}
/// <summary>
/// Hardcoded item creation. Please don't add any more items here - future items should be created
/// in the xml in the bin/inventory folder.
/// </summary>
///
/// Commented the following out due to sending it all through xml, remove this section once this is provin to work stable.
///
//private void CreateLibraryItems()
//{
// InventoryItemBase item =
// CreateItem(new LLUUID("66c41e39-38f9-f75a-024e-585989bfaba9"),
// new LLUUID("66c41e39-38f9-f75a-024e-585989bfab73"), "Default Shape", "Default Shape",
// (int) AssetType.Bodypart, (int) InventoryType.Wearable, folderID);
// item.inventoryCurrentPermissions = 0;
// item.inventoryNextPermissions = 0;
// Items.Add(item.inventoryID, item);
// item =
// CreateItem(new LLUUID("77c41e39-38f9-f75a-024e-585989bfabc9"),
// new LLUUID("77c41e39-38f9-f75a-024e-585989bbabbb"), "Default Skin", "Default Skin",
// (int) AssetType.Bodypart, (int) InventoryType.Wearable, folderID);
// item.inventoryCurrentPermissions = 0;
// item.inventoryNextPermissions = 0;
// Items.Add(item.inventoryID, item);
// item =
// CreateItem(new LLUUID("77c41e39-38f9-f75a-0000-585989bf0000"),
// new LLUUID("00000000-38f9-1111-024e-222222111110"), "Default Shirt", "Default Shirt",
// (int) AssetType.Clothing, (int) InventoryType.Wearable, folderID);
// item.inventoryCurrentPermissions = 0;
// item.inventoryNextPermissions = 0;
// Items.Add(item.inventoryID, item);
// item =
// CreateItem(new LLUUID("77c41e39-38f9-f75a-0000-5859892f1111"),
// new LLUUID("00000000-38f9-1111-024e-222222111120"), "Default Pants", "Default Pants",
// (int) AssetType.Clothing, (int) InventoryType.Wearable, folderID);
// item.inventoryCurrentPermissions = 0;
// item.inventoryNextPermissions = 0;
// Items.Add(item.inventoryID, item);
//}
public InventoryItemBase CreateItem(LLUUID inventoryID, LLUUID assetID, string name, string description,
int assetType, int invType, LLUUID parentFolderID)
{
InventoryItemBase item = new InventoryItemBase();
item.avatarID = libOwner;
item.creatorsID = libOwner;
item.inventoryID = inventoryID;
item.assetID = assetID;
item.inventoryDescription = description;
item.inventoryName = name;
item.assetType = assetType;
item.invType = invType;
item.parentFolderID = parentFolderID;
item.inventoryBasePermissions = 0x7FFFFFFF;
item.inventoryEveryOnePermissions = 0x7FFFFFFF;
item.inventoryCurrentPermissions = 0x7FFFFFFF;
item.inventoryNextPermissions = 0x7FFFFFFF;
return item;
}
/// <summary>
/// Use the asset set information at path to load assets
/// </summary>
/// <param name="path"></param>
/// <param name="assets"></param>
protected void LoadLibraries(string librariesControlPath)
{
MainLog.Instance.Verbose(
"LIBRARYINVENTORY", "Loading libraries control file {0}", librariesControlPath);
LoadFromFile(librariesControlPath, "Libraries control", ReadLibraryFromConfig);
}
/// <summary>
/// Read a library set from config
/// </summary>
/// <param name="config"></param>
protected void ReadLibraryFromConfig(IConfig config)
{
string foldersPath
= Path.Combine(
Util.inventoryDir(), config.GetString("foldersFile", ""));
LoadFromFile(foldersPath, "Library folders", ReadFolderFromConfig);
string itemsPath
= Path.Combine(
Util.inventoryDir(), config.GetString("itemsFile", ""));
LoadFromFile(itemsPath, "Library items", ReadItemFromConfig);
}
/// <summary>
/// Read a library inventory folder from a loaded configuration
/// </summary>
/// <param name="source"></param>
private void ReadFolderFromConfig(IConfig config)
{
InventoryFolderImpl folderInfo = new InventoryFolderImpl();
folderInfo.folderID = new LLUUID(config.GetString("folderID", folderID.ToString()));
folderInfo.name = config.GetString("name", "unknown");
folderInfo.parentID = new LLUUID(config.GetString("parentFolderID", folderID.ToString()));
folderInfo.type = (short)config.GetInt("type", 8);
folderInfo.agentID = libOwner;
folderInfo.version = 1;
if (libraryFolders.ContainsKey(folderInfo.parentID))
{
InventoryFolderImpl parentFolder = libraryFolders[folderInfo.parentID];
libraryFolders.Add(folderInfo.folderID, folderInfo);
parentFolder.SubFolders.Add(folderInfo.folderID, folderInfo);
// MainLog.Instance.Verbose(
// "LIBRARYINVENTORY", "Adding folder {0} ({1})", folderInfo.name, folderInfo.folderID);
}
else
{
MainLog.Instance.Warn(
"LIBRARYINVENTORY",
"Couldn't add folder {0} ({1}) since parent folder with ID {2} does not exist!",
folderInfo.name, folderInfo.folderID, folderInfo.parentID);
}
}
/// <summary>
/// Read a library inventory item metadata from a loaded configuration
/// </summary>
/// <param name="source"></param>
private void ReadItemFromConfig(IConfig config)
{
InventoryItemBase item = new InventoryItemBase();
item.avatarID = libOwner;
item.creatorsID = libOwner;
item.inventoryID = new LLUUID(config.GetString("inventoryID", folderID.ToString()));
item.assetID = new LLUUID(config.GetString("assetID", LLUUID.Random().ToString()));
item.parentFolderID = new LLUUID(config.GetString("folderID", folderID.ToString()));
item.inventoryDescription = config.GetString("description", "");
item.inventoryName = config.GetString("name", "");
item.assetType = config.GetInt("assetType", 0);
item.invType = config.GetInt("inventoryType", 0);
item.inventoryCurrentPermissions = (uint)config.GetLong("currentPermissions", 0x7FFFFFFF);
item.inventoryNextPermissions = (uint)config.GetLong("nextPermissions", 0x7FFFFFFF);
item.inventoryEveryOnePermissions = (uint)config.GetLong("everyonePermissions", 0x7FFFFFFF);
item.inventoryBasePermissions = (uint)config.GetLong("basePermissions", 0x7FFFFFFF);
if (libraryFolders.ContainsKey(item.parentFolderID))
{
InventoryFolderImpl parentFolder = libraryFolders[item.parentFolderID];
parentFolder.Items.Add(item.inventoryID, item);
}
else
{
MainLog.Instance.Warn(
"LIBRARYINVENTORY",
"Couldn't add item {0} ({1}) since parent folder with ID {2} does not exist!",
item.inventoryName, item.inventoryID, item.parentFolderID);
}
}
private delegate void ConfigAction(IConfig config);
/// <summary>
/// Load the given configuration at a path and perform an action on each Config contained within it
/// </summary>
/// <param name="path"></param>
/// <param name="fileDescription"></param>
/// <param name="action"></param>
private void LoadFromFile(string path, string fileDescription, ConfigAction action)
{
if (File.Exists(path))
{
try
{
XmlConfigSource source = new XmlConfigSource(path);
for (int i = 0; i < source.Configs.Count; i++)
{
action(source.Configs[i]);
}
}
catch (XmlException e)
{
MainLog.Instance.Error(
"LIBRARYINVENTORY", "Error loading {0} : {1}", path, e);
}
}
else
{
MainLog.Instance.Error(
"LIBRARYINVENTORY", "{0} file {1} does not exist!", fileDescription, path);
}
}
/// <summary>
/// Looks like a simple getter, but is written like this for some consistency with the other Request
/// methods in the superclass
/// </summary>
/// <returns></returns>
public Dictionary<LLUUID, InventoryFolderImpl> RequestSelfAndDescendentFolders()
{
return libraryFolders;
}
}
}

View File

@ -0,0 +1,86 @@
// Rex, new file
using System.Collections.Generic;
using System.IO;
using System.Xml;
using libsecondlife;
using Nini.Config;
using OpenSim.Framework.Console;
namespace OpenSim.Framework.Communications.Cache
{
// Rex, new class implementing the world assets folder
public class RexWorldAssetsFolder : InventoryFolderImpl
{
private LLUUID libOwner = new LLUUID("11111111-1111-0000-0000-000100bba001");
private InventoryFolderImpl m_WorldTexturesFolder;
private InventoryFolderImpl m_World3DModelsFolder;
private AssetCache AssetCache;
public RexWorldAssetsFolder(AssetCache vAssetCache)
{
MainLog.Instance.Verbose("LIBRARYINVENTORY", "Creating World library folder");
AssetCache = vAssetCache;
agentID = libOwner;
folderID = new LLUUID("00000112-000f-0000-0000-000100bba005");
name = "World Library";
parentID = new LLUUID("00000112-000f-0000-0000-000100bba000");
type = (short)8;
version = (ushort)1;
CreateNewSubFolder(new LLUUID("00000112-000f-0000-0000-000100bba006"), "Textures", (ushort)8);
m_WorldTexturesFolder = HasSubFolder("00000112-000f-0000-0000-000100bba006");
CreateNewSubFolder(new LLUUID("00000112-000f-0000-0000-000100bba007"), "3D Models", (ushort)8);
m_World3DModelsFolder = HasSubFolder("00000112-000f-0000-0000-000100bba007");
}
public InventoryItemBase CreateItem(LLUUID inventoryID, LLUUID assetID, string name, string description,
int assetType, int invType, LLUUID parentFolderID)
{
InventoryItemBase item = new InventoryItemBase();
item.avatarID = libOwner;
item.creatorsID = libOwner;
item.inventoryID = inventoryID;
item.assetID = assetID;
item.inventoryDescription = description;
item.inventoryName = name;
item.assetType = assetType;
item.invType = invType;
item.parentFolderID = parentFolderID;
item.inventoryBasePermissions = 0x7FFFFFFF;
item.inventoryEveryOnePermissions = 0x7FFFFFFF;
item.inventoryCurrentPermissions = 0x7FFFFFFF;
item.inventoryNextPermissions = 0x7FFFFFFF;
return item;
}
// Rex, function added.
public void UpdateWorldAssetFolders()
{
// Textures
List<AssetBase> allTex = AssetCache.GetAssetList(0);
m_WorldTexturesFolder.ClearFolder();
InventoryItemBase item;
foreach (AssetBase asset in allTex)
{
item = CreateItem(LLUUID.Random(), asset.FullID, asset.Name, asset.Description, (int)AssetType.Texture, (int)InventoryType.Texture, m_WorldTexturesFolder.folderID);
m_WorldTexturesFolder.Items.Add(item.inventoryID, item);
}
// 3D Models
List<AssetBase> allModels = AssetCache.GetAssetList(6);
m_World3DModelsFolder.ClearFolder();
foreach (AssetBase asset in allModels)
{
if (asset.Name != "Primitive")
{
item = CreateItem(LLUUID.Random(), asset.FullID, asset.Name, asset.Description, 43, 6, m_World3DModelsFolder.folderID);
m_World3DModelsFolder.Items.Add(item.inventoryID, item);
}
}
}
}
}

View File

@ -0,0 +1,107 @@
/*
* Copyright (c) Contributors, http://www.openmetaverse.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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.Reflection;
using OpenSim.Framework.Console;
namespace OpenSim.Framework.Communications.Cache
{
public class SQLAssetServer : AssetServerBase
{
public SQLAssetServer(string pluginName)
{
AddPlugin(pluginName);
}
public SQLAssetServer(IAssetProvider assetProvider)
{
m_assetProvider = assetProvider;
}
public void AddPlugin(string FileName)
{
MainLog.Instance.Verbose("SQLAssetServer", "AssetStorage: Attempting to load " + FileName);
Assembly pluginAssembly = Assembly.LoadFrom(FileName);
foreach (Type pluginType in pluginAssembly.GetTypes())
{
if (!pluginType.IsAbstract)
{
Type typeInterface = pluginType.GetInterface("IAssetProvider", true);
if (typeInterface != null)
{
IAssetProvider plug =
(IAssetProvider) Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));
m_assetProvider = plug;
m_assetProvider.Initialise();
MainLog.Instance.Verbose("AssetStorage",
"Added " + m_assetProvider.Name + " " +
m_assetProvider.Version);
}
}
}
}
public override void Close()
{
base.Close();
m_assetProvider.CommitAssets();
}
// rex new function for "replace assets" functionality
public override libsecondlife.LLUUID ExistsAsset(sbyte assetType, string name)
{
return m_assetProvider.ExistsAsset(assetType, name);
}
protected override AssetBase GetAsset(AssetRequest req)
{
AssetBase asset;
lock (m_syncLock)
{
asset = m_assetProvider.FetchAsset(req.AssetID);
}
return asset;
}
protected override void StoreAsset(AssetBase asset)
{
m_assetProvider.CreateAsset(asset);
}
protected override void CommitAssets()
{
m_assetProvider.CommitAssets();
}
}
}

View File

@ -0,0 +1,368 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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.Collections.Generic;
using libsecondlife;
using OpenSim.Framework.Console;
namespace OpenSim.Framework.Communications.Cache
{
public class UserProfileCacheService
{
// Fields
private readonly CommunicationsManager m_parent;
private readonly Dictionary<LLUUID, CachedUserInfo> m_userProfiles = new Dictionary<LLUUID, CachedUserInfo>();
public LibraryRootFolder libraryRoot = new LibraryRootFolder();
public RexWorldAssetsFolder worldlibraryRoot = null; // rex added
// Methods
public UserProfileCacheService(CommunicationsManager parent)
{
m_parent = parent;
// rex, added worldlibrary
if (GlobalSettings.Instance.ConfigSource.Configs["Startup"].GetBoolean("worldlibraryfolder", true))
{
worldlibraryRoot = new RexWorldAssetsFolder(m_parent.AssetCache);
libraryRoot.CreateNewSubFolder(new LLUUID("00000112-000f-0000-0000-000100bba005"), "World Library", (ushort)8);
}
// rexend
}
/// <summary>
/// A new user has moved into a region in this instance
/// so get info from servers
/// </summary>
/// <param name="userID"></param>
public void AddNewUser(LLUUID userID)
{
// Potential fix - Multithreading issue.
lock (m_userProfiles)
{
if (!m_userProfiles.ContainsKey(userID))
{
CachedUserInfo userInfo = new CachedUserInfo(m_parent);
userInfo.UserProfile = m_parent.UserService.GetUserProfile(userID, "");
if (userInfo.UserProfile != null)
{
// The request itself will occur when the agent finishes logging on to the region
// so there's no need to do it here.
//RequestInventoryForUser(userID, userInfo);
m_userProfiles.Add(userID, userInfo);
}
else
{
MainLog.Instance.Error("USERCACHE", "User profile for user {0} not found", userID);
}
}
}
}
//Rex mode
/// <summary>
/// A new user has moved into a region in this instance
/// so get info from servers
/// </summary>
/// <param name="userID"></param>
public void AddNewUser(LLUUID userID, string authAddr)
{
// Potential fix - Multithreading issue.
lock (m_userProfiles)
{
if (!m_userProfiles.ContainsKey(userID))
{
CachedUserInfo userInfo = new CachedUserInfo(m_parent);
userInfo.UserProfile = m_parent.UserService.GetUserProfile(userID, authAddr);
if (userInfo.UserProfile != null)
{
//RequestInventoryForUser(userID, userInfo);
// The request itself will occur when the agent finishes logging on to the region
// so there's no need to do it here.
//RequestInventoryForUser(userID, userInfo);
m_userProfiles.Add(userID, userInfo);
}
else
{
System.Console.WriteLine("CACHE", "User profile for user not found");
}
}
}
}
public void UpdateUserInventory(LLUUID userID)
{
CachedUserInfo userInfo = GetUserDetails(userID);
if (userInfo != null)
{
RequestInventoryForUser(userID, userInfo);
}
}
public CachedUserInfo GetUserDetails(LLUUID userID)
{
if (m_userProfiles.ContainsKey(userID))
return m_userProfiles[userID];
else
return null;
}
public void HandleCreateInventoryFolder(IClientAPI remoteClient, LLUUID folderID, ushort folderType,
string folderName, LLUUID parentID)
{
CachedUserInfo userProfile;
if (m_userProfiles.TryGetValue(remoteClient.AgentId, out userProfile))
{
if (userProfile.RootFolder != null)
{
if (userProfile.RootFolder.folderID == parentID)
{
InventoryFolderImpl createdFolder =
userProfile.RootFolder.CreateNewSubFolder(folderID, folderName, folderType);
if (createdFolder != null)
{
InventoryFolderBase createdBaseFolder = new InventoryFolderBase();
createdBaseFolder.agentID = createdFolder.agentID;
createdBaseFolder.folderID = createdFolder.folderID;
createdBaseFolder.name = createdFolder.name;
createdBaseFolder.parentID = createdFolder.parentID;
createdBaseFolder.type = createdFolder.type;
createdBaseFolder.version = createdFolder.version;
m_parent.InventoryService.AddNewInventoryFolder(remoteClient.AgentId, createdBaseFolder);
}
}
else
{
InventoryFolderImpl folder = userProfile.RootFolder.HasSubFolder(parentID);
if (folder != null)
{
folder.CreateNewSubFolder(folderID, folderName, folderType);
}
}
}
}
}
public void HandleUpdateInventoryFolder(IClientAPI remoteClient, LLUUID folderID, ushort type, string name,
LLUUID parentID)
{
CachedUserInfo userProfile;
if (m_userProfiles.TryGetValue(remoteClient.AgentId, out userProfile))
{
if (userProfile.RootFolder != null)
{
InventoryFolderBase baseFolder = new InventoryFolderBase();
baseFolder.agentID = remoteClient.AgentId;
baseFolder.folderID = folderID;
baseFolder.name = name;
baseFolder.parentID = parentID;
baseFolder.type = (short) type;
baseFolder.version = userProfile.RootFolder.version;
m_parent.InventoryService.AddNewInventoryFolder(remoteClient.AgentId, baseFolder);
}
}
}
public void HandleMoveInventoryFolder(IClientAPI remoteClient, LLUUID folderID, LLUUID parentID)
{
CachedUserInfo userProfile;
if (m_userProfiles.TryGetValue(remoteClient.AgentId, out userProfile))
{
if (userProfile.RootFolder != null)
{
InventoryFolderBase baseFolder = new InventoryFolderBase();
baseFolder.agentID = remoteClient.AgentId;
baseFolder.folderID = folderID;
baseFolder.parentID = parentID;
m_parent.InventoryService.MoveInventoryFolder(remoteClient.AgentId, baseFolder);
}
}
}
/// <summary>
/// Tell the client about the various child items and folders contained in the requested folder.
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="folderID"></param>
/// <param name="ownerID"></param>
/// <param name="fetchFolders"></param>
/// <param name="fetchItems"></param>
/// <param name="sortOrder"></param>
public void HandleFetchInventoryDescendents(IClientAPI remoteClient, LLUUID folderID, LLUUID ownerID,
bool fetchFolders, bool fetchItems, int sortOrder)
{
// XXX We're not handling sortOrder yet!
InventoryFolderImpl fold = null;
// rex, added worldassetfolder
if (worldlibraryRoot != null)
{
if (folderID == worldlibraryRoot.folderID)
{
remoteClient.SendInventoryFolderDetails(
worldlibraryRoot.agentID, worldlibraryRoot.folderID, worldlibraryRoot.RequestListOfItems(),
worldlibraryRoot.RequestListOfFolders(), fetchFolders, fetchItems);
return;
}
if ((fold = worldlibraryRoot.HasSubFolder(folderID)) != null)
{
worldlibraryRoot.UpdateWorldAssetFolders();
remoteClient.SendInventoryFolderDetails(
worldlibraryRoot.agentID, folderID, fold.RequestListOfItems(),
fold.RequestListOfFolders(), fetchFolders, fetchItems);
return;
}
}
// rex-end
if (folderID == libraryRoot.folderID)
{
remoteClient.SendInventoryFolderDetails(
libraryRoot.agentID, libraryRoot.folderID, libraryRoot.RequestListOfItems(),
libraryRoot.RequestListOfFolders(), fetchFolders, fetchItems);
return;
}
if ((fold = libraryRoot.HasSubFolder(folderID)) != null)
{
remoteClient.SendInventoryFolderDetails(
libraryRoot.agentID, folderID, fold.RequestListOfItems(),
fold.RequestListOfFolders(), fetchFolders, fetchItems);
return;
}
CachedUserInfo userProfile;
if (m_userProfiles.TryGetValue(remoteClient.AgentId, out userProfile))
{
if (userProfile.RootFolder != null)
{
if (userProfile.RootFolder.folderID == folderID)
{
remoteClient.SendInventoryFolderDetails(
remoteClient.AgentId, folderID, userProfile.RootFolder.RequestListOfItems(),
userProfile.RootFolder.RequestListOfFolders(),
fetchFolders, fetchItems);
return;
}
else
{
if ((fold = userProfile.RootFolder.HasSubFolder(folderID)) != null)
{
remoteClient.SendInventoryFolderDetails(
remoteClient.AgentId, folderID, fold.RequestListOfItems(),
fold.RequestListOfFolders(), fetchFolders, fetchItems);
return;
}
}
}
else
{
MainLog.Instance.Error(
"INVENTORYCACHE", "Could not find root folder for user {0}", remoteClient.Name);
return;
}
}
else
{
MainLog.Instance.Error(
"INVENTORYCACHE",
"Could not find user profile for {0} for folder {1}",
remoteClient.Name, folderID);
return;
}
// If we've reached this point then we couldn't find the folder, even though the client thinks
// it exists
MainLog.Instance.Error(
"INVENTORYCACHE",
"Could not find folder {0} for user {1}",
folderID, remoteClient.Name);
}
public void HandlePurgeInventoryDescendents(IClientAPI remoteClient, LLUUID folderID)
{
CachedUserInfo userProfile;
if (m_userProfiles.TryGetValue(remoteClient.AgentId, out userProfile))
{
if (userProfile.RootFolder != null)
{
InventoryFolderImpl subFolder = userProfile.RootFolder.HasSubFolder(folderID);
if (subFolder != null)
{
List<InventoryItemBase> items = subFolder.RequestListOfItems();
foreach (InventoryItemBase item in items)
{
userProfile.DeleteItem(remoteClient.AgentId, item);
}
}
}
}
}
public void HandleFetchInventory(IClientAPI remoteClient, LLUUID itemID, LLUUID ownerID)
{
if (ownerID == libraryRoot.agentID)
{
//Console.WriteLine("request info for library item");
return;
}
CachedUserInfo userProfile;
if (m_userProfiles.TryGetValue(remoteClient.AgentId, out userProfile))
{
if (userProfile.RootFolder != null)
{
InventoryItemBase item = userProfile.RootFolder.HasItem(itemID);
if (item != null)
{
remoteClient.SendInventoryItemDetails(ownerID, item);
}
}
}
}
private void RequestInventoryForUser(LLUUID userID, CachedUserInfo userInfo)
{
m_parent.InventoryService.RequestInventoryForUser(userID, userInfo.FolderReceive, userInfo.ItemReceive);
}
}
}

View File

@ -0,0 +1,812 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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;
using System.Collections.Generic;
using System.IO;
using libsecondlife;
using OpenSim.Framework;
using OpenSim.Framework.Communications.Cache;
using OpenSim.Framework.Console;
using OpenSim.Framework.Servers;
namespace OpenSim.Region.Capabilities
{
public delegate void UpLoadedAsset(
string assetName, string description, LLUUID assetID, LLUUID inventoryItem, LLUUID parentFolder,
byte[] data, string inventoryType, string assetType);
public delegate LLUUID UpdateItem(LLUUID itemID, byte[] data);
public delegate void UpdateTaskScript(LLUUID itemID, LLUUID primID, bool isScriptRunning, byte[] data);
public delegate void NewInventoryItem(LLUUID userID, InventoryItemBase item);
// rex, added for asset replace functionality
public delegate bool InventoryAssetCheck(LLUUID userID, LLUUID assetID);
public delegate LLUUID ItemUpdatedCallback(LLUUID userID, LLUUID itemID, byte[] data);
public delegate void TaskScriptUpdatedCallback(LLUUID userID, LLUUID itemID, LLUUID primID,
bool isScriptRunning, byte[] data);
public class Caps
{
private string m_httpListenerHostName;
private uint m_httpListenPort;
private string m_capsObjectPath = "00001-";
private string m_requestPath = "0000/";
private string m_mapLayerPath = "0001/";
private string m_newInventory = "0002/";
//private string m_requestTexture = "0003/";
private string m_notecardUpdatePath = "0004/";
private string m_notecardTaskUpdatePath = "0005/";
//private string eventQueue = "0100/";
private BaseHttpServer m_httpListener;
private LLUUID m_agentID;
private AssetCache m_assetCache;
private int m_eventQueueCount = 1;
private Queue<string> m_capsEventQueue = new Queue<string>();
private bool m_dumpAssetsToFile;
private bool m_replaceAssets;
// These are callbacks which will be setup by the scene so that we can update scene data when we
// receive capability calls
public NewInventoryItem AddNewInventoryItem = null;
public InventoryAssetCheck CheckInventoryForAsset = null;
public ItemUpdatedCallback ItemUpdatedCall = null;
public TaskScriptUpdatedCallback TaskScriptUpdatedCall = null;
public Caps(AssetCache assetCache, BaseHttpServer httpServer, string httpListen, uint httpPort, string capsPath,
LLUUID agent, bool dumpAssetsToFile)
{
m_assetCache = assetCache;
m_capsObjectPath = capsPath;
m_httpListener = httpServer;
m_httpListenerHostName = httpListen;
m_httpListenPort = httpPort;
m_agentID = agent;
m_dumpAssetsToFile = dumpAssetsToFile;
m_replaceAssets = (GlobalSettings.Instance.ConfigSource.Configs["Startup"].GetBoolean("replace_assets", true));
}
/// <summary>
///
/// </summary>
public void RegisterHandlers()
{
MainLog.Instance.Verbose("CAPS", "Registering CAPS handlers");
string capsBase = "/CAPS/" + m_capsObjectPath;
try
{
m_httpListener.AddStreamHandler(
new LLSDStreamhandler<LLSDMapRequest, LLSDMapLayerResponse>("POST", capsBase + m_mapLayerPath,
GetMapLayer));
m_httpListener.AddStreamHandler(
new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDAssetUploadResponse>("POST",
capsBase + m_newInventory,
NewAgentInventoryRequest));
AddLegacyCapsHandler(m_httpListener, m_requestPath, CapsRequest);
//AddLegacyCapsHandler(m_httpListener, m_requestTexture , RequestTexture);
AddLegacyCapsHandler(m_httpListener, m_notecardUpdatePath, NoteCardAgentInventory);
AddLegacyCapsHandler(m_httpListener, m_notecardTaskUpdatePath, ScriptTaskInventory);
}
catch (Exception e)
{
MainLog.Instance.Error("CAPS", e.ToString());
}
}
//[Obsolete("Use BaseHttpServer.AddStreamHandler(new LLSDStreamHandler( LLSDMethod delegate )) instead.")]
//Commented out the obsolete as at this time the first caps request can not use the new Caps method
//as the sent type is a array and not a map and the deserialising doesn't deal properly with arrays.
private void AddLegacyCapsHandler(BaseHttpServer httpListener, string path, RestMethod restMethod)
{
string capsBase = "/CAPS/" + m_capsObjectPath;
httpListener.AddStreamHandler(new RestStreamHandler("POST", capsBase + path, restMethod));
}
/// <summary>
/// Construct a client response detailing all the capabilities this server can provide.
/// </summary>
/// <param name="request"></param>
/// <param name="path"></param>
/// <param name="param"></param>
/// <returns></returns>
public string CapsRequest(string request, string path, string param)
{
//Console.WriteLine("caps request " + request);
string result = LLSDHelpers.SerialiseLLSDReply(GetCapabilities());
return result;
}
/// <summary>
/// Return an LLSDCapsDetails listing all the capabilities this server can provide
/// </summary>
/// <returns></returns>
protected LLSDCapsDetails GetCapabilities()
{
LLSDCapsDetails caps = new LLSDCapsDetails();
string capsBaseUrl = "http://" + m_httpListenerHostName + ":" + m_httpListenPort.ToString() + "/CAPS/" +
m_capsObjectPath;
caps.MapLayer = capsBaseUrl + m_mapLayerPath;
// caps.RequestTextureDownload = capsBaseUrl + m_requestTexture;
caps.NewFileAgentInventory = capsBaseUrl + m_newInventory;
caps.UpdateNotecardAgentInventory = capsBaseUrl + m_notecardUpdatePath;
caps.UpdateScriptAgentInventory = capsBaseUrl + m_notecardUpdatePath;
caps.UpdateScriptTaskInventory = capsBaseUrl + m_notecardTaskUpdatePath;
return caps;
}
/// <summary>
///
/// </summary>
/// <param name="mapReq"></param>
/// <returns></returns>
public LLSDMapLayerResponse GetMapLayer(LLSDMapRequest mapReq)
{
LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse();
mapResponse.LayerData.Array.Add(GetLLSDMapLayerResponse());
return mapResponse;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
protected LLSDMapLayer GetLLSDMapLayerResponse()
{
LLSDMapLayer mapLayer = new LLSDMapLayer();
mapLayer.Right = 5000;
mapLayer.Top = 5000;
mapLayer.ImageID = new LLUUID("00000000-0000-0000-9999-000000000006");
return mapLayer;
}
/// <summary>
///
/// </summary>
/// <param name="request"></param>
/// <param name="path"></param>
/// <param name="param"></param>
/// <returns></returns>
public string RequestTexture(string request, string path, string param)
{
Console.WriteLine("texture request " + request);
// Needs implementing (added to remove compiler warning)
return "";
}
#region EventQueue (Currently not enabled)
/// <summary>
///
/// </summary>
/// <param name="request"></param>
/// <param name="path"></param>
/// <param name="param"></param>
/// <returns></returns>
public string ProcessEventQueue(string request, string path, string param)
{
string res = "";
if (m_capsEventQueue.Count > 0)
{
lock (m_capsEventQueue)
{
string item = m_capsEventQueue.Dequeue();
res = item;
}
}
else
{
res = CreateEmptyEventResponse();
}
return res;
}
/// <summary>
///
/// </summary>
/// <param name="caps"></param>
/// <param name="ipAddressPort"></param>
/// <returns></returns>
public string CreateEstablishAgentComms(string caps, string ipAddressPort)
{
LLSDCapEvent eventItem = new LLSDCapEvent();
eventItem.id = m_eventQueueCount;
//should be creating a EstablishAgentComms item, but there isn't a class for it yet
eventItem.events.Array.Add(new LLSDEmpty());
string res = LLSDHelpers.SerialiseLLSDReply(eventItem);
m_eventQueueCount++;
m_capsEventQueue.Enqueue(res);
return res;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public string CreateEmptyEventResponse()
{
LLSDCapEvent eventItem = new LLSDCapEvent();
eventItem.id = m_eventQueueCount;
eventItem.events.Array.Add(new LLSDEmpty());
string res = LLSDHelpers.SerialiseLLSDReply(eventItem);
m_eventQueueCount++;
return res;
}
#endregion
/// <summary>
/// Callback for a client request for an upload url for a script task
/// inventory update
/// </summary>
/// <param name="request"></param>
/// <param name="path"></param>
/// <param name="param"></param>
/// <returns></returns>
public string ScriptTaskInventory(string request, string path, string param)
{
try
{
// MainLog.Instance.Debug("CAPS", "request: {0}, path: {1}, param: {2}", request, path, param);
Hashtable hash = (Hashtable) LLSD.LLSDDeserialize(Helpers.StringToField(request));
LLSDTaskScriptUpdate llsdUpdateRequest = new LLSDTaskScriptUpdate();
LLSDHelpers.DeserialiseLLSDMap(hash, llsdUpdateRequest);
string capsBase = "/CAPS/" + m_capsObjectPath;
string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
TaskInventoryScriptUpdater uploader =
new TaskInventoryScriptUpdater(
llsdUpdateRequest.item_id,
llsdUpdateRequest.task_id,
llsdUpdateRequest.is_script_running,
capsBase + uploaderPath,
m_httpListener,
m_dumpAssetsToFile);
uploader.OnUpLoad += TaskScriptUpdated;
m_httpListener.AddStreamHandler(
new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps));
string uploaderURL = "http://" + m_httpListenerHostName + ":" + m_httpListenPort.ToString() + capsBase +
uploaderPath;
LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse();
uploadResponse.uploader = uploaderURL;
uploadResponse.state = "upload";
// MainLog.Instance.Verbose(
// "CAPS",
// "ScriptTaskInventory response: {0}",
// LLSDHelpers.SerialiseLLSDReply(uploadResponse));
return LLSDHelpers.SerialiseLLSDReply(uploadResponse);
}
catch (Exception e)
{
MainLog.Instance.Error("CAPS", e.ToString());
}
return null;
}
/// <summary>
/// Callback for a client request for an upload url for a notecard (or script)
/// agent inventory update
/// </summary>
/// <param name="request"></param>
/// <param name="path"></param>
/// <param name="param"></param>
/// <returns></returns>
public string NoteCardAgentInventory(string request, string path, string param)
{
//libsecondlife.StructuredData.LLSDMap hash = (libsecondlife.StructuredData.LLSDMap)libsecondlife.StructuredData.LLSDParser.DeserializeBinary(Helpers.StringToField(request));
Hashtable hash = (Hashtable) LLSD.LLSDDeserialize(Helpers.StringToField(request));
LLSDItemUpdate llsdRequest = new LLSDItemUpdate();
LLSDHelpers.DeserialiseLLSDMap(hash, llsdRequest);
string capsBase = "/CAPS/" + m_capsObjectPath;
string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
ItemUpdater uploader =
new ItemUpdater(llsdRequest.item_id, capsBase + uploaderPath, m_httpListener, m_dumpAssetsToFile);
uploader.OnUpLoad += ItemUpdated;
m_httpListener.AddStreamHandler(
new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps));
string uploaderURL = "http://" + m_httpListenerHostName + ":" + m_httpListenPort.ToString() + capsBase +
uploaderPath;
LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse();
uploadResponse.uploader = uploaderURL;
uploadResponse.state = "upload";
// MainLog.Instance.Verbose(
// "CAPS",
// "NoteCardAgentInventory response: {0}",
// LLSDHelpers.SerialiseLLSDReply(uploadResponse));
return LLSDHelpers.SerialiseLLSDReply(uploadResponse);
}
/// <summary>
///
/// </summary>
/// <param name="llsdRequest"></param>
/// <returns></returns>
public LLSDAssetUploadResponse NewAgentInventoryRequest(LLSDAssetUploadRequest llsdRequest)
{
//Console.WriteLine("asset upload request via CAPS" + llsdRequest.inventory_type +" , "+ llsdRequest.asset_type);
string assetName = llsdRequest.name;
string assetDes = llsdRequest.description;
string capsBase = "/CAPS/" + m_capsObjectPath;
LLUUID newAsset = LLUUID.Random();
LLUUID newInvItem = LLUUID.Random();
LLUUID parentFolder = llsdRequest.folder_id;
string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
// rex, modified for "replace assets" functionality
if (m_replaceAssets)
{
// Check for asset replace upload
sbyte assType = 0;
sbyte inType = 0;
ParseAssetAndInventoryType(llsdRequest.asset_type, llsdRequest.inventory_type, out assType, out inType);
LLUUID dupID = m_assetCache.ExistsAsset(assType, llsdRequest.name);
if (dupID != LLUUID.Zero)
{
// If duplicate (same name and same assettype) found, use old asset UUID
newAsset = dupID;
// If user already has this asset in inventory, create no item
if (CheckInventoryForAsset != null)
{
if (CheckInventoryForAsset(m_agentID, dupID))
newInvItem = LLUUID.Zero;
}
}
}
// rexend
AssetUploader uploader =
new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type,
llsdRequest.asset_type, capsBase + uploaderPath, m_httpListener, m_dumpAssetsToFile);
m_httpListener.AddStreamHandler(
new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps));
string uploaderURL = "http://" + m_httpListenerHostName + ":" + m_httpListenPort.ToString() + capsBase +
uploaderPath;
LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse();
uploadResponse.uploader = uploaderURL;
uploadResponse.state = "upload";
uploader.OnUpLoad += UploadCompleteHandler;
return uploadResponse;
}
/// <summary>
///
/// </summary>
/// <param name="assetID"></param>
/// <param name="inventoryItem"></param>
/// <param name="data"></param>
public void UploadCompleteHandler(string assetName, string assetDescription, LLUUID assetID,
LLUUID inventoryItem, LLUUID parentFolder, byte[] data, string inventoryType,
string assetType)
{
sbyte assType = 0;
sbyte inType = 0;
// rex, modified to use extracted method, because needed in multiple places
ParseAssetAndInventoryType(assetType, inventoryType, out assType, out inType);
AssetBase asset;
asset = new AssetBase();
asset.FullID = assetID;
asset.Type = assType;
asset.InvType = inType;
asset.Name = assetName;
asset.Data = data;
// rex, modified for "replace assets" functionality
bool replace = (m_assetCache.ExistsAsset(assetID));
if (replace)
{
m_assetCache.ReplaceAsset(asset);
}
else
{
m_assetCache.AddAsset(asset);
}
if (inventoryItem != LLUUID.Zero)
{
InventoryItemBase item = new InventoryItemBase();
item.avatarID = m_agentID;
item.creatorsID = m_agentID;
item.inventoryID = inventoryItem;
item.assetID = asset.FullID;
item.inventoryDescription = assetDescription;
item.inventoryName = assetName;
item.assetType = assType;
item.invType = inType;
item.parentFolderID = parentFolder;
item.inventoryCurrentPermissions = 2147483647;
item.inventoryNextPermissions = 2147483647;
if (AddNewInventoryItem != null)
{
AddNewInventoryItem(m_agentID, item);
}
}
// rexend
}
// rex, new function (extracted method) with added Ogre asset support
private void ParseAssetAndInventoryType(string assetType, string inventoryType, out sbyte assType, out sbyte inType)
{
inType = 0;
assType = 0;
if (inventoryType == "sound")
{
inType = 1;
assType = 1;
}
else if (inventoryType == "animation")
{
inType = 19;
assType = 20;
}
if (assetType == "ogremesh")
{
inType = 6;
assType = 43;
}
if (assetType == "ogrepart")
{
inType = 41;
assType = 47;
}
}
/// <summary>
/// Called when new asset data for an agent inventory item update has been uploaded.
/// </summary>
/// <param name="itemID">Item to update</param>
/// <param name="data">New asset data</param>
/// <returns></returns>
public LLUUID ItemUpdated(LLUUID itemID, byte[] data)
{
if (ItemUpdatedCall != null)
{
return ItemUpdatedCall(m_agentID, itemID, data);
}
return LLUUID.Zero;
}
/// <summary>
/// Called when new asset data for an agent inventory item update has been uploaded.
/// </summary>
/// <param name="itemID">Item to update</param>
/// <param name="primID">Prim containing item to update</param>
/// <param name="isScriptRunning">Signals whether the script to update is currently running</param>
/// <param name="data">New asset data</param>
public void TaskScriptUpdated(LLUUID itemID, LLUUID primID, bool isScriptRunning, byte[] data)
{
if (TaskScriptUpdatedCall != null)
{
TaskScriptUpdatedCall(m_agentID, itemID, primID, isScriptRunning, data);
}
}
public class AssetUploader
{
public event UpLoadedAsset OnUpLoad;
private string uploaderPath = "";
private LLUUID newAssetID;
private LLUUID inventoryItemID;
private LLUUID parentFolder;
private BaseHttpServer httpListener;
private bool m_dumpAssetsToFile;
private string m_assetName = "";
private string m_assetDes = "";
private string m_invType = "";
private string m_assetType = "";
public AssetUploader(string assetName, string description, LLUUID assetID, LLUUID inventoryItem,
LLUUID parentFolderID, string invType, string assetType, string path,
BaseHttpServer httpServer, bool dumpAssetsToFile)
{
m_assetName = assetName;
m_assetDes = description;
newAssetID = assetID;
inventoryItemID = inventoryItem;
uploaderPath = path;
httpListener = httpServer;
parentFolder = parentFolderID;
m_assetType = assetType;
m_invType = invType;
m_dumpAssetsToFile = dumpAssetsToFile;
}
/// <summary>
///
/// </summary>
/// <param name="data"></param>
/// <param name="path"></param>
/// <param name="param"></param>
/// <returns></returns>
public string uploaderCaps(byte[] data, string path, string param)
{
LLUUID inv = inventoryItemID;
string res = "";
LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete();
uploadComplete.new_asset = newAssetID.ToString();
uploadComplete.new_inventory_item = inv;
uploadComplete.state = "complete";
res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
httpListener.RemoveStreamHandler("POST", uploaderPath);
if (m_dumpAssetsToFile)
{
SaveAssetToFile(m_assetName + ".jp2", data);
}
if (OnUpLoad != null)
{
OnUpLoad(m_assetName, m_assetDes, newAssetID, inv, parentFolder, data, m_invType, m_assetType);
}
return res;
}
///Left this in and commented in case there are unforseen issues
//private void SaveAssetToFile(string filename, byte[] data)
//{
// FileStream fs = File.Create(filename);
// BinaryWriter bw = new BinaryWriter(fs);
// bw.Write(data);
// bw.Close();
// fs.Close();
//}
private void SaveAssetToFile(string filename, byte[] data)
{
string assetPath = "UserAssets";
if (!Directory.Exists(assetPath))
{
Directory.CreateDirectory(assetPath);
}
FileStream fs = File.Create(Path.Combine(assetPath, filename));
BinaryWriter bw = new BinaryWriter(fs);
bw.Write(data);
bw.Close();
fs.Close();
}
}
/// <summary>
/// This class is a callback invoked when a client sends asset data to
/// an agent inventory notecard update url
/// </summary>
public class ItemUpdater
{
public event UpdateItem OnUpLoad;
private string uploaderPath = "";
private LLUUID inventoryItemID;
private BaseHttpServer httpListener;
private bool m_dumpAssetToFile;
public ItemUpdater(LLUUID inventoryItem, string path, BaseHttpServer httpServer, bool dumpAssetToFile)
{
m_dumpAssetToFile = dumpAssetToFile;
inventoryItemID = inventoryItem;
uploaderPath = path;
httpListener = httpServer;
}
/// <summary>
///
/// </summary>
/// <param name="data"></param>
/// <param name="path"></param>
/// <param name="param"></param>
/// <returns></returns>
public string uploaderCaps(byte[] data, string path, string param)
{
LLUUID inv = inventoryItemID;
string res = "";
LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete();
LLUUID assetID = LLUUID.Zero;
if (OnUpLoad != null)
{
assetID = OnUpLoad(inv, data);
}
uploadComplete.new_asset = assetID.ToString();
uploadComplete.new_inventory_item = inv;
uploadComplete.state = "complete";
res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
httpListener.RemoveStreamHandler("POST", uploaderPath);
if (m_dumpAssetToFile)
{
SaveAssetToFile("updateditem" + Util.RandomClass.Next(1, 1000) + ".dat", data);
}
return res;
}
///Left this in and commented in case there are unforseen issues
//private void SaveAssetToFile(string filename, byte[] data)
//{
// FileStream fs = File.Create(filename);
// BinaryWriter bw = new BinaryWriter(fs);
// bw.Write(data);
// bw.Close();
// fs.Close();
//}
private void SaveAssetToFile(string filename, byte[] data)
{
string assetPath = "UserAssets";
if (!Directory.Exists(assetPath))
{
Directory.CreateDirectory(assetPath);
}
FileStream fs = File.Create(Path.Combine(assetPath, filename));
BinaryWriter bw = new BinaryWriter(fs);
bw.Write(data);
bw.Close();
fs.Close();
}
}
/// <summary>
/// This class is a callback invoked when a client sends asset data to
/// a task inventory script update url
/// </summary>
public class TaskInventoryScriptUpdater
{
public event UpdateTaskScript OnUpLoad;
private string uploaderPath = "";
private LLUUID inventoryItemID;
private LLUUID primID;
private bool isScriptRunning;
private BaseHttpServer httpListener;
private bool m_dumpAssetToFile;
public TaskInventoryScriptUpdater(LLUUID inventoryItemID, LLUUID primID, int isScriptRunning,
string path, BaseHttpServer httpServer, bool dumpAssetToFile)
{
m_dumpAssetToFile = dumpAssetToFile;
this.inventoryItemID = inventoryItemID;
this.primID = primID;
// This comes in over the packet as an integer, but actually appears to be treated as a bool
this.isScriptRunning = (0 == isScriptRunning ? false : true);
uploaderPath = path;
httpListener = httpServer;
}
/// <summary>
///
/// </summary>
/// <param name="data"></param>
/// <param name="path"></param>
/// <param name="param"></param>
/// <returns></returns>
public string uploaderCaps(byte[] data, string path, string param)
{
try
{
// MainLog.Instance.Verbose(
// "CAPS",
// "TaskInventoryScriptUpdater received data: {0}, path: {1}, param: {2}",
// data, path, param);
string res = "";
LLSDTaskInventoryUploadComplete uploadComplete = new LLSDTaskInventoryUploadComplete();
if (OnUpLoad != null)
{
OnUpLoad(inventoryItemID, primID, isScriptRunning, data);
}
uploadComplete.item_id = inventoryItemID;
uploadComplete.task_id = primID;
uploadComplete.state = "complete";
res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
httpListener.RemoveStreamHandler("POST", uploaderPath);
if (m_dumpAssetToFile)
{
SaveAssetToFile("updatedtaskscript" + Util.RandomClass.Next(1, 1000) + ".dat", data);
}
// MainLog.Instance.Verbose("CAPS", "TaskInventoryScriptUpdater.uploaderCaps res: {0}", res);
return res;
}
catch (Exception e)
{
MainLog.Instance.Error("CAPS", e.ToString());
}
// XXX Maybe this should be some meaningful error packet
return null;
}
///Left this in and commented in case there are unforseen issues
//private void SaveAssetToFile(string filename, byte[] data)
//{
// FileStream fs = File.Create(filename);
// BinaryWriter bw = new BinaryWriter(fs);
// bw.Write(data);
// bw.Close();
// fs.Close();
//}
private void SaveAssetToFile(string filename, byte[] data)
{
string assetPath = "UserAssets";
if (!Directory.Exists(assetPath))
{
Directory.CreateDirectory(assetPath);
}
FileStream fs = File.Create(Path.Combine(assetPath, filename));
BinaryWriter bw = new BinaryWriter(fs);
bw.Write(data);
bw.Close();
fs.Close();
}
}
}
}

View File

@ -0,0 +1,680 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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;
using System.Globalization;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Xml;
using libsecondlife;
namespace OpenSim.Region.Capabilities
{
/// <summary>
/// Borrowed from (a older version of ) libsl for now, as their new llsd code doesn't work we our decoding code.
/// </summary>
public static class LLSD
{
/// <summary>
///
/// </summary>
public class LLSDParseException : Exception
{
public LLSDParseException(string message) : base(message)
{
}
}
/// <summary>
///
/// </summary>
public class LLSDSerializeException : Exception
{
public LLSDSerializeException(string message) : base(message)
{
}
}
/// <summary>
///
/// </summary>
/// <param name="b"></param>
/// <returns></returns>
public static object LLSDDeserialize(byte[] b)
{
return LLSDDeserialize(new MemoryStream(b, false));
}
/// <summary>
///
/// </summary>
/// <param name="st"></param>
/// <returns></returns>
public static object LLSDDeserialize(Stream st)
{
XmlTextReader reader = new XmlTextReader(st);
reader.Read();
SkipWS(reader);
if (reader.NodeType != XmlNodeType.Element || reader.LocalName != "llsd")
throw new LLSDParseException("Expected <llsd>");
reader.Read();
object ret = LLSDParseOne(reader);
SkipWS(reader);
if (reader.NodeType != XmlNodeType.EndElement || reader.LocalName != "llsd")
throw new LLSDParseException("Expected </llsd>");
return ret;
}
/// <summary>
///
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static byte[] LLSDSerialize(object obj)
{
StringWriter sw = new StringWriter();
XmlTextWriter writer = new XmlTextWriter(sw);
writer.Formatting = Formatting.None;
writer.WriteStartElement(String.Empty, "llsd", String.Empty);
LLSDWriteOne(writer, obj);
writer.WriteEndElement();
writer.Close();
return Encoding.UTF8.GetBytes(sw.ToString());
}
/// <summary>
///
/// </summary>
/// <param name="writer"></param>
/// <param name="obj"></param>
public static void LLSDWriteOne(XmlTextWriter writer, object obj)
{
if (obj == null)
{
writer.WriteStartElement(String.Empty, "undef", String.Empty);
writer.WriteEndElement();
return;
}
if (obj is string)
{
writer.WriteStartElement(String.Empty, "string", String.Empty);
writer.WriteString((string) obj);
writer.WriteEndElement();
}
else if (obj is int)
{
writer.WriteStartElement(String.Empty, "integer", String.Empty);
writer.WriteString(obj.ToString());
writer.WriteEndElement();
}
else if (obj is double)
{
writer.WriteStartElement(String.Empty, "real", String.Empty);
writer.WriteString(obj.ToString());
writer.WriteEndElement();
}
else if (obj is bool)
{
bool b = (bool) obj;
writer.WriteStartElement(String.Empty, "boolean", String.Empty);
writer.WriteString(b ? "1" : "0");
writer.WriteEndElement();
}
else if (obj is ulong)
{
throw new Exception("ulong in LLSD is currently not implemented, fix me!");
}
else if (obj is LLUUID)
{
LLUUID u = (LLUUID) obj;
writer.WriteStartElement(String.Empty, "uuid", String.Empty);
writer.WriteString(u.ToString());
writer.WriteEndElement();
}
else if (obj is Hashtable)
{
Hashtable h = obj as Hashtable;
writer.WriteStartElement(String.Empty, "map", String.Empty);
foreach (string key in h.Keys)
{
writer.WriteStartElement(String.Empty, "key", String.Empty);
writer.WriteString(key);
writer.WriteEndElement();
LLSDWriteOne(writer, h[key]);
}
writer.WriteEndElement();
}
else if (obj is ArrayList)
{
ArrayList a = obj as ArrayList;
writer.WriteStartElement(String.Empty, "array", String.Empty);
foreach (object item in a)
{
LLSDWriteOne(writer, item);
}
writer.WriteEndElement();
}
else if (obj is byte[])
{
byte[] b = obj as byte[];
writer.WriteStartElement(String.Empty, "binary", String.Empty);
writer.WriteStartAttribute(String.Empty, "encoding", String.Empty);
writer.WriteString("base64");
writer.WriteEndAttribute();
//// Calculate the length of the base64 output
//long length = (long)(4.0d * b.Length / 3.0d);
//if (length % 4 != 0) length += 4 - (length % 4);
//// Create the char[] for base64 output and fill it
//char[] tmp = new char[length];
//int i = Convert.ToBase64CharArray(b, 0, b.Length, tmp, 0);
//writer.WriteString(new String(tmp));
writer.WriteString(Convert.ToBase64String(b));
writer.WriteEndElement();
}
else
{
throw new LLSDSerializeException("Unknown type " + obj.GetType().Name);
}
}
/// <summary>
///
/// </summary>
/// <param name="reader"></param>
/// <returns></returns>
public static object LLSDParseOne(XmlTextReader reader)
{
SkipWS(reader);
if (reader.NodeType != XmlNodeType.Element)
throw new LLSDParseException("Expected an element");
string dtype = reader.LocalName;
object ret = null;
switch (dtype)
{
case "undef":
{
if (reader.IsEmptyElement)
{
reader.Read();
return null;
}
reader.Read();
SkipWS(reader);
ret = null;
break;
}
case "boolean":
{
if (reader.IsEmptyElement)
{
reader.Read();
return false;
}
reader.Read();
string s = reader.ReadString().Trim();
if (s == String.Empty || s == "false" || s == "0")
ret = false;
else if (s == "true" || s == "1")
ret = true;
else
throw new LLSDParseException("Bad boolean value " + s);
break;
}
case "integer":
{
if (reader.IsEmptyElement)
{
reader.Read();
return 0;
}
reader.Read();
ret = Convert.ToInt32(reader.ReadString().Trim());
break;
}
case "real":
{
if (reader.IsEmptyElement)
{
reader.Read();
return 0.0f;
}
reader.Read();
ret = Convert.ToDouble(reader.ReadString().Trim());
break;
}
case "uuid":
{
if (reader.IsEmptyElement)
{
reader.Read();
return LLUUID.Zero;
}
reader.Read();
ret = new LLUUID(reader.ReadString().Trim());
break;
}
case "string":
{
if (reader.IsEmptyElement)
{
reader.Read();
return String.Empty;
}
reader.Read();
ret = reader.ReadString();
break;
}
case "binary":
{
if (reader.IsEmptyElement)
{
reader.Read();
return new byte[0];
}
if (reader.GetAttribute("encoding") != null &&
reader.GetAttribute("encoding") != "base64")
{
throw new LLSDParseException("Unknown encoding: " + reader.GetAttribute("encoding"));
}
reader.Read();
FromBase64Transform b64 = new FromBase64Transform(FromBase64TransformMode.IgnoreWhiteSpaces);
byte[] inp = Encoding.ASCII.GetBytes(reader.ReadString());
ret = b64.TransformFinalBlock(inp, 0, inp.Length);
break;
}
case "date":
{
reader.Read();
throw new Exception("LLSD TODO: date");
}
case "map":
{
return LLSDParseMap(reader);
}
case "array":
{
return LLSDParseArray(reader);
}
default:
throw new LLSDParseException("Unknown element <" + dtype + ">");
}
if (reader.NodeType != XmlNodeType.EndElement || reader.LocalName != dtype)
{
throw new LLSDParseException("Expected </" + dtype + ">");
}
reader.Read();
return ret;
}
/// <summary>
///
/// </summary>
/// <param name="reader"></param>
/// <returns></returns>
public static Hashtable LLSDParseMap(XmlTextReader reader)
{
Hashtable ret = new Hashtable();
if (reader.NodeType != XmlNodeType.Element || reader.LocalName != "map")
throw new LLSDParseException("Expected <map>");
if (reader.IsEmptyElement)
{
reader.Read();
return ret;
}
reader.Read();
while (true)
{
SkipWS(reader);
if (reader.NodeType == XmlNodeType.EndElement && reader.LocalName == "map")
{
reader.Read();
break;
}
if (reader.NodeType != XmlNodeType.Element || reader.LocalName != "key")
throw new LLSDParseException("Expected <key>");
string key = reader.ReadString();
if (reader.NodeType != XmlNodeType.EndElement || reader.LocalName != "key")
throw new LLSDParseException("Expected </key>");
reader.Read();
object val = LLSDParseOne(reader);
ret[key] = val;
}
return ret; // TODO
}
/// <summary>
///
/// </summary>
/// <param name="reader"></param>
/// <returns></returns>
public static ArrayList LLSDParseArray(XmlTextReader reader)
{
ArrayList ret = new ArrayList();
if (reader.NodeType != XmlNodeType.Element || reader.LocalName != "array")
throw new LLSDParseException("Expected <array>");
if (reader.IsEmptyElement)
{
reader.Read();
return ret;
}
reader.Read();
while (true)
{
SkipWS(reader);
if (reader.NodeType == XmlNodeType.EndElement && reader.LocalName == "array")
{
reader.Read();
break;
}
ret.Insert(ret.Count, LLSDParseOne(reader));
}
return ret; // TODO
}
/// <summary>
///
/// </summary>
/// <param name="count"></param>
/// <returns></returns>
private static string GetSpaces(int count)
{
StringBuilder b = new StringBuilder();
for (int i = 0; i < count; i++) b.Append(" ");
return b.ToString();
}
/// <summary>
///
/// </summary>
/// <param name="obj"></param>
/// <param name="indent"></param>
/// <returns></returns>
public static String LLSDDump(object obj, int indent)
{
if (obj == null)
{
return GetSpaces(indent) + "- undef\n";
}
else if (obj is string)
{
return GetSpaces(indent) + "- string \"" + (string) obj + "\"\n";
}
else if (obj is int)
{
return GetSpaces(indent) + "- integer " + obj.ToString() + "\n";
}
else if (obj is double)
{
return GetSpaces(indent) + "- float " + obj.ToString() + "\n";
}
else if (obj is LLUUID)
{
return GetSpaces(indent) + "- uuid " + ((LLUUID) obj).ToString() + Environment.NewLine;
}
else if (obj is Hashtable)
{
StringBuilder ret = new StringBuilder();
ret.Append(GetSpaces(indent) + "- map" + Environment.NewLine);
Hashtable map = (Hashtable) obj;
foreach (string key in map.Keys)
{
ret.Append(GetSpaces(indent + 2) + "- key \"" + key + "\"" + Environment.NewLine);
ret.Append(LLSDDump(map[key], indent + 3));
}
return ret.ToString();
}
else if (obj is ArrayList)
{
StringBuilder ret = new StringBuilder();
ret.Append(GetSpaces(indent) + "- array\n");
ArrayList list = (ArrayList) obj;
foreach (object item in list)
{
ret.Append(LLSDDump(item, indent + 2));
}
return ret.ToString();
}
else if (obj is byte[])
{
return GetSpaces(indent) + "- binary\n" + Helpers.FieldToHexString((byte[]) obj, GetSpaces(indent)) +
Environment.NewLine;
}
else
{
return GetSpaces(indent) + "- unknown type " + obj.GetType().Name + Environment.NewLine;
}
}
public static object ParseTerseLLSD(string llsd)
{
int notused;
return ParseTerseLLSD(llsd, out notused);
}
public static object ParseTerseLLSD(string llsd, out int endPos)
{
if (llsd.Length == 0)
{
endPos = 0;
return null;
}
// Identify what type of object this is
switch (llsd[0])
{
case '!':
throw new LLSDParseException("Undefined value type encountered");
case '1':
endPos = 1;
return true;
case '0':
endPos = 1;
return false;
case 'i':
{
if (llsd.Length < 2) throw new LLSDParseException("Integer value type with no value");
int value;
endPos = FindEnd(llsd, 1);
if (Int32.TryParse(llsd.Substring(1, endPos - 1), out value))
return value;
else
throw new LLSDParseException("Failed to parse integer value type");
}
case 'r':
{
if (llsd.Length < 2) throw new LLSDParseException("Real value type with no value");
double value;
endPos = FindEnd(llsd, 1);
if (Double.TryParse(llsd.Substring(1, endPos - 1), NumberStyles.Float,
Helpers.EnUsCulture.NumberFormat, out value))
return value;
else
throw new LLSDParseException("Failed to parse double value type");
}
case 'u':
{
if (llsd.Length < 17) throw new LLSDParseException("LLUUID value type with no value");
LLUUID value;
endPos = FindEnd(llsd, 1);
if (LLUUID.TryParse(llsd.Substring(1, endPos - 1), out value))
return value;
else
throw new LLSDParseException("Failed to parse LLUUID value type");
}
case 'b':
//byte[] value = new byte[llsd.Length - 1];
// This isn't the actual binary LLSD format, just the terse format sent
// at login so I don't even know if there is a binary type
throw new LLSDParseException("Binary value type is unimplemented");
case 's':
case 'l':
if (llsd.Length < 2) throw new LLSDParseException("String value type with no value");
endPos = FindEnd(llsd, 1);
return llsd.Substring(1, endPos - 1);
case 'd':
// Never seen one before, don't know what the format is
throw new LLSDParseException("Date value type is unimplemented");
case '[':
{
if (llsd.IndexOf(']') == -1) throw new LLSDParseException("Invalid array");
int pos = 0;
ArrayList array = new ArrayList();
while (llsd[pos] != ']')
{
++pos;
// Advance past comma if need be
if (llsd[pos] == ',') ++pos;
// Allow a single whitespace character
if (pos < llsd.Length && llsd[pos] == ' ') ++pos;
int end;
array.Add(ParseTerseLLSD(llsd.Substring(pos), out end));
pos += end;
}
endPos = pos + 1;
return array;
}
case '{':
{
if (llsd.IndexOf('}') == -1) throw new LLSDParseException("Invalid map");
int pos = 0;
Hashtable hashtable = new Hashtable();
while (llsd[pos] != '}')
{
++pos;
// Advance past comma if need be
if (llsd[pos] == ',') ++pos;
// Allow a single whitespace character
if (pos < llsd.Length && llsd[pos] == ' ') ++pos;
if (llsd[pos] != '\'') throw new LLSDParseException("Expected a map key");
int endquote = llsd.IndexOf('\'', pos + 1);
if (endquote == -1 || (endquote + 1) >= llsd.Length || llsd[endquote + 1] != ':')
throw new LLSDParseException("Invalid map format");
string key = llsd.Substring(pos, endquote - pos);
key = key.Replace("'", String.Empty);
pos += (endquote - pos) + 2;
int end;
hashtable.Add(key, ParseTerseLLSD(llsd.Substring(pos), out end));
pos += end;
}
endPos = pos + 1;
return hashtable;
}
default:
throw new Exception("Unknown value type");
}
}
private static int FindEnd(string llsd, int start)
{
int end = llsd.IndexOfAny(new char[] {',', ']', '}'});
if (end == -1) end = llsd.Length - 1;
return end;
}
/// <summary>
///
/// </summary>
/// <param name="reader"></param>
private static void SkipWS(XmlTextReader reader)
{
while (
reader.NodeType == XmlNodeType.Comment ||
reader.NodeType == XmlNodeType.Whitespace ||
reader.NodeType == XmlNodeType.SignificantWhitespace ||
reader.NodeType == XmlNodeType.XmlDeclaration)
{
reader.Read();
}
}
}
}

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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.Collections;
namespace OpenSim.Region.Capabilities
{
[LLSDType("ARRAY")]
public class LLSDArray
{
public ArrayList Array = new ArrayList();
public LLSDArray()
{
}
}
}

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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 libsecondlife;
namespace OpenSim.Region.Capabilities
{
[LLSDType("MAP")]
public class LLSDAssetUploadComplete
{
public string new_asset = "";
public LLUUID new_inventory_item = LLUUID.Zero;
public string state = "";
//public bool success = false;
public LLSDAssetUploadComplete()
{
}
}
}

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS 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 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 libsecondlife;
namespace OpenSim.Region.Capabilities
{
[LLSDMap]
public class LLSDAssetUploadRequest
{
public string asset_type = "";
public string description = "";
public LLUUID folder_id = LLUUID.Zero;
public string inventory_type = "";
public string name = "";
public LLSDAssetUploadRequest()
{
}
}
}

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS 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 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.
*
*/
namespace OpenSim.Region.Capabilities
{
[LLSDMap]
public class LLSDAssetUploadResponse
{
public string uploader = "";
public string state = "";
public LLSDAssetUploadResponse()
{
}
}
}

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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.
*
*/
namespace OpenSim.Region.Capabilities
{
[LLSDType("MAP")]
public class LLSDCapEvent
{
public int id = 0;
public LLSDArray events = new LLSDArray();
public LLSDCapEvent()
{
}
}
}

View File

@ -0,0 +1,48 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS 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 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.
*
*/
namespace OpenSim.Region.Capabilities
{
[LLSDType("MAP")]
public class LLSDCapsDetails
{
public string MapLayer = "";
public string NewFileAgentInventory = "";
//public string EventQueueGet = "";
// public string RequestTextureDownload = "";
// public string ChatSessionRequest = "";
public string UpdateNotecardAgentInventory = "";
public string UpdateScriptAgentInventory = "";
public string UpdateScriptTaskInventory = "";
// public string ParcelVoiceInfoRequest = "";
public LLSDCapsDetails()
{
}
}
}

View File

@ -0,0 +1,37 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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.
*
*/
namespace OpenSim.Region.Capabilities
{
[LLSDType("MAP")]
public class LLSDEmpty
{
public LLSDEmpty()
{
}
}
}

View File

@ -0,0 +1,151 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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;
using System.IO;
using System.Reflection;
using System.Xml;
namespace OpenSim.Region.Capabilities
{
public class LLSDHelpers
{
public static string SerialiseLLSDReply(object obj)
{
StringWriter sw = new StringWriter();
XmlTextWriter writer = new XmlTextWriter(sw);
writer.Formatting = Formatting.None;
writer.WriteStartElement(String.Empty, "llsd", String.Empty);
SerializeLLSDType(writer, obj);
writer.WriteEndElement();
writer.Close();
return sw.ToString();
}
private static void SerializeLLSDType(XmlTextWriter writer, object obj)
{
Type myType = obj.GetType();
LLSDType[] llsdattributes = (LLSDType[]) myType.GetCustomAttributes(typeof (LLSDType), false);
if (llsdattributes.Length > 0)
{
switch (llsdattributes[0].ObjectType)
{
case "MAP":
writer.WriteStartElement(String.Empty, "map", String.Empty);
FieldInfo[] fields = myType.GetFields();
for (int i = 0; i < fields.Length; i++)
{
object fieldValue = fields[i].GetValue(obj);
LLSDType[] fieldAttributes =
(LLSDType[]) fieldValue.GetType().GetCustomAttributes(typeof (LLSDType), false);
if (fieldAttributes.Length > 0)
{
writer.WriteStartElement(String.Empty, "key", String.Empty);
writer.WriteString(fields[i].Name);
writer.WriteEndElement();
SerializeLLSDType(writer, fieldValue);
}
else
{
writer.WriteStartElement(String.Empty, "key", String.Empty);
writer.WriteString(fields[i].Name);
writer.WriteEndElement();
LLSD.LLSDWriteOne(writer, fieldValue);
// libsecondlife.StructuredData.LLSDParser.SerializeXmlElement(
// writer, libsecondlife.StructuredData.LLSD.FromObject(fieldValue));
}
}
writer.WriteEndElement();
break;
case "ARRAY":
// LLSDArray arrayObject = obj as LLSDArray;
// ArrayList a = arrayObject.Array;
ArrayList a = (ArrayList) obj.GetType().GetField("Array").GetValue(obj);
if (a != null)
{
writer.WriteStartElement(String.Empty, "array", String.Empty);
foreach (object item in a)
{
SerializeLLSDType(writer, item);
}
writer.WriteEndElement();
}
break;
}
}
else
{
LLSD.LLSDWriteOne(writer, obj);
//libsecondlife.StructuredData.LLSDParser.SerializeXmlElement(
// writer, libsecondlife.StructuredData.LLSD.FromObject(obj));
}
}
public static object DeserialiseLLSDMap(Hashtable llsd, object obj)
{
Type myType = obj.GetType();
LLSDType[] llsdattributes = (LLSDType[]) myType.GetCustomAttributes(typeof (LLSDType), false);
if (llsdattributes.Length > 0)
{
switch (llsdattributes[0].ObjectType)
{
case "MAP":
IDictionaryEnumerator enumerator = llsd.GetEnumerator();
while (enumerator.MoveNext())
{
FieldInfo field = myType.GetField((string) enumerator.Key);
if (field != null)
{
// if (enumerator.Value is libsecondlife.StructuredData.LLSDMap)
if (enumerator.Value is Hashtable)
{
object fieldValue = field.GetValue(obj);
DeserialiseLLSDMap((Hashtable) enumerator.Value, fieldValue);
// DeserialiseLLSDMap((libsecondlife.StructuredData.LLSDMap) enumerator.Value, fieldValue);
}
else if (enumerator.Value is ArrayList)
{
object fieldValue = field.GetValue(obj);
fieldValue.GetType().GetField("Array").SetValue(fieldValue, enumerator.Value);
//TODO
// the LLSD map/array types in the array need to be deserialised
// but first we need to know the right class to deserialise them into.
}
else
{
field.SetValue(obj, enumerator.Value);
}
}
}
break;
}
}
return obj;
}
}
}

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS 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 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 libsecondlife;
namespace OpenSim.Region.Capabilities
{
[LLSDMap]
public class LLSDItemUpdate
{
public LLUUID item_id;
public LLSDItemUpdate()
{
}
}
}

View File

@ -0,0 +1,45 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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 libsecondlife;
namespace OpenSim.Region.Capabilities
{
[LLSDType("MAP")]
public class LLSDMapLayer
{
public int Left = 0;
public int Right = 0;
public int Top = 0;
public int Bottom = 0;
public LLUUID ImageID = LLUUID.Zero;
public LLSDMapLayer()
{
}
}
}

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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.
*
*/
namespace OpenSim.Region.Capabilities
{
[LLSDType("MAP")]
public class LLSDMapLayerResponse
{
public LLSDMapRequest AgentData = new LLSDMapRequest();
public LLSDArray LayerData = new LLSDArray();
public LLSDMapLayerResponse()
{
}
}
}

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS 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 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.
*
*/
namespace OpenSim.Region.Capabilities
{
[LLSDType("MAP")]
public class LLSDMapRequest
{
public int Flags = 0;
public LLSDMapRequest()
{
}
}
}

View File

@ -0,0 +1,32 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS 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 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.
*
*/
namespace OpenSim.Region.Capabilities
{
public delegate TResponse LLSDMethod<TRequest, TResponse>(TRequest request);
}

View File

@ -0,0 +1,69 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS 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 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.Collections;
using System.IO;
using System.Text;
using OpenSim.Framework.Servers;
namespace OpenSim.Region.Capabilities
{
public class LLSDStreamhandler<TRequest, TResponse> : BaseStreamHandler
where TRequest : new()
{
private LLSDMethod<TRequest, TResponse> m_method;
public LLSDStreamhandler(string httpMethod, string path, LLSDMethod<TRequest, TResponse> method)
: base(httpMethod, path)
{
m_method = method;
}
public override byte[] Handle(string path, Stream request)
{
//Encoding encoding = Encoding.UTF8;
//StreamReader streamReader = new StreamReader(request, false);
//string requestBody = streamReader.ReadToEnd();
//streamReader.Close();
// libsecondlife.StructuredData.LLSDMap hash = (libsecondlife.StructuredData.LLSDMap)
// libsecondlife.StructuredData.LLSDParser.DeserializeXml(new XmlTextReader(request));
Hashtable hash = (Hashtable) LLSD.LLSDDeserialize(request);
TRequest llsdRequest = new TRequest();
LLSDHelpers.DeserialiseLLSDMap(hash, llsdRequest);
TResponse response = m_method(llsdRequest);
Encoding encoding = new UTF8Encoding(false);
return encoding.GetBytes(LLSDHelpers.SerialiseLLSDReply(response));
}
}
}

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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 libsecondlife;
namespace OpenSim.Region.Capabilities
{
[LLSDMap]
public class LLSDTaskInventoryUploadComplete
{
/// <summary>
/// The task inventory item that was updated
/// </summary>
public LLUUID item_id;
/// <summary>
/// The task that was updated
/// </summary>
public LLUUID task_id;
/// <summary>
/// State of the upload. So far have only even seen this set to "complete"
/// </summary>
public string state;
}
}

View File

@ -0,0 +1,51 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS 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 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 libsecondlife;
namespace OpenSim.Region.Capabilities
{
[LLSDMap]
public class LLSDTaskScriptUpdate
{
/// <summary>
/// The item containing the script to update
/// </summary>
public LLUUID item_id;
/// <summary>
/// The task containing the script
/// </summary>
public LLUUID task_id;
/// <summary>
/// Signals whether the script is currently active
/// </summary>
public int is_script_running;
}
}

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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.
*
*/
namespace OpenSim.Region.Capabilities
{
[LLSDType("MAP")]
public class LLSDTest
{
public int Test1 = 20;
public int Test2 = 10;
public LLSDTest()
{
}
}
}

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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;
namespace OpenSim.Region.Capabilities
{
[AttributeUsage(AttributeTargets.Class)]
public class LLSDType : Attribute
{
protected string myType;
public LLSDType(string type)
{
myType = type;
}
public string ObjectType
{
get { return myType; }
}
}
[AttributeUsage(AttributeTargets.Class)]
public class LLSDMap : LLSDType
{
public LLSDMap() : base("MAP")
{
}
}
}

View File

@ -0,0 +1,228 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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 libsecondlife;
using OpenSim.Framework.Communications.Cache;
using OpenSim.Framework.Console;
using OpenSim.Framework.Servers;
namespace OpenSim.Framework.Communications
{
public class CommunicationsManager
{
protected IUserService m_userService;
public IUserService UserService
{
get { return m_userService; }
}
protected IGridServices m_gridService;
public IGridServices GridService
{
get { return m_gridService; }
}
protected IInventoryServices m_inventoryService;
public IInventoryServices InventoryService
{
get { return m_inventoryService; }
}
protected IInterRegionCommunications m_interRegion;
public IInterRegionCommunications InterRegion
{
get { return m_interRegion; }
}
protected UserProfileCacheService m_userProfileCacheService;
public UserProfileCacheService UserProfileCacheService
{
get { return m_userProfileCacheService; }
}
protected AssetTransactionManager m_transactionsManager;
public AssetTransactionManager TransactionsManager
{
get { return m_transactionsManager; }
}
protected AssetCache m_assetCache;
public AssetCache AssetCache
{
get { return m_assetCache; }
}
protected NetworkServersInfo m_networkServersInfo;
public NetworkServersInfo NetworkServersInfo
{
get { return m_networkServersInfo; }
}
public CommunicationsManager(NetworkServersInfo serversInfo, BaseHttpServer httpServer, AssetCache assetCache,
bool dumpAssetsToFile)
{
m_networkServersInfo = serversInfo;
m_assetCache = assetCache;
m_userProfileCacheService = new UserProfileCacheService(this);
m_transactionsManager = new AssetTransactionManager(this, dumpAssetsToFile);
}
public void doCreate(string[] cmmdParams)
{
switch (cmmdParams[0])
{
case "user":
string firstName;
string lastName;
string password;
uint regX = 1000;
uint regY = 1000;
if (cmmdParams.Length < 2)
{
firstName = MainLog.Instance.CmdPrompt("First name", "Default");
lastName = MainLog.Instance.CmdPrompt("Last name", "User");
password = MainLog.Instance.PasswdPrompt("Password");
regX = Convert.ToUInt32(MainLog.Instance.CmdPrompt("Start Region X", "1000"));
regY = Convert.ToUInt32(MainLog.Instance.CmdPrompt("Start Region Y", "1000"));
}
else
{
firstName = cmmdParams[1];
lastName = cmmdParams[2];
password = cmmdParams[3];
regX = Convert.ToUInt32(cmmdParams[4]);
regY = Convert.ToUInt32(cmmdParams[5]);
}
AddUser(firstName, lastName, password, regX, regY);
break;
}
}
public LLUUID AddUser(string firstName, string lastName, string password, uint regX, uint regY)
{
string md5PasswdHash = Util.Md5Hash(Util.Md5Hash(password) + ":" + "");
m_userService.AddUserProfile(firstName, lastName, md5PasswdHash, regX, regY);
UserProfileData userProf = UserService.GetUserProfile(firstName, lastName, "");
if (userProf == null)
{
return LLUUID.Zero;
}
else
{
m_inventoryService.CreateNewUserInventory(userProf.UUID);
System.Console.WriteLine("Created new inventory set for " + firstName + " " + lastName);
return userProf.UUID;
}
}
#region Friend Methods
/// <summary>
/// Adds a new friend to the database for XUser
/// </summary>
/// <param name="friendlistowner">The agent that who's friends list is being added to</param>
/// <param name="friend">The agent that being added to the friends list of the friends list owner</param>
/// <param name="perms">A uint bit vector for set perms that the friend being added has; 0 = none, 1=This friend can see when they sign on, 2 = map, 4 edit objects </param>
public void AddNewUserFriend(LLUUID friendlistowner, LLUUID friend, uint perms)
{
m_userService.AddNewUserFriend(friendlistowner, friend, perms);
}
/// <summary>
/// Delete friend on friendlistowner's friendlist.
/// </summary>
/// <param name="friendlistowner">The agent that who's friends list is being updated</param>
/// <param name="friend">The Ex-friend agent</param>
public void RemoveUserFriend(LLUUID friendlistowner, LLUUID friend)
{
m_userService.RemoveUserFriend(friendlistowner, friend);
}
/// <summary>
/// Update permissions for friend on friendlistowner's friendlist.
/// </summary>
/// <param name="friendlistowner">The agent that who's friends list is being updated</param>
/// <param name="friend">The agent that is getting or loosing permissions</param>
/// <param name="perms">A uint bit vector for set perms that the friend being added has; 0 = none, 1=This friend can see when they sign on, 2 = map, 4 edit objects </param>
public void UpdateUserFriendPerms(LLUUID friendlistowner, LLUUID friend, uint perms)
{
m_userService.UpdateUserFriendPerms(friendlistowner, friend, perms);
}
/// <summary>
/// Returns a list of FriendsListItems that describe the friends and permissions in the friend relationship for LLUUID friendslistowner
/// </summary>
/// <param name="friendlistowner">The agent that we're retreiving the friends Data.</param>
public List<FriendListItem> GetUserFriendList(LLUUID friendlistowner)
{
return m_userService.GetUserFriendList(friendlistowner);
}
#endregion
#region Packet Handlers
public void HandleUUIDNameRequest(LLUUID uuid, IClientAPI remote_client)
{
if (uuid == m_userProfileCacheService.libraryRoot.agentID)
{
remote_client.SendNameReply(uuid, "Mr", "OpenSim");
}
else
{
UserProfileData profileData = m_userService.GetUserProfile(uuid, "");
if (profileData != null)
{
LLUUID profileId = profileData.UUID;
string firstname = profileData.username;
string lastname = profileData.surname;
remote_client.SendNameReply(profileId, firstname, lastname);
}
}
}
public List<AvatarPickerAvatar> GenerateAgentPickerRequestResponse(LLUUID queryID, string query)
{
List<AvatarPickerAvatar> pickerlist = m_userService.GenerateAgentPickerRequestResponse(queryID, query);
return pickerlist;
}
#endregion
}
}

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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.Collections.Generic;
namespace OpenSim.Framework.Communications
{
public interface IGridServices
{
string gdebugRegionName { get; set; }
RegionCommsListener RegisterRegion(RegionInfo regionInfos);
bool DeregisterRegion(RegionInfo regionInfo);
List<SimpleRegionInfo> RequestNeighbours(uint x, uint y);
RegionInfo RequestNeighbourInfo(ulong regionHandle);
Dictionary<string, string> GetGridSettings();
List<MapBlockData> RequestNeighbourMapBlocks(int minX, int minY, int maxX, int maxY);
}
}

View File

@ -0,0 +1,48 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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 libsecondlife;
namespace OpenSim.Framework.Communications
{
public interface IInterRegionCommunications
{
string rdebugRegionName { get; set; }
bool InformRegionOfChildAgent(ulong regionHandle, AgentCircuitData agentData);
bool InformRegionOfPrimCrossing(ulong regionHandle, LLUUID primID, string objData);
bool RegionUp(SearializableRegionInfo region, ulong regionhandle);
bool ChildAgentUpdate(ulong regionHandle, ChildAgentDataUpdate cAgentData);
bool ExpectAvatarCrossing(ulong regionHandle, LLUUID agentID, LLVector3 position, bool isFlying);
bool ExpectPrimCrossing(ulong regionHandle, LLUUID primID, LLVector3 position, bool isFlying);
bool AcknowledgeAgentCrossed(ulong regionHandle, LLUUID agentId);
bool AcknowledgePrimCrossed(ulong regionHandle, LLUUID primID);
void TellRegionToCloseChildConnection(ulong regionHandle, LLUUID agentID);
}
}

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS 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 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.Collections.Generic;
using libsecondlife;
using OpenSim.Framework.Communications.Cache;
namespace OpenSim.Framework.Communications
{
public delegate void InventoryFolderInfo(LLUUID userID, InventoryFolderImpl folderInfo);
public delegate void InventoryItemInfo(LLUUID userID, InventoryItemBase itemInfo);
public interface IInventoryServices
{
void RequestInventoryForUser(LLUUID userID, InventoryFolderInfo folderCallBack, InventoryItemInfo itemCallBack);
void AddNewInventoryFolder(LLUUID userID, InventoryFolderBase folder);
void MoveInventoryFolder(LLUUID userID, InventoryFolderBase folder);
void AddNewInventoryItem(LLUUID userID, InventoryItemBase item);
void DeleteInventoryItem(LLUUID userID, InventoryItemBase item);
void CreateNewUserInventory(LLUUID user);
/// <summary>
/// Returns the root folder plus any folders in root (so down one level in the Inventory folders tree)
/// </summary>
/// <param name="userID"></param>
/// <returns></returns>
List<InventoryFolderBase> RequestFirstLevelFolders(LLUUID userID);
}
}

View File

@ -0,0 +1,390 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS 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 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.Reflection;
using libsecondlife;
using OpenSim.Framework.Console;
namespace OpenSim.Framework.Communications
{
public abstract class InventoryServiceBase : IInventoryServices
{
protected Dictionary<string, IInventoryData> m_plugins = new Dictionary<string, IInventoryData>();
//protected IAssetServer m_assetServer;
public InventoryServiceBase()
{
//m_assetServer = assetServer;
}
/// <summary>
/// Adds a new user server plugin - plugins will be requested in the order they were loaded.
/// </summary>
/// <param name="FileName">The filename to the user server plugin DLL</param>
public void AddPlugin(string FileName)
{
if (!String.IsNullOrEmpty(FileName))
{
MainLog.Instance.Verbose("AGENTINVENTORY", "Inventorystorage: Attempting to load " + FileName);
Assembly pluginAssembly = Assembly.LoadFrom(FileName);
foreach (Type pluginType in pluginAssembly.GetTypes())
{
if (!pluginType.IsAbstract)
{
Type typeInterface = pluginType.GetInterface("IInventoryData", true);
if (typeInterface != null)
{
IInventoryData plug =
(IInventoryData) Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));
plug.Initialise();
m_plugins.Add(plug.getName(), plug);
MainLog.Instance.Verbose("AGENTINVENTORY", "Added IInventoryData Interface");
}
}
}
}
}
public List<InventoryFolderBase> RequestFirstLevelFolders(Guid rawUserID)
{
LLUUID userID = new LLUUID(rawUserID);
return RequestFirstLevelFolders(userID);
}
/// <summary>
/// Returns the root folder plus any folders in root (so down one level in the Inventory folders tree)
/// </summary>
/// <param name="userID"></param>
/// <returns></returns>
public List<InventoryFolderBase> RequestFirstLevelFolders(LLUUID userID)
{
List<InventoryFolderBase> inventoryList = new List<InventoryFolderBase>();
InventoryFolderBase rootFolder = null;
foreach (KeyValuePair<string, IInventoryData> plugin in m_plugins)
{
rootFolder = plugin.Value.getUserRootFolder(userID);
if (rootFolder != null)
{
MainLog.Instance.Verbose(
"INVENTORY",
"Found root folder for user with ID " + userID + ". Retrieving inventory contents.");
inventoryList = plugin.Value.getInventoryFolders(rootFolder.folderID);
inventoryList.Insert(0, rootFolder);
return inventoryList;
}
}
MainLog.Instance.Warn(
"INVENTORY", "Could not find a root folder belonging to user with ID " + userID);
return inventoryList;
}
/// <summary>
/// Get the root folder for a user
/// </summary>
/// <param name="userID"></param>
/// <returns>null if no root folder was found</returns>
public InventoryFolderBase RequestUsersRoot(LLUUID userID)
{
foreach (KeyValuePair<string, IInventoryData> plugin in m_plugins)
{
return plugin.Value.getUserRootFolder(userID);
}
return null;
}
/// <summary>
///
/// </summary>
public void MoveInventoryFolder(LLUUID userID, InventoryFolderBase folder)
{
foreach (KeyValuePair<string, IInventoryData> plugin in m_plugins)
{
plugin.Value.moveInventoryFolder(folder);
}
}
/// <summary>
///
/// </summary>
/// <param name="parentFolderID"></param>
/// <returns></returns>
public List<InventoryFolderBase> RequestSubFolders(LLUUID parentFolderID)
{
List<InventoryFolderBase> inventoryList = new List<InventoryFolderBase>();
foreach (KeyValuePair<string, IInventoryData> plugin in m_plugins)
{
return plugin.Value.getInventoryFolders(parentFolderID);
}
return inventoryList;
}
public List<InventoryItemBase> RequestFolderItems(LLUUID folderID)
{
List<InventoryItemBase> itemsList = new List<InventoryItemBase>();
foreach (KeyValuePair<string, IInventoryData> plugin in m_plugins)
{
itemsList = plugin.Value.getInventoryInFolder(folderID);
return itemsList;
}
return itemsList;
}
public void AddFolder(InventoryFolderBase folder)
{
foreach (KeyValuePair<string, IInventoryData> plugin in m_plugins)
{
plugin.Value.addInventoryFolder(folder);
}
}
public void MoveFolder(InventoryFolderBase folder)
{
foreach (KeyValuePair<string, IInventoryData> plugin in m_plugins)
{
plugin.Value.moveInventoryFolder(folder);
}
}
public void AddItem(InventoryItemBase item)
{
foreach (KeyValuePair<string, IInventoryData> plugin in m_plugins)
{
plugin.Value.addInventoryItem(item);
}
}
public void DeleteItem(InventoryItemBase item)
{
foreach (KeyValuePair<string, IInventoryData> plugin in m_plugins)
{
plugin.Value.deleteInventoryItem(item.inventoryID);
}
}
/// <summary>
///
/// </summary>
/// <param name="inventory"></param>
public void AddNewInventorySet(UsersInventory inventory)
{
foreach (InventoryFolderBase folder in inventory.Folders.Values)
{
AddFolder(folder);
}
}
/// <summary>
/// Create a new set of inventory folders for the given user.
/// </summary>
/// <param name="user"></param>
public void CreateNewUserInventory(LLUUID user)
{
InventoryFolderBase existingRootFolder = RequestUsersRoot(user);
if (null != existingRootFolder)
{
MainLog.Instance.Error(
"AGENTINVENTORY",
"Did not create a new inventory for user {0} since they already have "
+ "a root inventory folder with id {1}", user, existingRootFolder);
}
else
{
UsersInventory inven = new UsersInventory();
inven.CreateNewInventorySet(user);
AddNewInventorySet(inven);
}
}
public class UsersInventory
{
public Dictionary<LLUUID, InventoryFolderBase> Folders = new Dictionary<LLUUID, InventoryFolderBase>();
public Dictionary<LLUUID, InventoryItemBase> Items = new Dictionary<LLUUID, InventoryItemBase>();
public UsersInventory()
{
}
public virtual void CreateNewInventorySet(LLUUID user)
{
InventoryFolderBase folder = new InventoryFolderBase();
folder.parentID = LLUUID.Zero;
folder.agentID = user;
folder.folderID = LLUUID.Random();
folder.name = "My Inventory";
folder.type = 8;
folder.version = 1;
Folders.Add(folder.folderID, folder);
LLUUID rootFolder = folder.folderID;
folder = new InventoryFolderBase();
folder.parentID = rootFolder;
folder.agentID = user;
folder.folderID = LLUUID.Random();
folder.name = "Accessories";
folder.type = 8;
folder.version = 1;
Folders.Add(folder.folderID, folder);
folder = new InventoryFolderBase();
folder.parentID = rootFolder;
folder.agentID = user;
folder.folderID = LLUUID.Random();
folder.name = "Animations";
folder.type = 20;
folder.version = 1;
Folders.Add(folder.folderID, folder);
folder = new InventoryFolderBase();
folder.parentID = rootFolder;
folder.agentID = user;
folder.folderID = LLUUID.Random();
folder.name = "BodyParts";
folder.type = 13;
folder.version = 1;
Folders.Add(folder.folderID, folder);
folder = new InventoryFolderBase();
folder.parentID = rootFolder;
folder.agentID = user;
folder.folderID = LLUUID.Random();
folder.name = "Clothing";
folder.type = 5;
folder.version = 1;
Folders.Add(folder.folderID, folder);
folder = new InventoryFolderBase();
folder.parentID = rootFolder;
folder.agentID = user;
folder.folderID = LLUUID.Random();
folder.name = "Gestures";
folder.type = 21;
folder.version = 1;
Folders.Add(folder.folderID, folder);
folder = new InventoryFolderBase();
folder.parentID = rootFolder;
folder.agentID = user;
folder.folderID = LLUUID.Random();
folder.name = "Landmarks";
folder.type = 3;
folder.version = 1;
Folders.Add(folder.folderID, folder);
folder = new InventoryFolderBase();
folder.parentID = rootFolder;
folder.agentID = user;
folder.folderID = LLUUID.Random();
folder.name = "Lost And Found";
folder.type = 3;
folder.version = 1;
Folders.Add(folder.folderID, folder);
folder = new InventoryFolderBase();
folder.parentID = rootFolder;
folder.agentID = user;
folder.folderID = LLUUID.Random();
folder.name = "Notecards";
folder.type = 7;
folder.version = 1;
Folders.Add(folder.folderID, folder);
folder = new InventoryFolderBase();
folder.parentID = rootFolder;
folder.agentID = user;
folder.folderID = LLUUID.Random();
folder.name = "Objects";
folder.type = 6;
folder.version = 1;
Folders.Add(folder.folderID, folder);
folder = new InventoryFolderBase();
folder.parentID = rootFolder;
folder.agentID = user;
folder.folderID = LLUUID.Random();
folder.name = "Photo Album";
folder.type = 15;
folder.version = 1;
Folders.Add(folder.folderID, folder);
folder = new InventoryFolderBase();
folder.parentID = rootFolder;
folder.agentID = user;
folder.folderID = LLUUID.Random();
folder.name = "Scripts";
folder.type = 10;
folder.version = 1;
Folders.Add(folder.folderID, folder);
folder = new InventoryFolderBase();
folder.parentID = rootFolder;
folder.agentID = user;
folder.folderID = LLUUID.Random();
folder.name = "Sounds";
folder.type = 1;
folder.version = 1;
Folders.Add(folder.folderID, folder);
folder = new InventoryFolderBase();
folder.parentID = rootFolder;
folder.agentID = user;
folder.folderID = LLUUID.Random();
folder.name = "Textures";
folder.type = 0;
folder.version = 1;
Folders.Add(folder.folderID, folder);
folder = new InventoryFolderBase();
folder.parentID = rootFolder;
folder.agentID = user;
folder.folderID = LLUUID.Random();
folder.name = "Trash";
folder.type = 14;
folder.version = 1;
Folders.Add(folder.folderID, folder);
}
}
public abstract void RequestInventoryForUser(LLUUID userID, InventoryFolderInfo folderCallBack,
InventoryItemInfo itemCallBack);
public abstract void AddNewInventoryFolder(LLUUID userID, InventoryFolderBase folder);
public abstract void MoveExistingInventoryFolder(InventoryFolderBase folder);
public abstract void AddNewInventoryItem(LLUUID userID, InventoryItemBase item);
public abstract void DeleteInventoryItem(LLUUID userID, InventoryItemBase item);
}
}

View File

@ -0,0 +1,768 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS 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 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;
using System.Collections.Generic;
using libsecondlife;
using libsecondlife.StructuredData;
using Nwc.XmlRpc;
using OpenSim.Framework.Console;
namespace OpenSim.Framework.UserManagement
{
/// <summary>
/// A temp class to handle login response.
/// Should make use of UserProfileManager where possible.
/// </summary>
public class LoginResponse
{
private Hashtable loginFlagsHash;
private Hashtable globalTexturesHash;
private Hashtable loginError;
private Hashtable uiConfigHash;
private ArrayList loginFlags;
private ArrayList globalTextures;
private ArrayList eventCategories;
private ArrayList uiConfig;
private ArrayList classifiedCategories;
private ArrayList inventoryRoot;
private ArrayList initialOutfit;
private ArrayList agentInventory;
private ArrayList inventoryLibraryOwner;
private ArrayList inventoryLibRoot;
private ArrayList inventoryLibrary;
private UserInfo userProfile;
private LLUUID agentID;
private LLUUID sessionID;
private LLUUID secureSessionID;
// Login Flags
private string dst;
private string stipendSinceLogin;
private string gendered;
private string everLoggedIn;
private string login;
private uint simPort;
private string simAddress;
private string agentAccess;
private Int32 circuitCode;
private uint regionX;
private uint regionY;
// Login
private string firstname;
private string lastname;
// REX (client version string)
private string clientVersion = "not set";
// Global Textures
private string sunTexture;
private string cloudTexture;
private string moonTexture;
// Error Flags
private string errorReason;
private string errorMessage;
// Response
private XmlRpcResponse xmlRpcResponse;
private XmlRpcResponse defaultXmlRpcResponse;
private string welcomeMessage;
private string startLocation;
private string allowFirstLife;
private string home;
private string seedCapability;
private string lookAt;
private BuddyList m_buddyList = null;
public LoginResponse()
{
loginFlags = new ArrayList();
globalTextures = new ArrayList();
eventCategories = new ArrayList();
uiConfig = new ArrayList();
classifiedCategories = new ArrayList();
loginError = new Hashtable();
uiConfigHash = new Hashtable();
defaultXmlRpcResponse = new XmlRpcResponse();
userProfile = new UserInfo();
inventoryRoot = new ArrayList();
initialOutfit = new ArrayList();
agentInventory = new ArrayList();
inventoryLibrary = new ArrayList();
inventoryLibraryOwner = new ArrayList();
xmlRpcResponse = new XmlRpcResponse();
defaultXmlRpcResponse = new XmlRpcResponse();
SetDefaultValues();
} // LoginServer
public void SetDefaultValues()
{
DST = "N";
StipendSinceLogin = "N";
Gendered = "Y";
EverLoggedIn = "Y";
login = "false";
firstname = "Test";
lastname = "User";
agentAccess = "M";
startLocation = "last";
allowFirstLife = "Y";
SunTexture = "cce0f112-878f-4586-a2e2-a8f104bba271";
CloudTexture = "dc4b9f0b-d008-45c6-96a4-01dd947ac621";
MoonTexture = "ec4b9f0b-d008-45c6-96a4-01dd947ac621";
ErrorMessage = "You have entered an invalid name/password combination. Check Caps/lock.";
ErrorReason = "key";
welcomeMessage = "Welcome to OpenSim!";
seedCapability = "";
home = "{'region_handle':[r" + (1000*256).ToString() + ",r" + (1000*256).ToString() + "], 'position':[r" +
userProfile.homepos.X.ToString() + ",r" + userProfile.homepos.Y.ToString() + ",r" +
userProfile.homepos.Z.ToString() + "], 'look_at':[r" + userProfile.homelookat.X.ToString() + ",r" +
userProfile.homelookat.Y.ToString() + ",r" + userProfile.homelookat.Z.ToString() + "]}";
lookAt = "[r0.99949799999999999756,r0.03166859999999999814,r0]";
RegionX = (uint) 255232;
RegionY = (uint) 254976;
clientVersion = "not set"; //rex
// Classifieds;
AddClassifiedCategory((Int32) 1, "Shopping");
AddClassifiedCategory((Int32) 2, "Land Rental");
AddClassifiedCategory((Int32) 3, "Property Rental");
AddClassifiedCategory((Int32) 4, "Special Attraction");
AddClassifiedCategory((Int32) 5, "New Products");
AddClassifiedCategory((Int32) 6, "Employment");
AddClassifiedCategory((Int32) 7, "Wanted");
AddClassifiedCategory((Int32) 8, "Service");
AddClassifiedCategory((Int32) 9, "Personal");
SessionID = LLUUID.Random();
SecureSessionID = LLUUID.Random();
AgentID = LLUUID.Random();
Hashtable InitialOutfitHash = new Hashtable();
InitialOutfitHash["folder_name"] = "Nightclub Female";
InitialOutfitHash["gender"] = "female";
initialOutfit.Add(InitialOutfitHash);
} // SetDefaultValues
#region Login Failure Methods
public XmlRpcResponse GenerateFailureResponse(string reason, string message, string login)
{
// Overwrite any default values;
xmlRpcResponse = new XmlRpcResponse();
// Ensure Login Failed message/reason;
ErrorMessage = message;
ErrorReason = reason;
loginError["reason"] = ErrorReason;
loginError["message"] = ErrorMessage;
loginError["login"] = login;
xmlRpcResponse.Value = loginError;
return (xmlRpcResponse);
} // GenerateResponse
public LLSD GenerateFailureResponseLLSD(string reason, string message, string login)
{
LLSDMap map = new LLSDMap();
// Ensure Login Failed message/reason;
ErrorMessage = message;
ErrorReason = reason;
map["reason"] = LLSD.FromString(ErrorReason);
map["message"] = LLSD.FromString(ErrorMessage);
map["login"] = LLSD.FromString(login);
return map;
}
public XmlRpcResponse CreateFailedResponse()
{
return (CreateLoginFailedResponse());
} // CreateErrorConnectingToGridResponse()
public LLSD CreateFailedResponseLLSD()
{
return CreateLoginFailedResponseLLSD();
}
public XmlRpcResponse CreateLoginFailedResponse()
{
return
(GenerateFailureResponse("key",
"Could not authenticate your avatar. Please check your username and password, and check the grid if problems persist.",
"false"));
} // LoginFailedResponse
public LLSD CreateLoginFailedResponseLLSD()
{
return GenerateFailureResponseLLSD(
"key",
"Could not authenticate your avatar. Please check your username and password, and check the grid if problems persist.",
"false");
}
public XmlRpcResponse CreateAlreadyLoggedInResponse()
{
return
(GenerateFailureResponse("presence",
"You appear to be already logged in, if this is not the case please wait for your session to timeout, if this takes longer than a few minutes please contact the grid owner",
"false"));
} // CreateAlreadyLoggedInResponse()
public LLSD CreateAlreadyLoggedInResponseLLSD()
{
return GenerateFailureResponseLLSD(
"presence",
"You appear to be already logged in, if this is not the case please wait for your session to timeout, if this takes longer than a few minutes please contact the grid owner",
"false");
}
public XmlRpcResponse CreateDeadRegionResponse()
{
return
(GenerateFailureResponse("key",
"The region you are attempting to log into is not responding. Please select another region and try again.",
"false"));
}
public LLSD CreateDeadRegionResponseLLSD()
{
return GenerateFailureResponseLLSD(
"key",
"The region you are attempting to log into is not responding. Please select another region and try again.",
"false");
}
public XmlRpcResponse CreateGridErrorResponse()
{
return
(GenerateFailureResponse("key",
"Error connecting to grid. Could not percieve credentials from login XML.",
"false"));
}
public LLSD CreateGridErrorResponseLLSD()
{
return GenerateFailureResponseLLSD(
"key",
"Error connecting to grid. Could not percieve credentials from login XML.",
"false");
}
#endregion
public XmlRpcResponse ToXmlRpcResponse()
{
try
{
Hashtable responseData = new Hashtable();
loginFlagsHash = new Hashtable();
loginFlagsHash["daylight_savings"] = DST;
loginFlagsHash["stipend_since_login"] = StipendSinceLogin;
loginFlagsHash["gendered"] = Gendered;
loginFlagsHash["ever_logged_in"] = EverLoggedIn;
loginFlags.Add(loginFlagsHash);
responseData["first_name"] = Firstname;
responseData["last_name"] = Lastname;
responseData["agent_access"] = agentAccess;
globalTexturesHash = new Hashtable();
globalTexturesHash["sun_texture_id"] = SunTexture;
globalTexturesHash["cloud_texture_id"] = CloudTexture;
globalTexturesHash["moon_texture_id"] = MoonTexture;
globalTextures.Add(globalTexturesHash);
// this.eventCategories.Add(this.eventCategoriesHash);
AddToUIConfig("allow_first_life", allowFirstLife);
uiConfig.Add(uiConfigHash);
responseData["sim_port"] = (Int32) SimPort;
responseData["sim_ip"] = SimAddress;
responseData["agent_id"] = AgentID.ToString();
responseData["session_id"] = SessionID.ToString();
responseData["secure_session_id"] = SecureSessionID.ToString();
responseData["circuit_code"] = CircuitCode;
responseData["seconds_since_epoch"] = (Int32) (DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
responseData["login-flags"] = loginFlags;
responseData["global-textures"] = globalTextures;
responseData["seed_capability"] = seedCapability;
responseData["event_categories"] = eventCategories;
responseData["event_notifications"] = new ArrayList(); // todo
responseData["classified_categories"] = classifiedCategories;
responseData["ui-config"] = uiConfig;
responseData["inventory-skeleton"] = agentInventory;
responseData["inventory-skel-lib"] = inventoryLibrary;
responseData["inventory-root"] = inventoryRoot;
responseData["inventory-lib-root"] = inventoryLibRoot;
responseData["gestures"] = new ArrayList(); // todo
responseData["inventory-lib-owner"] = inventoryLibraryOwner;
responseData["initial-outfit"] = initialOutfit;
responseData["start_location"] = startLocation;
responseData["seed_capability"] = seedCapability;
responseData["home"] = home;
responseData["look_at"] = lookAt;
responseData["message"] = welcomeMessage;
responseData["region_x"] = (Int32) RegionX*256;
responseData["region_y"] = (Int32) RegionY*256;
responseData["version"] = clientVersion; //rex
//responseData["inventory-lib-root"] = new ArrayList(); // todo
if (m_buddyList != null)
{
responseData["buddy-list"] = m_buddyList.ToArray();
}
responseData["login"] = "true";
xmlRpcResponse.Value = responseData;
return (xmlRpcResponse);
}
catch (Exception e)
{
MainLog.Instance.Warn(
"CLIENT",
"LoginResponse: Error creating XML-RPC Response: " + e.Message
);
return (GenerateFailureResponse("Internal Error", "Error generating Login Response", "false"));
}
} // ToXmlRpcResponse
public LLSD ToLLSDResponse()
{
try
{
LLSDMap map = new LLSDMap();
map["first_name"] = LLSD.FromString(Firstname);
map["last_name"] = LLSD.FromString(Lastname);
map["agent_access"] = LLSD.FromString(agentAccess);
map["sim_port"] = LLSD.FromInteger(SimPort);
map["sim_ip"] = LLSD.FromString(SimAddress);
map["agent_id"] = LLSD.FromUUID(AgentID);
map["session_id"] = LLSD.FromUUID(SessionID);
map["secure_session_id"] = LLSD.FromUUID(SecureSessionID);
map["circuit_code"] = LLSD.FromInteger(CircuitCode);
map["seconds_since_epoch"] = LLSD.FromInteger((int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds);
#region Login Flags
LLSDMap loginFlagsLLSD = new LLSDMap();
loginFlagsLLSD["daylight_savings"] = LLSD.FromString(DST);
loginFlagsLLSD["stipend_since_login"] = LLSD.FromString(StipendSinceLogin);
loginFlagsLLSD["gendered"] = LLSD.FromString(Gendered);
loginFlagsLLSD["ever_logged_in"] = LLSD.FromString(EverLoggedIn);
map["login-flags"] = WrapLLSDMap(loginFlagsLLSD);
#endregion Login Flags
#region Global Textures
LLSDMap globalTexturesLLSD = new LLSDMap();
globalTexturesLLSD["sun_texture_id"] = LLSD.FromString(SunTexture);
globalTexturesLLSD["cloud_texture_id"] = LLSD.FromString(CloudTexture);
globalTexturesLLSD["moon_texture_id"] = LLSD.FromString(MoonTexture);
map["global-textures"] = WrapLLSDMap(globalTexturesLLSD);
#endregion Global Textures
map["seed_capability"] = LLSD.FromString(seedCapability);
// FIXME: Need a function that will convert these ArrayLists in to LLSDArrays,
// and convert the data inside them to LLSD objects as well
//map["event_categories"] = eventCategories;
//map["event_notifications"] = new LLSDArray(); // todo
//map["classified_categories"] = classifiedCategories;
#region UI Config
LLSDMap uiConfigLLSD = new LLSDMap();
uiConfigLLSD["allow_first_life"] = LLSD.FromString(allowFirstLife);
map["ui-config"] = WrapLLSDMap(uiConfigLLSD);
#endregion UI Config
#region Inventory
//map["inventory-skeleton"] = agentInventory;
//map["inventory-skel-lib"] = inventoryLibrary;
//map["inventory-root"] = inventoryRoot;
//map["inventory-lib-root"] = inventoryLibRoot;
//map["inventory-lib-owner"] = inventoryLibraryOwner;
#endregion Inventory
map["gestures"] = new LLSDArray(); // todo
//responseData["initial-outfit"] = initialOutfit;
//responseData["start_location"] = startLocation;
map["seed_capability"] = LLSD.FromString(seedCapability);
map["home"] = LLSD.FromString(home);
map["look_at"] = LLSD.FromString(lookAt);
map["message"] = LLSD.FromString(welcomeMessage);
map["region_x"] = LLSD.FromInteger(RegionX * 256);
map["region_y"] = LLSD.FromInteger(RegionY * 256);
map["version"] = LLSD.FromString(clientVersion); //rex
if (m_buddyList != null)
{
//map["buddy-list"] = m_buddyList.ToArray();
}
map["login"] = LLSD.FromString("true");
return map;
}
catch (Exception e)
{
MainLog.Instance.Warn(
"CLIENT",
"LoginResponse: Error creating XML-RPC Response: " + e.Message
);
return GenerateFailureResponseLLSD("Internal Error", "Error generating Login Response", "false");
}
}
private LLSDArray WrapLLSDMap(LLSDMap wrapMe)
{
LLSDArray array = new LLSDArray();
array.Add(wrapMe);
return array;
}
public void SetEventCategories(string category, string value)
{
// this.eventCategoriesHash[category] = value;
//TODO
} // SetEventCategories
public void AddToUIConfig(string itemName, string item)
{
uiConfigHash[itemName] = item;
} // SetUIConfig
public void AddClassifiedCategory(Int32 ID, string categoryName)
{
Hashtable hash = new Hashtable();
hash["category_name"] = categoryName;
hash["category_id"] = ID;
classifiedCategories.Add(hash);
// this.classifiedCategoriesHash.Clear();
} // SetClassifiedCategory
#region Properties
public string Login
{
get { return login; }
set { login = value; }
} // Login
public string DST
{
get { return dst; }
set { dst = value; }
} // DST
public string StipendSinceLogin
{
get { return stipendSinceLogin; }
set { stipendSinceLogin = value; }
} // StipendSinceLogin
public string Gendered
{
get { return gendered; }
set { gendered = value; }
} // Gendered
public string EverLoggedIn
{
get { return everLoggedIn; }
set { everLoggedIn = value; }
} // EverLoggedIn
public uint SimPort
{
get { return simPort; }
set { simPort = value; }
} // SimPort
public string SimAddress
{
get { return simAddress; }
set { simAddress = value; }
} // SimAddress
public LLUUID AgentID
{
get { return agentID; }
set { agentID = value; }
} // AgentID
public LLUUID SessionID
{
get { return sessionID; }
set { sessionID = value; }
} // SessionID
public LLUUID SecureSessionID
{
get { return secureSessionID; }
set { secureSessionID = value; }
} // SecureSessionID
public Int32 CircuitCode
{
get { return circuitCode; }
set { circuitCode = value; }
} // CircuitCode
public uint RegionX
{
get { return regionX; }
set { regionX = value; }
} // RegionX
public uint RegionY
{
get { return regionY; }
set { regionY = value; }
} // RegionY
public string SunTexture
{
get { return sunTexture; }
set { sunTexture = value; }
} // SunTexture
public string CloudTexture
{
get { return cloudTexture; }
set { cloudTexture = value; }
} // CloudTexture
public string MoonTexture
{
get { return moonTexture; }
set { moonTexture = value; }
} // MoonTexture
public string Firstname
{
get { return firstname; }
set { firstname = value; }
} // Firstname
public string Lastname
{
get { return lastname; }
set { lastname = value; }
} // Lastname
public string ClientVersion
{
get { return clientVersion; }
set { clientVersion = value; }
} //REX ClientVersion
public string AgentAccess
{
get { return agentAccess; }
set { agentAccess = value; }
}
public string StartLocation
{
get { return startLocation; }
set { startLocation = value; }
} // StartLocation
public string LookAt
{
get { return lookAt; }
set { lookAt = value; }
}
public string SeedCapability
{
get { return seedCapability; }
set { seedCapability = value; }
} // SeedCapability
public string ErrorReason
{
get { return errorReason; }
set { errorReason = value; }
} // ErrorReason
public string ErrorMessage
{
get { return errorMessage; }
set { errorMessage = value; }
} // ErrorMessage
public ArrayList InventoryRoot
{
get { return inventoryRoot; }
set { inventoryRoot = value; }
}
public ArrayList InventorySkeleton
{
get { return agentInventory; }
set { agentInventory = value; }
}
public ArrayList InventoryLibrary
{
get { return inventoryLibrary; }
set { inventoryLibrary = value; }
}
public ArrayList InventoryLibraryOwner
{
get { return inventoryLibraryOwner; }
set { inventoryLibraryOwner = value; }
}
public ArrayList InventoryLibRoot
{
get { return inventoryLibRoot; }
set { inventoryLibRoot = value; }
}
public string Home
{
get { return home; }
set { home = value; }
}
public string Message
{
get { return welcomeMessage; }
set { welcomeMessage = value; }
}
public BuddyList BuddList
{
get { return m_buddyList; }
set { m_buddyList = value; }
}
#endregion
public class UserInfo
{
public string firstname;
public string lastname;
public ulong homeregionhandle;
public LLVector3 homepos;
public LLVector3 homelookat;
}
public class BuddyList
{
public List<BuddyInfo> Buddies = new List<BuddyInfo>();
public void AddNewBuddy(BuddyInfo buddy)
{
if (!Buddies.Contains(buddy))
{
Buddies.Add(buddy);
}
}
public ArrayList ToArray()
{
ArrayList buddyArray = new ArrayList();
foreach (BuddyInfo buddy in Buddies)
{
buddyArray.Add(buddy.ToHashTable());
}
return buddyArray;
}
public class BuddyInfo
{
public int BuddyRightsHave = 1;
public int BuddyRightsGiven = 1;
public LLUUID BuddyID;
public BuddyInfo(string buddyID)
{
BuddyID = new LLUUID(buddyID);
}
public BuddyInfo(LLUUID buddyID)
{
BuddyID = buddyID;
}
public Hashtable ToHashTable()
{
Hashtable hTable = new Hashtable();
hTable["buddy_rights_has"] = BuddyRightsHave;
hTable["buddy_rights_given"] = BuddyRightsGiven;
hTable["buddy_id"] = BuddyID.ToString();
return hTable;
}
}
}
}
}

View File

@ -0,0 +1,620 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS 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 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;
using System.Collections.Generic;
using System.Threading;
using libsecondlife;
using libsecondlife.StructuredData;
using Nwc.XmlRpc;
using OpenSim.Framework.Communications.Cache;
using OpenSim.Framework.Console;
namespace OpenSim.Framework.UserManagement
{
public class LoginService
{
protected string m_welcomeMessage = "Welcome to OpenSim";
protected UserManagerBase m_userManager = null;
protected Mutex m_loginMutex = new Mutex(false);
protected Boolean m_rexMode;
protected RexLoginHandler m_rexLoginHandler;
/// <summary>
/// Used during login to send the skeleton of the OpenSim Library to the client.
/// </summary>
protected LibraryRootFolder m_libraryRootFolder;
public LoginService(
UserManagerBase userManager, LibraryRootFolder libraryRootFolder, string welcomeMess, Boolean rexMode)
{
m_userManager = userManager;
m_libraryRootFolder = libraryRootFolder;
m_rexMode = rexMode;
m_userManager.RexMode = rexMode;
if (m_rexMode)
m_rexLoginHandler = new RexLoginHandler(this, m_userManager);
if (welcomeMess != "")
{
m_welcomeMessage = welcomeMess;
}
}
/// <summary>
/// Main user login function
/// </summary>
/// <param name="request">The XMLRPC request</param>
/// <returns>The response to send</returns>
public XmlRpcResponse XmlRpcLoginMethod(XmlRpcRequest request)
{
// Temporary fix
m_loginMutex.WaitOne();
try
{
if (!m_rexMode)
{
//CFK: CustomizeResponse contains sufficient strings to alleviate the need for this.
//CKF: MainLog.Instance.Verbose("LOGIN", "Attempting login now...");
XmlRpcResponse response = new XmlRpcResponse();
Hashtable requestData = (Hashtable) request.Params[0];
bool GoodXML = (requestData.Contains("first") && requestData.Contains("last") &&
requestData.Contains("passwd"));
bool GoodLogin = false;
UserProfileData userProfile;
LoginResponse logResponse = new LoginResponse();
if (GoodXML)
{
string firstname = (string) requestData["first"];
string lastname = (string) requestData["last"];
string passwd = (string) requestData["passwd"];
userProfile = GetTheUser(firstname, lastname, "");
if (userProfile == null)
{
MainLog.Instance.Verbose(
"LOGIN",
"Could not find a profile for " + firstname + " " + lastname);
return logResponse.CreateLoginFailedResponse();
}
GoodLogin = AuthenticateUser(userProfile, passwd);
}
else
{
return logResponse.CreateGridErrorResponse();
}
if (!GoodLogin)
{
return logResponse.CreateLoginFailedResponse();
}
else
{
// If we already have a session...
if (userProfile.currentAgent != null && userProfile.currentAgent.agentOnline)
{
userProfile.currentAgent = null;
m_userManager.CommitAgent(ref userProfile);
// Reject the login
return logResponse.CreateAlreadyLoggedInResponse();
}
// Otherwise...
// Create a new agent session
CreateAgent(userProfile, request);
try
{
LLUUID agentID = userProfile.UUID;
// Inventory Library Section
InventoryData inventData = CreateInventoryData(agentID);
ArrayList AgentInventoryArray = inventData.InventoryArray;
Hashtable InventoryRootHash = new Hashtable();
InventoryRootHash["folder_id"] = inventData.RootFolderID.ToString();
ArrayList InventoryRoot = new ArrayList();
InventoryRoot.Add(InventoryRootHash);
userProfile.rootInventoryFolderID = inventData.RootFolderID;
// Circuit Code
uint circode = (uint) (Util.RandomClass.Next());
//REX: Get client version
if (requestData.ContainsKey("version"))
{
logResponse.ClientVersion = (string)requestData["version"];
}
logResponse.Lastname = userProfile.surname;
logResponse.Firstname = userProfile.username;
logResponse.AgentID = agentID.ToString();
logResponse.SessionID = userProfile.currentAgent.sessionID.ToString();
logResponse.SecureSessionID = userProfile.currentAgent.secureSessionID.ToString();
logResponse.InventoryRoot = InventoryRoot;
logResponse.InventorySkeleton = AgentInventoryArray;
logResponse.InventoryLibrary = GetInventoryLibrary();
Hashtable InventoryLibRootHash = new Hashtable();
InventoryLibRootHash["folder_id"] = "00000112-000f-0000-0000-000100bba000";
ArrayList InventoryLibRoot = new ArrayList();
InventoryLibRoot.Add(InventoryLibRootHash);
logResponse.InventoryLibRoot = InventoryLibRoot;
logResponse.InventoryLibraryOwner = GetLibraryOwner();
logResponse.CircuitCode = (Int32) circode;
//logResponse.RegionX = 0; //overwritten
//logResponse.RegionY = 0; //overwritten
logResponse.Home = "!!null temporary value {home}!!"; // Overwritten
//logResponse.LookAt = "\n[r" + TheUser.homeLookAt.X.ToString() + ",r" + TheUser.homeLookAt.Y.ToString() + ",r" + TheUser.homeLookAt.Z.ToString() + "]\n";
//logResponse.SimAddress = "127.0.0.1"; //overwritten
//logResponse.SimPort = 0; //overwritten
logResponse.Message = GetMessage();
logResponse.BuddList = ConvertFriendListItem(m_userManager.GetUserFriendList(agentID));
try
{
CustomiseResponse(logResponse, userProfile, null);
}
catch (Exception e)
{
MainLog.Instance.Verbose("LOGIN", e.ToString());
return logResponse.CreateDeadRegionResponse();
//return logResponse.ToXmlRpcResponse();
}
CommitAgent(ref userProfile);
return logResponse.ToXmlRpcResponse();
}
catch (Exception E)
{
MainLog.Instance.Verbose("LOGIN", E.ToString());
}
//}
}
return response;
}
else
{
return m_rexLoginHandler.XmlRpcLoginMethod(request);
}
}
finally
{
m_loginMutex.ReleaseMutex();
}
}
public LLSD LLSDLoginMethod(LLSD request)
{
// Temporary fix
m_loginMutex.WaitOne();
try
{
if (!m_rexMode)
{
bool GoodLogin = false;
string clientVersion = "not set"; //rex
UserProfileData userProfile = null;
LoginResponse logResponse = new LoginResponse();
if (request.Type == LLSDType.Map)
{
LLSDMap map = (LLSDMap)request;
if (map.ContainsKey("first") && map.ContainsKey("last") && map.ContainsKey("passwd"))
{
string firstname = map["first"].AsString();
string lastname = map["last"].AsString();
string passwd = map["passwd"].AsString();
//REX: Client version
if (map.ContainsKey("version"))
{
clientVersion = map["version"].AsString();
}
userProfile = GetTheUser(firstname, lastname, "");
if (userProfile == null)
{
MainLog.Instance.Verbose(
"LOGIN",
"Could not find a profile for " + firstname + " " + lastname);
return logResponse.CreateLoginFailedResponseLLSD();
}
GoodLogin = AuthenticateUser(userProfile, passwd);
}
}
if (!GoodLogin)
{
return logResponse.CreateLoginFailedResponseLLSD();
}
else
{
// If we already have a session...
if (userProfile.currentAgent != null && userProfile.currentAgent.agentOnline)
{
userProfile.currentAgent = null;
m_userManager.CommitAgent(ref userProfile);
// Reject the login
return logResponse.CreateAlreadyLoggedInResponseLLSD();
}
// Otherwise...
// Create a new agent session
CreateAgent(userProfile, request);
try
{
LLUUID agentID = userProfile.UUID;
// Inventory Library Section
InventoryData inventData = CreateInventoryData(agentID);
ArrayList AgentInventoryArray = inventData.InventoryArray;
Hashtable InventoryRootHash = new Hashtable();
InventoryRootHash["folder_id"] = inventData.RootFolderID.ToString();
ArrayList InventoryRoot = new ArrayList();
InventoryRoot.Add(InventoryRootHash);
userProfile.rootInventoryFolderID = inventData.RootFolderID;
// Circuit Code
uint circode = (uint)(Util.RandomClass.Next());
// REX: Set client version
logResponse.ClientVersion = clientVersion;
logResponse.Lastname = userProfile.surname;
logResponse.Firstname = userProfile.username;
logResponse.AgentID = agentID.ToString();
logResponse.SessionID = userProfile.currentAgent.sessionID.ToString();
logResponse.SecureSessionID = userProfile.currentAgent.secureSessionID.ToString();
logResponse.InventoryRoot = InventoryRoot;
logResponse.InventorySkeleton = AgentInventoryArray;
logResponse.InventoryLibrary = GetInventoryLibrary();
Hashtable InventoryLibRootHash = new Hashtable();
InventoryLibRootHash["folder_id"] = "00000112-000f-0000-0000-000100bba000";
ArrayList InventoryLibRoot = new ArrayList();
InventoryLibRoot.Add(InventoryLibRootHash);
logResponse.InventoryLibRoot = InventoryLibRoot;
logResponse.InventoryLibraryOwner = GetLibraryOwner();
logResponse.CircuitCode = (Int32)circode;
//logResponse.RegionX = 0; //overwritten
//logResponse.RegionY = 0; //overwritten
logResponse.Home = "!!null temporary value {home}!!"; // Overwritten
//logResponse.LookAt = "\n[r" + TheUser.homeLookAt.X.ToString() + ",r" + TheUser.homeLookAt.Y.ToString() + ",r" + TheUser.homeLookAt.Z.ToString() + "]\n";
//logResponse.SimAddress = "127.0.0.1"; //overwritten
//logResponse.SimPort = 0; //overwritten
logResponse.Message = GetMessage();
logResponse.BuddList = ConvertFriendListItem(m_userManager.GetUserFriendList(agentID));
try
{
CustomiseResponse(logResponse, userProfile, null);
}
catch (Exception ex)
{
MainLog.Instance.Verbose("LOGIN", ex.ToString());
return logResponse.CreateDeadRegionResponseLLSD();
}
CommitAgent(ref userProfile);
return logResponse.ToLLSDResponse();
}
catch (Exception ex)
{
MainLog.Instance.Verbose("LOGIN", ex.ToString());
return logResponse.CreateFailedResponseLLSD();
}
}
}
else
{
return m_rexLoginHandler.LLSDLoginMethod(request);
}
}
finally
{
m_loginMutex.ReleaseMutex();
}
}
/*
/// <summary>
/// Remove agent
/// </summary>
/// <param name="request">The XMLRPC request</param>
/// <returns>The response to send</returns>
public XmlRpcResponse XmlRpcRemoveAgentMethod(XmlRpcRequest request)
{
// Temporary fix
m_loginMutex.WaitOne();
try
{
MainLog.Instance.Verbose("REMOVE AGENT", "Attempting to remove agent...");
XmlRpcResponse response = new XmlRpcResponse();
Hashtable requestData = (Hashtable)request.Params[0];
bool parametersValid = (requestData.Contains("agentID"));
UserProfileData user;
LoginResponse logResponse = new LoginResponse();
if (parametersValid)
{
string agentID = (string)requestData["agentID"];
user = GetTheUser((libsecondlife.LLUUID)agentID);
if (user == null)
{
MainLog.Instance.Verbose("REMOVE AGENT", "Failed. UserProfile not found.");
return logResponse.CreateAgentRemoveFailedResponse();
}
if (user != null)
{
ClearUserAgent(ref user, user.authenticationAddr);
MainLog.Instance.Verbose("REMOVE AGENT", "Success. Agent removed from database. UUID = " + user.UUID);
return logResponse.GenerateAgentRemoveSuccessResponse();
}
}
MainLog.Instance.Verbose("REMOVE AGENT", "Failed. Parameters invalid.");
return logResponse.CreateAgentRemoveFailedResponse();
}
finally
{
m_loginMutex.ReleaseMutex();
}
return null;
}//*/
public void ClearUserAgent(ref UserProfileData profile, string authAddr)
{
m_userManager.clearUserAgent(profile.UUID, authAddr);
}
/// <summary>
/// Customises the login response and fills in missing values.
/// </summary>
/// <param name="response">The existing response</param>
/// <param name="theUser">The user profile</param>
public virtual void CustomiseResponse(LoginResponse response, UserProfileData theUser, string ASaddress)
{
}
/// <summary>
/// Saves a target agent to the database
/// </summary>
/// <param name="profile">The users profile</param>
/// <returns>Successful?</returns>
public void UpdateAgent(UserAgentData agent, string authAddr)
{
// Saves the agent to database
//return true;
m_userManager.UpdateUserAgentData(agent.UUID, agent.agentOnline, agent.currentPos, agent.logoutTime, authAddr);
}
/// <summary>
/// Saves a target agent to the database
/// </summary>
/// <param name="profile">The users profile</param>
/// <returns>Successful?</returns>
public bool CommitAgent(ref UserProfileData profile)
{
return m_userManager.CommitAgent(ref profile);
}
/// <summary>
/// Checks a user against it's password hash
/// </summary>
/// <param name="profile">The users profile</param>
/// <param name="password">The supplied password</param>
/// <returns>Authenticated?</returns>
public virtual bool AuthenticateUser(UserProfileData profile, string password)
{
MainLog.Instance.Verbose(
"LOGIN", "Authenticating {0} {1} ({2})", profile.username, profile.surname, profile.UUID);
password = password.Remove(0, 3); //remove $1$
string s = Util.Md5Hash(password + ":" + profile.passwordSalt);
return profile.passwordHash.Equals(s.ToString(), StringComparison.InvariantCultureIgnoreCase);
}
/// <summary>
///
/// </summary>
/// <param name="profile"></param>
/// <param name="request"></param>
public void CreateAgent(UserProfileData profile, XmlRpcRequest request)
{
m_userManager.CreateAgent(profile, request);
}
public void CreateAgent(UserProfileData profile, LLSD request)
{
m_userManager.CreateAgent(profile, request);
}
/// <summary>
///
/// </summary>
/// <param name="firstname"></param>
/// <param name="lastname"></param>
/// <returns></returns>
public virtual UserProfileData GetTheUser(string firstname, string lastname, string authAddr)
{
return m_userManager.GetUserProfile(firstname, lastname, authAddr);
}
/// <summary>
/// Get user according to uid
/// </summary>
/// <param name="userUID"></param>
/// <returns></returns>
public virtual UserProfileData GetTheUser(LLUUID userUID)
{
return this.m_userManager.GetUserProfile(userUID, "");
}
/// <summary>
/// Get user according to account
/// </summary>
/// <param name="account"></param>
/// <returns></returns>
public virtual UserProfileData GetTheUserByAccount(string account)
{
return this.m_userManager.GetUserProfileByAccount(account);
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public virtual string GetMessage()
{
return m_welcomeMessage;
}
private LoginResponse.BuddyList ConvertFriendListItem(List<FriendListItem> LFL)
{
LoginResponse.BuddyList buddylistreturn = new LoginResponse.BuddyList();
foreach (FriendListItem fl in LFL)
{
LoginResponse.BuddyList.BuddyInfo buddyitem = new LoginResponse.BuddyList.BuddyInfo(fl.Friend);
buddyitem.BuddyID = fl.Friend;
buddyitem.BuddyRightsHave = (int)fl.FriendListOwnerPerms;
buddyitem.BuddyRightsGiven = (int) fl.FriendPerms;
buddylistreturn.AddNewBuddy(buddyitem);
}
return buddylistreturn;
}
/// <summary>
/// Converts the inventory library skeleton into the form required by the rpc request.
/// </summary>
/// <returns></returns>
protected internal virtual ArrayList GetInventoryLibrary()
{
Dictionary<LLUUID, InventoryFolderImpl> rootFolders
= m_libraryRootFolder.RequestSelfAndDescendentFolders();
ArrayList folderHashes = new ArrayList();
foreach (InventoryFolderBase folder in rootFolders.Values)
{
Hashtable TempHash = new Hashtable();
TempHash["name"] = folder.name;
TempHash["parent_id"] = folder.parentID.ToString();
TempHash["version"] = (Int32)folder.version;
TempHash["type_default"] = (Int32)folder.type;
TempHash["folder_id"] = folder.folderID.ToString();
folderHashes.Add(TempHash);
}
return folderHashes;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
protected internal virtual ArrayList GetLibraryOwner()
{
//for now create random inventory library owner
Hashtable TempHash = new Hashtable();
TempHash["agent_id"] = "11111111-1111-0000-0000-000100bba000";
ArrayList inventoryLibOwner = new ArrayList();
inventoryLibOwner.Add(TempHash);
return inventoryLibOwner;
}
protected internal virtual InventoryData CreateInventoryData(LLUUID userID)
{
AgentInventory userInventory = new AgentInventory();
userInventory.CreateRootFolder(userID, false);
ArrayList AgentInventoryArray = new ArrayList();
Hashtable TempHash;
foreach (InventoryFolder InvFolder in userInventory.InventoryFolders.Values)
{
TempHash = new Hashtable();
TempHash["name"] = InvFolder.FolderName;
TempHash["parent_id"] = InvFolder.ParentID.ToString();
TempHash["version"] = (Int32) InvFolder.Version;
TempHash["type_default"] = (Int32) InvFolder.DefaultType;
TempHash["folder_id"] = InvFolder.FolderID.ToString();
AgentInventoryArray.Add(TempHash);
}
return new InventoryData(AgentInventoryArray, userInventory.InventoryRoot.FolderID);
}
public class InventoryData
{
public ArrayList InventoryArray = null;
public LLUUID RootFolderID = LLUUID.Zero;
public InventoryData(ArrayList invList, LLUUID rootID)
{
InventoryArray = invList;
RootFolderID = rootID;
}
}
}
}

View File

@ -0,0 +1,65 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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.Reflection;
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("OpenGrid.Framework.Communications")]
[assembly : AssemblyDescription("")]
[assembly : AssemblyConfiguration("")]
[assembly : AssemblyCompany("")]
[assembly : AssemblyProduct("OpenGrid.Framework.Communications")]
[assembly : AssemblyCopyright("Copyright © 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("13e7c396-78a9-4a5c-baf2-6f980ea75d95")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly : AssemblyVersion("1.0.0.0")]
[assembly : AssemblyFileVersion("1.0.0.0")]

View File

@ -0,0 +1,186 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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.Threading;
namespace OpenSim.Framework.Communications
{
internal class SimpleAsyncResult : IAsyncResult
{
private readonly AsyncCallback m_callback;
/// <summary>
/// Is process completed?
/// </summary>
/// <remarks>Should really be boolean, but VolatileRead has no boolean method</remarks>
private byte m_completed;
/// <summary>
/// Did process complete synchroneously?
/// </summary>
/// <remarks>I have a hard time imagining a scenario where this is the case, again, same issue about
/// booleans and VolatileRead as m_completed
/// </remarks>
private byte m_completedSynchronously;
private readonly object m_asyncState;
private ManualResetEvent m_waitHandle;
private Exception m_exception;
internal SimpleAsyncResult(AsyncCallback cb, object state)
{
m_callback = cb;
m_asyncState = state;
m_completed = 0;
m_completedSynchronously = 1;
}
#region IAsyncResult Members
public object AsyncState
{
get { return m_asyncState; }
}
public WaitHandle AsyncWaitHandle
{
get
{
if (m_waitHandle == null)
{
bool done = IsCompleted;
ManualResetEvent mre = new ManualResetEvent(done);
if (Interlocked.CompareExchange(ref m_waitHandle, mre, null) != null)
{
mre.Close();
}
else
{
if (!done && IsCompleted)
{
m_waitHandle.Set();
}
}
}
return m_waitHandle;
}
}
public bool CompletedSynchronously
{
get { return Thread.VolatileRead(ref m_completedSynchronously) == 1; }
}
public bool IsCompleted
{
get { return Thread.VolatileRead(ref m_completed) == 1; }
}
#endregion
#region class Methods
internal void SetAsCompleted(bool completedSynchronously)
{
m_completed = 1;
if (completedSynchronously)
m_completedSynchronously = 1;
else
m_completedSynchronously = 0;
SignalCompletion();
}
internal void HandleException(Exception e, bool completedSynchronously)
{
m_completed = 1;
if (completedSynchronously)
m_completedSynchronously = 1;
else
m_completedSynchronously = 0;
m_exception = e;
SignalCompletion();
}
private void SignalCompletion()
{
if (m_waitHandle != null) m_waitHandle.Set();
if (m_callback != null) m_callback(this);
}
public void EndInvoke()
{
// This method assumes that only 1 thread calls EndInvoke
if (!IsCompleted)
{
// If the operation isn't done, wait for it
AsyncWaitHandle.WaitOne();
AsyncWaitHandle.Close();
m_waitHandle = null; // Allow early GC
}
// Operation is done: if an exception occured, throw it
if (m_exception != null) throw m_exception;
}
#endregion
}
internal class AsyncResult<T> : SimpleAsyncResult
{
private T m_result = default(T);
public AsyncResult(AsyncCallback asyncCallback, Object state) :
base(asyncCallback, state)
{
}
public void SetAsCompleted(T result, bool completedSynchronously)
{
// Save the asynchronous operation's result
m_result = result;
// Tell the base class that the operation completed
// sucessfully (no exception)
base.SetAsCompleted(completedSynchronously);
}
public new T EndInvoke()
{
base.EndInvoke();
return m_result;
}
}
}

View File

@ -0,0 +1,443 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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.IO;
using System.Net;
using System.Text;
using System.Threading;
using System.Web;
using OpenSim.Framework.Console;
namespace OpenSim.Framework.Communications
{
/// <summary>
/// Implementation of a generic REST client
/// </summary>
/// <remarks>
/// This class is a generic implementation of a REST (Representational State Transfer) web service. This
/// class is designed to execute both synchroneously and asynchroneously.
///
/// Internally the implementation works as a two stage asynchroneous web-client.
/// When the request is initiated, RestClient will query asynchroneously for for a web-response,
/// sleeping until the initial response is returned by the server. Once the initial response is retrieved
/// the second stage of asynchroneous requests will be triggered, in an attempt to read of the response
/// object into a memorystream as a sequence of asynchroneous reads.
///
/// The asynchronisity of RestClient is designed to move as much processing into the back-ground, allowing
/// other threads to execute, while it waits for a response from the web-service. RestClient it self, can be
/// invoked by the caller in either synchroneous mode or asynchroneous mode.
/// </remarks>
public class RestClient
{
private string realuri;
#region member variables
/// <summary>
/// The base Uri of the web-service e.g. http://www.google.com
/// </summary>
private string _url;
/// <summary>
/// Path elements of the query
/// </summary>
private List<string> _pathElements = new List<string>();
/// <summary>
/// Parameter elements of the query, e.g. min=34
/// </summary>
private Dictionary<string, string> _parameterElements = new Dictionary<string, string>();
/// <summary>
/// Request method. E.g. GET, POST, PUT or DELETE
/// </summary>
private string _method;
/// <summary>
/// Temporary buffer used to store bytes temporarily as they come in from the server
/// </summary>
private byte[] _readbuf;
/// <summary>
/// MemoryStream representing the resultiong resource
/// </summary>
private Stream _resource;
/// <summary>
/// WebRequest object, held as a member variable
/// </summary>
private HttpWebRequest _request;
/// <summary>
/// WebResponse object, held as a member variable, so we can close it
/// </summary>
private HttpWebResponse _response;
/// <summary>
/// This flag will help block the main synchroneous method, in case we run in synchroneous mode
/// </summary>
public static ManualResetEvent _allDone = new ManualResetEvent(false);
/// <summary>
/// Default time out period
/// </summary>
private const int DefaultTimeout = 10*1000; // 10 seconds timeout
/// <summary>
/// Default Buffer size of a block requested from the web-server
/// </summary>
private const int BufferSize = 4096; // Read blocks of 4 KB.
/// <summary>
/// if an exception occours during async processing, we need to save it, so it can be
/// rethrown on the primary thread;
/// </summary>
private Exception _asyncException;
#endregion member variables
#region constructors
/// <summary>
/// Instantiate a new RestClient
/// </summary>
/// <param name="url">Web-service to query, e.g. http://osgrid.org:8003</param>
public RestClient(string url)
{
_url = url;
_readbuf = new byte[BufferSize];
_resource = new MemoryStream();
_request = null;
_response = null;
_lock = new object();
}
private object _lock;
#endregion constructors
/// <summary>
/// Add a path element to the query, e.g. assets
/// </summary>
/// <param name="element">path entry</param>
public void AddResourcePath(string element)
{
if (isSlashed(element))
_pathElements.Add(element.Substring(0, element.Length - 1));
else
_pathElements.Add(element);
}
/// <summary>
/// Add a query parameter to the Url
/// </summary>
/// <param name="name">Name of the parameter, e.g. min</param>
/// <param name="value">Value of the parameter, e.g. 42</param>
public void AddQueryParameter(string name, string value)
{
_parameterElements.Add(HttpUtility.UrlEncode(name), HttpUtility.UrlEncode(value));
}
/// <summary>
/// Add a query parameter to the Url
/// </summary>
/// <param name="name">Name of the parameter, e.g. min</param>
public void AddQueryParameter(string name)
{
_parameterElements.Add(HttpUtility.UrlEncode(name), null);
}
/// <summary>
/// Web-Request method, e.g. GET, PUT, POST, DELETE
/// </summary>
public string RequestMethod
{
get { return _method; }
set { _method = value; }
}
/// <summary>
/// True if string contains a trailing slash '/'
/// </summary>
/// <param name="s">string to be examined</param>
/// <returns>true if slash is present</returns>
private bool isSlashed(string s)
{
return s.Substring(s.Length - 1, 1) == "/";
}
/// <summary>
/// return a slash or blank. A slash will be returned if the string does not contain one
/// </summary>
/// <param name="s">stromg to be examined</param>
/// <returns>slash '/' if not already present</returns>
private string slash(string s)
{
return isSlashed(s) ? "" : "/";
}
/// <summary>
/// Build a Uri based on the initial Url, path elements and parameters
/// </summary>
/// <returns>fully constructed Uri</returns>
private Uri buildUri()
{
StringBuilder sb = new StringBuilder();
sb.Append(_url);
foreach (string e in _pathElements)
{
sb.Append("/");
sb.Append(e);
}
bool firstElement = true;
foreach (KeyValuePair<string, string> kv in _parameterElements)
{
if (firstElement)
{
sb.Append("?");
firstElement = false;
}
else
sb.Append("&");
sb.Append(kv.Key);
if (kv.Value != null && kv.Value.Length != 0)
{
sb.Append("=");
sb.Append(kv.Value);
}
}
realuri = sb.ToString();
MainLog.Instance.Verbose("REST", "RestURL: {0}", realuri);
return new Uri(sb.ToString());
}
#region Async communications with server
/// <summary>
/// Async method, invoked when a block of data has been received from the service
/// </summary>
/// <param name="ar"></param>
private void StreamIsReadyDelegate(IAsyncResult ar)
{
try
{
Stream s = (Stream) ar.AsyncState;
int read = s.EndRead(ar);
if (read > 0)
{
_resource.Write(_readbuf, 0, read);
IAsyncResult asynchronousResult =
s.BeginRead(_readbuf, 0, BufferSize, new AsyncCallback(StreamIsReadyDelegate), s);
// TODO! Implement timeout, without killing the server
//ThreadPool.RegisterWaitForSingleObject(asynchronousResult.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), _request, DefaultTimeout, true);
}
else
{
s.Close();
_allDone.Set();
}
}
catch (Exception e)
{
_allDone.Set();
_asyncException = e;
}
}
/// <summary>
/// Async method, invoked when the initial response if received from the server
/// </summary>
/// <param name="ar"></param>
private void ResponseIsReadyDelegate(IAsyncResult ar)
{
try
{
// grab response
WebRequest wr = (WebRequest) ar.AsyncState;
_response = (HttpWebResponse) wr.EndGetResponse(ar);
// get response stream, and setup async reading
Stream s = _response.GetResponseStream();
IAsyncResult asynchronousResult =
s.BeginRead(_readbuf, 0, BufferSize, new AsyncCallback(StreamIsReadyDelegate), s);
// TODO! Implement timeout, without killing the server
// wait until completed, or we timed out
// ThreadPool.RegisterWaitForSingleObject(asynchronousResult.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), _request, DefaultTimeout, true);
}
catch (Exception e)
{
_allDone.Set();
_asyncException = e;
}
}
// Abort the request if the timer fires.
private static void TimeoutCallback(object state, bool timedOut)
{
if (timedOut)
{
HttpWebRequest request = state as HttpWebRequest;
if (request != null)
{
request.Abort();
}
}
}
#endregion Async communications with server
/// <summary>
/// Perform synchroneous request
/// </summary>
public Stream Request()
{
lock (_lock)
{
_request = (HttpWebRequest) WebRequest.Create(buildUri());
_request.KeepAlive = false;
_request.ContentType = "application/xml";
_request.Timeout = 200000;
_asyncException = null;
// IAsyncResult responseAsyncResult = _request.BeginGetResponse(new AsyncCallback(ResponseIsReadyDelegate), _request);
_response = (HttpWebResponse) _request.GetResponse();
Stream src = _response.GetResponseStream();
int length = src.Read(_readbuf, 0, BufferSize);
while (length > 0)
{
_resource.Write(_readbuf, 0, length);
length = src.Read(_readbuf, 0, BufferSize);
}
// TODO! Implement timeout, without killing the server
// this line implements the timeout, if there is a timeout, the callback fires and the request becomes aborted
//ThreadPool.RegisterWaitForSingleObject(responseAsyncResult.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), _request, DefaultTimeout, true);
// _allDone.WaitOne();
if (_response != null)
_response.Close();
if (_asyncException != null)
throw _asyncException;
if (_resource != null)
{
_resource.Flush();
_resource.Seek(0, SeekOrigin.Begin);
}
return _resource;
}
}
public Stream Request(Stream src)
{
_request = (HttpWebRequest) WebRequest.Create(buildUri());
_request.KeepAlive = false;
_request.ContentType = "application/xml";
_request.Timeout = 900000;
_request.Method = RequestMethod;
_asyncException = null;
_request.ContentLength = src.Length;
MainLog.Instance.Verbose("REST", "Request Length {0}", _request.ContentLength);
MainLog.Instance.Verbose("REST", "Sending Web Request {0}", buildUri());
src.Seek(0, SeekOrigin.Begin);
MainLog.Instance.Verbose("REST", "Seek is ok");
Stream dst = _request.GetRequestStream();
MainLog.Instance.Verbose("REST", "GetRequestStream is ok");
byte[] buf = new byte[1024];
int length = src.Read(buf, 0, 1024);
MainLog.Instance.Verbose("REST", "First Read is ok");
while (length > 0)
{
dst.Write(buf, 0, length);
length = src.Read(buf, 0, 1024);
}
_response = (HttpWebResponse) _request.GetResponse();
// IAsyncResult responseAsyncResult = _request.BeginGetResponse(new AsyncCallback(ResponseIsReadyDelegate), _request);
// TODO! Implement timeout, without killing the server
// this line implements the timeout, if there is a timeout, the callback fires and the request becomes aborted
//ThreadPool.RegisterWaitForSingleObject(responseAsyncResult.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), _request, DefaultTimeout, true);
return null;
}
#region Async Invocation
public IAsyncResult BeginRequest(AsyncCallback callback, object state)
{
/// <summary>
/// In case, we are invoked asynchroneously this object will keep track of the state
/// </summary>
AsyncResult<Stream> ar = new AsyncResult<Stream>(callback, state);
ThreadPool.QueueUserWorkItem(RequestHelper, ar);
return ar;
}
public Stream EndRequest(IAsyncResult asyncResult)
{
AsyncResult<Stream> ar = (AsyncResult<Stream>) asyncResult;
// Wait for operation to complete, then return result or
// throw exception
return ar.EndInvoke();
}
private void RequestHelper(Object asyncResult)
{
// We know that it's really an AsyncResult<DateTime> object
AsyncResult<Stream> ar = (AsyncResult<Stream>) asyncResult;
try
{
// Perform the operation; if sucessful set the result
Stream s = Request();
ar.SetAsCompleted(s, false);
}
catch (Exception e)
{
// If operation fails, set the exception
ar.HandleException(e, false);
}
}
#endregion Async Invocation
}
}

View File

@ -0,0 +1,377 @@
using System;
using System.Collections;
using System.Threading;
using libsecondlife.StructuredData;
using libsecondlife;
using Nwc.XmlRpc;
using OpenSim.Framework.Console;
namespace OpenSim.Framework.UserManagement
{
public class RexLoginHandler
{
private LoginService m_ls;
protected UserManagerBase m_userManager = null;
public RexLoginHandler(LoginService loginservice, UserManagerBase userManager)
{
m_ls = loginservice;
m_userManager = userManager;
}
public LLSD LLSDLoginMethod(LLSD request)
{
string clientVersion = "not set"; //rex
LoginResponse logResponse = new LoginResponse();
string account = "";
string sessionhash = "";
string AuthenticationAddress = "";
if (request.Type == LLSDType.Map)
{
LLSDMap map = (LLSDMap)request;
if (map.ContainsKey("account") && map.ContainsKey("sessionhash") &&
map.ContainsKey("AuthenticationAddress"))
{
account = map["account"].AsString();
sessionhash = map["sessionhash"].AsString();
AuthenticationAddress = map["AuthenticationAddress"].AsString();
if (map.ContainsKey("version"))
{
clientVersion = map["version"].AsString();
}
}
else {
return logResponse.CreateLoginFailedResponseLLSD();
}
return (LLSD)CommonLoginProcess(account, sessionhash, AuthenticationAddress, clientVersion, true);
}
return logResponse.CreateLoginFailedResponseLLSD();
}
public XmlRpcResponse XmlRpcLoginMethod(XmlRpcRequest request)
{
MainLog.Instance.Verbose("LOGIN", "Attempting login to rexmode sim now...");
LoginResponse logResponse = new LoginResponse();
Hashtable requestData = (Hashtable)request.Params[0];
bool GoodXML = (//requestData.Contains("first") && requestData.Contains("last") &&
requestData.Contains("account") && requestData.Contains("sessionhash") &&
requestData.Contains("AuthenticationAddress"));
#region GoodXML // authentication and getting UserProfileData
if (GoodXML)
{
string account = (string)requestData["account"];
string sessionhash = (string)requestData["sessionhash"];
string AuthenticationAddress = (string)requestData["AuthenticationAddress"];
string clientVersion = "not set";
if (requestData.ContainsKey("version"))
{
clientVersion = (string)requestData["version"];
}
return (XmlRpcResponse) CommonLoginProcess(account, sessionhash, AuthenticationAddress,
clientVersion, false);
}
else {
return logResponse.CreateGridErrorResponse();
}
}
private object CommonLoginProcess(string account, string sessionhash, string AuthenticationAddress,
string clientVersion, bool useLLSD)
{
string asAddress;
UserProfileData userProfile;
bool GoodLogin = false;
XmlRpcResponse response = new XmlRpcResponse();
LoginResponse logResponse = new LoginResponse();
// in rex mode first thing to do is authenticate
GoodLogin = AuthenticateUser(account, ref sessionhash, AuthenticationAddress);
if (!GoodLogin)
return logResponse.CreateLoginFailedResponse();
userProfile = GetTheUser(account, sessionhash, AuthenticationAddress, out asAddress);
if (userProfile == null)
{
if (!useLLSD)
return logResponse.CreateLoginFailedResponse();
else
return logResponse.CreateAlreadyLoggedInResponseLLSD();
}
// Set at least here if not filled elsewhere later...
userProfile.authenticationAddr = AuthenticationAddress;
#endregion
#region GoodLogin // Agent storing issues
if (!GoodLogin)
{
return logResponse.CreateLoginFailedResponse();
}
else
{
// If we already have a session...
//if (userProfile.currentAgent != null && userProfile.currentAgent.agentOnline)
//{
// userProfile.currentAgent = null;
//m_userManager.CommitAgent(ref userProfile);// not needed
// Reject the login
// return logResponse.CreateAlreadyLoggedInResponse();
//}
// Otherwise...
// TODO: Actually this is needed at least for now as otherwise crashes to agent being null
//m_ls.CreateAgent(userProfile, request); // not needed
#endregion
#region AllTheRest
// All the rest in this method goes like in LoginServices method
try
{
LLUUID agentID = userProfile.UUID;
// Inventory Library Section
OpenSim.Framework.UserManagement.LoginService.InventoryData inventData = m_ls.CreateInventoryData(agentID);
ArrayList AgentInventoryArray = inventData.InventoryArray;
Hashtable InventoryRootHash = new Hashtable();
InventoryRootHash["folder_id"] = inventData.RootFolderID.ToString();
ArrayList InventoryRoot = new ArrayList();
InventoryRoot.Add(InventoryRootHash);
userProfile.rootInventoryFolderID = inventData.RootFolderID;
// Circuit Code
uint circode = (uint)(Util.RandomClass.Next());
logResponse.Lastname = userProfile.surname;
logResponse.Firstname = userProfile.username;
logResponse.AgentID = agentID.ToString();
// TODO: Authentication server does not send these, so use random generated defaults! (at least for now)
logResponse.SessionID = userProfile.currentAgent.sessionID.ToString();
logResponse.SecureSessionID = userProfile.currentAgent.secureSessionID.ToString();
logResponse.InventoryRoot = InventoryRoot;
logResponse.InventorySkeleton = AgentInventoryArray;
logResponse.InventoryLibrary = m_ls.GetInventoryLibrary();
logResponse.ClientVersion = clientVersion;
Hashtable InventoryLibRootHash = new Hashtable();
InventoryLibRootHash["folder_id"] = "00000112-000f-0000-0000-000100bba000";
ArrayList InventoryLibRoot = new ArrayList();
InventoryLibRoot.Add(InventoryLibRootHash);
logResponse.InventoryLibRoot = InventoryLibRoot;
logResponse.InventoryLibraryOwner = m_ls.GetLibraryOwner();
logResponse.CircuitCode = (Int32)circode;
//logResponse.RegionX = 0; //overwritten
//logResponse.RegionY = 0; //overwritten
logResponse.Home = "!!null temporary value {home}!!"; // Overwritten
//logResponse.LookAt = "\n[r" + TheUser.homeLookAt.X.ToString() + ",r" + TheUser.homeLookAt.Y.ToString() + ",r" + TheUser.homeLookAt.Z.ToString() + "]\n";
//logResponse.SimAddress = "127.0.0.1"; //overwritten
//logResponse.SimPort = 0; //overwritten
logResponse.Message = m_ls.GetMessage();
try
{
m_ls.CustomiseResponse(logResponse, userProfile, asAddress);
}
catch (Exception e)
{
MainLog.Instance.Verbose("LOGIN", e.ToString());
if (!useLLSD)
return logResponse.CreateDeadRegionResponse();
else
return logResponse.CreateDeadRegionResponseLLSD();
//return logResponse.ToXmlRpcResponse();
}
//m_ls.CommitAgent(ref userProfile);
if (!useLLSD)
return logResponse.ToXmlRpcResponse();
else
return logResponse.ToLLSDResponse();
}
catch (Exception E)
{
MainLog.Instance.Verbose("LOGIN", E.ToString());
}
#endregion
}
if (!useLLSD)
return response;
else
return logResponse.CreateFailedResponseLLSD();
}
/// <summary>
/// Does authentication to Authentication server
/// </summary>
/// <param name="account"></param>
/// <param name="loginSessionHash"></param>
/// <returns>new sessionhash ?</returns>
public bool AuthenticateUser(string account, ref string loginSessionHash, string authenticationAddr)
{
Hashtable requestParams = new Hashtable();
requestParams.Add("account", account);
requestParams.Add("sessionhash", loginSessionHash);
XmlRpcResponse res = doRequest("SimAuthenticationAccount", requestParams, authenticationAddr);
if ((string)((Hashtable)res.Value)["login"] == "success")
{
loginSessionHash = (string)((Hashtable)res.Value)["sessionHash"];
return true;
}
else
{
return false;
}
}
public virtual UserProfileData GetTheUser(string account, string sessionhash, string authenticationAddr,
out string asAddress)
{
Hashtable requestParams = new Hashtable();
requestParams.Add("avatar_account", account);
requestParams.Add("sessionhash", sessionhash);
XmlRpcResponse res = doRequest("get_user_by_account", requestParams, authenticationAddr);
// should do better check
if ((string)((Hashtable)res.Value)["uuid"] != null)
{
if ((string)((Hashtable)res.Value)["as_address"] != null)
asAddress = (string)((Hashtable)res.Value)["as_address"];
else
asAddress = "";
return HashtableToUserProfileData((Hashtable)res.Value);
}
asAddress = "";
return null;
}
protected XmlRpcResponse doRequest(string method,
Hashtable requestParams,
string authenticationAddr)
{
ArrayList SendParams = new ArrayList();
SendParams.Add(requestParams);
XmlRpcRequest req = new XmlRpcRequest(method, SendParams);
if (!authenticationAddr.StartsWith("http://"))
authenticationAddr = "http://" + authenticationAddr;
return req.Send(authenticationAddr, 300000);
}
static public UserProfileData HashtableToUserProfileData(Hashtable responseData)
{
UserProfileData profile = new UserProfileData();
// Account information
profile.username = (string)responseData["firstname"];
profile.surname = (string)responseData["lastname"];
profile.UUID = LLUUID.Parse((string)responseData["uuid"]);
// Server Information
profile.userInventoryURI = (string)responseData["server_inventory"];
profile.userAssetURI = (string)responseData["server_asset"];
// Profile Information
profile.profileAboutText = (string)responseData["profile_about"];
profile.profileFirstText = (string)responseData["profile_firstlife_about"];
profile.profileFirstImage = LLUUID.Parse((string)responseData["profile_firstlife_image"]);
profile.profileCanDoMask = uint.Parse((string)responseData["profile_can_do"]);
profile.profileWantDoMask = uint.Parse((string)responseData["profile_want_do"]);
profile.profileImage = LLUUID.Parse((string)responseData["profile_image"]);
profile.created = int.Parse((string)responseData["profile_created"]);
profile.lastLogin = int.Parse((string)responseData["profile_lastlogin"]);
// Home region information
profile.homeLocation = new LLVector3(float.Parse((string)responseData["home_coordinates_x"]),
float.Parse((string)responseData["home_coordinates_y"]),
float.Parse((string)responseData["home_coordinates_z"]));
profile.homeRegion = ulong.Parse((string)responseData["home_region"]);
profile.homeLookAt = new LLVector3(float.Parse((string)responseData["home_look_x"]),
float.Parse((string)responseData["home_look_y"]),
float.Parse((string)responseData["home_look_z"]));
Hashtable UADtable = (Hashtable)responseData["currentAgent"];
if (UADtable != null)
{
profile.currentAgent = new UserAgentData();
HashtableToAgentData(ref UADtable, ref profile.currentAgent);
}
else
{
System.Console.WriteLine("No currentAgent in response!");
}
return profile;
}
static public void HashtableToAgentData(ref Hashtable h, ref UserAgentData uad)
{
uad.UUID = LLUUID.Parse((string)h["UUID"]);
uad.agentIP = (string)h["agentIP"];
uad.agentPort = uint.Parse((string)h["agentPort"]);
uad.agentOnline = Boolean.Parse((string)h["agentOnline"]);
uad.sessionID = LLUUID.Parse((string)h["sessionID"]);
uad.secureSessionID = LLUUID.Parse((string)h["secureSessionID"]);
uad.regionID = LLUUID.Parse((string)h["regionID"]);
uad.loginTime = int.Parse((string)h["loginTime"]);
uad.logoutTime = int.Parse((string)h["logoutTime"]);
uad.currentRegion = LLUUID.Parse((string)h["currentRegion"]);
uad.currentHandle = ulong.Parse((string)h["currentHandle"]);
try
{
string pos1 = (string)h["currentPos"];//<123,3132,3123>
string pos2 = pos1.Substring(1, pos1.Length - 2); // remove < & >
string[] vals = pos2.Split(',');
uad.currentPos = new LLVector3(float.Parse(vals[0]), float.Parse(vals[1]), float.Parse(vals[2]));
}
catch (Exception)
{
uad.currentPos = new LLVector3();
}
}
}
}

View File

@ -0,0 +1,701 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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.Reflection;
using System.Security.Cryptography;
using libsecondlife;
using libsecondlife.StructuredData;
using Nwc.XmlRpc;
using OpenSim.Framework.Console;
namespace OpenSim.Framework.UserManagement
{
/// <summary>
/// Base class for user management (create, read, etc)
/// </summary>
public abstract class UserManagerBase : IUserService
{
public UserConfig _config;
private Dictionary<string, IUserData> _plugins = new Dictionary<string, IUserData>();
public bool RexMode = false; // _config is not initiated in local mode
/// <summary>
/// Adds a new user server plugin - user servers will be requested in the order they were loaded.
/// </summary>
/// <param name="FileName">The filename to the user server plugin DLL</param>
public void AddPlugin(string FileName)
{
if (!String.IsNullOrEmpty(FileName))
{
MainLog.Instance.Verbose("USERSTORAGE", "Attempting to load " + FileName);
Assembly pluginAssembly = Assembly.LoadFrom(FileName);
MainLog.Instance.Verbose("USERSTORAGE", "Found " + pluginAssembly.GetTypes().Length + " interfaces.");
foreach (Type pluginType in pluginAssembly.GetTypes())
{
if (!pluginType.IsAbstract)
{
Type typeInterface = pluginType.GetInterface("IUserData", true);
if (typeInterface != null)
{
IUserData plug =
(IUserData) Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));
AddPlugin(plug);
}
}
}
}
}
public void AddPlugin(IUserData plug)
{
plug.Initialise();
_plugins.Add(plug.getName(), plug);
MainLog.Instance.Verbose("USERSTORAGE", "Added IUserData Interface");
}
#region Get UserProfile
/// <summary>
/// Loads a user profile from a database by UUID
/// </summary>
/// <param name="uuid">The target UUID</param>
/// <returns>A user profile. Returns null if no user profile is found.</returns>
public UserProfileData GetUserProfile(LLUUID uuid, string authAddr)
{
if (!RexMode)
{
foreach (KeyValuePair<string, IUserData> plugin in _plugins)
{
try
{
UserProfileData profile = plugin.Value.GetUserByUUID(uuid);
if (null != profile)
{
profile.currentAgent = getUserAgent(profile.UUID);
return profile;
}
}
catch (Exception e)
{
MainLog.Instance.Verbose("USERSTORAGE", "Unable to find user via " + plugin.Key + "(" + e.ToString() + ")");
}
}
return null;
}
else
{
try
{
UserProfileData userpd = null;
System.Collections.Hashtable param = new System.Collections.Hashtable();
param["avatar_uuid"] = uuid.ToString();
param["AuthenticationAddress"] = authAddr;
System.Collections.Hashtable resp = MakeCommonRequest("get_user_by_uuid", param, authAddr, 3000);
userpd = RexLoginHandler.HashtableToUserProfileData(resp);
return userpd;
}
catch (Exception e)
{
System.Console.WriteLine("Error when trying to fetch profile data by uuid from remote authentication server: " +
e.Message);
}
return null;
}
}
public System.Collections.Hashtable MakeCommonRequest(string method, System.Collections.Hashtable param, string addr, int timeout)//rex
{
System.Collections.IList parameters = new System.Collections.ArrayList();
parameters.Add(param);
XmlRpcRequest req = new XmlRpcRequest(method, parameters);
if (!addr.StartsWith("http://"))
addr = "http://" + addr;
XmlRpcResponse resp = req.Send(addr, timeout);
return (System.Collections.Hashtable)resp.Value;
}
/// <summary>
/// Loads a user profile by name
/// </summary>
/// <param name="name">The target name</param>
/// <returns>A user profile</returns>
public UserProfileData GetUserProfileByAccount(string account)
{
foreach (KeyValuePair<string, IUserData> plugin in _plugins)
{
try
{
UserProfileData profile = plugin.Value.GetUserByAccount(account);
profile.currentAgent = getUserAgent(profile.UUID);
return profile;
}
catch (Exception e)
{
MainLog.Instance.Verbose("USERSTORAGE", "Unable to find user by account via " + plugin.Key + "(" + e.ToString() + ")");
}
}
return null;
}
public List<AvatarPickerAvatar> GenerateAgentPickerRequestResponse(LLUUID queryID, string query)
{
List<AvatarPickerAvatar> pickerlist = new List<AvatarPickerAvatar>();
foreach (KeyValuePair<string, IUserData> plugin in _plugins)
{
try
{
pickerlist = plugin.Value.GeneratePickerResults(queryID, query);
}
catch (Exception)
{
MainLog.Instance.Verbose("USERSTORAGE",
"Unable to generate AgentPickerData via " + plugin.Key + "(" + query + ")");
return new List<AvatarPickerAvatar>();
}
}
return pickerlist;
}
/// <summary>
/// Loads a user profile by name
/// </summary>
/// <param name="fname">First name</param>
/// <param name="lname">Last name</param>
/// <returns>A user profile. Returns null if no profile is found</returns>
public UserProfileData GetUserProfile(string fname, string lname, string authAddr)
{
if (!RexMode)
{
foreach (KeyValuePair<string, IUserData> plugin in _plugins)
{
try
{
UserProfileData profile = plugin.Value.GetUserByName(fname, lname);
if (profile != null)
{
profile.currentAgent = getUserAgent(profile.UUID);
return profile;
}
}
catch (Exception e)
{
MainLog.Instance.Verbose("USERSTORAGE", "Unable to find user via " + plugin.Key + "(" + e.ToString() + ")");
}
}
}
else
{
try
{
UserProfileData userpd = null;
System.Collections.Hashtable param = new System.Collections.Hashtable();
param["avatar_name"] = fname + " "+lname;
param["AuthenticationAddress"] = authAddr;
System.Collections.Hashtable resp = MakeCommonRequest("get_user_by_name", param, authAddr, 3000);
if (resp.Contains("error_type"))
{
return null;
}
else
{
userpd = RexLoginHandler.HashtableToUserProfileData(resp);
return userpd;
}
}
catch (Exception e)
{
System.Console.WriteLine("Error when trying to fetch profile data by firstname, lastname from remote authentication server: " +
e.Message);
}
}
return null;
}
/// <summary>
/// Set's user profile from object
/// </summary>
/// <param name="fname">First name</param>
/// <param name="lname">Last name</param>
/// <returns>A user profile</returns>
public bool setUserProfile(UserProfileData data)
{
foreach (KeyValuePair<string, IUserData> plugin in _plugins)
{
try
{
plugin.Value.UpdateUserProfile(data);
return true;
}
catch (Exception e)
{
MainLog.Instance.Verbose("USERSTORAGE",
"Unable to set user via " + plugin.Key + "(" + e.ToString() + ")");
}
}
return false;
}
#endregion
#region Get UserAgent
/// <summary>
/// Loads a user agent by uuid (not called directly)
/// </summary>
/// <param name="uuid">The agent's UUID</param>
/// <returns>Agent profiles</returns>
public UserAgentData getUserAgent(LLUUID uuid)
{
foreach (KeyValuePair<string, IUserData> plugin in _plugins)
{
try
{
return plugin.Value.GetAgentByUUID(uuid);
}
catch (Exception e)
{
MainLog.Instance.Verbose("USERSTORAGE",
"Unable to find user via " + plugin.Key + "(" + e.ToString() + ")");
}
}
return null;
}
/// <summary>
/// Loads a user's friend list
/// </summary>
/// <param name="name">the UUID of the friend list owner</param>
/// <returns>A List of FriendListItems that contains info about the user's friends</returns>
public List<FriendListItem> GetUserFriendList(LLUUID ownerID)
{
foreach (KeyValuePair<string, IUserData> plugin in _plugins)
{
try
{
return plugin.Value.GetUserFriendList(ownerID);
}
catch (Exception e)
{
MainLog.Instance.Verbose("USERSTORAGE",
"Unable to GetUserFriendList via " + plugin.Key + "(" + e.ToString() + ")");
}
}
return null;
}
public void AddNewUserFriend(LLUUID friendlistowner, LLUUID friend, uint perms)
{
foreach (KeyValuePair<string, IUserData> plugin in _plugins)
{
try
{
plugin.Value.AddNewUserFriend(friendlistowner,friend,perms);
}
catch (Exception e)
{
MainLog.Instance.Verbose("USERSTORAGE",
"Unable to AddNewUserFriend via " + plugin.Key + "(" + e.ToString() + ")");
}
}
}
public void RemoveUserFriend(LLUUID friendlistowner, LLUUID friend)
{
foreach (KeyValuePair<string, IUserData> plugin in _plugins)
{
try
{
plugin.Value.RemoveUserFriend(friendlistowner, friend);
}
catch (Exception e)
{
MainLog.Instance.Verbose("USERSTORAGE",
"Unable to RemoveUserFriend via " + plugin.Key + "(" + e.ToString() + ")");
}
}
}
public void UpdateUserFriendPerms(LLUUID friendlistowner, LLUUID friend, uint perms)
{
foreach (KeyValuePair<string, IUserData> plugin in _plugins)
{
try
{
plugin.Value.UpdateUserFriendPerms(friendlistowner, friend, perms);
}
catch (Exception e)
{
MainLog.Instance.Verbose("USERSTORAGE",
"Unable to UpdateUserFriendPerms via " + plugin.Key + "(" + e.ToString() + ")");
}
}
}
/// <summary>
/// Loads a user agent by name (not called directly)
/// </summary>
/// <param name="name">The agent's name</param>
/// <returns>A user agent</returns>
public UserAgentData getUserAgent(string name)
{
foreach (KeyValuePair<string, IUserData> plugin in _plugins)
{
try
{
return plugin.Value.GetAgentByName(name);
}
catch (Exception e)
{
MainLog.Instance.Verbose("USERSTORAGE",
"Unable to find user via " + plugin.Key + "(" + e.ToString() + ")");
}
}
return null;
}
// TODO: document
public void clearUserAgent(LLUUID agentID, string authAddr)
{
UserProfileData profile = GetUserProfile(agentID, authAddr);
if (profile != null)
{
profile.currentAgent = null;
if (!RexMode)
{
setUserProfile(profile);
}
else
{
try
{
System.Collections.Hashtable param = new System.Collections.Hashtable();
param["agentID"] = profile.UUID.ToString();
System.Collections.Hashtable resp = MakeCommonRequest("remove_user_agent", param, authAddr, 3000);
}
catch (Exception e)
{
System.Console.WriteLine("Error when trying to fetch agent data by uuid from remote authentication server: " +
e.Message);
}
}
}
else
{
MainLog.Instance.Verbose("USERSTORAGE", "Unable to clear user agent with agentID : " + agentID);
}
}
/// <summary>
/// Loads a user agent by name (not called directly)
/// </summary>
/// <param name="fname">The agent's firstname</param>
/// <param name="lname">The agent's lastname</param>
/// <returns>A user agent</returns>
public UserAgentData getUserAgent(string fname, string lname)
{
foreach (KeyValuePair<string, IUserData> plugin in _plugins)
{
try
{
return plugin.Value.GetAgentByName(fname, lname);
}
catch (Exception e)
{
MainLog.Instance.Verbose("USERSTORAGE",
"Unable to find user via " + plugin.Key + "(" + e.ToString() + ")");
}
}
return null;
}
#endregion
#region CreateAgent
/// <summary>
/// Creates and initialises a new user agent - make sure to use CommitAgent when done to submit to the DB
/// </summary>
/// <param name="profile">The users profile</param>
/// <param name="request">The users loginrequest</param>
public void CreateAgent(UserProfileData profile, XmlRpcRequest request)
{
//Hashtable requestData = (Hashtable) request.Params[0];
UserAgentData agent = new UserAgentData();
// User connection
agent.agentOnline = true;
// Generate sessions
RNGCryptoServiceProvider rand = new RNGCryptoServiceProvider();
byte[] randDataS = new byte[16];
byte[] randDataSS = new byte[16];
rand.GetBytes(randDataS);
rand.GetBytes(randDataSS);
agent.secureSessionID = new LLUUID(randDataSS, 0);
agent.sessionID = new LLUUID(randDataS, 0);
// Profile UUID
agent.UUID = profile.UUID;
// Current position (from Home)
agent.currentHandle = profile.homeRegion;
agent.currentPos = profile.homeLocation;
// If user specified additional start, use that
// if (requestData.ContainsKey("start"))
// {
// string startLoc = ((string) requestData["start"]).Trim();
// if (!(startLoc == "last" || startLoc == "home"))
// {
// // Format: uri:Ahern&162&213&34
// try
// {
// string[] parts = startLoc.Remove(0, 4).Split('&');
// //string region = parts[0];
//
// ////////////////////////////////////////////////////
// //SimProfile SimInfo = new SimProfile();
// //SimInfo = SimInfo.LoadFromGrid(theUser.currentAgent.currentHandle, _config.GridServerURL, _config.GridSendKey, _config.GridRecvKey);
// }
// catch (Exception)
// {
// }
// }
// }
// What time did the user login?
agent.loginTime = Util.UnixTimeSinceEpoch();
agent.logoutTime = 0;
// Current location
agent.regionID = LLUUID.Zero; // Fill in later
agent.currentRegion = LLUUID.Zero; // Fill in later
profile.currentAgent = agent;
}
public void CreateAgent(UserProfileData profile, LLSD request)
{
UserAgentData agent = new UserAgentData();
// User connection
agent.agentOnline = true;
// Generate sessions
RNGCryptoServiceProvider rand = new RNGCryptoServiceProvider();
byte[] randDataS = new byte[16];
byte[] randDataSS = new byte[16];
rand.GetBytes(randDataS);
rand.GetBytes(randDataSS);
agent.secureSessionID = new LLUUID(randDataSS, 0);
agent.sessionID = new LLUUID(randDataS, 0);
// Profile UUID
agent.UUID = profile.UUID;
// Current position (from Home)
agent.currentHandle = profile.homeRegion;
agent.currentPos = profile.homeLocation;
// What time did the user login?
agent.loginTime = Util.UnixTimeSinceEpoch();
agent.logoutTime = 0;
// Current location
agent.regionID = LLUUID.Zero; // Fill in later
agent.currentRegion = LLUUID.Zero; // Fill in later
profile.currentAgent = agent;
}
/// <summary>
/// Saves a target agent to the database
/// </summary>
/// <param name="profile">The users profile</param>
/// <returns>Successful?</returns>
public bool CommitAgent(ref UserProfileData profile)
{
// TODO: how is this function different from setUserProfile?
return setUserProfile(profile);
}
#endregion
/// <summary>
///
/// </summary>
/// <param name="user"></param>
public LLUUID AddUserProfile(string firstName, string lastName, string pass, uint regX, uint regY)
{
UserProfileData user = new UserProfileData();
user.homeLocation = new LLVector3(128, 128, 100);
user.UUID = LLUUID.Random();
user.username = firstName;
user.surname = lastName;
user.passwordHash = pass;
user.passwordSalt = "";
user.created = Util.UnixTimeSinceEpoch();
user.homeLookAt = new LLVector3(100, 100, 100);
user.homeRegionX = regX;
user.homeRegionY = regY;
foreach (KeyValuePair<string, IUserData> plugin in _plugins)
{
try
{
plugin.Value.AddNewUserProfile(user);
}
catch (Exception e)
{
MainLog.Instance.Verbose("USERSTORAGE",
"Unable to add user via " + plugin.Key + "(" + e.ToString() + ")");
}
}
return user.UUID;
}
public abstract UserProfileData SetupMasterUser(string firstName, string lastName);
public abstract UserProfileData SetupMasterUser(string firstName, string lastName, string password);
public abstract UserProfileData SetupMasterUser(LLUUID uuid);
public bool AuthenticateUser(LLUUID agentId, string sessionhash, out String avatarstorage)
{
avatarstorage = "";
return true;
}
/// <summary>
/// Loads a user profile by name
/// </summary>
/// <param name="name">The target name</param>
/// <returns>A user profile</returns>
public UserProfileData GetUserProfile(string name, string authAddr)
{
foreach (KeyValuePair<string, IUserData> plugin in _plugins)
{
try
{
UserProfileData profile = plugin.Value.GetUserByName(name, authAddr);
profile.currentAgent = getUserAgent(profile.UUID);
return profile;
}
catch (Exception e)
{
MainLog.Instance.Verbose("USERSTORAGE", "Unable to find user via " + plugin.Key + "(" + e.ToString() + ")");
}
}
return null;
}
public void UpdateUserAgentData(LLUUID agentId, bool agentOnline, LLVector3 currentPos, int logoutTime, string authAddr)
{
// Saves the agent to database
//return true;
if (!RexMode)
{
foreach (KeyValuePair<string, IUserData> plugin in _plugins)
{
try
{
UserAgentData agent = plugin.Value.GetAgentByUUID(agentId);
if (agent != null)
{
agent.agentOnline = agentOnline;
agent.logoutTime = logoutTime;
agent.currentPos = currentPos;
agent.currentPos = new LLVector3(
Convert.ToSingle(currentPos.X),
Convert.ToSingle(currentPos.Y),
Convert.ToSingle(currentPos.Z));
plugin.Value.AddNewUserAgent(agent);
MainLog.Instance.Verbose("USERSTORAGE", "Agent updated UUID = " + agent.UUID.ToString());
}
else
{
MainLog.Instance.Verbose("USERSTORAGE", "Agent update, agent not found with UUID = " + agentId);
}
}
catch (Exception e)
{
MainLog.Instance.Verbose("USERSTORAGE", "Unable to add or update agent via " + plugin.Key + "(" + e.ToString() + ")");
}
}
}
else
{
try
{
System.Collections.Hashtable param = new System.Collections.Hashtable();
param["agentID"] = agentId.ToString();
param["agentOnline"] = agentOnline.ToString();
param["logoutTime"] = logoutTime.ToString();
param["agent_currentPosX"] = Convert.ToSingle(currentPos.X).ToString();
param["agent_currentPosY"] = Convert.ToSingle(currentPos.Y).ToString();
param["agent_currentPosZ"] = Convert.ToSingle(currentPos.Z).ToString();
param["AuthenticationAddress"] = authAddr;
System.Collections.Hashtable resp = MakeCommonRequest("update_user_agent", param, authAddr, 3000);
}
catch (Exception e)
{
System.Console.WriteLine("Error when trying to update user agent data to remote authentication server: " +
e.Message);
}
}
}
}
}

View File

@ -0,0 +1,115 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS 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 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.IO;
using System.Net;
using System.Text;
using OpenSim.Framework.Console;
namespace OpenSim.Framework.Configuration.HTTP
{
public class HTTPConfiguration : IGenericConfig
{
private RemoteConfigSettings remoteConfigSettings;
private XmlConfiguration xmlConfig;
private string configFileName = "";
public HTTPConfiguration()
{
remoteConfigSettings = new RemoteConfigSettings("remoteconfig.xml");
xmlConfig = new XmlConfiguration();
}
public void SetFileName(string fileName)
{
configFileName = fileName;
}
public void LoadData()
{
try
{
StringBuilder sb = new StringBuilder();
byte[] buf = new byte[8192];
HttpWebRequest request =
(HttpWebRequest) WebRequest.Create(remoteConfigSettings.baseConfigURL + configFileName);
HttpWebResponse response = (HttpWebResponse) request.GetResponse();
Stream resStream = response.GetResponseStream();
string tempString = null;
int count = 0;
do
{
count = resStream.Read(buf, 0, buf.Length);
if (count != 0)
{
tempString = Encoding.ASCII.GetString(buf, 0, count);
sb.Append(tempString);
}
} while (count > 0);
LoadDataFromString(sb.ToString());
}
catch (WebException)
{
MainLog.Instance.Warn("Unable to connect to remote configuration file (" +
remoteConfigSettings.baseConfigURL + configFileName +
"). Creating local file instead.");
xmlConfig.SetFileName(configFileName);
xmlConfig.LoadData();
}
}
public void LoadDataFromString(string data)
{
xmlConfig.LoadDataFromString(data);
}
public string GetAttribute(string attributeName)
{
return xmlConfig.GetAttribute(attributeName);
}
public bool SetAttribute(string attributeName, string attributeValue)
{
return true;
}
public void Commit()
{
}
public void Close()
{
}
}
}

View File

@ -0,0 +1,62 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS 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 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.
*
*/
namespace OpenSim.Framework.Configuration.HTTP
{
public class RemoteConfigSettings
{
private ConfigurationMember configMember;
public string baseConfigURL = "";
public RemoteConfigSettings(string filename)
{
configMember =
new ConfigurationMember(filename, "REMOTE CONFIG SETTINGS", loadConfigurationOptions,
handleIncomingConfiguration,true);
configMember.forceConfigurationPluginLibrary("OpenSim.Framework.Configuration.XML.dll");
configMember.performConfigurationRetrieve();
}
public void loadConfigurationOptions()
{
configMember.addConfigurationOption("base_config_url",
ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY,
"URL Containing Configuration Files", "http://localhost/", false);
}
public bool handleIncomingConfiguration(string configuration_key, object configuration_result)
{
if (configuration_key == "base_config_url")
{
baseConfigURL = (string) configuration_result;
}
return true;
}
}
}

View File

@ -0,0 +1,139 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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.IO;
using System.Xml;
namespace OpenSim.Framework.Configuration
{
public class XmlConfiguration : IGenericConfig
{
private XmlDocument doc;
private XmlNode rootNode;
private XmlNode configNode;
private string fileName;
private bool createdFile = false;
public void SetFileName(string file)
{
fileName = file;
}
private void LoadDataToClass()
{
rootNode = doc.FirstChild;
if (rootNode.Name != "Root")
throw new Exception("Error: Invalid .xml File. Missing <Root>");
configNode = rootNode.FirstChild;
if (configNode.Name != "Config")
throw new Exception("Error: Invalid .xml File. <Root> first child should be <Config>");
}
public void LoadData()
{
lock (this)
{
doc = new XmlDocument();
if (File.Exists(fileName))
{
XmlTextReader reader = new XmlTextReader(fileName);
reader.WhitespaceHandling = WhitespaceHandling.None;
doc.Load(reader);
reader.Close();
}
else
{
createdFile = true;
rootNode = doc.CreateNode(XmlNodeType.Element, "Root", "");
doc.AppendChild(rootNode);
configNode = doc.CreateNode(XmlNodeType.Element, "Config", "");
rootNode.AppendChild(configNode);
}
LoadDataToClass();
if (createdFile)
{
Commit();
}
}
}
public void LoadDataFromString(string data)
{
doc = new XmlDocument();
doc.LoadXml(data);
LoadDataToClass();
}
public string GetAttribute(string attributeName)
{
string result = null;
if (configNode.Attributes[attributeName] != null)
{
result = ((XmlAttribute) configNode.Attributes.GetNamedItem(attributeName)).Value;
}
return result;
}
public bool SetAttribute(string attributeName, string attributeValue)
{
if (configNode.Attributes[attributeName] != null)
{
((XmlAttribute) configNode.Attributes.GetNamedItem(attributeName)).Value = attributeValue;
}
else
{
XmlAttribute attri;
attri = doc.CreateAttribute(attributeName);
attri.Value = attributeValue;
configNode.Attributes.Append(attri);
}
return true;
}
public void Commit()
{
if (!Directory.Exists(Util.configDir()))
{
Directory.CreateDirectory(Util.configDir());
}
doc.Save(fileName);
}
public void Close()
{
configNode = null;
rootNode = null;
doc = null;
}
}
}

View File

@ -0,0 +1,505 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS 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 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.Globalization;
using System.Net;
using System.Reflection;
using System.Xml;
using libsecondlife;
using OpenSim.Framework.Console;
namespace OpenSim.Framework
{
public class ConfigurationMember
{
public delegate bool ConfigurationOptionResult(string configuration_key, object configuration_result);
public delegate void ConfigurationOptionsLoad();
private List<ConfigurationOption> configurationOptions = new List<ConfigurationOption>();
private string configurationFilename = "";
private string configurationDescription = "";
private XmlNode configurationFromXMLNode = null;
private ConfigurationOptionsLoad loadFunction;
private ConfigurationOptionResult resultFunction;
private IGenericConfig configurationPlugin = null;
private bool useConsoleToPromptOnError = true;
/// <summary>
/// This is the default configuration DLL loaded
/// </summary>
private string configurationPluginFilename = "OpenSim.Framework.Configuration.XML.dll";
public ConfigurationMember(string configuration_filename, string configuration_description,
ConfigurationOptionsLoad load_function, ConfigurationOptionResult result_function, bool use_console_to_prompt_on_error)
{
configurationFilename = configuration_filename;
configurationDescription = configuration_description;
loadFunction = load_function;
resultFunction = result_function;
useConsoleToPromptOnError = use_console_to_prompt_on_error;
}
public ConfigurationMember(XmlNode configuration_xml, string configuration_description,
ConfigurationOptionsLoad load_function, ConfigurationOptionResult result_function, bool use_console_to_prompt_on_error)
{
configurationFilename = "";
configurationFromXMLNode = configuration_xml;
configurationDescription = configuration_description;
loadFunction = load_function;
resultFunction = result_function;
useConsoleToPromptOnError = use_console_to_prompt_on_error;
}
public void setConfigurationFilename(string filename)
{
configurationFilename = filename;
}
public void setConfigurationDescription(string desc)
{
configurationDescription = desc;
}
public void setConfigurationResultFunction(ConfigurationOptionResult result)
{
resultFunction = result;
}
public void forceConfigurationPluginLibrary(string dll_filename)
{
configurationPluginFilename = dll_filename;
}
private void checkAndAddConfigOption(ConfigurationOption option)
{
if ((option.configurationKey != "" && option.configurationQuestion != "") ||
(option.configurationKey != "" && option.configurationUseDefaultNoPrompt))
{
if (!configurationOptions.Contains(option))
{
configurationOptions.Add(option);
}
}
else
{
MainLog.Instance.Notice(
"Required fields for adding a configuration option is invalid. Will not add this option (" +
option.configurationKey + ")");
}
}
public void addConfigurationOption(string configuration_key,
ConfigurationOption.ConfigurationTypes configuration_type,
string configuration_question, string configuration_default,
bool use_default_no_prompt)
{
ConfigurationOption configOption = new ConfigurationOption();
configOption.configurationKey = configuration_key;
configOption.configurationQuestion = configuration_question;
configOption.configurationDefault = configuration_default;
configOption.configurationType = configuration_type;
configOption.configurationUseDefaultNoPrompt = use_default_no_prompt;
configOption.shouldIBeAsked = null; //Assumes true, I can ask whenever
checkAndAddConfigOption(configOption);
}
public void addConfigurationOption(string configuration_key,
ConfigurationOption.ConfigurationTypes configuration_type,
string configuration_question, string configuration_default,
bool use_default_no_prompt,
ConfigurationOption.ConfigurationOptionShouldBeAsked shouldIBeAskedDelegate)
{
ConfigurationOption configOption = new ConfigurationOption();
configOption.configurationKey = configuration_key;
configOption.configurationQuestion = configuration_question;
configOption.configurationDefault = configuration_default;
configOption.configurationType = configuration_type;
configOption.configurationUseDefaultNoPrompt = use_default_no_prompt;
configOption.shouldIBeAsked = shouldIBeAskedDelegate;
checkAndAddConfigOption(configOption);
}
// TEMP - REMOVE
private int cE = 0;
public void performConfigurationRetrieve()
{
if (cE > 1)
MainLog.Instance.Error("READING CONFIGURATION COUT: " + cE.ToString());
configurationPlugin = LoadConfigDll(configurationPluginFilename);
configurationOptions.Clear();
if (loadFunction == null)
{
MainLog.Instance.Error("Load Function for '" + configurationDescription +
"' is null. Refusing to run configuration.");
return;
}
if (resultFunction == null)
{
MainLog.Instance.Error("Result Function for '" + configurationDescription +
"' is null. Refusing to run configuration.");
return;
}
MainLog.Instance.Verbose("CONFIG", "Calling Configuration Load Function...");
loadFunction();
if (configurationOptions.Count <= 0)
{
MainLog.Instance.Error("CONFIG",
"No configuration options were specified for '" + configurationOptions +
"'. Refusing to continue configuration.");
return;
}
bool useFile = true;
if (configurationPlugin == null)
{
MainLog.Instance.Error("CONFIG", "Configuration Plugin NOT LOADED!");
return;
}
if (configurationFilename.Trim() != "")
{
configurationPlugin.SetFileName(configurationFilename);
try
{
configurationPlugin.LoadData();
useFile = true;
}
catch (XmlException e)
{
MainLog.Instance.Error("Error loading " + configurationFilename + ": " + e.ToString());
useFile = false;
}
}
else
{
if (configurationFromXMLNode != null)
{
MainLog.Instance.Notice("Loading from XML Node, will not save to the file");
configurationPlugin.LoadDataFromString(configurationFromXMLNode.OuterXml);
}
MainLog.Instance.Notice("XML Configuration Filename is not valid; will not save to the file.");
useFile = false;
}
foreach (ConfigurationOption configOption in configurationOptions)
{
bool convertSuccess = false;
object return_result = null;
string errorMessage = "";
bool ignoreNextFromConfig = false;
while (convertSuccess == false)
{
string console_result = "";
string attribute = null;
if (useFile || configurationFromXMLNode != null)
{
if (!ignoreNextFromConfig)
{
attribute = configurationPlugin.GetAttribute(configOption.configurationKey);
}
else
{
ignoreNextFromConfig = false;
}
}
if (attribute == null)
{
if (configOption.configurationUseDefaultNoPrompt || useConsoleToPromptOnError == false)
{
console_result = configOption.configurationDefault;
}
else
{
if ((configOption.shouldIBeAsked != null &&
configOption.shouldIBeAsked(configOption.configurationKey)) ||
configOption.shouldIBeAsked == null)
{
if (configurationDescription.Trim() != "")
{
console_result =
MainLog.Instance.CmdPrompt(
configurationDescription + ": " + configOption.configurationQuestion,
configOption.configurationDefault);
}
else
{
console_result =
MainLog.Instance.CmdPrompt(configOption.configurationQuestion,
configOption.configurationDefault);
}
}
else
{
//Dont Ask! Just use default
console_result = configOption.configurationDefault;
}
}
}
else
{
console_result = attribute;
}
switch (configOption.configurationType)
{
case ConfigurationOption.ConfigurationTypes.TYPE_STRING:
return_result = console_result;
convertSuccess = true;
break;
case ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY:
if (console_result.Length > 0)
{
return_result = console_result;
convertSuccess = true;
}
errorMessage = "a string that is not empty";
break;
case ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN:
bool boolResult;
if (Boolean.TryParse(console_result, out boolResult))
{
convertSuccess = true;
return_result = boolResult;
}
errorMessage = "'true' or 'false' (Boolean)";
break;
case ConfigurationOption.ConfigurationTypes.TYPE_BYTE:
byte byteResult;
if (Byte.TryParse(console_result, out byteResult))
{
convertSuccess = true;
return_result = byteResult;
}
errorMessage = "a byte (Byte)";
break;
case ConfigurationOption.ConfigurationTypes.TYPE_CHARACTER:
char charResult;
if (Char.TryParse(console_result, out charResult))
{
convertSuccess = true;
return_result = charResult;
}
errorMessage = "a character (Char)";
break;
case ConfigurationOption.ConfigurationTypes.TYPE_INT16:
short shortResult;
if (Int16.TryParse(console_result, out shortResult))
{
convertSuccess = true;
return_result = shortResult;
}
errorMessage = "a signed 32 bit integer (short)";
break;
case ConfigurationOption.ConfigurationTypes.TYPE_INT32:
int intResult;
if (Int32.TryParse(console_result, out intResult))
{
convertSuccess = true;
return_result = intResult;
}
errorMessage = "a signed 32 bit integer (int)";
break;
case ConfigurationOption.ConfigurationTypes.TYPE_INT64:
long longResult;
if (Int64.TryParse(console_result, out longResult))
{
convertSuccess = true;
return_result = longResult;
}
errorMessage = "a signed 32 bit integer (long)";
break;
case ConfigurationOption.ConfigurationTypes.TYPE_IP_ADDRESS:
IPAddress ipAddressResult;
if (IPAddress.TryParse(console_result, out ipAddressResult))
{
convertSuccess = true;
return_result = ipAddressResult;
}
errorMessage = "an IP Address (IPAddress)";
break;
case ConfigurationOption.ConfigurationTypes.TYPE_LLUUID:
LLUUID uuidResult;
if (LLUUID.TryParse(console_result, out uuidResult))
{
convertSuccess = true;
return_result = uuidResult;
}
errorMessage = "a UUID (LLUUID)";
break;
case ConfigurationOption.ConfigurationTypes.TYPE_LLVECTOR3:
LLVector3 vectorResult;
if (LLVector3.TryParse(console_result, out vectorResult))
{
convertSuccess = true;
return_result = vectorResult;
}
errorMessage = "a vector (LLVector3)";
break;
case ConfigurationOption.ConfigurationTypes.TYPE_UINT16:
ushort ushortResult;
if (UInt16.TryParse(console_result, out ushortResult))
{
convertSuccess = true;
return_result = ushortResult;
}
errorMessage = "an unsigned 16 bit integer (ushort)";
break;
case ConfigurationOption.ConfigurationTypes.TYPE_UINT32:
uint uintResult;
if (UInt32.TryParse(console_result, out uintResult))
{
convertSuccess = true;
return_result = uintResult;
}
errorMessage = "an unsigned 32 bit integer (uint)";
break;
case ConfigurationOption.ConfigurationTypes.TYPE_UINT64:
ulong ulongResult;
if (UInt64.TryParse(console_result, out ulongResult))
{
convertSuccess = true;
return_result = ulongResult;
}
errorMessage = "an unsigned 64 bit integer (ulong)";
break;
case ConfigurationOption.ConfigurationTypes.TYPE_FLOAT:
float floatResult;
if (
float.TryParse(console_result, NumberStyles.AllowDecimalPoint, Culture.NumberFormatInfo,
out floatResult))
{
convertSuccess = true;
return_result = floatResult;
}
errorMessage = "a single-precision floating point number (float)";
break;
case ConfigurationOption.ConfigurationTypes.TYPE_DOUBLE:
double doubleResult;
if (
Double.TryParse(console_result, NumberStyles.AllowDecimalPoint, Culture.NumberFormatInfo,
out doubleResult))
{
convertSuccess = true;
return_result = doubleResult;
}
errorMessage = "an double-precision floating point number (double)";
break;
}
if (convertSuccess)
{
if (useFile)
{
configurationPlugin.SetAttribute(configOption.configurationKey, console_result);
}
if (!resultFunction(configOption.configurationKey, return_result))
{
MainLog.Instance.Notice(
"The handler for the last configuration option denied that input, please try again.");
convertSuccess = false;
ignoreNextFromConfig = true;
}
}
else
{
if (configOption.configurationUseDefaultNoPrompt)
{
MainLog.Instance.Error("CONFIG",
string.Format(
"[{3}]:[{1}] is not valid default for parameter [{0}].\nThe configuration result must be parsable to {2}.\n",
configOption.configurationKey, console_result, errorMessage,
configurationFilename));
convertSuccess = true;
}
else
{
MainLog.Instance.Warn("CONFIG",
string.Format(
"[{3}]:[{1}] is not a valid value [{0}].\nThe configuration result must be parsable to {2}.\n",
configOption.configurationKey, console_result, errorMessage,
configurationFilename));
ignoreNextFromConfig = true;
}
}
}
}
if (useFile)
{
configurationPlugin.Commit();
configurationPlugin.Close();
}
}
private IGenericConfig LoadConfigDll(string dllName)
{
Assembly pluginAssembly = Assembly.LoadFrom(dllName);
IGenericConfig plug = null;
foreach (Type pluginType in pluginAssembly.GetTypes())
{
if (pluginType.IsPublic)
{
if (!pluginType.IsAbstract)
{
Type typeInterface = pluginType.GetInterface("IGenericConfig", true);
if (typeInterface != null)
{
plug =
(IGenericConfig) Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));
}
}
}
}
pluginAssembly = null;
return plug;
}
public void forceSetConfigurationOption(string configuration_key, string configuration_value)
{
configurationPlugin.LoadData();
configurationPlugin.SetAttribute(configuration_key, configuration_value);
configurationPlugin.Commit();
configurationPlugin.Close();
}
}
}

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS 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 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.
*
*/
namespace OpenSim.Framework
{
public class ConfigurationOption
{
public delegate bool ConfigurationOptionShouldBeAsked(string configuration_key);
public enum ConfigurationTypes
{
TYPE_STRING,
TYPE_STRING_NOT_EMPTY,
TYPE_UINT16,
TYPE_UINT32,
TYPE_UINT64,
TYPE_INT16,
TYPE_INT32,
TYPE_INT64,
TYPE_IP_ADDRESS,
TYPE_CHARACTER,
TYPE_BOOLEAN,
TYPE_BYTE,
TYPE_LLUUID,
TYPE_LLVECTOR3,
TYPE_FLOAT,
TYPE_DOUBLE
} ;
public string configurationKey = "";
public string configurationQuestion = "";
public string configurationDefault = "";
public ConfigurationTypes configurationType = ConfigurationTypes.TYPE_STRING;
public bool configurationUseDefaultNoPrompt = false;
public ConfigurationOptionShouldBeAsked shouldIBeAsked; //Should I be asked now? Based on previous answers
}
}

View File

@ -0,0 +1,58 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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.Reflection;
using System.Runtime.InteropServices;
// Information about this assembly is defined by the following
// attributes.
//
// change them to the information which is associated with the assembly
// you compile.
[assembly : AssemblyTitle("ServerConsole")]
[assembly : AssemblyDescription("")]
[assembly : AssemblyConfiguration("")]
[assembly : AssemblyCompany("")]
[assembly : AssemblyProduct("ServerConsole")]
[assembly : AssemblyCopyright("")]
[assembly : AssemblyTrademark("")]
[assembly : AssemblyCulture("")]
// This sets the default COM visibility of types in the assembly to invisible.
// If you need to expose a type to COM, use [ComVisible(true)] on that type.
[assembly : ComVisible(false)]
// The assembly version has following format :
//
// Major.Minor.Build.Revision
//
// You can specify all values by your own or you can build default build and revision
// numbers with the '*' character (the default):
[assembly : AssemblyVersion("1.0.*")]

View File

@ -0,0 +1,35 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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.
*
*/
namespace OpenSim.Framework.Console
{
public interface conscmd_callback
{
void RunCmd(string cmd, string[] cmdparams);
void Show(string ShowWhat);
}
}

View File

@ -0,0 +1,482 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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.Diagnostics;
using System.IO;
using System.Net;
namespace OpenSim.Framework.Console
{
public enum LogPriority : int
{
CRITICAL,
HIGH,
MEDIUM,
NORMAL,
LOW,
VERBOSE,
EXTRAVERBOSE
}
public class LogBase
{
private object m_syncRoot = new object();
private StreamWriter Log;
public conscmd_callback cmdparser;
public string componentname;
private bool m_verbose;
public LogBase(string LogFile, string componentname, conscmd_callback cmdparser, bool verbose)
{
this.componentname = componentname;
this.cmdparser = cmdparser;
m_verbose = verbose;
System.Console.WriteLine("Creating new local console");
if (String.IsNullOrEmpty(LogFile))
{
LogFile = componentname + ".log";
}
System.Console.WriteLine("Logs will be saved to current directory in " + LogFile);
Log = File.AppendText(LogFile);
Log.WriteLine("========================================================================");
Log.WriteLine(componentname + " Started at " + DateTime.Now.ToString());
}
public void Close()
{
Log.WriteLine("Shutdown at " + DateTime.Now.ToString());
Log.Close();
}
/// <summary>
/// derive an ansi color from a string, ignoring the darker colors.
/// This is used to help automatically bin component tags with colors
/// in various print functions.
/// </summary>
/// <param name="input">arbitrary string for input</param>
/// <returns>an ansii color</returns>
private ConsoleColor DeriveColor(string input)
{
int colIdx = (input.ToUpper().GetHashCode()%6) + 9;
return (ConsoleColor) colIdx;
}
/// <summary>
/// Sends a warning to the current log output
/// </summary>
/// <param name="format">The message to send</param>
/// <param name="args">WriteLine-style message arguments</param>
public void Warn(string format, params object[] args)
{
WriteNewLine(ConsoleColor.Yellow, format, args);
return;
}
/// <summary>
/// Sends a warning to the current log output
/// </summary>
/// <param name="sender">The module that sent this message</param>
/// <param name="format">The message to send</param>
/// <param name="args">WriteLine-style message arguments</param>
public void Warn(string sender, string format, params object[] args)
{
WritePrefixLine(DeriveColor(sender), sender);
WriteNewLine(ConsoleColor.Yellow, format, args);
return;
}
/// <summary>
/// Sends a notice to the current log output
/// </summary>
/// <param name="format">The message to send</param>
/// <param name="args">WriteLine-style message arguments</param>
public void Notice(string format, params object[] args)
{
WriteNewLine(ConsoleColor.White, format, args);
return;
}
/// <summary>
/// Sends a notice to the current log output
/// </summary>
/// <param name="sender">The module that sent this message</param>
/// <param name="format">The message to send</param>
/// <param name="args">WriteLine-style message arguments</param>
public void Notice(string sender, string format, params object[] args)
{
WritePrefixLine(DeriveColor(sender), sender);
WriteNewLine(ConsoleColor.White, format, args);
return;
}
/// <summary>
/// Sends an error to the current log output
/// </summary>
/// <param name="format">The message to send</param>
/// <param name="args">WriteLine-style message arguments</param>
public void Error(string format, params object[] args)
{
WriteNewLine(ConsoleColor.Red, format, args);
return;
}
/// <summary>
/// Sends an error to the current log output
/// </summary>
/// <param name="sender">The module that sent this message</param>
/// <param name="format">The message to send</param>
/// <param name="args">WriteLine-style message arguments</param>
public void Error(string sender, string format, params object[] args)
{
WritePrefixLine(DeriveColor(sender), sender);
Error(format, args);
return;
}
/// <summary>
/// Sends an informational message to the current log output
/// </summary>
/// <param name="sender">The module that sent this message</param>
/// <param name="format">The message to send</param>
/// <param name="args">WriteLine-style message arguments</param>
public void Verbose(string sender, string format, params object[] args)
{
if (m_verbose)
{
WritePrefixLine(DeriveColor(sender), sender);
WriteNewLine(ConsoleColor.Gray, format, args);
return;
}
}
/// <summary>
/// Sends a status message to the current log output
/// </summary>
/// <param name="format">The message to send</param>
/// <param name="args">WriteLine-style message arguments</param>
public void Status(string format, params object[] args)
{
WriteNewLine(ConsoleColor.Blue, format, args);
return;
}
/// <summary>
/// Sends a status message to the current log output
/// </summary>
/// <param name="sender">The module that sent this message</param>
/// <param name="format">The message to send</param>
/// <param name="args">WriteLine-style message arguments</param>
public void Status(string sender, string format, params object[] args)
{
WritePrefixLine(DeriveColor(sender), sender);
WriteNewLine(ConsoleColor.Blue, format, args);
return;
}
[Conditional("DEBUG")]
public void Debug(string format, params object[] args)
{
WriteNewLine(ConsoleColor.Gray, format, args);
return;
}
[Conditional("DEBUG")]
public void Debug(string sender, string format, params object[] args)
{
WritePrefixLine(DeriveColor(sender), sender);
WriteNewLine(ConsoleColor.Gray, format, args);
return;
}
private void WriteNewLine(ConsoleColor color, string format, params object[] args)
{
lock (m_syncRoot)
{
string now = DateTime.Now.ToString("[MM-dd hh:mm:ss] ");
Log.Write(now);
try
{
Log.WriteLine(format, args);
Log.Flush();
}
catch (FormatException)
{
System.Console.WriteLine(args);
}
System.Console.Write(now);
try
{
if (color != ConsoleColor.White)
System.Console.ForegroundColor = color;
System.Console.WriteLine(format, args);
System.Console.ResetColor();
}
catch (ArgumentNullException)
{
// Some older systems dont support coloured text.
System.Console.WriteLine(format, args);
}
catch (FormatException)
{
// Some older systems dont support coloured text.
System.Console.WriteLine(args);
}
return;
}
}
private void WritePrefixLine(ConsoleColor color, string sender)
{
lock (m_syncRoot)
{
sender = sender.ToUpper();
Log.WriteLine("[" + sender + "] ");
Log.Flush();
System.Console.Write("[");
try
{
System.Console.ForegroundColor = color;
System.Console.Write(sender);
System.Console.ResetColor();
}
catch (ArgumentNullException)
{
// Some older systems dont support coloured text.
System.Console.WriteLine(sender);
}
System.Console.Write("] \t");
return;
}
}
public string ReadLine()
{
try
{
string TempStr = System.Console.ReadLine();
Log.WriteLine(TempStr);
return TempStr;
}
catch (Exception e)
{
MainLog.Instance.Error("Console", "System.Console.ReadLine exception " + e.ToString());
return "";
}
}
public int Read()
{
int TempInt = System.Console.Read();
Log.Write((char) TempInt);
return TempInt;
}
public IPAddress CmdPromptIPAddress(string prompt, string defaultvalue)
{
IPAddress address;
string addressStr;
while (true)
{
addressStr = MainLog.Instance.CmdPrompt(prompt, defaultvalue);
if (IPAddress.TryParse(addressStr, out address))
{
break;
}
else
{
MainLog.Instance.Error("Illegal address. Please re-enter.");
}
}
return address;
}
public uint CmdPromptIPPort(string prompt, string defaultvalue)
{
uint port;
string portStr;
while (true)
{
portStr = MainLog.Instance.CmdPrompt(prompt, defaultvalue);
if (uint.TryParse(portStr, out port))
{
if (port >= IPEndPoint.MinPort && port <= IPEndPoint.MaxPort)
{
break;
}
}
MainLog.Instance.Error("Illegal address. Please re-enter.");
}
return port;
}
// Displays a prompt and waits for the user to enter a string, then returns that string
// Done with no echo and suitable for passwords
public string PasswdPrompt(string prompt)
{
// FIXME: Needs to be better abstracted
Log.WriteLine(prompt);
Notice(prompt);
ConsoleColor oldfg = System.Console.ForegroundColor;
System.Console.ForegroundColor = System.Console.BackgroundColor;
string temp = System.Console.ReadLine();
System.Console.ForegroundColor = oldfg;
return temp;
}
// Displays a command prompt and waits for the user to enter a string, then returns that string
public string CmdPrompt(string prompt)
{
Notice(String.Format("{0}: ", prompt));
return ReadLine();
}
// Displays a command prompt and returns a default value if the user simply presses enter
public string CmdPrompt(string prompt, string defaultresponse)
{
string temp = CmdPrompt(String.Format("{0} [{1}]", prompt, defaultresponse));
if (temp == "")
{
return defaultresponse;
}
else
{
return temp;
}
}
// Displays a command prompt and returns a default value, user may only enter 1 of 2 options
public string CmdPrompt(string prompt, string defaultresponse, string OptionA, string OptionB)
{
bool itisdone = false;
string temp = CmdPrompt(prompt, defaultresponse);
while (itisdone == false)
{
if ((temp == OptionA) || (temp == OptionB))
{
itisdone = true;
}
else
{
Notice("Valid options are " + OptionA + " or " + OptionB);
temp = CmdPrompt(prompt, defaultresponse);
}
}
return temp;
}
// Runs a command with a number of parameters
public Object RunCmd(string Cmd, string[] cmdparams)
{
cmdparser.RunCmd(Cmd, cmdparams);
return null;
}
// Shows data about something
public void ShowCommands(string ShowWhat)
{
cmdparser.Show(ShowWhat);
}
public void MainLogPrompt()
{
string tempstr = CmdPrompt(componentname + "# ");
MainLogRunCommand(tempstr);
}
public void MainLogRunCommand(string command)
{
string[] tempstrarray;
tempstrarray = command.Split(' ');
string cmd = tempstrarray[0];
Array.Reverse(tempstrarray);
Array.Resize<string>(ref tempstrarray, tempstrarray.Length - 1);
Array.Reverse(tempstrarray);
string[] cmdparams = (string[]) tempstrarray;
try
{
RunCmd(cmd, cmdparams);
}
catch (Exception e)
{
MainLog.Instance.Error("Console", "Command failed with exception " + e.ToString());
}
}
public string LineInfo
{
get
{
string result = String.Empty;
string stacktrace = Environment.StackTrace;
List<string> lines = new List<string>(stacktrace.Split(new string[] {"at "}, StringSplitOptions.None));
if (lines.Count > 4)
{
lines.RemoveRange(0, 4);
string tmpLine = lines[0];
int inIndex = tmpLine.IndexOf(" in ");
if (inIndex > -1)
{
result = tmpLine.Substring(0, inIndex);
int lineIndex = tmpLine.IndexOf(":line ");
if (lineIndex > -1)
{
lineIndex += 6;
result += ", line " + tmpLine.Substring(lineIndex, (tmpLine.Length - lineIndex) - 5);
}
}
}
return result;
}
}
}
}

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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.
*
*/
namespace OpenSim.Framework.Console
{
public class MainLog
{
private static LogBase instance;
public static LogBase Instance
{
get { return instance; }
set { instance = value; }
}
}
}

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS 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 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.Globalization;
using System.Threading;
namespace OpenSim.Framework
{
public class Culture
{
private static readonly CultureInfo m_cultureInfo = new CultureInfo("en-US", true);
public static NumberFormatInfo NumberFormatInfo
{
get { return m_cultureInfo.NumberFormat; }
}
public static IFormatProvider FormatProvider
{
get { return m_cultureInfo; }
}
public static void SetCurrentCulture()
{
Thread.CurrentThread.CurrentCulture = m_cultureInfo;
}
}
}

View File

@ -0,0 +1,177 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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 libsecondlife;
namespace OpenSim.Framework.Data.DB4o
{
/// <summary>
/// A grid server storage mechanism employing the DB4o database system
/// </summary>
internal class DB4oGridData : IGridData
{
/// <summary>
/// The database manager object
/// </summary>
private DB4oGridManager manager;
/// <summary>
/// Called when the plugin is first loaded (as constructors are not called)
/// </summary>
public void Initialise()
{
manager = new DB4oGridManager("gridserver.yap");
}
/// <summary>
/// Returns a list of regions within the specified ranges
/// </summary>
/// <param name="a">minimum X coordinate</param>
/// <param name="b">minimum Y coordinate</param>
/// <param name="c">maximum X coordinate</param>
/// <param name="d">maximum Y coordinate</param>
/// <returns>An array of region profiles</returns>
public RegionProfileData[] GetProfilesInRange(uint a, uint b, uint c, uint d)
{
return null;
}
/// <summary>
/// Returns a region located at the specified regionHandle (warning multiple regions may occupy the one spot, first found is returned)
/// </summary>
/// <param name="handle">The handle to search for</param>
/// <returns>A region profile</returns>
public RegionProfileData GetProfileByHandle(ulong handle)
{
lock (manager.simProfiles)
{
foreach (LLUUID UUID in manager.simProfiles.Keys)
{
if (manager.simProfiles[UUID].regionHandle == handle)
{
return manager.simProfiles[UUID];
}
}
}
throw new Exception("Unable to find profile with handle (" + handle.ToString() + ")");
}
/// <summary>
/// Returns a specific region
/// </summary>
/// <param name="uuid">The region ID code</param>
/// <returns>A region profile</returns>
public RegionProfileData GetProfileByLLUUID(LLUUID uuid)
{
lock (manager.simProfiles)
{
if (manager.simProfiles.ContainsKey(uuid))
return manager.simProfiles[uuid];
}
throw new Exception("Unable to find profile with UUID (" + uuid.ToString() +
"). Total Registered Regions: " + manager.simProfiles.Count);
}
/// <summary>
/// Adds a new specified region to the database
/// </summary>
/// <param name="profile">The profile to add</param>
/// <returns>A dataresponse enum indicating success</returns>
public DataResponse AddProfile(RegionProfileData profile)
{
lock (manager.simProfiles)
{
if (manager.AddRow(profile))
{
return DataResponse.RESPONSE_OK;
}
else
{
return DataResponse.RESPONSE_ERROR;
}
}
}
/// <summary>
/// Authenticates a new region using the shared secrets. NOT SECURE.
/// </summary>
/// <param name="uuid">The UUID the region is authenticating with</param>
/// <param name="handle">The location the region is logging into (unused in Db4o)</param>
/// <param name="key">The shared secret</param>
/// <returns>Authenticated?</returns>
public bool AuthenticateSim(LLUUID uuid, ulong handle, string key)
{
if (manager.simProfiles[uuid].regionRecvKey == key)
return true;
return false;
}
/// <summary>
/// Shuts down the database
/// </summary>
public void Close()
{
manager = null;
}
/// <summary>
/// // Returns a list of avatar and UUIDs that match the query
/// </summary>
public List<AvatarPickerAvatar> GeneratePickerResults(LLUUID queryID, string query)
{
//Do nothing yet
List<AvatarPickerAvatar> returnlist = new List<AvatarPickerAvatar>();
return returnlist;
}
/// <summary>
/// Returns the providers name
/// </summary>
/// <returns>The name of the storage system</returns>
public string getName()
{
return "DB4o Grid Provider";
}
/// <summary>
/// Returns the providers version
/// </summary>
/// <returns>The version of the storage system</returns>
public string getVersion()
{
return "0.1";
}
public ReservationData GetReservationAtPoint(uint x, uint y)
{
return null;
}
}
}

View File

@ -0,0 +1,170 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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 Db4objects.Db4o;
using libsecondlife;
namespace OpenSim.Framework.Data.DB4o
{
/// <summary>
/// A Database manager for Db4o
/// </summary>
internal class DB4oGridManager
{
/// <summary>
/// A list of the current regions connected (in-memory cache)
/// </summary>
public Dictionary<LLUUID, RegionProfileData> simProfiles = new Dictionary<LLUUID, RegionProfileData>();
/// <summary>
/// Database File Name
/// </summary>
private string dbfl;
/// <summary>
/// Creates a new grid storage manager
/// </summary>
/// <param name="db4odb">Filename to the database file</param>
public DB4oGridManager(string db4odb)
{
dbfl = db4odb;
IObjectContainer database;
database = Db4oFactory.OpenFile(dbfl);
IObjectSet result = database.Get(typeof (RegionProfileData));
// Loads the file into the in-memory cache
foreach (RegionProfileData row in result)
{
simProfiles.Add(row.UUID, row);
}
database.Close();
}
/// <summary>
/// Adds a new profile to the database (Warning: Probably slow.)
/// </summary>
/// <param name="row">The profile to add</param>
/// <returns>Successful?</returns>
public bool AddRow(RegionProfileData row)
{
if (simProfiles.ContainsKey(row.UUID))
{
simProfiles[row.UUID] = row;
}
else
{
simProfiles.Add(row.UUID, row);
}
try
{
IObjectContainer database;
database = Db4oFactory.OpenFile(dbfl);
database.Set(row);
database.Close();
return true;
}
catch (Exception)
{
return false;
}
}
}
/// <summary>
/// A manager for the DB4o database (user profiles)
/// </summary>
internal class DB4oUserManager
{
/// <summary>
/// A list of the user profiles (in memory cache)
/// </summary>
public Dictionary<LLUUID, UserProfileData> userProfiles = new Dictionary<LLUUID, UserProfileData>();
/// <summary>
/// Database filename
/// </summary>
private string dbfl;
/// <summary>
/// Initialises a new DB manager
/// </summary>
/// <param name="db4odb">The filename to the database</param>
public DB4oUserManager(string db4odb)
{
dbfl = db4odb;
IObjectContainer database;
database = Db4oFactory.OpenFile(dbfl);
// Load to cache
IObjectSet result = database.Get(typeof (UserProfileData));
foreach (UserProfileData row in result)
{
if (userProfiles.ContainsKey(row.UUID))
userProfiles[row.UUID] = row;
else
userProfiles.Add(row.UUID, row);
}
database.Close();
}
/// <summary>
/// Adds or updates a record to the user database. Do this when changes are needed
/// in the user profile that need to be persistant.
///
/// TODO: the logic here is not ACID, the local cache will be
/// updated even if the persistant data is not. This may lead
/// to unexpected results.
/// </summary>
/// <param name="record">The profile to update</param>
/// <returns>true on success, false on fail to persist to db</returns>
public bool UpdateRecord(UserProfileData record)
{
if (userProfiles.ContainsKey(record.UUID))
{
userProfiles[record.UUID] = record;
}
else
{
userProfiles.Add(record.UUID, record);
}
try
{
IObjectContainer database;
database = Db4oFactory.OpenFile(dbfl);
database.Set(record);
database.Close();
return true;
}
catch (Exception)
{
return false;
}
}
}
}

View File

@ -0,0 +1,277 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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.IO;
using libsecondlife;
namespace OpenSim.Framework.Data.DB4o
{
/// <summary>
/// A User storage interface for the DB4o database system
/// </summary>
public class DB4oUserData : IUserData
{
/// <summary>
/// The database manager
/// </summary>
private DB4oUserManager manager;
/// <summary>
/// Artificial constructor called upon plugin load
/// </summary>
public void Initialise()
{
manager = new DB4oUserManager(Path.Combine(Util.dataDir(), "userprofiles.yap"));
}
/// <summary>
/// Loads a specified user profile from a UUID
/// </summary>
/// <param name="uuid">The users UUID</param>
/// <returns>A user profile</returns>
public UserProfileData GetUserByUUID(LLUUID uuid)
{
if (manager.userProfiles.ContainsKey(uuid))
return manager.userProfiles[uuid];
return null;
}
/// <summary>
/// Loads a specified user profile from a account
/// </summary>
/// <param name="uuid">The users account</param>
/// <returns>A user profile</returns>
public UserProfileData GetUserByAccount(string account)
{
if (manager.userProfiles.ContainsKey(account))
return manager.userProfiles[account];
return null;
}
/// <summary>
/// Returns a user by searching for its name
/// </summary>
/// <param name="name">The users account name</param>
/// <returns>A matching users profile</returns>
public UserProfileData GetUserByName(string name)
{
return GetUserByName(name.Split(' ')[0], name.Split(' ')[1]);
}
/// <summary>
/// Returns a user by searching for its name
/// </summary>
/// <param name="fname">The first part of the users account name</param>
/// <param name="lname">The second part of the users account name</param>
/// <returns>A matching users profile</returns>
public UserProfileData GetUserByName(string fname, string lname)
{
foreach (UserProfileData profile in manager.userProfiles.Values)
{
if (profile.username == fname && profile.surname == lname)
return profile;
}
return null;
}
/// <summary>
/// Returns a user by UUID direct
/// </summary>
/// <param name="uuid">The users account ID</param>
/// <returns>A matching users profile</returns>
public UserAgentData GetAgentByUUID(LLUUID uuid)
{
try
{
return GetUserByUUID(uuid).currentAgent;
}
catch (Exception)
{
return null;
}
}
/// <summary>
/// Returns a session by account name
/// </summary>
/// <param name="name">The account name</param>
/// <returns>The users session agent</returns>
public UserAgentData GetAgentByName(string name)
{
return GetAgentByName(name.Split(' ')[0], name.Split(' ')[1]);
}
/// <summary>
/// Returns a session by account name
/// </summary>
/// <param name="fname">The first part of the users account name</param>
/// <param name="lname">The second part of the users account name</param>
/// <returns>A user agent</returns>
public UserAgentData GetAgentByName(string fname, string lname)
{
try
{
return GetUserByName(fname, lname).currentAgent;
}
catch (Exception)
{
return null;
}
}
#region User Friends List Data
public void AddNewUserFriend(LLUUID friendlistowner, LLUUID friend, uint perms)
{
//MainLog.Instance.Verbose("FRIEND", "Stub AddNewUserFriend called");
}
public void RemoveUserFriend(LLUUID friendlistowner, LLUUID friend)
{
//MainLog.Instance.Verbose("FRIEND", "Stub RemoveUserFriend called");
}
public void UpdateUserFriendPerms(LLUUID friendlistowner, LLUUID friend, uint perms)
{
//MainLog.Instance.Verbose("FRIEND", "Stub UpdateUserFriendPerms called");
}
public List<FriendListItem> GetUserFriendList(LLUUID friendlistowner)
{
//MainLog.Instance.Verbose("FRIEND", "Stub GetUserFriendList called");
return new List<FriendListItem>();
}
#endregion
public void UpdateUserCurrentRegion(LLUUID avatarid, LLUUID regionuuid)
{
//MainLog.Instance.Verbose("USER", "Stub UpdateUserCUrrentRegion called");
}
public void LogOffUser(LLUUID avatarid)
{
//MainLog.Instance.Verbose("USER", "Stub LogOffUser called");
}
public List<Framework.AvatarPickerAvatar> GeneratePickerResults(LLUUID queryID, string query)
{
//Do nothing yet
List<Framework.AvatarPickerAvatar> returnlist = new List<Framework.AvatarPickerAvatar>();
return returnlist;
}
/// <summary>
/// Creates a new user profile
/// </summary>
/// <param name="user">The profile to add to the database</param>
public void AddNewUserProfile(UserProfileData user)
{
try
{
manager.UpdateRecord(user);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
/// <summary>
/// Creates a new user profile
/// </summary>
/// <param name="user">The profile to add to the database</param>
/// <returns>True on success, false on error</returns>
public bool UpdateUserProfile(UserProfileData user)
{
try
{
return manager.UpdateRecord(user);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
return false;
}
}
/// <summary>
/// Creates a new user agent
/// </summary>
/// <param name="agent">The agent to add to the database</param>
public void AddNewUserAgent(UserAgentData agent)
{
// Do nothing. yet.
}
/// <summary>
/// Transfers money between two user accounts
/// </summary>
/// <param name="from">Starting account</param>
/// <param name="to">End account</param>
/// <param name="amount">The amount to move</param>
/// <returns>Success?</returns>
public bool MoneyTransferRequest(LLUUID from, LLUUID to, uint amount)
{
return true;
}
/// <summary>
/// Transfers inventory between two accounts
/// </summary>
/// <remarks>Move to inventory server</remarks>
/// <param name="from">Senders account</param>
/// <param name="to">Receivers account</param>
/// <param name="item">Inventory item</param>
/// <returns>Success?</returns>
public bool InventoryTransferRequest(LLUUID from, LLUUID to, LLUUID item)
{
return true;
}
/// <summary>
/// Returns the name of the storage provider
/// </summary>
/// <returns>Storage provider name</returns>
public string getName()
{
return "DB4o Userdata";
}
/// <summary>
/// Returns the version of the storage provider
/// </summary>
/// <returns>Storage provider version</returns>
public string GetVersion()
{
return "0.1";
}
}
}

View File

@ -0,0 +1,38 @@
using System.Reflection;
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("OpenSim.Framework.Data.DB4o")]
[assembly : AssemblyDescription("")]
[assembly : AssemblyConfiguration("")]
[assembly : AssemblyCompany("")]
[assembly : AssemblyProduct("OpenSim.Framework.Data.DB4o")]
[assembly : AssemblyCopyright("Copyright © 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("57991e15-79da-41b7-aa06-2e6b49165a63")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly : AssemblyVersion("1.0.0.0")]
[assembly : AssemblyFileVersion("1.0.0.0")]

View File

@ -0,0 +1,240 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS 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 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.Data;
using System.Data.SqlClient;
using libsecondlife;
using OpenSim.Framework.Console;
namespace OpenSim.Framework.Data.MSSQL
{
internal class MSSQLAssetData : IAssetProvider
{
private MSSQLManager database;
#region IAssetProvider Members
private void UpgradeAssetsTable(string tableName)
{
// null as the version, indicates that the table didn't exist
if (tableName == null)
{
MainLog.Instance.Notice("ASSETS", "Creating new database tables");
database.ExecuteResourceSql("CreateAssetsTable.sql");
return;
}
}
/// <summary>
/// Ensure that the assets related tables exists and are at the latest version
/// </summary>
private void TestTables()
{
Dictionary<string, string> tableList = new Dictionary<string, string>();
tableList["assets"] = null;
database.GetTableVersion(tableList);
UpgradeAssetsTable(tableList["assets"]);
}
public AssetBase FetchAsset(LLUUID assetID)
{
AssetBase asset = null;
Dictionary<string, string> param = new Dictionary<string, string>();
param["id"] = assetID.ToString();
IDbCommand result = database.Query("SELECT * FROM assets WHERE id = @id", param);
IDataReader reader = result.ExecuteReader();
asset = database.getAssetRow(reader);
reader.Close();
result.Dispose();
return asset;
}
public void CreateAsset(AssetBase asset)
{
if (ExistsAsset((LLUUID) asset.FullID))
{
return;
}
SqlCommand cmd =
new SqlCommand(
"INSERT INTO assets ([id], [name], [mediaUrl], [description], [assetType], [invType], [local], [temporary], [data])" +
" VALUES " +
"(@id, @name, @mediaUrl, @description, @assetType, @invType, @local, @temporary, @data)",
database.getConnection());
using (cmd)
{
//SqlParameter p = cmd.Parameters.Add("id", SqlDbType.NVarChar);
//p.Value = asset.FullID.ToString();
cmd.Parameters.AddWithValue("id", asset.FullID.ToString());
cmd.Parameters.AddWithValue("name", asset.Name);
cmd.Parameters.AddWithValue("mediaUrl", asset.MediaURL);
cmd.Parameters.AddWithValue("description", asset.Description);
SqlParameter e = cmd.Parameters.Add("assetType", SqlDbType.TinyInt);
e.Value = asset.Type;
SqlParameter f = cmd.Parameters.Add("invType", SqlDbType.TinyInt);
f.Value = asset.InvType;
SqlParameter g = cmd.Parameters.Add("local", SqlDbType.TinyInt);
g.Value = asset.Local;
SqlParameter h = cmd.Parameters.Add("temporary", SqlDbType.TinyInt);
h.Value = asset.Temporary;
SqlParameter i = cmd.Parameters.Add("data", SqlDbType.Image);
i.Value = asset.Data;
try
{
cmd.ExecuteNonQuery();
}
catch (Exception)
{
throw;
}
cmd.Dispose();
}
}
public void UpdateAsset(AssetBase asset)
{
SqlCommand command = new SqlCommand("UPDATE assets set id = @id, " +
"name = @name, " +
"mediaUrl = @mediaUrl, "+
"description = @description," +
"assetType = @assetType," +
"invType = @invType," +
"local = @local," +
"temporary = @temporary," +
"data = @data where " +
"id = @keyId;", database.getConnection());
SqlParameter param1 = new SqlParameter("@id", asset.FullID.ToString());
SqlParameter param2 = new SqlParameter("@name", asset.Name);
SqlParameter param3 = new SqlParameter("@mediaUrl", asset.MediaURL);
SqlParameter param4 = new SqlParameter("@description", asset.Description);
SqlParameter param5 = new SqlParameter("@assetType", Convert.ToBoolean(asset.Type));
SqlParameter param6 = new SqlParameter("@invType", Convert.ToBoolean(asset.InvType));
SqlParameter param7 = new SqlParameter("@local", asset.Local);
SqlParameter param8 = new SqlParameter("@temporary", asset.Temporary);
SqlParameter param9 = new SqlParameter("@data", asset.Data);
SqlParameter param10 = new SqlParameter("@keyId", asset.FullID.ToString());
command.Parameters.Add(param1);
command.Parameters.Add(param2);
command.Parameters.Add(param3);
command.Parameters.Add(param4);
command.Parameters.Add(param5);
command.Parameters.Add(param6);
command.Parameters.Add(param7);
command.Parameters.Add(param8);
command.Parameters.Add(param9);
command.Parameters.Add(param10);
try
{
command.ExecuteNonQuery();
}
catch (Exception e)
{
MainLog.Instance.Error(e.ToString());
}
}
public bool ExistsAsset(LLUUID uuid)
{
if (FetchAsset(uuid) != null)
{
return true;
}
return false;
}
// rex, new function, fixme not implemented
public List<AssetBase> GetAssetList(int vAssetType)
{
List<AssetBase> retvals = new List<AssetBase>();
return retvals;
}
/// <summary>
/// All writes are immediately commited to the database, so this is a no-op
/// </summary>
public void CommitAssets()
{
}
// rex new function for "replace assets" functionality
// TODO: actual implementation by someone, should return LLUUID of an asset
// with matching type & name, or zero if not in DB
public LLUUID ExistsAsset(sbyte type, string name)
{
return LLUUID.Zero;
}
#endregion
#region IPlugin Members
public void Initialise()
{
IniFile GridDataMySqlFile = new IniFile("mssql_connection.ini");
string settingDataSource = GridDataMySqlFile.ParseFileReadValue("data_source");
string settingInitialCatalog = GridDataMySqlFile.ParseFileReadValue("initial_catalog");
string settingPersistSecurityInfo = GridDataMySqlFile.ParseFileReadValue("persist_security_info");
string settingUserId = GridDataMySqlFile.ParseFileReadValue("user_id");
string settingPassword = GridDataMySqlFile.ParseFileReadValue("password");
database =
new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId,
settingPassword);
TestTables();
}
public string Version
{
// get { return database.getVersion(); }
get { return database.getVersion(); }
}
public string Name
{
get { return "MSSQL Asset storage engine"; }
}
#endregion
}
}

View File

@ -0,0 +1,309 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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.Data;
using System.Security.Cryptography;
using System.Text;
using libsecondlife;
using OpenSim.Framework.Console;
namespace OpenSim.Framework.Data.MSSQL
{
/// <summary>
/// A grid data interface for Microsoft SQL Server
/// </summary>
public class SqlGridData : IGridData
{
/// <summary>
/// Database manager
/// </summary>
private MSSQLManager database;
/// <summary>
/// Initialises the Grid Interface
/// </summary>
public void Initialise()
{
IniFile GridDataMySqlFile = new IniFile("mssql_connection.ini");
string settingDataSource = GridDataMySqlFile.ParseFileReadValue("data_source");
string settingInitialCatalog = GridDataMySqlFile.ParseFileReadValue("initial_catalog");
string settingPersistSecurityInfo = GridDataMySqlFile.ParseFileReadValue("persist_security_info");
string settingUserId = GridDataMySqlFile.ParseFileReadValue("user_id");
string settingPassword = GridDataMySqlFile.ParseFileReadValue("password");
database =
new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId,
settingPassword);
}
/// <summary>
/// Shuts down the grid interface
/// </summary>
public void Close()
{
database.Close();
}
/// <summary>
/// Returns the storage system name
/// </summary>
/// <returns>A string containing the storage system name</returns>
public string getName()
{
return "Sql OpenGridData";
}
/// <summary>
/// Returns the storage system version
/// </summary>
/// <returns>A string containing the storage system version</returns>
public string getVersion()
{
return "0.1";
}
/// <summary>
/// Returns a list of regions within the specified ranges
/// </summary>
/// <param name="a">minimum X coordinate</param>
/// <param name="b">minimum Y coordinate</param>
/// <param name="c">maximum X coordinate</param>
/// <param name="d">maximum Y coordinate</param>
/// <returns>An array of region profiles</returns>
public RegionProfileData[] GetProfilesInRange(uint a, uint b, uint c, uint d)
{
return null;
}
/// <summary>
/// Returns a sim profile from it's location
/// </summary>
/// <param name="handle">Region location handle</param>
/// <returns>Sim profile</returns>
public RegionProfileData GetProfileByHandle(ulong handle)
{
IDataReader reader = null;
try
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["handle"] = handle.ToString();
IDbCommand result = database.Query("SELECT * FROM regions WHERE regionHandle = @handle", param);
reader = result.ExecuteReader();
RegionProfileData row = database.getRegionRow(reader);
reader.Close();
result.Dispose();
return row;
}
catch (Exception)
{
if (reader != null)
{
reader.Close();
}
}
return null;
}
/// <summary>
/// // Returns a list of avatar and UUIDs that match the query
/// </summary>
public List<AvatarPickerAvatar> GeneratePickerResults(LLUUID queryID, string query)
{
List<AvatarPickerAvatar> returnlist = new List<AvatarPickerAvatar>();
string[] querysplit;
querysplit = query.Split(' ');
if (querysplit.Length == 2)
{
try
{
lock (database)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["first"] = querysplit[0];
param["second"] = querysplit[1];
IDbCommand result =
database.Query(
"SELECT UUID,username,surname FROM users WHERE username = @first AND lastname = @second",
param);
IDataReader reader = result.ExecuteReader();
while (reader.Read())
{
AvatarPickerAvatar user = new AvatarPickerAvatar();
user.AvatarID = new LLUUID((string) reader["UUID"]);
user.firstName = (string) reader["username"];
user.lastName = (string) reader["surname"];
returnlist.Add(user);
}
reader.Close();
result.Dispose();
}
}
catch (Exception e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
return returnlist;
}
}
else if (querysplit.Length == 1)
{
try
{
lock (database)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["first"] = querysplit[0];
param["second"] = querysplit[1];
IDbCommand result =
database.Query(
"SELECT UUID,username,surname FROM users WHERE username = @first OR lastname = @second",
param);
IDataReader reader = result.ExecuteReader();
while (reader.Read())
{
AvatarPickerAvatar user = new AvatarPickerAvatar();
user.AvatarID = new LLUUID((string) reader["UUID"]);
user.firstName = (string) reader["username"];
user.lastName = (string) reader["surname"];
returnlist.Add(user);
}
reader.Close();
result.Dispose();
}
}
catch (Exception e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
return returnlist;
}
}
return returnlist;
}
/// <summary>
/// Returns a sim profile from it's UUID
/// </summary>
/// <param name="uuid">The region UUID</param>
/// <returns>The sim profile</returns>
public RegionProfileData GetProfileByLLUUID(LLUUID uuid)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["uuid"] = uuid.ToString();
IDbCommand result = database.Query("SELECT * FROM regions WHERE uuid = @uuid", param);
IDataReader reader = result.ExecuteReader();
RegionProfileData row = database.getRegionRow(reader);
reader.Close();
result.Dispose();
return row;
}
/// <summary>
/// Adds a new specified region to the database
/// </summary>
/// <param name="profile">The profile to add</param>
/// <returns>A dataresponse enum indicating success</returns>
public DataResponse AddProfile(RegionProfileData profile)
{
try
{
if (GetProfileByLLUUID(profile.UUID) != null)
{
return DataResponse.RESPONSE_OK;
}
}
catch (Exception)
{
System.Console.WriteLine("No regions found. Create new one.");
}
if (database.insertRegionRow(profile))
{
return DataResponse.RESPONSE_OK;
}
else
{
return DataResponse.RESPONSE_ERROR;
}
}
/// <summary>
/// DEPRECIATED. Attempts to authenticate a region by comparing a shared secret.
/// </summary>
/// <param name="uuid">The UUID of the challenger</param>
/// <param name="handle">The attempted regionHandle of the challenger</param>
/// <param name="authkey">The secret</param>
/// <returns>Whether the secret and regionhandle match the database entry for UUID</returns>
public bool AuthenticateSim(LLUUID uuid, ulong handle, string authkey)
{
bool throwHissyFit = false; // Should be true by 1.0
if (throwHissyFit)
throw new Exception("CRYPTOWEAK AUTHENTICATE: Refusing to authenticate due to replay potential.");
RegionProfileData data = GetProfileByLLUUID(uuid);
return (handle == data.regionHandle && authkey == data.regionSecret);
}
/// <summary>
/// NOT YET FUNCTIONAL. Provides a cryptographic authentication of a region
/// </summary>
/// <remarks>This requires a security audit.</remarks>
/// <param name="uuid"></param>
/// <param name="handle"></param>
/// <param name="authhash"></param>
/// <param name="challenge"></param>
/// <returns></returns>
public bool AuthenticateSim(LLUUID uuid, ulong handle, string authhash, string challenge)
{
SHA512Managed HashProvider = new SHA512Managed();
ASCIIEncoding TextProvider = new ASCIIEncoding();
byte[] stream = TextProvider.GetBytes(uuid.ToString() + ":" + handle.ToString() + ":" + challenge);
byte[] hash = HashProvider.ComputeHash(stream);
return false;
}
public ReservationData GetReservationAtPoint(uint x, uint y)
{
return null;
}
}
}

View File

@ -0,0 +1,726 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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.Data;
using System.Data.SqlClient;
using libsecondlife;
using OpenSim.Framework.Console;
namespace OpenSim.Framework.Data.MSSQL
{
/// <summary>
/// A MySQL interface for the inventory server
/// </summary>
public class MSSQLInventoryData : IInventoryData
{
/// <summary>
/// The database manager
/// </summary>
private MSSQLManager database;
/// <summary>
/// Loads and initialises this database plugin
/// </summary>
public void Initialise()
{
IniFile GridDataMySqlFile = new IniFile("mssql_connection.ini");
string settingDataSource = GridDataMySqlFile.ParseFileReadValue("data_source");
string settingInitialCatalog = GridDataMySqlFile.ParseFileReadValue("initial_catalog");
string settingPersistSecurityInfo = GridDataMySqlFile.ParseFileReadValue("persist_security_info");
string settingUserId = GridDataMySqlFile.ParseFileReadValue("user_id");
string settingPassword = GridDataMySqlFile.ParseFileReadValue("password");
database =
new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId,
settingPassword);
TestTables();
}
#region Test and initialization code
private void UpgradeFoldersTable(string tableName)
{
// null as the version, indicates that the table didn't exist
if (tableName == null)
{
database.ExecuteResourceSql("CreateFoldersTable.sql");
//database.ExecuteResourceSql("UpgradeFoldersTableToVersion2.sql");
return;
}
}
private void UpgradeItemsTable(string tableName)
{
// null as the version, indicates that the table didn't exist
if (tableName == null)
{
database.ExecuteResourceSql("CreateItemsTable.sql");
//database.ExecuteResourceSql("UpgradeItemsTableToVersion2.sql");
return;
}
}
private void TestTables()
{
Dictionary<string, string> tableList = new Dictionary<string, string>();
tableList["inventoryfolders"] = null;
tableList["inventoryitems"] = null;
database.GetTableVersion(tableList);
UpgradeFoldersTable(tableList["inventoryfolders"]);
UpgradeItemsTable(tableList["inventoryitems"]);
}
#endregion
/// <summary>
/// The name of this DB provider
/// </summary>
/// <returns>Name of DB provider</returns>
public string getName()
{
return "MSSQL Inventory Data Interface";
}
/// <summary>
/// Closes this DB provider
/// </summary>
public void Close()
{
// Do nothing.
}
/// <summary>
/// Returns the version of this DB provider
/// </summary>
/// <returns>A string containing the DB provider</returns>
public string getVersion()
{
return database.getVersion();
}
/// <summary>
/// Returns a list of items in a specified folder
/// </summary>
/// <param name="folderID">The folder to search</param>
/// <returns>A list containing inventory items</returns>
public List<InventoryItemBase> getInventoryInFolder(LLUUID folderID)
{
try
{
lock (database)
{
List<InventoryItemBase> items = new List<InventoryItemBase>();
Dictionary<string, string> param = new Dictionary<string, string>();
param["parentFolderID"] = folderID.ToString();
IDbCommand result =
database.Query("SELECT * FROM inventoryitems WHERE parentFolderID = @parentFolderID", param);
IDataReader reader = result.ExecuteReader();
while (reader.Read())
items.Add(readInventoryItem(reader));
reader.Close();
result.Dispose();
return items;
}
}
catch (Exception e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
return null;
}
}
/// <summary>
/// Returns a list of the root folders within a users inventory
/// </summary>
/// <param name="user">The user whos inventory is to be searched</param>
/// <returns>A list of folder objects</returns>
public List<InventoryFolderBase> getUserRootFolders(LLUUID user)
{
try
{
lock (database)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["uuid"] = user.ToString();
param["zero"] = LLUUID.Zero.ToString();
IDbCommand result =
database.Query(
"SELECT * FROM inventoryfolders WHERE parentFolderID = @zero AND agentID = @uuid", param);
IDataReader reader = result.ExecuteReader();
List<InventoryFolderBase> items = new List<InventoryFolderBase>();
while (reader.Read())
items.Add(readInventoryFolder(reader));
reader.Close();
result.Dispose();
return items;
}
}
catch (Exception e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
return null;
}
}
// see InventoryItemBase.getUserRootFolder
public InventoryFolderBase getUserRootFolder(LLUUID user)
{
try
{
lock (database)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["uuid"] = user.ToString();
param["zero"] = LLUUID.Zero.ToString();
IDbCommand result =
database.Query(
"SELECT * FROM inventoryfolders WHERE parentFolderID = @zero AND agentID = @uuid", param);
IDataReader reader = result.ExecuteReader();
List<InventoryFolderBase> items = new List<InventoryFolderBase>();
while (reader.Read())
items.Add(readInventoryFolder(reader));
InventoryFolderBase rootFolder = null;
// There should only ever be one root folder for a user. However, if there's more
// than one we'll simply use the first one rather than failing. It would be even
// nicer to print some message to this effect, but this feels like it's too low a
// to put such a message out, and it's too minor right now to spare the time to
// suitably refactor.
if (items.Count > 0)
{
rootFolder = items[0];
}
reader.Close();
result.Dispose();
return rootFolder;
}
}
catch (Exception e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
return null;
}
}
/// <summary>
/// Returns a list of folders in a users inventory contained within the specified folder
/// </summary>
/// <param name="parentID">The folder to search</param>
/// <returns>A list of inventory folders</returns>
public List<InventoryFolderBase> getInventoryFolders(LLUUID parentID)
{
try
{
lock (database)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["parentFolderID"] = parentID.ToString();
IDbCommand result =
database.Query("SELECT * FROM inventoryfolders WHERE parentFolderID = @parentFolderID", param);
IDataReader reader = result.ExecuteReader();
List<InventoryFolderBase> items = new List<InventoryFolderBase>();
while (reader.Read())
items.Add(readInventoryFolder(reader));
reader.Close();
result.Dispose();
return items;
}
}
catch (Exception e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
return null;
}
}
/// <summary>
/// Reads a one item from an SQL result
/// </summary>
/// <param name="reader">The SQL Result</param>
/// <returns>the item read</returns>
private InventoryItemBase readInventoryItem(IDataReader reader)
{
try
{
InventoryItemBase item = new InventoryItemBase();
item.inventoryID = new LLUUID((string) reader["inventoryID"]);
item.assetID = new LLUUID((string) reader["assetID"]);
item.assetType = (int) reader["assetType"];
item.parentFolderID = new LLUUID((string) reader["parentFolderID"]);
item.avatarID = new LLUUID((string) reader["avatarID"]);
item.inventoryName = (string) reader["inventoryName"];
item.inventoryDescription = (string) reader["inventoryDescription"];
item.inventoryNextPermissions = Convert.ToUInt32(reader["inventoryNextPermissions"]);
item.inventoryCurrentPermissions = Convert.ToUInt32(reader["inventoryCurrentPermissions"]);
item.invType = (int) reader["invType"];
item.creatorsID = new LLUUID((string) reader["creatorID"]);
item.inventoryBasePermissions = Convert.ToUInt32(reader["inventoryBasePermissions"]);
item.inventoryEveryOnePermissions = Convert.ToUInt32(reader["inventoryEveryOnePermissions"]);
return item;
}
catch (SqlException e)
{
MainLog.Instance.Error(e.ToString());
}
return null;
}
/// <summary>
/// Returns a specified inventory item
/// </summary>
/// <param name="item">The item to return</param>
/// <returns>An inventory item</returns>
public InventoryItemBase getInventoryItem(LLUUID itemID)
{
try
{
lock (database)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["inventoryID"] = itemID.ToString();
IDbCommand result =
database.Query("SELECT * FROM inventoryitems WHERE inventoryID = @inventoryID", param);
IDataReader reader = result.ExecuteReader();
InventoryItemBase item = null;
if (reader.Read())
item = readInventoryItem(reader);
reader.Close();
result.Dispose();
return item;
}
}
catch (Exception e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
}
return null;
}
/// <summary>
/// Reads a list of inventory folders returned by a query.
/// </summary>
/// <param name="reader">A MySQL Data Reader</param>
/// <returns>A List containing inventory folders</returns>
protected InventoryFolderBase readInventoryFolder(IDataReader reader)
{
try
{
InventoryFolderBase folder = new InventoryFolderBase();
folder.agentID = new LLUUID((string) reader["agentID"]);
folder.parentID = new LLUUID((string) reader["parentFolderID"]);
folder.folderID = new LLUUID((string) reader["folderID"]);
folder.name = (string) reader["folderName"];
folder.type = (short) reader["type"];
folder.version = (ushort) ((int) reader["version"]);
return folder;
}
catch (Exception e)
{
MainLog.Instance.Error(e.ToString());
}
return null;
}
/// <summary>
/// Returns a specified inventory folder
/// </summary>
/// <param name="folder">The folder to return</param>
/// <returns>A folder class</returns>
public InventoryFolderBase getInventoryFolder(LLUUID folderID)
{
try
{
lock (database)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["uuid"] = folderID.ToString();
IDbCommand result = database.Query("SELECT * FROM inventoryfolders WHERE folderID = @uuid", param);
IDataReader reader = result.ExecuteReader();
reader.Read();
InventoryFolderBase folder = readInventoryFolder(reader);
reader.Close();
result.Dispose();
return folder;
}
}
catch (Exception e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
return null;
}
}
/// <summary>
/// Adds a specified item to the database
/// </summary>
/// <param name="item">The inventory item</param>
public void addInventoryItem(InventoryItemBase item)
{
string sql = "INSERT INTO inventoryitems";
sql +=
"([inventoryID], [assetID], [assetType], [parentFolderID], [avatarID], [inventoryName], [inventoryDescription], [inventoryNextPermissions], [inventoryCurrentPermissions], [invType], [creatorID], [inventoryBasePermissions], [inventoryEveryOnePermissions]) VALUES ";
sql +=
"(@inventoryID, @assetID, @assetType, @parentFolderID, @avatarID, @inventoryName, @inventoryDescription, @inventoryNextPermissions, @inventoryCurrentPermissions, @invType, @creatorID, @inventoryBasePermissions, @inventoryEveryOnePermissions);";
try
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["inventoryID"] = item.inventoryID.ToString();
param["assetID"] = item.assetID.ToString();
param["assetType"] = item.assetType.ToString();
param["parentFolderID"] = item.parentFolderID.ToString();
param["avatarID"] = item.avatarID.ToString();
param["inventoryName"] = item.inventoryName;
param["inventoryDescription"] = item.inventoryDescription;
param["inventoryNextPermissions"] = item.inventoryNextPermissions.ToString();
param["inventoryCurrentPermissions"] = item.inventoryCurrentPermissions.ToString();
param["invType"] = Convert.ToString(item.invType);
param["creatorID"] = item.creatorsID.ToString();
param["inventoryBasePermissions"] = Convert.ToString(item.inventoryBasePermissions);
param["inventoryEveryOnePermissions"] = Convert.ToString(item.inventoryEveryOnePermissions);
IDbCommand result = database.Query(sql, param);
result.ExecuteNonQuery();
result.Dispose();
}
catch (SqlException e)
{
MainLog.Instance.Error(e.ToString());
}
}
/// <summary>
/// Updates the specified inventory item
/// </summary>
/// <param name="item">Inventory item to update</param>
public void updateInventoryItem(InventoryItemBase item)
{
SqlCommand command = new SqlCommand("UPDATE inventoryitems set inventoryID = @inventoryID, " +
"assetID = @assetID, " +
"assetType = @assetType" +
"parentFolderID = @parentFolderID" +
"avatarID = @avatarID" +
"inventoryName = @inventoryName" +
"inventoryDescription = @inventoryDescription" +
"inventoryNextPermissions = @inventoryNextPermissions" +
"inventoryCurrentPermissions = @inventoryCurrentPermissions" +
"invType = @invType" +
"creatorID = @creatorID" +
"inventoryBasePermissions = @inventoryBasePermissions" +
"inventoryEveryOnePermissions = @inventoryEveryOnePermissions) where " +
"inventoryID = @keyInventoryID;", database.getConnection());
SqlParameter param1 = new SqlParameter("@inventoryID", item.inventoryID.ToString());
SqlParameter param2 = new SqlParameter("@assetID", item.assetID);
SqlParameter param3 = new SqlParameter("@assetType", item.assetType);
SqlParameter param4 = new SqlParameter("@parentFolderID", item.parentFolderID);
SqlParameter param5 = new SqlParameter("@avatarID", item.avatarID);
SqlParameter param6 = new SqlParameter("@inventoryName", item.inventoryName);
SqlParameter param7 = new SqlParameter("@inventoryDescription", item.inventoryDescription);
SqlParameter param8 = new SqlParameter("@inventoryNextPermissions", item.inventoryNextPermissions);
SqlParameter param9 = new SqlParameter("@inventoryCurrentPermissions", item.inventoryCurrentPermissions);
SqlParameter param10 = new SqlParameter("@invType", item.invType);
SqlParameter param11 = new SqlParameter("@creatorID", item.creatorsID);
SqlParameter param12 = new SqlParameter("@inventoryBasePermissions", item.inventoryBasePermissions);
SqlParameter param13 = new SqlParameter("@inventoryEveryOnePermissions", item.inventoryEveryOnePermissions);
SqlParameter param14 = new SqlParameter("@keyInventoryID", item.inventoryID.ToString());
command.Parameters.Add(param1);
command.Parameters.Add(param2);
command.Parameters.Add(param3);
command.Parameters.Add(param4);
command.Parameters.Add(param5);
command.Parameters.Add(param6);
command.Parameters.Add(param7);
command.Parameters.Add(param8);
command.Parameters.Add(param9);
command.Parameters.Add(param10);
command.Parameters.Add(param11);
command.Parameters.Add(param12);
command.Parameters.Add(param13);
command.Parameters.Add(param14);
try
{
command.ExecuteNonQuery();
}
catch (Exception e)
{
MainLog.Instance.Error(e.ToString());
}
}
/// <summary>
///
/// </summary>
/// <param name="item"></param>
public void deleteInventoryItem(LLUUID itemID)
{
try
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["uuid"] = itemID.ToString();
IDbCommand cmd = database.Query("DELETE FROM inventoryitems WHERE inventoryID=@uuid", param);
cmd.ExecuteNonQuery();
cmd.Dispose();
}
catch (SqlException e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
}
}
/// <summary>
/// Creates a new inventory folder
/// </summary>
/// <param name="folder">Folder to create</param>
public void addInventoryFolder(InventoryFolderBase folder)
{
string sql =
"INSERT INTO inventoryfolders ([folderID], [agentID], [parentFolderID], [folderName], [type], [version]) VALUES ";
sql += "(@folderID, @agentID, @parentFolderID, @folderName, @type, @version);";
Dictionary<string, string> param = new Dictionary<string, string>();
param["folderID"] = folder.folderID.ToString();
param["agentID"] = folder.agentID.ToString();
param["parentFolderID"] = folder.parentID.ToString();
param["folderName"] = folder.name;
param["type"] = Convert.ToString(folder.type);
param["version"] = Convert.ToString(folder.version);
try
{
IDbCommand result = database.Query(sql, param);
result.ExecuteNonQuery();
result.Dispose();
}
catch (Exception e)
{
MainLog.Instance.Error(e.ToString());
}
}
/// <summary>
/// Updates an inventory folder
/// </summary>
/// <param name="folder">Folder to update</param>
public void updateInventoryFolder(InventoryFolderBase folder)
{
SqlCommand command = new SqlCommand("UPDATE inventoryfolders set folderID = @folderID, " +
"agentID = @agentID, " +
"parentFolderID = @parentFolderID," +
"folderName = @folderName," +
"type = @type," +
"version = @version where " +
"folderID = @keyFolderID;", database.getConnection());
SqlParameter param1 = new SqlParameter("@folderID", folder.folderID.ToString());
SqlParameter param2 = new SqlParameter("@agentID", folder.agentID.ToString());
SqlParameter param3 = new SqlParameter("@parentFolderID", folder.parentID.ToString());
SqlParameter param4 = new SqlParameter("@folderName", folder.name);
SqlParameter param5 = new SqlParameter("@type", folder.type);
SqlParameter param6 = new SqlParameter("@version", folder.version);
SqlParameter param7 = new SqlParameter("@keyFolderID", folder.folderID.ToString());
command.Parameters.Add(param1);
command.Parameters.Add(param2);
command.Parameters.Add(param3);
command.Parameters.Add(param4);
command.Parameters.Add(param5);
command.Parameters.Add(param6);
command.Parameters.Add(param7);
try
{
command.ExecuteNonQuery();
}
catch (Exception e)
{
MainLog.Instance.Error(e.ToString());
}
}
/// <summary>
/// Updates an inventory folder
/// </summary>
/// <param name="folder">Folder to update</param>
public void moveInventoryFolder(InventoryFolderBase folder)
{
SqlCommand command = new SqlCommand("UPDATE inventoryfolders set folderID = @folderID, " +
"parentFolderID = @parentFolderID," +
"folderID = @keyFolderID;", database.getConnection());
SqlParameter param1 = new SqlParameter("@folderID", folder.folderID.ToString());
SqlParameter param2 = new SqlParameter("@parentFolderID", folder.parentID.ToString());
SqlParameter param3 = new SqlParameter("@keyFolderID", folder.folderID.ToString());
command.Parameters.Add(param1);
command.Parameters.Add(param2);
command.Parameters.Add(param3);
try
{
command.ExecuteNonQuery();
}
catch (Exception e)
{
MainLog.Instance.Error(e.ToString());
}
}
/// <summary>
/// Append a list of all the child folders of a parent folder
/// </summary>
/// <param name="folders">list where folders will be appended</param>
/// <param name="parentID">ID of parent</param>
protected void getInventoryFolders(ref List<InventoryFolderBase> folders, LLUUID parentID)
{
List<InventoryFolderBase> subfolderList = getInventoryFolders(parentID);
foreach (InventoryFolderBase f in subfolderList)
folders.Add(f);
}
/// <summary>
/// Returns all child folders in the hierarchy from the parent folder and down
/// </summary>
/// <param name="parentID">The folder to get subfolders for</param>
/// <returns>A list of inventory folders</returns>
protected List<InventoryFolderBase> getFolderHierarchy(LLUUID parentID)
{
List<InventoryFolderBase> folders = new List<InventoryFolderBase>();
getInventoryFolders(ref folders, parentID);
for (int i = 0; i < folders.Count; i++)
getInventoryFolders(ref folders, folders[i].folderID);
return folders;
}
protected void deleteOneFolder(LLUUID folderID)
{
try
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["folderID"] = folderID.ToString();
IDbCommand cmd = database.Query("DELETE FROM inventoryfolders WHERE folderID=@folderID", param);
cmd.ExecuteNonQuery();
cmd.Dispose();
}
catch (SqlException e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
}
}
protected void deleteItemsInFolder(LLUUID folderID)
{
try
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["parentFolderID"] = folderID.ToString();
IDbCommand cmd =
database.Query("DELETE FROM inventoryitems WHERE parentFolderID=@parentFolderID", param);
cmd.ExecuteNonQuery();
cmd.Dispose();
}
catch (SqlException e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
}
}
/// <summary>
/// Delete an inventory folder
/// </summary>
/// <param name="folderId">Id of folder to delete</param>
public void deleteInventoryFolder(LLUUID folderID)
{
lock (database)
{
List<InventoryFolderBase> subFolders = getFolderHierarchy(folderID);
//Delete all sub-folders
foreach (InventoryFolderBase f in subFolders)
{
deleteOneFolder(f.folderID);
deleteItemsInFolder(f.folderID);
}
//Delete the actual row
deleteOneFolder(folderID);
deleteItemsInFolder(folderID);
}
}
}
}

View File

@ -0,0 +1,105 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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.
*
*/
namespace OpenSim.Framework.Data.MSSQL
{
/// <summary>
/// An interface to the log database for MySQL
/// </summary>
internal class MSSQLLogData : ILogData
{
/// <summary>
/// The database manager
/// </summary>
public MSSQLManager database;
/// <summary>
/// Artificial constructor called when the plugin is loaded
/// </summary>
public void Initialise()
{
IniFile GridDataMySqlFile = new IniFile("mssql_connection.ini");
string settingDataSource = GridDataMySqlFile.ParseFileReadValue("data_source");
string settingInitialCatalog = GridDataMySqlFile.ParseFileReadValue("initial_catalog");
string settingPersistSecurityInfo = GridDataMySqlFile.ParseFileReadValue("persist_security_info");
string settingUserId = GridDataMySqlFile.ParseFileReadValue("user_id");
string settingPassword = GridDataMySqlFile.ParseFileReadValue("password");
database =
new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId,
settingPassword);
}
/// <summary>
/// Saves a log item to the database
/// </summary>
/// <param name="serverDaemon">The daemon triggering the event</param>
/// <param name="target">The target of the action (region / agent UUID, etc)</param>
/// <param name="methodCall">The method call where the problem occured</param>
/// <param name="arguments">The arguments passed to the method</param>
/// <param name="priority">How critical is this?</param>
/// <param name="logMessage">The message to log</param>
public void saveLog(string serverDaemon, string target, string methodCall, string arguments, int priority,
string logMessage)
{
try
{
database.insertLogRow(serverDaemon, target, methodCall, arguments, priority, logMessage);
}
catch
{
database.Reconnect();
}
}
/// <summary>
/// Returns the name of this DB provider
/// </summary>
/// <returns>A string containing the DB provider name</returns>
public string getName()
{
return "MSSQL Logdata Interface";
}
/// <summary>
/// Closes the database provider
/// </summary>
public void Close()
{
// Do nothing.
}
/// <summary>
/// Returns the version of this DB provider
/// </summary>
/// <returns>A string containing the provider version</returns>
public string getVersion()
{
return "0.1";
}
}
}

View File

@ -0,0 +1,769 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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.Data;
using System.Data.SqlClient;
using System.IO;
using System.Reflection;
using libsecondlife;
using OpenSim.Framework.Console;
namespace OpenSim.Framework.Data.MSSQL
{
/// <summary>
/// A management class for the MS SQL Storage Engine
/// </summary>
internal class MSSQLManager
{
/// <summary>
/// The database connection object
/// </summary>
private IDbConnection dbcon;
/// <summary>
/// Connection string for ADO.net
/// </summary>
private string connectionString;
/// <summary>
/// Initialises and creates a new Sql connection and maintains it.
/// </summary>
/// <param name="hostname">The Sql server being connected to</param>
/// <param name="database">The name of the Sql database being used</param>
/// <param name="username">The username logging into the database</param>
/// <param name="password">The password for the user logging in</param>
/// <param name="cpooling">Whether to use connection pooling or not, can be one of the following: 'yes', 'true', 'no' or 'false', if unsure use 'false'.</param>
public MSSQLManager(string dataSource, string initialCatalog, string persistSecurityInfo, string userId,
string password)
{
try
{
connectionString = "Data Source=" + dataSource + ";Initial Catalog=" + initialCatalog +
";Persist Security Info=" + persistSecurityInfo + ";User ID=" + userId + ";Password=" +
password + ";";
dbcon = new SqlConnection(connectionString);
TestTables(dbcon);
//System.Threading.Thread.Sleep(3000);
dbcon.Open();
}
catch (Exception e)
{
throw new Exception("Error initialising Sql Database: " + e.ToString());
}
}
private bool TestTables(IDbConnection conn)
{
IDbCommand cmd = Query("SELECT * FROM regions", new Dictionary<string, string>());
//SqlCommand cmd = (SqlCommand)dbcon.CreateCommand();
//cmd.CommandText = "SELECT * FROM regions";
try
{
conn.Open();
cmd.ExecuteNonQuery();
cmd.Dispose();
conn.Close();
}
catch (Exception)
{
MainLog.Instance.Verbose("DATASTORE", "MSSQL Database doesn't exist... creating");
InitDB(conn);
}
cmd = Query("select top 1 webLoginKey from users", new Dictionary<string, string>());
try
{
conn.Open();
cmd.ExecuteNonQuery();
cmd.Dispose();
conn.Close();
}
catch (Exception)
{
conn.Close();
conn.Open();
cmd = Query("alter table users add [webLoginKey] varchar(36) default NULL", new Dictionary<string, string>());
cmd.ExecuteNonQuery();
cmd.Dispose();
conn.Close();
}
return true;
}
private void InitDB(IDbConnection conn)
{
string createRegions = defineTable(createRegionsTable());
Dictionary<string, string> param = new Dictionary<string, string>();
IDbCommand pcmd = Query(createRegions, param);
if (conn.State == ConnectionState.Closed)
{
conn.Open();
}
pcmd.ExecuteNonQuery();
pcmd.Dispose();
ExecuteResourceSql("Mssql-users.sql");
ExecuteResourceSql("Mssql-agents.sql");
ExecuteResourceSql("Mssql-logs.sql");
conn.Close();
}
private DataTable createRegionsTable()
{
DataTable regions = new DataTable("regions");
createCol(regions, "regionHandle", typeof (ulong));
createCol(regions, "regionName", typeof (String));
createCol(regions, "uuid", typeof (String));
createCol(regions, "regionRecvKey", typeof (String));
createCol(regions, "regionSecret", typeof (String));
createCol(regions, "regionSendKey", typeof (String));
createCol(regions, "regionDataURI", typeof (String));
createCol(regions, "serverIP", typeof (String));
createCol(regions, "serverPort", typeof (String));
createCol(regions, "serverURI", typeof (String));
createCol(regions, "locX", typeof (uint));
createCol(regions, "locY", typeof (uint));
createCol(regions, "locZ", typeof (uint));
createCol(regions, "eastOverrideHandle", typeof (ulong));
createCol(regions, "westOverrideHandle", typeof (ulong));
createCol(regions, "southOverrideHandle", typeof (ulong));
createCol(regions, "northOverrideHandle", typeof (ulong));
createCol(regions, "regionAssetURI", typeof (String));
createCol(regions, "regionAssetRecvKey", typeof (String));
createCol(regions, "regionAssetSendKey", typeof (String));
createCol(regions, "regionUserURI", typeof (String));
createCol(regions, "regionUserRecvKey", typeof (String));
createCol(regions, "regionUserSendKey", typeof (String));
createCol(regions, "regionMapTexture", typeof (String));
createCol(regions, "serverHttpPort", typeof (String));
createCol(regions, "serverRemotingPort", typeof (uint));
// Add in contraints
regions.PrimaryKey = new DataColumn[] {regions.Columns["UUID"]};
return regions;
}
protected static void createCol(DataTable dt, string name, Type type)
{
DataColumn col = new DataColumn(name, type);
dt.Columns.Add(col);
}
protected static string defineTable(DataTable dt)
{
string sql = "create table " + dt.TableName + "(";
string subsql = "";
foreach (DataColumn col in dt.Columns)
{
if (subsql.Length > 0)
{
// a map function would rock so much here
subsql += ",\n";
}
subsql += col.ColumnName + " " + SqlType(col.DataType);
if (col == dt.PrimaryKey[0])
{
subsql += " primary key";
}
}
sql += subsql;
sql += ")";
return sql;
}
// this is something we'll need to implement for each db
// slightly differently.
private static string SqlType(Type type)
{
if (type == typeof (String))
{
return "varchar(255)";
}
else if (type == typeof (Int32))
{
return "integer";
}
else if (type == typeof (Double))
{
return "float";
}
else if (type == typeof (Byte[]))
{
return "image";
}
else
{
return "varchar(255)";
}
}
/// <summary>
/// Shuts down the database connection
/// </summary>
public void Close()
{
dbcon.Close();
dbcon = null;
}
/// <summary>
/// Reconnects to the database
/// </summary>
public void Reconnect()
{
lock (dbcon)
{
try
{
//string connectionString = "Data Source=WRK-OU-738\\SQLEXPRESS;Initial Catalog=rex;Persist Security Info=True;User ID=sa;Password=rex";
// Close the DB connection
dbcon.Close();
// Try reopen it
dbcon = new SqlConnection(connectionString);
dbcon.Open();
}
catch (Exception e)
{
MainLog.Instance.Error("Unable to reconnect to database " + e.ToString());
}
}
}
/// <summary>
/// Runs a query with protection against SQL Injection by using parameterised input.
/// </summary>
/// <param name="sql">The SQL string - replace any variables such as WHERE x = "y" with WHERE x = @y</param>
/// <param name="parameters">The parameters - index so that @y is indexed as 'y'</param>
/// <returns>A Sql DB Command</returns>
public IDbCommand Query(string sql, Dictionary<string, string> parameters)
{
SqlCommand dbcommand = (SqlCommand) dbcon.CreateCommand();
dbcommand.CommandText = sql;
foreach (KeyValuePair<string, string> param in parameters)
{
dbcommand.Parameters.AddWithValue(param.Key, param.Value);
}
return (IDbCommand) dbcommand;
}
/// <summary>
/// Runs a database reader object and returns a region row
/// </summary>
/// <param name="reader">An active database reader</param>
/// <returns>A region row</returns>
public RegionProfileData getRegionRow(IDataReader reader)
{
RegionProfileData regionprofile = new RegionProfileData();
if (reader.Read())
{
// Region Main
regionprofile.regionHandle = Convert.ToUInt64(reader["regionHandle"]);
regionprofile.regionName = (string) reader["regionName"];
regionprofile.UUID = new LLUUID((string) reader["uuid"]);
// Secrets
regionprofile.regionRecvKey = (string) reader["regionRecvKey"];
regionprofile.regionSecret = (string) reader["regionSecret"];
regionprofile.regionSendKey = (string) reader["regionSendKey"];
// Region Server
regionprofile.regionDataURI = (string) reader["regionDataURI"];
regionprofile.regionOnline = false; // Needs to be pinged before this can be set.
regionprofile.serverIP = (string) reader["serverIP"];
regionprofile.serverPort = Convert.ToUInt32(reader["serverPort"]);
regionprofile.serverURI = (string) reader["serverURI"];
regionprofile.httpPort = Convert.ToUInt32(reader["serverHttpPort"]);
regionprofile.remotingPort = Convert.ToUInt32(reader["serverRemotingPort"]);
// Location
regionprofile.regionLocX = Convert.ToUInt32(reader["locX"]);
regionprofile.regionLocY = Convert.ToUInt32(reader["locY"]);
regionprofile.regionLocZ = Convert.ToUInt32(reader["locZ"]);
// Neighbours - 0 = No Override
regionprofile.regionEastOverrideHandle = Convert.ToUInt64(reader["eastOverrideHandle"]);
regionprofile.regionWestOverrideHandle = Convert.ToUInt64(reader["westOverrideHandle"]);
regionprofile.regionSouthOverrideHandle = Convert.ToUInt64(reader["southOverrideHandle"]);
regionprofile.regionNorthOverrideHandle = Convert.ToUInt64(reader["northOverrideHandle"]);
// Assets
regionprofile.regionAssetURI = (string) reader["regionAssetURI"];
regionprofile.regionAssetRecvKey = (string) reader["regionAssetRecvKey"];
regionprofile.regionAssetSendKey = (string) reader["regionAssetSendKey"];
// Userserver
regionprofile.regionUserURI = (string) reader["regionUserURI"];
regionprofile.regionUserRecvKey = (string) reader["regionUserRecvKey"];
regionprofile.regionUserSendKey = (string) reader["regionUserSendKey"];
// World Map Addition
string tempRegionMap = reader["regionMapTexture"].ToString();
if (tempRegionMap != "")
{
regionprofile.regionMapTextureID = new LLUUID(tempRegionMap);
}
else
{
regionprofile.regionMapTextureID = new LLUUID();
}
}
else
{
reader.Close();
throw new Exception("No rows to return");
}
return regionprofile;
}
/// <summary>
/// Reads a user profile from an active data reader
/// </summary>
/// <param name="reader">An active database reader</param>
/// <returns>A user profile</returns>
public UserProfileData readUserRow(IDataReader reader)
{
UserProfileData retval = new UserProfileData();
if (reader.Read())
{
retval.UUID = new LLUUID((string) reader["UUID"]);
retval.username = (string) reader["username"];
retval.surname = (string) reader["lastname"];
retval.passwordHash = (string) reader["passwordHash"];
retval.passwordSalt = (string) reader["passwordSalt"];
retval.homeRegion = Convert.ToUInt64(reader["homeRegion"].ToString());
retval.homeLocation = new LLVector3(
Convert.ToSingle(reader["homeLocationX"].ToString()),
Convert.ToSingle(reader["homeLocationY"].ToString()),
Convert.ToSingle(reader["homeLocationZ"].ToString()));
retval.homeLookAt = new LLVector3(
Convert.ToSingle(reader["homeLookAtX"].ToString()),
Convert.ToSingle(reader["homeLookAtY"].ToString()),
Convert.ToSingle(reader["homeLookAtZ"].ToString()));
retval.created = Convert.ToInt32(reader["created"].ToString());
retval.lastLogin = Convert.ToInt32(reader["lastLogin"].ToString());
retval.userInventoryURI = (string) reader["userInventoryURI"];
retval.userAssetURI = (string) reader["userAssetURI"];
retval.profileCanDoMask = Convert.ToUInt32(reader["profileCanDoMask"].ToString());
retval.profileWantDoMask = Convert.ToUInt32(reader["profileWantDoMask"].ToString());
retval.profileAboutText = (string) reader["profileAboutText"];
retval.profileFirstText = (string) reader["profileFirstText"];
retval.profileImage = new LLUUID((string) reader["profileImage"]);
retval.profileFirstImage = new LLUUID((string) reader["profileFirstImage"]);
retval.webLoginKey = new LLUUID((string)reader["webLoginKey"]);
}
else
{
return null;
}
return retval;
}
/// <summary>
/// Reads an agent row from a database reader
/// </summary>
/// <param name="reader">An active database reader</param>
/// <returns>A user session agent</returns>
public UserAgentData readAgentRow(IDataReader reader)
{
UserAgentData retval = new UserAgentData();
if (reader.Read())
{
// Agent IDs
retval.UUID = new LLUUID((string) reader["UUID"]);
retval.sessionID = new LLUUID((string) reader["sessionID"]);
retval.secureSessionID = new LLUUID((string) reader["secureSessionID"]);
// Agent Who?
retval.agentIP = (string) reader["agentIP"];
retval.agentPort = Convert.ToUInt32(reader["agentPort"].ToString());
retval.agentOnline = Convert.ToBoolean(reader["agentOnline"].ToString());
// Login/Logout times (UNIX Epoch)
retval.loginTime = Convert.ToInt32(reader["loginTime"].ToString());
retval.logoutTime = Convert.ToInt32(reader["logoutTime"].ToString());
// Current position
retval.currentRegion = (string) reader["currentRegion"];
retval.currentHandle = Convert.ToUInt64(reader["currentHandle"].ToString());
LLVector3.TryParse((string) reader["currentPos"], out retval.currentPos);
}
else
{
return null;
}
return retval;
}
public AssetBase getAssetRow(IDataReader reader)
{
AssetBase asset = new AssetBase();
if (reader.Read())
{
// Region Main
asset = new AssetBase();
asset.Data = (byte[]) reader["data"];
asset.Description = (string) reader["description"];
asset.MediaURL = (string)reader["mediaUrl"];
asset.FullID = new LLUUID((string) reader["id"]);
asset.InvType = Convert.ToSByte(reader["invType"]);
asset.Local = Convert.ToBoolean(reader["local"]); // ((sbyte)reader["local"]) != 0 ? true : false;
asset.Name = (string) reader["name"];
asset.Type = Convert.ToSByte(reader["assetType"]);
}
else
{
return null; // throw new Exception("No rows to return");
}
return asset;
}
/// <summary>
/// Creates a new region in the database
/// </summary>
/// <param name="profile">The region profile to insert</param>
/// <returns>Successful?</returns>
public bool insertRegionRow(RegionProfileData profile)
{
//Insert new region
string sql =
"INSERT INTO regions ([regionHandle], [regionName], [uuid], [regionRecvKey], [regionSecret], [regionSendKey], [regionDataURI], ";
sql +=
"[serverIP], [serverPort], [serverURI], [locX], [locY], [locZ], [eastOverrideHandle], [westOverrideHandle], [southOverrideHandle], [northOverrideHandle], [regionAssetURI], [regionAssetRecvKey], ";
sql +=
"[regionAssetSendKey], [regionUserURI], [regionUserRecvKey], [regionUserSendKey], [regionMapTexture], [serverHttpPort], [serverRemotingPort]) VALUES ";
sql += "(@regionHandle, @regionName, @uuid, @regionRecvKey, @regionSecret, @regionSendKey, @regionDataURI, ";
sql +=
"@serverIP, @serverPort, @serverURI, @locX, @locY, @locZ, @eastOverrideHandle, @westOverrideHandle, @southOverrideHandle, @northOverrideHandle, @regionAssetURI, @regionAssetRecvKey, ";
sql +=
"@regionAssetSendKey, @regionUserURI, @regionUserRecvKey, @regionUserSendKey, @regionMapTexture, @serverHttpPort, @serverRemotingPort);";
Dictionary<string, string> parameters = new Dictionary<string, string>();
parameters["regionHandle"] = profile.regionHandle.ToString();
parameters["regionName"] = profile.regionName;
parameters["uuid"] = profile.UUID.ToString();
parameters["regionRecvKey"] = profile.regionRecvKey;
parameters["regionSecret"] = profile.regionSecret;
parameters["regionSendKey"] = profile.regionSendKey;
parameters["regionDataURI"] = profile.regionDataURI;
parameters["serverIP"] = profile.serverIP;
parameters["serverPort"] = profile.serverPort.ToString();
parameters["serverURI"] = profile.serverURI;
parameters["locX"] = profile.regionLocX.ToString();
parameters["locY"] = profile.regionLocY.ToString();
parameters["locZ"] = profile.regionLocZ.ToString();
parameters["eastOverrideHandle"] = profile.regionEastOverrideHandle.ToString();
parameters["westOverrideHandle"] = profile.regionWestOverrideHandle.ToString();
parameters["northOverrideHandle"] = profile.regionNorthOverrideHandle.ToString();
parameters["southOverrideHandle"] = profile.regionSouthOverrideHandle.ToString();
parameters["regionAssetURI"] = profile.regionAssetURI;
parameters["regionAssetRecvKey"] = profile.regionAssetRecvKey;
parameters["regionAssetSendKey"] = profile.regionAssetSendKey;
parameters["regionUserURI"] = profile.regionUserURI;
parameters["regionUserRecvKey"] = profile.regionUserRecvKey;
parameters["regionUserSendKey"] = profile.regionUserSendKey;
parameters["regionMapTexture"] = profile.regionMapTextureID.ToString();
parameters["serverHttpPort"] = profile.httpPort.ToString();
parameters["serverRemotingPort"] = profile.remotingPort.ToString();
bool returnval = false;
try
{
IDbCommand result = Query(sql, parameters);
if (result.ExecuteNonQuery() == 1)
returnval = true;
result.Dispose();
}
catch (Exception e)
{
MainLog.Instance.Error("MSSQLManager : " + e.ToString());
}
return returnval;
}
/// <summary>
/// Inserts a new row into the log database
/// </summary>
/// <param name="serverDaemon">The daemon which triggered this event</param>
/// <param name="target">Who were we operating on when this occured (region UUID, user UUID, etc)</param>
/// <param name="methodCall">The method call where the problem occured</param>
/// <param name="arguments">The arguments passed to the method</param>
/// <param name="priority">How critical is this?</param>
/// <param name="logMessage">Extra message info</param>
/// <returns>Saved successfully?</returns>
public bool insertLogRow(string serverDaemon, string target, string methodCall, string arguments, int priority,
string logMessage)
{
string sql = "INSERT INTO logs ([target], [server], [method], [arguments], [priority], [message]) VALUES ";
sql += "(@target, @server, @method, @arguments, @priority, @message);";
Dictionary<string, string> parameters = new Dictionary<string, string>();
parameters["server"] = serverDaemon;
parameters["target"] = target;
parameters["method"] = methodCall;
parameters["arguments"] = arguments;
parameters["priority"] = priority.ToString();
parameters["message"] = logMessage;
bool returnval = false;
try
{
IDbCommand result = Query(sql, parameters);
if (result.ExecuteNonQuery() == 1)
returnval = true;
result.Dispose();
}
catch (Exception e)
{
MainLog.Instance.Error(e.ToString());
return false;
}
return returnval;
}
/// <summary>
/// Creates a new user and inserts it into the database
/// </summary>
/// <param name="uuid">User ID</param>
/// <param name="username">First part of the login</param>
/// <param name="lastname">Second part of the login</param>
/// <param name="passwordHash">A salted hash of the users password</param>
/// <param name="passwordSalt">The salt used for the password hash</param>
/// <param name="homeRegion">A regionHandle of the users home region</param>
/// <param name="homeLocX">Home region position vector</param>
/// <param name="homeLocY">Home region position vector</param>
/// <param name="homeLocZ">Home region position vector</param>
/// <param name="homeLookAtX">Home region 'look at' vector</param>
/// <param name="homeLookAtY">Home region 'look at' vector</param>
/// <param name="homeLookAtZ">Home region 'look at' vector</param>
/// <param name="created">Account created (unix timestamp)</param>
/// <param name="lastlogin">Last login (unix timestamp)</param>
/// <param name="inventoryURI">Users inventory URI</param>
/// <param name="assetURI">Users asset URI</param>
/// <param name="canDoMask">I can do mask</param>
/// <param name="wantDoMask">I want to do mask</param>
/// <param name="aboutText">Profile text</param>
/// <param name="firstText">Firstlife text</param>
/// <param name="profileImage">UUID for profile image</param>
/// <param name="firstImage">UUID for firstlife image</param>
/// <returns>Success?</returns>
public bool insertUserRow(LLUUID uuid, string username, string lastname, string passwordHash,
string passwordSalt, UInt64 homeRegion, float homeLocX, float homeLocY, float homeLocZ,
float homeLookAtX, float homeLookAtY, float homeLookAtZ, int created, int lastlogin,
string inventoryURI, string assetURI, uint canDoMask, uint wantDoMask,
string aboutText, string firstText,
LLUUID profileImage, LLUUID firstImage, LLUUID webLoginKey)
{
string sql = "INSERT INTO users ";
sql += "([UUID], [username], [lastname], [passwordHash], [passwordSalt], [homeRegion], ";
sql +=
"[homeLocationX], [homeLocationY], [homeLocationZ], [homeLookAtX], [homeLookAtY], [homeLookAtZ], [created], ";
sql +=
"[lastLogin], [userInventoryURI], [userAssetURI], [profileCanDoMask], [profileWantDoMask], [profileAboutText], ";
sql += "[profileFirstText], [profileImage], [profileFirstImage], [webLoginKey]) VALUES ";
sql += "(@UUID, @username, @lastname, @passwordHash, @passwordSalt, @homeRegion, ";
sql +=
"@homeLocationX, @homeLocationY, @homeLocationZ, @homeLookAtX, @homeLookAtY, @homeLookAtZ, @created, ";
sql +=
"@lastLogin, @userInventoryURI, @userAssetURI, @profileCanDoMask, @profileWantDoMask, @profileAboutText, ";
sql += "@profileFirstText, @profileImage, @profileFirstImage, @webLoginKey);";
Dictionary<string, string> parameters = new Dictionary<string, string>();
parameters["UUID"] = uuid.ToString();
parameters["username"] = username.ToString();
parameters["lastname"] = lastname.ToString();
parameters["passwordHash"] = passwordHash.ToString();
parameters["passwordSalt"] = passwordSalt.ToString();
parameters["homeRegion"] = homeRegion.ToString();
parameters["homeLocationX"] = homeLocX.ToString();
parameters["homeLocationY"] = homeLocY.ToString();
parameters["homeLocationZ"] = homeLocZ.ToString();
parameters["homeLookAtX"] = homeLookAtX.ToString();
parameters["homeLookAtY"] = homeLookAtY.ToString();
parameters["homeLookAtZ"] = homeLookAtZ.ToString();
parameters["created"] = created.ToString();
parameters["lastLogin"] = lastlogin.ToString();
parameters["userInventoryURI"] = "";
parameters["userAssetURI"] = "";
parameters["profileCanDoMask"] = "0";
parameters["profileWantDoMask"] = "0";
parameters["profileAboutText"] = "";
parameters["profileFirstText"] = "";
parameters["profileImage"] = LLUUID.Zero.ToString();
parameters["profileFirstImage"] = LLUUID.Zero.ToString();
parameters["webLoginKey"] = LLUUID.Random().ToString();
bool returnval = false;
try
{
IDbCommand result = Query(sql, parameters);
if (result.ExecuteNonQuery() == 1)
returnval = true;
result.Dispose();
}
catch (Exception e)
{
MainLog.Instance.Error(e.ToString());
return false;
}
return returnval;
}
/// <summary>
/// Execute a SQL statement stored in a resource, as a string
/// </summary>
/// <param name="name"></param>
public void ExecuteResourceSql(string name)
{
try
{
SqlCommand cmd = new SqlCommand(getResourceString(name), (SqlConnection) dbcon);
cmd.ExecuteNonQuery();
cmd.Dispose();
}
catch (Exception e)
{
MainLog.Instance.Error("Unable to execute query " + e.ToString());
}
}
public SqlConnection getConnection()
{
return (SqlConnection) dbcon;
}
/// <summary>
/// Given a list of tables, return the version of the tables, as seen in the database
/// </summary>
/// <param name="tableList"></param>
public void GetTableVersion(Dictionary<string, string> tableList)
{
lock (dbcon)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["dbname"] = dbcon.Database;
IDbCommand tablesCmd =
Query("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_CATALOG=@dbname", param);
using (IDataReader tables = tablesCmd.ExecuteReader())
{
while (tables.Read())
{
try
{
string tableName = (string) tables["TABLE_NAME"];
if (tableList.ContainsKey(tableName))
tableList[tableName] = tableName;
}
catch (Exception e)
{
MainLog.Instance.Error(e.ToString());
}
}
tables.Close();
}
}
}
private string getResourceString(string name)
{
Assembly assem = GetType().Assembly;
string[] names = assem.GetManifestResourceNames();
foreach (string s in names)
if (s.EndsWith(name))
using (Stream resource = assem.GetManifestResourceStream(s))
{
using (StreamReader resourceReader = new StreamReader(resource))
{
string resourceString = resourceReader.ReadToEnd();
return resourceString;
}
}
throw new Exception(string.Format("Resource '{0}' was not found", name));
}
/// <summary>
/// Returns the version of this DB provider
/// </summary>
/// <returns>A string containing the DB provider</returns>
public string getVersion()
{
Module module = GetType().Module;
string dllName = module.Assembly.ManifestModule.Name;
Version dllVersion = module.Assembly.GetName().Version;
return
string.Format("{0}.{1}.{2}.{3}", dllVersion.Major, dllVersion.Minor, dllVersion.Build,
dllVersion.Revision);
}
}
}

View File

@ -0,0 +1,521 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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.Data;
using System.Data.SqlClient;
using libsecondlife;
using OpenSim.Framework.Console;
namespace OpenSim.Framework.Data.MSSQL
{
/// <summary>
/// A database interface class to a user profile storage system
/// </summary>
internal class MSSQLUserData : IUserData
{
/// <summary>
/// Database manager for MySQL
/// </summary>
public MSSQLManager database;
/// <summary>
/// Loads and initialises the MySQL storage plugin
/// </summary>
public void Initialise()
{
// Load from an INI file connection details
// TODO: move this to XML?
IniFile GridDataMySqlFile = new IniFile("mssql_connection.ini");
string settingDataSource = GridDataMySqlFile.ParseFileReadValue("data_source");
string settingInitialCatalog = GridDataMySqlFile.ParseFileReadValue("initial_catalog");
string settingPersistSecurityInfo = GridDataMySqlFile.ParseFileReadValue("persist_security_info");
string settingUserId = GridDataMySqlFile.ParseFileReadValue("user_id");
string settingPassword = GridDataMySqlFile.ParseFileReadValue("password");
database =
new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId,
settingPassword);
}
/// <summary>
/// Searches the database for a specified user profile by name components
/// </summary>
/// <param name="user">The first part of the account name</param>
/// <param name="last">The second part of the account name</param>
/// <returns>A user profile</returns>
public UserProfileData GetUserByName(string user, string last)
{
try
{
lock (database)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["first"] = user;
param["second"] = last;
IDbCommand result =
database.Query("SELECT * FROM users WHERE username = @first AND lastname = @second", param);
IDataReader reader = result.ExecuteReader();
UserProfileData row = database.readUserRow(reader);
reader.Close();
result.Dispose();
return row;
}
}
catch (Exception e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
return null;
}
}
#region User Friends List Data
public void AddNewUserFriend(LLUUID friendlistowner, LLUUID friend, uint perms)
{
MainLog.Instance.Verbose("FRIEND", "Stub AddNewUserFriend called");
}
public void RemoveUserFriend(LLUUID friendlistowner, LLUUID friend)
{
MainLog.Instance.Verbose("FRIEND", "Stub RemoveUserFriend called");
}
public void UpdateUserFriendPerms(LLUUID friendlistowner, LLUUID friend, uint perms)
{
MainLog.Instance.Verbose("FRIEND", "Stub UpdateUserFriendPerms called");
}
public List<FriendListItem> GetUserFriendList(LLUUID friendlistowner)
{
MainLog.Instance.Verbose("FRIEND", "Stub GetUserFriendList called");
return new List<FriendListItem>();
}
#endregion
public void UpdateUserCurrentRegion(LLUUID avatarid, LLUUID regionuuid)
{
MainLog.Instance.Verbose("USER", "Stub UpdateUserCUrrentRegion called");
}
public void LogOffUser(LLUUID avatarid)
{
MainLog.Instance.Verbose("USER", "Stub LogOffUser called");
}
public List<Framework.AvatarPickerAvatar> GeneratePickerResults(LLUUID queryID, string query)
{
List<Framework.AvatarPickerAvatar> returnlist = new List<Framework.AvatarPickerAvatar>();
string[] querysplit;
querysplit = query.Split(' ');
if (querysplit.Length == 2)
{
try
{
lock (database)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["first"] = querysplit[0];
param["second"] = querysplit[1];
IDbCommand result =
database.Query(
"SELECT UUID,username,surname FROM users WHERE username = @first AND lastname = @second",
param);
IDataReader reader = result.ExecuteReader();
while (reader.Read())
{
Framework.AvatarPickerAvatar user = new Framework.AvatarPickerAvatar();
user.AvatarID = new LLUUID((string) reader["UUID"]);
user.firstName = (string) reader["username"];
user.lastName = (string) reader["surname"];
returnlist.Add(user);
}
reader.Close();
result.Dispose();
}
}
catch (Exception e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
return returnlist;
}
}
else if (querysplit.Length == 1)
{
try
{
lock (database)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["first"] = querysplit[0];
param["second"] = querysplit[1];
IDbCommand result =
database.Query(
"SELECT UUID,username,surname FROM users WHERE username = @first OR lastname = @second",
param);
IDataReader reader = result.ExecuteReader();
while (reader.Read())
{
Framework.AvatarPickerAvatar user = new Framework.AvatarPickerAvatar();
user.AvatarID = new LLUUID((string) reader["UUID"]);
user.firstName = (string) reader["username"];
user.lastName = (string) reader["surname"];
returnlist.Add(user);
}
reader.Close();
result.Dispose();
}
}
catch (Exception e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
return returnlist;
}
}
return returnlist;
}
// See IUserData
public UserProfileData GetUserByUUID(LLUUID uuid)
{
try
{
lock (database)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["uuid"] = uuid.ToString();
IDbCommand result = database.Query("SELECT * FROM users WHERE UUID = @uuid", param);
IDataReader reader = result.ExecuteReader();
UserProfileData row = database.readUserRow(reader);
reader.Close();
result.Dispose();
return row;
}
}
catch (Exception e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
return null;
}
}
/// <summary>
/// Searches the database for a specified user profile by account
/// </summary>
/// <param name="uuid">The account</param>
/// <returns>The users profile</returns>
public UserProfileData GetUserByAccount(string account)
{
try
{
lock (database)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["account"] = account;
IDbCommand result = database.Query("SELECT * FROM users WHERE account = @account", param);
IDataReader reader = result.ExecuteReader();
UserProfileData row = database.readUserRow(reader);
reader.Close();
result.Dispose();
if (row != null)
{
UserAgentData agentData = GetAgentByUUID(row.UUID);
if (agentData != null)
{
row.currentAgent = agentData;
}
}
return row;
}
}
catch (Exception e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
return null;
}
}
/// <summary>
/// Returns a user session searching by name
/// </summary>
/// <param name="name">The account name</param>
/// <returns>The users session</returns>
public UserAgentData GetAgentByName(string name)
{
return GetAgentByName(name.Split(' ')[0], name.Split(' ')[1]);
}
/// <summary>
/// Returns a user session by account name
/// </summary>
/// <param name="user">First part of the users account name</param>
/// <param name="last">Second part of the users account name</param>
/// <returns>The users session</returns>
public UserAgentData GetAgentByName(string user, string last)
{
UserProfileData profile = GetUserByName(user, last);
return GetAgentByUUID(profile.UUID);
}
/// <summary>
/// Returns an agent session by account UUID
/// </summary>
/// <param name="uuid">The accounts UUID</param>
/// <returns>The users session</returns>
public UserAgentData GetAgentByUUID(LLUUID uuid)
{
try
{
lock (database)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["uuid"] = uuid.ToString();
IDbCommand result = database.Query("SELECT * FROM agents WHERE UUID = @uuid", param);
IDataReader reader = result.ExecuteReader();
UserAgentData row = database.readAgentRow(reader);
reader.Close();
result.Dispose();
return row;
}
}
catch (Exception e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
return null;
}
}
/// <summary>
/// Creates a new users profile
/// </summary>
/// <param name="user">The user profile to create</param>
public void AddNewUserProfile(UserProfileData user)
{
try
{
lock (database)
{
database.insertUserRow(user.UUID, user.username, user.surname, user.passwordHash, user.passwordSalt,
user.homeRegion, user.homeLocation.X, user.homeLocation.Y,
user.homeLocation.Z,
user.homeLookAt.X, user.homeLookAt.Y, user.homeLookAt.Z, user.created,
user.lastLogin, user.userInventoryURI, user.userAssetURI,
user.profileCanDoMask, user.profileWantDoMask,
user.profileAboutText, user.profileFirstText, user.profileImage,
user.profileFirstImage,user.webLoginKey);
}
}
catch (Exception e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
}
}
/// <summary>
/// Creates a new agent
/// </summary>
/// <param name="agent">The agent to create</param>
public void AddNewUserAgent(UserAgentData agent)
{
// Do nothing.
}
public bool UpdateUserProfile(UserProfileData user)
{
SqlCommand command = new SqlCommand("UPDATE users set UUID = @uuid, " +
"username = @username, " +
"lastname = @lastname," +
"passwordHash = @passwordHash," +
"passwordSalt = @passwordSalt," +
"homeRegion = @homeRegion," +
"homeLocationX = @homeLocationX," +
"homeLocationY = @homeLocationY," +
"homeLocationZ = @homeLocationZ," +
"homeLookAtX = @homeLookAtX," +
"homeLookAtY = @homeLookAtY," +
"homeLookAtZ = @homeLookAtZ," +
"created = @created," +
"lastLogin = @lastLogin," +
"userInventoryURI = @userInventoryURI," +
"userAssetURI = @userAssetURI," +
"profileCanDoMask = @profileCanDoMask," +
"profileWantDoMask = @profileWantDoMask," +
"profileAboutText = @profileAboutText," +
"profileFirstText = @profileFirstText," +
"profileImage = @profileImage," +
"profileFirstImage = @profileFirstImage where " +
"UUID = @keyUUUID;", database.getConnection());
SqlParameter param1 = new SqlParameter("@uuid", user.UUID.ToString());
SqlParameter param2 = new SqlParameter("@username", user.username);
SqlParameter param3 = new SqlParameter("@lastname", user.surname);
SqlParameter param4 = new SqlParameter("@passwordHash", user.passwordHash);
SqlParameter param5 = new SqlParameter("@passwordSalt", user.passwordSalt);
SqlParameter param6 = new SqlParameter("@homeRegion", Convert.ToInt64(user.homeRegion));
SqlParameter param7 = new SqlParameter("@homeLocationX", user.homeLocation.X);
SqlParameter param8 = new SqlParameter("@homeLocationY", user.homeLocation.Y);
SqlParameter param9 = new SqlParameter("@homeLocationZ", user.homeLocation.Y);
SqlParameter param10 = new SqlParameter("@homeLookAtX", user.homeLookAt.X);
SqlParameter param11 = new SqlParameter("@homeLookAtY", user.homeLookAt.Y);
SqlParameter param12 = new SqlParameter("@homeLookAtZ", user.homeLookAt.Z);
SqlParameter param13 = new SqlParameter("@created", Convert.ToInt32(user.created));
SqlParameter param14 = new SqlParameter("@lastLogin", Convert.ToInt32(user.lastLogin));
SqlParameter param15 = new SqlParameter("@userInventoryURI", user.userInventoryURI);
SqlParameter param16 = new SqlParameter("@userAssetURI", user.userAssetURI);
SqlParameter param17 = new SqlParameter("@profileCanDoMask", Convert.ToInt32(user.profileCanDoMask));
SqlParameter param18 = new SqlParameter("@profileWantDoMask", Convert.ToInt32(user.profileWantDoMask));
SqlParameter param19 = new SqlParameter("@profileAboutText", user.profileAboutText);
SqlParameter param20 = new SqlParameter("@profileFirstText", user.profileFirstText);
SqlParameter param21 = new SqlParameter("@profileImage", LLUUID.Zero.ToString());
SqlParameter param22 = new SqlParameter("@profileFirstImage", LLUUID.Zero.ToString());
SqlParameter param23 = new SqlParameter("@keyUUUID", user.UUID.ToString());
command.Parameters.Add(param1);
command.Parameters.Add(param2);
command.Parameters.Add(param3);
command.Parameters.Add(param4);
command.Parameters.Add(param5);
command.Parameters.Add(param6);
command.Parameters.Add(param7);
command.Parameters.Add(param8);
command.Parameters.Add(param9);
command.Parameters.Add(param10);
command.Parameters.Add(param11);
command.Parameters.Add(param12);
command.Parameters.Add(param13);
command.Parameters.Add(param14);
command.Parameters.Add(param15);
command.Parameters.Add(param16);
command.Parameters.Add(param17);
command.Parameters.Add(param18);
command.Parameters.Add(param19);
command.Parameters.Add(param20);
command.Parameters.Add(param21);
command.Parameters.Add(param22);
command.Parameters.Add(param23);
try
{
int affected = command.ExecuteNonQuery();
if (affected != 0)
{
return true;
}
else
{
return false;
}
}
catch (Exception e)
{
MainLog.Instance.Error(e.ToString());
}
return false;
}
/// <summary>
/// Performs a money transfer request between two accounts
/// </summary>
/// <param name="from">The senders account ID</param>
/// <param name="to">The receivers account ID</param>
/// <param name="amount">The amount to transfer</param>
/// <returns>Success?</returns>
public bool MoneyTransferRequest(LLUUID from, LLUUID to, uint amount)
{
return false;
}
/// <summary>
/// Performs an inventory transfer request between two accounts
/// </summary>
/// <remarks>TODO: Move to inventory server</remarks>
/// <param name="from">The senders account ID</param>
/// <param name="to">The receivers account ID</param>
/// <param name="item">The item to transfer</param>
/// <returns>Success?</returns>
public bool InventoryTransferRequest(LLUUID from, LLUUID to, LLUUID item)
{
return false;
}
/// <summary>
/// Database provider name
/// </summary>
/// <returns>Provider name</returns>
public string getName()
{
return "MSSQL Userdata Interface";
}
/// <summary>
/// Database provider version
/// </summary>
/// <returns>provider version</returns>
public string GetVersion()
{
return database.getVersion();
}
/// <summary>
/// Not implemented
/// </summary>
/// <param name="query"></param>
public void runQuery(string query)
{
}
}
}

View File

@ -0,0 +1,38 @@
using System.Reflection;
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("OpenSim.Framework.Data.MSSQL")]
[assembly : AssemblyDescription("")]
[assembly : AssemblyConfiguration("")]
[assembly : AssemblyCompany("")]
[assembly : AssemblyProduct("OpenSim.Framework.Data.MSSQL")]
[assembly : AssemblyCopyright("Copyright © 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("0e1c1ca4-2cf2-4315-b0e7-432c02feea8a")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly : AssemblyVersion("1.0.0.0")]
[assembly : AssemblyFileVersion("1.0.0.0")]

View File

@ -0,0 +1,20 @@
SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
SET ANSI_PADDING ON
CREATE TABLE [assets] (
[id] [varchar](36) NOT NULL,
[name] [varchar](64) NOT NULL,
[description] [varchar](64) NOT NULL,
[mediaURL] [varchar](255) NOT NULL,
[assetType] [tinyint] NOT NULL,
[invType] [tinyint] NOT NULL,
[local] [tinyint] NOT NULL,
[temporary] [tinyint] NOT NULL,
[data] [image] NOT NULL,
PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
SET ANSI_PADDING OFF

View File

@ -0,0 +1,27 @@
SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
SET ANSI_PADDING ON
CREATE TABLE [inventoryfolders] (
[folderID] [varchar](36) NOT NULL default '',
[agentID] [varchar](36) default NULL,
[parentFolderID] [varchar](36) default NULL,
[folderName] [varchar](64) default NULL,
[type] [smallint] NOT NULL default 0,
[version] [int] NOT NULL default 0,
PRIMARY KEY CLUSTERED
(
[folderID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE NONCLUSTERED INDEX [owner] ON [inventoryfolders]
(
[agentID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
CREATE NONCLUSTERED INDEX [parent] ON [inventoryfolders]
(
[parentFolderID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
SET ANSI_PADDING OFF

View File

@ -0,0 +1,39 @@
SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
SET ANSI_PADDING ON
CREATE TABLE [inventoryitems] (
[inventoryID] [varchar](36) NOT NULL default '',
[assetID] [varchar](36) default NULL,
[assetType] [int] default NULL,
[parentFolderID] [varchar](36) default NULL,
[avatarID] [varchar](36) default NULL,
[inventoryName] [varchar](64) default NULL,
[inventoryDescription] [varchar](64) default NULL,
[inventoryNextPermissions] [int] default NULL,
[inventoryCurrentPermissions] [int] default NULL,
[invType] [int] default NULL,
[creatorID] [varchar](36) default NULL,
[inventoryBasePermissions] [int] NOT NULL default 0,
[inventoryEveryOnePermissions] [int] NOT NULL default 0,
PRIMARY KEY CLUSTERED
(
[inventoryID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE NONCLUSTERED INDEX [owner] ON [inventoryitems]
(
[avatarID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
CREATE NONCLUSTERED INDEX [folder] ON [inventoryitems]
(
[parentFolderID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
SET ANSI_PADDING OFF

View File

@ -0,0 +1,37 @@
SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
SET ANSI_PADDING ON
CREATE TABLE [agents] (
[UUID] [varchar](36) NOT NULL,
[sessionID] [varchar](36) NOT NULL,
[secureSessionID] [varchar](36) NOT NULL,
[agentIP] [varchar](16) NOT NULL,
[agentPort] [int] NOT NULL,
[agentOnline] [tinyint] NOT NULL,
[loginTime] [int] NOT NULL,
[logoutTime] [int] NOT NULL,
[currentRegion] [varchar](36) NOT NULL,
[currentHandle] [bigint] NOT NULL,
[currentPos] [varchar](64) NOT NULL,
PRIMARY KEY CLUSTERED
(
[UUID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE NONCLUSTERED INDEX [session] ON [agents]
(
[sessionID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
CREATE NONCLUSTERED INDEX [ssession] ON [agents]
(
[secureSessionID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
SET ANSI_PADDING OFF

View File

@ -0,0 +1,20 @@
SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
SET ANSI_PADDING ON
CREATE TABLE [logs] (
[logID] [int] NOT NULL,
[target] [varchar](36) default NULL,
[server] [varchar](64) default NULL,
[method] [varchar](64) default NULL,
[arguments] [varchar](255) default NULL,
[priority] [int] default NULL,
[message] [ntext],
PRIMARY KEY CLUSTERED
(
[logID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

View File

@ -0,0 +1,42 @@
SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
SET ANSI_PADDING ON
CREATE TABLE [users] (
[UUID] [varchar](36) NOT NULL default '',
[username] [varchar](32) NOT NULL,
[lastname] [varchar](32) NOT NULL,
[passwordHash] [varchar](32) NOT NULL,
[passwordSalt] [varchar](32) NOT NULL,
[homeRegion] [bigint] default NULL,
[homeLocationX] [float] default NULL,
[homeLocationY] [float] default NULL,
[homeLocationZ] [float] default NULL,
[homeLookAtX] [float] default NULL,
[homeLookAtY] [float] default NULL,
[homeLookAtZ] [float] default NULL,
[created] [int] NOT NULL,
[lastLogin] [int] NOT NULL,
[userInventoryURI] [varchar](255) default NULL,
[userAssetURI] [varchar](255) default NULL,
[profileCanDoMask] [int] default NULL,
[profileWantDoMask] [int] default NULL,
[profileAboutText] [ntext],
[profileFirstText] [ntext],
[profileImage] [varchar](36) default NULL,
[profileFirstImage] [varchar](36) default NULL,
[webLoginKey] [varchar](36) default NULL,
PRIMARY KEY CLUSTERED
(
[UUID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE NONCLUSTERED INDEX [usernames] ON [users]
(
[username] ASC,
[lastname] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

View File

@ -0,0 +1,194 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS 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 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.Data;
using libsecondlife;
using MySql.Data.MySqlClient;
using OpenSim.Framework.Console;
namespace OpenSim.Framework.Data.MySQL
{
internal class MySQLAssetData : IAssetProvider
{
private MySQLManager _dbConnection;
#region IAssetProvider Members
private void UpgradeAssetsTable(string oldVersion)
{
// null as the version, indicates that the table didn't exist
if (oldVersion == null)
{
MainLog.Instance.Notice("ASSETS", "Creating new database tables");
_dbConnection.ExecuteResourceSql("CreateAssetsTable.sql");
return;
}
}
/// <summary>
/// Ensure that the assets related tables exists and are at the latest version
/// </summary>
private void TestTables()
{
Dictionary<string, string> tableList = new Dictionary<string, string>();
tableList["assets"] = null;
_dbConnection.GetTableVersion(tableList);
UpgradeAssetsTable(tableList["assets"]);
}
public AssetBase FetchAsset(LLUUID assetID)
{
AssetBase asset = null;
lock (_dbConnection)
{
MySqlCommand cmd =
new MySqlCommand(
"SELECT name, description, assetType, invType, local, temporary, data FROM assets WHERE id=?id",
_dbConnection.Connection);
MySqlParameter p = cmd.Parameters.Add("?id", MySqlDbType.Binary, 16);
p.Value = assetID.GetBytes();
try
{
using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
{
if (dbReader.Read())
{
asset = new AssetBase();
asset.Data = (byte[]) dbReader["data"];
asset.Description = (string) dbReader["description"];
asset.FullID = assetID;
asset.InvType = (sbyte) dbReader["invType"];
asset.Local = ((sbyte) dbReader["local"]) != 0 ? true : false;
asset.Name = (string) dbReader["name"];
asset.Type = (sbyte) dbReader["assetType"];
}
dbReader.Close();
cmd.Dispose();
}
}
catch (Exception)
{
MainLog.Instance.Warn("ASSETS", "MySql failure fetching asset");
}
}
return asset;
}
public void CreateAsset(AssetBase asset)
{
MySqlCommand cmd =
new MySqlCommand(
"REPLACE INTO assets(id, name, description, assetType, invType, local, temporary, data)" +
"VALUES(?id, ?name, ?description, ?assetType, ?invType, ?local, ?temporary, ?data)",
_dbConnection.Connection);
// need to ensure we dispose
using (cmd)
{
MySqlParameter p = cmd.Parameters.Add("?id", MySqlDbType.Binary, 16);
p.Value = asset.FullID.GetBytes();
cmd.Parameters.AddWithValue("?name", asset.Name);
cmd.Parameters.AddWithValue("?description", asset.Description);
cmd.Parameters.AddWithValue("?assetType", asset.Type);
cmd.Parameters.AddWithValue("?invType", asset.InvType);
cmd.Parameters.AddWithValue("?local", asset.Local);
cmd.Parameters.AddWithValue("?temporary", asset.Temporary);
cmd.Parameters.AddWithValue("?data", asset.Data);
cmd.ExecuteNonQuery();
cmd.Dispose();
}
}
public void UpdateAsset(AssetBase asset)
{
CreateAsset(asset);
}
public bool ExistsAsset(LLUUID uuid)
{
throw new Exception("The method or operation is not implemented.");
}
// rex, new function, fixme not implemented
public List<AssetBase> GetAssetList(int vAssetType)
{
List<AssetBase> retvals = new List<AssetBase>();
return retvals;
}
/// <summary>
/// All writes are immediately commited to the database, so this is a no-op
/// </summary>
public void CommitAssets()
{
}
// rex new function for "replace assets" functionality
// TODO: actual implementation by someone, should return LLUUID of an asset
// with matching type & name, or zero if not in DB
public LLUUID ExistsAsset(sbyte type, string name)
{
return LLUUID.Zero;
}
#endregion
#region IPlugin Members
public void Initialise()
{
IniFile GridDataMySqlFile = new IniFile("mysql_connection.ini");
string hostname = GridDataMySqlFile.ParseFileReadValue("hostname");
string database = GridDataMySqlFile.ParseFileReadValue("database");
string username = GridDataMySqlFile.ParseFileReadValue("username");
string password = GridDataMySqlFile.ParseFileReadValue("password");
string pooling = GridDataMySqlFile.ParseFileReadValue("pooling");
string port = GridDataMySqlFile.ParseFileReadValue("port");
_dbConnection = new MySQLManager(hostname, database, username, password, pooling, port);
TestTables();
}
public string Version
{
get { return _dbConnection.getVersion(); }
}
public string Name
{
get { return "MySQL Asset storage engine"; }
}
#endregion
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,413 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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.Data;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using libsecondlife;
using OpenSim.Framework.Console;
namespace OpenSim.Framework.Data.MySQL
{
/// <summary>
/// A MySQL Interface for the Grid Server
/// </summary>
public class MySQLGridData : IGridData
{
/// <summary>
/// MySQL Database Manager
/// </summary>
private MySQLManager database;
/// <summary>
/// Initialises the Grid Interface
/// </summary>
public void Initialise()
{
IniFile GridDataMySqlFile = new IniFile("mysql_connection.ini");
string settingHostname = GridDataMySqlFile.ParseFileReadValue("hostname");
string settingDatabase = GridDataMySqlFile.ParseFileReadValue("database");
string settingUsername = GridDataMySqlFile.ParseFileReadValue("username");
string settingPassword = GridDataMySqlFile.ParseFileReadValue("password");
string settingPooling = GridDataMySqlFile.ParseFileReadValue("pooling");
string settingPort = GridDataMySqlFile.ParseFileReadValue("port");
database =
new MySQLManager(settingHostname, settingDatabase, settingUsername, settingPassword, settingPooling,
settingPort);
TestTables();
}
#region Test and initialization code
/// <summary>
/// Ensure that the user related tables exists and are at the latest version
/// </summary>
private void TestTables()
{
Dictionary<string, string> tableList = new Dictionary<string, string>();
tableList["regions"] = null;
database.GetTableVersion(tableList);
UpgradeRegionsTable(tableList["regions"]);
}
/// <summary>
/// Create or upgrade the table if necessary
/// </summary>
/// <param name="oldVersion">A null indicates that the table does not
/// currently exist</param>
private void UpgradeRegionsTable(string oldVersion)
{
// null as the version, indicates that the table didn't exist
if (oldVersion == null)
{
database.ExecuteResourceSql("CreateRegionsTable.sql");
return;
}
}
#endregion
/// <summary>
/// Shuts down the grid interface
/// </summary>
public void Close()
{
database.Close();
}
/// <summary>
/// Returns the plugin name
/// </summary>
/// <returns>Plugin name</returns>
public string getName()
{
return "MySql OpenGridData";
}
/// <summary>
/// Returns the plugin version
/// </summary>
/// <returns>Plugin version</returns>
public string getVersion()
{
return "0.1";
}
/// <summary>
/// Returns all the specified region profiles within coordates -- coordinates are inclusive
/// </summary>
/// <param name="xmin">Minimum X coordinate</param>
/// <param name="ymin">Minimum Y coordinate</param>
/// <param name="xmax">Maximum X coordinate</param>
/// <param name="ymax">Maximum Y coordinate</param>
/// <returns></returns>
public RegionProfileData[] GetProfilesInRange(uint xmin, uint ymin, uint xmax, uint ymax)
{
try
{
lock (database)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["?xmin"] = xmin.ToString();
param["?ymin"] = ymin.ToString();
param["?xmax"] = xmax.ToString();
param["?ymax"] = ymax.ToString();
IDbCommand result =
database.Query(
"SELECT * FROM regions WHERE locX >= ?xmin AND locX <= ?xmax AND locY >= ?ymin AND locY <= ?ymax",
param);
IDataReader reader = result.ExecuteReader();
RegionProfileData row;
List<RegionProfileData> rows = new List<RegionProfileData>();
while ((row = database.readSimRow(reader)) != null)
{
rows.Add(row);
}
reader.Close();
result.Dispose();
return rows.ToArray();
}
}
catch (Exception e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
return null;
}
}
/// <summary>
/// Returns a sim profile from it's location
/// </summary>
/// <param name="handle">Region location handle</param>
/// <returns>Sim profile</returns>
public RegionProfileData GetProfileByHandle(ulong handle)
{
try
{
lock (database)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["?handle"] = handle.ToString();
IDbCommand result = database.Query("SELECT * FROM regions WHERE regionHandle = ?handle", param);
IDataReader reader = result.ExecuteReader();
RegionProfileData row = database.readSimRow(reader);
reader.Close();
result.Dispose();
return row;
}
}
catch (Exception e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
return null;
}
}
/// <summary>
/// // Returns a list of avatar and UUIDs that match the query
/// </summary>
public List<AvatarPickerAvatar> GeneratePickerResults(LLUUID queryID, string query)
{
List<AvatarPickerAvatar> returnlist = new List<AvatarPickerAvatar>();
Regex objAlphaNumericPattern = new Regex("[^a-zA-Z0-9]");
string[] querysplit;
querysplit = query.Split(' ');
if (querysplit.Length == 2)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["?first"] = objAlphaNumericPattern.Replace(querysplit[0], "") + "%";
param["?second"] = objAlphaNumericPattern.Replace(querysplit[1], "") + "%";
try
{
lock (database)
{
IDbCommand result =
database.Query(
"SELECT UUID,username,surname FROM users WHERE username like ?first AND lastname like ?second LIMIT 100",
param);
IDataReader reader = result.ExecuteReader();
while (reader.Read())
{
AvatarPickerAvatar user = new AvatarPickerAvatar();
user.AvatarID = new LLUUID((string) reader["UUID"]);
user.firstName = (string) reader["username"];
user.lastName = (string) reader["surname"];
returnlist.Add(user);
}
reader.Close();
result.Dispose();
}
}
catch (Exception e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
return returnlist;
}
}
else if (querysplit.Length == 1)
{
try
{
lock (database)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["?first"] = objAlphaNumericPattern.Replace(querysplit[0], "") + "%";
IDbCommand result =
database.Query(
"SELECT UUID,username,surname FROM users WHERE username like ?first OR lastname like ?second",
param);
IDataReader reader = result.ExecuteReader();
while (reader.Read())
{
AvatarPickerAvatar user = new AvatarPickerAvatar();
user.AvatarID = new LLUUID((string) reader["UUID"]);
user.firstName = (string) reader["username"];
user.lastName = (string) reader["surname"];
returnlist.Add(user);
}
reader.Close();
result.Dispose();
}
}
catch (Exception e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
return returnlist;
}
}
return returnlist;
}
/// <summary>
/// Returns a sim profile from it's UUID
/// </summary>
/// <param name="uuid">The region UUID</param>
/// <returns>The sim profile</returns>
public RegionProfileData GetProfileByLLUUID(LLUUID uuid)
{
try
{
lock (database)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["?uuid"] = uuid.ToString();
IDbCommand result = database.Query("SELECT * FROM regions WHERE uuid = ?uuid", param);
IDataReader reader = result.ExecuteReader();
RegionProfileData row = database.readSimRow(reader);
reader.Close();
result.Dispose();
return row;
}
}
catch (Exception e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
return null;
}
}
/// <summary>
/// Adds a new profile to the database
/// </summary>
/// <param name="profile">The profile to add</param>
/// <returns>Successful?</returns>
public DataResponse AddProfile(RegionProfileData profile)
{
lock (database)
{
if (database.insertRegion(profile))
{
return DataResponse.RESPONSE_OK;
}
else
{
return DataResponse.RESPONSE_ERROR;
}
}
}
/// <summary>
/// DEPRECIATED. Attempts to authenticate a region by comparing a shared secret.
/// </summary>
/// <param name="uuid">The UUID of the challenger</param>
/// <param name="handle">The attempted regionHandle of the challenger</param>
/// <param name="authkey">The secret</param>
/// <returns>Whether the secret and regionhandle match the database entry for UUID</returns>
public bool AuthenticateSim(LLUUID uuid, ulong handle, string authkey)
{
bool throwHissyFit = false; // Should be true by 1.0
if (throwHissyFit)
throw new Exception("CRYPTOWEAK AUTHENTICATE: Refusing to authenticate due to replay potential.");
RegionProfileData data = GetProfileByLLUUID(uuid);
return (handle == data.regionHandle && authkey == data.regionSecret);
}
/// <summary>
/// NOT YET FUNCTIONAL. Provides a cryptographic authentication of a region
/// </summary>
/// <remarks>This requires a security audit.</remarks>
/// <param name="uuid"></param>
/// <param name="handle"></param>
/// <param name="authhash"></param>
/// <param name="challenge"></param>
/// <returns></returns>
public bool AuthenticateSim(LLUUID uuid, ulong handle, string authhash, string challenge)
{
SHA512Managed HashProvider = new SHA512Managed();
ASCIIEncoding TextProvider = new ASCIIEncoding();
byte[] stream = TextProvider.GetBytes(uuid.ToString() + ":" + handle.ToString() + ":" + challenge);
byte[] hash = HashProvider.ComputeHash(stream);
return false;
}
public ReservationData GetReservationAtPoint(uint x, uint y)
{
try
{
lock (database)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["?x"] = x.ToString();
param["?y"] = y.ToString();
IDbCommand result =
database.Query(
"SELECT * FROM reservations WHERE resXMin <= ?x AND resXMax >= ?x AND resYMin <= ?y AND resYMax >= ?y",
param);
IDataReader reader = result.ExecuteReader();
ReservationData row = database.readReservationRow(reader);
reader.Close();
result.Dispose();
return row;
}
}
catch (Exception e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
return null;
}
}
}
}

View File

@ -0,0 +1,640 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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 libsecondlife;
using MySql.Data.MySqlClient;
using OpenSim.Framework.Console;
namespace OpenSim.Framework.Data.MySQL
{
/// <summary>
/// A MySQL interface for the inventory server
/// </summary>
public class MySQLInventoryData : IInventoryData
{
/// <summary>
/// The database manager
/// </summary>
private MySQLManager database;
/// <summary>
/// Loads and initialises this database plugin
/// </summary>
public void Initialise()
{
IniFile GridDataMySqlFile = new IniFile("mysql_connection.ini");
string settingHostname = GridDataMySqlFile.ParseFileReadValue("hostname");
string settingDatabase = GridDataMySqlFile.ParseFileReadValue("database");
string settingUsername = GridDataMySqlFile.ParseFileReadValue("username");
string settingPassword = GridDataMySqlFile.ParseFileReadValue("password");
string settingPooling = GridDataMySqlFile.ParseFileReadValue("pooling");
string settingPort = GridDataMySqlFile.ParseFileReadValue("port");
database =
new MySQLManager(settingHostname, settingDatabase, settingUsername, settingPassword, settingPooling,
settingPort);
TestTables(database.Connection);
}
#region Test and initialization code
private void UpgradeFoldersTable(string oldVersion)
{
// null as the version, indicates that the table didn't exist
if (oldVersion == null)
{
database.ExecuteResourceSql("CreateFoldersTable.sql");
return;
}
// if the table is already at the current version, then we can exit immediately
// if (oldVersion == "Rev. 2")
// return;
// database.ExecuteResourceSql("UpgradeFoldersTableToVersion2.sql");
}
private void UpgradeItemsTable(string oldVersion)
{
// null as the version, indicates that the table didn't exist
if (oldVersion == null)
{
database.ExecuteResourceSql("CreateItemsTable.sql");
return;
}
// if the table is already at the current version, then we can exit immediately
// if (oldVersion == "Rev. 2")
// return;
// database.ExecuteResourceSql("UpgradeItemsTableToVersion2.sql");
}
private void TestTables(MySqlConnection conn)
{
Dictionary<string, string> tableList = new Dictionary<string, string>();
tableList["inventoryfolders"] = null;
tableList["inventoryitems"] = null;
database.GetTableVersion(tableList);
MainLog.Instance.Verbose("MYSQL", "Inventory Folder Version: " + tableList["inventoryfolders"]);
MainLog.Instance.Verbose("MYSQL", "Inventory Items Version: " + tableList["inventoryitems"]);
UpgradeFoldersTable(tableList["inventoryfolders"]);
UpgradeItemsTable(tableList["inventoryitems"]);
}
#endregion
/// <summary>
/// The name of this DB provider
/// </summary>
/// <returns>Name of DB provider</returns>
public string getName()
{
return "MySQL Inventory Data Interface";
}
/// <summary>
/// Closes this DB provider
/// </summary>
public void Close()
{
// Do nothing.
}
/// <summary>
/// Returns the version of this DB provider
/// </summary>
/// <returns>A string containing the DB provider</returns>
public string getVersion()
{
return database.getVersion();
}
/// <summary>
/// Returns a list of items in a specified folder
/// </summary>
/// <param name="folderID">The folder to search</param>
/// <returns>A list containing inventory items</returns>
public List<InventoryItemBase> getInventoryInFolder(LLUUID folderID)
{
try
{
lock (database)
{
List<InventoryItemBase> items = new List<InventoryItemBase>();
MySqlCommand result =
new MySqlCommand("SELECT * FROM inventoryitems WHERE parentFolderID = ?uuid",
database.Connection);
result.Parameters.AddWithValue("?uuid", folderID.ToString());
MySqlDataReader reader = result.ExecuteReader();
while (reader.Read())
items.Add(readInventoryItem(reader));
reader.Close();
result.Dispose();
return items;
}
}
catch (Exception e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
return null;
}
}
/// <summary>
/// Returns a list of the root folders within a users inventory
/// </summary>
/// <param name="user">The user whos inventory is to be searched</param>
/// <returns>A list of folder objects</returns>
public List<InventoryFolderBase> getUserRootFolders(LLUUID user)
{
try
{
lock (database)
{
MySqlCommand result =
new MySqlCommand(
"SELECT * FROM inventoryfolders WHERE parentFolderID = ?zero AND agentID = ?uuid",
database.Connection);
result.Parameters.AddWithValue("?uuid", user.ToString());
result.Parameters.AddWithValue("?zero", LLUUID.Zero.ToString());
MySqlDataReader reader = result.ExecuteReader();
List<InventoryFolderBase> items = new List<InventoryFolderBase>();
while (reader.Read())
items.Add(readInventoryFolder(reader));
reader.Close();
result.Dispose();
return items;
}
}
catch (Exception e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
return null;
}
}
// see InventoryItemBase.getUserRootFolder
public InventoryFolderBase getUserRootFolder(LLUUID user)
{
try
{
lock (database)
{
MySqlCommand result =
new MySqlCommand(
"SELECT * FROM inventoryfolders WHERE parentFolderID = ?zero AND agentID = ?uuid",
database.Connection);
result.Parameters.AddWithValue("?uuid", user.ToString());
result.Parameters.AddWithValue("?zero", LLUUID.Zero.ToString());
MySqlDataReader reader = result.ExecuteReader();
List<InventoryFolderBase> items = new List<InventoryFolderBase>();
while (reader.Read())
items.Add(readInventoryFolder(reader));
InventoryFolderBase rootFolder = null;
// There should only ever be one root folder for a user. However, if there's more
// than one we'll simply use the first one rather than failing. It would be even
// nicer to print some message to this effect, but this feels like it's too low a
// to put such a message out, and it's too minor right now to spare the time to
// suitably refactor.
if (items.Count > 0)
{
rootFolder = items[0];
}
reader.Close();
result.Dispose();
return rootFolder;
}
}
catch (Exception e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
return null;
}
}
/// <summary>
/// Return a list of folders in a users inventory contained within the specified folder.
/// This method is only used in tests - in normal operation the user always have one,
/// and only one, root folder.
/// </summary>
/// <param name="parentID">The folder to search</param>
/// <returns>A list of inventory folders</returns>
public List<InventoryFolderBase> getInventoryFolders(LLUUID parentID)
{
try
{
lock (database)
{
MySqlCommand result =
new MySqlCommand("SELECT * FROM inventoryfolders WHERE parentFolderID = ?uuid",
database.Connection);
result.Parameters.AddWithValue("?uuid", parentID.ToString());
MySqlDataReader reader = result.ExecuteReader();
List<InventoryFolderBase> items = new List<InventoryFolderBase>();
while (reader.Read())
items.Add(readInventoryFolder(reader));
reader.Close();
result.Dispose();
return items;
}
}
catch (Exception e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
return null;
}
}
/// <summary>
/// Reads a one item from an SQL result
/// </summary>
/// <param name="reader">The SQL Result</param>
/// <returns>the item read</returns>
private InventoryItemBase readInventoryItem(MySqlDataReader reader)
{
try
{
InventoryItemBase item = new InventoryItemBase();
item.inventoryID = new LLUUID((string) reader["inventoryID"]);
item.assetID = new LLUUID((string) reader["assetID"]);
item.assetType = (int) reader["assetType"];
item.parentFolderID = new LLUUID((string) reader["parentFolderID"]);
item.avatarID = new LLUUID((string) reader["avatarID"]);
item.inventoryName = (string) reader["inventoryName"];
item.inventoryDescription = (string) reader["inventoryDescription"];
item.inventoryNextPermissions = (uint) reader["inventoryNextPermissions"];
item.inventoryCurrentPermissions = (uint) reader["inventoryCurrentPermissions"];
item.invType = (int) reader["invType"];
item.creatorsID = new LLUUID((string) reader["creatorID"]);
item.inventoryBasePermissions = (uint) reader["inventoryBasePermissions"];
item.inventoryEveryOnePermissions = (uint) reader["inventoryEveryOnePermissions"];
return item;
}
catch (MySqlException e)
{
MainLog.Instance.Error(e.ToString());
}
return null;
}
/// <summary>
/// Returns a specified inventory item
/// </summary>
/// <param name="item">The item to return</param>
/// <returns>An inventory item</returns>
public InventoryItemBase getInventoryItem(LLUUID itemID)
{
try
{
lock (database)
{
Dictionary<string, string> param = new Dictionary<string, string>();
MySqlCommand result =
new MySqlCommand("SELECT * FROM inventoryitems WHERE inventoryID = ?uuid", database.Connection);
result.Parameters.AddWithValue("?uuid", itemID.ToString());
MySqlDataReader reader = result.ExecuteReader();
InventoryItemBase item = null;
if (reader.Read())
item = readInventoryItem(reader);
reader.Close();
result.Dispose();
return item;
}
}
catch (Exception e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
}
return null;
}
/// <summary>
/// Reads a list of inventory folders returned by a query.
/// </summary>
/// <param name="reader">A MySQL Data Reader</param>
/// <returns>A List containing inventory folders</returns>
protected InventoryFolderBase readInventoryFolder(MySqlDataReader reader)
{
try
{
InventoryFolderBase folder = new InventoryFolderBase();
folder.agentID = new LLUUID((string) reader["agentID"]);
folder.parentID = new LLUUID((string) reader["parentFolderID"]);
folder.folderID = new LLUUID((string) reader["folderID"]);
folder.name = (string) reader["folderName"];
folder.type = (short) reader["type"];
folder.version = (ushort) ((int) reader["version"]);
return folder;
}
catch (Exception e)
{
MainLog.Instance.Error(e.ToString());
}
return null;
}
/// <summary>
/// Returns a specified inventory folder
/// </summary>
/// <param name="folder">The folder to return</param>
/// <returns>A folder class</returns>
public InventoryFolderBase getInventoryFolder(LLUUID folderID)
{
try
{
lock (database)
{
MySqlCommand result =
new MySqlCommand("SELECT * FROM inventoryfolders WHERE folderID = ?uuid", database.Connection);
result.Parameters.AddWithValue("?uuid", folderID.ToString());
MySqlDataReader reader = result.ExecuteReader();
reader.Read();
InventoryFolderBase folder = readInventoryFolder(reader);
reader.Close();
result.Dispose();
return folder;
}
}
catch (Exception e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
return null;
}
}
/// <summary>
/// Adds a specified item to the database
/// </summary>
/// <param name="item">The inventory item</param>
public void addInventoryItem(InventoryItemBase item)
{
string sql =
"REPLACE INTO inventoryitems (inventoryID, assetID, assetType, parentFolderID, avatarID, inventoryName, inventoryDescription, inventoryNextPermissions, inventoryCurrentPermissions, invType, creatorID, inventoryBasePermissions, inventoryEveryOnePermissions) VALUES ";
sql +=
"(?inventoryID, ?assetID, ?assetType, ?parentFolderID, ?avatarID, ?inventoryName, ?inventoryDescription, ?inventoryNextPermissions, ?inventoryCurrentPermissions, ?invType, ?creatorID, ?inventoryBasePermissions, ?inventoryEveryOnePermissions)";
try
{
MySqlCommand result = new MySqlCommand(sql, database.Connection);
result.Parameters.AddWithValue("?inventoryID", item.inventoryID.ToString());
result.Parameters.AddWithValue("?assetID", item.assetID.ToString());
result.Parameters.AddWithValue("?assetType", item.assetType.ToString());
result.Parameters.AddWithValue("?parentFolderID", item.parentFolderID.ToString());
result.Parameters.AddWithValue("?avatarID", item.avatarID.ToString());
result.Parameters.AddWithValue("?inventoryName", item.inventoryName);
result.Parameters.AddWithValue("?inventoryDescription", item.inventoryDescription);
result.Parameters.AddWithValue("?inventoryNextPermissions", item.inventoryNextPermissions.ToString());
result.Parameters.AddWithValue("?inventoryCurrentPermissions",
item.inventoryCurrentPermissions.ToString());
result.Parameters.AddWithValue("?invType", item.invType);
result.Parameters.AddWithValue("?creatorID", item.creatorsID.ToString());
result.Parameters.AddWithValue("?inventoryBasePermissions", item.inventoryBasePermissions);
result.Parameters.AddWithValue("?inventoryEveryOnePermissions", item.inventoryEveryOnePermissions);
result.ExecuteNonQuery();
result.Dispose();
}
catch (MySqlException e)
{
MainLog.Instance.Error(e.ToString());
}
}
/// <summary>
/// Updates the specified inventory item
/// </summary>
/// <param name="item">Inventory item to update</param>
public void updateInventoryItem(InventoryItemBase item)
{
addInventoryItem(item);
}
/// <summary>
///
/// </summary>
/// <param name="item"></param>
public void deleteInventoryItem(LLUUID itemID)
{
try
{
MySqlCommand cmd =
new MySqlCommand("DELETE FROM inventoryitems WHERE inventoryID=?uuid", database.Connection);
cmd.Parameters.AddWithValue("?uuid", itemID.ToString());
cmd.ExecuteNonQuery();
}
catch (MySqlException e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
}
}
/// <summary>
/// Creates a new inventory folder
/// </summary>
/// <param name="folder">Folder to create</param>
public void addInventoryFolder(InventoryFolderBase folder)
{
string sql =
"REPLACE INTO inventoryfolders (folderID, agentID, parentFolderID, folderName, type, version) VALUES ";
sql += "(?folderID, ?agentID, ?parentFolderID, ?folderName, ?type, ?version)";
MySqlCommand cmd = new MySqlCommand(sql, database.Connection);
cmd.Parameters.AddWithValue("?folderID", folder.folderID.ToString());
cmd.Parameters.AddWithValue("?agentID", folder.agentID.ToString());
cmd.Parameters.AddWithValue("?parentFolderID", folder.parentID.ToString());
cmd.Parameters.AddWithValue("?folderName", folder.name);
cmd.Parameters.AddWithValue("?type", (short) folder.type);
cmd.Parameters.AddWithValue("?version", folder.version);
try
{
cmd.ExecuteNonQuery();
}
catch (Exception e)
{
MainLog.Instance.Error(e.ToString());
}
}
/// <summary>
/// Updates an inventory folder
/// </summary>
/// <param name="folder">Folder to update</param>
public void updateInventoryFolder(InventoryFolderBase folder)
{
addInventoryFolder(folder);
}
/// Creates a new inventory folder
/// </summary>
/// <param name="folder">Folder to create</param>
public void moveInventoryFolder(InventoryFolderBase folder)
{
string sql =
"UPDATE inventoryfolders SET parentFolderID=?parentFolderID WHERE folderID=?folderID";
MySqlCommand cmd = new MySqlCommand(sql, database.Connection);
cmd.Parameters.AddWithValue("?folderID", folder.folderID.ToString());
cmd.Parameters.AddWithValue("?parentFolderID", folder.parentID.ToString());
try
{
cmd.ExecuteNonQuery();
}
catch (Exception e)
{
MainLog.Instance.Error(e.ToString());
}
}
/// <summary>
/// Append a list of all the child folders of a parent folder
/// </summary>
/// <param name="folders">list where folders will be appended</param>
/// <param name="parentID">ID of parent</param>
protected void getInventoryFolders(ref List<InventoryFolderBase> folders, LLUUID parentID)
{
List<InventoryFolderBase> subfolderList = getInventoryFolders(parentID);
foreach (InventoryFolderBase f in subfolderList)
folders.Add(f);
}
/// <summary>
/// Returns all child folders in the hierarchy from the parent folder and down
/// </summary>
/// <param name="parentID">The folder to get subfolders for</param>
/// <returns>A list of inventory folders</returns>
protected List<InventoryFolderBase> getFolderHierarchy(LLUUID parentID)
{
List<InventoryFolderBase> folders = new List<InventoryFolderBase>();
getInventoryFolders(ref folders, parentID);
for (int i = 0; i < folders.Count; i++)
getInventoryFolders(ref folders, folders[i].folderID);
return folders;
}
protected void deleteOneFolder(LLUUID folderID)
{
try
{
MySqlCommand cmd =
new MySqlCommand("DELETE FROM inventoryfolders WHERE folderID=?uuid", database.Connection);
cmd.Parameters.AddWithValue("?uuid", folderID.ToString());
cmd.ExecuteNonQuery();
}
catch (MySqlException e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
}
}
protected void deleteItemsInFolder(LLUUID folderID)
{
try
{
MySqlCommand cmd =
new MySqlCommand("DELETE FROM inventoryitems WHERE parentFolderID=?uuid", database.Connection);
cmd.Parameters.AddWithValue("?uuid", folderID.ToString());
cmd.ExecuteNonQuery();
}
catch (MySqlException e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
}
}
/// <summary>
/// Delete an inventory folder
/// </summary>
/// <param name="folderId">Id of folder to delete</param>
public void deleteInventoryFolder(LLUUID folderID)
{
lock (database)
{
List<InventoryFolderBase> subFolders = getFolderHierarchy(folderID);
//Delete all sub-folders
foreach (InventoryFolderBase f in subFolders)
{
deleteOneFolder(f.folderID);
deleteItemsInFolder(f.folderID);
}
//Delete the actual row
deleteOneFolder(folderID);
deleteItemsInFolder(folderID);
}
}
}
}

View File

@ -0,0 +1,106 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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.
*
*/
namespace OpenSim.Framework.Data.MySQL
{
/// <summary>
/// An interface to the log database for MySQL
/// </summary>
internal class MySQLLogData : ILogData
{
/// <summary>
/// The database manager
/// </summary>
public MySQLManager database;
/// <summary>
/// Artificial constructor called when the plugin is loaded
/// </summary>
public void Initialise()
{
IniFile GridDataMySqlFile = new IniFile("mysql_connection.ini");
string settingHostname = GridDataMySqlFile.ParseFileReadValue("hostname");
string settingDatabase = GridDataMySqlFile.ParseFileReadValue("database");
string settingUsername = GridDataMySqlFile.ParseFileReadValue("username");
string settingPassword = GridDataMySqlFile.ParseFileReadValue("password");
string settingPooling = GridDataMySqlFile.ParseFileReadValue("pooling");
string settingPort = GridDataMySqlFile.ParseFileReadValue("port");
database =
new MySQLManager(settingHostname, settingDatabase, settingUsername, settingPassword, settingPooling,
settingPort);
}
/// <summary>
/// Saves a log item to the database
/// </summary>
/// <param name="serverDaemon">The daemon triggering the event</param>
/// <param name="target">The target of the action (region / agent UUID, etc)</param>
/// <param name="methodCall">The method call where the problem occured</param>
/// <param name="arguments">The arguments passed to the method</param>
/// <param name="priority">How critical is this?</param>
/// <param name="logMessage">The message to log</param>
public void saveLog(string serverDaemon, string target, string methodCall, string arguments, int priority,
string logMessage)
{
try
{
database.insertLogRow(serverDaemon, target, methodCall, arguments, priority, logMessage);
}
catch
{
database.Reconnect();
}
}
/// <summary>
/// Returns the name of this DB provider
/// </summary>
/// <returns>A string containing the DB provider name</returns>
public string getName()
{
return "MySQL Logdata Interface";
}
/// <summary>
/// Closes the database provider
/// </summary>
public void Close()
{
// Do nothing.
}
/// <summary>
/// Returns the version of this DB provider
/// </summary>
/// <returns>A string containing the provider version</returns>
public string getVersion()
{
return "0.1";
}
}
}

View File

@ -0,0 +1,690 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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.Data;
using System.IO;
using System.Reflection;
using libsecondlife;
using MySql.Data.MySqlClient;
using OpenSim.Framework.Console;
namespace OpenSim.Framework.Data.MySQL
{
/// <summary>
/// A MySQL Database manager
/// </summary>
internal class MySQLManager
{
/// <summary>
/// The database connection object
/// </summary>
private MySqlConnection dbcon;
/// <summary>
/// Connection string for ADO.net
/// </summary>
private string connectionString;
/// <summary>
/// Initialises and creates a new MySQL connection and maintains it.
/// </summary>
/// <param name="hostname">The MySQL server being connected to</param>
/// <param name="database">The name of the MySQL database being used</param>
/// <param name="username">The username logging into the database</param>
/// <param name="password">The password for the user logging in</param>
/// <param name="cpooling">Whether to use connection pooling or not, can be one of the following: 'yes', 'true', 'no' or 'false', if unsure use 'false'.</param>
public MySQLManager(string hostname, string database, string username, string password, string cpooling,
string port)
{
try
{
connectionString = "Server=" + hostname + ";Port=" + port + ";Database=" + database + ";User ID=" +
username + ";Password=" + password + ";Pooling=" + cpooling + ";";
dbcon = new MySqlConnection(connectionString);
dbcon.Open();
MainLog.Instance.Verbose("MYSQL", "Connection established");
}
catch (Exception e)
{
throw new Exception("Error initialising MySql Database: " + e.ToString());
}
}
/// <summary>
/// Get the connection being used
/// </summary>
public MySqlConnection Connection
{
get { return dbcon; }
}
/// <summary>
/// Shuts down the database connection
/// </summary>
public void Close()
{
dbcon.Close();
dbcon = null;
}
/// <summary>
/// Reconnects to the database
/// </summary>
public void Reconnect()
{
lock (dbcon)
{
try
{
// Close the DB connection
dbcon.Close();
// Try reopen it
dbcon = new MySqlConnection(connectionString);
dbcon.Open();
}
catch (Exception e)
{
MainLog.Instance.Error("Unable to reconnect to database " + e.ToString());
}
}
}
/// <summary>
/// Returns the version of this DB provider
/// </summary>
/// <returns>A string containing the DB provider</returns>
public string getVersion()
{
Module module = GetType().Module;
string dllName = module.Assembly.ManifestModule.Name;
Version dllVersion = module.Assembly.GetName().Version;
return
string.Format("{0}.{1}.{2}.{3}", dllVersion.Major, dllVersion.Minor, dllVersion.Build,
dllVersion.Revision);
}
/// <summary>
/// Extract a named string resource from the embedded resources
/// </summary>
/// <param name="name">name of embedded resource</param>
/// <returns>string contained within the embedded resource</returns>
private string getResourceString(string name)
{
Assembly assem = GetType().Assembly;
string[] names = assem.GetManifestResourceNames();
foreach (string s in names)
if (s.EndsWith(name))
using (Stream resource = assem.GetManifestResourceStream(s))
{
using (StreamReader resourceReader = new StreamReader(resource))
{
string resourceString = resourceReader.ReadToEnd();
return resourceString;
}
}
throw new Exception(string.Format("Resource '{0}' was not found", name));
}
/// <summary>
/// Execute a SQL statement stored in a resource, as a string
/// </summary>
/// <param name="name"></param>
public void ExecuteResourceSql(string name)
{
MySqlCommand cmd = new MySqlCommand(getResourceString(name), dbcon);
cmd.ExecuteNonQuery();
}
/// <summary>
/// Given a list of tables, return the version of the tables, as seen in the database
/// </summary>
/// <param name="tableList"></param>
public void GetTableVersion(Dictionary<string, string> tableList)
{
lock (dbcon)
{
MySqlCommand tablesCmd =
new MySqlCommand(
"SELECT TABLE_NAME, TABLE_COMMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=?dbname",
dbcon);
tablesCmd.Parameters.AddWithValue("?dbname", dbcon.Database);
using (MySqlDataReader tables = tablesCmd.ExecuteReader())
{
while (tables.Read())
{
try
{
string tableName = (string) tables["TABLE_NAME"];
string comment = (string) tables["TABLE_COMMENT"];
if (tableList.ContainsKey(tableName))
tableList[tableName] = comment;
}
catch (Exception e)
{
MainLog.Instance.Error(e.ToString());
}
}
tables.Close();
}
}
}
// at some time this code should be cleaned up
/// <summary>
/// Runs a query with protection against SQL Injection by using parameterised input.
/// </summary>
/// <param name="sql">The SQL string - replace any variables such as WHERE x = "y" with WHERE x = @y</param>
/// <param name="parameters">The parameters - index so that @y is indexed as 'y'</param>
/// <returns>A MySQL DB Command</returns>
public IDbCommand Query(string sql, Dictionary<string, string> parameters)
{
try
{
MySqlCommand dbcommand = (MySqlCommand) dbcon.CreateCommand();
dbcommand.CommandText = sql;
foreach (KeyValuePair<string, string> param in parameters)
{
dbcommand.Parameters.AddWithValue(param.Key, param.Value);
}
return (IDbCommand) dbcommand;
}
catch
{
lock (dbcon)
{
// Close the DB connection
try
{
dbcon.Close();
}
catch
{
}
// Try reopen it
try
{
dbcon = new MySqlConnection(connectionString);
dbcon.Open();
}
catch (Exception e)
{
MainLog.Instance.Error("Unable to reconnect to database " + e.ToString());
}
// Run the query again
try
{
MySqlCommand dbcommand = (MySqlCommand) dbcon.CreateCommand();
dbcommand.CommandText = sql;
foreach (KeyValuePair<string, string> param in parameters)
{
dbcommand.Parameters.AddWithValue(param.Key, param.Value);
}
return (IDbCommand) dbcommand;
}
catch (Exception e)
{
// Return null if it fails.
MainLog.Instance.Error("Failed during Query generation: " + e.ToString());
return null;
}
}
}
}
/// <summary>
/// Reads a region row from a database reader
/// </summary>
/// <param name="reader">An active database reader</param>
/// <returns>A region profile</returns>
public RegionProfileData readSimRow(IDataReader reader)
{
RegionProfileData retval = new RegionProfileData();
if (reader.Read())
{
// Region Main
retval.regionHandle = Convert.ToUInt64(reader["regionHandle"].ToString());
retval.regionName = (string) reader["regionName"];
retval.UUID = new LLUUID((string) reader["uuid"]);
// Secrets
retval.regionRecvKey = (string) reader["regionRecvKey"];
retval.regionSecret = (string) reader["regionSecret"];
retval.regionSendKey = (string) reader["regionSendKey"];
// Region Server
retval.regionDataURI = (string) reader["regionDataURI"];
retval.regionOnline = false; // Needs to be pinged before this can be set.
retval.serverIP = (string) reader["serverIP"];
retval.serverPort = uint.Parse(reader["serverPort"].ToString());
//retval.serverPort = (uint) reader["serverPort"]; // this caused exceptions
retval.serverURI = (string) reader["serverURI"];
retval.httpPort = Convert.ToUInt32(reader["serverHttpPort"].ToString());
retval.remotingPort = Convert.ToUInt32(reader["serverRemotingPort"].ToString());
// Location
retval.regionLocX = Convert.ToUInt32(reader["locX"].ToString());
retval.regionLocY = Convert.ToUInt32(reader["locY"].ToString());
retval.regionLocZ = Convert.ToUInt32(reader["locZ"].ToString());
// Neighbours - 0 = No Override
retval.regionEastOverrideHandle = Convert.ToUInt64(reader["eastOverrideHandle"].ToString());
retval.regionWestOverrideHandle = Convert.ToUInt64(reader["westOverrideHandle"].ToString());
retval.regionSouthOverrideHandle = Convert.ToUInt64(reader["southOverrideHandle"].ToString());
retval.regionNorthOverrideHandle = Convert.ToUInt64(reader["northOverrideHandle"].ToString());
// Assets
retval.regionAssetURI = (string) reader["regionAssetURI"];
retval.regionAssetRecvKey = (string) reader["regionAssetRecvKey"];
retval.regionAssetSendKey = (string) reader["regionAssetSendKey"];
// Userserver
retval.regionUserURI = (string) reader["regionUserURI"];
retval.regionUserRecvKey = (string) reader["regionUserRecvKey"];
retval.regionUserSendKey = (string) reader["regionUserSendKey"];
// World Map Addition
string tempRegionMap = reader["regionMapTexture"].ToString();
if (tempRegionMap != "")
{
retval.regionMapTextureID = new LLUUID(tempRegionMap);
}
else
{
retval.regionMapTextureID = LLUUID.Zero;
}
}
else
{
return null;
}
return retval;
}
/// <summary>
/// Reads a reservation row from a database reader
/// </summary>
/// <param name="reader">An active database reader</param>
/// <returns>A reservation data object</returns>
public ReservationData readReservationRow(IDataReader reader)
{
ReservationData retval = new ReservationData();
if (reader.Read())
{
retval.gridRecvKey = (string) reader["gridRecvKey"];
retval.gridSendKey = (string) reader["gridSendKey"];
retval.reservationCompany = (string) reader["resCompany"];
retval.reservationMaxX = Convert.ToInt32(reader["resXMax"].ToString());
retval.reservationMaxY = Convert.ToInt32(reader["resYMax"].ToString());
retval.reservationMinX = Convert.ToInt32(reader["resXMin"].ToString());
retval.reservationMinY = Convert.ToInt32(reader["resYMin"].ToString());
retval.reservationName = (string) reader["resName"];
retval.status = Convert.ToInt32(reader["status"].ToString()) == 1;
retval.userUUID = new LLUUID((string) reader["userUUID"]);
}
else
{
return null;
}
return retval;
}
/// <summary>
/// Reads an agent row from a database reader
/// </summary>
/// <param name="reader">An active database reader</param>
/// <returns>A user session agent</returns>
public UserAgentData readAgentRow(IDataReader reader)
{
UserAgentData retval = new UserAgentData();
if (reader.Read())
{
// Agent IDs
retval.UUID = new LLUUID((string) reader["UUID"]);
retval.sessionID = new LLUUID((string) reader["sessionID"]);
retval.secureSessionID = new LLUUID((string) reader["secureSessionID"]);
// Agent Who?
retval.agentIP = (string) reader["agentIP"];
retval.agentPort = Convert.ToUInt32(reader["agentPort"].ToString());
retval.agentOnline = Convert.ToBoolean(reader["agentOnline"].ToString());
// Login/Logout times (UNIX Epoch)
retval.loginTime = Convert.ToInt32(reader["loginTime"].ToString());
retval.logoutTime = Convert.ToInt32(reader["logoutTime"].ToString());
// Current position
retval.currentRegion = (string) reader["currentRegion"];
retval.currentHandle = Convert.ToUInt64(reader["currentHandle"].ToString());
LLVector3.TryParse((string) reader["currentPos"], out retval.currentPos);
}
else
{
return null;
}
return retval;
}
/// <summary>
/// Reads a user profile from an active data reader
/// </summary>
/// <param name="reader">An active database reader</param>
/// <returns>A user profile</returns>
public UserProfileData readUserRow(IDataReader reader)
{
UserProfileData retval = new UserProfileData();
if (reader.Read())
{
retval.UUID = new LLUUID((string) reader["UUID"]);
retval.username = (string) reader["username"];
retval.surname = (string) reader["lastname"];
retval.passwordHash = (string) reader["passwordHash"];
retval.passwordSalt = (string) reader["passwordSalt"];
retval.homeRegion = Convert.ToUInt64(reader["homeRegion"].ToString());
retval.homeLocation = new LLVector3(
Convert.ToSingle(reader["homeLocationX"].ToString()),
Convert.ToSingle(reader["homeLocationY"].ToString()),
Convert.ToSingle(reader["homeLocationZ"].ToString()));
retval.homeLookAt = new LLVector3(
Convert.ToSingle(reader["homeLookAtX"].ToString()),
Convert.ToSingle(reader["homeLookAtY"].ToString()),
Convert.ToSingle(reader["homeLookAtZ"].ToString()));
retval.created = Convert.ToInt32(reader["created"].ToString());
retval.lastLogin = Convert.ToInt32(reader["lastLogin"].ToString());
retval.userInventoryURI = (string) reader["userInventoryURI"];
retval.userAssetURI = (string) reader["userAssetURI"];
retval.profileCanDoMask = Convert.ToUInt32(reader["profileCanDoMask"].ToString());
retval.profileWantDoMask = Convert.ToUInt32(reader["profileWantDoMask"].ToString());
retval.profileAboutText = (string) reader["profileAboutText"];
retval.profileFirstText = (string) reader["profileFirstText"];
retval.profileImage = new LLUUID((string) reader["profileImage"]);
retval.profileFirstImage = new LLUUID((string) reader["profileFirstImage"]);
retval.webLoginKey = new LLUUID((string)reader["webLoginKey"]);
}
else
{
return null;
}
return retval;
}
/// <summary>
/// Inserts a new row into the log database
/// </summary>
/// <param name="serverDaemon">The daemon which triggered this event</param>
/// <param name="target">Who were we operating on when this occured (region UUID, user UUID, etc)</param>
/// <param name="methodCall">The method call where the problem occured</param>
/// <param name="arguments">The arguments passed to the method</param>
/// <param name="priority">How critical is this?</param>
/// <param name="logMessage">Extra message info</param>
/// <returns>Saved successfully?</returns>
public bool insertLogRow(string serverDaemon, string target, string methodCall, string arguments, int priority,
string logMessage)
{
string sql = "INSERT INTO logs (`target`, `server`, `method`, `arguments`, `priority`, `message`) VALUES ";
sql += "(?target, ?server, ?method, ?arguments, ?priority, ?message)";
Dictionary<string, string> parameters = new Dictionary<string, string>();
parameters["?server"] = serverDaemon;
parameters["?target"] = target;
parameters["?method"] = methodCall;
parameters["?arguments"] = arguments;
parameters["?priority"] = priority.ToString();
parameters["?message"] = logMessage;
bool returnval = false;
try
{
IDbCommand result = Query(sql, parameters);
if (result.ExecuteNonQuery() == 1)
returnval = true;
result.Dispose();
}
catch (Exception e)
{
MainLog.Instance.Error(e.ToString());
return false;
}
return returnval;
}
/// <summary>
/// Creates a new user and inserts it into the database
/// </summary>
/// <param name="uuid">User ID</param>
/// <param name="username">First part of the login</param>
/// <param name="lastname">Second part of the login</param>
/// <param name="passwordHash">A salted hash of the users password</param>
/// <param name="passwordSalt">The salt used for the password hash</param>
/// <param name="homeRegion">A regionHandle of the users home region</param>
/// <param name="homeLocX">Home region position vector</param>
/// <param name="homeLocY">Home region position vector</param>
/// <param name="homeLocZ">Home region position vector</param>
/// <param name="homeLookAtX">Home region 'look at' vector</param>
/// <param name="homeLookAtY">Home region 'look at' vector</param>
/// <param name="homeLookAtZ">Home region 'look at' vector</param>
/// <param name="created">Account created (unix timestamp)</param>
/// <param name="lastlogin">Last login (unix timestamp)</param>
/// <param name="inventoryURI">Users inventory URI</param>
/// <param name="assetURI">Users asset URI</param>
/// <param name="canDoMask">I can do mask</param>
/// <param name="wantDoMask">I want to do mask</param>
/// <param name="aboutText">Profile text</param>
/// <param name="firstText">Firstlife text</param>
/// <param name="profileImage">UUID for profile image</param>
/// <param name="firstImage">UUID for firstlife image</param>
/// <returns>Success?</returns>
public bool insertUserRow(LLUUID uuid, string username, string lastname, string passwordHash,
string passwordSalt, UInt64 homeRegion, float homeLocX, float homeLocY, float homeLocZ,
float homeLookAtX, float homeLookAtY, float homeLookAtZ, int created, int lastlogin,
string inventoryURI, string assetURI, uint canDoMask, uint wantDoMask,
string aboutText, string firstText,
LLUUID profileImage, LLUUID firstImage, LLUUID webLoginKey)
{
string sql =
"INSERT INTO users (`UUID`, `username`, `lastname`, `passwordHash`, `passwordSalt`, `homeRegion`, ";
sql +=
"`homeLocationX`, `homeLocationY`, `homeLocationZ`, `homeLookAtX`, `homeLookAtY`, `homeLookAtZ`, `created`, ";
sql +=
"`lastLogin`, `userInventoryURI`, `userAssetURI`, `profileCanDoMask`, `profileWantDoMask`, `profileAboutText`, ";
sql += "`profileFirstText`, `profileImage`, `profileFirstImage`, `webLoginKey`) VALUES ";
sql += "(?UUID, ?username, ?lastname, ?passwordHash, ?passwordSalt, ?homeRegion, ";
sql +=
"?homeLocationX, ?homeLocationY, ?homeLocationZ, ?homeLookAtX, ?homeLookAtY, ?homeLookAtZ, ?created, ";
sql +=
"?lastLogin, ?userInventoryURI, ?userAssetURI, ?profileCanDoMask, ?profileWantDoMask, ?profileAboutText, ";
sql += "?profileFirstText, ?profileImage, ?profileFirstImage, ?webLoginKey)";
Dictionary<string, string> parameters = new Dictionary<string, string>();
parameters["?UUID"] = uuid.ToString();
parameters["?username"] = username.ToString();
parameters["?lastname"] = lastname.ToString();
parameters["?passwordHash"] = passwordHash.ToString();
parameters["?passwordSalt"] = passwordSalt.ToString();
parameters["?homeRegion"] = homeRegion.ToString();
parameters["?homeLocationX"] = homeLocX.ToString();
parameters["?homeLocationY"] = homeLocY.ToString();
parameters["?homeLocationZ"] = homeLocZ.ToString();
parameters["?homeLookAtX"] = homeLookAtX.ToString();
parameters["?homeLookAtY"] = homeLookAtY.ToString();
parameters["?homeLookAtZ"] = homeLookAtZ.ToString();
parameters["?created"] = created.ToString();
parameters["?lastLogin"] = lastlogin.ToString();
parameters["?userInventoryURI"] = "";
parameters["?userAssetURI"] = "";
parameters["?profileCanDoMask"] = "0";
parameters["?profileWantDoMask"] = "0";
parameters["?profileAboutText"] = "";
parameters["?profileFirstText"] = "";
parameters["?profileImage"] = LLUUID.Zero.ToString();
parameters["?profileFirstImage"] = LLUUID.Zero.ToString();
parameters["?webLoginKey"] = LLUUID.Random().ToString();
bool returnval = false;
try
{
IDbCommand result = Query(sql, parameters);
if (result.ExecuteNonQuery() == 1)
returnval = true;
result.Dispose();
}
catch (Exception e)
{
MainLog.Instance.Error(e.ToString());
return false;
}
return returnval;
}
/// <summary>
/// Inserts a new region into the database
/// </summary>
/// <param name="profile">The region to insert</param>
/// <returns>Success?</returns>
public bool insertRegion(RegionProfileData regiondata)
{
bool GRID_ONLY_UPDATE_NECESSARY_DATA = false;
string sql = "";
if (GRID_ONLY_UPDATE_NECESSARY_DATA)
{
sql += "INSERT INTO ";
}
else
{
sql += "REPLACE INTO ";
}
sql += "regions (regionHandle, regionName, uuid, regionRecvKey, regionSecret, regionSendKey, regionDataURI, ";
sql +=
"serverIP, serverPort, serverURI, locX, locY, locZ, eastOverrideHandle, westOverrideHandle, southOverrideHandle, northOverrideHandle, regionAssetURI, regionAssetRecvKey, ";
sql +=
"regionAssetSendKey, regionUserURI, regionUserRecvKey, regionUserSendKey, regionMapTexture, serverHttpPort, serverRemotingPort) VALUES ";
sql += "(?regionHandle, ?regionName, ?uuid, ?regionRecvKey, ?regionSecret, ?regionSendKey, ?regionDataURI, ";
sql +=
"?serverIP, ?serverPort, ?serverURI, ?locX, ?locY, ?locZ, ?eastOverrideHandle, ?westOverrideHandle, ?southOverrideHandle, ?northOverrideHandle, ?regionAssetURI, ?regionAssetRecvKey, ";
sql +=
"?regionAssetSendKey, ?regionUserURI, ?regionUserRecvKey, ?regionUserSendKey, ?regionMapTexture, ?serverHttpPort, ?serverRemotingPort)";
if (GRID_ONLY_UPDATE_NECESSARY_DATA)
{
sql += "ON DUPLICATE KEY UPDATE serverIP = ?serverIP, serverPort = ?serverPort, serverURI = ?serverURI;";
}
else
{
sql += ";";
}
Dictionary<string, string> parameters = new Dictionary<string, string>();
parameters["?regionHandle"] = regiondata.regionHandle.ToString();
parameters["?regionName"] = regiondata.regionName.ToString();
parameters["?uuid"] = regiondata.UUID.ToString();
parameters["?regionRecvKey"] = regiondata.regionRecvKey.ToString();
parameters["?regionSecret"] = regiondata.regionSecret.ToString();
parameters["?regionSendKey"] = regiondata.regionSendKey.ToString();
parameters["?regionDataURI"] = regiondata.regionDataURI.ToString();
parameters["?serverIP"] = regiondata.serverIP.ToString();
parameters["?serverPort"] = regiondata.serverPort.ToString();
parameters["?serverURI"] = regiondata.serverURI.ToString();
parameters["?locX"] = regiondata.regionLocX.ToString();
parameters["?locY"] = regiondata.regionLocY.ToString();
parameters["?locZ"] = regiondata.regionLocZ.ToString();
parameters["?eastOverrideHandle"] = regiondata.regionEastOverrideHandle.ToString();
parameters["?westOverrideHandle"] = regiondata.regionWestOverrideHandle.ToString();
parameters["?northOverrideHandle"] = regiondata.regionNorthOverrideHandle.ToString();
parameters["?southOverrideHandle"] = regiondata.regionSouthOverrideHandle.ToString();
parameters["?regionAssetURI"] = regiondata.regionAssetURI.ToString();
parameters["?regionAssetRecvKey"] = regiondata.regionAssetRecvKey.ToString();
parameters["?regionAssetSendKey"] = regiondata.regionAssetSendKey.ToString();
parameters["?regionUserURI"] = regiondata.regionUserURI.ToString();
parameters["?regionUserRecvKey"] = regiondata.regionUserRecvKey.ToString();
parameters["?regionUserSendKey"] = regiondata.regionUserSendKey.ToString();
parameters["?regionMapTexture"] = regiondata.regionMapTextureID.ToString();
parameters["?serverHttpPort"] = regiondata.httpPort.ToString();
parameters["?serverRemotingPort"] = regiondata.remotingPort.ToString();
bool returnval = false;
try
{
IDbCommand result = Query(sql, parameters);
//Console.WriteLine(result.CommandText);
int x;
if ((x = result.ExecuteNonQuery()) > 0)
{
returnval = true;
}
result.Dispose();
}
catch (Exception e)
{
MainLog.Instance.Error(e.ToString());
return false;
}
return returnval;
}
}
}

View File

@ -0,0 +1,626 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project 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 DEVELOPERS ``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 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.Data;
using System.Text.RegularExpressions;
using libsecondlife;
using OpenSim.Framework.Console;
namespace OpenSim.Framework.Data.MySQL
{
/// <summary>
/// A database interface class to a user profile storage system
/// </summary>
internal class MySQLUserData : IUserData
{
/// <summary>
/// Database manager for MySQL
/// </summary>
public MySQLManager database;
/// <summary>
/// Loads and initialises the MySQL storage plugin
/// </summary>
public void Initialise()
{
// Load from an INI file connection details
// TODO: move this to XML?
IniFile GridDataMySqlFile = new IniFile("mysql_connection.ini");
string settingHostname = GridDataMySqlFile.ParseFileReadValue("hostname");
string settingDatabase = GridDataMySqlFile.ParseFileReadValue("database");
string settingUsername = GridDataMySqlFile.ParseFileReadValue("username");
string settingPassword = GridDataMySqlFile.ParseFileReadValue("password");
string settingPooling = GridDataMySqlFile.ParseFileReadValue("pooling");
string settingPort = GridDataMySqlFile.ParseFileReadValue("port");
database =
new MySQLManager(settingHostname, settingDatabase, settingUsername, settingPassword, settingPooling,
settingPort);
TestTables();
}
#region Test and initialization code
/// <summary>
/// Ensure that the user related tables exists and are at the latest version
/// </summary>
private void TestTables()
{
Dictionary<string, string> tableList = new Dictionary<string, string>();
tableList["agents"] = null;
tableList["users"] = null;
tableList["userfriends"] = null;
database.GetTableVersion(tableList);
UpgradeAgentsTable(tableList["agents"]);
UpgradeUsersTable(tableList["users"]);
UpgradeFriendsTable(tableList["userfriends"]);
}
/// <summary>
/// Create or upgrade the table if necessary
/// </summary>
/// <param name="oldVersion">A null indicates that the table does not
/// currently exist</param>
private void UpgradeAgentsTable(string oldVersion)
{
// null as the version, indicates that the table didn't exist
if (oldVersion == null)
{
database.ExecuteResourceSql("CreateAgentsTable.sql");
return;
}
}
/// <summary>
/// Create or upgrade the table if necessary
/// </summary>
/// <param name="oldVersion">A null indicates that the table does not
/// currently exist</param>
private void UpgradeUsersTable(string oldVersion)
{
// null as the version, indicates that the table didn't exist
if (oldVersion == null)
{
database.ExecuteResourceSql("CreateUsersTable.sql");
return;
}
else if (oldVersion.Contains("Rev. 1"))
{
database.ExecuteResourceSql("UpgradeUsersTableToVersion2.sql");
return;
}
//MainLog.Instance.Verbose("DB","DBVers:" + oldVersion);
}
/// <summary>
/// Create or upgrade the table if necessary
/// </summary>
/// <param name="oldVersion">A null indicates that the table does not
/// currently exist</param>
private void UpgradeFriendsTable(string oldVersion)
{
// null as the version, indicates that the table didn't exist
if (oldVersion == null)
{
database.ExecuteResourceSql("CreateUserFriendsTable.sql");
return;
}
}
#endregion
// see IUserData
public UserProfileData GetUserByName(string user, string last)
{
try
{
lock (database)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["?first"] = user;
param["?second"] = last;
IDbCommand result =
database.Query("SELECT * FROM users WHERE username = ?first AND lastname = ?second", param);
IDataReader reader = result.ExecuteReader();
UserProfileData row = database.readUserRow(reader);
reader.Close();
result.Dispose();
return row;
}
}
catch (Exception e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
return null;
}
}
#region User Friends List Data
public void AddNewUserFriend(LLUUID friendlistowner, LLUUID friend, uint perms)
{
int dtvalue = Util.UnixTimeSinceEpoch();
Dictionary<string, string> param = new Dictionary<string, string>();
param["?ownerID"] = friendlistowner.UUID.ToString();
param["?friendID"] = friend.UUID.ToString();
param["?friendPerms"] = perms.ToString();
param["?datetimestamp"] = dtvalue.ToString();
try
{
lock (database)
{
IDbCommand adder =
database.Query(
"INSERT INTO `userfriends` " +
"(`ownerID`,`friendID`,`friendPerms`,`datetimestamp`) " +
"VALUES " +
"(?ownerID,?friendID,?friendPerms,?datetimestamp)",
param);
adder.ExecuteNonQuery();
adder =
database.Query(
"INSERT INTO `userfriends` " +
"(`ownerID`,`friendID`,`friendPerms`,`datetimestamp`) " +
"VALUES " +
"(?friendID,?ownerID,?friendPerms,?datetimestamp)",
param);
adder.ExecuteNonQuery();
}
}
catch (Exception e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
return;
}
}
public void RemoveUserFriend(LLUUID friendlistowner, LLUUID friend)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["?ownerID"] = friendlistowner.UUID.ToString();
param["?friendID"] = friend.UUID.ToString();
try
{
lock (database)
{
IDbCommand updater =
database.Query(
"delete from userfriends " +
"where ownerID = ?ownerID and friendID = ?friendID",
param);
updater.ExecuteNonQuery();
updater =
database.Query(
"delete from userfriends " +
"where ownerID = ?friendID and friendID = ?ownerID",
param);
updater.ExecuteNonQuery();
}
}
catch (Exception e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
return;
}
}
public void UpdateUserFriendPerms(LLUUID friendlistowner, LLUUID friend, uint perms)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["?ownerID"] = friendlistowner.UUID.ToString();
param["?friendID"] = friend.UUID.ToString();
param["?friendPerms"] = perms.ToString();
try
{
lock (database)
{
IDbCommand updater =
database.Query(
"update userfriends " +
"SET friendPerms = ?friendPerms " +
"where ownerID = ?ownerID and friendID = ?friendID",
param);
updater.ExecuteNonQuery();
}
}
catch (Exception e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
return;
}
}
public List<FriendListItem> GetUserFriendList(LLUUID friendlistowner)
{
List<FriendListItem> Lfli = new List<FriendListItem>();
Dictionary<string, string> param = new Dictionary<string, string>();
param["?ownerID"] = friendlistowner.UUID.ToString();
try
{
lock (database)
{
//Left Join userfriends to itself
IDbCommand result =
database.Query(
"select a.ownerID,a.friendID,a.friendPerms,b.friendPerms as ownerperms from userfriends as a, userfriends as b" +
" where a.ownerID = ?ownerID and b.ownerID = a.friendID and b.friendID = a.ownerID",
param);
IDataReader reader = result.ExecuteReader();
while (reader.Read())
{
FriendListItem fli = new FriendListItem();
fli.FriendListOwner = new LLUUID((string)reader["ownerID"]);
fli.Friend = new LLUUID((string)reader["friendID"]);
fli.FriendPerms = (uint)Convert.ToInt32(reader["friendPerms"]);
// This is not a real column in the database table, it's a joined column from the opposite record
fli.FriendListOwnerPerms = (uint)Convert.ToInt32(reader["ownerperms"]);
Lfli.Add(fli);
}
reader.Close();
result.Dispose();
}
}
catch (Exception e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
return Lfli;
}
return Lfli;
}
#endregion
public void UpdateUserCurrentRegion(LLUUID avatarid, LLUUID regionuuid)
{
MainLog.Instance.Verbose("USER", "Stub UpdateUserCUrrentRegion called");
}
public void LogOffUser(LLUUID avatarid)
{
MainLog.Instance.Verbose("USER", "Stub LogOffUser called");
}
public List<Framework.AvatarPickerAvatar> GeneratePickerResults(LLUUID queryID, string query)
{
List<Framework.AvatarPickerAvatar> returnlist = new List<Framework.AvatarPickerAvatar>();
Regex objAlphaNumericPattern = new Regex("[^a-zA-Z0-9]");
string[] querysplit;
querysplit = query.Split(' ');
if (querysplit.Length == 2)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["?first"] = objAlphaNumericPattern.Replace(querysplit[0], "") + "%";
param["?second"] = objAlphaNumericPattern.Replace(querysplit[1], "") + "%";
try
{
lock (database)
{
IDbCommand result =
database.Query(
"SELECT UUID,username,lastname FROM users WHERE username like ?first AND lastname like ?second LIMIT 100",
param);
IDataReader reader = result.ExecuteReader();
while (reader.Read())
{
Framework.AvatarPickerAvatar user = new Framework.AvatarPickerAvatar();
user.AvatarID = new LLUUID((string) reader["UUID"]);
user.firstName = (string) reader["username"];
user.lastName = (string) reader["lastname"];
returnlist.Add(user);
}
reader.Close();
result.Dispose();
}
}
catch (Exception e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
return returnlist;
}
}
else if (querysplit.Length == 1)
{
try
{
lock (database)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["?first"] = objAlphaNumericPattern.Replace(querysplit[0], "") + "%";
IDbCommand result =
database.Query(
"SELECT UUID,username,lastname FROM users WHERE username like ?first OR lastname like ?first LIMIT 100",
param);
IDataReader reader = result.ExecuteReader();
while (reader.Read())
{
Framework.AvatarPickerAvatar user = new Framework.AvatarPickerAvatar();
user.AvatarID = new LLUUID((string) reader["UUID"]);
user.firstName = (string) reader["username"];
user.lastName = (string) reader["lastname"];
returnlist.Add(user);
}
reader.Close();
result.Dispose();
}
}
catch (Exception e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
return returnlist;
}
}
return returnlist;
}
// see IUserData
public UserProfileData GetUserByUUID(LLUUID uuid)
{
try
{
lock (database)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["?uuid"] = uuid.ToString();
IDbCommand result = database.Query("SELECT * FROM users WHERE UUID = ?uuid", param);
IDataReader reader = result.ExecuteReader();
UserProfileData row = database.readUserRow(reader);
reader.Close();
result.Dispose();
return row;
}
}
catch (Exception e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
return null;
}
}
/// <summary>
/// Searches the database for a specified user profile by account
/// </summary>
/// <param name="uuid">The account</param>
/// <returns>The users profile</returns>
public UserProfileData GetUserByAccount(string account)
{
try
{
lock (database)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["?account"] = account;
IDbCommand result = database.Query("SELECT * FROM users WHERE account = ?account", param);
IDataReader reader = result.ExecuteReader();
UserProfileData row = database.readUserRow(reader);
reader.Close();
result.Dispose();
return row;
}
}
catch (Exception e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
return null;
}
}
/// <summary>
/// Returns a user session searching by name
/// </summary>
/// <param name="name">The account name</param>
/// <returns>The users session</returns>
public UserAgentData GetAgentByName(string name)
{
return GetAgentByName(name.Split(' ')[0], name.Split(' ')[1]);
}
/// <summary>
/// Returns a user session by account name
/// </summary>
/// <param name="user">First part of the users account name</param>
/// <param name="last">Second part of the users account name</param>
/// <returns>The users session</returns>
public UserAgentData GetAgentByName(string user, string last)
{
UserProfileData profile = GetUserByName(user, last);
return GetAgentByUUID(profile.UUID);
}
/// <summary>
/// Returns an agent session by account UUID
/// </summary>
/// <param name="uuid">The accounts UUID</param>
/// <returns>The users session</returns>
public UserAgentData GetAgentByUUID(LLUUID uuid)
{
try
{
lock (database)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["?uuid"] = uuid.ToString();
IDbCommand result = database.Query("SELECT * FROM agents WHERE UUID = ?uuid", param);
IDataReader reader = result.ExecuteReader();
UserAgentData row = database.readAgentRow(reader);
reader.Close();
result.Dispose();
return row;
}
}
catch (Exception e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
return null;
}
}
/// <summary>
/// Creates a new users profile
/// </summary>
/// <param name="user">The user profile to create</param>
public void AddNewUserProfile(UserProfileData user)
{
try
{
lock (database)
{
database.insertUserRow(user.UUID, user.username, user.surname, user.passwordHash, user.passwordSalt,
user.homeRegion, user.homeLocation.X, user.homeLocation.Y,
user.homeLocation.Z,
user.homeLookAt.X, user.homeLookAt.Y, user.homeLookAt.Z, user.created,
user.lastLogin, user.userInventoryURI, user.userAssetURI,
user.profileCanDoMask, user.profileWantDoMask,
user.profileAboutText, user.profileFirstText, user.profileImage,
user.profileFirstImage, user.webLoginKey);
}
}
catch (Exception e)
{
database.Reconnect();
MainLog.Instance.Error(e.ToString());
}
}
/// <summary>
/// Creates a new agent
/// </summary>
/// <param name="agent">The agent to create</param>
public void AddNewUserAgent(UserAgentData agent)
{
// Do nothing.
}
/// <summary>
/// Updates a user profile stored in the DB
/// </summary>
/// <param name="user">The profile data to use to update the DB</param>
public bool UpdateUserProfile(UserProfileData user)
{
// TODO: implement
return true;
}
/// <summary>
/// Performs a money transfer request between two accounts
/// </summary>
/// <param name="from">The senders account ID</param>
/// <param name="to">The receivers account ID</param>
/// <param name="amount">The amount to transfer</param>
/// <returns>Success?</returns>
public bool MoneyTransferRequest(LLUUID from, LLUUID to, uint amount)
{
return false;
}
/// <summary>
/// Performs an inventory transfer request between two accounts
/// </summary>
/// <remarks>TODO: Move to inventory server</remarks>
/// <param name="from">The senders account ID</param>
/// <param name="to">The receivers account ID</param>
/// <param name="item">The item to transfer</param>
/// <returns>Success?</returns>
public bool InventoryTransferRequest(LLUUID from, LLUUID to, LLUUID item)
{
return false;
}
/// <summary>
/// Database provider name
/// </summary>
/// <returns>Provider name</returns>
public string getName()
{
return "MySQL Userdata Interface";
}
/// <summary>
/// Database provider version
/// </summary>
/// <returns>provider version</returns>
public string GetVersion()
{
return "0.1";
}
}
}

View File

@ -0,0 +1,38 @@
using System.Reflection;
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("OpenSim.Framework.Data.MySQL")]
[assembly : AssemblyDescription("")]
[assembly : AssemblyConfiguration("")]
[assembly : AssemblyCompany("")]
[assembly : AssemblyProduct("OpenSim.Framework.Data.MySQL")]
[assembly : AssemblyCopyright("Copyright © 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("e49826b2-dcef-41be-a5bd-596733fa3304")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly : AssemblyVersion("1.0.0.0")]
[assembly : AssemblyFileVersion("1.0.0.0")]

Some files were not shown because too many files have changed in this diff Show More