Update svn properties. Minor formatting cleanup.
parent
bdf1262605
commit
d51ce47b2d
|
@ -1,39 +1,39 @@
|
|||
CREATE TABLE `land`
|
||||
(
|
||||
`UUID` varchar (255) NOT NULL,
|
||||
`RegionUUID` varchar (255) DEFAULT NULL ,
|
||||
`LocalLandID` int (11) DEFAULT NULL ,
|
||||
`Bitmap` longblob,
|
||||
`Name` varchar (255) DEFAULT NULL ,
|
||||
`Description` varchar (255) DEFAULT NULL ,
|
||||
`OwnerUUID` varchar (255) DEFAULT NULL ,
|
||||
`IsGroupOwned` int (11) DEFAULT NULL ,
|
||||
`Area` int (11) DEFAULT NULL ,
|
||||
`AuctionID` int (11) DEFAULT NULL ,
|
||||
`Category` int (11) DEFAULT NULL ,
|
||||
`ClaimDate` int (11) DEFAULT NULL ,
|
||||
`ClaimPrice` int (11) DEFAULT NULL ,
|
||||
`GroupUUID` varchar (255) DEFAULT NULL ,
|
||||
`SalePrice` int (11) DEFAULT NULL ,
|
||||
`LandStatus` int (11) DEFAULT NULL ,
|
||||
`LandFlags` int (11) DEFAULT NULL ,
|
||||
`LandingType` int (11) DEFAULT NULL ,
|
||||
`MediaAutoScale` int (11) DEFAULT NULL ,
|
||||
`MediaTextureUUID` varchar (255) DEFAULT NULL ,
|
||||
`MediaURL` varchar (255) DEFAULT NULL ,
|
||||
`MusicURL` varchar (255) DEFAULT NULL ,
|
||||
`PassHours` float DEFAULT NULL ,
|
||||
`PassPrice` int (11) DEFAULT NULL ,
|
||||
`SnapshotUUID` varchar (255) DEFAULT NULL ,
|
||||
`UserLocationX` float DEFAULT NULL ,
|
||||
`UserLocationY` float DEFAULT NULL ,
|
||||
`UserLocationZ` float DEFAULT NULL ,
|
||||
`UserLookAtX` float DEFAULT NULL ,
|
||||
`UserLookAtY` float DEFAULT NULL ,
|
||||
`UserLookAtZ` float DEFAULT NULL ,
|
||||
`AuthbuyerID` varchar(36) default '00000000-0000-0000-0000-000000000000' not null,
|
||||
|
||||
PRIMARY KEY (`UUID`)
|
||||
)
|
||||
ENGINE=INNODB
|
||||
CREATE TABLE `land`
|
||||
(
|
||||
`UUID` varchar (255) NOT NULL,
|
||||
`RegionUUID` varchar (255) DEFAULT NULL ,
|
||||
`LocalLandID` int (11) DEFAULT NULL ,
|
||||
`Bitmap` longblob,
|
||||
`Name` varchar (255) DEFAULT NULL ,
|
||||
`Description` varchar (255) DEFAULT NULL ,
|
||||
`OwnerUUID` varchar (255) DEFAULT NULL ,
|
||||
`IsGroupOwned` int (11) DEFAULT NULL ,
|
||||
`Area` int (11) DEFAULT NULL ,
|
||||
`AuctionID` int (11) DEFAULT NULL ,
|
||||
`Category` int (11) DEFAULT NULL ,
|
||||
`ClaimDate` int (11) DEFAULT NULL ,
|
||||
`ClaimPrice` int (11) DEFAULT NULL ,
|
||||
`GroupUUID` varchar (255) DEFAULT NULL ,
|
||||
`SalePrice` int (11) DEFAULT NULL ,
|
||||
`LandStatus` int (11) DEFAULT NULL ,
|
||||
`LandFlags` int (11) DEFAULT NULL ,
|
||||
`LandingType` int (11) DEFAULT NULL ,
|
||||
`MediaAutoScale` int (11) DEFAULT NULL ,
|
||||
`MediaTextureUUID` varchar (255) DEFAULT NULL ,
|
||||
`MediaURL` varchar (255) DEFAULT NULL ,
|
||||
`MusicURL` varchar (255) DEFAULT NULL ,
|
||||
`PassHours` float DEFAULT NULL ,
|
||||
`PassPrice` int (11) DEFAULT NULL ,
|
||||
`SnapshotUUID` varchar (255) DEFAULT NULL ,
|
||||
`UserLocationX` float DEFAULT NULL ,
|
||||
`UserLocationY` float DEFAULT NULL ,
|
||||
`UserLocationZ` float DEFAULT NULL ,
|
||||
`UserLookAtX` float DEFAULT NULL ,
|
||||
`UserLookAtY` float DEFAULT NULL ,
|
||||
`UserLookAtZ` float DEFAULT NULL ,
|
||||
`AuthbuyerID` varchar(36) default '00000000-0000-0000-0000-000000000000' not null,
|
||||
|
||||
PRIMARY KEY (`UUID`)
|
||||
)
|
||||
ENGINE=INNODB
|
||||
DEFAULT CHARSET=utf8 COMMENT='Rev. 2';
|
|
@ -1,3 +1,3 @@
|
|||
ALTER TABLE `land`
|
||||
ADD COLUMN `AuthbuyerID` varchar(36) default '00000000-0000-0000-0000-000000000000' not null,
|
||||
ALTER TABLE `land`
|
||||
ADD COLUMN `AuthbuyerID` varchar(36) default '00000000-0000-0000-0000-000000000000' not null,
|
||||
COMMENT='Rev. 2';
|
|
@ -1,65 +1,65 @@
|
|||
using System;
|
||||
|
||||
namespace OpenSim.Framework
|
||||
{
|
||||
[Serializable]
|
||||
public class Location : ICloneable
|
||||
{
|
||||
private readonly int m_x;
|
||||
private readonly int m_y;
|
||||
|
||||
public Location(int x, int y)
|
||||
{
|
||||
m_x = x;
|
||||
m_y = y;
|
||||
}
|
||||
|
||||
public int X
|
||||
{
|
||||
get { return m_x; }
|
||||
}
|
||||
|
||||
public int Y
|
||||
{
|
||||
get { return m_y; }
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(obj, this))
|
||||
return true;
|
||||
|
||||
if (obj is Location)
|
||||
{
|
||||
return Equals((Location) obj);
|
||||
}
|
||||
|
||||
return base.Equals(obj);
|
||||
}
|
||||
|
||||
public bool Equals(Location loc)
|
||||
{
|
||||
return loc.X == X && loc.Y == Y;
|
||||
}
|
||||
|
||||
public bool Equals(int x, int y)
|
||||
{
|
||||
return X == x && y == Y;
|
||||
}
|
||||
|
||||
public UInt64 RegionHandle
|
||||
{
|
||||
get { return UInt64.MinValue; }
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return X.GetHashCode() * 29 + Y.GetHashCode();
|
||||
}
|
||||
|
||||
public object Clone()
|
||||
{
|
||||
return new Location(X, Y);
|
||||
}
|
||||
}
|
||||
using System;
|
||||
|
||||
namespace OpenSim.Framework
|
||||
{
|
||||
[Serializable]
|
||||
public class Location : ICloneable
|
||||
{
|
||||
private readonly int m_x;
|
||||
private readonly int m_y;
|
||||
|
||||
public Location(int x, int y)
|
||||
{
|
||||
m_x = x;
|
||||
m_y = y;
|
||||
}
|
||||
|
||||
public int X
|
||||
{
|
||||
get { return m_x; }
|
||||
}
|
||||
|
||||
public int Y
|
||||
{
|
||||
get { return m_y; }
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(obj, this))
|
||||
return true;
|
||||
|
||||
if (obj is Location)
|
||||
{
|
||||
return Equals((Location) obj);
|
||||
}
|
||||
|
||||
return base.Equals(obj);
|
||||
}
|
||||
|
||||
public bool Equals(Location loc)
|
||||
{
|
||||
return loc.X == X && loc.Y == Y;
|
||||
}
|
||||
|
||||
public bool Equals(int x, int y)
|
||||
{
|
||||
return X == x && y == Y;
|
||||
}
|
||||
|
||||
public UInt64 RegionHandle
|
||||
{
|
||||
get { return UInt64.MinValue; }
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return X.GetHashCode() * 29 + Y.GetHashCode();
|
||||
}
|
||||
|
||||
public object Clone()
|
||||
{
|
||||
return new Location(X, Y);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -588,7 +588,6 @@ namespace OpenSim
|
|||
m_moduleLoader, m_dumpAssetsToFile, m_physicalPrim, m_see_into_region_from_neighbor);
|
||||
}
|
||||
|
||||
|
||||
public void handleRestartRegion(RegionInfo whichRegion)
|
||||
{
|
||||
m_log.Error("[OPENSIM MAIN]: Got restart signal from SceneManager");
|
||||
|
|
|
@ -1,228 +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.Collections.Generic;
|
||||
using libsecondlife;
|
||||
using libsecondlife.Packets;
|
||||
using Nini.Config;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Agent.AssetDownload
|
||||
{
|
||||
public class AssetDownloadModule : IRegionModule
|
||||
{
|
||||
/// <summary>
|
||||
/// Asset requests with data which are ready to be sent back to requesters. This includes textures.
|
||||
/// </summary>
|
||||
private List<AssetRequest> AssetRequests;
|
||||
|
||||
private Scene m_scene;
|
||||
private Dictionary<LLUUID, Scene> RegisteredScenes = new Dictionary<LLUUID, Scene>();
|
||||
|
||||
///
|
||||
/// Assets requests (for each user) which are waiting for asset server data. This includes texture requests
|
||||
/// </summary>
|
||||
private Dictionary<LLUUID, Dictionary<LLUUID, AssetRequest>> RequestedAssets;
|
||||
|
||||
public AssetDownloadModule()
|
||||
{
|
||||
RequestedAssets = new Dictionary<LLUUID, Dictionary<LLUUID, AssetRequest>>();
|
||||
AssetRequests = new List<AssetRequest>();
|
||||
}
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource config)
|
||||
{
|
||||
if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID))
|
||||
{
|
||||
RegisteredScenes.Add(scene.RegionInfo.RegionID, scene);
|
||||
// scene.EventManager.OnNewClient += NewClient;
|
||||
}
|
||||
|
||||
if (m_scene == null)
|
||||
{
|
||||
m_scene = scene;
|
||||
// m_thread = new Thread(new ThreadStart(RunAssetQueue));
|
||||
// m_thread.Name = "AssetDownloadQueueThread";
|
||||
// m_thread.IsBackground = true;
|
||||
// m_thread.Start();
|
||||
// OpenSim.Framework.ThreadTracker.Add(m_thread);
|
||||
}
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "AssetDownloadModule"; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void NewClient(IClientAPI client)
|
||||
{
|
||||
// client.OnRequestAsset += AddAssetRequest;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Make an asset request the result of which will be packeted up and sent directly back to the client.
|
||||
/// </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);
|
||||
}
|
||||
|
||||
//not found asset
|
||||
// so request from asset server
|
||||
Dictionary<LLUUID, AssetRequest> userRequests = null;
|
||||
if (RequestedAssets.TryGetValue(userInfo.AgentId, out userRequests))
|
||||
{
|
||||
if (!userRequests.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;
|
||||
userRequests[requestID] = request;
|
||||
m_scene.AssetCache.GetAsset(requestID, AssetCallback, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
userRequests = new Dictionary<LLUUID, AssetRequest>();
|
||||
AssetRequest request = new AssetRequest();
|
||||
request.RequestUser = userInfo;
|
||||
request.RequestAssetID = requestID;
|
||||
request.TransferRequestID = transferRequest.TransferInfo.TransferID;
|
||||
request.AssetRequestSource = source;
|
||||
request.Params = transferRequest.TransferInfo.Params;
|
||||
userRequests.Add(requestID, request);
|
||||
RequestedAssets[userInfo.AgentId] = userRequests;
|
||||
m_scene.AssetCache.GetAsset(requestID, AssetCallback, false);
|
||||
}
|
||||
}
|
||||
|
||||
public void AssetCallback(LLUUID assetID, AssetBase asset)
|
||||
{
|
||||
if (asset != null)
|
||||
{
|
||||
foreach (Dictionary<LLUUID, AssetRequest> userRequests in RequestedAssets.Values)
|
||||
{
|
||||
if (userRequests.ContainsKey(assetID))
|
||||
{
|
||||
AssetRequest req = userRequests[assetID];
|
||||
if (req != null)
|
||||
{
|
||||
req.AssetInf = asset;
|
||||
req.NumPackets = CalculateNumPackets(asset.Data);
|
||||
|
||||
userRequests.Remove(assetID);
|
||||
AssetRequests.Add(req);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate the number of packets required to send the asset to the client.
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
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 Nested type: AssetRequest
|
||||
|
||||
public class AssetRequest
|
||||
{
|
||||
public AssetBase AssetInf;
|
||||
public byte AssetRequestSource = 2;
|
||||
public long DataPointer = 0;
|
||||
public int DiscardLevel = -1;
|
||||
public AssetBase ImageInfo;
|
||||
public bool IsTextureRequest;
|
||||
public int NumPackets = 0;
|
||||
public int PacketCounter = 0;
|
||||
public byte[] Params = null;
|
||||
public LLUUID RequestAssetID;
|
||||
public IClientAPI RequestUser;
|
||||
public LLUUID TransferRequestID;
|
||||
//public bool AssetInCache;
|
||||
//public int TimeRequested;
|
||||
|
||||
public AssetRequest()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
/*
|
||||
* 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;
|
||||
using Nini.Config;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Agent.AssetDownload
|
||||
{
|
||||
public class AssetDownloadModule : IRegionModule
|
||||
{
|
||||
/// <summary>
|
||||
/// Asset requests with data which are ready to be sent back to requesters. This includes textures.
|
||||
/// </summary>
|
||||
private List<AssetRequest> AssetRequests;
|
||||
|
||||
private Scene m_scene;
|
||||
private Dictionary<LLUUID, Scene> RegisteredScenes = new Dictionary<LLUUID, Scene>();
|
||||
|
||||
///
|
||||
/// Assets requests (for each user) which are waiting for asset server data. This includes texture requests
|
||||
/// </summary>
|
||||
private Dictionary<LLUUID, Dictionary<LLUUID, AssetRequest>> RequestedAssets;
|
||||
|
||||
public AssetDownloadModule()
|
||||
{
|
||||
RequestedAssets = new Dictionary<LLUUID, Dictionary<LLUUID, AssetRequest>>();
|
||||
AssetRequests = new List<AssetRequest>();
|
||||
}
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource config)
|
||||
{
|
||||
if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID))
|
||||
{
|
||||
RegisteredScenes.Add(scene.RegionInfo.RegionID, scene);
|
||||
// scene.EventManager.OnNewClient += NewClient;
|
||||
}
|
||||
|
||||
if (m_scene == null)
|
||||
{
|
||||
m_scene = scene;
|
||||
// m_thread = new Thread(new ThreadStart(RunAssetQueue));
|
||||
// m_thread.Name = "AssetDownloadQueueThread";
|
||||
// m_thread.IsBackground = true;
|
||||
// m_thread.Start();
|
||||
// OpenSim.Framework.ThreadTracker.Add(m_thread);
|
||||
}
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "AssetDownloadModule"; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void NewClient(IClientAPI client)
|
||||
{
|
||||
// client.OnRequestAsset += AddAssetRequest;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Make an asset request the result of which will be packeted up and sent directly back to the client.
|
||||
/// </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);
|
||||
}
|
||||
|
||||
//not found asset
|
||||
// so request from asset server
|
||||
Dictionary<LLUUID, AssetRequest> userRequests = null;
|
||||
if (RequestedAssets.TryGetValue(userInfo.AgentId, out userRequests))
|
||||
{
|
||||
if (!userRequests.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;
|
||||
userRequests[requestID] = request;
|
||||
m_scene.AssetCache.GetAsset(requestID, AssetCallback, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
userRequests = new Dictionary<LLUUID, AssetRequest>();
|
||||
AssetRequest request = new AssetRequest();
|
||||
request.RequestUser = userInfo;
|
||||
request.RequestAssetID = requestID;
|
||||
request.TransferRequestID = transferRequest.TransferInfo.TransferID;
|
||||
request.AssetRequestSource = source;
|
||||
request.Params = transferRequest.TransferInfo.Params;
|
||||
userRequests.Add(requestID, request);
|
||||
RequestedAssets[userInfo.AgentId] = userRequests;
|
||||
m_scene.AssetCache.GetAsset(requestID, AssetCallback, false);
|
||||
}
|
||||
}
|
||||
|
||||
public void AssetCallback(LLUUID assetID, AssetBase asset)
|
||||
{
|
||||
if (asset != null)
|
||||
{
|
||||
foreach (Dictionary<LLUUID, AssetRequest> userRequests in RequestedAssets.Values)
|
||||
{
|
||||
if (userRequests.ContainsKey(assetID))
|
||||
{
|
||||
AssetRequest req = userRequests[assetID];
|
||||
if (req != null)
|
||||
{
|
||||
req.AssetInf = asset;
|
||||
req.NumPackets = CalculateNumPackets(asset.Data);
|
||||
|
||||
userRequests.Remove(assetID);
|
||||
AssetRequests.Add(req);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate the number of packets required to send the asset to the client.
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
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 Nested type: AssetRequest
|
||||
|
||||
public class AssetRequest
|
||||
{
|
||||
public AssetBase AssetInf;
|
||||
public byte AssetRequestSource = 2;
|
||||
public long DataPointer = 0;
|
||||
public int DiscardLevel = -1;
|
||||
public AssetBase ImageInfo;
|
||||
public bool IsTextureRequest;
|
||||
public int NumPackets = 0;
|
||||
public int PacketCounter = 0;
|
||||
public byte[] Params = null;
|
||||
public LLUUID RequestAssetID;
|
||||
public IClientAPI RequestUser;
|
||||
public LLUUID TransferRequestID;
|
||||
//public bool AssetInCache;
|
||||
//public int TimeRequested;
|
||||
|
||||
public AssetRequest()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -1,412 +1,412 @@
|
|||
/*
|
||||
* 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;
|
||||
using OpenSim.Framework.Communications.Cache;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Agent.AssetTransaction
|
||||
{
|
||||
/// <summary>
|
||||
/// Manage asset transactions for a single agent.
|
||||
/// </summary>
|
||||
public class AgentAssetTransactions
|
||||
{
|
||||
//private static readonly log4net.ILog m_log
|
||||
// = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
// Fields
|
||||
private bool m_dumpAssetsToFile;
|
||||
public AgentAssetTransactionsManager Manager;
|
||||
public LLUUID UserID;
|
||||
public Dictionary<LLUUID, AssetXferUploader> XferUploaders = new Dictionary<LLUUID, AssetXferUploader>();
|
||||
|
||||
// Methods
|
||||
public AgentAssetTransactions(LLUUID agentID, AgentAssetTransactionsManager manager, bool dumpAssetsToFile)
|
||||
{
|
||||
UserID = agentID;
|
||||
Manager = manager;
|
||||
m_dumpAssetsToFile = dumpAssetsToFile;
|
||||
}
|
||||
|
||||
public AssetXferUploader RequestXferUploader(LLUUID transactionID)
|
||||
{
|
||||
if (!XferUploaders.ContainsKey(transactionID))
|
||||
{
|
||||
AssetXferUploader uploader = new AssetXferUploader(this, m_dumpAssetsToFile);
|
||||
|
||||
lock (XferUploaders)
|
||||
{
|
||||
XferUploaders.Add(transactionID, uploader);
|
||||
}
|
||||
|
||||
return uploader;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void HandleXfer(ulong xferID, uint packetID, byte[] data)
|
||||
{
|
||||
// AssetXferUploader uploaderFound = null;
|
||||
|
||||
lock (XferUploaders)
|
||||
{
|
||||
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 void RequestUpdateInventoryItem(IClientAPI remoteClient, LLUUID transactionID,
|
||||
InventoryItemBase item)
|
||||
{
|
||||
if (XferUploaders.ContainsKey(transactionID))
|
||||
{
|
||||
XferUploaders[transactionID].RequestUpdateInventoryItem(remoteClient, transactionID, item);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get an uploaded asset. If the data is successfully retrieved, the transaction will be removed.
|
||||
/// </summary>
|
||||
/// <param name="transactionID"></param>
|
||||
/// <returns>The asset if the upload has completed, null if it has not.</returns>
|
||||
public AssetBase GetTransactionAsset(LLUUID transactionID)
|
||||
{
|
||||
if (XferUploaders.ContainsKey(transactionID))
|
||||
{
|
||||
AssetXferUploader uploader = XferUploaders[transactionID];
|
||||
AssetBase asset = uploader.GetAssetData();
|
||||
|
||||
lock (XferUploaders)
|
||||
{
|
||||
XferUploaders.Remove(transactionID);
|
||||
}
|
||||
|
||||
return asset;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Nested Types
|
||||
|
||||
#region Nested type: AssetXferUploader
|
||||
|
||||
public class AssetXferUploader
|
||||
{
|
||||
// Fields
|
||||
public bool AddToInventory;
|
||||
public AssetBase Asset;
|
||||
public LLUUID InventFolder = LLUUID.Zero;
|
||||
private sbyte invType = 0;
|
||||
private bool m_createItem = false;
|
||||
private string m_description = String.Empty;
|
||||
private bool m_dumpAssetToFile;
|
||||
private bool m_finished = false;
|
||||
private string m_name = String.Empty;
|
||||
private bool m_storeLocal;
|
||||
private AgentAssetTransactions m_userTransactions;
|
||||
private uint nextPerm = 0;
|
||||
private IClientAPI ourClient;
|
||||
public LLUUID TransactionID = LLUUID.Zero;
|
||||
private sbyte type = 0;
|
||||
public bool UploadComplete;
|
||||
private byte wearableType = 0;
|
||||
public ulong XferID;
|
||||
|
||||
public AssetXferUploader(AgentAssetTransactions transactions, bool dumpAssetToFile)
|
||||
{
|
||||
m_userTransactions = transactions;
|
||||
m_dumpAssetToFile = dumpAssetToFile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process transfer data received from the client.
|
||||
/// </summary>
|
||||
/// <param name="xferID"></param>
|
||||
/// <param name="packetID"></param>
|
||||
/// <param name="data"></param>
|
||||
/// <returns>True if the transfer is complete, false otherwise or if the xferID was not valid</returns>
|
||||
public bool 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();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialise asset transfer from the client
|
||||
/// </summary>
|
||||
/// <param name="xferID"></param>
|
||||
/// <param name="packetID"></param>
|
||||
/// <param name="data"></param>
|
||||
/// <returns>True if the transfer is complete, false otherwise</returns>
|
||||
public bool 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();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
RequestStartXfer();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void RequestStartXfer()
|
||||
{
|
||||
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.MyScene.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;
|
||||
this.wearableType = wearableType;
|
||||
nextPerm = nextOwnerMask;
|
||||
Asset.Name = name;
|
||||
Asset.Description = description;
|
||||
Asset.Type = type;
|
||||
Asset.InvType = invType;
|
||||
m_createItem = true;
|
||||
if (m_finished)
|
||||
{
|
||||
DoCreateItem();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RequestUpdateInventoryItem(IClientAPI remoteClient, LLUUID transactionID,
|
||||
InventoryItemBase item)
|
||||
{
|
||||
if (TransactionID == transactionID)
|
||||
{
|
||||
CachedUserInfo userInfo =
|
||||
m_userTransactions.Manager.MyScene.CommsManager.UserProfileCacheService.GetUserDetails(
|
||||
remoteClient.AgentId);
|
||||
|
||||
if (userInfo != null)
|
||||
{
|
||||
LLUUID assetID = LLUUID.Combine(transactionID, remoteClient.SecureSessionId);
|
||||
|
||||
AssetBase asset
|
||||
= m_userTransactions.Manager.MyScene.CommsManager.AssetCache.GetAsset(
|
||||
assetID, (item.AssetType == (int) AssetType.Texture ? true : false));
|
||||
|
||||
if (asset == null)
|
||||
{
|
||||
asset = m_userTransactions.GetTransactionAsset(transactionID);
|
||||
}
|
||||
|
||||
if (asset != null && asset.FullID == assetID)
|
||||
{
|
||||
asset.Name = item.Name;
|
||||
asset.Description = item.Description;
|
||||
asset.InvType = (sbyte) item.InvType;
|
||||
asset.Type = (sbyte) item.AssetType;
|
||||
item.AssetID = asset.FullID;
|
||||
|
||||
m_userTransactions.Manager.MyScene.CommsManager.AssetCache.AddAsset(Asset);
|
||||
}
|
||||
|
||||
userInfo.UpdateItem(remoteClient.AgentId, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DoCreateItem()
|
||||
{
|
||||
//really need to fix this call, if lbsa71 saw this he would die.
|
||||
m_userTransactions.Manager.MyScene.CommsManager.AssetCache.AddAsset(Asset);
|
||||
CachedUserInfo userInfo =
|
||||
m_userTransactions.Manager.MyScene.CommsManager.UserProfileCacheService.GetUserDetails(ourClient.AgentId);
|
||||
if (userInfo != null)
|
||||
{
|
||||
InventoryItemBase item = new InventoryItemBase();
|
||||
item.Owner = ourClient.AgentId;
|
||||
item.Creator = ourClient.AgentId;
|
||||
item.ID = LLUUID.Random();
|
||||
item.AssetID = Asset.FullID;
|
||||
item.Description = m_description;
|
||||
item.Name = m_name;
|
||||
item.AssetType = type;
|
||||
item.InvType = invType;
|
||||
item.Folder = InventFolder;
|
||||
item.BasePermissions = 2147483647;
|
||||
item.CurrentPermissions = 2147483647;
|
||||
item.NextPermissions = nextPerm;
|
||||
item.Flags = (uint) wearableType;
|
||||
|
||||
userInfo.AddItem(ourClient.AgentId, item);
|
||||
ourClient.SendInventoryItemCreateUpdate(item);
|
||||
}
|
||||
}
|
||||
|
||||
public AssetBase GetAssetData()
|
||||
{
|
||||
if (m_finished)
|
||||
{
|
||||
return Asset;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
/*
|
||||
* 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;
|
||||
using OpenSim.Framework.Communications.Cache;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Agent.AssetTransaction
|
||||
{
|
||||
/// <summary>
|
||||
/// Manage asset transactions for a single agent.
|
||||
/// </summary>
|
||||
public class AgentAssetTransactions
|
||||
{
|
||||
//private static readonly log4net.ILog m_log
|
||||
// = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
// Fields
|
||||
private bool m_dumpAssetsToFile;
|
||||
public AgentAssetTransactionsManager Manager;
|
||||
public LLUUID UserID;
|
||||
public Dictionary<LLUUID, AssetXferUploader> XferUploaders = new Dictionary<LLUUID, AssetXferUploader>();
|
||||
|
||||
// Methods
|
||||
public AgentAssetTransactions(LLUUID agentID, AgentAssetTransactionsManager manager, bool dumpAssetsToFile)
|
||||
{
|
||||
UserID = agentID;
|
||||
Manager = manager;
|
||||
m_dumpAssetsToFile = dumpAssetsToFile;
|
||||
}
|
||||
|
||||
public AssetXferUploader RequestXferUploader(LLUUID transactionID)
|
||||
{
|
||||
if (!XferUploaders.ContainsKey(transactionID))
|
||||
{
|
||||
AssetXferUploader uploader = new AssetXferUploader(this, m_dumpAssetsToFile);
|
||||
|
||||
lock (XferUploaders)
|
||||
{
|
||||
XferUploaders.Add(transactionID, uploader);
|
||||
}
|
||||
|
||||
return uploader;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void HandleXfer(ulong xferID, uint packetID, byte[] data)
|
||||
{
|
||||
// AssetXferUploader uploaderFound = null;
|
||||
|
||||
lock (XferUploaders)
|
||||
{
|
||||
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 void RequestUpdateInventoryItem(IClientAPI remoteClient, LLUUID transactionID,
|
||||
InventoryItemBase item)
|
||||
{
|
||||
if (XferUploaders.ContainsKey(transactionID))
|
||||
{
|
||||
XferUploaders[transactionID].RequestUpdateInventoryItem(remoteClient, transactionID, item);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get an uploaded asset. If the data is successfully retrieved, the transaction will be removed.
|
||||
/// </summary>
|
||||
/// <param name="transactionID"></param>
|
||||
/// <returns>The asset if the upload has completed, null if it has not.</returns>
|
||||
public AssetBase GetTransactionAsset(LLUUID transactionID)
|
||||
{
|
||||
if (XferUploaders.ContainsKey(transactionID))
|
||||
{
|
||||
AssetXferUploader uploader = XferUploaders[transactionID];
|
||||
AssetBase asset = uploader.GetAssetData();
|
||||
|
||||
lock (XferUploaders)
|
||||
{
|
||||
XferUploaders.Remove(transactionID);
|
||||
}
|
||||
|
||||
return asset;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Nested Types
|
||||
|
||||
#region Nested type: AssetXferUploader
|
||||
|
||||
public class AssetXferUploader
|
||||
{
|
||||
// Fields
|
||||
public bool AddToInventory;
|
||||
public AssetBase Asset;
|
||||
public LLUUID InventFolder = LLUUID.Zero;
|
||||
private sbyte invType = 0;
|
||||
private bool m_createItem = false;
|
||||
private string m_description = String.Empty;
|
||||
private bool m_dumpAssetToFile;
|
||||
private bool m_finished = false;
|
||||
private string m_name = String.Empty;
|
||||
private bool m_storeLocal;
|
||||
private AgentAssetTransactions m_userTransactions;
|
||||
private uint nextPerm = 0;
|
||||
private IClientAPI ourClient;
|
||||
public LLUUID TransactionID = LLUUID.Zero;
|
||||
private sbyte type = 0;
|
||||
public bool UploadComplete;
|
||||
private byte wearableType = 0;
|
||||
public ulong XferID;
|
||||
|
||||
public AssetXferUploader(AgentAssetTransactions transactions, bool dumpAssetToFile)
|
||||
{
|
||||
m_userTransactions = transactions;
|
||||
m_dumpAssetToFile = dumpAssetToFile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process transfer data received from the client.
|
||||
/// </summary>
|
||||
/// <param name="xferID"></param>
|
||||
/// <param name="packetID"></param>
|
||||
/// <param name="data"></param>
|
||||
/// <returns>True if the transfer is complete, false otherwise or if the xferID was not valid</returns>
|
||||
public bool 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();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialise asset transfer from the client
|
||||
/// </summary>
|
||||
/// <param name="xferID"></param>
|
||||
/// <param name="packetID"></param>
|
||||
/// <param name="data"></param>
|
||||
/// <returns>True if the transfer is complete, false otherwise</returns>
|
||||
public bool 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();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
RequestStartXfer();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void RequestStartXfer()
|
||||
{
|
||||
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.MyScene.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;
|
||||
this.wearableType = wearableType;
|
||||
nextPerm = nextOwnerMask;
|
||||
Asset.Name = name;
|
||||
Asset.Description = description;
|
||||
Asset.Type = type;
|
||||
Asset.InvType = invType;
|
||||
m_createItem = true;
|
||||
if (m_finished)
|
||||
{
|
||||
DoCreateItem();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RequestUpdateInventoryItem(IClientAPI remoteClient, LLUUID transactionID,
|
||||
InventoryItemBase item)
|
||||
{
|
||||
if (TransactionID == transactionID)
|
||||
{
|
||||
CachedUserInfo userInfo =
|
||||
m_userTransactions.Manager.MyScene.CommsManager.UserProfileCacheService.GetUserDetails(
|
||||
remoteClient.AgentId);
|
||||
|
||||
if (userInfo != null)
|
||||
{
|
||||
LLUUID assetID = LLUUID.Combine(transactionID, remoteClient.SecureSessionId);
|
||||
|
||||
AssetBase asset
|
||||
= m_userTransactions.Manager.MyScene.CommsManager.AssetCache.GetAsset(
|
||||
assetID, (item.AssetType == (int) AssetType.Texture ? true : false));
|
||||
|
||||
if (asset == null)
|
||||
{
|
||||
asset = m_userTransactions.GetTransactionAsset(transactionID);
|
||||
}
|
||||
|
||||
if (asset != null && asset.FullID == assetID)
|
||||
{
|
||||
asset.Name = item.Name;
|
||||
asset.Description = item.Description;
|
||||
asset.InvType = (sbyte) item.InvType;
|
||||
asset.Type = (sbyte) item.AssetType;
|
||||
item.AssetID = asset.FullID;
|
||||
|
||||
m_userTransactions.Manager.MyScene.CommsManager.AssetCache.AddAsset(Asset);
|
||||
}
|
||||
|
||||
userInfo.UpdateItem(remoteClient.AgentId, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DoCreateItem()
|
||||
{
|
||||
//really need to fix this call, if lbsa71 saw this he would die.
|
||||
m_userTransactions.Manager.MyScene.CommsManager.AssetCache.AddAsset(Asset);
|
||||
CachedUserInfo userInfo =
|
||||
m_userTransactions.Manager.MyScene.CommsManager.UserProfileCacheService.GetUserDetails(ourClient.AgentId);
|
||||
if (userInfo != null)
|
||||
{
|
||||
InventoryItemBase item = new InventoryItemBase();
|
||||
item.Owner = ourClient.AgentId;
|
||||
item.Creator = ourClient.AgentId;
|
||||
item.ID = LLUUID.Random();
|
||||
item.AssetID = Asset.FullID;
|
||||
item.Description = m_description;
|
||||
item.Name = m_name;
|
||||
item.AssetType = type;
|
||||
item.InvType = invType;
|
||||
item.Folder = InventFolder;
|
||||
item.BasePermissions = 2147483647;
|
||||
item.CurrentPermissions = 2147483647;
|
||||
item.NextPermissions = nextPerm;
|
||||
item.Flags = (uint) wearableType;
|
||||
|
||||
userInfo.AddItem(ourClient.AgentId, item);
|
||||
ourClient.SendInventoryItemCreateUpdate(item);
|
||||
}
|
||||
}
|
||||
|
||||
public AssetBase GetAssetData()
|
||||
{
|
||||
if (m_finished)
|
||||
{
|
||||
return Asset;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -1,291 +1,291 @@
|
|||
/*
|
||||
* 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 log4net;
|
||||
using Nini.Config;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Agent.AssetTransaction
|
||||
{
|
||||
public class AssetTransactionModule : IRegionModule, IAgentAssetTransactions
|
||||
{
|
||||
private readonly Dictionary<LLUUID, Scene> RegisteredScenes = new Dictionary<LLUUID, Scene>();
|
||||
private bool m_dumpAssetsToFile = false;
|
||||
private Scene m_scene = null;
|
||||
|
||||
private AgentAssetTransactionsManager m_transactionManager;
|
||||
|
||||
public AssetTransactionModule()
|
||||
{
|
||||
// System.Console.WriteLine("creating AgentAssetTransactionModule");
|
||||
}
|
||||
|
||||
#region IAgentAssetTransactions Members
|
||||
|
||||
public void HandleItemCreationFromTransaction(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID,
|
||||
uint callbackID, string description, string name, sbyte invType,
|
||||
sbyte type, byte wearableType, uint nextOwnerMask)
|
||||
{
|
||||
m_transactionManager.HandleItemCreationFromTransaction(remoteClient, transactionID, folderID, callbackID, description, name, invType, type,
|
||||
wearableType, nextOwnerMask);
|
||||
}
|
||||
|
||||
public void HandleItemUpdateFromTransaction(IClientAPI remoteClient, LLUUID transactionID,
|
||||
InventoryItemBase item)
|
||||
{
|
||||
m_transactionManager.HandleItemUpdateFromTransaction(remoteClient, transactionID, item);
|
||||
}
|
||||
|
||||
public void RemoveAgentAssetTransactions(LLUUID userID)
|
||||
{
|
||||
m_transactionManager.RemoveAgentAssetTransactions(userID);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource config)
|
||||
{
|
||||
if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID))
|
||||
{
|
||||
// System.Console.WriteLine("initialising AgentAssetTransactionModule");
|
||||
RegisteredScenes.Add(scene.RegionInfo.RegionID, scene);
|
||||
scene.RegisterModuleInterface<IAgentAssetTransactions>(this);
|
||||
|
||||
scene.EventManager.OnNewClient += NewClient;
|
||||
}
|
||||
|
||||
if (m_scene == null)
|
||||
{
|
||||
m_scene = scene;
|
||||
if (config.Configs["StandAlone"] != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_dumpAssetsToFile = config.Configs["StandAlone"].GetBoolean("dump_assets_to_file", false);
|
||||
m_transactionManager = new AgentAssetTransactionsManager(m_scene, m_dumpAssetsToFile);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
m_transactionManager = new AgentAssetTransactionsManager(m_scene, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_transactionManager = new AgentAssetTransactionsManager(m_scene, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "AgentTransactionModule"; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void NewClient(IClientAPI client)
|
||||
{
|
||||
client.OnAssetUploadRequest += m_transactionManager.HandleUDPUploadRequest;
|
||||
client.OnXferReceive += m_transactionManager.HandleXfer;
|
||||
}
|
||||
}
|
||||
|
||||
public class AgentAssetTransactionsManager
|
||||
{
|
||||
private static readonly ILog m_log
|
||||
= LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
// Fields
|
||||
|
||||
/// <summary>
|
||||
/// Each agent has its own singleton collection of transactions
|
||||
/// </summary>
|
||||
private Dictionary<LLUUID, AgentAssetTransactions> AgentTransactions =
|
||||
new Dictionary<LLUUID, AgentAssetTransactions>();
|
||||
|
||||
/// <summary>
|
||||
/// Should we dump uploaded assets to the filesystem?
|
||||
/// </summary>
|
||||
private bool m_dumpAssetsToFile;
|
||||
|
||||
public Scene MyScene;
|
||||
|
||||
public AgentAssetTransactionsManager(Scene scene, bool dumpAssetsToFile)
|
||||
{
|
||||
MyScene = scene;
|
||||
m_dumpAssetsToFile = dumpAssetsToFile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the collection of asset transactions for the given user. If one does not already exist, it
|
||||
/// is created.
|
||||
/// </summary>
|
||||
/// <param name="userID"></param>
|
||||
/// <returns></returns>
|
||||
private AgentAssetTransactions GetUserTransactions(LLUUID userID)
|
||||
{
|
||||
lock (AgentTransactions)
|
||||
{
|
||||
if (!AgentTransactions.ContainsKey(userID))
|
||||
{
|
||||
AgentAssetTransactions transactions
|
||||
= new AgentAssetTransactions(userID, this, m_dumpAssetsToFile);
|
||||
AgentTransactions.Add(userID, transactions);
|
||||
}
|
||||
|
||||
return AgentTransactions[userID];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove the given agent asset transactions. This should be called when a client is departing
|
||||
/// from a scene (and hence won't be making any more transactions here).
|
||||
/// </summary>
|
||||
/// <param name="userID"></param>
|
||||
public void RemoveAgentAssetTransactions(LLUUID userID)
|
||||
{
|
||||
// m_log.DebugFormat("Removing agent asset transactions structure for agent {0}", userID);
|
||||
|
||||
lock (AgentTransactions)
|
||||
{
|
||||
AgentTransactions.Remove(userID);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create an inventory item from data that has been received through a transaction.
|
||||
///
|
||||
/// This is called when new clothing or body parts are created. It may also be called in other
|
||||
/// situations.
|
||||
/// </summary>
|
||||
/// <param name="remoteClient"></param>
|
||||
/// <param name="transactionID"></param>
|
||||
/// <param name="folderID"></param>
|
||||
/// <param name="callbackID"></param>
|
||||
/// <param name="description"></param>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="invType"></param>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="wearableType"></param>
|
||||
/// <param name="nextOwnerMask"></param>
|
||||
public void HandleItemCreationFromTransaction(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID,
|
||||
uint callbackID, string description, string name, sbyte invType,
|
||||
sbyte type, byte wearableType, uint nextOwnerMask)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[TRANSACTIONS MANAGER] Called HandleItemCreationFromTransaction with item {0}", name);
|
||||
|
||||
AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
|
||||
|
||||
transactions.RequestCreateInventoryItem(
|
||||
remoteClient, transactionID, folderID, callbackID, description,
|
||||
name, invType, type, wearableType, nextOwnerMask);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update an inventory item with data that has been received through a transaction.
|
||||
///
|
||||
/// This is called when clothing or body parts are updated (for instance, with new textures or
|
||||
/// colours). It may also be called in other situations.
|
||||
/// </summary>
|
||||
/// <param name="remoteClient"></param>
|
||||
/// <param name="transactionID"></param>
|
||||
/// <param name="item"></param>
|
||||
public void HandleItemUpdateFromTransaction(IClientAPI remoteClient, LLUUID transactionID,
|
||||
InventoryItemBase item)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[TRANSACTIONS MANAGER] Called HandleItemUpdateFromTransaction with item {0}",
|
||||
item.Name);
|
||||
|
||||
AgentAssetTransactions transactions
|
||||
= GetUserTransactions(remoteClient.AgentId);
|
||||
|
||||
transactions.RequestUpdateInventoryItem(remoteClient, transactionID, item);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Request that a client (agent) begin an asset transfer.
|
||||
/// </summary>
|
||||
/// <param name="remoteClient"></param>
|
||||
/// <param name="assetID"></param>
|
||||
/// <param name="transaction"></param>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="data"></param></param>
|
||||
/// <param name="tempFile"></param>
|
||||
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);
|
||||
|
||||
AgentAssetTransactions.AssetXferUploader uploader = transactions.RequestXferUploader(transaction);
|
||||
if (uploader != null)
|
||||
{
|
||||
if (uploader.Initialise(remoteClient, assetID, transaction, type, data, storeLocal, tempFile))
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle asset transfer data packets received in response to the asset upload request in
|
||||
/// HandleUDPUploadRequest()
|
||||
/// </summary>
|
||||
/// <param name="remoteClient"></param>
|
||||
/// <param name="xferID"></param>
|
||||
/// <param name="packetID"></param>
|
||||
/// <param name="data"></param>
|
||||
public void HandleXfer(IClientAPI remoteClient, ulong xferID, uint packetID, byte[] data)
|
||||
{
|
||||
AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
|
||||
|
||||
transactions.HandleXfer(xferID, packetID, data);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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 log4net;
|
||||
using Nini.Config;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Agent.AssetTransaction
|
||||
{
|
||||
public class AssetTransactionModule : IRegionModule, IAgentAssetTransactions
|
||||
{
|
||||
private readonly Dictionary<LLUUID, Scene> RegisteredScenes = new Dictionary<LLUUID, Scene>();
|
||||
private bool m_dumpAssetsToFile = false;
|
||||
private Scene m_scene = null;
|
||||
|
||||
private AgentAssetTransactionsManager m_transactionManager;
|
||||
|
||||
public AssetTransactionModule()
|
||||
{
|
||||
// System.Console.WriteLine("creating AgentAssetTransactionModule");
|
||||
}
|
||||
|
||||
#region IAgentAssetTransactions Members
|
||||
|
||||
public void HandleItemCreationFromTransaction(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID,
|
||||
uint callbackID, string description, string name, sbyte invType,
|
||||
sbyte type, byte wearableType, uint nextOwnerMask)
|
||||
{
|
||||
m_transactionManager.HandleItemCreationFromTransaction(remoteClient, transactionID, folderID, callbackID, description, name, invType, type,
|
||||
wearableType, nextOwnerMask);
|
||||
}
|
||||
|
||||
public void HandleItemUpdateFromTransaction(IClientAPI remoteClient, LLUUID transactionID,
|
||||
InventoryItemBase item)
|
||||
{
|
||||
m_transactionManager.HandleItemUpdateFromTransaction(remoteClient, transactionID, item);
|
||||
}
|
||||
|
||||
public void RemoveAgentAssetTransactions(LLUUID userID)
|
||||
{
|
||||
m_transactionManager.RemoveAgentAssetTransactions(userID);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource config)
|
||||
{
|
||||
if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID))
|
||||
{
|
||||
// System.Console.WriteLine("initialising AgentAssetTransactionModule");
|
||||
RegisteredScenes.Add(scene.RegionInfo.RegionID, scene);
|
||||
scene.RegisterModuleInterface<IAgentAssetTransactions>(this);
|
||||
|
||||
scene.EventManager.OnNewClient += NewClient;
|
||||
}
|
||||
|
||||
if (m_scene == null)
|
||||
{
|
||||
m_scene = scene;
|
||||
if (config.Configs["StandAlone"] != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_dumpAssetsToFile = config.Configs["StandAlone"].GetBoolean("dump_assets_to_file", false);
|
||||
m_transactionManager = new AgentAssetTransactionsManager(m_scene, m_dumpAssetsToFile);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
m_transactionManager = new AgentAssetTransactionsManager(m_scene, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_transactionManager = new AgentAssetTransactionsManager(m_scene, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "AgentTransactionModule"; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void NewClient(IClientAPI client)
|
||||
{
|
||||
client.OnAssetUploadRequest += m_transactionManager.HandleUDPUploadRequest;
|
||||
client.OnXferReceive += m_transactionManager.HandleXfer;
|
||||
}
|
||||
}
|
||||
|
||||
public class AgentAssetTransactionsManager
|
||||
{
|
||||
private static readonly ILog m_log
|
||||
= LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
// Fields
|
||||
|
||||
/// <summary>
|
||||
/// Each agent has its own singleton collection of transactions
|
||||
/// </summary>
|
||||
private Dictionary<LLUUID, AgentAssetTransactions> AgentTransactions =
|
||||
new Dictionary<LLUUID, AgentAssetTransactions>();
|
||||
|
||||
/// <summary>
|
||||
/// Should we dump uploaded assets to the filesystem?
|
||||
/// </summary>
|
||||
private bool m_dumpAssetsToFile;
|
||||
|
||||
public Scene MyScene;
|
||||
|
||||
public AgentAssetTransactionsManager(Scene scene, bool dumpAssetsToFile)
|
||||
{
|
||||
MyScene = scene;
|
||||
m_dumpAssetsToFile = dumpAssetsToFile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the collection of asset transactions for the given user. If one does not already exist, it
|
||||
/// is created.
|
||||
/// </summary>
|
||||
/// <param name="userID"></param>
|
||||
/// <returns></returns>
|
||||
private AgentAssetTransactions GetUserTransactions(LLUUID userID)
|
||||
{
|
||||
lock (AgentTransactions)
|
||||
{
|
||||
if (!AgentTransactions.ContainsKey(userID))
|
||||
{
|
||||
AgentAssetTransactions transactions
|
||||
= new AgentAssetTransactions(userID, this, m_dumpAssetsToFile);
|
||||
AgentTransactions.Add(userID, transactions);
|
||||
}
|
||||
|
||||
return AgentTransactions[userID];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove the given agent asset transactions. This should be called when a client is departing
|
||||
/// from a scene (and hence won't be making any more transactions here).
|
||||
/// </summary>
|
||||
/// <param name="userID"></param>
|
||||
public void RemoveAgentAssetTransactions(LLUUID userID)
|
||||
{
|
||||
// m_log.DebugFormat("Removing agent asset transactions structure for agent {0}", userID);
|
||||
|
||||
lock (AgentTransactions)
|
||||
{
|
||||
AgentTransactions.Remove(userID);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create an inventory item from data that has been received through a transaction.
|
||||
///
|
||||
/// This is called when new clothing or body parts are created. It may also be called in other
|
||||
/// situations.
|
||||
/// </summary>
|
||||
/// <param name="remoteClient"></param>
|
||||
/// <param name="transactionID"></param>
|
||||
/// <param name="folderID"></param>
|
||||
/// <param name="callbackID"></param>
|
||||
/// <param name="description"></param>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="invType"></param>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="wearableType"></param>
|
||||
/// <param name="nextOwnerMask"></param>
|
||||
public void HandleItemCreationFromTransaction(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID,
|
||||
uint callbackID, string description, string name, sbyte invType,
|
||||
sbyte type, byte wearableType, uint nextOwnerMask)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[TRANSACTIONS MANAGER] Called HandleItemCreationFromTransaction with item {0}", name);
|
||||
|
||||
AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
|
||||
|
||||
transactions.RequestCreateInventoryItem(
|
||||
remoteClient, transactionID, folderID, callbackID, description,
|
||||
name, invType, type, wearableType, nextOwnerMask);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update an inventory item with data that has been received through a transaction.
|
||||
///
|
||||
/// This is called when clothing or body parts are updated (for instance, with new textures or
|
||||
/// colours). It may also be called in other situations.
|
||||
/// </summary>
|
||||
/// <param name="remoteClient"></param>
|
||||
/// <param name="transactionID"></param>
|
||||
/// <param name="item"></param>
|
||||
public void HandleItemUpdateFromTransaction(IClientAPI remoteClient, LLUUID transactionID,
|
||||
InventoryItemBase item)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[TRANSACTIONS MANAGER] Called HandleItemUpdateFromTransaction with item {0}",
|
||||
item.Name);
|
||||
|
||||
AgentAssetTransactions transactions
|
||||
= GetUserTransactions(remoteClient.AgentId);
|
||||
|
||||
transactions.RequestUpdateInventoryItem(remoteClient, transactionID, item);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Request that a client (agent) begin an asset transfer.
|
||||
/// </summary>
|
||||
/// <param name="remoteClient"></param>
|
||||
/// <param name="assetID"></param>
|
||||
/// <param name="transaction"></param>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="data"></param></param>
|
||||
/// <param name="tempFile"></param>
|
||||
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);
|
||||
|
||||
AgentAssetTransactions.AssetXferUploader uploader = transactions.RequestXferUploader(transaction);
|
||||
if (uploader != null)
|
||||
{
|
||||
if (uploader.Initialise(remoteClient, assetID, transaction, type, data, storeLocal, tempFile))
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle asset transfer data packets received in response to the asset upload request in
|
||||
/// HandleUDPUploadRequest()
|
||||
/// </summary>
|
||||
/// <param name="remoteClient"></param>
|
||||
/// <param name="xferID"></param>
|
||||
/// <param name="packetID"></param>
|
||||
/// <param name="data"></param>
|
||||
public void HandleXfer(IClientAPI remoteClient, ulong xferID, uint packetID, byte[] data)
|
||||
{
|
||||
AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
|
||||
|
||||
transactions.HandleXfer(xferID, packetID, data);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,219 +1,219 @@
|
|||
/*
|
||||
* 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 Nini.Config;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Agent.TextureDownload
|
||||
{
|
||||
public class TextureDownloadModule : IRegionModule
|
||||
{
|
||||
//private static readonly log4net.ILog m_log
|
||||
// = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
/// <summary>
|
||||
/// There is one queue for all textures waiting to be sent, regardless of the requesting user.
|
||||
/// </summary>
|
||||
private readonly BlockingQueue<ITextureSender> m_queueSenders
|
||||
= new BlockingQueue<ITextureSender>();
|
||||
|
||||
/// <summary>
|
||||
/// Each user has their own texture download service.
|
||||
/// </summary>
|
||||
private readonly Dictionary<LLUUID, UserTextureDownloadService> m_userTextureServices =
|
||||
new Dictionary<LLUUID, UserTextureDownloadService>();
|
||||
|
||||
private Scene m_scene;
|
||||
private List<Scene> m_scenes = new List<Scene>();
|
||||
|
||||
private Thread m_thread;
|
||||
|
||||
public TextureDownloadModule()
|
||||
{
|
||||
}
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource config)
|
||||
{
|
||||
if (m_scene == null)
|
||||
{
|
||||
//Console.WriteLine("Creating Texture download module");
|
||||
m_thread = new Thread(new ThreadStart(ProcessTextureSenders));
|
||||
m_thread.Name = "ProcessTextureSenderThread";
|
||||
m_thread.IsBackground = true;
|
||||
m_thread.Start();
|
||||
ThreadTracker.Add(m_thread);
|
||||
}
|
||||
|
||||
if (!m_scenes.Contains(scene))
|
||||
{
|
||||
m_scenes.Add(scene);
|
||||
m_scene = scene;
|
||||
m_scene.EventManager.OnNewClient += NewClient;
|
||||
m_scene.EventManager.OnRemovePresence += EventManager_OnRemovePresence;
|
||||
}
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "TextureDownloadModule"; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Cleanup the texture service related objects for the removed presence.
|
||||
/// </summary>
|
||||
/// <param name="agentId"> </param>
|
||||
private void EventManager_OnRemovePresence(LLUUID agentId)
|
||||
{
|
||||
UserTextureDownloadService textureService;
|
||||
|
||||
lock (m_userTextureServices)
|
||||
{
|
||||
if (m_userTextureServices.TryGetValue(agentId, out textureService))
|
||||
{
|
||||
textureService.Close();
|
||||
|
||||
m_userTextureServices.Remove(agentId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void NewClient(IClientAPI client)
|
||||
{
|
||||
client.OnRequestTexture += TextureRequest;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Does this user have a registered texture download service?
|
||||
/// </summary>
|
||||
/// <param name="userID"></param>
|
||||
/// <param name="textureService"></param>
|
||||
/// <returns>Always returns true, since a service is created if one does not already exist</returns>
|
||||
private bool TryGetUserTextureService(
|
||||
IClientAPI client, out UserTextureDownloadService textureService)
|
||||
{
|
||||
lock (m_userTextureServices)
|
||||
{
|
||||
if (m_userTextureServices.TryGetValue(client.AgentId, out textureService))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
textureService = new UserTextureDownloadService(client, m_scene, m_queueSenders);
|
||||
m_userTextureServices.Add(client.AgentId, textureService);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start the process of requesting a given texture.
|
||||
/// </summary>
|
||||
/// <param name="sender"> </param>
|
||||
/// <param name="e"></param>
|
||||
public void TextureRequest(Object sender, TextureRequestArgs e)
|
||||
{
|
||||
IClientAPI client = (IClientAPI) sender;
|
||||
UserTextureDownloadService textureService;
|
||||
|
||||
if (TryGetUserTextureService(client, out textureService))
|
||||
{
|
||||
textureService.HandleTextureRequest(e);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Entry point for the thread dedicated to processing the texture queue.
|
||||
/// </summary>
|
||||
public void ProcessTextureSenders()
|
||||
{
|
||||
ITextureSender sender = null;
|
||||
|
||||
while (true)
|
||||
{
|
||||
sender = m_queueSenders.Dequeue();
|
||||
|
||||
if (sender.Cancel)
|
||||
{
|
||||
TextureSent(sender);
|
||||
|
||||
sender.Cancel = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool finished = sender.SendTexturePacket();
|
||||
if (finished)
|
||||
{
|
||||
TextureSent(sender);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_queueSenders.Enqueue(sender);
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure that any sender we currently have can get garbage collected
|
||||
sender = null;
|
||||
|
||||
//m_log.InfoFormat("[TEXTURE DOWNLOAD] Texture sender queue size: {0}", m_queueSenders.Count());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when the texture has finished sending.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
private void TextureSent(ITextureSender sender)
|
||||
{
|
||||
sender.Sending = false;
|
||||
//m_log.DebugFormat("[TEXTURE DOWNLOAD]: Removing download stat for {0}", sender.assetID);
|
||||
m_scene.AddPendingDownloads(-1);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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 Nini.Config;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Agent.TextureDownload
|
||||
{
|
||||
public class TextureDownloadModule : IRegionModule
|
||||
{
|
||||
//private static readonly log4net.ILog m_log
|
||||
// = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
/// <summary>
|
||||
/// There is one queue for all textures waiting to be sent, regardless of the requesting user.
|
||||
/// </summary>
|
||||
private readonly BlockingQueue<ITextureSender> m_queueSenders
|
||||
= new BlockingQueue<ITextureSender>();
|
||||
|
||||
/// <summary>
|
||||
/// Each user has their own texture download service.
|
||||
/// </summary>
|
||||
private readonly Dictionary<LLUUID, UserTextureDownloadService> m_userTextureServices =
|
||||
new Dictionary<LLUUID, UserTextureDownloadService>();
|
||||
|
||||
private Scene m_scene;
|
||||
private List<Scene> m_scenes = new List<Scene>();
|
||||
|
||||
private Thread m_thread;
|
||||
|
||||
public TextureDownloadModule()
|
||||
{
|
||||
}
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource config)
|
||||
{
|
||||
if (m_scene == null)
|
||||
{
|
||||
//Console.WriteLine("Creating Texture download module");
|
||||
m_thread = new Thread(new ThreadStart(ProcessTextureSenders));
|
||||
m_thread.Name = "ProcessTextureSenderThread";
|
||||
m_thread.IsBackground = true;
|
||||
m_thread.Start();
|
||||
ThreadTracker.Add(m_thread);
|
||||
}
|
||||
|
||||
if (!m_scenes.Contains(scene))
|
||||
{
|
||||
m_scenes.Add(scene);
|
||||
m_scene = scene;
|
||||
m_scene.EventManager.OnNewClient += NewClient;
|
||||
m_scene.EventManager.OnRemovePresence += EventManager_OnRemovePresence;
|
||||
}
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "TextureDownloadModule"; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Cleanup the texture service related objects for the removed presence.
|
||||
/// </summary>
|
||||
/// <param name="agentId"> </param>
|
||||
private void EventManager_OnRemovePresence(LLUUID agentId)
|
||||
{
|
||||
UserTextureDownloadService textureService;
|
||||
|
||||
lock (m_userTextureServices)
|
||||
{
|
||||
if (m_userTextureServices.TryGetValue(agentId, out textureService))
|
||||
{
|
||||
textureService.Close();
|
||||
|
||||
m_userTextureServices.Remove(agentId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void NewClient(IClientAPI client)
|
||||
{
|
||||
client.OnRequestTexture += TextureRequest;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Does this user have a registered texture download service?
|
||||
/// </summary>
|
||||
/// <param name="userID"></param>
|
||||
/// <param name="textureService"></param>
|
||||
/// <returns>Always returns true, since a service is created if one does not already exist</returns>
|
||||
private bool TryGetUserTextureService(
|
||||
IClientAPI client, out UserTextureDownloadService textureService)
|
||||
{
|
||||
lock (m_userTextureServices)
|
||||
{
|
||||
if (m_userTextureServices.TryGetValue(client.AgentId, out textureService))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
textureService = new UserTextureDownloadService(client, m_scene, m_queueSenders);
|
||||
m_userTextureServices.Add(client.AgentId, textureService);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start the process of requesting a given texture.
|
||||
/// </summary>
|
||||
/// <param name="sender"> </param>
|
||||
/// <param name="e"></param>
|
||||
public void TextureRequest(Object sender, TextureRequestArgs e)
|
||||
{
|
||||
IClientAPI client = (IClientAPI) sender;
|
||||
UserTextureDownloadService textureService;
|
||||
|
||||
if (TryGetUserTextureService(client, out textureService))
|
||||
{
|
||||
textureService.HandleTextureRequest(e);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Entry point for the thread dedicated to processing the texture queue.
|
||||
/// </summary>
|
||||
public void ProcessTextureSenders()
|
||||
{
|
||||
ITextureSender sender = null;
|
||||
|
||||
while (true)
|
||||
{
|
||||
sender = m_queueSenders.Dequeue();
|
||||
|
||||
if (sender.Cancel)
|
||||
{
|
||||
TextureSent(sender);
|
||||
|
||||
sender.Cancel = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool finished = sender.SendTexturePacket();
|
||||
if (finished)
|
||||
{
|
||||
TextureSent(sender);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_queueSenders.Enqueue(sender);
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure that any sender we currently have can get garbage collected
|
||||
sender = null;
|
||||
|
||||
//m_log.InfoFormat("[TEXTURE DOWNLOAD] Texture sender queue size: {0}", m_queueSenders.Count());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when the texture has finished sending.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
private void TextureSent(ITextureSender sender)
|
||||
{
|
||||
sender.Sending = false;
|
||||
//m_log.DebugFormat("[TEXTURE DOWNLOAD]: Removing download stat for {0}", sender.assetID);
|
||||
m_scene.AddPendingDownloads(-1);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,98 +1,98 @@
|
|||
/*
|
||||
* 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;
|
||||
using libsecondlife.Packets;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Agent.TextureDownload
|
||||
{
|
||||
/// <summary>
|
||||
/// Sends a 'texture not found' packet back to the client
|
||||
/// </summary>
|
||||
public class TextureNotFoundSender : ITextureSender
|
||||
{
|
||||
//private static readonly log4net.ILog m_log
|
||||
// = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private bool m_cancel = false;
|
||||
private IClientAPI m_client;
|
||||
|
||||
// See ITextureSender
|
||||
|
||||
private bool m_sending = false;
|
||||
private LLUUID m_textureId;
|
||||
|
||||
// See ITextureSender
|
||||
|
||||
public TextureNotFoundSender(IClientAPI client, LLUUID textureID)
|
||||
{
|
||||
m_client = client;
|
||||
m_textureId = textureID;
|
||||
}
|
||||
|
||||
#region ITextureSender Members
|
||||
|
||||
public bool Sending
|
||||
{
|
||||
get { return false; }
|
||||
set { m_sending = value; }
|
||||
}
|
||||
|
||||
public bool Cancel
|
||||
{
|
||||
get { return false; }
|
||||
set { m_cancel = value; }
|
||||
}
|
||||
|
||||
// See ITextureSender
|
||||
public void UpdateRequest(int discardLevel, uint packetNumber)
|
||||
{
|
||||
// Not need to implement since priority changes don't affect this operation
|
||||
}
|
||||
|
||||
// See ITextureSender
|
||||
public bool SendTexturePacket()
|
||||
{
|
||||
//m_log.InfoFormat(
|
||||
// "[TEXTURE NOT FOUND SENDER]: Informing the client that texture {0} cannot be found",
|
||||
// m_textureId);
|
||||
|
||||
ImageNotInDatabasePacket notFound = new ImageNotInDatabasePacket();
|
||||
notFound.ImageID.ID = m_textureId;
|
||||
|
||||
// XXX Temporarily disabling as this appears to be causing client crashes on at least
|
||||
// 1.19.0(5) of the Linden Second Life client.
|
||||
// m_client.OutPacket(notFound, ThrottleOutPacketType.Texture);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
/*
|
||||
* 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;
|
||||
using libsecondlife.Packets;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Agent.TextureDownload
|
||||
{
|
||||
/// <summary>
|
||||
/// Sends a 'texture not found' packet back to the client
|
||||
/// </summary>
|
||||
public class TextureNotFoundSender : ITextureSender
|
||||
{
|
||||
//private static readonly log4net.ILog m_log
|
||||
// = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private bool m_cancel = false;
|
||||
private IClientAPI m_client;
|
||||
|
||||
// See ITextureSender
|
||||
|
||||
private bool m_sending = false;
|
||||
private LLUUID m_textureId;
|
||||
|
||||
// See ITextureSender
|
||||
|
||||
public TextureNotFoundSender(IClientAPI client, LLUUID textureID)
|
||||
{
|
||||
m_client = client;
|
||||
m_textureId = textureID;
|
||||
}
|
||||
|
||||
#region ITextureSender Members
|
||||
|
||||
public bool Sending
|
||||
{
|
||||
get { return false; }
|
||||
set { m_sending = value; }
|
||||
}
|
||||
|
||||
public bool Cancel
|
||||
{
|
||||
get { return false; }
|
||||
set { m_cancel = value; }
|
||||
}
|
||||
|
||||
// See ITextureSender
|
||||
public void UpdateRequest(int discardLevel, uint packetNumber)
|
||||
{
|
||||
// Not need to implement since priority changes don't affect this operation
|
||||
}
|
||||
|
||||
// See ITextureSender
|
||||
public bool SendTexturePacket()
|
||||
{
|
||||
//m_log.InfoFormat(
|
||||
// "[TEXTURE NOT FOUND SENDER]: Informing the client that texture {0} cannot be found",
|
||||
// m_textureId);
|
||||
|
||||
ImageNotInDatabasePacket notFound = new ImageNotInDatabasePacket();
|
||||
notFound.ImageID.ID = m_textureId;
|
||||
|
||||
// XXX Temporarily disabling as this appears to be causing client crashes on at least
|
||||
// 1.19.0(5) of the Linden Second Life client.
|
||||
// m_client.OutPacket(notFound, ThrottleOutPacketType.Texture);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -1,249 +1,249 @@
|
|||
/*
|
||||
* 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.Reflection;
|
||||
using libsecondlife;
|
||||
using log4net;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Communications.Limit;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Agent.TextureDownload
|
||||
{
|
||||
/// <summary>
|
||||
/// This module sets up texture senders in response to client texture requests, and places them on a
|
||||
/// processing queue once those senders have the appropriate data (i.e. a texture retrieved from the
|
||||
/// asset cache).
|
||||
/// </summary>
|
||||
public class UserTextureDownloadService
|
||||
{
|
||||
private static readonly ILog m_log
|
||||
= LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
/// <summary>
|
||||
/// We will allow the client to request the same texture n times before dropping further requests
|
||||
///
|
||||
/// This number includes repeated requests for the same texture at different resolutions (which we don't
|
||||
/// currently handle properly as far as I know). However, this situation should be handled in a more
|
||||
/// sophisticated way.
|
||||
/// </summary>
|
||||
private static readonly int MAX_ALLOWED_TEXTURE_REQUESTS = 5;
|
||||
|
||||
/// <summary>
|
||||
/// XXX Also going to limit requests for found textures.
|
||||
/// </summary>
|
||||
private readonly IRequestLimitStrategy<LLUUID> foundTextureLimitStrategy
|
||||
= new RepeatLimitStrategy<LLUUID>(MAX_ALLOWED_TEXTURE_REQUESTS);
|
||||
|
||||
private readonly IClientAPI m_client;
|
||||
private readonly Scene m_scene;
|
||||
|
||||
/// <summary>
|
||||
/// Texture Senders are placed in this queue once they have received their texture from the asset
|
||||
/// cache. Another module actually invokes the send.
|
||||
/// </summary>
|
||||
private readonly BlockingQueue<ITextureSender> m_sharedSendersQueue;
|
||||
|
||||
/// <summary>
|
||||
/// Holds texture senders before they have received the appropriate texture from the asset cache.
|
||||
/// </summary>
|
||||
private readonly Dictionary<LLUUID, TextureSender.TextureSender> m_textureSenders = new Dictionary<LLUUID, TextureSender.TextureSender>();
|
||||
|
||||
/// <summary>
|
||||
/// We're going to limit requests for the same missing texture.
|
||||
/// XXX This is really a temporary solution to deal with the situation where a client continually requests
|
||||
/// the same missing textures
|
||||
/// </summary>
|
||||
private readonly IRequestLimitStrategy<LLUUID> missingTextureLimitStrategy
|
||||
= new RepeatLimitStrategy<LLUUID>(MAX_ALLOWED_TEXTURE_REQUESTS);
|
||||
|
||||
public UserTextureDownloadService(
|
||||
IClientAPI client, Scene scene, BlockingQueue<ITextureSender> sharedQueue)
|
||||
{
|
||||
m_client = client;
|
||||
m_scene = scene;
|
||||
m_sharedSendersQueue = sharedQueue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle a texture request. This involves creating a texture sender and placing it on the
|
||||
/// previously passed in shared queue.
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
public void HandleTextureRequest(TextureRequestArgs e)
|
||||
{
|
||||
TextureSender.TextureSender textureSender;
|
||||
|
||||
//TODO: should be working out the data size/ number of packets to be sent for each discard level
|
||||
if ((e.DiscardLevel >= 0) || (e.Priority != 0))
|
||||
{
|
||||
lock (m_textureSenders)
|
||||
{
|
||||
if (m_textureSenders.TryGetValue(e.RequestedAssetID, out textureSender))
|
||||
{
|
||||
// If we've received new non UUID information for this request and it hasn't dispatched
|
||||
// yet, then update the request accordingly.
|
||||
textureSender.UpdateRequest(e.DiscardLevel, e.PacketNumber);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!foundTextureLimitStrategy.AllowRequest(e.RequestedAssetID))
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[USER TEXTURE DOWNLOAD SERVICE]: Refusing request for {0} from client {1}",
|
||||
// e.RequestedAssetID, m_client.AgentId);
|
||||
|
||||
return;
|
||||
}
|
||||
else if (!missingTextureLimitStrategy.AllowRequest(e.RequestedAssetID))
|
||||
{
|
||||
if (missingTextureLimitStrategy.IsFirstRefusal(e.RequestedAssetID))
|
||||
{
|
||||
// Commenting out this message for now as it causes too much noise with other
|
||||
// debug messages.
|
||||
// TODO: possibly record this as a statistic in the future
|
||||
//
|
||||
// m_log.DebugFormat(
|
||||
// "[USER TEXTURE DOWNLOAD SERVICE]: Dropping requests for notified missing texture {0} for client {1} since we have received more than {2} requests",
|
||||
// e.RequestedAssetID, m_client.AgentId, MAX_ALLOWED_TEXTURE_REQUESTS);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
m_scene.AddPendingDownloads(1);
|
||||
|
||||
TextureSender.TextureSender requestHandler = new TextureSender.TextureSender(m_client, e.DiscardLevel, e.PacketNumber);
|
||||
m_textureSenders.Add(e.RequestedAssetID, requestHandler);
|
||||
|
||||
m_scene.AssetCache.GetAsset(e.RequestedAssetID, TextureCallback, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lock (m_textureSenders)
|
||||
{
|
||||
if (m_textureSenders.TryGetValue(e.RequestedAssetID, out textureSender))
|
||||
{
|
||||
textureSender.Cancel = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The callback for the asset cache when a texture has been retrieved. This method queues the
|
||||
/// texture sender for processing.
|
||||
/// </summary>
|
||||
/// <param name="textureID"></param>
|
||||
/// <param name="texture"></param>
|
||||
public void TextureCallback(LLUUID textureID, AssetBase texture)
|
||||
{
|
||||
//m_log.DebugFormat("[USER TEXTURE DOWNLOAD SERVICE]: Calling TextureCallback with {0}, texture == null is {1}", textureID, (texture == null ? true : false));
|
||||
|
||||
lock (m_textureSenders)
|
||||
{
|
||||
TextureSender.TextureSender textureSender;
|
||||
|
||||
if (m_textureSenders.TryGetValue(textureID, out textureSender))
|
||||
{
|
||||
// XXX It may be perfectly valid for a texture to have no data... but if we pass
|
||||
// this on to the TextureSender it will blow up, so just discard for now.
|
||||
// Needs investigation.
|
||||
if (texture == null || texture.Data == null)
|
||||
{
|
||||
if (!missingTextureLimitStrategy.IsMonitoringRequests(textureID))
|
||||
{
|
||||
missingTextureLimitStrategy.MonitorRequests(textureID);
|
||||
|
||||
m_log.DebugFormat(
|
||||
"[USER TEXTURE DOWNLOAD SERVICE]: Queueing first TextureNotFoundSender for {0}, client {1}",
|
||||
textureID, m_client.AgentId);
|
||||
}
|
||||
|
||||
ITextureSender textureNotFoundSender = new TextureNotFoundSender(m_client, textureID);
|
||||
EnqueueTextureSender(textureNotFoundSender);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!textureSender.ImageLoaded)
|
||||
{
|
||||
textureSender.TextureReceived(texture);
|
||||
EnqueueTextureSender(textureSender);
|
||||
|
||||
foundTextureLimitStrategy.MonitorRequests(textureID);
|
||||
}
|
||||
}
|
||||
|
||||
//m_log.InfoFormat("[TEXTURE SENDER] Removing texture sender with uuid {0}", textureID);
|
||||
m_textureSenders.Remove(textureID);
|
||||
//m_log.InfoFormat("[TEXTURE SENDER] Current texture senders in dictionary: {0}", m_textureSenders.Count);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"Got a texture uuid {0} with no sender object to handle it, this shouldn't happen",
|
||||
textureID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Place a ready texture sender on the processing queue.
|
||||
/// </summary>
|
||||
/// <param name="textureSender"></param>
|
||||
private void EnqueueTextureSender(ITextureSender textureSender)
|
||||
{
|
||||
textureSender.Cancel = false;
|
||||
textureSender.Sending = true;
|
||||
|
||||
if (!m_sharedSendersQueue.Contains(textureSender))
|
||||
{
|
||||
m_sharedSendersQueue.Enqueue(textureSender);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Close this module.
|
||||
/// </summary>
|
||||
internal void Close()
|
||||
{
|
||||
lock (m_textureSenders)
|
||||
{
|
||||
foreach (TextureSender.TextureSender textureSender in m_textureSenders.Values)
|
||||
{
|
||||
textureSender.Cancel = true;
|
||||
}
|
||||
|
||||
m_textureSenders.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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.Reflection;
|
||||
using libsecondlife;
|
||||
using log4net;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Communications.Limit;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Agent.TextureDownload
|
||||
{
|
||||
/// <summary>
|
||||
/// This module sets up texture senders in response to client texture requests, and places them on a
|
||||
/// processing queue once those senders have the appropriate data (i.e. a texture retrieved from the
|
||||
/// asset cache).
|
||||
/// </summary>
|
||||
public class UserTextureDownloadService
|
||||
{
|
||||
private static readonly ILog m_log
|
||||
= LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
/// <summary>
|
||||
/// We will allow the client to request the same texture n times before dropping further requests
|
||||
///
|
||||
/// This number includes repeated requests for the same texture at different resolutions (which we don't
|
||||
/// currently handle properly as far as I know). However, this situation should be handled in a more
|
||||
/// sophisticated way.
|
||||
/// </summary>
|
||||
private static readonly int MAX_ALLOWED_TEXTURE_REQUESTS = 5;
|
||||
|
||||
/// <summary>
|
||||
/// XXX Also going to limit requests for found textures.
|
||||
/// </summary>
|
||||
private readonly IRequestLimitStrategy<LLUUID> foundTextureLimitStrategy
|
||||
= new RepeatLimitStrategy<LLUUID>(MAX_ALLOWED_TEXTURE_REQUESTS);
|
||||
|
||||
private readonly IClientAPI m_client;
|
||||
private readonly Scene m_scene;
|
||||
|
||||
/// <summary>
|
||||
/// Texture Senders are placed in this queue once they have received their texture from the asset
|
||||
/// cache. Another module actually invokes the send.
|
||||
/// </summary>
|
||||
private readonly BlockingQueue<ITextureSender> m_sharedSendersQueue;
|
||||
|
||||
/// <summary>
|
||||
/// Holds texture senders before they have received the appropriate texture from the asset cache.
|
||||
/// </summary>
|
||||
private readonly Dictionary<LLUUID, TextureSender.TextureSender> m_textureSenders = new Dictionary<LLUUID, TextureSender.TextureSender>();
|
||||
|
||||
/// <summary>
|
||||
/// We're going to limit requests for the same missing texture.
|
||||
/// XXX This is really a temporary solution to deal with the situation where a client continually requests
|
||||
/// the same missing textures
|
||||
/// </summary>
|
||||
private readonly IRequestLimitStrategy<LLUUID> missingTextureLimitStrategy
|
||||
= new RepeatLimitStrategy<LLUUID>(MAX_ALLOWED_TEXTURE_REQUESTS);
|
||||
|
||||
public UserTextureDownloadService(
|
||||
IClientAPI client, Scene scene, BlockingQueue<ITextureSender> sharedQueue)
|
||||
{
|
||||
m_client = client;
|
||||
m_scene = scene;
|
||||
m_sharedSendersQueue = sharedQueue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle a texture request. This involves creating a texture sender and placing it on the
|
||||
/// previously passed in shared queue.
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
public void HandleTextureRequest(TextureRequestArgs e)
|
||||
{
|
||||
TextureSender.TextureSender textureSender;
|
||||
|
||||
//TODO: should be working out the data size/ number of packets to be sent for each discard level
|
||||
if ((e.DiscardLevel >= 0) || (e.Priority != 0))
|
||||
{
|
||||
lock (m_textureSenders)
|
||||
{
|
||||
if (m_textureSenders.TryGetValue(e.RequestedAssetID, out textureSender))
|
||||
{
|
||||
// If we've received new non UUID information for this request and it hasn't dispatched
|
||||
// yet, then update the request accordingly.
|
||||
textureSender.UpdateRequest(e.DiscardLevel, e.PacketNumber);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!foundTextureLimitStrategy.AllowRequest(e.RequestedAssetID))
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[USER TEXTURE DOWNLOAD SERVICE]: Refusing request for {0} from client {1}",
|
||||
// e.RequestedAssetID, m_client.AgentId);
|
||||
|
||||
return;
|
||||
}
|
||||
else if (!missingTextureLimitStrategy.AllowRequest(e.RequestedAssetID))
|
||||
{
|
||||
if (missingTextureLimitStrategy.IsFirstRefusal(e.RequestedAssetID))
|
||||
{
|
||||
// Commenting out this message for now as it causes too much noise with other
|
||||
// debug messages.
|
||||
// TODO: possibly record this as a statistic in the future
|
||||
//
|
||||
// m_log.DebugFormat(
|
||||
// "[USER TEXTURE DOWNLOAD SERVICE]: Dropping requests for notified missing texture {0} for client {1} since we have received more than {2} requests",
|
||||
// e.RequestedAssetID, m_client.AgentId, MAX_ALLOWED_TEXTURE_REQUESTS);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
m_scene.AddPendingDownloads(1);
|
||||
|
||||
TextureSender.TextureSender requestHandler = new TextureSender.TextureSender(m_client, e.DiscardLevel, e.PacketNumber);
|
||||
m_textureSenders.Add(e.RequestedAssetID, requestHandler);
|
||||
|
||||
m_scene.AssetCache.GetAsset(e.RequestedAssetID, TextureCallback, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lock (m_textureSenders)
|
||||
{
|
||||
if (m_textureSenders.TryGetValue(e.RequestedAssetID, out textureSender))
|
||||
{
|
||||
textureSender.Cancel = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The callback for the asset cache when a texture has been retrieved. This method queues the
|
||||
/// texture sender for processing.
|
||||
/// </summary>
|
||||
/// <param name="textureID"></param>
|
||||
/// <param name="texture"></param>
|
||||
public void TextureCallback(LLUUID textureID, AssetBase texture)
|
||||
{
|
||||
//m_log.DebugFormat("[USER TEXTURE DOWNLOAD SERVICE]: Calling TextureCallback with {0}, texture == null is {1}", textureID, (texture == null ? true : false));
|
||||
|
||||
lock (m_textureSenders)
|
||||
{
|
||||
TextureSender.TextureSender textureSender;
|
||||
|
||||
if (m_textureSenders.TryGetValue(textureID, out textureSender))
|
||||
{
|
||||
// XXX It may be perfectly valid for a texture to have no data... but if we pass
|
||||
// this on to the TextureSender it will blow up, so just discard for now.
|
||||
// Needs investigation.
|
||||
if (texture == null || texture.Data == null)
|
||||
{
|
||||
if (!missingTextureLimitStrategy.IsMonitoringRequests(textureID))
|
||||
{
|
||||
missingTextureLimitStrategy.MonitorRequests(textureID);
|
||||
|
||||
m_log.DebugFormat(
|
||||
"[USER TEXTURE DOWNLOAD SERVICE]: Queueing first TextureNotFoundSender for {0}, client {1}",
|
||||
textureID, m_client.AgentId);
|
||||
}
|
||||
|
||||
ITextureSender textureNotFoundSender = new TextureNotFoundSender(m_client, textureID);
|
||||
EnqueueTextureSender(textureNotFoundSender);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!textureSender.ImageLoaded)
|
||||
{
|
||||
textureSender.TextureReceived(texture);
|
||||
EnqueueTextureSender(textureSender);
|
||||
|
||||
foundTextureLimitStrategy.MonitorRequests(textureID);
|
||||
}
|
||||
}
|
||||
|
||||
//m_log.InfoFormat("[TEXTURE SENDER] Removing texture sender with uuid {0}", textureID);
|
||||
m_textureSenders.Remove(textureID);
|
||||
//m_log.InfoFormat("[TEXTURE SENDER] Current texture senders in dictionary: {0}", m_textureSenders.Count);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"Got a texture uuid {0} with no sender object to handle it, this shouldn't happen",
|
||||
textureID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Place a ready texture sender on the processing queue.
|
||||
/// </summary>
|
||||
/// <param name="textureSender"></param>
|
||||
private void EnqueueTextureSender(ITextureSender textureSender)
|
||||
{
|
||||
textureSender.Cancel = false;
|
||||
textureSender.Sending = true;
|
||||
|
||||
if (!m_sharedSendersQueue.Contains(textureSender))
|
||||
{
|
||||
m_sharedSendersQueue.Enqueue(textureSender);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Close this module.
|
||||
/// </summary>
|
||||
internal void Close()
|
||||
{
|
||||
lock (m_textureSenders)
|
||||
{
|
||||
foreach (TextureSender.TextureSender textureSender in m_textureSenders.Values)
|
||||
{
|
||||
textureSender.Cancel = true;
|
||||
}
|
||||
|
||||
m_textureSenders.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,223 +1,223 @@
|
|||
/*
|
||||
* 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.Reflection;
|
||||
using libsecondlife.Packets;
|
||||
using log4net;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Agent.TextureSender
|
||||
{
|
||||
/// <summary>
|
||||
/// A TextureSender handles the process of receiving a texture requested by the client from the
|
||||
/// AssetCache, and then sending that texture back to the client.
|
||||
/// </summary>
|
||||
public class TextureSender : ITextureSender
|
||||
{
|
||||
private static readonly ILog m_log
|
||||
= LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
/// <summary>
|
||||
/// Records the number of times texture send has been called.
|
||||
/// </summary>
|
||||
public int counter = 0;
|
||||
|
||||
public bool ImageLoaded = false;
|
||||
|
||||
/// <summary>
|
||||
/// Holds the texture asset to send.
|
||||
/// </summary>
|
||||
private AssetBase m_asset;
|
||||
|
||||
//public LLUUID assetID { get { return m_asset.FullID; } }
|
||||
|
||||
private bool m_cancel = false;
|
||||
|
||||
// See ITextureSender
|
||||
|
||||
private bool m_sending = false;
|
||||
|
||||
/// <summary>
|
||||
/// This is actually the number of extra packets required to send the texture data! We always assume
|
||||
/// at least one is required.
|
||||
/// </summary>
|
||||
private int NumPackets = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Holds the packet number to send next. In this case, each packet is 1000 bytes long and starts
|
||||
/// at the 600th byte (0th indexed).
|
||||
/// </summary>
|
||||
private int PacketCounter = 0;
|
||||
|
||||
private int RequestedDiscardLevel = -1;
|
||||
private IClientAPI RequestUser;
|
||||
private uint StartPacketNumber = 0;
|
||||
|
||||
public TextureSender(IClientAPI client, int discardLevel, uint packetNumber)
|
||||
{
|
||||
RequestUser = client;
|
||||
RequestedDiscardLevel = discardLevel;
|
||||
StartPacketNumber = packetNumber;
|
||||
}
|
||||
|
||||
#region ITextureSender Members
|
||||
|
||||
public bool Cancel
|
||||
{
|
||||
get { return false; }
|
||||
set { m_cancel = value; }
|
||||
}
|
||||
|
||||
public bool Sending
|
||||
{
|
||||
get { return false; }
|
||||
set { m_sending = value; }
|
||||
}
|
||||
|
||||
// See ITextureSender
|
||||
public void UpdateRequest(int discardLevel, uint packetNumber)
|
||||
{
|
||||
RequestedDiscardLevel = discardLevel;
|
||||
StartPacketNumber = packetNumber;
|
||||
PacketCounter = (int) StartPacketNumber;
|
||||
}
|
||||
|
||||
// See ITextureSender
|
||||
public bool SendTexturePacket()
|
||||
{
|
||||
//m_log.DebugFormat("[TEXTURE SENDER]: Sending packet for {0}", m_asset.FullID);
|
||||
|
||||
SendPacket();
|
||||
counter++;
|
||||
if ((NumPackets == 0) || (RequestedDiscardLevel == -1) || (PacketCounter > NumPackets) ||
|
||||
((RequestedDiscardLevel > 0) && (counter > 50 + (NumPackets / (RequestedDiscardLevel + 1)))))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Load up the texture data to send.
|
||||
/// </summary>
|
||||
/// <param name="asset">
|
||||
/// A <see cref="AssetBase"/>
|
||||
/// </param>
|
||||
public void TextureReceived(AssetBase asset)
|
||||
{
|
||||
m_asset = asset;
|
||||
NumPackets = CalculateNumPackets(asset.Data.Length);
|
||||
PacketCounter = (int) StartPacketNumber;
|
||||
ImageLoaded = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a texture packet to the client.
|
||||
/// </summary>
|
||||
private void SendPacket()
|
||||
{
|
||||
if (PacketCounter <= NumPackets)
|
||||
{
|
||||
if (PacketCounter == 0)
|
||||
{
|
||||
if (NumPackets == 0)
|
||||
{
|
||||
ImageDataPacket im = new ImageDataPacket();
|
||||
im.Header.Reliable = false;
|
||||
im.ImageID.Packets = 1;
|
||||
im.ImageID.ID = m_asset.FullID;
|
||||
im.ImageID.Size = (uint) m_asset.Data.Length;
|
||||
im.ImageData.Data = m_asset.Data;
|
||||
im.ImageID.Codec = 2;
|
||||
RequestUser.OutPacket(im, ThrottleOutPacketType.Texture);
|
||||
PacketCounter++;
|
||||
}
|
||||
else
|
||||
{
|
||||
ImageDataPacket im = new ImageDataPacket();
|
||||
im.Header.Reliable = false;
|
||||
im.ImageID.Packets = (ushort) (NumPackets);
|
||||
im.ImageID.ID = m_asset.FullID;
|
||||
im.ImageID.Size = (uint) m_asset.Data.Length;
|
||||
im.ImageData.Data = new byte[600];
|
||||
Array.Copy(m_asset.Data, 0, im.ImageData.Data, 0, 600);
|
||||
im.ImageID.Codec = 2;
|
||||
RequestUser.OutPacket(im, ThrottleOutPacketType.Texture);
|
||||
PacketCounter++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ImagePacketPacket im = new ImagePacketPacket();
|
||||
im.Header.Reliable = false;
|
||||
im.ImageID.Packet = (ushort) (PacketCounter);
|
||||
im.ImageID.ID = m_asset.FullID;
|
||||
int size = m_asset.Data.Length - 600 - (1000 * (PacketCounter - 1));
|
||||
if (size > 1000) size = 1000;
|
||||
im.ImageData.Data = new byte[size];
|
||||
try
|
||||
{
|
||||
Array.Copy(m_asset.Data, 600 + (1000 * (PacketCounter - 1)), im.ImageData.Data, 0, size);
|
||||
}
|
||||
catch (ArgumentOutOfRangeException)
|
||||
{
|
||||
m_log.Error("[TEXTURE SENDER]: Unable to separate texture into multiple packets: Array bounds failure on asset:" +
|
||||
m_asset.FullID.ToString());
|
||||
return;
|
||||
}
|
||||
RequestUser.OutPacket(im, ThrottleOutPacketType.Texture);
|
||||
PacketCounter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate the number of packets that will be required to send the texture loaded into this sender
|
||||
/// This is actually the number of 1000 byte packets not including an initial 600 byte packet...
|
||||
/// </summary>
|
||||
/// <param name="length"></param>
|
||||
/// <returns></returns>
|
||||
private int CalculateNumPackets(int length)
|
||||
{
|
||||
int numPackets = 0;
|
||||
|
||||
if (length > 600)
|
||||
{
|
||||
//over 600 bytes so split up file
|
||||
int restData = (length - 600);
|
||||
int restPackets = ((restData + 999) / 1000);
|
||||
numPackets = restPackets;
|
||||
}
|
||||
|
||||
return numPackets;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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.Reflection;
|
||||
using libsecondlife.Packets;
|
||||
using log4net;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Agent.TextureSender
|
||||
{
|
||||
/// <summary>
|
||||
/// A TextureSender handles the process of receiving a texture requested by the client from the
|
||||
/// AssetCache, and then sending that texture back to the client.
|
||||
/// </summary>
|
||||
public class TextureSender : ITextureSender
|
||||
{
|
||||
private static readonly ILog m_log
|
||||
= LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
/// <summary>
|
||||
/// Records the number of times texture send has been called.
|
||||
/// </summary>
|
||||
public int counter = 0;
|
||||
|
||||
public bool ImageLoaded = false;
|
||||
|
||||
/// <summary>
|
||||
/// Holds the texture asset to send.
|
||||
/// </summary>
|
||||
private AssetBase m_asset;
|
||||
|
||||
//public LLUUID assetID { get { return m_asset.FullID; } }
|
||||
|
||||
private bool m_cancel = false;
|
||||
|
||||
// See ITextureSender
|
||||
|
||||
private bool m_sending = false;
|
||||
|
||||
/// <summary>
|
||||
/// This is actually the number of extra packets required to send the texture data! We always assume
|
||||
/// at least one is required.
|
||||
/// </summary>
|
||||
private int NumPackets = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Holds the packet number to send next. In this case, each packet is 1000 bytes long and starts
|
||||
/// at the 600th byte (0th indexed).
|
||||
/// </summary>
|
||||
private int PacketCounter = 0;
|
||||
|
||||
private int RequestedDiscardLevel = -1;
|
||||
private IClientAPI RequestUser;
|
||||
private uint StartPacketNumber = 0;
|
||||
|
||||
public TextureSender(IClientAPI client, int discardLevel, uint packetNumber)
|
||||
{
|
||||
RequestUser = client;
|
||||
RequestedDiscardLevel = discardLevel;
|
||||
StartPacketNumber = packetNumber;
|
||||
}
|
||||
|
||||
#region ITextureSender Members
|
||||
|
||||
public bool Cancel
|
||||
{
|
||||
get { return false; }
|
||||
set { m_cancel = value; }
|
||||
}
|
||||
|
||||
public bool Sending
|
||||
{
|
||||
get { return false; }
|
||||
set { m_sending = value; }
|
||||
}
|
||||
|
||||
// See ITextureSender
|
||||
public void UpdateRequest(int discardLevel, uint packetNumber)
|
||||
{
|
||||
RequestedDiscardLevel = discardLevel;
|
||||
StartPacketNumber = packetNumber;
|
||||
PacketCounter = (int) StartPacketNumber;
|
||||
}
|
||||
|
||||
// See ITextureSender
|
||||
public bool SendTexturePacket()
|
||||
{
|
||||
//m_log.DebugFormat("[TEXTURE SENDER]: Sending packet for {0}", m_asset.FullID);
|
||||
|
||||
SendPacket();
|
||||
counter++;
|
||||
if ((NumPackets == 0) || (RequestedDiscardLevel == -1) || (PacketCounter > NumPackets) ||
|
||||
((RequestedDiscardLevel > 0) && (counter > 50 + (NumPackets / (RequestedDiscardLevel + 1)))))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Load up the texture data to send.
|
||||
/// </summary>
|
||||
/// <param name="asset">
|
||||
/// A <see cref="AssetBase"/>
|
||||
/// </param>
|
||||
public void TextureReceived(AssetBase asset)
|
||||
{
|
||||
m_asset = asset;
|
||||
NumPackets = CalculateNumPackets(asset.Data.Length);
|
||||
PacketCounter = (int) StartPacketNumber;
|
||||
ImageLoaded = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a texture packet to the client.
|
||||
/// </summary>
|
||||
private void SendPacket()
|
||||
{
|
||||
if (PacketCounter <= NumPackets)
|
||||
{
|
||||
if (PacketCounter == 0)
|
||||
{
|
||||
if (NumPackets == 0)
|
||||
{
|
||||
ImageDataPacket im = new ImageDataPacket();
|
||||
im.Header.Reliable = false;
|
||||
im.ImageID.Packets = 1;
|
||||
im.ImageID.ID = m_asset.FullID;
|
||||
im.ImageID.Size = (uint) m_asset.Data.Length;
|
||||
im.ImageData.Data = m_asset.Data;
|
||||
im.ImageID.Codec = 2;
|
||||
RequestUser.OutPacket(im, ThrottleOutPacketType.Texture);
|
||||
PacketCounter++;
|
||||
}
|
||||
else
|
||||
{
|
||||
ImageDataPacket im = new ImageDataPacket();
|
||||
im.Header.Reliable = false;
|
||||
im.ImageID.Packets = (ushort) (NumPackets);
|
||||
im.ImageID.ID = m_asset.FullID;
|
||||
im.ImageID.Size = (uint) m_asset.Data.Length;
|
||||
im.ImageData.Data = new byte[600];
|
||||
Array.Copy(m_asset.Data, 0, im.ImageData.Data, 0, 600);
|
||||
im.ImageID.Codec = 2;
|
||||
RequestUser.OutPacket(im, ThrottleOutPacketType.Texture);
|
||||
PacketCounter++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ImagePacketPacket im = new ImagePacketPacket();
|
||||
im.Header.Reliable = false;
|
||||
im.ImageID.Packet = (ushort) (PacketCounter);
|
||||
im.ImageID.ID = m_asset.FullID;
|
||||
int size = m_asset.Data.Length - 600 - (1000 * (PacketCounter - 1));
|
||||
if (size > 1000) size = 1000;
|
||||
im.ImageData.Data = new byte[size];
|
||||
try
|
||||
{
|
||||
Array.Copy(m_asset.Data, 600 + (1000 * (PacketCounter - 1)), im.ImageData.Data, 0, size);
|
||||
}
|
||||
catch (ArgumentOutOfRangeException)
|
||||
{
|
||||
m_log.Error("[TEXTURE SENDER]: Unable to separate texture into multiple packets: Array bounds failure on asset:" +
|
||||
m_asset.FullID.ToString());
|
||||
return;
|
||||
}
|
||||
RequestUser.OutPacket(im, ThrottleOutPacketType.Texture);
|
||||
PacketCounter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate the number of packets that will be required to send the texture loaded into this sender
|
||||
/// This is actually the number of 1000 byte packets not including an initial 600 byte packet...
|
||||
/// </summary>
|
||||
/// <param name="length"></param>
|
||||
/// <returns></returns>
|
||||
private int CalculateNumPackets(int length)
|
||||
{
|
||||
int numPackets = 0;
|
||||
|
||||
if (length > 600)
|
||||
{
|
||||
//over 600 bytes so split up file
|
||||
int restData = (length - 600);
|
||||
int restPackets = ((restData + 999) / 1000);
|
||||
numPackets = restPackets;
|
||||
}
|
||||
|
||||
return numPackets;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,235 +1,235 @@
|
|||
/*
|
||||
* 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 Nini.Config;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Agent.Xfer
|
||||
{
|
||||
public class XferModule : IRegionModule, IXfer
|
||||
{
|
||||
private Scene m_scene;
|
||||
public Dictionary<string, byte[]> NewFiles = new Dictionary<string, byte[]>();
|
||||
public Dictionary<ulong, XferDownLoad> Transfers = new Dictionary<ulong, XferDownLoad>();
|
||||
|
||||
public XferModule()
|
||||
{
|
||||
}
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource config)
|
||||
{
|
||||
m_scene = scene;
|
||||
m_scene.EventManager.OnNewClient += NewClient;
|
||||
|
||||
m_scene.RegisterModuleInterface<IXfer>(this);
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "XferModule"; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IXfer Members
|
||||
|
||||
public bool AddNewFile(string fileName, byte[] data)
|
||||
{
|
||||
lock (NewFiles)
|
||||
{
|
||||
if (NewFiles.ContainsKey(fileName))
|
||||
{
|
||||
NewFiles[fileName] = data;
|
||||
}
|
||||
else
|
||||
{
|
||||
NewFiles.Add(fileName, data);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void NewClient(IClientAPI client)
|
||||
{
|
||||
client.OnRequestXfer += RequestXfer;
|
||||
client.OnConfirmXfer += AckPacket;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="remoteClient"></param>
|
||||
/// <param name="xferID"></param>
|
||||
/// <param name="fileName"></param>
|
||||
public void RequestXfer(IClientAPI remoteClient, ulong xferID, string fileName)
|
||||
{
|
||||
lock (NewFiles)
|
||||
{
|
||||
if (NewFiles.ContainsKey(fileName))
|
||||
{
|
||||
if (!Transfers.ContainsKey(xferID))
|
||||
{
|
||||
byte[] fileData = NewFiles[fileName];
|
||||
XferDownLoad transaction = new XferDownLoad(fileName, fileData, xferID, remoteClient);
|
||||
Transfers.Add(xferID, transaction);
|
||||
NewFiles.Remove(fileName);
|
||||
|
||||
if (transaction.StartSend())
|
||||
{
|
||||
Transfers.Remove(xferID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void AckPacket(IClientAPI remoteClient, ulong xferID, uint packet)
|
||||
{
|
||||
if (Transfers.ContainsKey(xferID))
|
||||
{
|
||||
if (Transfers[xferID].AckPacket(packet))
|
||||
{
|
||||
{
|
||||
Transfers.Remove(xferID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region Nested type: XferDownLoad
|
||||
|
||||
public class XferDownLoad
|
||||
{
|
||||
public IClientAPI Client;
|
||||
private bool complete;
|
||||
public byte[] Data = new byte[0];
|
||||
public int DataPointer = 0;
|
||||
public string FileName = String.Empty;
|
||||
public uint Packet = 0;
|
||||
public uint Serial = 1;
|
||||
public ulong XferID = 0;
|
||||
|
||||
public XferDownLoad(string fileName, byte[] data, ulong xferID, IClientAPI client)
|
||||
{
|
||||
FileName = fileName;
|
||||
Data = data;
|
||||
XferID = xferID;
|
||||
Client = client;
|
||||
}
|
||||
|
||||
public XferDownLoad()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start a transfer
|
||||
/// </summary>
|
||||
/// <returns>True if the transfer is complete, false if not</returns>
|
||||
public bool StartSend()
|
||||
{
|
||||
if (Data.Length < 1000)
|
||||
{
|
||||
// for now (testing ) we only support files under 1000 bytes
|
||||
byte[] transferData = new byte[Data.Length + 4];
|
||||
Array.Copy(Helpers.IntToBytes(Data.Length), 0, transferData, 0, 4);
|
||||
Array.Copy(Data, 0, transferData, 4, Data.Length);
|
||||
Client.SendXferPacket(XferID, 0 + 0x80000000, transferData);
|
||||
|
||||
complete = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] transferData = new byte[1000 + 4];
|
||||
Array.Copy(Helpers.IntToBytes(Data.Length), 0, transferData, 0, 4);
|
||||
Array.Copy(Data, 0, transferData, 4, 1000);
|
||||
Client.SendXferPacket(XferID, 0, transferData);
|
||||
Packet++;
|
||||
DataPointer = 1000;
|
||||
}
|
||||
|
||||
return complete;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Respond to an ack packet from the client
|
||||
/// </summary>
|
||||
/// <param name="packet"></param>
|
||||
/// <returns>True if the transfer is complete, false otherwise</returns>
|
||||
public bool AckPacket(uint packet)
|
||||
{
|
||||
if (!complete)
|
||||
{
|
||||
if ((Data.Length - DataPointer) > 1000)
|
||||
{
|
||||
byte[] transferData = new byte[1000];
|
||||
Array.Copy(Data, DataPointer, transferData, 0, 1000);
|
||||
Client.SendXferPacket(XferID, Packet, transferData);
|
||||
Packet++;
|
||||
DataPointer += 1000;
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] transferData = new byte[Data.Length - DataPointer];
|
||||
Array.Copy(Data, DataPointer, transferData, 0, Data.Length - DataPointer);
|
||||
uint endPacket = Packet |= (uint) 0x80000000;
|
||||
Client.SendXferPacket(XferID, endPacket, transferData);
|
||||
Packet++;
|
||||
DataPointer += (Data.Length - DataPointer);
|
||||
|
||||
complete = true;
|
||||
}
|
||||
}
|
||||
|
||||
return complete;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
/*
|
||||
* 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 Nini.Config;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Agent.Xfer
|
||||
{
|
||||
public class XferModule : IRegionModule, IXfer
|
||||
{
|
||||
private Scene m_scene;
|
||||
public Dictionary<string, byte[]> NewFiles = new Dictionary<string, byte[]>();
|
||||
public Dictionary<ulong, XferDownLoad> Transfers = new Dictionary<ulong, XferDownLoad>();
|
||||
|
||||
public XferModule()
|
||||
{
|
||||
}
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource config)
|
||||
{
|
||||
m_scene = scene;
|
||||
m_scene.EventManager.OnNewClient += NewClient;
|
||||
|
||||
m_scene.RegisterModuleInterface<IXfer>(this);
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "XferModule"; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IXfer Members
|
||||
|
||||
public bool AddNewFile(string fileName, byte[] data)
|
||||
{
|
||||
lock (NewFiles)
|
||||
{
|
||||
if (NewFiles.ContainsKey(fileName))
|
||||
{
|
||||
NewFiles[fileName] = data;
|
||||
}
|
||||
else
|
||||
{
|
||||
NewFiles.Add(fileName, data);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void NewClient(IClientAPI client)
|
||||
{
|
||||
client.OnRequestXfer += RequestXfer;
|
||||
client.OnConfirmXfer += AckPacket;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="remoteClient"></param>
|
||||
/// <param name="xferID"></param>
|
||||
/// <param name="fileName"></param>
|
||||
public void RequestXfer(IClientAPI remoteClient, ulong xferID, string fileName)
|
||||
{
|
||||
lock (NewFiles)
|
||||
{
|
||||
if (NewFiles.ContainsKey(fileName))
|
||||
{
|
||||
if (!Transfers.ContainsKey(xferID))
|
||||
{
|
||||
byte[] fileData = NewFiles[fileName];
|
||||
XferDownLoad transaction = new XferDownLoad(fileName, fileData, xferID, remoteClient);
|
||||
Transfers.Add(xferID, transaction);
|
||||
NewFiles.Remove(fileName);
|
||||
|
||||
if (transaction.StartSend())
|
||||
{
|
||||
Transfers.Remove(xferID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void AckPacket(IClientAPI remoteClient, ulong xferID, uint packet)
|
||||
{
|
||||
if (Transfers.ContainsKey(xferID))
|
||||
{
|
||||
if (Transfers[xferID].AckPacket(packet))
|
||||
{
|
||||
{
|
||||
Transfers.Remove(xferID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region Nested type: XferDownLoad
|
||||
|
||||
public class XferDownLoad
|
||||
{
|
||||
public IClientAPI Client;
|
||||
private bool complete;
|
||||
public byte[] Data = new byte[0];
|
||||
public int DataPointer = 0;
|
||||
public string FileName = String.Empty;
|
||||
public uint Packet = 0;
|
||||
public uint Serial = 1;
|
||||
public ulong XferID = 0;
|
||||
|
||||
public XferDownLoad(string fileName, byte[] data, ulong xferID, IClientAPI client)
|
||||
{
|
||||
FileName = fileName;
|
||||
Data = data;
|
||||
XferID = xferID;
|
||||
Client = client;
|
||||
}
|
||||
|
||||
public XferDownLoad()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start a transfer
|
||||
/// </summary>
|
||||
/// <returns>True if the transfer is complete, false if not</returns>
|
||||
public bool StartSend()
|
||||
{
|
||||
if (Data.Length < 1000)
|
||||
{
|
||||
// for now (testing ) we only support files under 1000 bytes
|
||||
byte[] transferData = new byte[Data.Length + 4];
|
||||
Array.Copy(Helpers.IntToBytes(Data.Length), 0, transferData, 0, 4);
|
||||
Array.Copy(Data, 0, transferData, 4, Data.Length);
|
||||
Client.SendXferPacket(XferID, 0 + 0x80000000, transferData);
|
||||
|
||||
complete = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] transferData = new byte[1000 + 4];
|
||||
Array.Copy(Helpers.IntToBytes(Data.Length), 0, transferData, 0, 4);
|
||||
Array.Copy(Data, 0, transferData, 4, 1000);
|
||||
Client.SendXferPacket(XferID, 0, transferData);
|
||||
Packet++;
|
||||
DataPointer = 1000;
|
||||
}
|
||||
|
||||
return complete;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Respond to an ack packet from the client
|
||||
/// </summary>
|
||||
/// <param name="packet"></param>
|
||||
/// <returns>True if the transfer is complete, false otherwise</returns>
|
||||
public bool AckPacket(uint packet)
|
||||
{
|
||||
if (!complete)
|
||||
{
|
||||
if ((Data.Length - DataPointer) > 1000)
|
||||
{
|
||||
byte[] transferData = new byte[1000];
|
||||
Array.Copy(Data, DataPointer, transferData, 0, 1000);
|
||||
Client.SendXferPacket(XferID, Packet, transferData);
|
||||
Packet++;
|
||||
DataPointer += 1000;
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] transferData = new byte[Data.Length - DataPointer];
|
||||
Array.Copy(Data, DataPointer, transferData, 0, Data.Length - DataPointer);
|
||||
uint endPacket = Packet |= (uint) 0x80000000;
|
||||
Client.SendXferPacket(XferID, endPacket, transferData);
|
||||
Packet++;
|
||||
DataPointer += (Data.Length - DataPointer);
|
||||
|
||||
complete = true;
|
||||
}
|
||||
}
|
||||
|
||||
return complete;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -1,338 +1,338 @@
|
|||
/*
|
||||
* 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 Nini.Config;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Communications.Cache;
|
||||
using OpenSim.Data.MySQLMapper;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
using OpenSim.Data.Base;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules
|
||||
{
|
||||
public class AvatarFactoryModule : IAvatarFactory
|
||||
{
|
||||
private Scene m_scene = null;
|
||||
private readonly Dictionary<LLUUID, AvatarAppearance> m_avatarsAppearance = new Dictionary<LLUUID, AvatarAppearance>();
|
||||
|
||||
private bool m_enablePersist = false;
|
||||
private string m_connectionString;
|
||||
private bool m_configured = false;
|
||||
private BaseDatabaseConnector m_databaseMapper;
|
||||
private AppearanceTableMapper m_appearanceMapper;
|
||||
|
||||
private Dictionary<LLUUID, EventWaitHandle> m_fetchesInProgress = new Dictionary<LLUUID, EventWaitHandle>();
|
||||
private object m_syncLock = new object();
|
||||
|
||||
public bool TryGetAvatarAppearance(LLUUID avatarId, out AvatarAppearance appearance)
|
||||
{
|
||||
|
||||
//should only let one thread at a time do this part
|
||||
EventWaitHandle waitHandle = null;
|
||||
bool fetchInProgress = false;
|
||||
lock (m_syncLock)
|
||||
{
|
||||
appearance = CheckCache(avatarId);
|
||||
if (appearance != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//not in cache so check to see if another thread is already fetching it
|
||||
if (m_fetchesInProgress.TryGetValue(avatarId, out waitHandle))
|
||||
{
|
||||
fetchInProgress = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
fetchInProgress = false;
|
||||
|
||||
//no thread already fetching this appearance, so add a wait handle to list
|
||||
//for any following threads that want the same appearance
|
||||
waitHandle = new EventWaitHandle(false, EventResetMode.ManualReset);
|
||||
m_fetchesInProgress.Add(avatarId, waitHandle);
|
||||
}
|
||||
}
|
||||
|
||||
if (fetchInProgress)
|
||||
{
|
||||
waitHandle.WaitOne();
|
||||
appearance = CheckCache(avatarId);
|
||||
if (appearance != null)
|
||||
{
|
||||
waitHandle = null;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
waitHandle = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Thread.Sleep(5000);
|
||||
|
||||
//this is the first thread to request this appearance
|
||||
//so let it check the db and if not found then create a default appearance
|
||||
//and add that to the cache
|
||||
appearance = CheckDatabase(avatarId);
|
||||
if (appearance != null)
|
||||
{
|
||||
//appearance has now been added to cache so lets pulse any waiting threads
|
||||
lock (m_syncLock)
|
||||
{
|
||||
m_fetchesInProgress.Remove(avatarId);
|
||||
waitHandle.Set();
|
||||
}
|
||||
// waitHandle.Close();
|
||||
waitHandle = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
//not found a appearance for the user, so create a new default one
|
||||
appearance = CreateDefault(avatarId);
|
||||
if (appearance != null)
|
||||
{
|
||||
//update database
|
||||
if (m_enablePersist)
|
||||
{
|
||||
m_appearanceMapper.Add(avatarId.UUID, appearance);
|
||||
}
|
||||
|
||||
//add appearance to dictionary cache
|
||||
lock (m_avatarsAppearance)
|
||||
{
|
||||
m_avatarsAppearance[avatarId] = appearance;
|
||||
}
|
||||
|
||||
//appearance has now been added to cache so lets pulse any waiting threads
|
||||
lock (m_syncLock)
|
||||
{
|
||||
m_fetchesInProgress.Remove(avatarId);
|
||||
waitHandle.Set();
|
||||
}
|
||||
// waitHandle.Close();
|
||||
waitHandle = null;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
//something went wrong, so release the wait handle and remove it
|
||||
//all waiting threads will fail to find cached appearance
|
||||
//but its better for them to fail than wait for ever
|
||||
lock (m_syncLock)
|
||||
{
|
||||
m_fetchesInProgress.Remove(avatarId);
|
||||
waitHandle.Set();
|
||||
}
|
||||
//waitHandle.Close();
|
||||
waitHandle = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private AvatarAppearance CreateDefault(LLUUID avatarId)
|
||||
{
|
||||
AvatarAppearance appearance = null;
|
||||
AvatarWearable[] wearables;
|
||||
byte[] visualParams;
|
||||
GetDefaultAvatarAppearance(out wearables, out visualParams);
|
||||
appearance = new AvatarAppearance(avatarId, wearables, visualParams);
|
||||
|
||||
return appearance;
|
||||
}
|
||||
|
||||
private AvatarAppearance CheckDatabase(LLUUID avatarId)
|
||||
{
|
||||
AvatarAppearance appearance = null;
|
||||
if (m_enablePersist)
|
||||
{
|
||||
if (m_appearanceMapper.TryGetValue(avatarId.UUID, out appearance))
|
||||
{
|
||||
appearance.VisualParams = GetDefaultVisualParams();
|
||||
appearance.TextureEntry = AvatarAppearance.GetDefaultTextureEntry();
|
||||
lock (m_avatarsAppearance)
|
||||
{
|
||||
m_avatarsAppearance[avatarId] = appearance;
|
||||
}
|
||||
}
|
||||
}
|
||||
return appearance;
|
||||
}
|
||||
|
||||
private AvatarAppearance CheckCache(LLUUID avatarId)
|
||||
{
|
||||
AvatarAppearance appearance = null;
|
||||
lock (m_avatarsAppearance)
|
||||
{
|
||||
if (m_avatarsAppearance.ContainsKey(avatarId))
|
||||
{
|
||||
appearance = m_avatarsAppearance[avatarId];
|
||||
}
|
||||
}
|
||||
return appearance;
|
||||
}
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource source)
|
||||
{
|
||||
scene.RegisterModuleInterface<IAvatarFactory>(this);
|
||||
scene.EventManager.OnNewClient += NewClient;
|
||||
|
||||
if (m_scene == null)
|
||||
{
|
||||
m_scene = scene;
|
||||
}
|
||||
|
||||
if (!m_configured)
|
||||
{
|
||||
m_configured = true;
|
||||
try
|
||||
{
|
||||
m_enablePersist = source.Configs["Startup"].GetBoolean("appearance_persist", false);
|
||||
m_connectionString = source.Configs["Startup"].GetString("appearance_connection_string", "");
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
if (m_enablePersist)
|
||||
{
|
||||
m_databaseMapper = new MySQLDatabaseMapper(m_connectionString);
|
||||
m_appearanceMapper = new AppearanceTableMapper(m_databaseMapper, "AvatarAppearance");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "Default Avatar Factory"; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public void NewClient(IClientAPI client)
|
||||
{
|
||||
client.OnAvatarNowWearing += AvatarIsWearing;
|
||||
}
|
||||
|
||||
public void RemoveClient(IClientAPI client)
|
||||
{
|
||||
// client.OnAvatarNowWearing -= AvatarIsWearing;
|
||||
}
|
||||
|
||||
public void AvatarIsWearing(Object sender, AvatarWearingArgs e)
|
||||
{
|
||||
IClientAPI clientView = (IClientAPI)sender;
|
||||
CachedUserInfo profile = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(clientView.AgentId);
|
||||
if (profile != null)
|
||||
{
|
||||
if (profile.RootFolder != null)
|
||||
{
|
||||
if (m_avatarsAppearance.ContainsKey(clientView.AgentId))
|
||||
{
|
||||
AvatarAppearance avatAppearance = null;
|
||||
lock (m_avatarsAppearance)
|
||||
{
|
||||
avatAppearance = m_avatarsAppearance[clientView.AgentId];
|
||||
}
|
||||
|
||||
foreach (AvatarWearingArgs.Wearable wear in e.NowWearing)
|
||||
{
|
||||
if (wear.Type < 13)
|
||||
{
|
||||
if (wear.ItemID == LLUUID.Zero)
|
||||
{
|
||||
avatAppearance.Wearables[wear.Type].ItemID = LLUUID.Zero;
|
||||
avatAppearance.Wearables[wear.Type].AssetID = LLUUID.Zero;
|
||||
|
||||
UpdateDatabase(clientView.AgentId, avatAppearance);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLUUID assetId;
|
||||
|
||||
InventoryItemBase baseItem = profile.RootFolder.HasItem(wear.ItemID);
|
||||
if (baseItem != null)
|
||||
{
|
||||
assetId = baseItem.assetID;
|
||||
avatAppearance.Wearables[wear.Type].AssetID = assetId;
|
||||
avatAppearance.Wearables[wear.Type].ItemID = wear.ItemID;
|
||||
|
||||
UpdateDatabase(clientView.AgentId, avatAppearance);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateDatabase(LLUUID userID, AvatarAppearance avatAppearance)
|
||||
{
|
||||
if (m_enablePersist)
|
||||
{
|
||||
m_appearanceMapper.Update(userID.UUID, avatAppearance);
|
||||
}
|
||||
}
|
||||
|
||||
public static void GetDefaultAvatarAppearance(out AvatarWearable[] wearables, out byte[] visualParams)
|
||||
{
|
||||
visualParams = GetDefaultVisualParams();
|
||||
wearables = AvatarWearable.DefaultWearables;
|
||||
}
|
||||
|
||||
private static byte[] GetDefaultVisualParams()
|
||||
{
|
||||
byte[] visualParams;
|
||||
visualParams = new byte[218];
|
||||
for (int i = 0; i < 218; i++)
|
||||
{
|
||||
visualParams[i] = 100;
|
||||
}
|
||||
return visualParams;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
/*
|
||||
* 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 Nini.Config;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Communications.Cache;
|
||||
using OpenSim.Data.MySQLMapper;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
using OpenSim.Data.Base;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules
|
||||
{
|
||||
public class AvatarFactoryModule : IAvatarFactory
|
||||
{
|
||||
private Scene m_scene = null;
|
||||
private readonly Dictionary<LLUUID, AvatarAppearance> m_avatarsAppearance = new Dictionary<LLUUID, AvatarAppearance>();
|
||||
|
||||
private bool m_enablePersist = false;
|
||||
private string m_connectionString;
|
||||
private bool m_configured = false;
|
||||
private BaseDatabaseConnector m_databaseMapper;
|
||||
private AppearanceTableMapper m_appearanceMapper;
|
||||
|
||||
private Dictionary<LLUUID, EventWaitHandle> m_fetchesInProgress = new Dictionary<LLUUID, EventWaitHandle>();
|
||||
private object m_syncLock = new object();
|
||||
|
||||
public bool TryGetAvatarAppearance(LLUUID avatarId, out AvatarAppearance appearance)
|
||||
{
|
||||
|
||||
//should only let one thread at a time do this part
|
||||
EventWaitHandle waitHandle = null;
|
||||
bool fetchInProgress = false;
|
||||
lock (m_syncLock)
|
||||
{
|
||||
appearance = CheckCache(avatarId);
|
||||
if (appearance != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//not in cache so check to see if another thread is already fetching it
|
||||
if (m_fetchesInProgress.TryGetValue(avatarId, out waitHandle))
|
||||
{
|
||||
fetchInProgress = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
fetchInProgress = false;
|
||||
|
||||
//no thread already fetching this appearance, so add a wait handle to list
|
||||
//for any following threads that want the same appearance
|
||||
waitHandle = new EventWaitHandle(false, EventResetMode.ManualReset);
|
||||
m_fetchesInProgress.Add(avatarId, waitHandle);
|
||||
}
|
||||
}
|
||||
|
||||
if (fetchInProgress)
|
||||
{
|
||||
waitHandle.WaitOne();
|
||||
appearance = CheckCache(avatarId);
|
||||
if (appearance != null)
|
||||
{
|
||||
waitHandle = null;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
waitHandle = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Thread.Sleep(5000);
|
||||
|
||||
//this is the first thread to request this appearance
|
||||
//so let it check the db and if not found then create a default appearance
|
||||
//and add that to the cache
|
||||
appearance = CheckDatabase(avatarId);
|
||||
if (appearance != null)
|
||||
{
|
||||
//appearance has now been added to cache so lets pulse any waiting threads
|
||||
lock (m_syncLock)
|
||||
{
|
||||
m_fetchesInProgress.Remove(avatarId);
|
||||
waitHandle.Set();
|
||||
}
|
||||
// waitHandle.Close();
|
||||
waitHandle = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
//not found a appearance for the user, so create a new default one
|
||||
appearance = CreateDefault(avatarId);
|
||||
if (appearance != null)
|
||||
{
|
||||
//update database
|
||||
if (m_enablePersist)
|
||||
{
|
||||
m_appearanceMapper.Add(avatarId.UUID, appearance);
|
||||
}
|
||||
|
||||
//add appearance to dictionary cache
|
||||
lock (m_avatarsAppearance)
|
||||
{
|
||||
m_avatarsAppearance[avatarId] = appearance;
|
||||
}
|
||||
|
||||
//appearance has now been added to cache so lets pulse any waiting threads
|
||||
lock (m_syncLock)
|
||||
{
|
||||
m_fetchesInProgress.Remove(avatarId);
|
||||
waitHandle.Set();
|
||||
}
|
||||
// waitHandle.Close();
|
||||
waitHandle = null;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
//something went wrong, so release the wait handle and remove it
|
||||
//all waiting threads will fail to find cached appearance
|
||||
//but its better for them to fail than wait for ever
|
||||
lock (m_syncLock)
|
||||
{
|
||||
m_fetchesInProgress.Remove(avatarId);
|
||||
waitHandle.Set();
|
||||
}
|
||||
//waitHandle.Close();
|
||||
waitHandle = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private AvatarAppearance CreateDefault(LLUUID avatarId)
|
||||
{
|
||||
AvatarAppearance appearance = null;
|
||||
AvatarWearable[] wearables;
|
||||
byte[] visualParams;
|
||||
GetDefaultAvatarAppearance(out wearables, out visualParams);
|
||||
appearance = new AvatarAppearance(avatarId, wearables, visualParams);
|
||||
|
||||
return appearance;
|
||||
}
|
||||
|
||||
private AvatarAppearance CheckDatabase(LLUUID avatarId)
|
||||
{
|
||||
AvatarAppearance appearance = null;
|
||||
if (m_enablePersist)
|
||||
{
|
||||
if (m_appearanceMapper.TryGetValue(avatarId.UUID, out appearance))
|
||||
{
|
||||
appearance.VisualParams = GetDefaultVisualParams();
|
||||
appearance.TextureEntry = AvatarAppearance.GetDefaultTextureEntry();
|
||||
lock (m_avatarsAppearance)
|
||||
{
|
||||
m_avatarsAppearance[avatarId] = appearance;
|
||||
}
|
||||
}
|
||||
}
|
||||
return appearance;
|
||||
}
|
||||
|
||||
private AvatarAppearance CheckCache(LLUUID avatarId)
|
||||
{
|
||||
AvatarAppearance appearance = null;
|
||||
lock (m_avatarsAppearance)
|
||||
{
|
||||
if (m_avatarsAppearance.ContainsKey(avatarId))
|
||||
{
|
||||
appearance = m_avatarsAppearance[avatarId];
|
||||
}
|
||||
}
|
||||
return appearance;
|
||||
}
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource source)
|
||||
{
|
||||
scene.RegisterModuleInterface<IAvatarFactory>(this);
|
||||
scene.EventManager.OnNewClient += NewClient;
|
||||
|
||||
if (m_scene == null)
|
||||
{
|
||||
m_scene = scene;
|
||||
}
|
||||
|
||||
if (!m_configured)
|
||||
{
|
||||
m_configured = true;
|
||||
try
|
||||
{
|
||||
m_enablePersist = source.Configs["Startup"].GetBoolean("appearance_persist", false);
|
||||
m_connectionString = source.Configs["Startup"].GetString("appearance_connection_string", "");
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
if (m_enablePersist)
|
||||
{
|
||||
m_databaseMapper = new MySQLDatabaseMapper(m_connectionString);
|
||||
m_appearanceMapper = new AppearanceTableMapper(m_databaseMapper, "AvatarAppearance");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "Default Avatar Factory"; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public void NewClient(IClientAPI client)
|
||||
{
|
||||
client.OnAvatarNowWearing += AvatarIsWearing;
|
||||
}
|
||||
|
||||
public void RemoveClient(IClientAPI client)
|
||||
{
|
||||
// client.OnAvatarNowWearing -= AvatarIsWearing;
|
||||
}
|
||||
|
||||
public void AvatarIsWearing(Object sender, AvatarWearingArgs e)
|
||||
{
|
||||
IClientAPI clientView = (IClientAPI)sender;
|
||||
CachedUserInfo profile = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(clientView.AgentId);
|
||||
if (profile != null)
|
||||
{
|
||||
if (profile.RootFolder != null)
|
||||
{
|
||||
if (m_avatarsAppearance.ContainsKey(clientView.AgentId))
|
||||
{
|
||||
AvatarAppearance avatAppearance = null;
|
||||
lock (m_avatarsAppearance)
|
||||
{
|
||||
avatAppearance = m_avatarsAppearance[clientView.AgentId];
|
||||
}
|
||||
|
||||
foreach (AvatarWearingArgs.Wearable wear in e.NowWearing)
|
||||
{
|
||||
if (wear.Type < 13)
|
||||
{
|
||||
if (wear.ItemID == LLUUID.Zero)
|
||||
{
|
||||
avatAppearance.Wearables[wear.Type].ItemID = LLUUID.Zero;
|
||||
avatAppearance.Wearables[wear.Type].AssetID = LLUUID.Zero;
|
||||
|
||||
UpdateDatabase(clientView.AgentId, avatAppearance);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLUUID assetId;
|
||||
|
||||
InventoryItemBase baseItem = profile.RootFolder.HasItem(wear.ItemID);
|
||||
if (baseItem != null)
|
||||
{
|
||||
assetId = baseItem.assetID;
|
||||
avatAppearance.Wearables[wear.Type].AssetID = assetId;
|
||||
avatAppearance.Wearables[wear.Type].ItemID = wear.ItemID;
|
||||
|
||||
UpdateDatabase(clientView.AgentId, avatAppearance);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateDatabase(LLUUID userID, AvatarAppearance avatAppearance)
|
||||
{
|
||||
if (m_enablePersist)
|
||||
{
|
||||
m_appearanceMapper.Update(userID.UUID, avatAppearance);
|
||||
}
|
||||
}
|
||||
|
||||
public static void GetDefaultAvatarAppearance(out AvatarWearable[] wearables, out byte[] visualParams)
|
||||
{
|
||||
visualParams = GetDefaultVisualParams();
|
||||
wearables = AvatarWearable.DefaultWearables;
|
||||
}
|
||||
|
||||
private static byte[] GetDefaultVisualParams()
|
||||
{
|
||||
byte[] visualParams;
|
||||
visualParams = new byte[218];
|
||||
for (int i = 0; i < 218; i++)
|
||||
{
|
||||
visualParams[i] = 100;
|
||||
}
|
||||
return visualParams;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,273 +1,273 @@
|
|||
/*
|
||||
* 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 log4net;
|
||||
using Nini.Config;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Avatar.Groups
|
||||
{
|
||||
public class GroupsModule : IRegionModule
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private Dictionary<LLUUID, GroupList> m_grouplistmap = new Dictionary<LLUUID, GroupList>();
|
||||
private Dictionary<LLUUID, GroupData> m_groupmap = new Dictionary<LLUUID, GroupData>();
|
||||
private Dictionary<LLUUID, IClientAPI> m_iclientmap = new Dictionary<LLUUID, IClientAPI>();
|
||||
private List<Scene> m_scene = new List<Scene>();
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource config)
|
||||
{
|
||||
lock (m_scene)
|
||||
{
|
||||
m_scene.Add(scene);
|
||||
}
|
||||
scene.EventManager.OnNewClient += OnNewClient;
|
||||
scene.EventManager.OnClientClosed += OnClientClosed;
|
||||
scene.EventManager.OnGridInstantMessageToGroupsModule += OnGridInstantMessage;
|
||||
//scene.EventManager.
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
m_log.Info("[GROUP]: Shutting down group module.");
|
||||
lock (m_iclientmap)
|
||||
{
|
||||
m_iclientmap.Clear();
|
||||
}
|
||||
|
||||
lock (m_groupmap)
|
||||
{
|
||||
m_groupmap.Clear();
|
||||
}
|
||||
|
||||
lock (m_grouplistmap)
|
||||
{
|
||||
m_grouplistmap.Clear();
|
||||
}
|
||||
GC.Collect();
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "GroupsModule"; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void OnNewClient(IClientAPI client)
|
||||
{
|
||||
// All friends establishment protocol goes over instant message
|
||||
// There's no way to send a message from the sim
|
||||
// to a user to 'add a friend' without causing dialog box spam
|
||||
//
|
||||
// The base set of friends are added when the user signs on in their XMLRPC response
|
||||
// Generated by LoginService. The friends are retreived from the database by the UserManager
|
||||
|
||||
// Subscribe to instant messages
|
||||
client.OnInstantMessage += OnInstantMessage;
|
||||
client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest;
|
||||
lock (m_iclientmap)
|
||||
{
|
||||
if (!m_iclientmap.ContainsKey(client.AgentId))
|
||||
{
|
||||
m_iclientmap.Add(client.AgentId, client);
|
||||
}
|
||||
}
|
||||
GroupData OpenSimulatorGroup = new GroupData();
|
||||
OpenSimulatorGroup.ActiveGroupTitle = "OpenSimulator Tester";
|
||||
OpenSimulatorGroup.GroupID = new LLUUID("00000000-68f9-1111-024e-222222111120");
|
||||
OpenSimulatorGroup.GroupMembers.Add(client.AgentId);
|
||||
OpenSimulatorGroup.groupName = "OpenSimulator Testing";
|
||||
OpenSimulatorGroup.ActiveGroupPowers = GroupPowers.LandAllowSetHome;
|
||||
OpenSimulatorGroup.GroupTitles.Add("OpenSimulator Tester");
|
||||
lock (m_groupmap)
|
||||
{
|
||||
if (!m_groupmap.ContainsKey(client.AgentId))
|
||||
{
|
||||
m_groupmap.Add(client.AgentId, OpenSimulatorGroup);
|
||||
}
|
||||
}
|
||||
GroupList testGroupList = new GroupList();
|
||||
testGroupList.m_GroupList.Add(new LLUUID("00000000-68f9-1111-024e-222222111120"));
|
||||
|
||||
lock (m_grouplistmap)
|
||||
{
|
||||
if (!m_grouplistmap.ContainsKey(client.AgentId))
|
||||
{
|
||||
m_grouplistmap.Add(client.AgentId, testGroupList);
|
||||
}
|
||||
}
|
||||
m_log.Info("[GROUP]: Adding " + client.FirstName + " " + client.LastName + " to OpenSimulator Tester group");
|
||||
}
|
||||
|
||||
private void OnAgentDataUpdateRequest(IClientAPI remoteClient, LLUUID AgentID, LLUUID SessionID)
|
||||
{
|
||||
string firstname = remoteClient.FirstName;
|
||||
string lastname = remoteClient.LastName;
|
||||
|
||||
LLUUID ActiveGroupID = LLUUID.Zero;
|
||||
uint ActiveGroupPowers = 0;
|
||||
string ActiveGroupName = "";
|
||||
string ActiveGroupTitle = "";
|
||||
|
||||
bool foundUser = false;
|
||||
|
||||
lock (m_iclientmap)
|
||||
{
|
||||
if (m_iclientmap.ContainsKey(remoteClient.AgentId))
|
||||
{
|
||||
foundUser = true;
|
||||
}
|
||||
}
|
||||
if (foundUser)
|
||||
{
|
||||
lock (m_groupmap)
|
||||
{
|
||||
if (m_groupmap.ContainsKey(remoteClient.AgentId))
|
||||
{
|
||||
GroupData grp = m_groupmap[remoteClient.AgentId];
|
||||
if (grp != null)
|
||||
{
|
||||
ActiveGroupID = grp.GroupID;
|
||||
ActiveGroupName = grp.groupName;
|
||||
ActiveGroupPowers = grp.groupPowers;
|
||||
ActiveGroupTitle = grp.ActiveGroupTitle;
|
||||
}
|
||||
|
||||
//remoteClient.SendAgentDataUpdate(AgentID, ActiveGroupID, firstname, lastname, ActiveGroupPowers, ActiveGroupName, ActiveGroupTitle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnInstantMessage(IClientAPI client, LLUUID fromAgentID,
|
||||
LLUUID fromAgentSession, LLUUID toAgentID,
|
||||
LLUUID imSessionID, uint timestamp, string fromAgentName,
|
||||
string message, byte dialog, bool fromGroup, byte offline,
|
||||
uint ParentEstateID, LLVector3 Position, LLUUID RegionID,
|
||||
byte[] binaryBucket)
|
||||
{
|
||||
}
|
||||
|
||||
private void OnGridInstantMessage(GridInstantMessage msg)
|
||||
{
|
||||
// Trigger the above event handler
|
||||
OnInstantMessage(null, new LLUUID(msg.fromAgentID), new LLUUID(msg.fromAgentSession),
|
||||
new LLUUID(msg.toAgentID), new LLUUID(msg.imSessionID), msg.timestamp, msg.fromAgentName,
|
||||
msg.message, msg.dialog, msg.fromGroup, msg.offline, msg.ParentEstateID,
|
||||
new LLVector3(msg.Position.x, msg.Position.y, msg.Position.z), new LLUUID(msg.RegionID),
|
||||
msg.binaryBucket);
|
||||
}
|
||||
|
||||
private void OnClientClosed(LLUUID agentID)
|
||||
{
|
||||
lock (m_iclientmap)
|
||||
{
|
||||
if (m_iclientmap.ContainsKey(agentID))
|
||||
{
|
||||
IClientAPI cli = m_iclientmap[agentID];
|
||||
if (cli != null)
|
||||
{
|
||||
m_log.Info("[GROUP]: Removing all reference to groups for " + cli.FirstName + " " + cli.LastName);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Info("[GROUP]: Removing all reference to groups for " + agentID.ToString());
|
||||
}
|
||||
m_iclientmap.Remove(agentID);
|
||||
}
|
||||
}
|
||||
|
||||
lock (m_groupmap)
|
||||
{
|
||||
if (m_groupmap.ContainsKey(agentID))
|
||||
{
|
||||
m_groupmap.Remove(agentID);
|
||||
}
|
||||
}
|
||||
|
||||
lock (m_grouplistmap)
|
||||
{
|
||||
if (m_grouplistmap.ContainsKey(agentID))
|
||||
{
|
||||
m_grouplistmap.Remove(agentID);
|
||||
}
|
||||
}
|
||||
GC.Collect();
|
||||
}
|
||||
}
|
||||
|
||||
public class GroupData
|
||||
{
|
||||
public string ActiveGroupTitle;
|
||||
public LLUUID GroupID;
|
||||
public List<LLUUID> GroupMembers;
|
||||
public string groupName;
|
||||
public uint groupPowers = (uint) (GroupPowers.LandAllowLandmark | GroupPowers.LandAllowSetHome);
|
||||
public List<string> GroupTitles;
|
||||
|
||||
public GroupData()
|
||||
{
|
||||
GroupTitles = new List<string>();
|
||||
GroupMembers = new List<LLUUID>();
|
||||
}
|
||||
|
||||
public GroupPowers ActiveGroupPowers
|
||||
{
|
||||
set { groupPowers = (uint) value; }
|
||||
get { return (GroupPowers) groupPowers; }
|
||||
}
|
||||
}
|
||||
|
||||
public class GroupList
|
||||
{
|
||||
public List<LLUUID> m_GroupList;
|
||||
|
||||
public GroupList()
|
||||
{
|
||||
m_GroupList = new List<LLUUID>();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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 log4net;
|
||||
using Nini.Config;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Avatar.Groups
|
||||
{
|
||||
public class GroupsModule : IRegionModule
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private Dictionary<LLUUID, GroupList> m_grouplistmap = new Dictionary<LLUUID, GroupList>();
|
||||
private Dictionary<LLUUID, GroupData> m_groupmap = new Dictionary<LLUUID, GroupData>();
|
||||
private Dictionary<LLUUID, IClientAPI> m_iclientmap = new Dictionary<LLUUID, IClientAPI>();
|
||||
private List<Scene> m_scene = new List<Scene>();
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource config)
|
||||
{
|
||||
lock (m_scene)
|
||||
{
|
||||
m_scene.Add(scene);
|
||||
}
|
||||
scene.EventManager.OnNewClient += OnNewClient;
|
||||
scene.EventManager.OnClientClosed += OnClientClosed;
|
||||
scene.EventManager.OnGridInstantMessageToGroupsModule += OnGridInstantMessage;
|
||||
//scene.EventManager.
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
m_log.Info("[GROUP]: Shutting down group module.");
|
||||
lock (m_iclientmap)
|
||||
{
|
||||
m_iclientmap.Clear();
|
||||
}
|
||||
|
||||
lock (m_groupmap)
|
||||
{
|
||||
m_groupmap.Clear();
|
||||
}
|
||||
|
||||
lock (m_grouplistmap)
|
||||
{
|
||||
m_grouplistmap.Clear();
|
||||
}
|
||||
GC.Collect();
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "GroupsModule"; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void OnNewClient(IClientAPI client)
|
||||
{
|
||||
// All friends establishment protocol goes over instant message
|
||||
// There's no way to send a message from the sim
|
||||
// to a user to 'add a friend' without causing dialog box spam
|
||||
//
|
||||
// The base set of friends are added when the user signs on in their XMLRPC response
|
||||
// Generated by LoginService. The friends are retreived from the database by the UserManager
|
||||
|
||||
// Subscribe to instant messages
|
||||
client.OnInstantMessage += OnInstantMessage;
|
||||
client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest;
|
||||
lock (m_iclientmap)
|
||||
{
|
||||
if (!m_iclientmap.ContainsKey(client.AgentId))
|
||||
{
|
||||
m_iclientmap.Add(client.AgentId, client);
|
||||
}
|
||||
}
|
||||
GroupData OpenSimulatorGroup = new GroupData();
|
||||
OpenSimulatorGroup.ActiveGroupTitle = "OpenSimulator Tester";
|
||||
OpenSimulatorGroup.GroupID = new LLUUID("00000000-68f9-1111-024e-222222111120");
|
||||
OpenSimulatorGroup.GroupMembers.Add(client.AgentId);
|
||||
OpenSimulatorGroup.groupName = "OpenSimulator Testing";
|
||||
OpenSimulatorGroup.ActiveGroupPowers = GroupPowers.LandAllowSetHome;
|
||||
OpenSimulatorGroup.GroupTitles.Add("OpenSimulator Tester");
|
||||
lock (m_groupmap)
|
||||
{
|
||||
if (!m_groupmap.ContainsKey(client.AgentId))
|
||||
{
|
||||
m_groupmap.Add(client.AgentId, OpenSimulatorGroup);
|
||||
}
|
||||
}
|
||||
GroupList testGroupList = new GroupList();
|
||||
testGroupList.m_GroupList.Add(new LLUUID("00000000-68f9-1111-024e-222222111120"));
|
||||
|
||||
lock (m_grouplistmap)
|
||||
{
|
||||
if (!m_grouplistmap.ContainsKey(client.AgentId))
|
||||
{
|
||||
m_grouplistmap.Add(client.AgentId, testGroupList);
|
||||
}
|
||||
}
|
||||
m_log.Info("[GROUP]: Adding " + client.FirstName + " " + client.LastName + " to OpenSimulator Tester group");
|
||||
}
|
||||
|
||||
private void OnAgentDataUpdateRequest(IClientAPI remoteClient, LLUUID AgentID, LLUUID SessionID)
|
||||
{
|
||||
string firstname = remoteClient.FirstName;
|
||||
string lastname = remoteClient.LastName;
|
||||
|
||||
LLUUID ActiveGroupID = LLUUID.Zero;
|
||||
uint ActiveGroupPowers = 0;
|
||||
string ActiveGroupName = "";
|
||||
string ActiveGroupTitle = "";
|
||||
|
||||
bool foundUser = false;
|
||||
|
||||
lock (m_iclientmap)
|
||||
{
|
||||
if (m_iclientmap.ContainsKey(remoteClient.AgentId))
|
||||
{
|
||||
foundUser = true;
|
||||
}
|
||||
}
|
||||
if (foundUser)
|
||||
{
|
||||
lock (m_groupmap)
|
||||
{
|
||||
if (m_groupmap.ContainsKey(remoteClient.AgentId))
|
||||
{
|
||||
GroupData grp = m_groupmap[remoteClient.AgentId];
|
||||
if (grp != null)
|
||||
{
|
||||
ActiveGroupID = grp.GroupID;
|
||||
ActiveGroupName = grp.groupName;
|
||||
ActiveGroupPowers = grp.groupPowers;
|
||||
ActiveGroupTitle = grp.ActiveGroupTitle;
|
||||
}
|
||||
|
||||
//remoteClient.SendAgentDataUpdate(AgentID, ActiveGroupID, firstname, lastname, ActiveGroupPowers, ActiveGroupName, ActiveGroupTitle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnInstantMessage(IClientAPI client, LLUUID fromAgentID,
|
||||
LLUUID fromAgentSession, LLUUID toAgentID,
|
||||
LLUUID imSessionID, uint timestamp, string fromAgentName,
|
||||
string message, byte dialog, bool fromGroup, byte offline,
|
||||
uint ParentEstateID, LLVector3 Position, LLUUID RegionID,
|
||||
byte[] binaryBucket)
|
||||
{
|
||||
}
|
||||
|
||||
private void OnGridInstantMessage(GridInstantMessage msg)
|
||||
{
|
||||
// Trigger the above event handler
|
||||
OnInstantMessage(null, new LLUUID(msg.fromAgentID), new LLUUID(msg.fromAgentSession),
|
||||
new LLUUID(msg.toAgentID), new LLUUID(msg.imSessionID), msg.timestamp, msg.fromAgentName,
|
||||
msg.message, msg.dialog, msg.fromGroup, msg.offline, msg.ParentEstateID,
|
||||
new LLVector3(msg.Position.x, msg.Position.y, msg.Position.z), new LLUUID(msg.RegionID),
|
||||
msg.binaryBucket);
|
||||
}
|
||||
|
||||
private void OnClientClosed(LLUUID agentID)
|
||||
{
|
||||
lock (m_iclientmap)
|
||||
{
|
||||
if (m_iclientmap.ContainsKey(agentID))
|
||||
{
|
||||
IClientAPI cli = m_iclientmap[agentID];
|
||||
if (cli != null)
|
||||
{
|
||||
m_log.Info("[GROUP]: Removing all reference to groups for " + cli.FirstName + " " + cli.LastName);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Info("[GROUP]: Removing all reference to groups for " + agentID.ToString());
|
||||
}
|
||||
m_iclientmap.Remove(agentID);
|
||||
}
|
||||
}
|
||||
|
||||
lock (m_groupmap)
|
||||
{
|
||||
if (m_groupmap.ContainsKey(agentID))
|
||||
{
|
||||
m_groupmap.Remove(agentID);
|
||||
}
|
||||
}
|
||||
|
||||
lock (m_grouplistmap)
|
||||
{
|
||||
if (m_grouplistmap.ContainsKey(agentID))
|
||||
{
|
||||
m_grouplistmap.Remove(agentID);
|
||||
}
|
||||
}
|
||||
GC.Collect();
|
||||
}
|
||||
}
|
||||
|
||||
public class GroupData
|
||||
{
|
||||
public string ActiveGroupTitle;
|
||||
public LLUUID GroupID;
|
||||
public List<LLUUID> GroupMembers;
|
||||
public string groupName;
|
||||
public uint groupPowers = (uint) (GroupPowers.LandAllowLandmark | GroupPowers.LandAllowSetHome);
|
||||
public List<string> GroupTitles;
|
||||
|
||||
public GroupData()
|
||||
{
|
||||
GroupTitles = new List<string>();
|
||||
GroupMembers = new List<LLUUID>();
|
||||
}
|
||||
|
||||
public GroupPowers ActiveGroupPowers
|
||||
{
|
||||
set { groupPowers = (uint) value; }
|
||||
get { return (GroupPowers) groupPowers; }
|
||||
}
|
||||
}
|
||||
|
||||
public class GroupList
|
||||
{
|
||||
public List<LLUUID> m_GroupList;
|
||||
|
||||
public GroupList()
|
||||
{
|
||||
m_GroupList = new List<LLUUID>();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,158 +1,158 @@
|
|||
/*
|
||||
* 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 Nini.Config;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Avatar.InstantMessage
|
||||
{
|
||||
public class InstantMessageModule : IRegionModule
|
||||
{
|
||||
private readonly List<Scene> m_scenes = new List<Scene>();
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource config)
|
||||
{
|
||||
lock (m_scenes)
|
||||
{
|
||||
if (m_scenes.Count == 0)
|
||||
{
|
||||
//scene.AddXmlRPCHandler("avatar_location_update", processPresenceUpdate);
|
||||
}
|
||||
|
||||
if (!m_scenes.Contains(scene))
|
||||
{
|
||||
m_scenes.Add(scene);
|
||||
scene.EventManager.OnNewClient += OnNewClient;
|
||||
scene.EventManager.OnGridInstantMessageToIMModule += OnGridInstantMessage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "InstantMessageModule"; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void OnNewClient(IClientAPI client)
|
||||
{
|
||||
client.OnInstantMessage += OnInstantMessage;
|
||||
}
|
||||
|
||||
private void OnInstantMessage(IClientAPI client, LLUUID fromAgentID,
|
||||
LLUUID fromAgentSession, LLUUID toAgentID,
|
||||
LLUUID imSessionID, uint timestamp, string fromAgentName,
|
||||
string message, byte dialog, bool fromGroup, byte offline,
|
||||
uint ParentEstateID, LLVector3 Position, LLUUID RegionID,
|
||||
byte[] binaryBucket)
|
||||
{
|
||||
bool dialogHandledElsewhere
|
||||
= ((dialog == 38) || (dialog == 39) || (dialog == 40)
|
||||
|| dialog == (byte) InstantMessageDialog.InventoryOffered
|
||||
|| dialog == (byte) InstantMessageDialog.InventoryAccepted
|
||||
|| dialog == (byte) InstantMessageDialog.InventoryDeclined);
|
||||
|
||||
// IM dialogs need to be pre-processed and have their sessionID filled by the server
|
||||
// so the sim can match the transaction on the return packet.
|
||||
|
||||
// Don't send a Friend Dialog IM with a LLUUID.Zero session.
|
||||
if (!(dialogHandledElsewhere && imSessionID == LLUUID.Zero))
|
||||
{
|
||||
// Try root avatar only first
|
||||
foreach (Scene scene in m_scenes)
|
||||
{
|
||||
if (scene.Entities.ContainsKey(toAgentID) && scene.Entities[toAgentID] is ScenePresence)
|
||||
{
|
||||
// Local message
|
||||
ScenePresence user = (ScenePresence) scene.Entities[toAgentID];
|
||||
if (!user.IsChildAgent)
|
||||
{
|
||||
user.ControllingClient.SendInstantMessage(fromAgentID, fromAgentSession, message,
|
||||
toAgentID, imSessionID, fromAgentName, dialog,
|
||||
timestamp);
|
||||
// Message sent
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// try child avatar second
|
||||
foreach (Scene scene in m_scenes)
|
||||
{
|
||||
if (scene.Entities.ContainsKey(toAgentID) && scene.Entities[toAgentID] is ScenePresence)
|
||||
{
|
||||
// Local message
|
||||
ScenePresence user = (ScenePresence) scene.Entities[toAgentID];
|
||||
|
||||
user.ControllingClient.SendInstantMessage(fromAgentID, fromAgentSession, message,
|
||||
toAgentID, imSessionID, fromAgentName, dialog,
|
||||
timestamp);
|
||||
// Message sent
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Still here, try send via Grid
|
||||
// TODO
|
||||
}
|
||||
|
||||
// Trusty OSG1 called method. This method also gets called from the FriendsModule
|
||||
// Turns out the sim has to send an instant message to the user to get it to show an accepted friend.
|
||||
|
||||
private void OnGridInstantMessage(GridInstantMessage msg)
|
||||
{
|
||||
// Trigger the above event handler
|
||||
OnInstantMessage(null, new LLUUID(msg.fromAgentID), new LLUUID(msg.fromAgentSession),
|
||||
new LLUUID(msg.toAgentID), new LLUUID(msg.imSessionID), msg.timestamp, msg.fromAgentName,
|
||||
msg.message, msg.dialog, msg.fromGroup, msg.offline, msg.ParentEstateID,
|
||||
new LLVector3(msg.Position.x, msg.Position.y, msg.Position.z), new LLUUID(msg.RegionID),
|
||||
msg.binaryBucket);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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 Nini.Config;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Avatar.InstantMessage
|
||||
{
|
||||
public class InstantMessageModule : IRegionModule
|
||||
{
|
||||
private readonly List<Scene> m_scenes = new List<Scene>();
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource config)
|
||||
{
|
||||
lock (m_scenes)
|
||||
{
|
||||
if (m_scenes.Count == 0)
|
||||
{
|
||||
//scene.AddXmlRPCHandler("avatar_location_update", processPresenceUpdate);
|
||||
}
|
||||
|
||||
if (!m_scenes.Contains(scene))
|
||||
{
|
||||
m_scenes.Add(scene);
|
||||
scene.EventManager.OnNewClient += OnNewClient;
|
||||
scene.EventManager.OnGridInstantMessageToIMModule += OnGridInstantMessage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "InstantMessageModule"; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void OnNewClient(IClientAPI client)
|
||||
{
|
||||
client.OnInstantMessage += OnInstantMessage;
|
||||
}
|
||||
|
||||
private void OnInstantMessage(IClientAPI client, LLUUID fromAgentID,
|
||||
LLUUID fromAgentSession, LLUUID toAgentID,
|
||||
LLUUID imSessionID, uint timestamp, string fromAgentName,
|
||||
string message, byte dialog, bool fromGroup, byte offline,
|
||||
uint ParentEstateID, LLVector3 Position, LLUUID RegionID,
|
||||
byte[] binaryBucket)
|
||||
{
|
||||
bool dialogHandledElsewhere
|
||||
= ((dialog == 38) || (dialog == 39) || (dialog == 40)
|
||||
|| dialog == (byte) InstantMessageDialog.InventoryOffered
|
||||
|| dialog == (byte) InstantMessageDialog.InventoryAccepted
|
||||
|| dialog == (byte) InstantMessageDialog.InventoryDeclined);
|
||||
|
||||
// IM dialogs need to be pre-processed and have their sessionID filled by the server
|
||||
// so the sim can match the transaction on the return packet.
|
||||
|
||||
// Don't send a Friend Dialog IM with a LLUUID.Zero session.
|
||||
if (!(dialogHandledElsewhere && imSessionID == LLUUID.Zero))
|
||||
{
|
||||
// Try root avatar only first
|
||||
foreach (Scene scene in m_scenes)
|
||||
{
|
||||
if (scene.Entities.ContainsKey(toAgentID) && scene.Entities[toAgentID] is ScenePresence)
|
||||
{
|
||||
// Local message
|
||||
ScenePresence user = (ScenePresence) scene.Entities[toAgentID];
|
||||
if (!user.IsChildAgent)
|
||||
{
|
||||
user.ControllingClient.SendInstantMessage(fromAgentID, fromAgentSession, message,
|
||||
toAgentID, imSessionID, fromAgentName, dialog,
|
||||
timestamp);
|
||||
// Message sent
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// try child avatar second
|
||||
foreach (Scene scene in m_scenes)
|
||||
{
|
||||
if (scene.Entities.ContainsKey(toAgentID) && scene.Entities[toAgentID] is ScenePresence)
|
||||
{
|
||||
// Local message
|
||||
ScenePresence user = (ScenePresence) scene.Entities[toAgentID];
|
||||
|
||||
user.ControllingClient.SendInstantMessage(fromAgentID, fromAgentSession, message,
|
||||
toAgentID, imSessionID, fromAgentName, dialog,
|
||||
timestamp);
|
||||
// Message sent
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Still here, try send via Grid
|
||||
// TODO
|
||||
}
|
||||
|
||||
// Trusty OSG1 called method. This method also gets called from the FriendsModule
|
||||
// Turns out the sim has to send an instant message to the user to get it to show an accepted friend.
|
||||
|
||||
private void OnGridInstantMessage(GridInstantMessage msg)
|
||||
{
|
||||
// Trigger the above event handler
|
||||
OnInstantMessage(null, new LLUUID(msg.fromAgentID), new LLUUID(msg.fromAgentSession),
|
||||
new LLUUID(msg.toAgentID), new LLUUID(msg.imSessionID), msg.timestamp, msg.fromAgentName,
|
||||
msg.message, msg.dialog, msg.fromGroup, msg.offline, msg.ParentEstateID,
|
||||
new LLVector3(msg.Position.x, msg.Position.y, msg.Position.z), new LLUUID(msg.RegionID),
|
||||
msg.binaryBucket);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,220 +1,220 @@
|
|||
/*
|
||||
* 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.Reflection;
|
||||
using libsecondlife;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Avatar.Inventory
|
||||
{
|
||||
public class InventoryModule : IRegionModule
|
||||
{
|
||||
private static readonly ILog m_log
|
||||
= LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
/// <summary>
|
||||
/// We need to keep track of the pending item offers between clients since the itemId offered only
|
||||
/// occurs in the initial offer message, not the accept message. So this dictionary links
|
||||
/// IM Session Ids to ItemIds
|
||||
/// </summary>
|
||||
private IDictionary<LLUUID, LLUUID> m_pendingOffers = new Dictionary<LLUUID, LLUUID>();
|
||||
|
||||
private Scene m_scene;
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource config)
|
||||
{
|
||||
m_scene = scene;
|
||||
scene.EventManager.OnNewClient += OnNewClient;
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "InventoryModule"; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void OnNewClient(IClientAPI client)
|
||||
{
|
||||
// Inventory giving is conducted via instant message
|
||||
client.OnInstantMessage += OnInstantMessage;
|
||||
}
|
||||
|
||||
private void OnInstantMessage(IClientAPI client, LLUUID fromAgentID,
|
||||
LLUUID fromAgentSession, LLUUID toAgentID,
|
||||
LLUUID imSessionID, uint timestamp, string fromAgentName,
|
||||
string message, byte dialog, bool fromGroup, byte offline,
|
||||
uint ParentEstateID, LLVector3 Position, LLUUID RegionID,
|
||||
byte[] binaryBucket)
|
||||
{
|
||||
if (dialog == (byte) InstantMessageDialog.InventoryOffered)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[AGENT INVENTORY]: Routing inventory offering message from {0}, {1} to {2}",
|
||||
client.AgentId, client.Name, toAgentID);
|
||||
|
||||
if (m_scene.Entities.ContainsKey(toAgentID) && m_scene.Entities[toAgentID] is ScenePresence)
|
||||
{
|
||||
ScenePresence user = (ScenePresence) m_scene.Entities[toAgentID];
|
||||
|
||||
if (!user.IsChildAgent)
|
||||
{
|
||||
//byte[] rawId = new byte[16];
|
||||
|
||||
// First byte of the array is probably the item type
|
||||
// Next 16 bytes are the UUID
|
||||
//Array.Copy(binaryBucket, 1, rawId, 0, 16);
|
||||
|
||||
//LLUUID itemId = new LLUUID(new Guid(rawId));
|
||||
LLUUID itemId = new LLUUID(binaryBucket, 1);
|
||||
|
||||
m_log.DebugFormat(
|
||||
"[AGENT INVENTORY]: ItemId for giving is {0}", itemId);
|
||||
|
||||
m_pendingOffers[imSessionID] = itemId;
|
||||
|
||||
user.ControllingClient.SendInstantMessage(
|
||||
fromAgentID, fromAgentSession, message, toAgentID, imSessionID, fromAgentName,
|
||||
dialog, timestamp, binaryBucket);
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[AGENT INVENTORY]: Agent {0} targeted for inventory give by {1}, {2} of {3} was a child agent!",
|
||||
toAgentID, client.AgentId, client.Name, message);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[AGENT INVENTORY]: Could not find agent {0} for user {1}, {2} to give {3}",
|
||||
toAgentID, client.AgentId, client.Name, message);
|
||||
}
|
||||
}
|
||||
else if (dialog == (byte) InstantMessageDialog.InventoryAccepted)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[AGENT INVENTORY]: Routing inventory accepted message from {0}, {1} to {2}",
|
||||
client.AgentId, client.Name, toAgentID);
|
||||
|
||||
if (m_scene.Entities.ContainsKey(toAgentID) && m_scene.Entities[toAgentID] is ScenePresence)
|
||||
{
|
||||
ScenePresence user = (ScenePresence) m_scene.Entities[toAgentID];
|
||||
|
||||
if (!user.IsChildAgent)
|
||||
{
|
||||
user.ControllingClient.SendInstantMessage(
|
||||
fromAgentID, fromAgentSession, message, toAgentID, imSessionID, fromAgentName,
|
||||
dialog, timestamp, binaryBucket);
|
||||
|
||||
if (m_pendingOffers.ContainsKey(imSessionID))
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[AGENT INVENTORY]: Accepted item id {0}", m_pendingOffers[imSessionID]);
|
||||
|
||||
// Since the message originates from the accepting client, the toAgentID is
|
||||
// the agent giving the item.
|
||||
m_scene.GiveInventoryItem(client, toAgentID, m_pendingOffers[imSessionID]);
|
||||
|
||||
m_pendingOffers.Remove(imSessionID);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[AGENT INVENTORY]: Could not find an item associated with session id {0} to accept",
|
||||
imSessionID);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[AGENT INVENTORY]: Agent {0} targeted for inventory give by {1}, {2} of {3} was a child agent!",
|
||||
toAgentID, client.AgentId, client.Name, message);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[AGENT INVENTORY]: Could not find agent {0} for user {1}, {2} to give {3}",
|
||||
toAgentID, client.AgentId, client.Name, message);
|
||||
}
|
||||
}
|
||||
else if (dialog == (byte) InstantMessageDialog.InventoryDeclined)
|
||||
{
|
||||
if (m_scene.Entities.ContainsKey(toAgentID) && m_scene.Entities[toAgentID] is ScenePresence)
|
||||
{
|
||||
ScenePresence user = (ScenePresence) m_scene.Entities[toAgentID];
|
||||
|
||||
if (!user.IsChildAgent)
|
||||
{
|
||||
user.ControllingClient.SendInstantMessage(
|
||||
fromAgentID, fromAgentSession, message, toAgentID, imSessionID, fromAgentName,
|
||||
dialog, timestamp, binaryBucket);
|
||||
|
||||
if (m_pendingOffers.ContainsKey(imSessionID))
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[AGENT INVENTORY]: Declined item id {0}", m_pendingOffers[imSessionID]);
|
||||
|
||||
m_pendingOffers.Remove(imSessionID);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[AGENT INVENTORY]: Could not find an item associated with session id {0} to decline",
|
||||
imSessionID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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.Reflection;
|
||||
using libsecondlife;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Avatar.Inventory
|
||||
{
|
||||
public class InventoryModule : IRegionModule
|
||||
{
|
||||
private static readonly ILog m_log
|
||||
= LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
/// <summary>
|
||||
/// We need to keep track of the pending item offers between clients since the itemId offered only
|
||||
/// occurs in the initial offer message, not the accept message. So this dictionary links
|
||||
/// IM Session Ids to ItemIds
|
||||
/// </summary>
|
||||
private IDictionary<LLUUID, LLUUID> m_pendingOffers = new Dictionary<LLUUID, LLUUID>();
|
||||
|
||||
private Scene m_scene;
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource config)
|
||||
{
|
||||
m_scene = scene;
|
||||
scene.EventManager.OnNewClient += OnNewClient;
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "InventoryModule"; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void OnNewClient(IClientAPI client)
|
||||
{
|
||||
// Inventory giving is conducted via instant message
|
||||
client.OnInstantMessage += OnInstantMessage;
|
||||
}
|
||||
|
||||
private void OnInstantMessage(IClientAPI client, LLUUID fromAgentID,
|
||||
LLUUID fromAgentSession, LLUUID toAgentID,
|
||||
LLUUID imSessionID, uint timestamp, string fromAgentName,
|
||||
string message, byte dialog, bool fromGroup, byte offline,
|
||||
uint ParentEstateID, LLVector3 Position, LLUUID RegionID,
|
||||
byte[] binaryBucket)
|
||||
{
|
||||
if (dialog == (byte) InstantMessageDialog.InventoryOffered)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[AGENT INVENTORY]: Routing inventory offering message from {0}, {1} to {2}",
|
||||
client.AgentId, client.Name, toAgentID);
|
||||
|
||||
if (m_scene.Entities.ContainsKey(toAgentID) && m_scene.Entities[toAgentID] is ScenePresence)
|
||||
{
|
||||
ScenePresence user = (ScenePresence) m_scene.Entities[toAgentID];
|
||||
|
||||
if (!user.IsChildAgent)
|
||||
{
|
||||
//byte[] rawId = new byte[16];
|
||||
|
||||
// First byte of the array is probably the item type
|
||||
// Next 16 bytes are the UUID
|
||||
//Array.Copy(binaryBucket, 1, rawId, 0, 16);
|
||||
|
||||
//LLUUID itemId = new LLUUID(new Guid(rawId));
|
||||
LLUUID itemId = new LLUUID(binaryBucket, 1);
|
||||
|
||||
m_log.DebugFormat(
|
||||
"[AGENT INVENTORY]: ItemId for giving is {0}", itemId);
|
||||
|
||||
m_pendingOffers[imSessionID] = itemId;
|
||||
|
||||
user.ControllingClient.SendInstantMessage(
|
||||
fromAgentID, fromAgentSession, message, toAgentID, imSessionID, fromAgentName,
|
||||
dialog, timestamp, binaryBucket);
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[AGENT INVENTORY]: Agent {0} targeted for inventory give by {1}, {2} of {3} was a child agent!",
|
||||
toAgentID, client.AgentId, client.Name, message);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[AGENT INVENTORY]: Could not find agent {0} for user {1}, {2} to give {3}",
|
||||
toAgentID, client.AgentId, client.Name, message);
|
||||
}
|
||||
}
|
||||
else if (dialog == (byte) InstantMessageDialog.InventoryAccepted)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[AGENT INVENTORY]: Routing inventory accepted message from {0}, {1} to {2}",
|
||||
client.AgentId, client.Name, toAgentID);
|
||||
|
||||
if (m_scene.Entities.ContainsKey(toAgentID) && m_scene.Entities[toAgentID] is ScenePresence)
|
||||
{
|
||||
ScenePresence user = (ScenePresence) m_scene.Entities[toAgentID];
|
||||
|
||||
if (!user.IsChildAgent)
|
||||
{
|
||||
user.ControllingClient.SendInstantMessage(
|
||||
fromAgentID, fromAgentSession, message, toAgentID, imSessionID, fromAgentName,
|
||||
dialog, timestamp, binaryBucket);
|
||||
|
||||
if (m_pendingOffers.ContainsKey(imSessionID))
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[AGENT INVENTORY]: Accepted item id {0}", m_pendingOffers[imSessionID]);
|
||||
|
||||
// Since the message originates from the accepting client, the toAgentID is
|
||||
// the agent giving the item.
|
||||
m_scene.GiveInventoryItem(client, toAgentID, m_pendingOffers[imSessionID]);
|
||||
|
||||
m_pendingOffers.Remove(imSessionID);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[AGENT INVENTORY]: Could not find an item associated with session id {0} to accept",
|
||||
imSessionID);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[AGENT INVENTORY]: Agent {0} targeted for inventory give by {1}, {2} of {3} was a child agent!",
|
||||
toAgentID, client.AgentId, client.Name, message);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[AGENT INVENTORY]: Could not find agent {0} for user {1}, {2} to give {3}",
|
||||
toAgentID, client.AgentId, client.Name, message);
|
||||
}
|
||||
}
|
||||
else if (dialog == (byte) InstantMessageDialog.InventoryDeclined)
|
||||
{
|
||||
if (m_scene.Entities.ContainsKey(toAgentID) && m_scene.Entities[toAgentID] is ScenePresence)
|
||||
{
|
||||
ScenePresence user = (ScenePresence) m_scene.Entities[toAgentID];
|
||||
|
||||
if (!user.IsChildAgent)
|
||||
{
|
||||
user.ControllingClient.SendInstantMessage(
|
||||
fromAgentID, fromAgentSession, message, toAgentID, imSessionID, fromAgentName,
|
||||
dialog, timestamp, binaryBucket);
|
||||
|
||||
if (m_pendingOffers.ContainsKey(imSessionID))
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[AGENT INVENTORY]: Declined item id {0}", m_pendingOffers[imSessionID]);
|
||||
|
||||
m_pendingOffers.Remove(imSessionID);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[AGENT INVENTORY]: Could not find an item associated with session id {0} to decline",
|
||||
imSessionID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,133 +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 System;
|
||||
using System.Reflection;
|
||||
using libsecondlife;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Avatar.Profiles
|
||||
{
|
||||
public class AvatarProfilesModule : IRegionModule
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private Scene m_scene;
|
||||
|
||||
public AvatarProfilesModule()
|
||||
{
|
||||
}
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource config)
|
||||
{
|
||||
m_scene = scene;
|
||||
m_scene.EventManager.OnNewClient += NewClient;
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "AvatarProfilesModule"; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void NewClient(IClientAPI client)
|
||||
{
|
||||
client.OnRequestAvatarProperties += RequestAvatarProperty;
|
||||
client.OnUpdateAvatarProperties += UpdateAvatarProperties;
|
||||
}
|
||||
|
||||
public void RemoveClient(IClientAPI client)
|
||||
{
|
||||
client.OnRequestAvatarProperties -= RequestAvatarProperty;
|
||||
client.OnUpdateAvatarProperties -= UpdateAvatarProperties;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="remoteClient"></param>
|
||||
/// <param name="avatarID"></param>
|
||||
public void RequestAvatarProperty(IClientAPI remoteClient, LLUUID avatarID)
|
||||
{
|
||||
// FIXME: finish adding fields such as url, masking, etc.
|
||||
LLUUID partner = new LLUUID("11111111-1111-0000-0000-000100bba000");
|
||||
UserProfileData profile = m_scene.CommsManager.UserService.GetUserProfile(avatarID);
|
||||
if (null != profile)
|
||||
{
|
||||
remoteClient.SendAvatarProperties(profile.ID, profile.AboutText,
|
||||
Util.ToDateTime(profile.Created).ToString(),
|
||||
String.Empty, profile.FirstLifeAboutText, profile.CanDoMask,
|
||||
profile.FirstLifeImage, profile.Image, String.Empty, partner);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Debug("[AvatarProfilesModule]: Got null for profile for " + avatarID.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateAvatarProperties(IClientAPI remoteClient, UserProfileData newProfile)
|
||||
{
|
||||
UserProfileData Profile = m_scene.CommsManager.UserService.GetUserProfile(newProfile.ID);
|
||||
|
||||
// if it's the profile of the user requesting the update, then we change only a few things.
|
||||
if (remoteClient.AgentId.CompareTo(Profile.ID) == 0)
|
||||
{
|
||||
Profile.Image = newProfile.Image;
|
||||
Profile.FirstLifeImage = newProfile.FirstLifeImage;
|
||||
Profile.AboutText = newProfile.AboutText;
|
||||
Profile.FirstLifeAboutText = newProfile.FirstLifeAboutText;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (m_scene.CommsManager.UserService.UpdateUserProfileProperties(Profile))
|
||||
{
|
||||
RequestAvatarProperty(remoteClient, newProfile.ID);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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.Reflection;
|
||||
using libsecondlife;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Avatar.Profiles
|
||||
{
|
||||
public class AvatarProfilesModule : IRegionModule
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private Scene m_scene;
|
||||
|
||||
public AvatarProfilesModule()
|
||||
{
|
||||
}
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource config)
|
||||
{
|
||||
m_scene = scene;
|
||||
m_scene.EventManager.OnNewClient += NewClient;
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "AvatarProfilesModule"; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void NewClient(IClientAPI client)
|
||||
{
|
||||
client.OnRequestAvatarProperties += RequestAvatarProperty;
|
||||
client.OnUpdateAvatarProperties += UpdateAvatarProperties;
|
||||
}
|
||||
|
||||
public void RemoveClient(IClientAPI client)
|
||||
{
|
||||
client.OnRequestAvatarProperties -= RequestAvatarProperty;
|
||||
client.OnUpdateAvatarProperties -= UpdateAvatarProperties;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="remoteClient"></param>
|
||||
/// <param name="avatarID"></param>
|
||||
public void RequestAvatarProperty(IClientAPI remoteClient, LLUUID avatarID)
|
||||
{
|
||||
// FIXME: finish adding fields such as url, masking, etc.
|
||||
LLUUID partner = new LLUUID("11111111-1111-0000-0000-000100bba000");
|
||||
UserProfileData profile = m_scene.CommsManager.UserService.GetUserProfile(avatarID);
|
||||
if (null != profile)
|
||||
{
|
||||
remoteClient.SendAvatarProperties(profile.ID, profile.AboutText,
|
||||
Util.ToDateTime(profile.Created).ToString(),
|
||||
String.Empty, profile.FirstLifeAboutText, profile.CanDoMask,
|
||||
profile.FirstLifeImage, profile.Image, String.Empty, partner);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Debug("[AvatarProfilesModule]: Got null for profile for " + avatarID.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateAvatarProperties(IClientAPI remoteClient, UserProfileData newProfile)
|
||||
{
|
||||
UserProfileData Profile = m_scene.CommsManager.UserService.GetUserProfile(newProfile.ID);
|
||||
|
||||
// if it's the profile of the user requesting the update, then we change only a few things.
|
||||
if (remoteClient.AgentId.CompareTo(Profile.ID) == 0)
|
||||
{
|
||||
Profile.Image = newProfile.Image;
|
||||
Profile.FirstLifeImage = newProfile.FirstLifeImage;
|
||||
Profile.AboutText = newProfile.AboutText;
|
||||
Profile.FirstLifeAboutText = newProfile.FirstLifeAboutText;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (m_scene.CommsManager.UserService.UpdateUserProfileProperties(Profile))
|
||||
{
|
||||
RequestAvatarProperty(remoteClient, newProfile.ID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,290 +1,290 @@
|
|||
/*
|
||||
* 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.Reflection;
|
||||
using libsecondlife;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using Nwc.XmlRpc;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Communications.Cache;
|
||||
using OpenSim.Framework.Servers;
|
||||
using OpenSim.Region.Capabilities;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
using Caps=OpenSim.Region.Capabilities.Caps;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Avatar.Voice.AsterixVoice
|
||||
{
|
||||
public class AsteriskVoiceModule : IRegionModule
|
||||
{
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private static readonly string m_parcelVoiceInfoRequestPath = "0007/";
|
||||
private static readonly string m_provisionVoiceAccountRequestPath = "0008/";
|
||||
|
||||
private string m_asterisk;
|
||||
private string m_asterisk_password;
|
||||
private string m_asterisk_salt;
|
||||
private int m_asterisk_timeout;
|
||||
private string m_confDomain;
|
||||
private IConfig m_config;
|
||||
private Scene m_scene;
|
||||
private string m_sipDomain;
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource config)
|
||||
{
|
||||
m_scene = scene;
|
||||
m_config = config.Configs["AsteriskVoice"];
|
||||
|
||||
if (null == m_config)
|
||||
{
|
||||
m_log.Info("[ASTERISKVOICE] no config found, plugin disabled");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_config.GetBoolean("enabled", false))
|
||||
{
|
||||
m_log.Info("[ASTERISKVOICE] plugin disabled by configuration");
|
||||
return;
|
||||
}
|
||||
m_log.Info("[ASTERISKVOICE] plugin enabled");
|
||||
|
||||
try
|
||||
{
|
||||
m_sipDomain = m_config.GetString("sip_domain", String.Empty);
|
||||
m_log.InfoFormat("[ASTERISKVOICE] using SIP domain {0}", m_sipDomain);
|
||||
|
||||
m_confDomain = m_config.GetString("conf_domain", String.Empty);
|
||||
m_log.InfoFormat("[ASTERISKVOICE] using conf domain {0}", m_confDomain);
|
||||
|
||||
m_asterisk = m_config.GetString("asterisk_frontend", String.Empty);
|
||||
m_asterisk_password = m_config.GetString("asterisk_password", String.Empty);
|
||||
m_asterisk_timeout = m_config.GetInt("asterisk_timeout", 3000);
|
||||
m_asterisk_salt = m_config.GetString("asterisk_salt", "Wuffwuff");
|
||||
if (String.IsNullOrEmpty(m_asterisk)) throw new Exception("missing asterisk_frontend config parameter");
|
||||
if (String.IsNullOrEmpty(m_asterisk_password)) throw new Exception("missing asterisk_password config parameter");
|
||||
m_log.InfoFormat("[ASTERISKVOICE] using asterisk front end {0}", m_asterisk);
|
||||
|
||||
scene.EventManager.OnRegisterCaps += OnRegisterCaps;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[ASTERISKVOICE] plugin initialization failed: {0}", e.Message);
|
||||
m_log.DebugFormat("[ASTERISKVOICE] plugin initialization failed: {0}", e.ToString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "AsteriskVoiceModule"; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void OnRegisterCaps(LLUUID agentID, Caps caps)
|
||||
{
|
||||
m_log.DebugFormat("[ASTERISKVOICE] OnRegisterCaps: agentID {0} caps {1}", agentID, caps);
|
||||
string capsBase = "/CAPS/" + caps.CapsObjectPath;
|
||||
caps.RegisterHandler("ParcelVoiceInfoRequest",
|
||||
new RestStreamHandler("POST", capsBase + m_parcelVoiceInfoRequestPath,
|
||||
delegate(string request, string path, string param)
|
||||
{
|
||||
return ParcelVoiceInfoRequest(request, path, param,
|
||||
agentID, caps);
|
||||
}));
|
||||
caps.RegisterHandler("ProvisionVoiceAccountRequest",
|
||||
new RestStreamHandler("POST", capsBase + m_provisionVoiceAccountRequestPath,
|
||||
delegate(string request, string path, string param)
|
||||
{
|
||||
return ProvisionVoiceAccountRequest(request, path, param,
|
||||
agentID, caps);
|
||||
}));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Callback for a client request for ParcelVoiceInfo
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="param"></param>
|
||||
/// <param name="agentID"></param>
|
||||
/// <param name="caps"></param>
|
||||
/// <returns></returns>
|
||||
public string ParcelVoiceInfoRequest(string request, string path, string param,
|
||||
LLUUID agentID, Caps caps)
|
||||
{
|
||||
// we need to do:
|
||||
// - send channel_uri: as "sip:regionID@m_sipDomain"
|
||||
try
|
||||
{
|
||||
m_log.DebugFormat("[ASTERISKVOICE][PARCELVOICE]: request: {0}, path: {1}, param: {2}",
|
||||
request, path, param);
|
||||
|
||||
|
||||
// setup response to client
|
||||
Hashtable creds = new Hashtable();
|
||||
creds["channel_uri"] = String.Format("sip:{0}@{1}",
|
||||
m_scene.RegionInfo.RegionID, m_sipDomain);
|
||||
|
||||
string regionName = m_scene.RegionInfo.RegionName;
|
||||
ScenePresence avatar = m_scene.GetScenePresence(agentID);
|
||||
if (null == m_scene.LandChannel) throw new Exception("land data not yet available");
|
||||
LandData land = m_scene.GetLandData(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
|
||||
|
||||
LLSDParcelVoiceInfoResponse parcelVoiceInfo =
|
||||
new LLSDParcelVoiceInfoResponse(regionName, land.localID, creds);
|
||||
|
||||
string r = LLSDHelpers.SerialiseLLSDReply(parcelVoiceInfo);
|
||||
|
||||
|
||||
// update region on asterisk-opensim frontend
|
||||
Hashtable requestData = new Hashtable();
|
||||
requestData["admin_password"] = m_asterisk_password;
|
||||
requestData["region"] = m_scene.RegionInfo.RegionID.ToString();
|
||||
if (!String.IsNullOrEmpty(m_confDomain))
|
||||
{
|
||||
requestData["region"] += String.Format("@{0}", m_confDomain);
|
||||
}
|
||||
|
||||
ArrayList SendParams = new ArrayList();
|
||||
SendParams.Add(requestData);
|
||||
XmlRpcRequest updateAccountRequest = new XmlRpcRequest("region_update", SendParams);
|
||||
XmlRpcResponse updateAccountResponse = updateAccountRequest.Send(m_asterisk, m_asterisk_timeout);
|
||||
Hashtable responseData = (Hashtable) updateAccountResponse.Value;
|
||||
|
||||
if (!responseData.ContainsKey("success")) throw new Exception("region_update call failed");
|
||||
|
||||
bool success = Convert.ToBoolean((string) responseData["success"]);
|
||||
if (!success) throw new Exception("region_update failed");
|
||||
|
||||
|
||||
m_log.DebugFormat("[ASTERISKVOICE][PARCELVOICE]: {0}", r);
|
||||
return r;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[ASTERISKVOICE][CAPS][PARCELVOICE]: {0}, retry later", e.Message);
|
||||
m_log.DebugFormat("[ASTERISKVOICE][CAPS][PARCELVOICE]: {0} failed", e.ToString());
|
||||
|
||||
return "<llsd>undef</llsd>";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Callback for a client request for Voice Account Details
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="param"></param>
|
||||
/// <param name="agentID"></param>
|
||||
/// <param name="caps"></param>
|
||||
/// <returns></returns>
|
||||
public string ProvisionVoiceAccountRequest(string request, string path, string param,
|
||||
LLUUID agentID, Caps caps)
|
||||
{
|
||||
// we need to
|
||||
// - get user data from UserProfileCacheService
|
||||
// - generate nonce for user voice account password
|
||||
// - issue XmlRpc request to asterisk opensim front end:
|
||||
// + user: base 64 encoded user name (otherwise SL
|
||||
// client is unhappy)
|
||||
// + password: nonce
|
||||
// - the XmlRpc call to asteris-opensim was successful:
|
||||
// send account details back to client
|
||||
try
|
||||
{
|
||||
m_log.DebugFormat("[ASTERISKVOICE][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}",
|
||||
request, path, param);
|
||||
|
||||
// get user data & prepare voice account response
|
||||
string voiceUser = "x" + Convert.ToBase64String(agentID.GetBytes());
|
||||
voiceUser = voiceUser.Replace('+', '-').Replace('/', '_');
|
||||
|
||||
CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(agentID);
|
||||
if (null == userInfo) throw new Exception("cannot get user details");
|
||||
|
||||
// we generate a nonce everytime
|
||||
string voicePassword = "$1$" + Util.Md5Hash(DateTime.UtcNow.ToLongTimeString() + m_asterisk_salt);
|
||||
LLSDVoiceAccountResponse voiceAccountResponse =
|
||||
new LLSDVoiceAccountResponse(voiceUser, voicePassword);
|
||||
string r = LLSDHelpers.SerialiseLLSDReply(voiceAccountResponse);
|
||||
m_log.DebugFormat("[CAPS][PROVISIONVOICE]: {0}", r);
|
||||
|
||||
|
||||
// update user account on asterisk frontend
|
||||
Hashtable requestData = new Hashtable();
|
||||
requestData["admin_password"] = m_asterisk_password;
|
||||
requestData["username"] = voiceUser;
|
||||
if (!String.IsNullOrEmpty(m_sipDomain))
|
||||
{
|
||||
requestData["username"] += String.Format("@{0}", m_sipDomain);
|
||||
}
|
||||
requestData["password"] = voicePassword;
|
||||
|
||||
ArrayList SendParams = new ArrayList();
|
||||
SendParams.Add(requestData);
|
||||
XmlRpcRequest updateAccountRequest = new XmlRpcRequest("account_update", SendParams);
|
||||
XmlRpcResponse updateAccountResponse = updateAccountRequest.Send(m_asterisk, m_asterisk_timeout);
|
||||
Hashtable responseData = (Hashtable) updateAccountResponse.Value;
|
||||
|
||||
if (!responseData.ContainsKey("success")) throw new Exception("account_update call failed");
|
||||
|
||||
bool success = Convert.ToBoolean((string) responseData["success"]);
|
||||
if (!success) throw new Exception("account_update failed");
|
||||
|
||||
return r;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[ASTERISKVOICE][CAPS][PROVISIONVOICE]: {0}, retry later", e.Message);
|
||||
m_log.DebugFormat("[ASTERISKVOICE][CAPS][PROVISIONVOICE]: {0} failed", e.ToString());
|
||||
|
||||
return "<llsd>undef</llsd>";
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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.Reflection;
|
||||
using libsecondlife;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using Nwc.XmlRpc;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Communications.Cache;
|
||||
using OpenSim.Framework.Servers;
|
||||
using OpenSim.Region.Capabilities;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
using Caps=OpenSim.Region.Capabilities.Caps;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Avatar.Voice.AsterixVoice
|
||||
{
|
||||
public class AsteriskVoiceModule : IRegionModule
|
||||
{
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private static readonly string m_parcelVoiceInfoRequestPath = "0007/";
|
||||
private static readonly string m_provisionVoiceAccountRequestPath = "0008/";
|
||||
|
||||
private string m_asterisk;
|
||||
private string m_asterisk_password;
|
||||
private string m_asterisk_salt;
|
||||
private int m_asterisk_timeout;
|
||||
private string m_confDomain;
|
||||
private IConfig m_config;
|
||||
private Scene m_scene;
|
||||
private string m_sipDomain;
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource config)
|
||||
{
|
||||
m_scene = scene;
|
||||
m_config = config.Configs["AsteriskVoice"];
|
||||
|
||||
if (null == m_config)
|
||||
{
|
||||
m_log.Info("[ASTERISKVOICE] no config found, plugin disabled");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_config.GetBoolean("enabled", false))
|
||||
{
|
||||
m_log.Info("[ASTERISKVOICE] plugin disabled by configuration");
|
||||
return;
|
||||
}
|
||||
m_log.Info("[ASTERISKVOICE] plugin enabled");
|
||||
|
||||
try
|
||||
{
|
||||
m_sipDomain = m_config.GetString("sip_domain", String.Empty);
|
||||
m_log.InfoFormat("[ASTERISKVOICE] using SIP domain {0}", m_sipDomain);
|
||||
|
||||
m_confDomain = m_config.GetString("conf_domain", String.Empty);
|
||||
m_log.InfoFormat("[ASTERISKVOICE] using conf domain {0}", m_confDomain);
|
||||
|
||||
m_asterisk = m_config.GetString("asterisk_frontend", String.Empty);
|
||||
m_asterisk_password = m_config.GetString("asterisk_password", String.Empty);
|
||||
m_asterisk_timeout = m_config.GetInt("asterisk_timeout", 3000);
|
||||
m_asterisk_salt = m_config.GetString("asterisk_salt", "Wuffwuff");
|
||||
if (String.IsNullOrEmpty(m_asterisk)) throw new Exception("missing asterisk_frontend config parameter");
|
||||
if (String.IsNullOrEmpty(m_asterisk_password)) throw new Exception("missing asterisk_password config parameter");
|
||||
m_log.InfoFormat("[ASTERISKVOICE] using asterisk front end {0}", m_asterisk);
|
||||
|
||||
scene.EventManager.OnRegisterCaps += OnRegisterCaps;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[ASTERISKVOICE] plugin initialization failed: {0}", e.Message);
|
||||
m_log.DebugFormat("[ASTERISKVOICE] plugin initialization failed: {0}", e.ToString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "AsteriskVoiceModule"; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void OnRegisterCaps(LLUUID agentID, Caps caps)
|
||||
{
|
||||
m_log.DebugFormat("[ASTERISKVOICE] OnRegisterCaps: agentID {0} caps {1}", agentID, caps);
|
||||
string capsBase = "/CAPS/" + caps.CapsObjectPath;
|
||||
caps.RegisterHandler("ParcelVoiceInfoRequest",
|
||||
new RestStreamHandler("POST", capsBase + m_parcelVoiceInfoRequestPath,
|
||||
delegate(string request, string path, string param)
|
||||
{
|
||||
return ParcelVoiceInfoRequest(request, path, param,
|
||||
agentID, caps);
|
||||
}));
|
||||
caps.RegisterHandler("ProvisionVoiceAccountRequest",
|
||||
new RestStreamHandler("POST", capsBase + m_provisionVoiceAccountRequestPath,
|
||||
delegate(string request, string path, string param)
|
||||
{
|
||||
return ProvisionVoiceAccountRequest(request, path, param,
|
||||
agentID, caps);
|
||||
}));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Callback for a client request for ParcelVoiceInfo
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="param"></param>
|
||||
/// <param name="agentID"></param>
|
||||
/// <param name="caps"></param>
|
||||
/// <returns></returns>
|
||||
public string ParcelVoiceInfoRequest(string request, string path, string param,
|
||||
LLUUID agentID, Caps caps)
|
||||
{
|
||||
// we need to do:
|
||||
// - send channel_uri: as "sip:regionID@m_sipDomain"
|
||||
try
|
||||
{
|
||||
m_log.DebugFormat("[ASTERISKVOICE][PARCELVOICE]: request: {0}, path: {1}, param: {2}",
|
||||
request, path, param);
|
||||
|
||||
|
||||
// setup response to client
|
||||
Hashtable creds = new Hashtable();
|
||||
creds["channel_uri"] = String.Format("sip:{0}@{1}",
|
||||
m_scene.RegionInfo.RegionID, m_sipDomain);
|
||||
|
||||
string regionName = m_scene.RegionInfo.RegionName;
|
||||
ScenePresence avatar = m_scene.GetScenePresence(agentID);
|
||||
if (null == m_scene.LandChannel) throw new Exception("land data not yet available");
|
||||
LandData land = m_scene.GetLandData(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
|
||||
|
||||
LLSDParcelVoiceInfoResponse parcelVoiceInfo =
|
||||
new LLSDParcelVoiceInfoResponse(regionName, land.localID, creds);
|
||||
|
||||
string r = LLSDHelpers.SerialiseLLSDReply(parcelVoiceInfo);
|
||||
|
||||
|
||||
// update region on asterisk-opensim frontend
|
||||
Hashtable requestData = new Hashtable();
|
||||
requestData["admin_password"] = m_asterisk_password;
|
||||
requestData["region"] = m_scene.RegionInfo.RegionID.ToString();
|
||||
if (!String.IsNullOrEmpty(m_confDomain))
|
||||
{
|
||||
requestData["region"] += String.Format("@{0}", m_confDomain);
|
||||
}
|
||||
|
||||
ArrayList SendParams = new ArrayList();
|
||||
SendParams.Add(requestData);
|
||||
XmlRpcRequest updateAccountRequest = new XmlRpcRequest("region_update", SendParams);
|
||||
XmlRpcResponse updateAccountResponse = updateAccountRequest.Send(m_asterisk, m_asterisk_timeout);
|
||||
Hashtable responseData = (Hashtable) updateAccountResponse.Value;
|
||||
|
||||
if (!responseData.ContainsKey("success")) throw new Exception("region_update call failed");
|
||||
|
||||
bool success = Convert.ToBoolean((string) responseData["success"]);
|
||||
if (!success) throw new Exception("region_update failed");
|
||||
|
||||
|
||||
m_log.DebugFormat("[ASTERISKVOICE][PARCELVOICE]: {0}", r);
|
||||
return r;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[ASTERISKVOICE][CAPS][PARCELVOICE]: {0}, retry later", e.Message);
|
||||
m_log.DebugFormat("[ASTERISKVOICE][CAPS][PARCELVOICE]: {0} failed", e.ToString());
|
||||
|
||||
return "<llsd>undef</llsd>";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Callback for a client request for Voice Account Details
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="param"></param>
|
||||
/// <param name="agentID"></param>
|
||||
/// <param name="caps"></param>
|
||||
/// <returns></returns>
|
||||
public string ProvisionVoiceAccountRequest(string request, string path, string param,
|
||||
LLUUID agentID, Caps caps)
|
||||
{
|
||||
// we need to
|
||||
// - get user data from UserProfileCacheService
|
||||
// - generate nonce for user voice account password
|
||||
// - issue XmlRpc request to asterisk opensim front end:
|
||||
// + user: base 64 encoded user name (otherwise SL
|
||||
// client is unhappy)
|
||||
// + password: nonce
|
||||
// - the XmlRpc call to asteris-opensim was successful:
|
||||
// send account details back to client
|
||||
try
|
||||
{
|
||||
m_log.DebugFormat("[ASTERISKVOICE][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}",
|
||||
request, path, param);
|
||||
|
||||
// get user data & prepare voice account response
|
||||
string voiceUser = "x" + Convert.ToBase64String(agentID.GetBytes());
|
||||
voiceUser = voiceUser.Replace('+', '-').Replace('/', '_');
|
||||
|
||||
CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(agentID);
|
||||
if (null == userInfo) throw new Exception("cannot get user details");
|
||||
|
||||
// we generate a nonce everytime
|
||||
string voicePassword = "$1$" + Util.Md5Hash(DateTime.UtcNow.ToLongTimeString() + m_asterisk_salt);
|
||||
LLSDVoiceAccountResponse voiceAccountResponse =
|
||||
new LLSDVoiceAccountResponse(voiceUser, voicePassword);
|
||||
string r = LLSDHelpers.SerialiseLLSDReply(voiceAccountResponse);
|
||||
m_log.DebugFormat("[CAPS][PROVISIONVOICE]: {0}", r);
|
||||
|
||||
|
||||
// update user account on asterisk frontend
|
||||
Hashtable requestData = new Hashtable();
|
||||
requestData["admin_password"] = m_asterisk_password;
|
||||
requestData["username"] = voiceUser;
|
||||
if (!String.IsNullOrEmpty(m_sipDomain))
|
||||
{
|
||||
requestData["username"] += String.Format("@{0}", m_sipDomain);
|
||||
}
|
||||
requestData["password"] = voicePassword;
|
||||
|
||||
ArrayList SendParams = new ArrayList();
|
||||
SendParams.Add(requestData);
|
||||
XmlRpcRequest updateAccountRequest = new XmlRpcRequest("account_update", SendParams);
|
||||
XmlRpcResponse updateAccountResponse = updateAccountRequest.Send(m_asterisk, m_asterisk_timeout);
|
||||
Hashtable responseData = (Hashtable) updateAccountResponse.Value;
|
||||
|
||||
if (!responseData.ContainsKey("success")) throw new Exception("account_update call failed");
|
||||
|
||||
bool success = Convert.ToBoolean((string) responseData["success"]);
|
||||
if (!success) throw new Exception("account_update failed");
|
||||
|
||||
return r;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[ASTERISKVOICE][CAPS][PROVISIONVOICE]: {0}, retry later", e.Message);
|
||||
m_log.DebugFormat("[ASTERISKVOICE][CAPS][PROVISIONVOICE]: {0} failed", e.ToString());
|
||||
|
||||
return "<llsd>undef</llsd>";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,200 +1,200 @@
|
|||
/*
|
||||
* 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.Reflection;
|
||||
using libsecondlife;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Communications.Cache;
|
||||
using OpenSim.Framework.Servers;
|
||||
using OpenSim.Region.Capabilities;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
using Caps=OpenSim.Region.Capabilities.Caps;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Avatar.Voice.SIPVoice
|
||||
{
|
||||
public class SIPVoiceModule : IRegionModule
|
||||
{
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private static readonly string m_parcelVoiceInfoRequestPath = "0007/";
|
||||
private static readonly string m_provisionVoiceAccountRequestPath = "0008/";
|
||||
private IConfig m_config;
|
||||
private Scene m_scene;
|
||||
private string m_sipDomain;
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource config)
|
||||
{
|
||||
m_scene = scene;
|
||||
m_config = config.Configs["Voice"];
|
||||
|
||||
if (null == m_config || !m_config.GetBoolean("enabled", false))
|
||||
{
|
||||
m_log.Info("[VOICE] plugin disabled");
|
||||
return;
|
||||
}
|
||||
m_log.Info("[VOICE] plugin enabled");
|
||||
|
||||
m_sipDomain = m_config.GetString("sip_domain", String.Empty);
|
||||
if (String.IsNullOrEmpty(m_sipDomain))
|
||||
{
|
||||
m_log.Error("[VOICE] plugin mis-configured: missing sip_domain configuration");
|
||||
m_log.Info("[VOICE] plugin disabled");
|
||||
return;
|
||||
}
|
||||
m_log.InfoFormat("[VOICE] using SIP domain {0}", m_sipDomain);
|
||||
|
||||
scene.EventManager.OnRegisterCaps += OnRegisterCaps;
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "VoiceModule"; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void OnRegisterCaps(LLUUID agentID, Caps caps)
|
||||
{
|
||||
m_log.DebugFormat("[VOICE] OnRegisterCaps: agentID {0} caps {1}", agentID, caps);
|
||||
string capsBase = "/CAPS/" + caps.CapsObjectPath;
|
||||
caps.RegisterHandler("ParcelVoiceInfoRequest",
|
||||
new RestStreamHandler("POST", capsBase + m_parcelVoiceInfoRequestPath,
|
||||
delegate(string request, string path, string param)
|
||||
{
|
||||
return ParcelVoiceInfoRequest(request, path, param,
|
||||
agentID, caps);
|
||||
}));
|
||||
caps.RegisterHandler("ProvisionVoiceAccountRequest",
|
||||
new RestStreamHandler("POST", capsBase + m_provisionVoiceAccountRequestPath,
|
||||
delegate(string request, string path, string param)
|
||||
{
|
||||
return ProvisionVoiceAccountRequest(request, path, param,
|
||||
agentID, caps);
|
||||
}));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Callback for a client request for ParcelVoiceInfo
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="param"></param>
|
||||
/// <param name="agentID"></param>
|
||||
/// <param name="caps"></param>
|
||||
/// <returns></returns>
|
||||
public string ParcelVoiceInfoRequest(string request, string path, string param,
|
||||
LLUUID agentID, Caps caps)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_log.DebugFormat("[VOICE][PARCELVOICE]: request: {0}, path: {1}, param: {2}", request, path, param);
|
||||
|
||||
// FIXME: get the creds from region file or from config
|
||||
Hashtable creds = new Hashtable();
|
||||
|
||||
creds["channel_uri"] = String.Format("sip:{0}@{1}", agentID, m_sipDomain);
|
||||
|
||||
string regionName = m_scene.RegionInfo.RegionName;
|
||||
ScenePresence avatar = m_scene.GetScenePresence(agentID);
|
||||
if (null == m_scene.LandChannel) throw new Exception("land data not yet available");
|
||||
LandData land = m_scene.GetLandData(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
|
||||
|
||||
LLSDParcelVoiceInfoResponse parcelVoiceInfo =
|
||||
new LLSDParcelVoiceInfoResponse(regionName, land.localID, creds);
|
||||
|
||||
string r = LLSDHelpers.SerialiseLLSDReply(parcelVoiceInfo);
|
||||
m_log.DebugFormat("[VOICE][PARCELVOICE]: {0}", r);
|
||||
|
||||
return r;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[CAPS]: {0}, try again later", e.ToString());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Callback for a client request for Voice Account Details
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="param"></param>
|
||||
/// <param name="agentID"></param>
|
||||
/// <param name="caps"></param>
|
||||
/// <returns></returns>
|
||||
public string ProvisionVoiceAccountRequest(string request, string path, string param,
|
||||
LLUUID agentID, Caps caps)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_log.DebugFormat("[VOICE][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}",
|
||||
request, path, param);
|
||||
|
||||
string voiceUser = "x" + Convert.ToBase64String(agentID.GetBytes());
|
||||
voiceUser = voiceUser.Replace('+', '-').Replace('/', '_');
|
||||
|
||||
CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(agentID);
|
||||
if (null == userInfo) throw new Exception("cannot get user details");
|
||||
|
||||
LLSDVoiceAccountResponse voiceAccountResponse =
|
||||
new LLSDVoiceAccountResponse(voiceUser, "$1$" + userInfo.UserProfile.PasswordHash);
|
||||
string r = LLSDHelpers.SerialiseLLSDReply(voiceAccountResponse);
|
||||
m_log.DebugFormat("[CAPS][PROVISIONVOICE]: {0}", r);
|
||||
return r;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[CAPS][PROVISIONVOICE]: {0}, retry later", e.Message);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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.Reflection;
|
||||
using libsecondlife;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Communications.Cache;
|
||||
using OpenSim.Framework.Servers;
|
||||
using OpenSim.Region.Capabilities;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
using Caps=OpenSim.Region.Capabilities.Caps;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Avatar.Voice.SIPVoice
|
||||
{
|
||||
public class SIPVoiceModule : IRegionModule
|
||||
{
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private static readonly string m_parcelVoiceInfoRequestPath = "0007/";
|
||||
private static readonly string m_provisionVoiceAccountRequestPath = "0008/";
|
||||
private IConfig m_config;
|
||||
private Scene m_scene;
|
||||
private string m_sipDomain;
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource config)
|
||||
{
|
||||
m_scene = scene;
|
||||
m_config = config.Configs["Voice"];
|
||||
|
||||
if (null == m_config || !m_config.GetBoolean("enabled", false))
|
||||
{
|
||||
m_log.Info("[VOICE] plugin disabled");
|
||||
return;
|
||||
}
|
||||
m_log.Info("[VOICE] plugin enabled");
|
||||
|
||||
m_sipDomain = m_config.GetString("sip_domain", String.Empty);
|
||||
if (String.IsNullOrEmpty(m_sipDomain))
|
||||
{
|
||||
m_log.Error("[VOICE] plugin mis-configured: missing sip_domain configuration");
|
||||
m_log.Info("[VOICE] plugin disabled");
|
||||
return;
|
||||
}
|
||||
m_log.InfoFormat("[VOICE] using SIP domain {0}", m_sipDomain);
|
||||
|
||||
scene.EventManager.OnRegisterCaps += OnRegisterCaps;
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "VoiceModule"; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void OnRegisterCaps(LLUUID agentID, Caps caps)
|
||||
{
|
||||
m_log.DebugFormat("[VOICE] OnRegisterCaps: agentID {0} caps {1}", agentID, caps);
|
||||
string capsBase = "/CAPS/" + caps.CapsObjectPath;
|
||||
caps.RegisterHandler("ParcelVoiceInfoRequest",
|
||||
new RestStreamHandler("POST", capsBase + m_parcelVoiceInfoRequestPath,
|
||||
delegate(string request, string path, string param)
|
||||
{
|
||||
return ParcelVoiceInfoRequest(request, path, param,
|
||||
agentID, caps);
|
||||
}));
|
||||
caps.RegisterHandler("ProvisionVoiceAccountRequest",
|
||||
new RestStreamHandler("POST", capsBase + m_provisionVoiceAccountRequestPath,
|
||||
delegate(string request, string path, string param)
|
||||
{
|
||||
return ProvisionVoiceAccountRequest(request, path, param,
|
||||
agentID, caps);
|
||||
}));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Callback for a client request for ParcelVoiceInfo
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="param"></param>
|
||||
/// <param name="agentID"></param>
|
||||
/// <param name="caps"></param>
|
||||
/// <returns></returns>
|
||||
public string ParcelVoiceInfoRequest(string request, string path, string param,
|
||||
LLUUID agentID, Caps caps)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_log.DebugFormat("[VOICE][PARCELVOICE]: request: {0}, path: {1}, param: {2}", request, path, param);
|
||||
|
||||
// FIXME: get the creds from region file or from config
|
||||
Hashtable creds = new Hashtable();
|
||||
|
||||
creds["channel_uri"] = String.Format("sip:{0}@{1}", agentID, m_sipDomain);
|
||||
|
||||
string regionName = m_scene.RegionInfo.RegionName;
|
||||
ScenePresence avatar = m_scene.GetScenePresence(agentID);
|
||||
if (null == m_scene.LandChannel) throw new Exception("land data not yet available");
|
||||
LandData land = m_scene.GetLandData(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
|
||||
|
||||
LLSDParcelVoiceInfoResponse parcelVoiceInfo =
|
||||
new LLSDParcelVoiceInfoResponse(regionName, land.localID, creds);
|
||||
|
||||
string r = LLSDHelpers.SerialiseLLSDReply(parcelVoiceInfo);
|
||||
m_log.DebugFormat("[VOICE][PARCELVOICE]: {0}", r);
|
||||
|
||||
return r;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[CAPS]: {0}, try again later", e.ToString());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Callback for a client request for Voice Account Details
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="param"></param>
|
||||
/// <param name="agentID"></param>
|
||||
/// <param name="caps"></param>
|
||||
/// <returns></returns>
|
||||
public string ProvisionVoiceAccountRequest(string request, string path, string param,
|
||||
LLUUID agentID, Caps caps)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_log.DebugFormat("[VOICE][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}",
|
||||
request, path, param);
|
||||
|
||||
string voiceUser = "x" + Convert.ToBase64String(agentID.GetBytes());
|
||||
voiceUser = voiceUser.Replace('+', '-').Replace('/', '_');
|
||||
|
||||
CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(agentID);
|
||||
if (null == userInfo) throw new Exception("cannot get user details");
|
||||
|
||||
LLSDVoiceAccountResponse voiceAccountResponse =
|
||||
new LLSDVoiceAccountResponse(voiceUser, "$1$" + userInfo.UserProfile.PasswordHash);
|
||||
string r = LLSDHelpers.SerialiseLLSDReply(voiceAccountResponse);
|
||||
m_log.DebugFormat("[CAPS][PROVISIONVOICE]: {0}", r);
|
||||
return r;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[CAPS][PROVISIONVOICE]: {0}, retry later", e.Message);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,308 +1,308 @@
|
|||
/*
|
||||
* 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.Text;
|
||||
using log4net;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Framework
|
||||
{
|
||||
/// <summary>
|
||||
/// A single function call encapsulated in a class which enforces arguments when passing around as Object[]'s.
|
||||
/// Used for console commands and script API generation
|
||||
/// </summary>
|
||||
public class Command : ICommand
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private List<CommandArgument> m_args = new List<CommandArgument>();
|
||||
|
||||
private Action<object[]> m_command;
|
||||
private string m_help;
|
||||
private string m_name;
|
||||
|
||||
public Command(string name, Action<Object[]> command, string help)
|
||||
{
|
||||
m_name = name;
|
||||
m_command = command;
|
||||
m_help = help;
|
||||
}
|
||||
|
||||
#region ICommand Members
|
||||
|
||||
public void AddArgument(string name, string helptext, string type)
|
||||
{
|
||||
m_args.Add(new CommandArgument(name, helptext, type));
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return m_name; }
|
||||
}
|
||||
|
||||
public string Help
|
||||
{
|
||||
get { return m_help; }
|
||||
}
|
||||
|
||||
public Dictionary<string, string> Arguments
|
||||
{
|
||||
get
|
||||
{
|
||||
Dictionary<string, string> tmp = new Dictionary<string, string>();
|
||||
foreach (CommandArgument arg in m_args)
|
||||
{
|
||||
tmp.Add(arg.Name, arg.ArgumentType);
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
|
||||
public void ShowConsoleHelp()
|
||||
{
|
||||
m_log.Info("== " + Name + " ==");
|
||||
m_log.Info(m_help);
|
||||
m_log.Info("= Parameters =");
|
||||
foreach (CommandArgument arg in m_args)
|
||||
{
|
||||
m_log.Info("* " + arg.Name + " (" + arg.ArgumentType + ")");
|
||||
m_log.Info("\t" + arg.HelpText);
|
||||
}
|
||||
}
|
||||
|
||||
public void Run(Object[] args)
|
||||
{
|
||||
Object[] cleanArgs = new Object[m_args.Count];
|
||||
|
||||
if (args.Length < cleanArgs.Length)
|
||||
{
|
||||
m_log.Error("Missing " + (cleanArgs.Length - args.Length) + " argument(s)");
|
||||
ShowConsoleHelp();
|
||||
return;
|
||||
}
|
||||
if (args.Length > cleanArgs.Length)
|
||||
{
|
||||
m_log.Error("Too many arguments for this command. Type '<module> <command> help' for help.");
|
||||
return;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
foreach (Object arg in args)
|
||||
{
|
||||
if (string.IsNullOrEmpty(arg.ToString()))
|
||||
{
|
||||
m_log.Error("Empty arguments are not allowed");
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
switch (m_args[i].ArgumentType)
|
||||
{
|
||||
case "String":
|
||||
m_args[i].ArgumentValue = arg.ToString();
|
||||
break;
|
||||
case "Integer":
|
||||
m_args[i].ArgumentValue = Int32.Parse(arg.ToString());
|
||||
break;
|
||||
case "Double":
|
||||
m_args[i].ArgumentValue = Double.Parse(arg.ToString());
|
||||
break;
|
||||
case "Boolean":
|
||||
m_args[i].ArgumentValue = Boolean.Parse(arg.ToString());
|
||||
break;
|
||||
default:
|
||||
m_log.Error("Unknown desired type for argument " + m_args[i].Name + " on command " + m_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
m_log.Error("Argument number " + (i + 1) +
|
||||
" (" + m_args[i].Name + ") must be a valid " +
|
||||
m_args[i].ArgumentType.ToLower() + ".");
|
||||
}
|
||||
cleanArgs[i] = m_args[i].ArgumentValue;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
m_command.Invoke(cleanArgs);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A single command argument, contains name, type and at runtime, value.
|
||||
/// </summary>
|
||||
public class CommandArgument
|
||||
{
|
||||
private string m_help;
|
||||
private string m_name;
|
||||
private string m_type;
|
||||
private Object m_val;
|
||||
|
||||
public CommandArgument(string name, string help, string type)
|
||||
{
|
||||
m_name = name;
|
||||
m_help = help;
|
||||
m_type = type;
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return m_name; }
|
||||
}
|
||||
|
||||
public string HelpText
|
||||
{
|
||||
get { return m_help; }
|
||||
}
|
||||
|
||||
public string ArgumentType
|
||||
{
|
||||
get { return m_type; }
|
||||
}
|
||||
|
||||
public Object ArgumentValue
|
||||
{
|
||||
get { return m_val; }
|
||||
set { m_val = value; }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A class to enable modules to register console and script commands, which enforces typing and valid input.
|
||||
/// </summary>
|
||||
public class Commander : ICommander
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private Dictionary<string, ICommand> m_commands = new Dictionary<string, ICommand>();
|
||||
private string m_name;
|
||||
|
||||
public Commander(string name)
|
||||
{
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
#region ICommander Members
|
||||
|
||||
public void RegisterCommand(string commandName, ICommand command)
|
||||
{
|
||||
m_commands[commandName] = command;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a runtime C# class which can be compiled and inserted via reflection to enable modules to register new script commands
|
||||
/// </summary>
|
||||
/// <returns>Returns C# source code to create a binding</returns>
|
||||
public string GenerateRuntimeAPI()
|
||||
{
|
||||
string classSrc = "\n\tpublic class " + m_name + " {\n";
|
||||
foreach (ICommand com in m_commands.Values)
|
||||
{
|
||||
classSrc += "\tpublic void " + EscapeRuntimeAPICommand(com.Name) + "( ";
|
||||
foreach (KeyValuePair<string, string> arg in com.Arguments)
|
||||
{
|
||||
classSrc += arg.Value + " " + Util.Md5Hash(arg.Key) + ",";
|
||||
}
|
||||
classSrc = classSrc.Remove(classSrc.Length - 1); // Delete the last comma
|
||||
classSrc += " )\n\t{\n";
|
||||
classSrc += "\t\tObject[] args = new Object[" + com.Arguments.Count.ToString() + "];\n";
|
||||
int i = 0;
|
||||
foreach (KeyValuePair<string, string> arg in com.Arguments)
|
||||
{
|
||||
classSrc += "\t\targs[" + i.ToString() + "] = " + Util.Md5Hash(arg.Key) + " " + ";\n";
|
||||
i++;
|
||||
}
|
||||
classSrc += "\t\tGetCommander(\"" + m_name + "\").Run(\"" + com.Name + "\", args);\n";
|
||||
classSrc += "\t}\n";
|
||||
}
|
||||
classSrc += "}\n";
|
||||
|
||||
return classSrc;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs a specified function with attached arguments
|
||||
/// *** <b>DO NOT CALL DIRECTLY.</b> ***
|
||||
/// Call ProcessConsoleCommand instead if handling human input.
|
||||
/// </summary>
|
||||
/// <param name="function">The function name to call</param>
|
||||
/// <param name="args">The function parameters</param>
|
||||
public void Run(string function, object[] args)
|
||||
{
|
||||
m_commands[function].Run(args);
|
||||
}
|
||||
|
||||
public void ProcessConsoleCommand(string function, string[] args)
|
||||
{
|
||||
if (m_commands.ContainsKey(function))
|
||||
{
|
||||
if (args.Length > 0 && args[0] == "help")
|
||||
{
|
||||
m_commands[function].ShowConsoleHelp();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_commands[function].Run(args);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (function != "help")
|
||||
m_log.Error("Invalid command - No such command exists");
|
||||
if (function == "api")
|
||||
m_log.Info(GenerateRuntimeAPI());
|
||||
ShowConsoleHelp();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void ShowConsoleHelp()
|
||||
{
|
||||
m_log.Info("===" + m_name + "===");
|
||||
foreach (ICommand com in m_commands.Values)
|
||||
{
|
||||
m_log.Info("* " + com.Name + " - " + com.Help);
|
||||
}
|
||||
}
|
||||
|
||||
private string EscapeRuntimeAPICommand(string command)
|
||||
{
|
||||
command = command.Replace('-', '_');
|
||||
StringBuilder tmp = new StringBuilder(command);
|
||||
tmp[0] = tmp[0].ToString().ToUpper().ToCharArray()[0];
|
||||
|
||||
return tmp.ToString();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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.Text;
|
||||
using log4net;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Framework
|
||||
{
|
||||
/// <summary>
|
||||
/// A single function call encapsulated in a class which enforces arguments when passing around as Object[]'s.
|
||||
/// Used for console commands and script API generation
|
||||
/// </summary>
|
||||
public class Command : ICommand
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private List<CommandArgument> m_args = new List<CommandArgument>();
|
||||
|
||||
private Action<object[]> m_command;
|
||||
private string m_help;
|
||||
private string m_name;
|
||||
|
||||
public Command(string name, Action<Object[]> command, string help)
|
||||
{
|
||||
m_name = name;
|
||||
m_command = command;
|
||||
m_help = help;
|
||||
}
|
||||
|
||||
#region ICommand Members
|
||||
|
||||
public void AddArgument(string name, string helptext, string type)
|
||||
{
|
||||
m_args.Add(new CommandArgument(name, helptext, type));
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return m_name; }
|
||||
}
|
||||
|
||||
public string Help
|
||||
{
|
||||
get { return m_help; }
|
||||
}
|
||||
|
||||
public Dictionary<string, string> Arguments
|
||||
{
|
||||
get
|
||||
{
|
||||
Dictionary<string, string> tmp = new Dictionary<string, string>();
|
||||
foreach (CommandArgument arg in m_args)
|
||||
{
|
||||
tmp.Add(arg.Name, arg.ArgumentType);
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
|
||||
public void ShowConsoleHelp()
|
||||
{
|
||||
m_log.Info("== " + Name + " ==");
|
||||
m_log.Info(m_help);
|
||||
m_log.Info("= Parameters =");
|
||||
foreach (CommandArgument arg in m_args)
|
||||
{
|
||||
m_log.Info("* " + arg.Name + " (" + arg.ArgumentType + ")");
|
||||
m_log.Info("\t" + arg.HelpText);
|
||||
}
|
||||
}
|
||||
|
||||
public void Run(Object[] args)
|
||||
{
|
||||
Object[] cleanArgs = new Object[m_args.Count];
|
||||
|
||||
if (args.Length < cleanArgs.Length)
|
||||
{
|
||||
m_log.Error("Missing " + (cleanArgs.Length - args.Length) + " argument(s)");
|
||||
ShowConsoleHelp();
|
||||
return;
|
||||
}
|
||||
if (args.Length > cleanArgs.Length)
|
||||
{
|
||||
m_log.Error("Too many arguments for this command. Type '<module> <command> help' for help.");
|
||||
return;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
foreach (Object arg in args)
|
||||
{
|
||||
if (string.IsNullOrEmpty(arg.ToString()))
|
||||
{
|
||||
m_log.Error("Empty arguments are not allowed");
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
switch (m_args[i].ArgumentType)
|
||||
{
|
||||
case "String":
|
||||
m_args[i].ArgumentValue = arg.ToString();
|
||||
break;
|
||||
case "Integer":
|
||||
m_args[i].ArgumentValue = Int32.Parse(arg.ToString());
|
||||
break;
|
||||
case "Double":
|
||||
m_args[i].ArgumentValue = Double.Parse(arg.ToString());
|
||||
break;
|
||||
case "Boolean":
|
||||
m_args[i].ArgumentValue = Boolean.Parse(arg.ToString());
|
||||
break;
|
||||
default:
|
||||
m_log.Error("Unknown desired type for argument " + m_args[i].Name + " on command " + m_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
m_log.Error("Argument number " + (i + 1) +
|
||||
" (" + m_args[i].Name + ") must be a valid " +
|
||||
m_args[i].ArgumentType.ToLower() + ".");
|
||||
}
|
||||
cleanArgs[i] = m_args[i].ArgumentValue;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
m_command.Invoke(cleanArgs);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A single command argument, contains name, type and at runtime, value.
|
||||
/// </summary>
|
||||
public class CommandArgument
|
||||
{
|
||||
private string m_help;
|
||||
private string m_name;
|
||||
private string m_type;
|
||||
private Object m_val;
|
||||
|
||||
public CommandArgument(string name, string help, string type)
|
||||
{
|
||||
m_name = name;
|
||||
m_help = help;
|
||||
m_type = type;
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return m_name; }
|
||||
}
|
||||
|
||||
public string HelpText
|
||||
{
|
||||
get { return m_help; }
|
||||
}
|
||||
|
||||
public string ArgumentType
|
||||
{
|
||||
get { return m_type; }
|
||||
}
|
||||
|
||||
public Object ArgumentValue
|
||||
{
|
||||
get { return m_val; }
|
||||
set { m_val = value; }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A class to enable modules to register console and script commands, which enforces typing and valid input.
|
||||
/// </summary>
|
||||
public class Commander : ICommander
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private Dictionary<string, ICommand> m_commands = new Dictionary<string, ICommand>();
|
||||
private string m_name;
|
||||
|
||||
public Commander(string name)
|
||||
{
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
#region ICommander Members
|
||||
|
||||
public void RegisterCommand(string commandName, ICommand command)
|
||||
{
|
||||
m_commands[commandName] = command;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a runtime C# class which can be compiled and inserted via reflection to enable modules to register new script commands
|
||||
/// </summary>
|
||||
/// <returns>Returns C# source code to create a binding</returns>
|
||||
public string GenerateRuntimeAPI()
|
||||
{
|
||||
string classSrc = "\n\tpublic class " + m_name + " {\n";
|
||||
foreach (ICommand com in m_commands.Values)
|
||||
{
|
||||
classSrc += "\tpublic void " + EscapeRuntimeAPICommand(com.Name) + "( ";
|
||||
foreach (KeyValuePair<string, string> arg in com.Arguments)
|
||||
{
|
||||
classSrc += arg.Value + " " + Util.Md5Hash(arg.Key) + ",";
|
||||
}
|
||||
classSrc = classSrc.Remove(classSrc.Length - 1); // Delete the last comma
|
||||
classSrc += " )\n\t{\n";
|
||||
classSrc += "\t\tObject[] args = new Object[" + com.Arguments.Count.ToString() + "];\n";
|
||||
int i = 0;
|
||||
foreach (KeyValuePair<string, string> arg in com.Arguments)
|
||||
{
|
||||
classSrc += "\t\targs[" + i.ToString() + "] = " + Util.Md5Hash(arg.Key) + " " + ";\n";
|
||||
i++;
|
||||
}
|
||||
classSrc += "\t\tGetCommander(\"" + m_name + "\").Run(\"" + com.Name + "\", args);\n";
|
||||
classSrc += "\t}\n";
|
||||
}
|
||||
classSrc += "}\n";
|
||||
|
||||
return classSrc;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs a specified function with attached arguments
|
||||
/// *** <b>DO NOT CALL DIRECTLY.</b> ***
|
||||
/// Call ProcessConsoleCommand instead if handling human input.
|
||||
/// </summary>
|
||||
/// <param name="function">The function name to call</param>
|
||||
/// <param name="args">The function parameters</param>
|
||||
public void Run(string function, object[] args)
|
||||
{
|
||||
m_commands[function].Run(args);
|
||||
}
|
||||
|
||||
public void ProcessConsoleCommand(string function, string[] args)
|
||||
{
|
||||
if (m_commands.ContainsKey(function))
|
||||
{
|
||||
if (args.Length > 0 && args[0] == "help")
|
||||
{
|
||||
m_commands[function].ShowConsoleHelp();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_commands[function].Run(args);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (function != "help")
|
||||
m_log.Error("Invalid command - No such command exists");
|
||||
if (function == "api")
|
||||
m_log.Info(GenerateRuntimeAPI());
|
||||
ShowConsoleHelp();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void ShowConsoleHelp()
|
||||
{
|
||||
m_log.Info("===" + m_name + "===");
|
||||
foreach (ICommand com in m_commands.Values)
|
||||
{
|
||||
m_log.Info("* " + com.Name + " - " + com.Help);
|
||||
}
|
||||
}
|
||||
|
||||
private string EscapeRuntimeAPICommand(string command)
|
||||
{
|
||||
command = command.Replace('-', '_');
|
||||
StringBuilder tmp = new StringBuilder(command);
|
||||
tmp[0] = tmp[0].ToString().ToUpper().ToCharArray()[0];
|
||||
|
||||
return tmp.ToString();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,88 +1,88 @@
|
|||
/*
|
||||
* 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 Nini.Config;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Framework
|
||||
{
|
||||
public class CommanderTestModule : IRegionModule, ICommandableModule
|
||||
{
|
||||
private Commander m_commander = new Commander("CommanderTest");
|
||||
private Scene m_scene;
|
||||
|
||||
#region ICommandableModule Members
|
||||
|
||||
public ICommander CommandInterface
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource source)
|
||||
{
|
||||
m_scene = scene;
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
Command testCommand = new Command("hello", InterfaceHelloWorld, "Says a simple debugging test string");
|
||||
testCommand.AddArgument("world", "Write world here", "string");
|
||||
|
||||
m_commander.RegisterCommand("hello", testCommand);
|
||||
|
||||
// Register me
|
||||
m_scene.RegisterModuleCommander("commandertest", m_commander);
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "CommanderTestModule"; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void InterfaceHelloWorld(Object[] args)
|
||||
{
|
||||
Console.WriteLine("Hello World");
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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 Nini.Config;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Framework
|
||||
{
|
||||
public class CommanderTestModule : IRegionModule, ICommandableModule
|
||||
{
|
||||
private Commander m_commander = new Commander("CommanderTest");
|
||||
private Scene m_scene;
|
||||
|
||||
#region ICommandableModule Members
|
||||
|
||||
public ICommander CommandInterface
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource source)
|
||||
{
|
||||
m_scene = scene;
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
Command testCommand = new Command("hello", InterfaceHelloWorld, "Says a simple debugging test string");
|
||||
testCommand.AddArgument("world", "Write world here", "string");
|
||||
|
||||
m_commander.RegisterCommand("hello", testCommand);
|
||||
|
||||
// Register me
|
||||
m_scene.RegisterModuleCommander("commandertest", m_commander);
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "CommanderTestModule"; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void InterfaceHelloWorld(Object[] args)
|
||||
{
|
||||
Console.WriteLine("Hello World");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,16 +1,16 @@
|
|||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Environment.Modules.Communications.Interregion;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Grid.Interregion
|
||||
{
|
||||
public interface IInterregionModule
|
||||
{
|
||||
void RegisterMethod<T>(T e);
|
||||
bool HasInterface<T>(Location loc);
|
||||
T RequestInterface<T>(Location loc);
|
||||
T[] RequestInterface<T>();
|
||||
Location GetLocationByDirection(Scene scene, InterregionModule.Direction dir);
|
||||
void internal_CreateRemotingObjects();
|
||||
}
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Environment.Modules.Communications.Interregion;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Grid.Interregion
|
||||
{
|
||||
public interface IInterregionModule
|
||||
{
|
||||
void RegisterMethod<T>(T e);
|
||||
bool HasInterface<T>(Location loc);
|
||||
T RequestInterface<T>(Location loc);
|
||||
T[] RequestInterface<T>();
|
||||
Location GetLocationByDirection(Scene scene, InterregionModule.Direction dir);
|
||||
void internal_CreateRemotingObjects();
|
||||
}
|
||||
}
|
|
@ -1,180 +1,180 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Remoting;
|
||||
using System.Runtime.Remoting.Channels;
|
||||
using System.Runtime.Remoting.Channels.Tcp;
|
||||
using Nini.Config;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Modules.Grid.Interregion;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Communications.Interregion
|
||||
{
|
||||
public class InterregionModule : IInterregionModule, IRegionModule
|
||||
{
|
||||
#region Direction enum
|
||||
|
||||
public enum Direction
|
||||
{
|
||||
North,
|
||||
NorthEast,
|
||||
East,
|
||||
SouthEast,
|
||||
South,
|
||||
SouthWest,
|
||||
West,
|
||||
NorthWest
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private readonly Dictionary<Type, Object> m_interfaces = new Dictionary<Type, object>();
|
||||
private readonly List<Location> m_myLocations = new List<Location>();
|
||||
|
||||
private readonly Dictionary<Location, string[]> m_neighbourInterfaces = new Dictionary<Location, string[]>();
|
||||
private readonly Dictionary<Location, RemotingObject> m_neighbourRemote = new Dictionary<Location, RemotingObject>();
|
||||
private IConfigSource m_config;
|
||||
private bool m_enabled = false;
|
||||
|
||||
private Object m_lockObject = new object();
|
||||
private RemotingObject m_myRemote;
|
||||
private TcpChannel m_tcpChannel;
|
||||
private int m_tcpPort = 10101;
|
||||
|
||||
#region IInterregionModule Members
|
||||
|
||||
public void internal_CreateRemotingObjects()
|
||||
{
|
||||
lock (m_lockObject)
|
||||
{
|
||||
if (m_tcpChannel == null)
|
||||
{
|
||||
m_myRemote = new RemotingObject(m_interfaces, m_myLocations.ToArray());
|
||||
m_tcpChannel = new TcpChannel(m_tcpPort);
|
||||
|
||||
ChannelServices.RegisterChannel(m_tcpChannel, false);
|
||||
RemotingServices.Marshal(m_myRemote, "OpenSimRemote2", typeof (RemotingObject));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RegisterMethod<T>(T e)
|
||||
{
|
||||
m_interfaces[typeof (T)] = e;
|
||||
}
|
||||
|
||||
public bool HasInterface<T>(Location loc)
|
||||
{
|
||||
foreach (string val in m_neighbourInterfaces[loc])
|
||||
{
|
||||
if (val == typeof (T).FullName)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public T RequestInterface<T>(Location loc)
|
||||
{
|
||||
if (m_neighbourRemote.ContainsKey(loc))
|
||||
{
|
||||
return m_neighbourRemote[loc].RequestInterface<T>();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IndexOutOfRangeException("No neighbour availible at that location");
|
||||
}
|
||||
}
|
||||
|
||||
public T[] RequestInterface<T>()
|
||||
{
|
||||
List<T> m_t = new List<T>();
|
||||
foreach (RemotingObject remote in m_neighbourRemote.Values)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_t.Add(remote.RequestInterface<T>());
|
||||
}
|
||||
catch (NotSupportedException)
|
||||
{
|
||||
}
|
||||
}
|
||||
return m_t.ToArray();
|
||||
}
|
||||
|
||||
public Location GetLocationByDirection(Scene scene, Direction dir)
|
||||
{
|
||||
return new Location(0, 0);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
//TODO: This prevents us from registering new scenes after PostInitialise if we want comms updated.
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource source)
|
||||
{
|
||||
if (m_enabled)
|
||||
{
|
||||
m_myLocations.Add(new Location((int) scene.RegionInfo.RegionLocX,
|
||||
(int) scene.RegionInfo.RegionLocY));
|
||||
m_config = source;
|
||||
|
||||
scene.RegisterModuleInterface<IInterregionModule>(this);
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: This prevents us from registering new scenes after PostInitialise if we want comms updated.
|
||||
public void PostInitialise()
|
||||
{
|
||||
if (m_enabled)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_tcpPort = m_config.Configs["Comms"].GetInt("remoting_port", m_tcpPort);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
internal_CreateRemotingObjects();
|
||||
}
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
ChannelServices.UnregisterChannel(m_tcpChannel);
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "InterregionModule"; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void RegisterRemoteRegion(string uri)
|
||||
{
|
||||
RegisterRemotingInterface((RemotingObject) Activator.GetObject(typeof (RemotingObject), uri));
|
||||
}
|
||||
|
||||
private void RegisterRemotingInterface(RemotingObject remote)
|
||||
{
|
||||
Location[] locs = remote.GetLocations();
|
||||
string[] interfaces = remote.GetInterfaces();
|
||||
foreach (Location loc in locs)
|
||||
{
|
||||
m_neighbourInterfaces[loc] = interfaces;
|
||||
m_neighbourRemote[loc] = remote;
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Remoting;
|
||||
using System.Runtime.Remoting.Channels;
|
||||
using System.Runtime.Remoting.Channels.Tcp;
|
||||
using Nini.Config;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Modules.Grid.Interregion;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Communications.Interregion
|
||||
{
|
||||
public class InterregionModule : IInterregionModule, IRegionModule
|
||||
{
|
||||
#region Direction enum
|
||||
|
||||
public enum Direction
|
||||
{
|
||||
North,
|
||||
NorthEast,
|
||||
East,
|
||||
SouthEast,
|
||||
South,
|
||||
SouthWest,
|
||||
West,
|
||||
NorthWest
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private readonly Dictionary<Type, Object> m_interfaces = new Dictionary<Type, object>();
|
||||
private readonly List<Location> m_myLocations = new List<Location>();
|
||||
|
||||
private readonly Dictionary<Location, string[]> m_neighbourInterfaces = new Dictionary<Location, string[]>();
|
||||
private readonly Dictionary<Location, RemotingObject> m_neighbourRemote = new Dictionary<Location, RemotingObject>();
|
||||
private IConfigSource m_config;
|
||||
private bool m_enabled = false;
|
||||
|
||||
private Object m_lockObject = new object();
|
||||
private RemotingObject m_myRemote;
|
||||
private TcpChannel m_tcpChannel;
|
||||
private int m_tcpPort = 10101;
|
||||
|
||||
#region IInterregionModule Members
|
||||
|
||||
public void internal_CreateRemotingObjects()
|
||||
{
|
||||
lock (m_lockObject)
|
||||
{
|
||||
if (m_tcpChannel == null)
|
||||
{
|
||||
m_myRemote = new RemotingObject(m_interfaces, m_myLocations.ToArray());
|
||||
m_tcpChannel = new TcpChannel(m_tcpPort);
|
||||
|
||||
ChannelServices.RegisterChannel(m_tcpChannel, false);
|
||||
RemotingServices.Marshal(m_myRemote, "OpenSimRemote2", typeof (RemotingObject));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RegisterMethod<T>(T e)
|
||||
{
|
||||
m_interfaces[typeof (T)] = e;
|
||||
}
|
||||
|
||||
public bool HasInterface<T>(Location loc)
|
||||
{
|
||||
foreach (string val in m_neighbourInterfaces[loc])
|
||||
{
|
||||
if (val == typeof (T).FullName)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public T RequestInterface<T>(Location loc)
|
||||
{
|
||||
if (m_neighbourRemote.ContainsKey(loc))
|
||||
{
|
||||
return m_neighbourRemote[loc].RequestInterface<T>();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IndexOutOfRangeException("No neighbour availible at that location");
|
||||
}
|
||||
}
|
||||
|
||||
public T[] RequestInterface<T>()
|
||||
{
|
||||
List<T> m_t = new List<T>();
|
||||
foreach (RemotingObject remote in m_neighbourRemote.Values)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_t.Add(remote.RequestInterface<T>());
|
||||
}
|
||||
catch (NotSupportedException)
|
||||
{
|
||||
}
|
||||
}
|
||||
return m_t.ToArray();
|
||||
}
|
||||
|
||||
public Location GetLocationByDirection(Scene scene, Direction dir)
|
||||
{
|
||||
return new Location(0, 0);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
//TODO: This prevents us from registering new scenes after PostInitialise if we want comms updated.
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource source)
|
||||
{
|
||||
if (m_enabled)
|
||||
{
|
||||
m_myLocations.Add(new Location((int) scene.RegionInfo.RegionLocX,
|
||||
(int) scene.RegionInfo.RegionLocY));
|
||||
m_config = source;
|
||||
|
||||
scene.RegisterModuleInterface<IInterregionModule>(this);
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: This prevents us from registering new scenes after PostInitialise if we want comms updated.
|
||||
public void PostInitialise()
|
||||
{
|
||||
if (m_enabled)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_tcpPort = m_config.Configs["Comms"].GetInt("remoting_port", m_tcpPort);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
internal_CreateRemotingObjects();
|
||||
}
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
ChannelServices.UnregisterChannel(m_tcpChannel);
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "InterregionModule"; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void RegisterRemoteRegion(string uri)
|
||||
{
|
||||
RegisterRemotingInterface((RemotingObject) Activator.GetObject(typeof (RemotingObject), uri));
|
||||
}
|
||||
|
||||
private void RegisterRemotingInterface(RemotingObject remote)
|
||||
{
|
||||
Location[] locs = remote.GetLocations();
|
||||
string[] interfaces = remote.GetInterfaces();
|
||||
foreach (Location loc in locs)
|
||||
{
|
||||
m_neighbourInterfaces[loc] = interfaces;
|
||||
m_neighbourRemote[loc] = remote;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,50 +1,50 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using OpenSim.Framework;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Grid.Interregion
|
||||
{
|
||||
public class RemotingObject : MarshalByRefObject
|
||||
{
|
||||
private readonly Location[] m_coords;
|
||||
private readonly Dictionary<Type, Object> m_interfaces = new Dictionary<Type, object>();
|
||||
|
||||
public RemotingObject(Dictionary<Type, Object> myInterfaces, Location[] coords)
|
||||
{
|
||||
m_interfaces = myInterfaces;
|
||||
m_coords = coords;
|
||||
}
|
||||
|
||||
public Location[] GetLocations()
|
||||
{
|
||||
return (Location[]) m_coords.Clone();
|
||||
}
|
||||
|
||||
public string[] GetInterfaces()
|
||||
{
|
||||
string[] interfaces = new string[m_interfaces.Count];
|
||||
int i = 0;
|
||||
|
||||
foreach (KeyValuePair<Type, object> pair in m_interfaces)
|
||||
{
|
||||
interfaces[i++] = pair.Key.FullName;
|
||||
}
|
||||
|
||||
return interfaces;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a registered interface availible to neighbouring regions.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of interface you wish to request</typeparam>
|
||||
/// <returns>A MarshalByRefObject inherited from this region inheriting the interface requested.</returns>
|
||||
/// <remarks>All registered interfaces <b>MUST</b> inherit from MarshalByRefObject and use only serialisable types.</remarks>
|
||||
public T RequestInterface<T>()
|
||||
{
|
||||
if (m_interfaces.ContainsKey(typeof (T)))
|
||||
return (T) m_interfaces[typeof (T)];
|
||||
|
||||
throw new NotSupportedException("No such interface registered.");
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using OpenSim.Framework;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Grid.Interregion
|
||||
{
|
||||
public class RemotingObject : MarshalByRefObject
|
||||
{
|
||||
private readonly Location[] m_coords;
|
||||
private readonly Dictionary<Type, Object> m_interfaces = new Dictionary<Type, object>();
|
||||
|
||||
public RemotingObject(Dictionary<Type, Object> myInterfaces, Location[] coords)
|
||||
{
|
||||
m_interfaces = myInterfaces;
|
||||
m_coords = coords;
|
||||
}
|
||||
|
||||
public Location[] GetLocations()
|
||||
{
|
||||
return (Location[]) m_coords.Clone();
|
||||
}
|
||||
|
||||
public string[] GetInterfaces()
|
||||
{
|
||||
string[] interfaces = new string[m_interfaces.Count];
|
||||
int i = 0;
|
||||
|
||||
foreach (KeyValuePair<Type, object> pair in m_interfaces)
|
||||
{
|
||||
interfaces[i++] = pair.Key.FullName;
|
||||
}
|
||||
|
||||
return interfaces;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a registered interface availible to neighbouring regions.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of interface you wish to request</typeparam>
|
||||
/// <returns>A MarshalByRefObject inherited from this region inheriting the interface requested.</returns>
|
||||
/// <remarks>All registered interfaces <b>MUST</b> inherit from MarshalByRefObject and use only serialisable types.</remarks>
|
||||
public T RequestInterface<T>()
|
||||
{
|
||||
if (m_interfaces.ContainsKey(typeof (T)))
|
||||
return (T) m_interfaces[typeof (T)];
|
||||
|
||||
throw new NotSupportedException("No such interface registered.");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,283 +1,283 @@
|
|||
/*
|
||||
* 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.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using libsecondlife;
|
||||
using Nini.Config;
|
||||
using OpenJPEGNet;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Scripting.DynamicTexture
|
||||
{
|
||||
public class DynamicTextureModule : IRegionModule, IDynamicTextureManager
|
||||
{
|
||||
private Dictionary<LLUUID, Scene> RegisteredScenes = new Dictionary<LLUUID, Scene>();
|
||||
|
||||
private Dictionary<string, IDynamicTextureRender> RenderPlugins =
|
||||
new Dictionary<string, IDynamicTextureRender>();
|
||||
|
||||
private Dictionary<LLUUID, DynamicTextureUpdater> Updaters = new Dictionary<LLUUID, DynamicTextureUpdater>();
|
||||
|
||||
#region IDynamicTextureManager Members
|
||||
|
||||
public void RegisterRender(string handleType, IDynamicTextureRender render)
|
||||
{
|
||||
if (!RenderPlugins.ContainsKey(handleType))
|
||||
{
|
||||
RenderPlugins.Add(handleType, render);
|
||||
}
|
||||
}
|
||||
|
||||
public void ReturnData(LLUUID id, byte[] data)
|
||||
{
|
||||
if (Updaters.ContainsKey(id))
|
||||
{
|
||||
DynamicTextureUpdater updater = Updaters[id];
|
||||
if (RegisteredScenes.ContainsKey(updater.SimUUID))
|
||||
{
|
||||
Scene scene = RegisteredScenes[updater.SimUUID];
|
||||
updater.DataReceived(data, scene);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public LLUUID AddDynamicTextureURL(LLUUID simID, LLUUID primID, string contentType, string url,
|
||||
string extraParams, int updateTimer)
|
||||
{
|
||||
return AddDynamicTextureURL(simID, primID, contentType, url, extraParams, updateTimer, false, 255);
|
||||
}
|
||||
|
||||
public LLUUID AddDynamicTextureURL(LLUUID simID, LLUUID primID, string contentType, string url,
|
||||
string extraParams, int updateTimer, bool SetBlending, byte AlphaValue)
|
||||
{
|
||||
if (RenderPlugins.ContainsKey(contentType))
|
||||
{
|
||||
//Console.WriteLine("dynamic texture being created: " + url + " of type " + contentType);
|
||||
|
||||
DynamicTextureUpdater updater = new DynamicTextureUpdater();
|
||||
updater.SimUUID = simID;
|
||||
updater.PrimID = primID;
|
||||
updater.ContentType = contentType;
|
||||
updater.Url = url;
|
||||
updater.UpdateTimer = updateTimer;
|
||||
updater.UpdaterID = LLUUID.Random();
|
||||
updater.Params = extraParams;
|
||||
updater.BlendWithOldTexture = SetBlending;
|
||||
updater.FrontAlpha = AlphaValue;
|
||||
|
||||
if (!Updaters.ContainsKey(updater.UpdaterID))
|
||||
{
|
||||
Updaters.Add(updater.UpdaterID, updater);
|
||||
}
|
||||
|
||||
RenderPlugins[contentType].AsyncConvertUrl(updater.UpdaterID, url, extraParams);
|
||||
return updater.UpdaterID;
|
||||
}
|
||||
return LLUUID.Zero;
|
||||
}
|
||||
|
||||
public LLUUID AddDynamicTextureData(LLUUID simID, LLUUID primID, string contentType, string data,
|
||||
string extraParams, int updateTimer)
|
||||
{
|
||||
return AddDynamicTextureData(simID, primID, contentType, data, extraParams, updateTimer, false, 255);
|
||||
}
|
||||
|
||||
public LLUUID AddDynamicTextureData(LLUUID simID, LLUUID primID, string contentType, string data,
|
||||
string extraParams, int updateTimer, bool SetBlending, byte AlphaValue)
|
||||
{
|
||||
if (RenderPlugins.ContainsKey(contentType))
|
||||
{
|
||||
DynamicTextureUpdater updater = new DynamicTextureUpdater();
|
||||
updater.SimUUID = simID;
|
||||
updater.PrimID = primID;
|
||||
updater.ContentType = contentType;
|
||||
updater.BodyData = data;
|
||||
updater.UpdateTimer = updateTimer;
|
||||
updater.UpdaterID = LLUUID.Random();
|
||||
updater.Params = extraParams;
|
||||
updater.BlendWithOldTexture = SetBlending;
|
||||
updater.FrontAlpha = AlphaValue;
|
||||
|
||||
if (!Updaters.ContainsKey(updater.UpdaterID))
|
||||
{
|
||||
Updaters.Add(updater.UpdaterID, updater);
|
||||
}
|
||||
|
||||
RenderPlugins[contentType].AsyncConvertData(updater.UpdaterID, data, extraParams);
|
||||
return updater.UpdaterID;
|
||||
}
|
||||
return LLUUID.Zero;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource config)
|
||||
{
|
||||
if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID))
|
||||
{
|
||||
RegisteredScenes.Add(scene.RegionInfo.RegionID, scene);
|
||||
scene.RegisterModuleInterface<IDynamicTextureManager>(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "DynamicTextureModule"; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Nested type: DynamicTextureUpdater
|
||||
|
||||
public class DynamicTextureUpdater
|
||||
{
|
||||
public bool BlendWithOldTexture = false;
|
||||
public string BodyData;
|
||||
public string ContentType;
|
||||
public byte FrontAlpha = 255;
|
||||
public LLUUID LastAssetID;
|
||||
public string Params;
|
||||
public LLUUID PrimID;
|
||||
public bool SetNewFrontAlpha = false;
|
||||
public LLUUID SimUUID;
|
||||
public LLUUID UpdaterID;
|
||||
public int UpdateTimer;
|
||||
public string Url;
|
||||
|
||||
public DynamicTextureUpdater()
|
||||
{
|
||||
LastAssetID = LLUUID.Zero;
|
||||
UpdateTimer = 0;
|
||||
BodyData = null;
|
||||
}
|
||||
|
||||
public void DataReceived(byte[] data, Scene scene)
|
||||
{
|
||||
SceneObjectPart part = scene.GetSceneObjectPart(PrimID);
|
||||
byte[] assetData;
|
||||
AssetBase oldAsset = null;
|
||||
if (BlendWithOldTexture)
|
||||
{
|
||||
LLUUID lastTextureID = part.Shape.Textures.DefaultTexture.TextureID;
|
||||
oldAsset = scene.AssetCache.GetAsset(lastTextureID, true);
|
||||
if (oldAsset != null)
|
||||
{
|
||||
assetData = BlendTextures(data, oldAsset.Data, SetNewFrontAlpha, FrontAlpha);
|
||||
}
|
||||
else
|
||||
{
|
||||
assetData = new byte[data.Length];
|
||||
Array.Copy(data, assetData, data.Length);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
assetData = new byte[data.Length];
|
||||
Array.Copy(data, assetData, data.Length);
|
||||
}
|
||||
|
||||
//TODO delete the last asset(data), if it was a dynamic texture
|
||||
AssetBase asset = new AssetBase();
|
||||
asset.FullID = LLUUID.Random();
|
||||
asset.Data = assetData;
|
||||
asset.Name = "DynamicImage" + Util.RandomClass.Next(1, 10000);
|
||||
asset.Type = 0;
|
||||
asset.Description = "dynamic image";
|
||||
asset.Local = false;
|
||||
asset.Temporary = true;
|
||||
scene.AssetCache.AddAsset(asset);
|
||||
|
||||
LastAssetID = asset.FullID;
|
||||
|
||||
|
||||
part.Shape.Textures = new LLObject.TextureEntry(asset.FullID);
|
||||
part.ScheduleFullUpdate();
|
||||
}
|
||||
|
||||
private byte[] BlendTextures(byte[] frontImage, byte[] backImage, bool setNewAlpha, byte newAlpha)
|
||||
{
|
||||
Bitmap image1 = new Bitmap(OpenJPEG.DecodeToImage(frontImage));
|
||||
Bitmap image2 = new Bitmap(OpenJPEG.DecodeToImage(backImage));
|
||||
if (setNewAlpha)
|
||||
{
|
||||
SetAlpha(ref image1, newAlpha);
|
||||
}
|
||||
Bitmap joint = MergeBitMaps(image1, image2);
|
||||
|
||||
return OpenJPEG.EncodeFromImage(joint, true);
|
||||
}
|
||||
|
||||
public Bitmap MergeBitMaps(Bitmap front, Bitmap back)
|
||||
{
|
||||
Bitmap joint;
|
||||
Graphics jG;
|
||||
|
||||
joint = new Bitmap(back.Width, back.Height, PixelFormat.Format32bppArgb);
|
||||
jG = Graphics.FromImage(joint);
|
||||
|
||||
jG.DrawImage(back, 0, 0, back.Width, back.Height);
|
||||
jG.DrawImage(front, 0, 0, back.Width, back.Height);
|
||||
|
||||
return joint;
|
||||
}
|
||||
|
||||
private void SetAlpha(ref Bitmap b, byte alpha)
|
||||
{
|
||||
for (int w = 0; w < b.Width; w++)
|
||||
{
|
||||
for (int h = 0; h < b.Height; h++)
|
||||
{
|
||||
b.SetPixel(w, h, Color.FromArgb(alpha, b.GetPixel(w, h)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
/*
|
||||
* 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.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using libsecondlife;
|
||||
using Nini.Config;
|
||||
using OpenJPEGNet;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Scripting.DynamicTexture
|
||||
{
|
||||
public class DynamicTextureModule : IRegionModule, IDynamicTextureManager
|
||||
{
|
||||
private Dictionary<LLUUID, Scene> RegisteredScenes = new Dictionary<LLUUID, Scene>();
|
||||
|
||||
private Dictionary<string, IDynamicTextureRender> RenderPlugins =
|
||||
new Dictionary<string, IDynamicTextureRender>();
|
||||
|
||||
private Dictionary<LLUUID, DynamicTextureUpdater> Updaters = new Dictionary<LLUUID, DynamicTextureUpdater>();
|
||||
|
||||
#region IDynamicTextureManager Members
|
||||
|
||||
public void RegisterRender(string handleType, IDynamicTextureRender render)
|
||||
{
|
||||
if (!RenderPlugins.ContainsKey(handleType))
|
||||
{
|
||||
RenderPlugins.Add(handleType, render);
|
||||
}
|
||||
}
|
||||
|
||||
public void ReturnData(LLUUID id, byte[] data)
|
||||
{
|
||||
if (Updaters.ContainsKey(id))
|
||||
{
|
||||
DynamicTextureUpdater updater = Updaters[id];
|
||||
if (RegisteredScenes.ContainsKey(updater.SimUUID))
|
||||
{
|
||||
Scene scene = RegisteredScenes[updater.SimUUID];
|
||||
updater.DataReceived(data, scene);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public LLUUID AddDynamicTextureURL(LLUUID simID, LLUUID primID, string contentType, string url,
|
||||
string extraParams, int updateTimer)
|
||||
{
|
||||
return AddDynamicTextureURL(simID, primID, contentType, url, extraParams, updateTimer, false, 255);
|
||||
}
|
||||
|
||||
public LLUUID AddDynamicTextureURL(LLUUID simID, LLUUID primID, string contentType, string url,
|
||||
string extraParams, int updateTimer, bool SetBlending, byte AlphaValue)
|
||||
{
|
||||
if (RenderPlugins.ContainsKey(contentType))
|
||||
{
|
||||
//Console.WriteLine("dynamic texture being created: " + url + " of type " + contentType);
|
||||
|
||||
DynamicTextureUpdater updater = new DynamicTextureUpdater();
|
||||
updater.SimUUID = simID;
|
||||
updater.PrimID = primID;
|
||||
updater.ContentType = contentType;
|
||||
updater.Url = url;
|
||||
updater.UpdateTimer = updateTimer;
|
||||
updater.UpdaterID = LLUUID.Random();
|
||||
updater.Params = extraParams;
|
||||
updater.BlendWithOldTexture = SetBlending;
|
||||
updater.FrontAlpha = AlphaValue;
|
||||
|
||||
if (!Updaters.ContainsKey(updater.UpdaterID))
|
||||
{
|
||||
Updaters.Add(updater.UpdaterID, updater);
|
||||
}
|
||||
|
||||
RenderPlugins[contentType].AsyncConvertUrl(updater.UpdaterID, url, extraParams);
|
||||
return updater.UpdaterID;
|
||||
}
|
||||
return LLUUID.Zero;
|
||||
}
|
||||
|
||||
public LLUUID AddDynamicTextureData(LLUUID simID, LLUUID primID, string contentType, string data,
|
||||
string extraParams, int updateTimer)
|
||||
{
|
||||
return AddDynamicTextureData(simID, primID, contentType, data, extraParams, updateTimer, false, 255);
|
||||
}
|
||||
|
||||
public LLUUID AddDynamicTextureData(LLUUID simID, LLUUID primID, string contentType, string data,
|
||||
string extraParams, int updateTimer, bool SetBlending, byte AlphaValue)
|
||||
{
|
||||
if (RenderPlugins.ContainsKey(contentType))
|
||||
{
|
||||
DynamicTextureUpdater updater = new DynamicTextureUpdater();
|
||||
updater.SimUUID = simID;
|
||||
updater.PrimID = primID;
|
||||
updater.ContentType = contentType;
|
||||
updater.BodyData = data;
|
||||
updater.UpdateTimer = updateTimer;
|
||||
updater.UpdaterID = LLUUID.Random();
|
||||
updater.Params = extraParams;
|
||||
updater.BlendWithOldTexture = SetBlending;
|
||||
updater.FrontAlpha = AlphaValue;
|
||||
|
||||
if (!Updaters.ContainsKey(updater.UpdaterID))
|
||||
{
|
||||
Updaters.Add(updater.UpdaterID, updater);
|
||||
}
|
||||
|
||||
RenderPlugins[contentType].AsyncConvertData(updater.UpdaterID, data, extraParams);
|
||||
return updater.UpdaterID;
|
||||
}
|
||||
return LLUUID.Zero;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource config)
|
||||
{
|
||||
if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID))
|
||||
{
|
||||
RegisteredScenes.Add(scene.RegionInfo.RegionID, scene);
|
||||
scene.RegisterModuleInterface<IDynamicTextureManager>(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "DynamicTextureModule"; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Nested type: DynamicTextureUpdater
|
||||
|
||||
public class DynamicTextureUpdater
|
||||
{
|
||||
public bool BlendWithOldTexture = false;
|
||||
public string BodyData;
|
||||
public string ContentType;
|
||||
public byte FrontAlpha = 255;
|
||||
public LLUUID LastAssetID;
|
||||
public string Params;
|
||||
public LLUUID PrimID;
|
||||
public bool SetNewFrontAlpha = false;
|
||||
public LLUUID SimUUID;
|
||||
public LLUUID UpdaterID;
|
||||
public int UpdateTimer;
|
||||
public string Url;
|
||||
|
||||
public DynamicTextureUpdater()
|
||||
{
|
||||
LastAssetID = LLUUID.Zero;
|
||||
UpdateTimer = 0;
|
||||
BodyData = null;
|
||||
}
|
||||
|
||||
public void DataReceived(byte[] data, Scene scene)
|
||||
{
|
||||
SceneObjectPart part = scene.GetSceneObjectPart(PrimID);
|
||||
byte[] assetData;
|
||||
AssetBase oldAsset = null;
|
||||
if (BlendWithOldTexture)
|
||||
{
|
||||
LLUUID lastTextureID = part.Shape.Textures.DefaultTexture.TextureID;
|
||||
oldAsset = scene.AssetCache.GetAsset(lastTextureID, true);
|
||||
if (oldAsset != null)
|
||||
{
|
||||
assetData = BlendTextures(data, oldAsset.Data, SetNewFrontAlpha, FrontAlpha);
|
||||
}
|
||||
else
|
||||
{
|
||||
assetData = new byte[data.Length];
|
||||
Array.Copy(data, assetData, data.Length);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
assetData = new byte[data.Length];
|
||||
Array.Copy(data, assetData, data.Length);
|
||||
}
|
||||
|
||||
//TODO delete the last asset(data), if it was a dynamic texture
|
||||
AssetBase asset = new AssetBase();
|
||||
asset.FullID = LLUUID.Random();
|
||||
asset.Data = assetData;
|
||||
asset.Name = "DynamicImage" + Util.RandomClass.Next(1, 10000);
|
||||
asset.Type = 0;
|
||||
asset.Description = "dynamic image";
|
||||
asset.Local = false;
|
||||
asset.Temporary = true;
|
||||
scene.AssetCache.AddAsset(asset);
|
||||
|
||||
LastAssetID = asset.FullID;
|
||||
|
||||
|
||||
part.Shape.Textures = new LLObject.TextureEntry(asset.FullID);
|
||||
part.ScheduleFullUpdate();
|
||||
}
|
||||
|
||||
private byte[] BlendTextures(byte[] frontImage, byte[] backImage, bool setNewAlpha, byte newAlpha)
|
||||
{
|
||||
Bitmap image1 = new Bitmap(OpenJPEG.DecodeToImage(frontImage));
|
||||
Bitmap image2 = new Bitmap(OpenJPEG.DecodeToImage(backImage));
|
||||
if (setNewAlpha)
|
||||
{
|
||||
SetAlpha(ref image1, newAlpha);
|
||||
}
|
||||
Bitmap joint = MergeBitMaps(image1, image2);
|
||||
|
||||
return OpenJPEG.EncodeFromImage(joint, true);
|
||||
}
|
||||
|
||||
public Bitmap MergeBitMaps(Bitmap front, Bitmap back)
|
||||
{
|
||||
Bitmap joint;
|
||||
Graphics jG;
|
||||
|
||||
joint = new Bitmap(back.Width, back.Height, PixelFormat.Format32bppArgb);
|
||||
jG = Graphics.FromImage(joint);
|
||||
|
||||
jG.DrawImage(back, 0, 0, back.Width, back.Height);
|
||||
jG.DrawImage(front, 0, 0, back.Width, back.Height);
|
||||
|
||||
return joint;
|
||||
}
|
||||
|
||||
private void SetAlpha(ref Bitmap b, byte alpha)
|
||||
{
|
||||
for (int w = 0; w < b.Width; w++)
|
||||
{
|
||||
for (int h = 0; h < b.Height; h++)
|
||||
{
|
||||
b.SetPixel(w, h, Color.FromArgb(alpha, b.GetPixel(w, h)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -1,364 +1,364 @@
|
|||
/*
|
||||
* 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 libsecondlife;
|
||||
using Nini.Config;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
/*****************************************************
|
||||
*
|
||||
* ScriptsHttpRequests
|
||||
*
|
||||
* Implements the llHttpRequest and http_response
|
||||
* callback.
|
||||
*
|
||||
* Some stuff was already in LSLLongCmdHandler, and then
|
||||
* there was this file with a stub class in it. So,
|
||||
* I am moving some of the objects and functions out of
|
||||
* LSLLongCmdHandler, such as the HttpRequestClass, the
|
||||
* start and stop methods, and setting up pending and
|
||||
* completed queues. These are processed in the
|
||||
* LSLLongCmdHandler polling loop. Similiar to the
|
||||
* XMLRPCModule, since that seems to work.
|
||||
*
|
||||
* //TODO
|
||||
*
|
||||
* This probably needs some throttling mechanism but
|
||||
* its wide open right now. This applies to both
|
||||
* number of requests and data volume.
|
||||
*
|
||||
* Linden puts all kinds of header fields in the requests.
|
||||
* Not doing any of that:
|
||||
* User-Agent
|
||||
* X-SecondLife-Shard
|
||||
* X-SecondLife-Object-Name
|
||||
* X-SecondLife-Object-Key
|
||||
* X-SecondLife-Region
|
||||
* X-SecondLife-Local-Position
|
||||
* X-SecondLife-Local-Velocity
|
||||
* X-SecondLife-Local-Rotation
|
||||
* X-SecondLife-Owner-Name
|
||||
* X-SecondLife-Owner-Key
|
||||
*
|
||||
* HTTPS support
|
||||
*
|
||||
* Configurable timeout?
|
||||
* Configurable max repsonse size?
|
||||
* Configurable
|
||||
*
|
||||
* **************************************************/
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Scripting.HttpRequest
|
||||
{
|
||||
public class HttpRequestModule : IRegionModule, IHttpRequests
|
||||
{
|
||||
private object HttpListLock = new object();
|
||||
private int httpTimeout = 30000;
|
||||
private string m_name = "HttpScriptRequests";
|
||||
|
||||
// <request id, HttpRequestClass>
|
||||
private Dictionary<LLUUID, HttpRequestClass> m_pendingRequests;
|
||||
private Scene m_scene;
|
||||
private Queue<HttpRequestClass> rpcQueue = new Queue<HttpRequestClass>();
|
||||
|
||||
public HttpRequestModule()
|
||||
{
|
||||
}
|
||||
|
||||
#region IHttpRequests Members
|
||||
|
||||
public LLUUID MakeHttpRequest(string url, string parameters, string body)
|
||||
{
|
||||
return LLUUID.Zero;
|
||||
}
|
||||
|
||||
public LLUUID StartHttpRequest(uint localID, LLUUID itemID, string url, List<string> parameters, string body)
|
||||
{
|
||||
LLUUID reqID = LLUUID.Random();
|
||||
HttpRequestClass htc = new HttpRequestClass();
|
||||
|
||||
// Partial implementation: support for parameter flags needed
|
||||
// see http://wiki.secondlife.com/wiki/LlHTTPRequest
|
||||
//
|
||||
// Parameters are expected in {key, value, ... , key, value}
|
||||
if (parameters != null)
|
||||
{
|
||||
string[] parms = parameters.ToArray();
|
||||
for (int i = 0; i < parms.Length / 2; i += 2)
|
||||
{
|
||||
switch (Int32.Parse(parms[i]))
|
||||
{
|
||||
case HttpRequestClass.HTTP_METHOD:
|
||||
|
||||
htc.httpMethod = parms[i + 1];
|
||||
break;
|
||||
|
||||
case HttpRequestClass.HTTP_MIMETYPE:
|
||||
|
||||
htc.httpMIMEType = parms[i + 1];
|
||||
break;
|
||||
|
||||
case HttpRequestClass.HTTP_BODY_MAXLENGTH:
|
||||
|
||||
// TODO implement me
|
||||
break;
|
||||
|
||||
case HttpRequestClass.HTTP_VERIFY_CERT:
|
||||
|
||||
// TODO implement me
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
htc.localID = localID;
|
||||
htc.itemID = itemID;
|
||||
htc.url = url;
|
||||
htc.reqID = reqID;
|
||||
htc.httpTimeout = httpTimeout;
|
||||
htc.outbound_body = body;
|
||||
|
||||
lock (HttpListLock)
|
||||
{
|
||||
m_pendingRequests.Add(reqID, htc);
|
||||
}
|
||||
|
||||
htc.process();
|
||||
|
||||
return reqID;
|
||||
}
|
||||
|
||||
public void StopHttpRequest(uint m_localID, LLUUID m_itemID)
|
||||
{
|
||||
if (m_pendingRequests != null)
|
||||
{
|
||||
lock (HttpListLock)
|
||||
{
|
||||
HttpRequestClass tmpReq;
|
||||
if (m_pendingRequests.TryGetValue(m_itemID, out tmpReq))
|
||||
{
|
||||
tmpReq.Stop();
|
||||
m_pendingRequests.Remove(m_itemID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO
|
||||
* Not sure how important ordering is is here - the next first
|
||||
* one completed in the list is returned, based soley on its list
|
||||
* position, not the order in which the request was started or
|
||||
* finsihed. I thought about setting up a queue for this, but
|
||||
* it will need some refactoring and this works 'enough' right now
|
||||
*/
|
||||
|
||||
public HttpRequestClass GetNextCompletedRequest()
|
||||
{
|
||||
lock (HttpListLock)
|
||||
{
|
||||
foreach (LLUUID luid in m_pendingRequests.Keys)
|
||||
{
|
||||
HttpRequestClass tmpReq;
|
||||
|
||||
if (m_pendingRequests.TryGetValue(luid, out tmpReq))
|
||||
{
|
||||
if (tmpReq.finished)
|
||||
{
|
||||
return tmpReq;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void RemoveCompletedRequest(LLUUID id)
|
||||
{
|
||||
lock (HttpListLock)
|
||||
{
|
||||
HttpRequestClass tmpReq;
|
||||
if (m_pendingRequests.TryGetValue(id, out tmpReq))
|
||||
{
|
||||
tmpReq.Stop();
|
||||
tmpReq = null;
|
||||
m_pendingRequests.Remove(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource config)
|
||||
{
|
||||
m_scene = scene;
|
||||
|
||||
m_scene.RegisterModuleInterface<IHttpRequests>(this);
|
||||
|
||||
m_pendingRequests = new Dictionary<LLUUID, HttpRequestClass>();
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return m_name; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class HttpRequestClass
|
||||
{
|
||||
// Constants for parameters
|
||||
public const int HTTP_BODY_MAXLENGTH = 2;
|
||||
public const int HTTP_METHOD = 0;
|
||||
public const int HTTP_MIMETYPE = 1;
|
||||
public const int HTTP_VERIFY_CERT = 3;
|
||||
public bool finished;
|
||||
public int httpBodyMaxLen = 2048; // not implemented
|
||||
|
||||
// Parameter members and default values
|
||||
public string httpMethod = "GET";
|
||||
public string httpMIMEType = "text/plain;charset=utf-8";
|
||||
private Thread httpThread;
|
||||
public int httpTimeout;
|
||||
public bool httpVerifyCert = true; // not implemented
|
||||
|
||||
// Request info
|
||||
public LLUUID itemID;
|
||||
public uint localID;
|
||||
public DateTime next;
|
||||
public string outbound_body;
|
||||
public LLUUID reqID;
|
||||
public HttpWebRequest request;
|
||||
public string response_body;
|
||||
public List<string> response_metadata;
|
||||
public int status;
|
||||
public string url;
|
||||
|
||||
public void process()
|
||||
{
|
||||
httpThread = new Thread(SendRequest);
|
||||
httpThread.Name = "HttpRequestThread";
|
||||
httpThread.Priority = ThreadPriority.BelowNormal;
|
||||
httpThread.IsBackground = true;
|
||||
finished = false;
|
||||
httpThread.Start();
|
||||
ThreadTracker.Add(httpThread);
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: More work on the response codes. Right now
|
||||
* returning 200 for success or 499 for exception
|
||||
*/
|
||||
|
||||
public void SendRequest()
|
||||
{
|
||||
HttpWebResponse response = null;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
byte[] buf = new byte[8192];
|
||||
string tempString = null;
|
||||
int count = 0;
|
||||
|
||||
try
|
||||
{
|
||||
request = (HttpWebRequest)
|
||||
WebRequest.Create(url);
|
||||
request.Method = httpMethod;
|
||||
request.ContentType = httpMIMEType;
|
||||
|
||||
request.Timeout = httpTimeout;
|
||||
// execute the request
|
||||
response = (HttpWebResponse)
|
||||
request.GetResponse();
|
||||
|
||||
Stream resStream = response.GetResponseStream();
|
||||
|
||||
do
|
||||
{
|
||||
// fill the buffer with data
|
||||
count = resStream.Read(buf, 0, buf.Length);
|
||||
|
||||
// make sure we read some data
|
||||
if (count != 0)
|
||||
{
|
||||
// translate from bytes to ASCII text
|
||||
tempString = Encoding.UTF8.GetString(buf, 0, count);
|
||||
|
||||
// continue building the string
|
||||
sb.Append(tempString);
|
||||
}
|
||||
} while (count > 0); // any more data to read?
|
||||
|
||||
response_body = sb.ToString();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
status = 499;
|
||||
response_body = e.Message;
|
||||
finished = true;
|
||||
return;
|
||||
}
|
||||
|
||||
status = 200;
|
||||
finished = true;
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
try
|
||||
{
|
||||
httpThread.Abort();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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 libsecondlife;
|
||||
using Nini.Config;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
/*****************************************************
|
||||
*
|
||||
* ScriptsHttpRequests
|
||||
*
|
||||
* Implements the llHttpRequest and http_response
|
||||
* callback.
|
||||
*
|
||||
* Some stuff was already in LSLLongCmdHandler, and then
|
||||
* there was this file with a stub class in it. So,
|
||||
* I am moving some of the objects and functions out of
|
||||
* LSLLongCmdHandler, such as the HttpRequestClass, the
|
||||
* start and stop methods, and setting up pending and
|
||||
* completed queues. These are processed in the
|
||||
* LSLLongCmdHandler polling loop. Similiar to the
|
||||
* XMLRPCModule, since that seems to work.
|
||||
*
|
||||
* //TODO
|
||||
*
|
||||
* This probably needs some throttling mechanism but
|
||||
* its wide open right now. This applies to both
|
||||
* number of requests and data volume.
|
||||
*
|
||||
* Linden puts all kinds of header fields in the requests.
|
||||
* Not doing any of that:
|
||||
* User-Agent
|
||||
* X-SecondLife-Shard
|
||||
* X-SecondLife-Object-Name
|
||||
* X-SecondLife-Object-Key
|
||||
* X-SecondLife-Region
|
||||
* X-SecondLife-Local-Position
|
||||
* X-SecondLife-Local-Velocity
|
||||
* X-SecondLife-Local-Rotation
|
||||
* X-SecondLife-Owner-Name
|
||||
* X-SecondLife-Owner-Key
|
||||
*
|
||||
* HTTPS support
|
||||
*
|
||||
* Configurable timeout?
|
||||
* Configurable max repsonse size?
|
||||
* Configurable
|
||||
*
|
||||
* **************************************************/
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Scripting.HttpRequest
|
||||
{
|
||||
public class HttpRequestModule : IRegionModule, IHttpRequests
|
||||
{
|
||||
private object HttpListLock = new object();
|
||||
private int httpTimeout = 30000;
|
||||
private string m_name = "HttpScriptRequests";
|
||||
|
||||
// <request id, HttpRequestClass>
|
||||
private Dictionary<LLUUID, HttpRequestClass> m_pendingRequests;
|
||||
private Scene m_scene;
|
||||
private Queue<HttpRequestClass> rpcQueue = new Queue<HttpRequestClass>();
|
||||
|
||||
public HttpRequestModule()
|
||||
{
|
||||
}
|
||||
|
||||
#region IHttpRequests Members
|
||||
|
||||
public LLUUID MakeHttpRequest(string url, string parameters, string body)
|
||||
{
|
||||
return LLUUID.Zero;
|
||||
}
|
||||
|
||||
public LLUUID StartHttpRequest(uint localID, LLUUID itemID, string url, List<string> parameters, string body)
|
||||
{
|
||||
LLUUID reqID = LLUUID.Random();
|
||||
HttpRequestClass htc = new HttpRequestClass();
|
||||
|
||||
// Partial implementation: support for parameter flags needed
|
||||
// see http://wiki.secondlife.com/wiki/LlHTTPRequest
|
||||
//
|
||||
// Parameters are expected in {key, value, ... , key, value}
|
||||
if (parameters != null)
|
||||
{
|
||||
string[] parms = parameters.ToArray();
|
||||
for (int i = 0; i < parms.Length / 2; i += 2)
|
||||
{
|
||||
switch (Int32.Parse(parms[i]))
|
||||
{
|
||||
case HttpRequestClass.HTTP_METHOD:
|
||||
|
||||
htc.httpMethod = parms[i + 1];
|
||||
break;
|
||||
|
||||
case HttpRequestClass.HTTP_MIMETYPE:
|
||||
|
||||
htc.httpMIMEType = parms[i + 1];
|
||||
break;
|
||||
|
||||
case HttpRequestClass.HTTP_BODY_MAXLENGTH:
|
||||
|
||||
// TODO implement me
|
||||
break;
|
||||
|
||||
case HttpRequestClass.HTTP_VERIFY_CERT:
|
||||
|
||||
// TODO implement me
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
htc.localID = localID;
|
||||
htc.itemID = itemID;
|
||||
htc.url = url;
|
||||
htc.reqID = reqID;
|
||||
htc.httpTimeout = httpTimeout;
|
||||
htc.outbound_body = body;
|
||||
|
||||
lock (HttpListLock)
|
||||
{
|
||||
m_pendingRequests.Add(reqID, htc);
|
||||
}
|
||||
|
||||
htc.process();
|
||||
|
||||
return reqID;
|
||||
}
|
||||
|
||||
public void StopHttpRequest(uint m_localID, LLUUID m_itemID)
|
||||
{
|
||||
if (m_pendingRequests != null)
|
||||
{
|
||||
lock (HttpListLock)
|
||||
{
|
||||
HttpRequestClass tmpReq;
|
||||
if (m_pendingRequests.TryGetValue(m_itemID, out tmpReq))
|
||||
{
|
||||
tmpReq.Stop();
|
||||
m_pendingRequests.Remove(m_itemID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO
|
||||
* Not sure how important ordering is is here - the next first
|
||||
* one completed in the list is returned, based soley on its list
|
||||
* position, not the order in which the request was started or
|
||||
* finsihed. I thought about setting up a queue for this, but
|
||||
* it will need some refactoring and this works 'enough' right now
|
||||
*/
|
||||
|
||||
public HttpRequestClass GetNextCompletedRequest()
|
||||
{
|
||||
lock (HttpListLock)
|
||||
{
|
||||
foreach (LLUUID luid in m_pendingRequests.Keys)
|
||||
{
|
||||
HttpRequestClass tmpReq;
|
||||
|
||||
if (m_pendingRequests.TryGetValue(luid, out tmpReq))
|
||||
{
|
||||
if (tmpReq.finished)
|
||||
{
|
||||
return tmpReq;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void RemoveCompletedRequest(LLUUID id)
|
||||
{
|
||||
lock (HttpListLock)
|
||||
{
|
||||
HttpRequestClass tmpReq;
|
||||
if (m_pendingRequests.TryGetValue(id, out tmpReq))
|
||||
{
|
||||
tmpReq.Stop();
|
||||
tmpReq = null;
|
||||
m_pendingRequests.Remove(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource config)
|
||||
{
|
||||
m_scene = scene;
|
||||
|
||||
m_scene.RegisterModuleInterface<IHttpRequests>(this);
|
||||
|
||||
m_pendingRequests = new Dictionary<LLUUID, HttpRequestClass>();
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return m_name; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class HttpRequestClass
|
||||
{
|
||||
// Constants for parameters
|
||||
public const int HTTP_BODY_MAXLENGTH = 2;
|
||||
public const int HTTP_METHOD = 0;
|
||||
public const int HTTP_MIMETYPE = 1;
|
||||
public const int HTTP_VERIFY_CERT = 3;
|
||||
public bool finished;
|
||||
public int httpBodyMaxLen = 2048; // not implemented
|
||||
|
||||
// Parameter members and default values
|
||||
public string httpMethod = "GET";
|
||||
public string httpMIMEType = "text/plain;charset=utf-8";
|
||||
private Thread httpThread;
|
||||
public int httpTimeout;
|
||||
public bool httpVerifyCert = true; // not implemented
|
||||
|
||||
// Request info
|
||||
public LLUUID itemID;
|
||||
public uint localID;
|
||||
public DateTime next;
|
||||
public string outbound_body;
|
||||
public LLUUID reqID;
|
||||
public HttpWebRequest request;
|
||||
public string response_body;
|
||||
public List<string> response_metadata;
|
||||
public int status;
|
||||
public string url;
|
||||
|
||||
public void process()
|
||||
{
|
||||
httpThread = new Thread(SendRequest);
|
||||
httpThread.Name = "HttpRequestThread";
|
||||
httpThread.Priority = ThreadPriority.BelowNormal;
|
||||
httpThread.IsBackground = true;
|
||||
finished = false;
|
||||
httpThread.Start();
|
||||
ThreadTracker.Add(httpThread);
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: More work on the response codes. Right now
|
||||
* returning 200 for success or 499 for exception
|
||||
*/
|
||||
|
||||
public void SendRequest()
|
||||
{
|
||||
HttpWebResponse response = null;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
byte[] buf = new byte[8192];
|
||||
string tempString = null;
|
||||
int count = 0;
|
||||
|
||||
try
|
||||
{
|
||||
request = (HttpWebRequest)
|
||||
WebRequest.Create(url);
|
||||
request.Method = httpMethod;
|
||||
request.ContentType = httpMIMEType;
|
||||
|
||||
request.Timeout = httpTimeout;
|
||||
// execute the request
|
||||
response = (HttpWebResponse)
|
||||
request.GetResponse();
|
||||
|
||||
Stream resStream = response.GetResponseStream();
|
||||
|
||||
do
|
||||
{
|
||||
// fill the buffer with data
|
||||
count = resStream.Read(buf, 0, buf.Length);
|
||||
|
||||
// make sure we read some data
|
||||
if (count != 0)
|
||||
{
|
||||
// translate from bytes to ASCII text
|
||||
tempString = Encoding.UTF8.GetString(buf, 0, count);
|
||||
|
||||
// continue building the string
|
||||
sb.Append(tempString);
|
||||
}
|
||||
} while (count > 0); // any more data to read?
|
||||
|
||||
response_body = sb.ToString();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
status = 499;
|
||||
response_body = e.Message;
|
||||
finished = true;
|
||||
return;
|
||||
}
|
||||
|
||||
status = 200;
|
||||
finished = true;
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
try
|
||||
{
|
||||
httpThread.Abort();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,191 +1,191 @@
|
|||
/*
|
||||
* 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.Drawing;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using libsecondlife;
|
||||
using Nini.Config;
|
||||
using OpenJPEGNet;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Scripting.LoadImageURL
|
||||
{
|
||||
public class LoadImageURLModule : IRegionModule, IDynamicTextureRender
|
||||
{
|
||||
private string m_name = "LoadImageURL";
|
||||
private Scene m_scene;
|
||||
private IDynamicTextureManager m_textureManager;
|
||||
|
||||
#region IDynamicTextureRender Members
|
||||
|
||||
public string GetName()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
public string GetContentType()
|
||||
{
|
||||
return ("image");
|
||||
}
|
||||
|
||||
public bool SupportsAsynchronous()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public byte[] ConvertUrl(string url, string extraParams)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public byte[] ConvertStream(Stream data, string extraParams)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool AsyncConvertUrl(LLUUID id, string url, string extraParams)
|
||||
{
|
||||
MakeHttpRequest(url, id);
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool AsyncConvertData(LLUUID id, string bodyData, string extraParams)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource config)
|
||||
{
|
||||
if (m_scene == null)
|
||||
{
|
||||
m_scene = scene;
|
||||
}
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
m_textureManager = m_scene.RequestModuleInterface<IDynamicTextureManager>();
|
||||
if (m_textureManager != null)
|
||||
{
|
||||
m_textureManager.RegisterRender(GetContentType(), this);
|
||||
}
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return m_name; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void MakeHttpRequest(string url, LLUUID requestID)
|
||||
{
|
||||
WebRequest request = HttpWebRequest.Create(url);
|
||||
RequestState state = new RequestState((HttpWebRequest) request, requestID);
|
||||
IAsyncResult result = request.BeginGetResponse(new AsyncCallback(HttpRequestReturn), state);
|
||||
|
||||
TimeSpan t = (DateTime.UtcNow - new DateTime(1970, 1, 1));
|
||||
state.TimeOfRequest = (int) t.TotalSeconds;
|
||||
}
|
||||
|
||||
private void HttpRequestReturn(IAsyncResult result)
|
||||
{
|
||||
RequestState state = (RequestState) result.AsyncState;
|
||||
WebRequest request = (WebRequest) state.Request;
|
||||
HttpWebResponse response = (HttpWebResponse) request.EndGetResponse(result);
|
||||
if (response.StatusCode == HttpStatusCode.OK)
|
||||
{
|
||||
Bitmap image = new Bitmap(response.GetResponseStream());
|
||||
Size newsize;
|
||||
|
||||
// TODO: make this a bit less hard coded
|
||||
if ((image.Height < 64) && (image.Width < 64))
|
||||
{
|
||||
newsize = new Size(32, 32);
|
||||
}
|
||||
else if ((image.Height < 128) && (image.Width < 128))
|
||||
{
|
||||
newsize = new Size(64, 64);
|
||||
}
|
||||
else if ((image.Height < 256) && (image.Width < 256))
|
||||
{
|
||||
newsize = new Size(128, 128);
|
||||
}
|
||||
else if ((image.Height < 512 && image.Width < 512))
|
||||
{
|
||||
newsize = new Size(256, 256);
|
||||
}
|
||||
else if ((image.Height < 1024 && image.Width < 1024))
|
||||
{
|
||||
newsize = new Size(512, 512);
|
||||
}
|
||||
else
|
||||
{
|
||||
newsize = new Size(1024, 1024);
|
||||
}
|
||||
|
||||
Bitmap resize = new Bitmap(image, newsize);
|
||||
byte[] imageJ2000 = OpenJPEG.EncodeFromImage(resize, true);
|
||||
|
||||
m_textureManager.ReturnData(state.RequestID, imageJ2000);
|
||||
}
|
||||
}
|
||||
|
||||
#region Nested type: RequestState
|
||||
|
||||
public class RequestState
|
||||
{
|
||||
public HttpWebRequest Request = null;
|
||||
public LLUUID RequestID = LLUUID.Zero;
|
||||
public int TimeOfRequest = 0;
|
||||
|
||||
public RequestState(HttpWebRequest request, LLUUID requestID)
|
||||
{
|
||||
Request = request;
|
||||
RequestID = requestID;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
/*
|
||||
* 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.Drawing;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using libsecondlife;
|
||||
using Nini.Config;
|
||||
using OpenJPEGNet;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Scripting.LoadImageURL
|
||||
{
|
||||
public class LoadImageURLModule : IRegionModule, IDynamicTextureRender
|
||||
{
|
||||
private string m_name = "LoadImageURL";
|
||||
private Scene m_scene;
|
||||
private IDynamicTextureManager m_textureManager;
|
||||
|
||||
#region IDynamicTextureRender Members
|
||||
|
||||
public string GetName()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
public string GetContentType()
|
||||
{
|
||||
return ("image");
|
||||
}
|
||||
|
||||
public bool SupportsAsynchronous()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public byte[] ConvertUrl(string url, string extraParams)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public byte[] ConvertStream(Stream data, string extraParams)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool AsyncConvertUrl(LLUUID id, string url, string extraParams)
|
||||
{
|
||||
MakeHttpRequest(url, id);
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool AsyncConvertData(LLUUID id, string bodyData, string extraParams)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource config)
|
||||
{
|
||||
if (m_scene == null)
|
||||
{
|
||||
m_scene = scene;
|
||||
}
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
m_textureManager = m_scene.RequestModuleInterface<IDynamicTextureManager>();
|
||||
if (m_textureManager != null)
|
||||
{
|
||||
m_textureManager.RegisterRender(GetContentType(), this);
|
||||
}
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return m_name; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void MakeHttpRequest(string url, LLUUID requestID)
|
||||
{
|
||||
WebRequest request = HttpWebRequest.Create(url);
|
||||
RequestState state = new RequestState((HttpWebRequest) request, requestID);
|
||||
IAsyncResult result = request.BeginGetResponse(new AsyncCallback(HttpRequestReturn), state);
|
||||
|
||||
TimeSpan t = (DateTime.UtcNow - new DateTime(1970, 1, 1));
|
||||
state.TimeOfRequest = (int) t.TotalSeconds;
|
||||
}
|
||||
|
||||
private void HttpRequestReturn(IAsyncResult result)
|
||||
{
|
||||
RequestState state = (RequestState) result.AsyncState;
|
||||
WebRequest request = (WebRequest) state.Request;
|
||||
HttpWebResponse response = (HttpWebResponse) request.EndGetResponse(result);
|
||||
if (response.StatusCode == HttpStatusCode.OK)
|
||||
{
|
||||
Bitmap image = new Bitmap(response.GetResponseStream());
|
||||
Size newsize;
|
||||
|
||||
// TODO: make this a bit less hard coded
|
||||
if ((image.Height < 64) && (image.Width < 64))
|
||||
{
|
||||
newsize = new Size(32, 32);
|
||||
}
|
||||
else if ((image.Height < 128) && (image.Width < 128))
|
||||
{
|
||||
newsize = new Size(64, 64);
|
||||
}
|
||||
else if ((image.Height < 256) && (image.Width < 256))
|
||||
{
|
||||
newsize = new Size(128, 128);
|
||||
}
|
||||
else if ((image.Height < 512 && image.Width < 512))
|
||||
{
|
||||
newsize = new Size(256, 256);
|
||||
}
|
||||
else if ((image.Height < 1024 && image.Width < 1024))
|
||||
{
|
||||
newsize = new Size(512, 512);
|
||||
}
|
||||
else
|
||||
{
|
||||
newsize = new Size(1024, 1024);
|
||||
}
|
||||
|
||||
Bitmap resize = new Bitmap(image, newsize);
|
||||
byte[] imageJ2000 = OpenJPEG.EncodeFromImage(resize, true);
|
||||
|
||||
m_textureManager.ReturnData(state.RequestID, imageJ2000);
|
||||
}
|
||||
}
|
||||
|
||||
#region Nested type: RequestState
|
||||
|
||||
public class RequestState
|
||||
{
|
||||
public HttpWebRequest Request = null;
|
||||
public LLUUID RequestID = LLUUID.Zero;
|
||||
public int TimeOfRequest = 0;
|
||||
|
||||
public RequestState(HttpWebRequest request, LLUUID requestID)
|
||||
{
|
||||
Request = request;
|
||||
RequestID = requestID;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -1,369 +1,369 @@
|
|||
/*
|
||||
* 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.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using libsecondlife;
|
||||
using Nini.Config;
|
||||
using OpenJPEGNet;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
using Image=System.Drawing.Image;
|
||||
|
||||
//using Cairo;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Scripting.VectorRender
|
||||
{
|
||||
public class VectorRenderModule : IRegionModule, IDynamicTextureRender
|
||||
{
|
||||
private string m_name = "VectorRenderModule";
|
||||
private Scene m_scene;
|
||||
private IDynamicTextureManager m_textureManager;
|
||||
|
||||
public VectorRenderModule()
|
||||
{
|
||||
}
|
||||
|
||||
#region IDynamicTextureRender Members
|
||||
|
||||
public string GetContentType()
|
||||
{
|
||||
return ("vector");
|
||||
}
|
||||
|
||||
public string GetName()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
public bool SupportsAsynchronous()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public byte[] ConvertUrl(string url, string extraParams)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public byte[] ConvertStream(Stream data, string extraParams)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool AsyncConvertUrl(LLUUID id, string url, string extraParams)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool AsyncConvertData(LLUUID id, string bodyData, string extraParams)
|
||||
{
|
||||
Draw(bodyData, id, extraParams);
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource config)
|
||||
{
|
||||
if (m_scene == null)
|
||||
{
|
||||
m_scene = scene;
|
||||
}
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
m_textureManager = m_scene.RequestModuleInterface<IDynamicTextureManager>();
|
||||
if (m_textureManager != null)
|
||||
{
|
||||
m_textureManager.RegisterRender(GetContentType(), this);
|
||||
}
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return m_name; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void Draw(string data, LLUUID id, string extraParams)
|
||||
{
|
||||
// TODO: this is a brutal hack. extraParams should actually be parsed reasonably.
|
||||
int size = 256;
|
||||
try
|
||||
{
|
||||
size = Convert.ToInt32(extraParams);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
//Ckrinke: Add a WriteLine to remove the warning about 'e' defined but not used
|
||||
Console.WriteLine("Problem with Draw. Please verify parameters." + e.ToString());
|
||||
}
|
||||
|
||||
if ((size < 128) || (size > 1024))
|
||||
size = 256;
|
||||
|
||||
Bitmap bitmap = new Bitmap(size, size, PixelFormat.Format32bppArgb);
|
||||
|
||||
Graphics graph = Graphics.FromImage(bitmap);
|
||||
|
||||
extraParams = extraParams.ToLower();
|
||||
int alpha = 255;
|
||||
if (extraParams == "setalpha")
|
||||
{
|
||||
alpha = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
graph.FillRectangle(new SolidBrush(Color.White), 0, 0, size, size);
|
||||
}
|
||||
|
||||
for (int w = 0; w < bitmap.Width; w++)
|
||||
{
|
||||
for (int h = 0; h < bitmap.Height; h++)
|
||||
{
|
||||
bitmap.SetPixel(w, h, Color.FromArgb(alpha, bitmap.GetPixel(w, h)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GDIDraw(data, graph);
|
||||
|
||||
byte[] imageJ2000 = OpenJPEG.EncodeFromImage(bitmap, true);
|
||||
m_textureManager.ReturnData(id, imageJ2000);
|
||||
}
|
||||
|
||||
/*
|
||||
private void CairoDraw(string data, System.Drawing.Graphics graph)
|
||||
{
|
||||
using (Win32Surface draw = new Win32Surface(graph.GetHdc()))
|
||||
{
|
||||
Context contex = new Context(draw);
|
||||
|
||||
contex.Antialias = Antialias.None; //fastest method but low quality
|
||||
contex.LineWidth = 7;
|
||||
char[] lineDelimiter = { ';' };
|
||||
char[] partsDelimiter = { ',' };
|
||||
string[] lines = data.Split(lineDelimiter);
|
||||
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string nextLine = line.Trim();
|
||||
|
||||
if (nextLine.StartsWith("MoveTO"))
|
||||
{
|
||||
float x = 0;
|
||||
float y = 0;
|
||||
GetParams(partsDelimiter, ref nextLine, ref x, ref y);
|
||||
contex.MoveTo(x, y);
|
||||
}
|
||||
else if (nextLine.StartsWith("LineTo"))
|
||||
{
|
||||
float x = 0;
|
||||
float y = 0;
|
||||
GetParams(partsDelimiter, ref nextLine, ref x, ref y);
|
||||
contex.LineTo(x, y);
|
||||
contex.Stroke();
|
||||
}
|
||||
}
|
||||
}
|
||||
graph.ReleaseHdc();
|
||||
}
|
||||
*/
|
||||
|
||||
private void GDIDraw(string data, Graphics graph)
|
||||
{
|
||||
Point startPoint = new Point(0, 0);
|
||||
Point endPoint = new Point(0, 0);
|
||||
Pen drawPen = new Pen(Color.Black, 7);
|
||||
Font myFont = new Font("Times New Roman", 14);
|
||||
SolidBrush myBrush = new SolidBrush(Color.Black);
|
||||
char[] lineDelimiter = {';'};
|
||||
char[] partsDelimiter = {','};
|
||||
string[] lines = data.Split(lineDelimiter);
|
||||
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string nextLine = line.Trim();
|
||||
//replace with switch, or even better, do some proper parsing
|
||||
if (nextLine.StartsWith("MoveTo"))
|
||||
{
|
||||
float x = 0;
|
||||
float y = 0;
|
||||
GetParams(partsDelimiter, ref nextLine, 6, ref x, ref y);
|
||||
startPoint.X = (int) x;
|
||||
startPoint.Y = (int) y;
|
||||
}
|
||||
else if (nextLine.StartsWith("LineTo"))
|
||||
{
|
||||
float x = 0;
|
||||
float y = 0;
|
||||
GetParams(partsDelimiter, ref nextLine, 6, ref x, ref y);
|
||||
endPoint.X = (int) x;
|
||||
endPoint.Y = (int) y;
|
||||
graph.DrawLine(drawPen, startPoint, endPoint);
|
||||
startPoint.X = endPoint.X;
|
||||
startPoint.Y = endPoint.Y;
|
||||
}
|
||||
else if (nextLine.StartsWith("Text"))
|
||||
{
|
||||
nextLine = nextLine.Remove(0, 4);
|
||||
nextLine = nextLine.Trim();
|
||||
graph.DrawString(nextLine, myFont, myBrush, startPoint);
|
||||
}
|
||||
else if (nextLine.StartsWith("Image"))
|
||||
{
|
||||
float x = 0;
|
||||
float y = 0;
|
||||
GetParams(partsDelimiter, ref nextLine, 5, ref x, ref y);
|
||||
endPoint.X = (int) x;
|
||||
endPoint.Y = (int) y;
|
||||
Image image = ImageHttpRequest(nextLine);
|
||||
graph.DrawImage(image, (float) startPoint.X, (float) startPoint.Y, x, y);
|
||||
startPoint.X += endPoint.X;
|
||||
startPoint.Y += endPoint.Y;
|
||||
}
|
||||
else if (nextLine.StartsWith("Rectangle"))
|
||||
{
|
||||
float x = 0;
|
||||
float y = 0;
|
||||
GetParams(partsDelimiter, ref nextLine, 9, ref x, ref y);
|
||||
endPoint.X = (int) x;
|
||||
endPoint.Y = (int) y;
|
||||
graph.DrawRectangle(drawPen, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y);
|
||||
startPoint.X += endPoint.X;
|
||||
startPoint.Y += endPoint.Y;
|
||||
}
|
||||
else if (nextLine.StartsWith("FillRectangle"))
|
||||
{
|
||||
float x = 0;
|
||||
float y = 0;
|
||||
GetParams(partsDelimiter, ref nextLine, 13, ref x, ref y);
|
||||
endPoint.X = (int) x;
|
||||
endPoint.Y = (int) y;
|
||||
graph.FillRectangle(myBrush, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y);
|
||||
startPoint.X += endPoint.X;
|
||||
startPoint.Y += endPoint.Y;
|
||||
}
|
||||
else if (nextLine.StartsWith("Ellipse"))
|
||||
{
|
||||
float x = 0;
|
||||
float y = 0;
|
||||
GetParams(partsDelimiter, ref nextLine, 7, ref x, ref y);
|
||||
endPoint.X = (int) x;
|
||||
endPoint.Y = (int) y;
|
||||
graph.DrawEllipse(drawPen, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y);
|
||||
startPoint.X += endPoint.X;
|
||||
startPoint.Y += endPoint.Y;
|
||||
}
|
||||
else if (nextLine.StartsWith("FontSize"))
|
||||
{
|
||||
nextLine = nextLine.Remove(0, 8);
|
||||
nextLine = nextLine.Trim();
|
||||
float size = Convert.ToSingle(nextLine, CultureInfo.InvariantCulture);
|
||||
myFont = new Font("Times New Roman", size);
|
||||
}
|
||||
else if (nextLine.StartsWith("PenSize"))
|
||||
{
|
||||
nextLine = nextLine.Remove(0, 8);
|
||||
nextLine = nextLine.Trim();
|
||||
float size = Convert.ToSingle(nextLine, CultureInfo.InvariantCulture);
|
||||
drawPen.Width = size;
|
||||
}
|
||||
else if (nextLine.StartsWith("PenColour"))
|
||||
{
|
||||
nextLine = nextLine.Remove(0, 9);
|
||||
nextLine = nextLine.Trim();
|
||||
|
||||
Color newColour = Color.FromName(nextLine);
|
||||
|
||||
myBrush.Color = newColour;
|
||||
drawPen.Color = newColour;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void GetParams(char[] partsDelimiter, ref string line, int startLength, ref float x, ref float y)
|
||||
{
|
||||
line = line.Remove(0, startLength);
|
||||
string[] parts = line.Split(partsDelimiter);
|
||||
if (parts.Length == 2)
|
||||
{
|
||||
string xVal = parts[0].Trim();
|
||||
string yVal = parts[1].Trim();
|
||||
x = Convert.ToSingle(xVal, CultureInfo.InvariantCulture);
|
||||
y = Convert.ToSingle(yVal, CultureInfo.InvariantCulture);
|
||||
}
|
||||
else if (parts.Length > 2)
|
||||
{
|
||||
string xVal = parts[0].Trim();
|
||||
string yVal = parts[1].Trim();
|
||||
x = Convert.ToSingle(xVal, CultureInfo.InvariantCulture);
|
||||
y = Convert.ToSingle(yVal, CultureInfo.InvariantCulture);
|
||||
|
||||
line = "";
|
||||
for (int i = 2; i < parts.Length; i++)
|
||||
{
|
||||
line = line + parts[i].Trim();
|
||||
line = line + " ";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Bitmap ImageHttpRequest(string url)
|
||||
{
|
||||
WebRequest request = HttpWebRequest.Create(url);
|
||||
//Ckrinke: Comment out for now as 'str' is unused. Bring it back into play later when it is used.
|
||||
//Ckrinke Stream str = null;
|
||||
HttpWebResponse response = (HttpWebResponse) (request).GetResponse();
|
||||
if (response.StatusCode == HttpStatusCode.OK)
|
||||
{
|
||||
Bitmap image = new Bitmap(response.GetResponseStream());
|
||||
return image;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using libsecondlife;
|
||||
using Nini.Config;
|
||||
using OpenJPEGNet;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
using Image=System.Drawing.Image;
|
||||
|
||||
//using Cairo;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.Scripting.VectorRender
|
||||
{
|
||||
public class VectorRenderModule : IRegionModule, IDynamicTextureRender
|
||||
{
|
||||
private string m_name = "VectorRenderModule";
|
||||
private Scene m_scene;
|
||||
private IDynamicTextureManager m_textureManager;
|
||||
|
||||
public VectorRenderModule()
|
||||
{
|
||||
}
|
||||
|
||||
#region IDynamicTextureRender Members
|
||||
|
||||
public string GetContentType()
|
||||
{
|
||||
return ("vector");
|
||||
}
|
||||
|
||||
public string GetName()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
public bool SupportsAsynchronous()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public byte[] ConvertUrl(string url, string extraParams)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public byte[] ConvertStream(Stream data, string extraParams)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool AsyncConvertUrl(LLUUID id, string url, string extraParams)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool AsyncConvertData(LLUUID id, string bodyData, string extraParams)
|
||||
{
|
||||
Draw(bodyData, id, extraParams);
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource config)
|
||||
{
|
||||
if (m_scene == null)
|
||||
{
|
||||
m_scene = scene;
|
||||
}
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
m_textureManager = m_scene.RequestModuleInterface<IDynamicTextureManager>();
|
||||
if (m_textureManager != null)
|
||||
{
|
||||
m_textureManager.RegisterRender(GetContentType(), this);
|
||||
}
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return m_name; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void Draw(string data, LLUUID id, string extraParams)
|
||||
{
|
||||
// TODO: this is a brutal hack. extraParams should actually be parsed reasonably.
|
||||
int size = 256;
|
||||
try
|
||||
{
|
||||
size = Convert.ToInt32(extraParams);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
//Ckrinke: Add a WriteLine to remove the warning about 'e' defined but not used
|
||||
Console.WriteLine("Problem with Draw. Please verify parameters." + e.ToString());
|
||||
}
|
||||
|
||||
if ((size < 128) || (size > 1024))
|
||||
size = 256;
|
||||
|
||||
Bitmap bitmap = new Bitmap(size, size, PixelFormat.Format32bppArgb);
|
||||
|
||||
Graphics graph = Graphics.FromImage(bitmap);
|
||||
|
||||
extraParams = extraParams.ToLower();
|
||||
int alpha = 255;
|
||||
if (extraParams == "setalpha")
|
||||
{
|
||||
alpha = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
graph.FillRectangle(new SolidBrush(Color.White), 0, 0, size, size);
|
||||
}
|
||||
|
||||
for (int w = 0; w < bitmap.Width; w++)
|
||||
{
|
||||
for (int h = 0; h < bitmap.Height; h++)
|
||||
{
|
||||
bitmap.SetPixel(w, h, Color.FromArgb(alpha, bitmap.GetPixel(w, h)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GDIDraw(data, graph);
|
||||
|
||||
byte[] imageJ2000 = OpenJPEG.EncodeFromImage(bitmap, true);
|
||||
m_textureManager.ReturnData(id, imageJ2000);
|
||||
}
|
||||
|
||||
/*
|
||||
private void CairoDraw(string data, System.Drawing.Graphics graph)
|
||||
{
|
||||
using (Win32Surface draw = new Win32Surface(graph.GetHdc()))
|
||||
{
|
||||
Context contex = new Context(draw);
|
||||
|
||||
contex.Antialias = Antialias.None; //fastest method but low quality
|
||||
contex.LineWidth = 7;
|
||||
char[] lineDelimiter = { ';' };
|
||||
char[] partsDelimiter = { ',' };
|
||||
string[] lines = data.Split(lineDelimiter);
|
||||
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string nextLine = line.Trim();
|
||||
|
||||
if (nextLine.StartsWith("MoveTO"))
|
||||
{
|
||||
float x = 0;
|
||||
float y = 0;
|
||||
GetParams(partsDelimiter, ref nextLine, ref x, ref y);
|
||||
contex.MoveTo(x, y);
|
||||
}
|
||||
else if (nextLine.StartsWith("LineTo"))
|
||||
{
|
||||
float x = 0;
|
||||
float y = 0;
|
||||
GetParams(partsDelimiter, ref nextLine, ref x, ref y);
|
||||
contex.LineTo(x, y);
|
||||
contex.Stroke();
|
||||
}
|
||||
}
|
||||
}
|
||||
graph.ReleaseHdc();
|
||||
}
|
||||
*/
|
||||
|
||||
private void GDIDraw(string data, Graphics graph)
|
||||
{
|
||||
Point startPoint = new Point(0, 0);
|
||||
Point endPoint = new Point(0, 0);
|
||||
Pen drawPen = new Pen(Color.Black, 7);
|
||||
Font myFont = new Font("Times New Roman", 14);
|
||||
SolidBrush myBrush = new SolidBrush(Color.Black);
|
||||
char[] lineDelimiter = {';'};
|
||||
char[] partsDelimiter = {','};
|
||||
string[] lines = data.Split(lineDelimiter);
|
||||
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string nextLine = line.Trim();
|
||||
//replace with switch, or even better, do some proper parsing
|
||||
if (nextLine.StartsWith("MoveTo"))
|
||||
{
|
||||
float x = 0;
|
||||
float y = 0;
|
||||
GetParams(partsDelimiter, ref nextLine, 6, ref x, ref y);
|
||||
startPoint.X = (int) x;
|
||||
startPoint.Y = (int) y;
|
||||
}
|
||||
else if (nextLine.StartsWith("LineTo"))
|
||||
{
|
||||
float x = 0;
|
||||
float y = 0;
|
||||
GetParams(partsDelimiter, ref nextLine, 6, ref x, ref y);
|
||||
endPoint.X = (int) x;
|
||||
endPoint.Y = (int) y;
|
||||
graph.DrawLine(drawPen, startPoint, endPoint);
|
||||
startPoint.X = endPoint.X;
|
||||
startPoint.Y = endPoint.Y;
|
||||
}
|
||||
else if (nextLine.StartsWith("Text"))
|
||||
{
|
||||
nextLine = nextLine.Remove(0, 4);
|
||||
nextLine = nextLine.Trim();
|
||||
graph.DrawString(nextLine, myFont, myBrush, startPoint);
|
||||
}
|
||||
else if (nextLine.StartsWith("Image"))
|
||||
{
|
||||
float x = 0;
|
||||
float y = 0;
|
||||
GetParams(partsDelimiter, ref nextLine, 5, ref x, ref y);
|
||||
endPoint.X = (int) x;
|
||||
endPoint.Y = (int) y;
|
||||
Image image = ImageHttpRequest(nextLine);
|
||||
graph.DrawImage(image, (float) startPoint.X, (float) startPoint.Y, x, y);
|
||||
startPoint.X += endPoint.X;
|
||||
startPoint.Y += endPoint.Y;
|
||||
}
|
||||
else if (nextLine.StartsWith("Rectangle"))
|
||||
{
|
||||
float x = 0;
|
||||
float y = 0;
|
||||
GetParams(partsDelimiter, ref nextLine, 9, ref x, ref y);
|
||||
endPoint.X = (int) x;
|
||||
endPoint.Y = (int) y;
|
||||
graph.DrawRectangle(drawPen, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y);
|
||||
startPoint.X += endPoint.X;
|
||||
startPoint.Y += endPoint.Y;
|
||||
}
|
||||
else if (nextLine.StartsWith("FillRectangle"))
|
||||
{
|
||||
float x = 0;
|
||||
float y = 0;
|
||||
GetParams(partsDelimiter, ref nextLine, 13, ref x, ref y);
|
||||
endPoint.X = (int) x;
|
||||
endPoint.Y = (int) y;
|
||||
graph.FillRectangle(myBrush, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y);
|
||||
startPoint.X += endPoint.X;
|
||||
startPoint.Y += endPoint.Y;
|
||||
}
|
||||
else if (nextLine.StartsWith("Ellipse"))
|
||||
{
|
||||
float x = 0;
|
||||
float y = 0;
|
||||
GetParams(partsDelimiter, ref nextLine, 7, ref x, ref y);
|
||||
endPoint.X = (int) x;
|
||||
endPoint.Y = (int) y;
|
||||
graph.DrawEllipse(drawPen, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y);
|
||||
startPoint.X += endPoint.X;
|
||||
startPoint.Y += endPoint.Y;
|
||||
}
|
||||
else if (nextLine.StartsWith("FontSize"))
|
||||
{
|
||||
nextLine = nextLine.Remove(0, 8);
|
||||
nextLine = nextLine.Trim();
|
||||
float size = Convert.ToSingle(nextLine, CultureInfo.InvariantCulture);
|
||||
myFont = new Font("Times New Roman", size);
|
||||
}
|
||||
else if (nextLine.StartsWith("PenSize"))
|
||||
{
|
||||
nextLine = nextLine.Remove(0, 8);
|
||||
nextLine = nextLine.Trim();
|
||||
float size = Convert.ToSingle(nextLine, CultureInfo.InvariantCulture);
|
||||
drawPen.Width = size;
|
||||
}
|
||||
else if (nextLine.StartsWith("PenColour"))
|
||||
{
|
||||
nextLine = nextLine.Remove(0, 9);
|
||||
nextLine = nextLine.Trim();
|
||||
|
||||
Color newColour = Color.FromName(nextLine);
|
||||
|
||||
myBrush.Color = newColour;
|
||||
drawPen.Color = newColour;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void GetParams(char[] partsDelimiter, ref string line, int startLength, ref float x, ref float y)
|
||||
{
|
||||
line = line.Remove(0, startLength);
|
||||
string[] parts = line.Split(partsDelimiter);
|
||||
if (parts.Length == 2)
|
||||
{
|
||||
string xVal = parts[0].Trim();
|
||||
string yVal = parts[1].Trim();
|
||||
x = Convert.ToSingle(xVal, CultureInfo.InvariantCulture);
|
||||
y = Convert.ToSingle(yVal, CultureInfo.InvariantCulture);
|
||||
}
|
||||
else if (parts.Length > 2)
|
||||
{
|
||||
string xVal = parts[0].Trim();
|
||||
string yVal = parts[1].Trim();
|
||||
x = Convert.ToSingle(xVal, CultureInfo.InvariantCulture);
|
||||
y = Convert.ToSingle(yVal, CultureInfo.InvariantCulture);
|
||||
|
||||
line = "";
|
||||
for (int i = 2; i < parts.Length; i++)
|
||||
{
|
||||
line = line + parts[i].Trim();
|
||||
line = line + " ";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Bitmap ImageHttpRequest(string url)
|
||||
{
|
||||
WebRequest request = HttpWebRequest.Create(url);
|
||||
//Ckrinke: Comment out for now as 'str' is unused. Bring it back into play later when it is used.
|
||||
//Ckrinke Stream str = null;
|
||||
HttpWebResponse response = (HttpWebResponse) (request).GetResponse();
|
||||
if (response.StatusCode == HttpStatusCode.OK)
|
||||
{
|
||||
Bitmap image = new Bitmap(response.GetResponseStream());
|
||||
return image;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,79 +1,79 @@
|
|||
/*
|
||||
* 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 Nini.Config;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Land
|
||||
{
|
||||
public class LandManagementModule : IRegionModule
|
||||
{
|
||||
private LandChannel landChannel;
|
||||
private Scene m_scene;
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource source)
|
||||
{
|
||||
m_scene = scene;
|
||||
landChannel = new LandChannel(scene);
|
||||
|
||||
m_scene.EventManager.OnParcelPrimCountAdd += landChannel.addPrimToLandPrimCounts;
|
||||
m_scene.EventManager.OnParcelPrimCountUpdate += landChannel.updateLandPrimCounts;
|
||||
m_scene.EventManager.OnAvatarEnteringNewParcel += new EventManager.AvatarEnteringNewParcel(landChannel.handleAvatarChangingParcel);
|
||||
m_scene.EventManager.OnClientMovement += new EventManager.ClientMovement(landChannel.handleAnyClientMovement);
|
||||
m_scene.EventManager.OnValidateLandBuy += landChannel.handleLandValidationRequest;
|
||||
m_scene.EventManager.OnLandBuy += landChannel.handleLandBuyRequest;
|
||||
|
||||
lock (m_scene)
|
||||
{
|
||||
m_scene.LandChannel = (ILandChannel) landChannel;
|
||||
}
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "LandManagementModule"; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
/*
|
||||
* 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 Nini.Config;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Land
|
||||
{
|
||||
public class LandManagementModule : IRegionModule
|
||||
{
|
||||
private LandChannel landChannel;
|
||||
private Scene m_scene;
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource source)
|
||||
{
|
||||
m_scene = scene;
|
||||
landChannel = new LandChannel(scene);
|
||||
|
||||
m_scene.EventManager.OnParcelPrimCountAdd += landChannel.addPrimToLandPrimCounts;
|
||||
m_scene.EventManager.OnParcelPrimCountUpdate += landChannel.updateLandPrimCounts;
|
||||
m_scene.EventManager.OnAvatarEnteringNewParcel += new EventManager.AvatarEnteringNewParcel(landChannel.handleAvatarChangingParcel);
|
||||
m_scene.EventManager.OnClientMovement += new EventManager.ClientMovement(landChannel.handleAnyClientMovement);
|
||||
m_scene.EventManager.OnValidateLandBuy += landChannel.handleLandValidationRequest;
|
||||
m_scene.EventManager.OnLandBuy += landChannel.handleLandBuyRequest;
|
||||
|
||||
lock (m_scene)
|
||||
{
|
||||
m_scene.LandChannel = (ILandChannel) landChannel;
|
||||
}
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "LandManagementModule"; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,36 +1,36 @@
|
|||
/*
|
||||
* 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.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.ExportSerialiser
|
||||
{
|
||||
internal interface IFileSerialiser
|
||||
{
|
||||
string WriteToFile(Scene scene, string dir);
|
||||
}
|
||||
/*
|
||||
* 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.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.ExportSerialiser
|
||||
{
|
||||
internal interface IFileSerialiser
|
||||
{
|
||||
string WriteToFile(Scene scene, string dir);
|
||||
}
|
||||
}
|
|
@ -1,37 +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.
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.ExportSerialiser
|
||||
{
|
||||
public interface IRegionSerialiser
|
||||
{
|
||||
List<string> SerialiseRegion(Scene scene, string saveDir);
|
||||
}
|
||||
/*
|
||||
* 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 OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.ExportSerialiser
|
||||
{
|
||||
public interface IRegionSerialiser
|
||||
{
|
||||
List<string> SerialiseRegion(Scene scene, string saveDir);
|
||||
}
|
||||
}
|
|
@ -1,125 +1,125 @@
|
|||
/*
|
||||
* 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.IO.Compression;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.ExportSerialiser
|
||||
{
|
||||
internal class SerialiseObjects : IFileSerialiser
|
||||
{
|
||||
#region IFileSerialiser Members
|
||||
|
||||
public string WriteToFile(Scene scene, string dir)
|
||||
{
|
||||
string targetFileName = dir + "objects.xml";
|
||||
|
||||
SaveSerialisedToFile(targetFileName, scene);
|
||||
|
||||
return "objects.xml";
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void SaveSerialisedToFile(string fileName, Scene scene)
|
||||
{
|
||||
string xmlstream = GetObjectXml(scene);
|
||||
|
||||
MemoryStream stream = ReformatXmlString(xmlstream);
|
||||
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
CreateXmlFile(stream, fileName);
|
||||
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
CreateCompressedXmlFile(stream, fileName);
|
||||
}
|
||||
|
||||
private static MemoryStream ReformatXmlString(string xmlstream)
|
||||
{
|
||||
MemoryStream stream = new MemoryStream();
|
||||
XmlTextWriter formatter = new XmlTextWriter(stream, Encoding.UTF8);
|
||||
XmlDocument doc = new XmlDocument();
|
||||
|
||||
doc.LoadXml(xmlstream);
|
||||
formatter.Formatting = Formatting.Indented;
|
||||
doc.WriteContentTo(formatter);
|
||||
formatter.Flush();
|
||||
return stream;
|
||||
}
|
||||
|
||||
private static string GetObjectXml(Scene scene)
|
||||
{
|
||||
string xmlstream = "<scene>";
|
||||
|
||||
List<EntityBase> EntityList = scene.GetEntities();
|
||||
List<string> EntityXml = new List<string>();
|
||||
|
||||
foreach (EntityBase ent in EntityList)
|
||||
{
|
||||
if (ent is SceneObjectGroup)
|
||||
{
|
||||
EntityXml.Add(((SceneObjectGroup) ent).ToXmlString2());
|
||||
}
|
||||
}
|
||||
EntityXml.Sort();
|
||||
|
||||
foreach (string xml in EntityXml)
|
||||
xmlstream += xml;
|
||||
|
||||
xmlstream += "</scene>";
|
||||
return xmlstream;
|
||||
}
|
||||
|
||||
private static void CreateXmlFile(MemoryStream xmlStream, string fileName)
|
||||
{
|
||||
FileStream objectsFile = new FileStream(fileName, FileMode.Create);
|
||||
|
||||
xmlStream.WriteTo(objectsFile);
|
||||
objectsFile.Flush();
|
||||
objectsFile.Close();
|
||||
}
|
||||
|
||||
private static void CreateCompressedXmlFile(MemoryStream xmlStream, string fileName)
|
||||
{
|
||||
#region GZip Compressed Version
|
||||
|
||||
FileStream objectsFileCompressed = new FileStream(fileName + ".gzs", FileMode.Create);
|
||||
MemoryStream gzipMSStream = new MemoryStream();
|
||||
GZipStream gzipStream = new GZipStream(gzipMSStream, CompressionMode.Compress);
|
||||
xmlStream.WriteTo(gzipStream);
|
||||
gzipMSStream.WriteTo(objectsFileCompressed);
|
||||
objectsFileCompressed.Flush();
|
||||
objectsFileCompressed.Close();
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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.IO.Compression;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.ExportSerialiser
|
||||
{
|
||||
internal class SerialiseObjects : IFileSerialiser
|
||||
{
|
||||
#region IFileSerialiser Members
|
||||
|
||||
public string WriteToFile(Scene scene, string dir)
|
||||
{
|
||||
string targetFileName = dir + "objects.xml";
|
||||
|
||||
SaveSerialisedToFile(targetFileName, scene);
|
||||
|
||||
return "objects.xml";
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void SaveSerialisedToFile(string fileName, Scene scene)
|
||||
{
|
||||
string xmlstream = GetObjectXml(scene);
|
||||
|
||||
MemoryStream stream = ReformatXmlString(xmlstream);
|
||||
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
CreateXmlFile(stream, fileName);
|
||||
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
CreateCompressedXmlFile(stream, fileName);
|
||||
}
|
||||
|
||||
private static MemoryStream ReformatXmlString(string xmlstream)
|
||||
{
|
||||
MemoryStream stream = new MemoryStream();
|
||||
XmlTextWriter formatter = new XmlTextWriter(stream, Encoding.UTF8);
|
||||
XmlDocument doc = new XmlDocument();
|
||||
|
||||
doc.LoadXml(xmlstream);
|
||||
formatter.Formatting = Formatting.Indented;
|
||||
doc.WriteContentTo(formatter);
|
||||
formatter.Flush();
|
||||
return stream;
|
||||
}
|
||||
|
||||
private static string GetObjectXml(Scene scene)
|
||||
{
|
||||
string xmlstream = "<scene>";
|
||||
|
||||
List<EntityBase> EntityList = scene.GetEntities();
|
||||
List<string> EntityXml = new List<string>();
|
||||
|
||||
foreach (EntityBase ent in EntityList)
|
||||
{
|
||||
if (ent is SceneObjectGroup)
|
||||
{
|
||||
EntityXml.Add(((SceneObjectGroup) ent).ToXmlString2());
|
||||
}
|
||||
}
|
||||
EntityXml.Sort();
|
||||
|
||||
foreach (string xml in EntityXml)
|
||||
xmlstream += xml;
|
||||
|
||||
xmlstream += "</scene>";
|
||||
return xmlstream;
|
||||
}
|
||||
|
||||
private static void CreateXmlFile(MemoryStream xmlStream, string fileName)
|
||||
{
|
||||
FileStream objectsFile = new FileStream(fileName, FileMode.Create);
|
||||
|
||||
xmlStream.WriteTo(objectsFile);
|
||||
objectsFile.Flush();
|
||||
objectsFile.Close();
|
||||
}
|
||||
|
||||
private static void CreateCompressedXmlFile(MemoryStream xmlStream, string fileName)
|
||||
{
|
||||
#region GZip Compressed Version
|
||||
|
||||
FileStream objectsFileCompressed = new FileStream(fileName + ".gzs", FileMode.Create);
|
||||
MemoryStream gzipMSStream = new MemoryStream();
|
||||
GZipStream gzipStream = new GZipStream(gzipMSStream, CompressionMode.Compress);
|
||||
xmlStream.WriteTo(gzipStream);
|
||||
gzipMSStream.WriteTo(objectsFileCompressed);
|
||||
objectsFileCompressed.Flush();
|
||||
objectsFileCompressed.Close();
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,53 +1,53 @@
|
|||
/*
|
||||
* 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.Region.Environment.Modules.World.Terrain;
|
||||
using OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.ExportSerialiser
|
||||
{
|
||||
internal class SerialiseTerrain : IFileSerialiser
|
||||
{
|
||||
#region IFileSerialiser Members
|
||||
|
||||
public string WriteToFile(Scene scene, string dir)
|
||||
{
|
||||
ITerrainLoader fileSystemExporter = new RAW32();
|
||||
string targetFileName = dir + "heightmap.r32";
|
||||
|
||||
lock (scene.Heightmap)
|
||||
{
|
||||
fileSystemExporter.SaveFile(targetFileName, scene.Heightmap);
|
||||
}
|
||||
|
||||
return "heightmap.r32";
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
/*
|
||||
* 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.Region.Environment.Modules.World.Terrain;
|
||||
using OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.ExportSerialiser
|
||||
{
|
||||
internal class SerialiseTerrain : IFileSerialiser
|
||||
{
|
||||
#region IFileSerialiser Members
|
||||
|
||||
public string WriteToFile(Scene scene, string dir)
|
||||
{
|
||||
ITerrainLoader fileSystemExporter = new RAW32();
|
||||
string targetFileName = dir + "heightmap.r32";
|
||||
|
||||
lock (scene.Heightmap)
|
||||
{
|
||||
fileSystemExporter.SaveFile(targetFileName, scene.Heightmap);
|
||||
}
|
||||
|
||||
return "heightmap.r32";
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -1,169 +1,169 @@
|
|||
/*
|
||||
* 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 Nini.Config;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Modules.ExportSerialiser;
|
||||
using OpenSim.Region.Environment.Modules.Framework;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Serialiser
|
||||
{
|
||||
public class SerialiserModule : IRegionModule, IRegionSerialiser
|
||||
{
|
||||
private Commander m_commander = new Commander("Export");
|
||||
private List<Scene> m_regions = new List<Scene>();
|
||||
private string m_savedir = "exports" + "/";
|
||||
private List<IFileSerialiser> m_serialisers = new List<IFileSerialiser>();
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource source)
|
||||
{
|
||||
scene.RegisterModuleCommander("Export", m_commander);
|
||||
scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole;
|
||||
scene.RegisterModuleInterface<IRegionSerialiser>(this);
|
||||
|
||||
lock (m_regions)
|
||||
{
|
||||
m_regions.Add(scene);
|
||||
}
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
lock (m_serialisers)
|
||||
{
|
||||
m_serialisers.Add(new SerialiseTerrain());
|
||||
m_serialisers.Add(new SerialiseObjects());
|
||||
}
|
||||
|
||||
LoadCommanderCommands();
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
m_regions.Clear();
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "ExportSerialisationModule"; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IRegionSerialiser Members
|
||||
|
||||
public List<string> SerialiseRegion(Scene scene, string saveDir)
|
||||
{
|
||||
List<string> results = new List<string>();
|
||||
|
||||
if (!Directory.Exists(saveDir))
|
||||
{
|
||||
Directory.CreateDirectory(saveDir);
|
||||
}
|
||||
|
||||
lock (m_serialisers)
|
||||
{
|
||||
foreach (IFileSerialiser serialiser in m_serialisers)
|
||||
{
|
||||
results.Add(serialiser.WriteToFile(scene, saveDir));
|
||||
}
|
||||
}
|
||||
|
||||
TextWriter regionInfoWriter = new StreamWriter(saveDir + "README.TXT");
|
||||
regionInfoWriter.WriteLine("Region Name: " + scene.RegionInfo.RegionName);
|
||||
regionInfoWriter.WriteLine("Region ID: " + scene.RegionInfo.RegionID.ToString());
|
||||
regionInfoWriter.WriteLine("Backup Time: UTC " + DateTime.UtcNow.ToString());
|
||||
regionInfoWriter.WriteLine("Serialise Version: 0.1");
|
||||
regionInfoWriter.Close();
|
||||
|
||||
TextWriter manifestWriter = new StreamWriter(saveDir + "region.manifest");
|
||||
foreach (string line in results)
|
||||
{
|
||||
manifestWriter.WriteLine(line);
|
||||
}
|
||||
manifestWriter.Close();
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void EventManager_OnPluginConsole(string[] args)
|
||||
{
|
||||
if (args[0] == "export")
|
||||
{
|
||||
string[] tmpArgs = new string[args.Length - 2];
|
||||
int i = 0;
|
||||
for (i = 2; i < args.Length; i++)
|
||||
tmpArgs[i - 2] = args[i];
|
||||
|
||||
m_commander.ProcessConsoleCommand(args[1], tmpArgs);
|
||||
}
|
||||
}
|
||||
|
||||
private void InterfaceSaveRegion(Object[] args)
|
||||
{
|
||||
foreach (Scene region in m_regions)
|
||||
{
|
||||
if (region.RegionInfo.RegionName == (string) args[0])
|
||||
{
|
||||
List<string> results = SerialiseRegion(region, m_savedir + region.RegionInfo.RegionID.ToString() + "/");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void InterfaceSaveAllRegions(Object[] args)
|
||||
{
|
||||
foreach (Scene region in m_regions)
|
||||
{
|
||||
List<string> results = SerialiseRegion(region, m_savedir + region.RegionInfo.RegionID.ToString() + "/");
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadCommanderCommands()
|
||||
{
|
||||
Command serialiseSceneCommand = new Command("save", InterfaceSaveRegion, "Saves the named region into the exports directory.");
|
||||
serialiseSceneCommand.AddArgument("region-name", "The name of the region you wish to export", "String");
|
||||
|
||||
Command serialiseAllScenesCommand = new Command("save-all", InterfaceSaveAllRegions, "Saves all regions into the exports directory.");
|
||||
|
||||
m_commander.RegisterCommand("save", serialiseSceneCommand);
|
||||
m_commander.RegisterCommand("save-all", serialiseAllScenesCommand);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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 Nini.Config;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Modules.ExportSerialiser;
|
||||
using OpenSim.Region.Environment.Modules.Framework;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Serialiser
|
||||
{
|
||||
public class SerialiserModule : IRegionModule, IRegionSerialiser
|
||||
{
|
||||
private Commander m_commander = new Commander("Export");
|
||||
private List<Scene> m_regions = new List<Scene>();
|
||||
private string m_savedir = "exports" + "/";
|
||||
private List<IFileSerialiser> m_serialisers = new List<IFileSerialiser>();
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource source)
|
||||
{
|
||||
scene.RegisterModuleCommander("Export", m_commander);
|
||||
scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole;
|
||||
scene.RegisterModuleInterface<IRegionSerialiser>(this);
|
||||
|
||||
lock (m_regions)
|
||||
{
|
||||
m_regions.Add(scene);
|
||||
}
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
lock (m_serialisers)
|
||||
{
|
||||
m_serialisers.Add(new SerialiseTerrain());
|
||||
m_serialisers.Add(new SerialiseObjects());
|
||||
}
|
||||
|
||||
LoadCommanderCommands();
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
m_regions.Clear();
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "ExportSerialisationModule"; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IRegionSerialiser Members
|
||||
|
||||
public List<string> SerialiseRegion(Scene scene, string saveDir)
|
||||
{
|
||||
List<string> results = new List<string>();
|
||||
|
||||
if (!Directory.Exists(saveDir))
|
||||
{
|
||||
Directory.CreateDirectory(saveDir);
|
||||
}
|
||||
|
||||
lock (m_serialisers)
|
||||
{
|
||||
foreach (IFileSerialiser serialiser in m_serialisers)
|
||||
{
|
||||
results.Add(serialiser.WriteToFile(scene, saveDir));
|
||||
}
|
||||
}
|
||||
|
||||
TextWriter regionInfoWriter = new StreamWriter(saveDir + "README.TXT");
|
||||
regionInfoWriter.WriteLine("Region Name: " + scene.RegionInfo.RegionName);
|
||||
regionInfoWriter.WriteLine("Region ID: " + scene.RegionInfo.RegionID.ToString());
|
||||
regionInfoWriter.WriteLine("Backup Time: UTC " + DateTime.UtcNow.ToString());
|
||||
regionInfoWriter.WriteLine("Serialise Version: 0.1");
|
||||
regionInfoWriter.Close();
|
||||
|
||||
TextWriter manifestWriter = new StreamWriter(saveDir + "region.manifest");
|
||||
foreach (string line in results)
|
||||
{
|
||||
manifestWriter.WriteLine(line);
|
||||
}
|
||||
manifestWriter.Close();
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void EventManager_OnPluginConsole(string[] args)
|
||||
{
|
||||
if (args[0] == "export")
|
||||
{
|
||||
string[] tmpArgs = new string[args.Length - 2];
|
||||
int i = 0;
|
||||
for (i = 2; i < args.Length; i++)
|
||||
tmpArgs[i - 2] = args[i];
|
||||
|
||||
m_commander.ProcessConsoleCommand(args[1], tmpArgs);
|
||||
}
|
||||
}
|
||||
|
||||
private void InterfaceSaveRegion(Object[] args)
|
||||
{
|
||||
foreach (Scene region in m_regions)
|
||||
{
|
||||
if (region.RegionInfo.RegionName == (string) args[0])
|
||||
{
|
||||
List<string> results = SerialiseRegion(region, m_savedir + region.RegionInfo.RegionID.ToString() + "/");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void InterfaceSaveAllRegions(Object[] args)
|
||||
{
|
||||
foreach (Scene region in m_regions)
|
||||
{
|
||||
List<string> results = SerialiseRegion(region, m_savedir + region.RegionInfo.RegionID.ToString() + "/");
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadCommanderCommands()
|
||||
{
|
||||
Command serialiseSceneCommand = new Command("save", InterfaceSaveRegion, "Saves the named region into the exports directory.");
|
||||
serialiseSceneCommand.AddArgument("region-name", "The name of the region you wish to export", "String");
|
||||
|
||||
Command serialiseAllScenesCommand = new Command("save-all", InterfaceSaveAllRegions, "Saves all regions into the exports directory.");
|
||||
|
||||
m_commander.RegisterCommand("save", serialiseSceneCommand);
|
||||
m_commander.RegisterCommand("save-all", serialiseAllScenesCommand);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,199 +1,199 @@
|
|||
/*
|
||||
* 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 Nini.Config;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules
|
||||
{
|
||||
public class SunModule : IRegionModule
|
||||
{
|
||||
//private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private const int m_default_frame = 100;
|
||||
private const double m_real_day = 24.0;
|
||||
private double m_day_length;
|
||||
private int m_dilation;
|
||||
private int m_frame;
|
||||
private int m_frame_mod;
|
||||
|
||||
private Scene m_scene;
|
||||
private long m_start;
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource config)
|
||||
{
|
||||
m_start = DateTime.Now.Ticks;
|
||||
m_frame = 0;
|
||||
|
||||
// Just in case they don't have the stanzas
|
||||
try
|
||||
{
|
||||
m_day_length = config.Configs["Sun"].GetDouble("day_length", m_real_day);
|
||||
m_frame_mod = config.Configs["Sun"].GetInt("frame_rate", m_default_frame);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
m_day_length = m_real_day;
|
||||
m_frame_mod = m_default_frame;
|
||||
}
|
||||
|
||||
m_dilation = (int) (m_real_day / m_day_length);
|
||||
m_scene = scene;
|
||||
scene.EventManager.OnFrame += SunUpdate;
|
||||
scene.EventManager.OnNewClient += SunToClient;
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "SunModule"; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void SunToClient(IClientAPI client)
|
||||
{
|
||||
client.SendSunPos(SunPos(HourOfTheDay()), new LLVector3(0, 0.0f, 10.0f));
|
||||
}
|
||||
|
||||
public void SunUpdate()
|
||||
{
|
||||
if (m_frame < m_frame_mod)
|
||||
{
|
||||
m_frame++;
|
||||
return;
|
||||
}
|
||||
// m_log.InfoFormat("[SUN]: I've got an update {0} => {1}", m_scene.RegionsInfo.RegionName, HourOfTheDay());
|
||||
List<ScenePresence> avatars = m_scene.GetAvatars();
|
||||
foreach (ScenePresence avatar in avatars)
|
||||
{
|
||||
avatar.ControllingClient.SendSunPos(SunPos(HourOfTheDay()), new LLVector3(0, 0.0f, 10.0f));
|
||||
}
|
||||
// set estate settings for region access to sun position
|
||||
m_scene.RegionInfo.EstateSettings.sunPosition = SunPos(HourOfTheDay());
|
||||
|
||||
m_frame = 0;
|
||||
}
|
||||
|
||||
// Hour of the Day figures out the hour of the day as a float.
|
||||
// The intent here is that we seed hour of the day with real
|
||||
// time when the simulator starts, then run time forward
|
||||
// faster based on time dilation factor. This means that
|
||||
// ticks don't get out of hand
|
||||
private double HourOfTheDay()
|
||||
{
|
||||
long m_addticks = (DateTime.Now.Ticks - m_start) * m_dilation;
|
||||
DateTime dt = new DateTime(m_start + m_addticks);
|
||||
return (double) dt.Hour + ((double) dt.Minute / 60.0);
|
||||
}
|
||||
|
||||
private LLVector3 SunPos(double hour)
|
||||
{
|
||||
// now we have our radian position
|
||||
double rad = (hour / m_real_day) * 2 * Math.PI - (Math.PI / 2.0);
|
||||
double z = Math.Sin(rad);
|
||||
double x = Math.Cos(rad);
|
||||
return new LLVector3((float) x, 0f, (float) z);
|
||||
}
|
||||
|
||||
// TODO: clear this out. This is here so that I remember to
|
||||
// figure out if we need those other packet fields that I've
|
||||
// left out so far
|
||||
//
|
||||
// public void SendViewerTime(int phase)
|
||||
// {
|
||||
// Console.WriteLine("SunPhase: {0}", phase);
|
||||
// SimulatorViewerTimeMessagePacket viewertime = new SimulatorViewerTimeMessagePacket();
|
||||
// //viewertime.TimeInfo.SecPerDay = 86400;
|
||||
// // viewertime.TimeInfo.SecPerYear = 31536000;
|
||||
// viewertime.TimeInfo.SecPerDay = 1000;
|
||||
// viewertime.TimeInfo.SecPerYear = 365000;
|
||||
// viewertime.TimeInfo.SunPhase = 1;
|
||||
// int sunPhase = (phase + 2)/2;
|
||||
// if ((sunPhase < 6) || (sunPhase > 36))
|
||||
// {
|
||||
// viewertime.TimeInfo.SunDirection = new LLVector3(0f, 0.8f, -0.8f);
|
||||
// Console.WriteLine("sending night");
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// if (sunPhase < 12)
|
||||
// {
|
||||
// sunPhase = 12;
|
||||
// }
|
||||
// sunPhase = sunPhase - 12;
|
||||
//
|
||||
// float yValue = 0.1f*(sunPhase);
|
||||
// Console.WriteLine("Computed SunPhase: {0}, yValue: {1}", sunPhase, yValue);
|
||||
// if (yValue > 1.2f)
|
||||
// {
|
||||
// yValue = yValue - 1.2f;
|
||||
// }
|
||||
// if (yValue > 1)
|
||||
// {
|
||||
// yValue = 1;
|
||||
// }
|
||||
// if (yValue < 0)
|
||||
// {
|
||||
// yValue = 0;
|
||||
// }
|
||||
// if (sunPhase < 14)
|
||||
// {
|
||||
// yValue = 1 - yValue;
|
||||
// }
|
||||
// if (sunPhase < 12)
|
||||
// {
|
||||
// yValue *= -1;
|
||||
// }
|
||||
// viewertime.TimeInfo.SunDirection = new LLVector3(0f, yValue, 0.3f);
|
||||
// Console.WriteLine("sending sun update " + yValue);
|
||||
// }
|
||||
// viewertime.TimeInfo.SunAngVelocity = new LLVector3(0, 0.0f, 10.0f);
|
||||
// viewertime.TimeInfo.UsecSinceStart = (ulong) Util.UnixTimeSinceEpoch();
|
||||
// // OutPacket(viewertime);
|
||||
// }
|
||||
}
|
||||
/*
|
||||
* 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 Nini.Config;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules
|
||||
{
|
||||
public class SunModule : IRegionModule
|
||||
{
|
||||
//private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private const int m_default_frame = 100;
|
||||
private const double m_real_day = 24.0;
|
||||
private double m_day_length;
|
||||
private int m_dilation;
|
||||
private int m_frame;
|
||||
private int m_frame_mod;
|
||||
|
||||
private Scene m_scene;
|
||||
private long m_start;
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource config)
|
||||
{
|
||||
m_start = DateTime.Now.Ticks;
|
||||
m_frame = 0;
|
||||
|
||||
// Just in case they don't have the stanzas
|
||||
try
|
||||
{
|
||||
m_day_length = config.Configs["Sun"].GetDouble("day_length", m_real_day);
|
||||
m_frame_mod = config.Configs["Sun"].GetInt("frame_rate", m_default_frame);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
m_day_length = m_real_day;
|
||||
m_frame_mod = m_default_frame;
|
||||
}
|
||||
|
||||
m_dilation = (int) (m_real_day / m_day_length);
|
||||
m_scene = scene;
|
||||
scene.EventManager.OnFrame += SunUpdate;
|
||||
scene.EventManager.OnNewClient += SunToClient;
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "SunModule"; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void SunToClient(IClientAPI client)
|
||||
{
|
||||
client.SendSunPos(SunPos(HourOfTheDay()), new LLVector3(0, 0.0f, 10.0f));
|
||||
}
|
||||
|
||||
public void SunUpdate()
|
||||
{
|
||||
if (m_frame < m_frame_mod)
|
||||
{
|
||||
m_frame++;
|
||||
return;
|
||||
}
|
||||
// m_log.InfoFormat("[SUN]: I've got an update {0} => {1}", m_scene.RegionsInfo.RegionName, HourOfTheDay());
|
||||
List<ScenePresence> avatars = m_scene.GetAvatars();
|
||||
foreach (ScenePresence avatar in avatars)
|
||||
{
|
||||
avatar.ControllingClient.SendSunPos(SunPos(HourOfTheDay()), new LLVector3(0, 0.0f, 10.0f));
|
||||
}
|
||||
// set estate settings for region access to sun position
|
||||
m_scene.RegionInfo.EstateSettings.sunPosition = SunPos(HourOfTheDay());
|
||||
|
||||
m_frame = 0;
|
||||
}
|
||||
|
||||
// Hour of the Day figures out the hour of the day as a float.
|
||||
// The intent here is that we seed hour of the day with real
|
||||
// time when the simulator starts, then run time forward
|
||||
// faster based on time dilation factor. This means that
|
||||
// ticks don't get out of hand
|
||||
private double HourOfTheDay()
|
||||
{
|
||||
long m_addticks = (DateTime.Now.Ticks - m_start) * m_dilation;
|
||||
DateTime dt = new DateTime(m_start + m_addticks);
|
||||
return (double) dt.Hour + ((double) dt.Minute / 60.0);
|
||||
}
|
||||
|
||||
private LLVector3 SunPos(double hour)
|
||||
{
|
||||
// now we have our radian position
|
||||
double rad = (hour / m_real_day) * 2 * Math.PI - (Math.PI / 2.0);
|
||||
double z = Math.Sin(rad);
|
||||
double x = Math.Cos(rad);
|
||||
return new LLVector3((float) x, 0f, (float) z);
|
||||
}
|
||||
|
||||
// TODO: clear this out. This is here so that I remember to
|
||||
// figure out if we need those other packet fields that I've
|
||||
// left out so far
|
||||
//
|
||||
// public void SendViewerTime(int phase)
|
||||
// {
|
||||
// Console.WriteLine("SunPhase: {0}", phase);
|
||||
// SimulatorViewerTimeMessagePacket viewertime = new SimulatorViewerTimeMessagePacket();
|
||||
// //viewertime.TimeInfo.SecPerDay = 86400;
|
||||
// // viewertime.TimeInfo.SecPerYear = 31536000;
|
||||
// viewertime.TimeInfo.SecPerDay = 1000;
|
||||
// viewertime.TimeInfo.SecPerYear = 365000;
|
||||
// viewertime.TimeInfo.SunPhase = 1;
|
||||
// int sunPhase = (phase + 2)/2;
|
||||
// if ((sunPhase < 6) || (sunPhase > 36))
|
||||
// {
|
||||
// viewertime.TimeInfo.SunDirection = new LLVector3(0f, 0.8f, -0.8f);
|
||||
// Console.WriteLine("sending night");
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// if (sunPhase < 12)
|
||||
// {
|
||||
// sunPhase = 12;
|
||||
// }
|
||||
// sunPhase = sunPhase - 12;
|
||||
//
|
||||
// float yValue = 0.1f*(sunPhase);
|
||||
// Console.WriteLine("Computed SunPhase: {0}, yValue: {1}", sunPhase, yValue);
|
||||
// if (yValue > 1.2f)
|
||||
// {
|
||||
// yValue = yValue - 1.2f;
|
||||
// }
|
||||
// if (yValue > 1)
|
||||
// {
|
||||
// yValue = 1;
|
||||
// }
|
||||
// if (yValue < 0)
|
||||
// {
|
||||
// yValue = 0;
|
||||
// }
|
||||
// if (sunPhase < 14)
|
||||
// {
|
||||
// yValue = 1 - yValue;
|
||||
// }
|
||||
// if (sunPhase < 12)
|
||||
// {
|
||||
// yValue *= -1;
|
||||
// }
|
||||
// viewertime.TimeInfo.SunDirection = new LLVector3(0f, yValue, 0.3f);
|
||||
// Console.WriteLine("sending sun update " + yValue);
|
||||
// }
|
||||
// viewertime.TimeInfo.SunAngVelocity = new LLVector3(0, 0.0f, 10.0f);
|
||||
// viewertime.TimeInfo.UsecSinceStart = (ulong) Util.UnixTimeSinceEpoch();
|
||||
// // OutPacket(viewertime);
|
||||
// }
|
||||
}
|
||||
}
|
|
@ -1,124 +1,124 @@
|
|||
/*
|
||||
* 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 OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes;
|
||||
using OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.Effects
|
||||
{
|
||||
internal class CookieCutter : ITerrainEffect
|
||||
{
|
||||
#region ITerrainEffect Members
|
||||
|
||||
public void RunEffect(ITerrainChannel map)
|
||||
{
|
||||
SmoothArea smooth = new SmoothArea();
|
||||
ITerrainPaintableEffect eroder = new WeatherSphere();
|
||||
|
||||
bool[,] cliffMask = new bool[map.Width,map.Height];
|
||||
bool[,] channelMask = new bool[map.Width,map.Height];
|
||||
bool[,] smoothMask = new bool[map.Width,map.Height];
|
||||
|
||||
Console.WriteLine("S1");
|
||||
|
||||
// Step one, generate rough mask
|
||||
int x, y;
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
Console.Write(".");
|
||||
smoothMask[x, y] = true;
|
||||
|
||||
// Start underwater
|
||||
map[x, y] = TerrainUtil.PerlinNoise2D(x, y, 3, 0.25) * 5;
|
||||
// Add a little height. (terrain should now be above water, mostly.)
|
||||
map[x, y] += 20;
|
||||
|
||||
int channelsX = 4;
|
||||
int channelWidth = (map.Width / channelsX / 4);
|
||||
int channelsY = 4;
|
||||
int channelHeight = (map.Height / channelsY / 4);
|
||||
|
||||
SetLowerChannel(map, cliffMask, channelMask, x, y, channelsX, channelWidth, map.Width, x);
|
||||
SetLowerChannel(map, cliffMask, channelMask, x, y, channelsY, channelHeight, map.Height, y);
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine("S2");
|
||||
//smooth.FloodEffect(map, smoothMask, 4.0);
|
||||
|
||||
Console.WriteLine("S3");
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
if (cliffMask[x, y] == true)
|
||||
eroder.PaintEffect(map, x, y, 4, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
for (x = 0; x < map.Width; x += 2)
|
||||
{
|
||||
for (y = 0; y < map.Height; y += 2)
|
||||
{
|
||||
if (map[x, y] < 0.1)
|
||||
map[x, y] = 0.1;
|
||||
if (map[x, y] > 256)
|
||||
map[x, y] = 256;
|
||||
}
|
||||
}
|
||||
//smooth.FloodEffect(map, smoothMask, 4.0);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private static void SetLowerChannel(ITerrainChannel map, bool[,] cliffMask, bool[,] channelMask, int x, int y, int numChannels, int channelWidth,
|
||||
int mapSize, int rp)
|
||||
{
|
||||
for (int i = 0; i < numChannels; i++)
|
||||
{
|
||||
double distanceToLine = Math.Abs(rp - ((mapSize / numChannels) * i));
|
||||
|
||||
if (distanceToLine < channelWidth)
|
||||
{
|
||||
if (channelMask[x, y])
|
||||
return;
|
||||
|
||||
// Remove channels
|
||||
map[x, y] -= 10;
|
||||
channelMask[x, y] = true;
|
||||
}
|
||||
if (distanceToLine < 1)
|
||||
{
|
||||
cliffMask[x, y] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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 OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes;
|
||||
using OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.Effects
|
||||
{
|
||||
internal class CookieCutter : ITerrainEffect
|
||||
{
|
||||
#region ITerrainEffect Members
|
||||
|
||||
public void RunEffect(ITerrainChannel map)
|
||||
{
|
||||
SmoothArea smooth = new SmoothArea();
|
||||
ITerrainPaintableEffect eroder = new WeatherSphere();
|
||||
|
||||
bool[,] cliffMask = new bool[map.Width,map.Height];
|
||||
bool[,] channelMask = new bool[map.Width,map.Height];
|
||||
bool[,] smoothMask = new bool[map.Width,map.Height];
|
||||
|
||||
Console.WriteLine("S1");
|
||||
|
||||
// Step one, generate rough mask
|
||||
int x, y;
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
Console.Write(".");
|
||||
smoothMask[x, y] = true;
|
||||
|
||||
// Start underwater
|
||||
map[x, y] = TerrainUtil.PerlinNoise2D(x, y, 3, 0.25) * 5;
|
||||
// Add a little height. (terrain should now be above water, mostly.)
|
||||
map[x, y] += 20;
|
||||
|
||||
int channelsX = 4;
|
||||
int channelWidth = (map.Width / channelsX / 4);
|
||||
int channelsY = 4;
|
||||
int channelHeight = (map.Height / channelsY / 4);
|
||||
|
||||
SetLowerChannel(map, cliffMask, channelMask, x, y, channelsX, channelWidth, map.Width, x);
|
||||
SetLowerChannel(map, cliffMask, channelMask, x, y, channelsY, channelHeight, map.Height, y);
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine("S2");
|
||||
//smooth.FloodEffect(map, smoothMask, 4.0);
|
||||
|
||||
Console.WriteLine("S3");
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
if (cliffMask[x, y] == true)
|
||||
eroder.PaintEffect(map, x, y, 4, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
for (x = 0; x < map.Width; x += 2)
|
||||
{
|
||||
for (y = 0; y < map.Height; y += 2)
|
||||
{
|
||||
if (map[x, y] < 0.1)
|
||||
map[x, y] = 0.1;
|
||||
if (map[x, y] > 256)
|
||||
map[x, y] = 256;
|
||||
}
|
||||
}
|
||||
//smooth.FloodEffect(map, smoothMask, 4.0);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private static void SetLowerChannel(ITerrainChannel map, bool[,] cliffMask, bool[,] channelMask, int x, int y, int numChannels, int channelWidth,
|
||||
int mapSize, int rp)
|
||||
{
|
||||
for (int i = 0; i < numChannels; i++)
|
||||
{
|
||||
double distanceToLine = Math.Abs(rp - ((mapSize / numChannels) * i));
|
||||
|
||||
if (distanceToLine < channelWidth)
|
||||
{
|
||||
if (channelMask[x, y])
|
||||
return;
|
||||
|
||||
// Remove channels
|
||||
map[x, y] -= 10;
|
||||
channelMask[x, y] = true;
|
||||
}
|
||||
if (distanceToLine < 1)
|
||||
{
|
||||
cliffMask[x, y] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,55 +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 OpenSim.Framework;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.Effects
|
||||
{
|
||||
internal class DefaultTerrainGenerator : ITerrainEffect
|
||||
{
|
||||
#region ITerrainEffect Members
|
||||
|
||||
public void RunEffect(ITerrainChannel map)
|
||||
{
|
||||
int x, y;
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
map[x, y] = TerrainUtil.PerlinNoise2D(x, y, 3, 0.25) * 10;
|
||||
double spherFac = TerrainUtil.SphericalFactor(x, y, Constants.RegionSize / 2, Constants.RegionSize / 2, 50) * 0.01;
|
||||
if (map[x, y] < spherFac)
|
||||
{
|
||||
map[x, y] = spherFac;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
/*
|
||||
* 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;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.Effects
|
||||
{
|
||||
internal class DefaultTerrainGenerator : ITerrainEffect
|
||||
{
|
||||
#region ITerrainEffect Members
|
||||
|
||||
public void RunEffect(ITerrainChannel map)
|
||||
{
|
||||
int x, y;
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
map[x, y] = TerrainUtil.PerlinNoise2D(x, y, 3, 0.25) * 10;
|
||||
double spherFac = TerrainUtil.SphericalFactor(x, y, Constants.RegionSize / 2, Constants.RegionSize / 2, 50) * 0.01;
|
||||
if (map[x, y] < spherFac)
|
||||
{
|
||||
map[x, y] = spherFac;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -1,62 +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.
|
||||
*/
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders
|
||||
{
|
||||
/// <summary>
|
||||
/// A generic windows bitmap loader.
|
||||
/// Should be capable of handling 24-bit RGB images.
|
||||
///
|
||||
/// Uses the System.Drawing filesystem loader.
|
||||
/// </summary>
|
||||
internal class BMP : GenericSystemDrawing
|
||||
{
|
||||
/// <summary>
|
||||
/// Exports a file to a image on the disk using a System.Drawing exporter.
|
||||
/// </summary>
|
||||
/// <param name="filename">The target filename</param>
|
||||
/// <param name="map">The terrain channel being saved</param>
|
||||
public override void SaveFile(string filename, ITerrainChannel map)
|
||||
{
|
||||
Bitmap colours = CreateGrayscaleBitmapFromMap(map);
|
||||
|
||||
colours.Save(filename, ImageFormat.Bmp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The human readable version of the file format(s) this loader handles
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return "BMP";
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders
|
||||
{
|
||||
/// <summary>
|
||||
/// A generic windows bitmap loader.
|
||||
/// Should be capable of handling 24-bit RGB images.
|
||||
///
|
||||
/// Uses the System.Drawing filesystem loader.
|
||||
/// </summary>
|
||||
internal class BMP : GenericSystemDrawing
|
||||
{
|
||||
/// <summary>
|
||||
/// Exports a file to a image on the disk using a System.Drawing exporter.
|
||||
/// </summary>
|
||||
/// <param name="filename">The target filename</param>
|
||||
/// <param name="map">The terrain channel being saved</param>
|
||||
public override void SaveFile(string filename, ITerrainChannel map)
|
||||
{
|
||||
Bitmap colours = CreateGrayscaleBitmapFromMap(map);
|
||||
|
||||
colours.Save(filename, ImageFormat.Bmp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The human readable version of the file format(s) this loader handles
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return "BMP";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,47 +1,47 @@
|
|||
/*
|
||||
* 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.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders
|
||||
{
|
||||
internal class GIF : GenericSystemDrawing
|
||||
{
|
||||
public override void SaveFile(string filename, ITerrainChannel map)
|
||||
{
|
||||
Bitmap colours = CreateGrayscaleBitmapFromMap(map);
|
||||
|
||||
colours.Save(filename, ImageFormat.Gif);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "GIF";
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders
|
||||
{
|
||||
internal class GIF : GenericSystemDrawing
|
||||
{
|
||||
public override void SaveFile(string filename, ITerrainChannel map)
|
||||
{
|
||||
Bitmap colours = CreateGrayscaleBitmapFromMap(map);
|
||||
|
||||
colours.Save(filename, ImageFormat.Gif);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "GIF";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,172 +1,172 @@
|
|||
/*
|
||||
* 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.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders
|
||||
{
|
||||
/// <summary>
|
||||
/// A virtual class designed to have methods overloaded,
|
||||
/// this class provides an interface for a generic image
|
||||
/// saving and loading mechanism, but does not specify the
|
||||
/// format. It should not be insubstantiated directly.
|
||||
/// </summary>
|
||||
public class GenericSystemDrawing : ITerrainLoader
|
||||
{
|
||||
#region ITerrainLoader Members
|
||||
|
||||
public string FileExtension
|
||||
{
|
||||
get { return ".gsd"; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads a file from a specified filename on the disk,
|
||||
/// parses the image using the System.Drawing parsers
|
||||
/// then returns a terrain channel. Values are
|
||||
/// returned based on HSL brightness between 0m and 128m
|
||||
/// </summary>
|
||||
/// <param name="filename">The target image to load</param>
|
||||
/// <returns>A terrain channel generated from the image.</returns>
|
||||
public virtual ITerrainChannel LoadFile(string filename)
|
||||
{
|
||||
Bitmap file = new Bitmap(filename);
|
||||
|
||||
ITerrainChannel retval = new TerrainChannel(file.Width, file.Height);
|
||||
|
||||
int x, y;
|
||||
for (x = 0; x < file.Width; x++)
|
||||
{
|
||||
for (y = 0; y < file.Height; y++)
|
||||
{
|
||||
retval[x, y] = file.GetPixel(x, y).GetBrightness() * 128;
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
public ITerrainChannel LoadFile(string filename, int x, int y, int fileWidth, int fileHeight, int w, int h)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Exports a file to a image on the disk using a System.Drawing exporter.
|
||||
/// </summary>
|
||||
/// <param name="filename">The target filename</param>
|
||||
/// <param name="map">The terrain channel being saved</param>
|
||||
public virtual void SaveFile(string filename, ITerrainChannel map)
|
||||
{
|
||||
Bitmap colours = CreateGrayscaleBitmapFromMap(map);
|
||||
|
||||
colours.Save(filename, ImageFormat.Png);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "SYS.DRAWING";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Protected method, generates a grayscale bitmap
|
||||
/// image from a specified terrain channel.
|
||||
/// </summary>
|
||||
/// <param name="map">The terrain channel to export to bitmap</param>
|
||||
/// <returns>A System.Drawing.Bitmap containing a grayscale image</returns>
|
||||
protected Bitmap CreateGrayscaleBitmapFromMap(ITerrainChannel map)
|
||||
{
|
||||
Bitmap bmp = new Bitmap(map.Width, map.Height);
|
||||
|
||||
int pallete = 256;
|
||||
|
||||
Color[] grays = new Color[pallete];
|
||||
for (int i = 0; i < grays.Length; i++)
|
||||
{
|
||||
grays[i] = Color.FromArgb(i, i, i);
|
||||
}
|
||||
|
||||
for (int y = 0; y < map.Height; y++)
|
||||
{
|
||||
for (int x = 0; x < map.Width; x++)
|
||||
{
|
||||
// 512 is the largest possible height before colours clamp
|
||||
int colorindex = (int) (Math.Max(Math.Min(1.0, map[x, y] / 128.0), 0.0) * (pallete - 1));
|
||||
|
||||
// Handle error conditions
|
||||
if (colorindex > pallete - 1 || colorindex < 0)
|
||||
bmp.SetPixel(x, map.Height - y - 1, Color.Red);
|
||||
else
|
||||
bmp.SetPixel(x, map.Height - y - 1, grays[colorindex]);
|
||||
}
|
||||
}
|
||||
return bmp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Protected method, generates a coloured bitmap
|
||||
/// image from a specified terrain channel.
|
||||
/// </summary>
|
||||
/// <param name="map">The terrain channel to export to bitmap</param>
|
||||
/// <returns>A System.Drawing.Bitmap containing a coloured image</returns>
|
||||
protected Bitmap CreateBitmapFromMap(ITerrainChannel map)
|
||||
{
|
||||
Bitmap gradientmapLd = new Bitmap("defaultstripe.png");
|
||||
|
||||
int pallete = gradientmapLd.Height;
|
||||
|
||||
Bitmap bmp = new Bitmap(map.Width, map.Height);
|
||||
Color[] colours = new Color[pallete];
|
||||
|
||||
for (int i = 0; i < pallete; i++)
|
||||
{
|
||||
colours[i] = gradientmapLd.GetPixel(0, i);
|
||||
}
|
||||
|
||||
for (int y = 0; y < map.Height; y++)
|
||||
{
|
||||
for (int x = 0; x < map.Width; x++)
|
||||
{
|
||||
// 512 is the largest possible height before colours clamp
|
||||
int colorindex = (int) (Math.Max(Math.Min(1.0, map[x, y] / 512.0), 0.0) * (pallete - 1));
|
||||
|
||||
// Handle error conditions
|
||||
if (colorindex > pallete - 1 || colorindex < 0)
|
||||
bmp.SetPixel(x, map.Height - y - 1, Color.Red);
|
||||
else
|
||||
bmp.SetPixel(x, map.Height - y - 1, colours[colorindex]);
|
||||
}
|
||||
}
|
||||
return bmp;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders
|
||||
{
|
||||
/// <summary>
|
||||
/// A virtual class designed to have methods overloaded,
|
||||
/// this class provides an interface for a generic image
|
||||
/// saving and loading mechanism, but does not specify the
|
||||
/// format. It should not be insubstantiated directly.
|
||||
/// </summary>
|
||||
public class GenericSystemDrawing : ITerrainLoader
|
||||
{
|
||||
#region ITerrainLoader Members
|
||||
|
||||
public string FileExtension
|
||||
{
|
||||
get { return ".gsd"; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads a file from a specified filename on the disk,
|
||||
/// parses the image using the System.Drawing parsers
|
||||
/// then returns a terrain channel. Values are
|
||||
/// returned based on HSL brightness between 0m and 128m
|
||||
/// </summary>
|
||||
/// <param name="filename">The target image to load</param>
|
||||
/// <returns>A terrain channel generated from the image.</returns>
|
||||
public virtual ITerrainChannel LoadFile(string filename)
|
||||
{
|
||||
Bitmap file = new Bitmap(filename);
|
||||
|
||||
ITerrainChannel retval = new TerrainChannel(file.Width, file.Height);
|
||||
|
||||
int x, y;
|
||||
for (x = 0; x < file.Width; x++)
|
||||
{
|
||||
for (y = 0; y < file.Height; y++)
|
||||
{
|
||||
retval[x, y] = file.GetPixel(x, y).GetBrightness() * 128;
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
public ITerrainChannel LoadFile(string filename, int x, int y, int fileWidth, int fileHeight, int w, int h)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Exports a file to a image on the disk using a System.Drawing exporter.
|
||||
/// </summary>
|
||||
/// <param name="filename">The target filename</param>
|
||||
/// <param name="map">The terrain channel being saved</param>
|
||||
public virtual void SaveFile(string filename, ITerrainChannel map)
|
||||
{
|
||||
Bitmap colours = CreateGrayscaleBitmapFromMap(map);
|
||||
|
||||
colours.Save(filename, ImageFormat.Png);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "SYS.DRAWING";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Protected method, generates a grayscale bitmap
|
||||
/// image from a specified terrain channel.
|
||||
/// </summary>
|
||||
/// <param name="map">The terrain channel to export to bitmap</param>
|
||||
/// <returns>A System.Drawing.Bitmap containing a grayscale image</returns>
|
||||
protected Bitmap CreateGrayscaleBitmapFromMap(ITerrainChannel map)
|
||||
{
|
||||
Bitmap bmp = new Bitmap(map.Width, map.Height);
|
||||
|
||||
int pallete = 256;
|
||||
|
||||
Color[] grays = new Color[pallete];
|
||||
for (int i = 0; i < grays.Length; i++)
|
||||
{
|
||||
grays[i] = Color.FromArgb(i, i, i);
|
||||
}
|
||||
|
||||
for (int y = 0; y < map.Height; y++)
|
||||
{
|
||||
for (int x = 0; x < map.Width; x++)
|
||||
{
|
||||
// 512 is the largest possible height before colours clamp
|
||||
int colorindex = (int) (Math.Max(Math.Min(1.0, map[x, y] / 128.0), 0.0) * (pallete - 1));
|
||||
|
||||
// Handle error conditions
|
||||
if (colorindex > pallete - 1 || colorindex < 0)
|
||||
bmp.SetPixel(x, map.Height - y - 1, Color.Red);
|
||||
else
|
||||
bmp.SetPixel(x, map.Height - y - 1, grays[colorindex]);
|
||||
}
|
||||
}
|
||||
return bmp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Protected method, generates a coloured bitmap
|
||||
/// image from a specified terrain channel.
|
||||
/// </summary>
|
||||
/// <param name="map">The terrain channel to export to bitmap</param>
|
||||
/// <returns>A System.Drawing.Bitmap containing a coloured image</returns>
|
||||
protected Bitmap CreateBitmapFromMap(ITerrainChannel map)
|
||||
{
|
||||
Bitmap gradientmapLd = new Bitmap("defaultstripe.png");
|
||||
|
||||
int pallete = gradientmapLd.Height;
|
||||
|
||||
Bitmap bmp = new Bitmap(map.Width, map.Height);
|
||||
Color[] colours = new Color[pallete];
|
||||
|
||||
for (int i = 0; i < pallete; i++)
|
||||
{
|
||||
colours[i] = gradientmapLd.GetPixel(0, i);
|
||||
}
|
||||
|
||||
for (int y = 0; y < map.Height; y++)
|
||||
{
|
||||
for (int x = 0; x < map.Width; x++)
|
||||
{
|
||||
// 512 is the largest possible height before colours clamp
|
||||
int colorindex = (int) (Math.Max(Math.Min(1.0, map[x, y] / 512.0), 0.0) * (pallete - 1));
|
||||
|
||||
// Handle error conditions
|
||||
if (colorindex > pallete - 1 || colorindex < 0)
|
||||
bmp.SetPixel(x, map.Height - y - 1, Color.Red);
|
||||
else
|
||||
bmp.SetPixel(x, map.Height - y - 1, colours[colorindex]);
|
||||
}
|
||||
}
|
||||
return bmp;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,94 +1,94 @@
|
|||
/*
|
||||
* 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.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders
|
||||
{
|
||||
public class JPEG : ITerrainLoader
|
||||
{
|
||||
#region ITerrainLoader Members
|
||||
|
||||
public string FileExtension
|
||||
{
|
||||
get { return ".jpg"; }
|
||||
}
|
||||
|
||||
public ITerrainChannel LoadFile(string filename)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public ITerrainChannel LoadFile(string filename, int x, int y, int fileWidth, int fileHeight, int w, int h)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void SaveFile(string filename, ITerrainChannel map)
|
||||
{
|
||||
Bitmap colours = CreateBitmapFromMap(map);
|
||||
|
||||
colours.Save(filename, ImageFormat.Jpeg);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "JPEG";
|
||||
}
|
||||
|
||||
private Bitmap CreateBitmapFromMap(ITerrainChannel map)
|
||||
{
|
||||
Bitmap gradientmapLd = new Bitmap("defaultstripe.png");
|
||||
|
||||
int pallete = gradientmapLd.Height;
|
||||
|
||||
Bitmap bmp = new Bitmap(map.Width, map.Height);
|
||||
Color[] colours = new Color[pallete];
|
||||
|
||||
for (int i = 0; i < pallete; i++)
|
||||
{
|
||||
colours[i] = gradientmapLd.GetPixel(0, i);
|
||||
}
|
||||
|
||||
for (int y = 0; y < map.Height; y++)
|
||||
{
|
||||
for (int x = 0; x < map.Width; x++)
|
||||
{
|
||||
// 512 is the largest possible height before colours clamp
|
||||
int colorindex = (int) (Math.Max(Math.Min(1.0, map[x, y] / 512.0), 0.0) * (pallete - 1));
|
||||
bmp.SetPixel(x, map.Height - y - 1, colours[colorindex]);
|
||||
}
|
||||
}
|
||||
return bmp;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders
|
||||
{
|
||||
public class JPEG : ITerrainLoader
|
||||
{
|
||||
#region ITerrainLoader Members
|
||||
|
||||
public string FileExtension
|
||||
{
|
||||
get { return ".jpg"; }
|
||||
}
|
||||
|
||||
public ITerrainChannel LoadFile(string filename)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public ITerrainChannel LoadFile(string filename, int x, int y, int fileWidth, int fileHeight, int w, int h)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void SaveFile(string filename, ITerrainChannel map)
|
||||
{
|
||||
Bitmap colours = CreateBitmapFromMap(map);
|
||||
|
||||
colours.Save(filename, ImageFormat.Jpeg);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "JPEG";
|
||||
}
|
||||
|
||||
private Bitmap CreateBitmapFromMap(ITerrainChannel map)
|
||||
{
|
||||
Bitmap gradientmapLd = new Bitmap("defaultstripe.png");
|
||||
|
||||
int pallete = gradientmapLd.Height;
|
||||
|
||||
Bitmap bmp = new Bitmap(map.Width, map.Height);
|
||||
Color[] colours = new Color[pallete];
|
||||
|
||||
for (int i = 0; i < pallete; i++)
|
||||
{
|
||||
colours[i] = gradientmapLd.GetPixel(0, i);
|
||||
}
|
||||
|
||||
for (int y = 0; y < map.Height; y++)
|
||||
{
|
||||
for (int x = 0; x < map.Width; x++)
|
||||
{
|
||||
// 512 is the largest possible height before colours clamp
|
||||
int colorindex = (int) (Math.Max(Math.Min(1.0, map[x, y] / 512.0), 0.0) * (pallete - 1));
|
||||
bmp.SetPixel(x, map.Height - y - 1, colours[colorindex]);
|
||||
}
|
||||
}
|
||||
return bmp;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,148 +1,148 @@
|
|||
/*
|
||||
* 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 OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders
|
||||
{
|
||||
public class LLRAW : ITerrainLoader
|
||||
{
|
||||
#region ITerrainLoader Members
|
||||
|
||||
public ITerrainChannel LoadFile(string filename)
|
||||
{
|
||||
TerrainChannel retval = new TerrainChannel();
|
||||
|
||||
FileInfo file = new FileInfo(filename);
|
||||
FileStream s = file.Open(FileMode.Open, FileAccess.Read);
|
||||
BinaryReader bs = new BinaryReader(s);
|
||||
int x, y;
|
||||
for (y = 0; y < retval.Height; y++)
|
||||
{
|
||||
for (x = 0; x < retval.Width; x++)
|
||||
{
|
||||
retval[x, y] = (double) bs.ReadByte() * ((double) bs.ReadByte() / 127.0);
|
||||
bs.ReadBytes(11); // Advance the stream to next bytes.
|
||||
}
|
||||
}
|
||||
|
||||
bs.Close();
|
||||
s.Close();
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
public ITerrainChannel LoadFile(string filename, int x, int y, int fileWidth, int fileHeight, int w, int h)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void SaveFile(string filename, ITerrainChannel map)
|
||||
{
|
||||
FileInfo file = new FileInfo(filename);
|
||||
FileStream s = file.Open(FileMode.CreateNew, FileAccess.Write);
|
||||
BinaryWriter binStream = new BinaryWriter(s);
|
||||
|
||||
// Generate a smegging big lookup table to speed the operation up (it needs it)
|
||||
double[] lookupHeightTable = new double[65536];
|
||||
int i, j, x, y;
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
for (j = 0; j < 256; j++)
|
||||
{
|
||||
lookupHeightTable[i + (j * 256)] = ((double) i * ((double) j / 127.0));
|
||||
}
|
||||
}
|
||||
|
||||
// Output the calculated raw
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
double t = map[x, y];
|
||||
double min = double.MaxValue;
|
||||
int index = 0;
|
||||
|
||||
for (i = 0; i < 65536; i++)
|
||||
{
|
||||
if (Math.Abs(t - lookupHeightTable[i]) < min)
|
||||
{
|
||||
min = Math.Abs(t - lookupHeightTable[i]);
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
|
||||
byte red = (byte) (index & 0xFF);
|
||||
byte green = (byte) ((index >> 8) & 0xFF);
|
||||
byte blue = 20;
|
||||
byte alpha1 = 0; // Land Parcels
|
||||
byte alpha2 = 0; // For Sale Land
|
||||
byte alpha3 = 0; // Public Edit Object
|
||||
byte alpha4 = 0; // Public Edit Land
|
||||
byte alpha5 = 255; // Safe Land
|
||||
byte alpha6 = 255; // Flying Allowed
|
||||
byte alpha7 = 255; // Create Landmark
|
||||
byte alpha8 = 255; // Outside Scripts
|
||||
byte alpha9 = red;
|
||||
byte alpha10 = green;
|
||||
|
||||
binStream.Write(red);
|
||||
binStream.Write(green);
|
||||
binStream.Write(blue);
|
||||
binStream.Write(alpha1);
|
||||
binStream.Write(alpha2);
|
||||
binStream.Write(alpha3);
|
||||
binStream.Write(alpha4);
|
||||
binStream.Write(alpha5);
|
||||
binStream.Write(alpha6);
|
||||
binStream.Write(alpha7);
|
||||
binStream.Write(alpha8);
|
||||
binStream.Write(alpha9);
|
||||
binStream.Write(alpha10);
|
||||
}
|
||||
}
|
||||
|
||||
binStream.Close();
|
||||
s.Close();
|
||||
}
|
||||
|
||||
|
||||
public string FileExtension
|
||||
{
|
||||
get { return ".raw"; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "LL/SL RAW";
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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 OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders
|
||||
{
|
||||
public class LLRAW : ITerrainLoader
|
||||
{
|
||||
#region ITerrainLoader Members
|
||||
|
||||
public ITerrainChannel LoadFile(string filename)
|
||||
{
|
||||
TerrainChannel retval = new TerrainChannel();
|
||||
|
||||
FileInfo file = new FileInfo(filename);
|
||||
FileStream s = file.Open(FileMode.Open, FileAccess.Read);
|
||||
BinaryReader bs = new BinaryReader(s);
|
||||
int x, y;
|
||||
for (y = 0; y < retval.Height; y++)
|
||||
{
|
||||
for (x = 0; x < retval.Width; x++)
|
||||
{
|
||||
retval[x, y] = (double) bs.ReadByte() * ((double) bs.ReadByte() / 127.0);
|
||||
bs.ReadBytes(11); // Advance the stream to next bytes.
|
||||
}
|
||||
}
|
||||
|
||||
bs.Close();
|
||||
s.Close();
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
public ITerrainChannel LoadFile(string filename, int x, int y, int fileWidth, int fileHeight, int w, int h)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void SaveFile(string filename, ITerrainChannel map)
|
||||
{
|
||||
FileInfo file = new FileInfo(filename);
|
||||
FileStream s = file.Open(FileMode.CreateNew, FileAccess.Write);
|
||||
BinaryWriter binStream = new BinaryWriter(s);
|
||||
|
||||
// Generate a smegging big lookup table to speed the operation up (it needs it)
|
||||
double[] lookupHeightTable = new double[65536];
|
||||
int i, j, x, y;
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
for (j = 0; j < 256; j++)
|
||||
{
|
||||
lookupHeightTable[i + (j * 256)] = ((double) i * ((double) j / 127.0));
|
||||
}
|
||||
}
|
||||
|
||||
// Output the calculated raw
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
double t = map[x, y];
|
||||
double min = double.MaxValue;
|
||||
int index = 0;
|
||||
|
||||
for (i = 0; i < 65536; i++)
|
||||
{
|
||||
if (Math.Abs(t - lookupHeightTable[i]) < min)
|
||||
{
|
||||
min = Math.Abs(t - lookupHeightTable[i]);
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
|
||||
byte red = (byte) (index & 0xFF);
|
||||
byte green = (byte) ((index >> 8) & 0xFF);
|
||||
byte blue = 20;
|
||||
byte alpha1 = 0; // Land Parcels
|
||||
byte alpha2 = 0; // For Sale Land
|
||||
byte alpha3 = 0; // Public Edit Object
|
||||
byte alpha4 = 0; // Public Edit Land
|
||||
byte alpha5 = 255; // Safe Land
|
||||
byte alpha6 = 255; // Flying Allowed
|
||||
byte alpha7 = 255; // Create Landmark
|
||||
byte alpha8 = 255; // Outside Scripts
|
||||
byte alpha9 = red;
|
||||
byte alpha10 = green;
|
||||
|
||||
binStream.Write(red);
|
||||
binStream.Write(green);
|
||||
binStream.Write(blue);
|
||||
binStream.Write(alpha1);
|
||||
binStream.Write(alpha2);
|
||||
binStream.Write(alpha3);
|
||||
binStream.Write(alpha4);
|
||||
binStream.Write(alpha5);
|
||||
binStream.Write(alpha6);
|
||||
binStream.Write(alpha7);
|
||||
binStream.Write(alpha8);
|
||||
binStream.Write(alpha9);
|
||||
binStream.Write(alpha10);
|
||||
}
|
||||
}
|
||||
|
||||
binStream.Close();
|
||||
s.Close();
|
||||
}
|
||||
|
||||
|
||||
public string FileExtension
|
||||
{
|
||||
get { return ".raw"; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "LL/SL RAW";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,47 +1,47 @@
|
|||
/*
|
||||
* 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.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders
|
||||
{
|
||||
internal class PNG : GenericSystemDrawing
|
||||
{
|
||||
public override void SaveFile(string filename, ITerrainChannel map)
|
||||
{
|
||||
Bitmap colours = CreateGrayscaleBitmapFromMap(map);
|
||||
|
||||
colours.Save(filename, ImageFormat.Png);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "PNG";
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders
|
||||
{
|
||||
internal class PNG : GenericSystemDrawing
|
||||
{
|
||||
public override void SaveFile(string filename, ITerrainChannel map)
|
||||
{
|
||||
Bitmap colours = CreateGrayscaleBitmapFromMap(map);
|
||||
|
||||
colours.Save(filename, ImageFormat.Png);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "PNG";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,153 +1,153 @@
|
|||
/*
|
||||
* 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 OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders
|
||||
{
|
||||
public class RAW32 : ITerrainLoader
|
||||
{
|
||||
#region ITerrainLoader Members
|
||||
|
||||
public string FileExtension
|
||||
{
|
||||
get { return ".r32"; }
|
||||
}
|
||||
|
||||
public ITerrainChannel LoadFile(string filename)
|
||||
{
|
||||
TerrainChannel retval = new TerrainChannel();
|
||||
|
||||
FileInfo file = new FileInfo(filename);
|
||||
FileStream s = file.Open(FileMode.Open, FileAccess.Read);
|
||||
BinaryReader bs = new BinaryReader(s);
|
||||
int x, y;
|
||||
for (y = 0; y < retval.Height; y++)
|
||||
{
|
||||
for (x = 0; x < retval.Width; x++)
|
||||
{
|
||||
retval[x, y] = bs.ReadSingle();
|
||||
}
|
||||
}
|
||||
|
||||
bs.Close();
|
||||
s.Close();
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
public ITerrainChannel LoadFile(string filename, int offsetX, int offsetY, int fileWidth, int fileHeight, int sectionWidth, int sectionHeight)
|
||||
{
|
||||
TerrainChannel retval = new TerrainChannel(sectionWidth, sectionHeight);
|
||||
|
||||
FileInfo file = new FileInfo(filename);
|
||||
FileStream s = file.Open(FileMode.Open, FileAccess.Read);
|
||||
BinaryReader bs = new BinaryReader(s);
|
||||
|
||||
int currFileXOffset = 0;
|
||||
int currFileYOffset = 0;
|
||||
|
||||
// if our region isn't on the first Y section of the areas to be landscaped, then
|
||||
// advance to our section of the file
|
||||
while (currFileYOffset < offsetY)
|
||||
{
|
||||
// read a whole strip of regions
|
||||
int heightsToRead = sectionHeight * (fileWidth * sectionWidth);
|
||||
bs.ReadBytes(heightsToRead * 4); // because the floats are 4 bytes in the file
|
||||
currFileYOffset++;
|
||||
}
|
||||
|
||||
// got to the Y start offset within the file of our region
|
||||
// so read the file bits associated with our region
|
||||
int x, y;
|
||||
// for each Y within our Y offset
|
||||
for (y = 0; y < sectionHeight; y++)
|
||||
{
|
||||
currFileXOffset = 0;
|
||||
|
||||
// if our region isn't the first X section of the areas to be landscaped, then
|
||||
// advance the stream to the X start pos of our section in the file
|
||||
// i.e. eat X upto where we start
|
||||
while (currFileXOffset < offsetX)
|
||||
{
|
||||
bs.ReadBytes(sectionWidth * 4); // 4 bytes = single
|
||||
currFileXOffset++;
|
||||
}
|
||||
|
||||
// got to our X offset, so write our regions X line
|
||||
for (x = 0; x < sectionWidth; x++)
|
||||
{
|
||||
// Read a strip and continue
|
||||
retval[x, y] = bs.ReadSingle();
|
||||
}
|
||||
// record that we wrote it
|
||||
currFileXOffset++;
|
||||
|
||||
// if our region isn't the last X section of the areas to be landscaped, then
|
||||
// advance the stream to the end of this Y column
|
||||
while (currFileXOffset < fileWidth)
|
||||
{
|
||||
// eat the next regions x line
|
||||
bs.ReadBytes(sectionWidth * 4); // 4 bytes = single
|
||||
currFileXOffset++;
|
||||
}
|
||||
}
|
||||
|
||||
bs.Close();
|
||||
s.Close();
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
public void SaveFile(string filename, ITerrainChannel map)
|
||||
{
|
||||
FileInfo file = new FileInfo(filename);
|
||||
FileStream s = file.Open(FileMode.Create, FileAccess.Write);
|
||||
BinaryWriter bs = new BinaryWriter(s);
|
||||
|
||||
int x, y;
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
bs.Write((float) map[x, y]);
|
||||
}
|
||||
}
|
||||
|
||||
bs.Close();
|
||||
s.Close();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "RAW32";
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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 OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders
|
||||
{
|
||||
public class RAW32 : ITerrainLoader
|
||||
{
|
||||
#region ITerrainLoader Members
|
||||
|
||||
public string FileExtension
|
||||
{
|
||||
get { return ".r32"; }
|
||||
}
|
||||
|
||||
public ITerrainChannel LoadFile(string filename)
|
||||
{
|
||||
TerrainChannel retval = new TerrainChannel();
|
||||
|
||||
FileInfo file = new FileInfo(filename);
|
||||
FileStream s = file.Open(FileMode.Open, FileAccess.Read);
|
||||
BinaryReader bs = new BinaryReader(s);
|
||||
int x, y;
|
||||
for (y = 0; y < retval.Height; y++)
|
||||
{
|
||||
for (x = 0; x < retval.Width; x++)
|
||||
{
|
||||
retval[x, y] = bs.ReadSingle();
|
||||
}
|
||||
}
|
||||
|
||||
bs.Close();
|
||||
s.Close();
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
public ITerrainChannel LoadFile(string filename, int offsetX, int offsetY, int fileWidth, int fileHeight, int sectionWidth, int sectionHeight)
|
||||
{
|
||||
TerrainChannel retval = new TerrainChannel(sectionWidth, sectionHeight);
|
||||
|
||||
FileInfo file = new FileInfo(filename);
|
||||
FileStream s = file.Open(FileMode.Open, FileAccess.Read);
|
||||
BinaryReader bs = new BinaryReader(s);
|
||||
|
||||
int currFileXOffset = 0;
|
||||
int currFileYOffset = 0;
|
||||
|
||||
// if our region isn't on the first Y section of the areas to be landscaped, then
|
||||
// advance to our section of the file
|
||||
while (currFileYOffset < offsetY)
|
||||
{
|
||||
// read a whole strip of regions
|
||||
int heightsToRead = sectionHeight * (fileWidth * sectionWidth);
|
||||
bs.ReadBytes(heightsToRead * 4); // because the floats are 4 bytes in the file
|
||||
currFileYOffset++;
|
||||
}
|
||||
|
||||
// got to the Y start offset within the file of our region
|
||||
// so read the file bits associated with our region
|
||||
int x, y;
|
||||
// for each Y within our Y offset
|
||||
for (y = 0; y < sectionHeight; y++)
|
||||
{
|
||||
currFileXOffset = 0;
|
||||
|
||||
// if our region isn't the first X section of the areas to be landscaped, then
|
||||
// advance the stream to the X start pos of our section in the file
|
||||
// i.e. eat X upto where we start
|
||||
while (currFileXOffset < offsetX)
|
||||
{
|
||||
bs.ReadBytes(sectionWidth * 4); // 4 bytes = single
|
||||
currFileXOffset++;
|
||||
}
|
||||
|
||||
// got to our X offset, so write our regions X line
|
||||
for (x = 0; x < sectionWidth; x++)
|
||||
{
|
||||
// Read a strip and continue
|
||||
retval[x, y] = bs.ReadSingle();
|
||||
}
|
||||
// record that we wrote it
|
||||
currFileXOffset++;
|
||||
|
||||
// if our region isn't the last X section of the areas to be landscaped, then
|
||||
// advance the stream to the end of this Y column
|
||||
while (currFileXOffset < fileWidth)
|
||||
{
|
||||
// eat the next regions x line
|
||||
bs.ReadBytes(sectionWidth * 4); // 4 bytes = single
|
||||
currFileXOffset++;
|
||||
}
|
||||
}
|
||||
|
||||
bs.Close();
|
||||
s.Close();
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
public void SaveFile(string filename, ITerrainChannel map)
|
||||
{
|
||||
FileInfo file = new FileInfo(filename);
|
||||
FileStream s = file.Open(FileMode.Create, FileAccess.Write);
|
||||
BinaryWriter bs = new BinaryWriter(s);
|
||||
|
||||
int x, y;
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
bs.Write((float) map[x, y]);
|
||||
}
|
||||
}
|
||||
|
||||
bs.Close();
|
||||
s.Close();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "RAW32";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,47 +1,47 @@
|
|||
/*
|
||||
* 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.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders
|
||||
{
|
||||
internal class TIFF : GenericSystemDrawing
|
||||
{
|
||||
public override void SaveFile(string filename, ITerrainChannel map)
|
||||
{
|
||||
Bitmap colours = CreateGrayscaleBitmapFromMap(map);
|
||||
|
||||
colours.Save(filename, ImageFormat.Tiff);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "TIFF";
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders
|
||||
{
|
||||
internal class TIFF : GenericSystemDrawing
|
||||
{
|
||||
public override void SaveFile(string filename, ITerrainChannel map)
|
||||
{
|
||||
Bitmap colours = CreateGrayscaleBitmapFromMap(map);
|
||||
|
||||
colours.Save(filename, ImageFormat.Tiff);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "TIFF";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,127 +1,127 @@
|
|||
/*
|
||||
* 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.Text;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders
|
||||
{
|
||||
/// <summary>
|
||||
/// Terragen File Format Loader
|
||||
/// Built from specification at
|
||||
/// http://www.planetside.co.uk/terragen/dev/tgterrain.html
|
||||
/// </summary>
|
||||
internal class Terragen : ITerrainLoader
|
||||
{
|
||||
#region ITerrainLoader Members
|
||||
|
||||
public ITerrainChannel LoadFile(string filename)
|
||||
{
|
||||
TerrainChannel retval = new TerrainChannel();
|
||||
|
||||
FileInfo file = new FileInfo(filename);
|
||||
FileStream s = file.Open(FileMode.Open, FileAccess.Read);
|
||||
BinaryReader bs = new BinaryReader(s);
|
||||
|
||||
bool eof = false;
|
||||
if (ASCIIEncoding.ASCII.GetString(bs.ReadBytes(16)) == "TERRAGENTERRAIN ")
|
||||
{
|
||||
// Terragen file
|
||||
while (eof == false)
|
||||
{
|
||||
int w = 256;
|
||||
int h = 256;
|
||||
string tmp = ASCIIEncoding.ASCII.GetString(bs.ReadBytes(4));
|
||||
switch (tmp)
|
||||
{
|
||||
case "SIZE":
|
||||
int sztmp = bs.ReadInt16() + 1;
|
||||
w = sztmp;
|
||||
h = sztmp;
|
||||
bs.ReadInt16();
|
||||
break;
|
||||
case "XPTS":
|
||||
w = bs.ReadInt16();
|
||||
bs.ReadInt16();
|
||||
break;
|
||||
case "YPTS":
|
||||
h = bs.ReadInt16();
|
||||
bs.ReadInt16();
|
||||
break;
|
||||
case "ALTW":
|
||||
eof = true;
|
||||
Int16 heightScale = bs.ReadInt16();
|
||||
Int16 baseHeight = bs.ReadInt16();
|
||||
retval = new TerrainChannel(w, h);
|
||||
int x, y;
|
||||
for (x = 0; x < w; x++)
|
||||
{
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
retval[x, y] = (double) baseHeight + (double) bs.ReadInt16() * (double) heightScale / 65536.0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
bs.ReadInt32();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bs.Close();
|
||||
s.Close();
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
public void SaveFile(string filename, ITerrainChannel map)
|
||||
{
|
||||
char[] header = "TERRAGENTERRAIN".ToCharArray();
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public string FileExtension
|
||||
{
|
||||
get { return ".ter"; }
|
||||
}
|
||||
|
||||
public ITerrainChannel LoadFile(string filename, int x, int y, int fileWidth, int fileHeight, int w, int h)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "Terragen";
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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.Text;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders
|
||||
{
|
||||
/// <summary>
|
||||
/// Terragen File Format Loader
|
||||
/// Built from specification at
|
||||
/// http://www.planetside.co.uk/terragen/dev/tgterrain.html
|
||||
/// </summary>
|
||||
internal class Terragen : ITerrainLoader
|
||||
{
|
||||
#region ITerrainLoader Members
|
||||
|
||||
public ITerrainChannel LoadFile(string filename)
|
||||
{
|
||||
TerrainChannel retval = new TerrainChannel();
|
||||
|
||||
FileInfo file = new FileInfo(filename);
|
||||
FileStream s = file.Open(FileMode.Open, FileAccess.Read);
|
||||
BinaryReader bs = new BinaryReader(s);
|
||||
|
||||
bool eof = false;
|
||||
if (ASCIIEncoding.ASCII.GetString(bs.ReadBytes(16)) == "TERRAGENTERRAIN ")
|
||||
{
|
||||
// Terragen file
|
||||
while (eof == false)
|
||||
{
|
||||
int w = 256;
|
||||
int h = 256;
|
||||
string tmp = ASCIIEncoding.ASCII.GetString(bs.ReadBytes(4));
|
||||
switch (tmp)
|
||||
{
|
||||
case "SIZE":
|
||||
int sztmp = bs.ReadInt16() + 1;
|
||||
w = sztmp;
|
||||
h = sztmp;
|
||||
bs.ReadInt16();
|
||||
break;
|
||||
case "XPTS":
|
||||
w = bs.ReadInt16();
|
||||
bs.ReadInt16();
|
||||
break;
|
||||
case "YPTS":
|
||||
h = bs.ReadInt16();
|
||||
bs.ReadInt16();
|
||||
break;
|
||||
case "ALTW":
|
||||
eof = true;
|
||||
Int16 heightScale = bs.ReadInt16();
|
||||
Int16 baseHeight = bs.ReadInt16();
|
||||
retval = new TerrainChannel(w, h);
|
||||
int x, y;
|
||||
for (x = 0; x < w; x++)
|
||||
{
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
retval[x, y] = (double) baseHeight + (double) bs.ReadInt16() * (double) heightScale / 65536.0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
bs.ReadInt32();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bs.Close();
|
||||
s.Close();
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
public void SaveFile(string filename, ITerrainChannel map)
|
||||
{
|
||||
char[] header = "TERRAGENTERRAIN".ToCharArray();
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public string FileExtension
|
||||
{
|
||||
get { return ".ter"; }
|
||||
}
|
||||
|
||||
public ITerrainChannel LoadFile(string filename, int x, int y, int fileWidth, int fileHeight, int w, int h)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "Terragen";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,71 +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 OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes
|
||||
{
|
||||
public class FlattenArea : ITerrainFloodEffect
|
||||
{
|
||||
#region ITerrainFloodEffect Members
|
||||
|
||||
public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength)
|
||||
{
|
||||
double sum = 0.0;
|
||||
double steps = 0.0;
|
||||
double avg;
|
||||
|
||||
int x, y;
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
if (fillArea[x, y])
|
||||
{
|
||||
sum += map[x, y];
|
||||
steps += 1.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
avg = sum / steps;
|
||||
|
||||
double str = 0.1 * strength; // == 0.2 in the default client
|
||||
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
if (fillArea[x, y])
|
||||
map[x, y] = (map[x, y] * (1.0 - str)) + (avg * str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
/*
|
||||
* 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.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes
|
||||
{
|
||||
public class FlattenArea : ITerrainFloodEffect
|
||||
{
|
||||
#region ITerrainFloodEffect Members
|
||||
|
||||
public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength)
|
||||
{
|
||||
double sum = 0.0;
|
||||
double steps = 0.0;
|
||||
double avg;
|
||||
|
||||
int x, y;
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
if (fillArea[x, y])
|
||||
{
|
||||
sum += map[x, y];
|
||||
steps += 1.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
avg = sum / steps;
|
||||
|
||||
double str = 0.1 * strength; // == 0.2 in the default client
|
||||
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
if (fillArea[x, y])
|
||||
map[x, y] = (map[x, y] * (1.0 - str)) + (avg * str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -1,54 +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.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes
|
||||
{
|
||||
public class LowerArea : ITerrainFloodEffect
|
||||
{
|
||||
#region ITerrainFloodEffect Members
|
||||
|
||||
public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength)
|
||||
{
|
||||
int x;
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
int y;
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
if (fillArea[x, y])
|
||||
{
|
||||
map[x, y] -= strength;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
/*
|
||||
* 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.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes
|
||||
{
|
||||
public class LowerArea : ITerrainFloodEffect
|
||||
{
|
||||
#region ITerrainFloodEffect Members
|
||||
|
||||
public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength)
|
||||
{
|
||||
int x;
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
int y;
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
if (fillArea[x, y])
|
||||
{
|
||||
map[x, y] -= strength;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -1,56 +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 OpenSim.Framework;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes
|
||||
{
|
||||
public class NoiseArea : ITerrainFloodEffect
|
||||
{
|
||||
#region ITerrainFloodEffect Members
|
||||
|
||||
public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength)
|
||||
{
|
||||
int x, y;
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
if (fillArea[x, y])
|
||||
{
|
||||
double noise = TerrainUtil.PerlinNoise2D((double) x / Constants.RegionSize, (double) y / Constants.RegionSize, 8, 1.0);
|
||||
|
||||
map[x, y] += noise * strength;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
/*
|
||||
* 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;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes
|
||||
{
|
||||
public class NoiseArea : ITerrainFloodEffect
|
||||
{
|
||||
#region ITerrainFloodEffect Members
|
||||
|
||||
public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength)
|
||||
{
|
||||
int x, y;
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
if (fillArea[x, y])
|
||||
{
|
||||
double noise = TerrainUtil.PerlinNoise2D((double) x / Constants.RegionSize, (double) y / Constants.RegionSize, 8, 1.0);
|
||||
|
||||
map[x, y] += noise * strength;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -1,53 +1,53 @@
|
|||
/*
|
||||
* 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.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes
|
||||
{
|
||||
public class RaiseArea : ITerrainFloodEffect
|
||||
{
|
||||
#region ITerrainFloodEffect Members
|
||||
|
||||
public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength)
|
||||
{
|
||||
int x, y;
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
if (fillArea[x, y])
|
||||
{
|
||||
map[x, y] += strength;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
/*
|
||||
* 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.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes
|
||||
{
|
||||
public class RaiseArea : ITerrainFloodEffect
|
||||
{
|
||||
#region ITerrainFloodEffect Members
|
||||
|
||||
public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength)
|
||||
{
|
||||
int x, y;
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
if (fillArea[x, y])
|
||||
{
|
||||
map[x, y] += strength;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -1,60 +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 OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes
|
||||
{
|
||||
public class RevertArea : ITerrainFloodEffect
|
||||
{
|
||||
private readonly ITerrainChannel m_revertmap;
|
||||
|
||||
public RevertArea(ITerrainChannel revertmap)
|
||||
{
|
||||
m_revertmap = revertmap;
|
||||
}
|
||||
|
||||
#region ITerrainFloodEffect Members
|
||||
|
||||
public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength)
|
||||
{
|
||||
int x, y;
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
if (fillArea[x, y])
|
||||
{
|
||||
map[x, y] = (map[x, y] * (1.0 - strength)) + (m_revertmap[x, y] * strength);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
/*
|
||||
* 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.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes
|
||||
{
|
||||
public class RevertArea : ITerrainFloodEffect
|
||||
{
|
||||
private readonly ITerrainChannel m_revertmap;
|
||||
|
||||
public RevertArea(ITerrainChannel revertmap)
|
||||
{
|
||||
m_revertmap = revertmap;
|
||||
}
|
||||
|
||||
#region ITerrainFloodEffect Members
|
||||
|
||||
public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength)
|
||||
{
|
||||
int x, y;
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
if (fillArea[x, y])
|
||||
{
|
||||
map[x, y] = (map[x, y] * (1.0 - strength)) + (m_revertmap[x, y] * strength);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -1,114 +1,114 @@
|
|||
/*
|
||||
* 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.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes
|
||||
{
|
||||
public class SmoothArea : ITerrainFloodEffect
|
||||
{
|
||||
#region ITerrainFloodEffect Members
|
||||
|
||||
public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength)
|
||||
{
|
||||
double area = strength;
|
||||
double step = strength / 4.0;
|
||||
|
||||
double[,] manipulate = new double[map.Width,map.Height];
|
||||
int x, y;
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
if (!fillArea[x, y])
|
||||
continue;
|
||||
|
||||
double average = 0.0;
|
||||
int avgsteps = 0;
|
||||
|
||||
double n;
|
||||
for (n = 0.0 - area; n < area; n += step)
|
||||
{
|
||||
double l;
|
||||
for (l = 0.0 - area; l < area; l += step)
|
||||
{
|
||||
avgsteps++;
|
||||
average += GetBilinearInterpolate(x + n, y + l, map);
|
||||
}
|
||||
}
|
||||
|
||||
manipulate[x, y] = average / avgsteps;
|
||||
}
|
||||
}
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
if (!fillArea[x, y])
|
||||
continue;
|
||||
|
||||
map[x, y] = manipulate[x, y];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private static double GetBilinearInterpolate(double x, double y, ITerrainChannel map)
|
||||
{
|
||||
int w = map.Width;
|
||||
int h = map.Height;
|
||||
|
||||
if (x > w - 2.0)
|
||||
x = w - 2.0;
|
||||
if (y > h - 2.0)
|
||||
y = h - 2.0;
|
||||
if (x < 0.0)
|
||||
x = 0.0;
|
||||
if (y < 0.0)
|
||||
y = 0.0;
|
||||
|
||||
int stepSize = 1;
|
||||
double h00 = map[(int) x, (int) y];
|
||||
double h10 = map[(int) x + stepSize, (int) y];
|
||||
double h01 = map[(int) x, (int) y + stepSize];
|
||||
double h11 = map[(int) x + stepSize, (int) y + stepSize];
|
||||
double h1 = h00;
|
||||
double h2 = h10;
|
||||
double h3 = h01;
|
||||
double h4 = h11;
|
||||
double a00 = h1;
|
||||
double a10 = h2 - h1;
|
||||
double a01 = h3 - h1;
|
||||
double a11 = h1 - h2 - h3 + h4;
|
||||
double partialx = x - (int) x;
|
||||
double partialz = y - (int) y;
|
||||
double hi = a00 + (a10 * partialx) + (a01 * partialz) + (a11 * partialx * partialz);
|
||||
return hi;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes
|
||||
{
|
||||
public class SmoothArea : ITerrainFloodEffect
|
||||
{
|
||||
#region ITerrainFloodEffect Members
|
||||
|
||||
public void FloodEffect(ITerrainChannel map, bool[,] fillArea, double strength)
|
||||
{
|
||||
double area = strength;
|
||||
double step = strength / 4.0;
|
||||
|
||||
double[,] manipulate = new double[map.Width,map.Height];
|
||||
int x, y;
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
if (!fillArea[x, y])
|
||||
continue;
|
||||
|
||||
double average = 0.0;
|
||||
int avgsteps = 0;
|
||||
|
||||
double n;
|
||||
for (n = 0.0 - area; n < area; n += step)
|
||||
{
|
||||
double l;
|
||||
for (l = 0.0 - area; l < area; l += step)
|
||||
{
|
||||
avgsteps++;
|
||||
average += GetBilinearInterpolate(x + n, y + l, map);
|
||||
}
|
||||
}
|
||||
|
||||
manipulate[x, y] = average / avgsteps;
|
||||
}
|
||||
}
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
if (!fillArea[x, y])
|
||||
continue;
|
||||
|
||||
map[x, y] = manipulate[x, y];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private static double GetBilinearInterpolate(double x, double y, ITerrainChannel map)
|
||||
{
|
||||
int w = map.Width;
|
||||
int h = map.Height;
|
||||
|
||||
if (x > w - 2.0)
|
||||
x = w - 2.0;
|
||||
if (y > h - 2.0)
|
||||
y = h - 2.0;
|
||||
if (x < 0.0)
|
||||
x = 0.0;
|
||||
if (y < 0.0)
|
||||
y = 0.0;
|
||||
|
||||
int stepSize = 1;
|
||||
double h00 = map[(int) x, (int) y];
|
||||
double h10 = map[(int) x + stepSize, (int) y];
|
||||
double h01 = map[(int) x, (int) y + stepSize];
|
||||
double h11 = map[(int) x + stepSize, (int) y + stepSize];
|
||||
double h1 = h00;
|
||||
double h2 = h10;
|
||||
double h3 = h01;
|
||||
double h4 = h11;
|
||||
double a00 = h1;
|
||||
double a10 = h2 - h1;
|
||||
double a01 = h3 - h1;
|
||||
double a11 = h1 - h2 - h3 + h4;
|
||||
double partialx = x - (int) x;
|
||||
double partialz = y - (int) y;
|
||||
double hi = a00 + (a10 * partialx) + (a01 * partialz) + (a11 * partialx * partialz);
|
||||
return hi;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,36 +1,36 @@
|
|||
/*
|
||||
* 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.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain
|
||||
{
|
||||
public interface ITerrainEffect
|
||||
{
|
||||
void RunEffect(ITerrainChannel map);
|
||||
}
|
||||
/*
|
||||
* 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.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain
|
||||
{
|
||||
public interface ITerrainEffect
|
||||
{
|
||||
void RunEffect(ITerrainChannel map);
|
||||
}
|
||||
}
|
|
@ -1,37 +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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain
|
||||
{
|
||||
public interface ITerrainFloodEffect
|
||||
{
|
||||
void FloodEffect(ITerrainChannel map, Boolean[,] fillArea, double strength);
|
||||
}
|
||||
/*
|
||||
* 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 OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain
|
||||
{
|
||||
public interface ITerrainFloodEffect
|
||||
{
|
||||
void FloodEffect(ITerrainChannel map, Boolean[,] fillArea, double strength);
|
||||
}
|
||||
}
|
|
@ -1,39 +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.
|
||||
*/
|
||||
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain
|
||||
{
|
||||
public interface ITerrainLoader
|
||||
{
|
||||
string FileExtension { get; }
|
||||
ITerrainChannel LoadFile(string filename);
|
||||
ITerrainChannel LoadFile(string filename, int fileStartX, int fileStartY, int fileWidth, int fileHeight, int sectionWidth, int sectionHeight);
|
||||
void SaveFile(string filename, ITerrainChannel map);
|
||||
}
|
||||
/*
|
||||
* 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.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain
|
||||
{
|
||||
public interface ITerrainLoader
|
||||
{
|
||||
string FileExtension { get; }
|
||||
ITerrainChannel LoadFile(string filename);
|
||||
ITerrainChannel LoadFile(string filename, int fileStartX, int fileStartY, int fileWidth, int fileHeight, int sectionWidth, int sectionHeight);
|
||||
void SaveFile(string filename, ITerrainChannel map);
|
||||
}
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
namespace OpenSim.Region.Environment.Modules.World.Terrain
|
||||
{
|
||||
public interface ITerrainModule
|
||||
{
|
||||
void LoadFromFile(string filename);
|
||||
void SaveToFile(string filename);
|
||||
}
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain
|
||||
{
|
||||
public interface ITerrainModule
|
||||
{
|
||||
void LoadFromFile(string filename);
|
||||
void SaveToFile(string filename);
|
||||
}
|
||||
}
|
|
@ -1,36 +1,36 @@
|
|||
/*
|
||||
* 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.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain
|
||||
{
|
||||
public interface ITerrainPaintableEffect
|
||||
{
|
||||
void PaintEffect(ITerrainChannel map, double x, double y, double strength, double duration);
|
||||
}
|
||||
/*
|
||||
* 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.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain
|
||||
{
|
||||
public interface ITerrainPaintableEffect
|
||||
{
|
||||
void PaintEffect(ITerrainChannel map, double x, double y, double strength, double duration);
|
||||
}
|
||||
}
|
|
@ -1,168 +1,168 @@
|
|||
/*
|
||||
* 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.Drawing;
|
||||
using Nini.Config;
|
||||
using OpenJPEGNet;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain
|
||||
{
|
||||
internal class MapImageModule : IMapImageGenerator, IRegionModule
|
||||
{
|
||||
private Scene m_scene;
|
||||
|
||||
#region IMapImageGenerator Members
|
||||
|
||||
public byte[] WriteJpeg2000Image(string gradientmap)
|
||||
{
|
||||
byte[] imageData = null;
|
||||
|
||||
Bitmap bmp = TerrainToBitmap(gradientmap);
|
||||
|
||||
try
|
||||
{
|
||||
imageData = OpenJPEG.EncodeFromImage(bmp, true);
|
||||
}
|
||||
catch (Exception e) // LEGIT: Catching problems caused by OpenJPEG p/invoke
|
||||
{
|
||||
Console.WriteLine("Failed generating terrain map: " + e);
|
||||
}
|
||||
|
||||
return imageData;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource source)
|
||||
{
|
||||
m_scene = scene;
|
||||
m_scene.RegisterModuleInterface<IMapImageGenerator>(this);
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "MapImageModule"; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void ShadeBuildings(ref Bitmap map)
|
||||
{
|
||||
lock (map)
|
||||
{
|
||||
lock (m_scene.Entities)
|
||||
{
|
||||
foreach (EntityBase entity in m_scene.Entities.Values)
|
||||
{
|
||||
if (entity is SceneObjectGroup)
|
||||
{
|
||||
SceneObjectGroup sog = (SceneObjectGroup) entity;
|
||||
|
||||
foreach (SceneObjectPart primitive in sog.Children.Values)
|
||||
{
|
||||
int x, y, w, h;
|
||||
x = (int) (primitive.AbsolutePosition.X - (primitive.Scale.X / 2));
|
||||
y = (int) (primitive.AbsolutePosition.Y - (primitive.Scale.Y / 2));
|
||||
w = (int) primitive.Scale.X;
|
||||
h = (int) primitive.Scale.Y;
|
||||
|
||||
int dx;
|
||||
for (dx = x; dx < x + w; dx++)
|
||||
{
|
||||
int dy;
|
||||
for (dy = y; dy < y + h; dy++)
|
||||
{
|
||||
if (x < 0 || y < 0)
|
||||
continue;
|
||||
if (x >= map.Width || y >= map.Height)
|
||||
continue;
|
||||
|
||||
map.SetPixel(dx, dy, Color.DarkGray);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Bitmap TerrainToBitmap(string gradientmap)
|
||||
{
|
||||
Bitmap gradientmapLd = new Bitmap(gradientmap);
|
||||
|
||||
int pallete = gradientmapLd.Height;
|
||||
|
||||
Bitmap bmp = new Bitmap(m_scene.Heightmap.Width, m_scene.Heightmap.Height);
|
||||
Color[] colours = new Color[pallete];
|
||||
|
||||
for (int i = 0; i < pallete; i++)
|
||||
{
|
||||
colours[i] = gradientmapLd.GetPixel(0, i);
|
||||
}
|
||||
|
||||
lock (m_scene.Heightmap)
|
||||
{
|
||||
ITerrainChannel copy = m_scene.Heightmap;
|
||||
for (int y = 0; y < copy.Height; y++)
|
||||
{
|
||||
for (int x = 0; x < copy.Width; x++)
|
||||
{
|
||||
// 512 is the largest possible height before colours clamp
|
||||
int colorindex = (int) (Math.Max(Math.Min(1.0, copy[x, y] / 512.0), 0.0) * (pallete - 1));
|
||||
|
||||
// Handle error conditions
|
||||
if (colorindex > pallete - 1 || colorindex < 0)
|
||||
bmp.SetPixel(x, copy.Height - y - 1, Color.Red);
|
||||
else
|
||||
bmp.SetPixel(x, copy.Height - y - 1, colours[colorindex]);
|
||||
}
|
||||
}
|
||||
ShadeBuildings(ref bmp);
|
||||
return bmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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.Drawing;
|
||||
using Nini.Config;
|
||||
using OpenJPEGNet;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain
|
||||
{
|
||||
internal class MapImageModule : IMapImageGenerator, IRegionModule
|
||||
{
|
||||
private Scene m_scene;
|
||||
|
||||
#region IMapImageGenerator Members
|
||||
|
||||
public byte[] WriteJpeg2000Image(string gradientmap)
|
||||
{
|
||||
byte[] imageData = null;
|
||||
|
||||
Bitmap bmp = TerrainToBitmap(gradientmap);
|
||||
|
||||
try
|
||||
{
|
||||
imageData = OpenJPEG.EncodeFromImage(bmp, true);
|
||||
}
|
||||
catch (Exception e) // LEGIT: Catching problems caused by OpenJPEG p/invoke
|
||||
{
|
||||
Console.WriteLine("Failed generating terrain map: " + e);
|
||||
}
|
||||
|
||||
return imageData;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource source)
|
||||
{
|
||||
m_scene = scene;
|
||||
m_scene.RegisterModuleInterface<IMapImageGenerator>(this);
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "MapImageModule"; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void ShadeBuildings(ref Bitmap map)
|
||||
{
|
||||
lock (map)
|
||||
{
|
||||
lock (m_scene.Entities)
|
||||
{
|
||||
foreach (EntityBase entity in m_scene.Entities.Values)
|
||||
{
|
||||
if (entity is SceneObjectGroup)
|
||||
{
|
||||
SceneObjectGroup sog = (SceneObjectGroup) entity;
|
||||
|
||||
foreach (SceneObjectPart primitive in sog.Children.Values)
|
||||
{
|
||||
int x, y, w, h;
|
||||
x = (int) (primitive.AbsolutePosition.X - (primitive.Scale.X / 2));
|
||||
y = (int) (primitive.AbsolutePosition.Y - (primitive.Scale.Y / 2));
|
||||
w = (int) primitive.Scale.X;
|
||||
h = (int) primitive.Scale.Y;
|
||||
|
||||
int dx;
|
||||
for (dx = x; dx < x + w; dx++)
|
||||
{
|
||||
int dy;
|
||||
for (dy = y; dy < y + h; dy++)
|
||||
{
|
||||
if (x < 0 || y < 0)
|
||||
continue;
|
||||
if (x >= map.Width || y >= map.Height)
|
||||
continue;
|
||||
|
||||
map.SetPixel(dx, dy, Color.DarkGray);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Bitmap TerrainToBitmap(string gradientmap)
|
||||
{
|
||||
Bitmap gradientmapLd = new Bitmap(gradientmap);
|
||||
|
||||
int pallete = gradientmapLd.Height;
|
||||
|
||||
Bitmap bmp = new Bitmap(m_scene.Heightmap.Width, m_scene.Heightmap.Height);
|
||||
Color[] colours = new Color[pallete];
|
||||
|
||||
for (int i = 0; i < pallete; i++)
|
||||
{
|
||||
colours[i] = gradientmapLd.GetPixel(0, i);
|
||||
}
|
||||
|
||||
lock (m_scene.Heightmap)
|
||||
{
|
||||
ITerrainChannel copy = m_scene.Heightmap;
|
||||
for (int y = 0; y < copy.Height; y++)
|
||||
{
|
||||
for (int x = 0; x < copy.Width; x++)
|
||||
{
|
||||
// 512 is the largest possible height before colours clamp
|
||||
int colorindex = (int) (Math.Max(Math.Min(1.0, copy[x, y] / 512.0), 0.0) * (pallete - 1));
|
||||
|
||||
// Handle error conditions
|
||||
if (colorindex > pallete - 1 || colorindex < 0)
|
||||
bmp.SetPixel(x, copy.Height - y - 1, Color.Red);
|
||||
else
|
||||
bmp.SetPixel(x, copy.Height - y - 1, colours[colorindex]);
|
||||
}
|
||||
}
|
||||
ShadeBuildings(ref bmp);
|
||||
return bmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,312 +1,312 @@
|
|||
/*
|
||||
* 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 OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes
|
||||
{
|
||||
/// <summary>
|
||||
/// Hydraulic Erosion Brush
|
||||
/// </summary>
|
||||
public class ErodeSphere : ITerrainPaintableEffect
|
||||
{
|
||||
private double rainHeight = 0.2;
|
||||
private int rounds = 10;
|
||||
private NeighbourSystem type = NeighbourSystem.Moore; // Parameter
|
||||
private double waterSaturation = 0.30; // Can carry 1% of water in height
|
||||
|
||||
#region Supporting Functions
|
||||
|
||||
private int[] Neighbours(NeighbourSystem type, int index)
|
||||
{
|
||||
int[] coord = new int[2];
|
||||
|
||||
index++;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case NeighbourSystem.Moore:
|
||||
switch (index)
|
||||
{
|
||||
case 1:
|
||||
coord[0] = -1;
|
||||
coord[1] = -1;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
coord[0] = -0;
|
||||
coord[1] = -1;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
coord[0] = +1;
|
||||
coord[1] = -1;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
coord[0] = -1;
|
||||
coord[1] = -0;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
coord[0] = -0;
|
||||
coord[1] = -0;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
coord[0] = +1;
|
||||
coord[1] = -0;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
coord[0] = -1;
|
||||
coord[1] = +1;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
coord[0] = -0;
|
||||
coord[1] = +1;
|
||||
break;
|
||||
|
||||
case 9:
|
||||
coord[0] = +1;
|
||||
coord[1] = +1;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case NeighbourSystem.VonNeumann:
|
||||
switch (index)
|
||||
{
|
||||
case 1:
|
||||
coord[0] = 0;
|
||||
coord[1] = -1;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
coord[0] = -1;
|
||||
coord[1] = 0;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
coord[0] = +1;
|
||||
coord[1] = 0;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
coord[0] = 0;
|
||||
coord[1] = +1;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
coord[0] = -0;
|
||||
coord[1] = -0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return coord;
|
||||
}
|
||||
|
||||
private enum NeighbourSystem
|
||||
{
|
||||
Moore,
|
||||
VonNeumann
|
||||
} ;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ITerrainPaintableEffect Members
|
||||
|
||||
public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
|
||||
{
|
||||
strength = TerrainUtil.MetersToSphericalStrength(strength);
|
||||
|
||||
int x, y;
|
||||
// Using one 'rain' round for this, so skipping a useless loop
|
||||
// Will need to adapt back in for the Flood brush
|
||||
|
||||
ITerrainChannel water = new TerrainChannel(map.Width, map.Height);
|
||||
ITerrainChannel sediment = new TerrainChannel(map.Width, map.Height);
|
||||
|
||||
// Fill with rain
|
||||
for (x = 0; x < water.Width; x++)
|
||||
for (y = 0; y < water.Height; y++)
|
||||
water[x, y] = Math.Max(0.0, TerrainUtil.SphericalFactor(x, y, rx, ry, strength) * rainHeight * duration);
|
||||
|
||||
for (int i = 0; i < rounds; i++)
|
||||
{
|
||||
// Erode underlying terrain
|
||||
for (x = 0; x < water.Width; x++)
|
||||
{
|
||||
for (y = 0; y < water.Height; y++)
|
||||
{
|
||||
double solConst = (1.0 / rounds);
|
||||
double sedDelta = water[x, y] * solConst;
|
||||
map[x, y] -= sedDelta;
|
||||
sediment[x, y] += sedDelta;
|
||||
}
|
||||
}
|
||||
|
||||
// Move water
|
||||
for (x = 0; x < water.Width; x++)
|
||||
{
|
||||
for (y = 0; y < water.Height; y++)
|
||||
{
|
||||
if (water[x, y] <= 0)
|
||||
continue;
|
||||
|
||||
// Step 1. Calculate average of neighbours
|
||||
|
||||
int neighbours = 0;
|
||||
double altitudeTotal = 0.0;
|
||||
double altitudeMe = map[x, y] + water[x, y];
|
||||
|
||||
int NEIGHBOUR_ME = 4;
|
||||
|
||||
int NEIGHBOUR_MAX = type == NeighbourSystem.Moore ? 9 : 5;
|
||||
|
||||
for (int j = 0; j < NEIGHBOUR_MAX; j++)
|
||||
{
|
||||
if (j != NEIGHBOUR_ME)
|
||||
{
|
||||
int[] coords = Neighbours(type, j);
|
||||
|
||||
coords[0] += x;
|
||||
coords[1] += y;
|
||||
|
||||
if (coords[0] > map.Width - 1)
|
||||
continue;
|
||||
if (coords[1] > map.Height - 1)
|
||||
continue;
|
||||
if (coords[0] < 0)
|
||||
continue;
|
||||
if (coords[1] < 0)
|
||||
continue;
|
||||
|
||||
// Calculate total height of this neighbour
|
||||
double altitudeNeighbour = water[coords[0], coords[1]] + map[coords[0], coords[1]];
|
||||
|
||||
// If it's greater than me...
|
||||
if (altitudeNeighbour - altitudeMe < 0)
|
||||
{
|
||||
// Add it to our calculations
|
||||
neighbours++;
|
||||
altitudeTotal += altitudeNeighbour;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (neighbours == 0)
|
||||
continue;
|
||||
|
||||
double altitudeAvg = altitudeTotal / neighbours;
|
||||
|
||||
// Step 2. Allocate water to neighbours.
|
||||
for (int j = 0; j < NEIGHBOUR_MAX; j++)
|
||||
{
|
||||
if (j != NEIGHBOUR_ME)
|
||||
{
|
||||
int[] coords = Neighbours(type, j);
|
||||
|
||||
coords[0] += x;
|
||||
coords[1] += y;
|
||||
|
||||
if (coords[0] > map.Width - 1)
|
||||
continue;
|
||||
if (coords[1] > map.Height - 1)
|
||||
continue;
|
||||
if (coords[0] < 0)
|
||||
continue;
|
||||
if (coords[1] < 0)
|
||||
continue;
|
||||
|
||||
// Skip if we dont have water to begin with.
|
||||
if (water[x, y] < 0)
|
||||
continue;
|
||||
|
||||
// Calculate our delta average
|
||||
double altitudeDelta = altitudeMe - altitudeAvg;
|
||||
|
||||
if (altitudeDelta < 0)
|
||||
continue;
|
||||
|
||||
// Calculate how much water we can move
|
||||
double waterMin = Math.Min(water[x, y], altitudeDelta);
|
||||
double waterDelta = waterMin * ((water[coords[0], coords[1]] + map[coords[0], coords[1]])
|
||||
/ altitudeTotal);
|
||||
|
||||
double sedimentDelta = sediment[x, y] * (waterDelta / water[x, y]);
|
||||
|
||||
if (sedimentDelta > 0)
|
||||
{
|
||||
sediment[x, y] -= sedimentDelta;
|
||||
sediment[coords[0], coords[1]] += sedimentDelta;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Evaporate
|
||||
|
||||
for (x = 0; x < water.Width; x++)
|
||||
{
|
||||
for (y = 0; y < water.Height; y++)
|
||||
{
|
||||
water[x, y] *= 1.0 - (rainHeight / rounds);
|
||||
|
||||
double waterCapacity = waterSaturation * water[x, y];
|
||||
|
||||
double sedimentDeposit = sediment[x, y] - waterCapacity;
|
||||
if (sedimentDeposit > 0)
|
||||
{
|
||||
sediment[x, y] -= sedimentDeposit;
|
||||
map[x, y] += sedimentDeposit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Deposit any remainder (should be minimal)
|
||||
for (x = 0; x < water.Width; x++)
|
||||
for (y = 0; y < water.Height; y++)
|
||||
if (sediment[x, y] > 0)
|
||||
map[x, y] += sediment[x, y];
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
/*
|
||||
* 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 OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes
|
||||
{
|
||||
/// <summary>
|
||||
/// Hydraulic Erosion Brush
|
||||
/// </summary>
|
||||
public class ErodeSphere : ITerrainPaintableEffect
|
||||
{
|
||||
private double rainHeight = 0.2;
|
||||
private int rounds = 10;
|
||||
private NeighbourSystem type = NeighbourSystem.Moore; // Parameter
|
||||
private double waterSaturation = 0.30; // Can carry 1% of water in height
|
||||
|
||||
#region Supporting Functions
|
||||
|
||||
private int[] Neighbours(NeighbourSystem type, int index)
|
||||
{
|
||||
int[] coord = new int[2];
|
||||
|
||||
index++;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case NeighbourSystem.Moore:
|
||||
switch (index)
|
||||
{
|
||||
case 1:
|
||||
coord[0] = -1;
|
||||
coord[1] = -1;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
coord[0] = -0;
|
||||
coord[1] = -1;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
coord[0] = +1;
|
||||
coord[1] = -1;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
coord[0] = -1;
|
||||
coord[1] = -0;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
coord[0] = -0;
|
||||
coord[1] = -0;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
coord[0] = +1;
|
||||
coord[1] = -0;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
coord[0] = -1;
|
||||
coord[1] = +1;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
coord[0] = -0;
|
||||
coord[1] = +1;
|
||||
break;
|
||||
|
||||
case 9:
|
||||
coord[0] = +1;
|
||||
coord[1] = +1;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case NeighbourSystem.VonNeumann:
|
||||
switch (index)
|
||||
{
|
||||
case 1:
|
||||
coord[0] = 0;
|
||||
coord[1] = -1;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
coord[0] = -1;
|
||||
coord[1] = 0;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
coord[0] = +1;
|
||||
coord[1] = 0;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
coord[0] = 0;
|
||||
coord[1] = +1;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
coord[0] = -0;
|
||||
coord[1] = -0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return coord;
|
||||
}
|
||||
|
||||
private enum NeighbourSystem
|
||||
{
|
||||
Moore,
|
||||
VonNeumann
|
||||
} ;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ITerrainPaintableEffect Members
|
||||
|
||||
public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
|
||||
{
|
||||
strength = TerrainUtil.MetersToSphericalStrength(strength);
|
||||
|
||||
int x, y;
|
||||
// Using one 'rain' round for this, so skipping a useless loop
|
||||
// Will need to adapt back in for the Flood brush
|
||||
|
||||
ITerrainChannel water = new TerrainChannel(map.Width, map.Height);
|
||||
ITerrainChannel sediment = new TerrainChannel(map.Width, map.Height);
|
||||
|
||||
// Fill with rain
|
||||
for (x = 0; x < water.Width; x++)
|
||||
for (y = 0; y < water.Height; y++)
|
||||
water[x, y] = Math.Max(0.0, TerrainUtil.SphericalFactor(x, y, rx, ry, strength) * rainHeight * duration);
|
||||
|
||||
for (int i = 0; i < rounds; i++)
|
||||
{
|
||||
// Erode underlying terrain
|
||||
for (x = 0; x < water.Width; x++)
|
||||
{
|
||||
for (y = 0; y < water.Height; y++)
|
||||
{
|
||||
double solConst = (1.0 / rounds);
|
||||
double sedDelta = water[x, y] * solConst;
|
||||
map[x, y] -= sedDelta;
|
||||
sediment[x, y] += sedDelta;
|
||||
}
|
||||
}
|
||||
|
||||
// Move water
|
||||
for (x = 0; x < water.Width; x++)
|
||||
{
|
||||
for (y = 0; y < water.Height; y++)
|
||||
{
|
||||
if (water[x, y] <= 0)
|
||||
continue;
|
||||
|
||||
// Step 1. Calculate average of neighbours
|
||||
|
||||
int neighbours = 0;
|
||||
double altitudeTotal = 0.0;
|
||||
double altitudeMe = map[x, y] + water[x, y];
|
||||
|
||||
int NEIGHBOUR_ME = 4;
|
||||
|
||||
int NEIGHBOUR_MAX = type == NeighbourSystem.Moore ? 9 : 5;
|
||||
|
||||
for (int j = 0; j < NEIGHBOUR_MAX; j++)
|
||||
{
|
||||
if (j != NEIGHBOUR_ME)
|
||||
{
|
||||
int[] coords = Neighbours(type, j);
|
||||
|
||||
coords[0] += x;
|
||||
coords[1] += y;
|
||||
|
||||
if (coords[0] > map.Width - 1)
|
||||
continue;
|
||||
if (coords[1] > map.Height - 1)
|
||||
continue;
|
||||
if (coords[0] < 0)
|
||||
continue;
|
||||
if (coords[1] < 0)
|
||||
continue;
|
||||
|
||||
// Calculate total height of this neighbour
|
||||
double altitudeNeighbour = water[coords[0], coords[1]] + map[coords[0], coords[1]];
|
||||
|
||||
// If it's greater than me...
|
||||
if (altitudeNeighbour - altitudeMe < 0)
|
||||
{
|
||||
// Add it to our calculations
|
||||
neighbours++;
|
||||
altitudeTotal += altitudeNeighbour;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (neighbours == 0)
|
||||
continue;
|
||||
|
||||
double altitudeAvg = altitudeTotal / neighbours;
|
||||
|
||||
// Step 2. Allocate water to neighbours.
|
||||
for (int j = 0; j < NEIGHBOUR_MAX; j++)
|
||||
{
|
||||
if (j != NEIGHBOUR_ME)
|
||||
{
|
||||
int[] coords = Neighbours(type, j);
|
||||
|
||||
coords[0] += x;
|
||||
coords[1] += y;
|
||||
|
||||
if (coords[0] > map.Width - 1)
|
||||
continue;
|
||||
if (coords[1] > map.Height - 1)
|
||||
continue;
|
||||
if (coords[0] < 0)
|
||||
continue;
|
||||
if (coords[1] < 0)
|
||||
continue;
|
||||
|
||||
// Skip if we dont have water to begin with.
|
||||
if (water[x, y] < 0)
|
||||
continue;
|
||||
|
||||
// Calculate our delta average
|
||||
double altitudeDelta = altitudeMe - altitudeAvg;
|
||||
|
||||
if (altitudeDelta < 0)
|
||||
continue;
|
||||
|
||||
// Calculate how much water we can move
|
||||
double waterMin = Math.Min(water[x, y], altitudeDelta);
|
||||
double waterDelta = waterMin * ((water[coords[0], coords[1]] + map[coords[0], coords[1]])
|
||||
/ altitudeTotal);
|
||||
|
||||
double sedimentDelta = sediment[x, y] * (waterDelta / water[x, y]);
|
||||
|
||||
if (sedimentDelta > 0)
|
||||
{
|
||||
sediment[x, y] -= sedimentDelta;
|
||||
sediment[coords[0], coords[1]] += sedimentDelta;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Evaporate
|
||||
|
||||
for (x = 0; x < water.Width; x++)
|
||||
{
|
||||
for (y = 0; y < water.Height; y++)
|
||||
{
|
||||
water[x, y] *= 1.0 - (rainHeight / rounds);
|
||||
|
||||
double waterCapacity = waterSaturation * water[x, y];
|
||||
|
||||
double sedimentDeposit = sediment[x, y] - waterCapacity;
|
||||
if (sedimentDeposit > 0)
|
||||
{
|
||||
sediment[x, y] -= sedimentDeposit;
|
||||
map[x, y] += sedimentDeposit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Deposit any remainder (should be minimal)
|
||||
for (x = 0; x < water.Width; x++)
|
||||
for (y = 0; y < water.Height; y++)
|
||||
if (sediment[x, y] > 0)
|
||||
map[x, y] += sediment[x, y];
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -1,94 +1,94 @@
|
|||
/*
|
||||
* 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.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes
|
||||
{
|
||||
public class FlattenSphere : ITerrainPaintableEffect
|
||||
{
|
||||
|
||||
#region ITerrainPaintableEffect Members
|
||||
|
||||
public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
|
||||
{
|
||||
strength = TerrainUtil.MetersToSphericalStrength(strength);
|
||||
|
||||
int x, y;
|
||||
double[,] tweak = new double[map.Width,map.Height];
|
||||
|
||||
double area = strength;
|
||||
double step = strength / 4.0;
|
||||
|
||||
double sum = 0.0;
|
||||
double step2 = 0.0;
|
||||
double avg = 0.0;
|
||||
|
||||
// compute delta map
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
double z = SphericalFactor(x, y, rx, ry, strength);
|
||||
|
||||
if (z > 0) // add in non-zero amount
|
||||
{
|
||||
sum += map[x, y] * z;
|
||||
step2 += z;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
avg = sum / step2;
|
||||
|
||||
// blend in map
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
double z = SphericalFactor(x, y, rx, ry, strength) * duration;
|
||||
|
||||
if (z > 0) // add in non-zero amount
|
||||
{
|
||||
if (z > 1.0)
|
||||
z = 1.0;
|
||||
|
||||
map[x, y] = (map[x, y] * (1.0 - z)) + (avg * z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private double SphericalFactor(double x, double y, double rx, double ry, double size)
|
||||
{
|
||||
double z = size * size - ((x - rx) * (x - rx) + (y - ry) * (y - ry));
|
||||
return z;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes
|
||||
{
|
||||
public class FlattenSphere : ITerrainPaintableEffect
|
||||
{
|
||||
|
||||
#region ITerrainPaintableEffect Members
|
||||
|
||||
public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
|
||||
{
|
||||
strength = TerrainUtil.MetersToSphericalStrength(strength);
|
||||
|
||||
int x, y;
|
||||
double[,] tweak = new double[map.Width,map.Height];
|
||||
|
||||
double area = strength;
|
||||
double step = strength / 4.0;
|
||||
|
||||
double sum = 0.0;
|
||||
double step2 = 0.0;
|
||||
double avg = 0.0;
|
||||
|
||||
// compute delta map
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
double z = SphericalFactor(x, y, rx, ry, strength);
|
||||
|
||||
if (z > 0) // add in non-zero amount
|
||||
{
|
||||
sum += map[x, y] * z;
|
||||
step2 += z;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
avg = sum / step2;
|
||||
|
||||
// blend in map
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
double z = SphericalFactor(x, y, rx, ry, strength) * duration;
|
||||
|
||||
if (z > 0) // add in non-zero amount
|
||||
{
|
||||
if (z > 1.0)
|
||||
z = 1.0;
|
||||
|
||||
map[x, y] = (map[x, y] * (1.0 - z)) + (avg * z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private double SphericalFactor(double x, double y, double rx, double ry, double size)
|
||||
{
|
||||
double z = size * size - ((x - rx) * (x - rx) + (y - ry) * (y - ry));
|
||||
return z;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,67 +1,67 @@
|
|||
/*
|
||||
* 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 OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes
|
||||
{
|
||||
public class LowerSphere : ITerrainPaintableEffect
|
||||
{
|
||||
#region ITerrainPaintableEffect Members
|
||||
|
||||
public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
|
||||
{
|
||||
strength = TerrainUtil.MetersToSphericalStrength(strength);
|
||||
|
||||
int x, y;
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
// Skip everything unlikely to be affected
|
||||
if (Math.Abs(x - rx) > strength * 1.1)
|
||||
continue;
|
||||
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
// Skip everything unlikely to be affected
|
||||
if (Math.Abs(y - ry) > strength * 1.1)
|
||||
continue;
|
||||
|
||||
// Calculate a sphere and add it to the heighmap
|
||||
double z = strength;
|
||||
z *= z;
|
||||
z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry));
|
||||
|
||||
if (z > 0.0)
|
||||
map[x, y] -= z * duration;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
/*
|
||||
* 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 OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes
|
||||
{
|
||||
public class LowerSphere : ITerrainPaintableEffect
|
||||
{
|
||||
#region ITerrainPaintableEffect Members
|
||||
|
||||
public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
|
||||
{
|
||||
strength = TerrainUtil.MetersToSphericalStrength(strength);
|
||||
|
||||
int x, y;
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
// Skip everything unlikely to be affected
|
||||
if (Math.Abs(x - rx) > strength * 1.1)
|
||||
continue;
|
||||
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
// Skip everything unlikely to be affected
|
||||
if (Math.Abs(y - ry) > strength * 1.1)
|
||||
continue;
|
||||
|
||||
// Calculate a sphere and add it to the heighmap
|
||||
double z = strength;
|
||||
z *= z;
|
||||
z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry));
|
||||
|
||||
if (z > 0.0)
|
||||
map[x, y] -= z * duration;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -1,70 +1,70 @@
|
|||
/*
|
||||
* 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 OpenSim.Framework;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes
|
||||
{
|
||||
public class NoiseSphere : ITerrainPaintableEffect
|
||||
{
|
||||
#region ITerrainPaintableEffect Members
|
||||
|
||||
public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
|
||||
{
|
||||
strength = TerrainUtil.MetersToSphericalStrength(strength);
|
||||
|
||||
int x, y;
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
// Skip everything unlikely to be affected
|
||||
if (Math.Abs(x - rx) > strength * 1.1)
|
||||
continue;
|
||||
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
// Skip everything unlikely to be affected
|
||||
if (Math.Abs(y - ry) > strength * 1.1)
|
||||
continue;
|
||||
|
||||
// Calculate a sphere and add it to the heighmap
|
||||
double z = strength;
|
||||
z *= z;
|
||||
z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry));
|
||||
|
||||
double noise = TerrainUtil.PerlinNoise2D((double) x / (double) Constants.RegionSize, (double) y / (double) Constants.RegionSize, 8, 1.0);
|
||||
|
||||
if (z > 0.0)
|
||||
map[x, y] += noise * z * duration;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
/*
|
||||
* 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 OpenSim.Framework;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes
|
||||
{
|
||||
public class NoiseSphere : ITerrainPaintableEffect
|
||||
{
|
||||
#region ITerrainPaintableEffect Members
|
||||
|
||||
public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
|
||||
{
|
||||
strength = TerrainUtil.MetersToSphericalStrength(strength);
|
||||
|
||||
int x, y;
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
// Skip everything unlikely to be affected
|
||||
if (Math.Abs(x - rx) > strength * 1.1)
|
||||
continue;
|
||||
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
// Skip everything unlikely to be affected
|
||||
if (Math.Abs(y - ry) > strength * 1.1)
|
||||
continue;
|
||||
|
||||
// Calculate a sphere and add it to the heighmap
|
||||
double z = strength;
|
||||
z *= z;
|
||||
z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry));
|
||||
|
||||
double noise = TerrainUtil.PerlinNoise2D((double) x / (double) Constants.RegionSize, (double) y / (double) Constants.RegionSize, 8, 1.0);
|
||||
|
||||
if (z > 0.0)
|
||||
map[x, y] += noise * z * duration;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -1,225 +1,225 @@
|
|||
/*
|
||||
* 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 OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes
|
||||
{
|
||||
/// <summary>
|
||||
/// Speed-Optimised Hybrid Erosion Brush
|
||||
///
|
||||
/// As per Jacob Olsen's Paper
|
||||
/// http://www.oddlabs.com/download/terrain_generation.pdf
|
||||
/// </summary>
|
||||
public class OlsenSphere : ITerrainPaintableEffect
|
||||
{
|
||||
private double nConst = 1024.0;
|
||||
private NeighbourSystem type = NeighbourSystem.Moore; // Parameter
|
||||
|
||||
#region Supporting Functions
|
||||
|
||||
private int[] Neighbours(NeighbourSystem type, int index)
|
||||
{
|
||||
int[] coord = new int[2];
|
||||
|
||||
index++;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case NeighbourSystem.Moore:
|
||||
switch (index)
|
||||
{
|
||||
case 1:
|
||||
coord[0] = -1;
|
||||
coord[1] = -1;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
coord[0] = -0;
|
||||
coord[1] = -1;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
coord[0] = +1;
|
||||
coord[1] = -1;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
coord[0] = -1;
|
||||
coord[1] = -0;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
coord[0] = -0;
|
||||
coord[1] = -0;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
coord[0] = +1;
|
||||
coord[1] = -0;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
coord[0] = -1;
|
||||
coord[1] = +1;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
coord[0] = -0;
|
||||
coord[1] = +1;
|
||||
break;
|
||||
|
||||
case 9:
|
||||
coord[0] = +1;
|
||||
coord[1] = +1;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case NeighbourSystem.VonNeumann:
|
||||
switch (index)
|
||||
{
|
||||
case 1:
|
||||
coord[0] = 0;
|
||||
coord[1] = -1;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
coord[0] = -1;
|
||||
coord[1] = 0;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
coord[0] = +1;
|
||||
coord[1] = 0;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
coord[0] = 0;
|
||||
coord[1] = +1;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
coord[0] = -0;
|
||||
coord[1] = -0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return coord;
|
||||
}
|
||||
|
||||
private double SphericalFactor(double x, double y, double rx, double ry, double size)
|
||||
{
|
||||
double z = size * size - ((x - rx) * (x - rx) + (y - ry) * (y - ry));
|
||||
return z;
|
||||
}
|
||||
|
||||
private enum NeighbourSystem
|
||||
{
|
||||
Moore,
|
||||
VonNeumann
|
||||
} ;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ITerrainPaintableEffect Members
|
||||
|
||||
public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
|
||||
{
|
||||
strength = TerrainUtil.MetersToSphericalStrength(strength);
|
||||
|
||||
int x, y;
|
||||
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
double z = SphericalFactor(x, y, rx, ry, strength);
|
||||
|
||||
if (z > 0) // add in non-zero amount
|
||||
{
|
||||
int NEIGHBOUR_ME = 4;
|
||||
int NEIGHBOUR_MAX = type == NeighbourSystem.Moore ? 9 : 5;
|
||||
|
||||
double max = Double.MinValue;
|
||||
int loc = 0;
|
||||
double cellmax = 0;
|
||||
|
||||
|
||||
for (int j = 0; j < NEIGHBOUR_MAX; j++)
|
||||
{
|
||||
if (j != NEIGHBOUR_ME)
|
||||
{
|
||||
int[] coords = Neighbours(type, j);
|
||||
|
||||
coords[0] += x;
|
||||
coords[1] += y;
|
||||
|
||||
if (coords[0] > map.Width - 1)
|
||||
continue;
|
||||
if (coords[1] > map.Height - 1)
|
||||
continue;
|
||||
if (coords[0] < 0)
|
||||
continue;
|
||||
if (coords[1] < 0)
|
||||
continue;
|
||||
|
||||
cellmax = map[x, y] - map[coords[0], coords[1]];
|
||||
if (cellmax > max)
|
||||
{
|
||||
max = cellmax;
|
||||
loc = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double T = nConst / ((map.Width + map.Height) / 2);
|
||||
// Apply results
|
||||
if (0 < max && max <= T)
|
||||
{
|
||||
int[] maxCoords = Neighbours(type, loc);
|
||||
double heightDelta = 0.5 * max * z * duration;
|
||||
map[x, y] -= heightDelta;
|
||||
map[x + maxCoords[0], y + maxCoords[1]] += heightDelta;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
/*
|
||||
* 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 OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes
|
||||
{
|
||||
/// <summary>
|
||||
/// Speed-Optimised Hybrid Erosion Brush
|
||||
///
|
||||
/// As per Jacob Olsen's Paper
|
||||
/// http://www.oddlabs.com/download/terrain_generation.pdf
|
||||
/// </summary>
|
||||
public class OlsenSphere : ITerrainPaintableEffect
|
||||
{
|
||||
private double nConst = 1024.0;
|
||||
private NeighbourSystem type = NeighbourSystem.Moore; // Parameter
|
||||
|
||||
#region Supporting Functions
|
||||
|
||||
private int[] Neighbours(NeighbourSystem type, int index)
|
||||
{
|
||||
int[] coord = new int[2];
|
||||
|
||||
index++;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case NeighbourSystem.Moore:
|
||||
switch (index)
|
||||
{
|
||||
case 1:
|
||||
coord[0] = -1;
|
||||
coord[1] = -1;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
coord[0] = -0;
|
||||
coord[1] = -1;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
coord[0] = +1;
|
||||
coord[1] = -1;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
coord[0] = -1;
|
||||
coord[1] = -0;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
coord[0] = -0;
|
||||
coord[1] = -0;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
coord[0] = +1;
|
||||
coord[1] = -0;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
coord[0] = -1;
|
||||
coord[1] = +1;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
coord[0] = -0;
|
||||
coord[1] = +1;
|
||||
break;
|
||||
|
||||
case 9:
|
||||
coord[0] = +1;
|
||||
coord[1] = +1;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case NeighbourSystem.VonNeumann:
|
||||
switch (index)
|
||||
{
|
||||
case 1:
|
||||
coord[0] = 0;
|
||||
coord[1] = -1;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
coord[0] = -1;
|
||||
coord[1] = 0;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
coord[0] = +1;
|
||||
coord[1] = 0;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
coord[0] = 0;
|
||||
coord[1] = +1;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
coord[0] = -0;
|
||||
coord[1] = -0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return coord;
|
||||
}
|
||||
|
||||
private double SphericalFactor(double x, double y, double rx, double ry, double size)
|
||||
{
|
||||
double z = size * size - ((x - rx) * (x - rx) + (y - ry) * (y - ry));
|
||||
return z;
|
||||
}
|
||||
|
||||
private enum NeighbourSystem
|
||||
{
|
||||
Moore,
|
||||
VonNeumann
|
||||
} ;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ITerrainPaintableEffect Members
|
||||
|
||||
public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
|
||||
{
|
||||
strength = TerrainUtil.MetersToSphericalStrength(strength);
|
||||
|
||||
int x, y;
|
||||
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
double z = SphericalFactor(x, y, rx, ry, strength);
|
||||
|
||||
if (z > 0) // add in non-zero amount
|
||||
{
|
||||
int NEIGHBOUR_ME = 4;
|
||||
int NEIGHBOUR_MAX = type == NeighbourSystem.Moore ? 9 : 5;
|
||||
|
||||
double max = Double.MinValue;
|
||||
int loc = 0;
|
||||
double cellmax = 0;
|
||||
|
||||
|
||||
for (int j = 0; j < NEIGHBOUR_MAX; j++)
|
||||
{
|
||||
if (j != NEIGHBOUR_ME)
|
||||
{
|
||||
int[] coords = Neighbours(type, j);
|
||||
|
||||
coords[0] += x;
|
||||
coords[1] += y;
|
||||
|
||||
if (coords[0] > map.Width - 1)
|
||||
continue;
|
||||
if (coords[1] > map.Height - 1)
|
||||
continue;
|
||||
if (coords[0] < 0)
|
||||
continue;
|
||||
if (coords[1] < 0)
|
||||
continue;
|
||||
|
||||
cellmax = map[x, y] - map[coords[0], coords[1]];
|
||||
if (cellmax > max)
|
||||
{
|
||||
max = cellmax;
|
||||
loc = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double T = nConst / ((map.Width + map.Height) / 2);
|
||||
// Apply results
|
||||
if (0 < max && max <= T)
|
||||
{
|
||||
int[] maxCoords = Neighbours(type, loc);
|
||||
double heightDelta = 0.5 * max * z * duration;
|
||||
map[x, y] -= heightDelta;
|
||||
map[x + maxCoords[0], y + maxCoords[1]] += heightDelta;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -1,67 +1,67 @@
|
|||
/*
|
||||
* 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 OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes
|
||||
{
|
||||
public class RaiseSphere : ITerrainPaintableEffect
|
||||
{
|
||||
#region ITerrainPaintableEffect Members
|
||||
|
||||
public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
|
||||
{
|
||||
strength = TerrainUtil.MetersToSphericalStrength(strength);
|
||||
|
||||
int x, y;
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
// Skip everything unlikely to be affected
|
||||
if (Math.Abs(x - rx) > strength * 1.1)
|
||||
continue;
|
||||
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
// Skip everything unlikely to be affected
|
||||
if (Math.Abs(y - ry) > strength * 1.1)
|
||||
continue;
|
||||
|
||||
// Calculate a sphere and add it to the heighmap
|
||||
double z = strength;
|
||||
z *= z;
|
||||
z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry));
|
||||
|
||||
if (z > 0.0)
|
||||
map[x, y] += z * duration;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
/*
|
||||
* 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 OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes
|
||||
{
|
||||
public class RaiseSphere : ITerrainPaintableEffect
|
||||
{
|
||||
#region ITerrainPaintableEffect Members
|
||||
|
||||
public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
|
||||
{
|
||||
strength = TerrainUtil.MetersToSphericalStrength(strength);
|
||||
|
||||
int x, y;
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
// Skip everything unlikely to be affected
|
||||
if (Math.Abs(x - rx) > strength * 1.1)
|
||||
continue;
|
||||
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
// Skip everything unlikely to be affected
|
||||
if (Math.Abs(y - ry) > strength * 1.1)
|
||||
continue;
|
||||
|
||||
// Calculate a sphere and add it to the heighmap
|
||||
double z = strength;
|
||||
z *= z;
|
||||
z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry));
|
||||
|
||||
if (z > 0.0)
|
||||
map[x, y] += z * duration;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -1,82 +1,82 @@
|
|||
/*
|
||||
* 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 OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes
|
||||
{
|
||||
public class RevertSphere : ITerrainPaintableEffect
|
||||
{
|
||||
private ITerrainChannel m_revertmap;
|
||||
|
||||
public RevertSphere(ITerrainChannel revertmap)
|
||||
{
|
||||
m_revertmap = revertmap;
|
||||
}
|
||||
|
||||
#region ITerrainPaintableEffect Members
|
||||
|
||||
public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
|
||||
{
|
||||
strength = TerrainUtil.MetersToSphericalStrength(strength);
|
||||
|
||||
if (duration > 1.0)
|
||||
duration = 1.0;
|
||||
if (duration < 0)
|
||||
return;
|
||||
|
||||
int x, y;
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
// Skip everything unlikely to be affected
|
||||
if (Math.Abs(x - rx) > strength * 1.1)
|
||||
continue;
|
||||
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
// Skip everything unlikely to be affected
|
||||
if (Math.Abs(y - ry) > strength * 1.1)
|
||||
continue;
|
||||
|
||||
// Calculate a sphere and add it to the heighmap
|
||||
double z = strength;
|
||||
z *= z;
|
||||
z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry));
|
||||
|
||||
if (z > 0.0)
|
||||
{
|
||||
z *= duration;
|
||||
map[x, y] += (map[x, y] * (1.0 - z)) + (m_revertmap[x, y] * z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
/*
|
||||
* 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 OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes
|
||||
{
|
||||
public class RevertSphere : ITerrainPaintableEffect
|
||||
{
|
||||
private ITerrainChannel m_revertmap;
|
||||
|
||||
public RevertSphere(ITerrainChannel revertmap)
|
||||
{
|
||||
m_revertmap = revertmap;
|
||||
}
|
||||
|
||||
#region ITerrainPaintableEffect Members
|
||||
|
||||
public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
|
||||
{
|
||||
strength = TerrainUtil.MetersToSphericalStrength(strength);
|
||||
|
||||
if (duration > 1.0)
|
||||
duration = 1.0;
|
||||
if (duration < 0)
|
||||
return;
|
||||
|
||||
int x, y;
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
// Skip everything unlikely to be affected
|
||||
if (Math.Abs(x - rx) > strength * 1.1)
|
||||
continue;
|
||||
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
// Skip everything unlikely to be affected
|
||||
if (Math.Abs(y - ry) > strength * 1.1)
|
||||
continue;
|
||||
|
||||
// Calculate a sphere and add it to the heighmap
|
||||
double z = strength;
|
||||
z *= z;
|
||||
z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry));
|
||||
|
||||
if (z > 0.0)
|
||||
{
|
||||
z *= duration;
|
||||
map[x, y] += (map[x, y] * (1.0 - z)) + (m_revertmap[x, y] * z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -1,93 +1,93 @@
|
|||
/*
|
||||
* 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.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes
|
||||
{
|
||||
public class SmoothSphere : ITerrainPaintableEffect
|
||||
{
|
||||
#region ITerrainPaintableEffect Members
|
||||
|
||||
public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
|
||||
{
|
||||
strength = TerrainUtil.MetersToSphericalStrength(strength);
|
||||
|
||||
int x, y;
|
||||
double[,] tweak = new double[map.Width,map.Height];
|
||||
|
||||
double n, l;
|
||||
double area = strength;
|
||||
double step = strength / 4.0;
|
||||
|
||||
// compute delta map
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
double z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength);
|
||||
|
||||
if (z > 0) // add in non-zero amount
|
||||
{
|
||||
double average = 0.0;
|
||||
int avgsteps = 0;
|
||||
|
||||
for (n = 0.0 - area; n < area; n += step)
|
||||
{
|
||||
for (l = 0.0 - area; l < area; l += step)
|
||||
{
|
||||
avgsteps++;
|
||||
average += TerrainUtil.GetBilinearInterpolate(x + n, y + l, map);
|
||||
}
|
||||
}
|
||||
tweak[x, y] = average / avgsteps;
|
||||
}
|
||||
}
|
||||
}
|
||||
// blend in map
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
double z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength);
|
||||
|
||||
if (z > 0) // add in non-zero amount
|
||||
{
|
||||
double da = z;
|
||||
double a = (map[x, y] - tweak[x, y]) * da;
|
||||
double newz = map[x, y] - (a * duration);
|
||||
|
||||
if (newz > 0.0)
|
||||
map[x, y] = newz;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
/*
|
||||
* 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.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes
|
||||
{
|
||||
public class SmoothSphere : ITerrainPaintableEffect
|
||||
{
|
||||
#region ITerrainPaintableEffect Members
|
||||
|
||||
public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
|
||||
{
|
||||
strength = TerrainUtil.MetersToSphericalStrength(strength);
|
||||
|
||||
int x, y;
|
||||
double[,] tweak = new double[map.Width,map.Height];
|
||||
|
||||
double n, l;
|
||||
double area = strength;
|
||||
double step = strength / 4.0;
|
||||
|
||||
// compute delta map
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
double z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength);
|
||||
|
||||
if (z > 0) // add in non-zero amount
|
||||
{
|
||||
double average = 0.0;
|
||||
int avgsteps = 0;
|
||||
|
||||
for (n = 0.0 - area; n < area; n += step)
|
||||
{
|
||||
for (l = 0.0 - area; l < area; l += step)
|
||||
{
|
||||
avgsteps++;
|
||||
average += TerrainUtil.GetBilinearInterpolate(x + n, y + l, map);
|
||||
}
|
||||
}
|
||||
tweak[x, y] = average / avgsteps;
|
||||
}
|
||||
}
|
||||
}
|
||||
// blend in map
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
double z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength);
|
||||
|
||||
if (z > 0) // add in non-zero amount
|
||||
{
|
||||
double da = z;
|
||||
double a = (map[x, y] - tweak[x, y]) * da;
|
||||
double newz = map[x, y] - (a * duration);
|
||||
|
||||
if (newz > 0.0)
|
||||
map[x, y] = newz;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -1,207 +1,207 @@
|
|||
/*
|
||||
* 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.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes
|
||||
{
|
||||
/// <summary>
|
||||
/// Thermal Weathering Paint Brush
|
||||
/// </summary>
|
||||
public class WeatherSphere : ITerrainPaintableEffect
|
||||
{
|
||||
private double talus = 0.2; // Number of meters max difference before stop eroding. Tweakage required.
|
||||
private NeighbourSystem type = NeighbourSystem.Moore; // Parameter
|
||||
|
||||
#region Supporting Functions
|
||||
|
||||
private int[] Neighbours(NeighbourSystem type, int index)
|
||||
{
|
||||
int[] coord = new int[2];
|
||||
|
||||
index++;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case NeighbourSystem.Moore:
|
||||
switch (index)
|
||||
{
|
||||
case 1:
|
||||
coord[0] = -1;
|
||||
coord[1] = -1;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
coord[0] = -0;
|
||||
coord[1] = -1;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
coord[0] = +1;
|
||||
coord[1] = -1;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
coord[0] = -1;
|
||||
coord[1] = -0;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
coord[0] = -0;
|
||||
coord[1] = -0;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
coord[0] = +1;
|
||||
coord[1] = -0;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
coord[0] = -1;
|
||||
coord[1] = +1;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
coord[0] = -0;
|
||||
coord[1] = +1;
|
||||
break;
|
||||
|
||||
case 9:
|
||||
coord[0] = +1;
|
||||
coord[1] = +1;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case NeighbourSystem.VonNeumann:
|
||||
switch (index)
|
||||
{
|
||||
case 1:
|
||||
coord[0] = 0;
|
||||
coord[1] = -1;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
coord[0] = -1;
|
||||
coord[1] = 0;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
coord[0] = +1;
|
||||
coord[1] = 0;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
coord[0] = 0;
|
||||
coord[1] = +1;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
coord[0] = -0;
|
||||
coord[1] = -0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return coord;
|
||||
}
|
||||
|
||||
private enum NeighbourSystem
|
||||
{
|
||||
Moore,
|
||||
VonNeumann
|
||||
} ;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ITerrainPaintableEffect Members
|
||||
|
||||
public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
|
||||
{
|
||||
strength = TerrainUtil.MetersToSphericalStrength(strength);
|
||||
|
||||
int x, y;
|
||||
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
double z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength);
|
||||
|
||||
if (z > 0) // add in non-zero amount
|
||||
{
|
||||
int NEIGHBOUR_ME = 4;
|
||||
|
||||
int NEIGHBOUR_MAX = type == NeighbourSystem.Moore ? 9 : 5;
|
||||
|
||||
for (int j = 0; j < NEIGHBOUR_MAX; j++)
|
||||
{
|
||||
if (j != NEIGHBOUR_ME)
|
||||
{
|
||||
int[] coords = Neighbours(type, j);
|
||||
|
||||
coords[0] += x;
|
||||
coords[1] += y;
|
||||
|
||||
if (coords[0] > map.Width - 1)
|
||||
continue;
|
||||
if (coords[1] > map.Height - 1)
|
||||
continue;
|
||||
if (coords[0] < 0)
|
||||
continue;
|
||||
if (coords[1] < 0)
|
||||
continue;
|
||||
|
||||
double heightF = map[x, y];
|
||||
double target = map[coords[0], coords[1]];
|
||||
|
||||
if (target > heightF + talus)
|
||||
{
|
||||
double calc = duration * ((target - heightF) - talus) * z;
|
||||
heightF += calc;
|
||||
target -= calc;
|
||||
}
|
||||
|
||||
map[x, y] = heightF;
|
||||
map[coords[0], coords[1]] = target;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
/*
|
||||
* 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.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes
|
||||
{
|
||||
/// <summary>
|
||||
/// Thermal Weathering Paint Brush
|
||||
/// </summary>
|
||||
public class WeatherSphere : ITerrainPaintableEffect
|
||||
{
|
||||
private double talus = 0.2; // Number of meters max difference before stop eroding. Tweakage required.
|
||||
private NeighbourSystem type = NeighbourSystem.Moore; // Parameter
|
||||
|
||||
#region Supporting Functions
|
||||
|
||||
private int[] Neighbours(NeighbourSystem type, int index)
|
||||
{
|
||||
int[] coord = new int[2];
|
||||
|
||||
index++;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case NeighbourSystem.Moore:
|
||||
switch (index)
|
||||
{
|
||||
case 1:
|
||||
coord[0] = -1;
|
||||
coord[1] = -1;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
coord[0] = -0;
|
||||
coord[1] = -1;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
coord[0] = +1;
|
||||
coord[1] = -1;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
coord[0] = -1;
|
||||
coord[1] = -0;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
coord[0] = -0;
|
||||
coord[1] = -0;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
coord[0] = +1;
|
||||
coord[1] = -0;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
coord[0] = -1;
|
||||
coord[1] = +1;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
coord[0] = -0;
|
||||
coord[1] = +1;
|
||||
break;
|
||||
|
||||
case 9:
|
||||
coord[0] = +1;
|
||||
coord[1] = +1;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case NeighbourSystem.VonNeumann:
|
||||
switch (index)
|
||||
{
|
||||
case 1:
|
||||
coord[0] = 0;
|
||||
coord[1] = -1;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
coord[0] = -1;
|
||||
coord[1] = 0;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
coord[0] = +1;
|
||||
coord[1] = 0;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
coord[0] = 0;
|
||||
coord[1] = +1;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
coord[0] = -0;
|
||||
coord[1] = -0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return coord;
|
||||
}
|
||||
|
||||
private enum NeighbourSystem
|
||||
{
|
||||
Moore,
|
||||
VonNeumann
|
||||
} ;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ITerrainPaintableEffect Members
|
||||
|
||||
public void PaintEffect(ITerrainChannel map, double rx, double ry, double strength, double duration)
|
||||
{
|
||||
strength = TerrainUtil.MetersToSphericalStrength(strength);
|
||||
|
||||
int x, y;
|
||||
|
||||
for (x = 0; x < map.Width; x++)
|
||||
{
|
||||
for (y = 0; y < map.Height; y++)
|
||||
{
|
||||
double z = TerrainUtil.SphericalFactor(x, y, rx, ry, strength);
|
||||
|
||||
if (z > 0) // add in non-zero amount
|
||||
{
|
||||
int NEIGHBOUR_ME = 4;
|
||||
|
||||
int NEIGHBOUR_MAX = type == NeighbourSystem.Moore ? 9 : 5;
|
||||
|
||||
for (int j = 0; j < NEIGHBOUR_MAX; j++)
|
||||
{
|
||||
if (j != NEIGHBOUR_ME)
|
||||
{
|
||||
int[] coords = Neighbours(type, j);
|
||||
|
||||
coords[0] += x;
|
||||
coords[1] += y;
|
||||
|
||||
if (coords[0] > map.Width - 1)
|
||||
continue;
|
||||
if (coords[1] > map.Height - 1)
|
||||
continue;
|
||||
if (coords[0] < 0)
|
||||
continue;
|
||||
if (coords[1] < 0)
|
||||
continue;
|
||||
|
||||
double heightF = map[x, y];
|
||||
double target = map[coords[0], coords[1]];
|
||||
|
||||
if (target > heightF + talus)
|
||||
{
|
||||
double calc = duration * ((target - heightF) - talus) * z;
|
||||
heightF += calc;
|
||||
target -= calc;
|
||||
}
|
||||
|
||||
map[x, y] = heightF;
|
||||
map[coords[0], coords[1]] = target;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -1,157 +1,157 @@
|
|||
/*
|
||||
* 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;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain
|
||||
{
|
||||
/// <summary>
|
||||
/// A new version of the old Channel class, simplified
|
||||
/// </summary>
|
||||
public class TerrainChannel : ITerrainChannel
|
||||
{
|
||||
private readonly bool[,] taint;
|
||||
private double[,] map;
|
||||
|
||||
public TerrainChannel()
|
||||
{
|
||||
map = new double[Constants.RegionSize,Constants.RegionSize];
|
||||
taint = new bool[Constants.RegionSize / 16,Constants.RegionSize / 16];
|
||||
|
||||
int x;
|
||||
for (x = 0; x < Constants.RegionSize; x++)
|
||||
{
|
||||
int y;
|
||||
for (y = 0; y < Constants.RegionSize; y++)
|
||||
{
|
||||
map[x, y] = TerrainUtil.PerlinNoise2D(x, y, 3, 0.25) * 10;
|
||||
double spherFac = TerrainUtil.SphericalFactor(x, y, Constants.RegionSize / 2, Constants.RegionSize / 2, 50) * 0.01;
|
||||
if (map[x, y] < spherFac)
|
||||
{
|
||||
map[x, y] = spherFac;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public TerrainChannel(double[,] import)
|
||||
{
|
||||
map = import;
|
||||
taint = new bool[import.GetLength(0),import.GetLength(1)];
|
||||
}
|
||||
|
||||
public TerrainChannel(bool createMap)
|
||||
{
|
||||
if (createMap)
|
||||
{
|
||||
map = new double[Constants.RegionSize,Constants.RegionSize];
|
||||
taint = new bool[Constants.RegionSize / 16,Constants.RegionSize / 16];
|
||||
}
|
||||
}
|
||||
|
||||
public TerrainChannel(int w, int h)
|
||||
{
|
||||
map = new double[w,h];
|
||||
taint = new bool[w / 16,h / 16];
|
||||
}
|
||||
|
||||
#region ITerrainChannel Members
|
||||
|
||||
public int Width
|
||||
{
|
||||
get { return map.GetLength(0); }
|
||||
}
|
||||
|
||||
public int Height
|
||||
{
|
||||
get { return map.GetLength(1); }
|
||||
}
|
||||
|
||||
public ITerrainChannel MakeCopy()
|
||||
{
|
||||
TerrainChannel copy = new TerrainChannel(false);
|
||||
copy.map = (double[,]) map.Clone();
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
public float[] GetFloatsSerialised()
|
||||
{
|
||||
float[] heights = new float[Width * Height];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < Width * Height; i++)
|
||||
{
|
||||
heights[i] = (float) map[i % Width, i / Width];
|
||||
}
|
||||
|
||||
return heights;
|
||||
}
|
||||
|
||||
public double[,] GetDoubles()
|
||||
{
|
||||
return map;
|
||||
}
|
||||
|
||||
public double this[int x, int y]
|
||||
{
|
||||
get { return map[x, y]; }
|
||||
set
|
||||
{
|
||||
if (map[x, y] != value)
|
||||
{
|
||||
taint[x / 16, y / 16] = true;
|
||||
map[x, y] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool Tainted(int x, int y)
|
||||
{
|
||||
if (taint[x / 16, y / 16])
|
||||
{
|
||||
taint[x / 16, y / 16] = false;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public TerrainChannel Copy()
|
||||
{
|
||||
TerrainChannel copy = new TerrainChannel(false);
|
||||
copy.map = (double[,]) map.Clone();
|
||||
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain
|
||||
{
|
||||
/// <summary>
|
||||
/// A new version of the old Channel class, simplified
|
||||
/// </summary>
|
||||
public class TerrainChannel : ITerrainChannel
|
||||
{
|
||||
private readonly bool[,] taint;
|
||||
private double[,] map;
|
||||
|
||||
public TerrainChannel()
|
||||
{
|
||||
map = new double[Constants.RegionSize,Constants.RegionSize];
|
||||
taint = new bool[Constants.RegionSize / 16,Constants.RegionSize / 16];
|
||||
|
||||
int x;
|
||||
for (x = 0; x < Constants.RegionSize; x++)
|
||||
{
|
||||
int y;
|
||||
for (y = 0; y < Constants.RegionSize; y++)
|
||||
{
|
||||
map[x, y] = TerrainUtil.PerlinNoise2D(x, y, 3, 0.25) * 10;
|
||||
double spherFac = TerrainUtil.SphericalFactor(x, y, Constants.RegionSize / 2, Constants.RegionSize / 2, 50) * 0.01;
|
||||
if (map[x, y] < spherFac)
|
||||
{
|
||||
map[x, y] = spherFac;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public TerrainChannel(double[,] import)
|
||||
{
|
||||
map = import;
|
||||
taint = new bool[import.GetLength(0),import.GetLength(1)];
|
||||
}
|
||||
|
||||
public TerrainChannel(bool createMap)
|
||||
{
|
||||
if (createMap)
|
||||
{
|
||||
map = new double[Constants.RegionSize,Constants.RegionSize];
|
||||
taint = new bool[Constants.RegionSize / 16,Constants.RegionSize / 16];
|
||||
}
|
||||
}
|
||||
|
||||
public TerrainChannel(int w, int h)
|
||||
{
|
||||
map = new double[w,h];
|
||||
taint = new bool[w / 16,h / 16];
|
||||
}
|
||||
|
||||
#region ITerrainChannel Members
|
||||
|
||||
public int Width
|
||||
{
|
||||
get { return map.GetLength(0); }
|
||||
}
|
||||
|
||||
public int Height
|
||||
{
|
||||
get { return map.GetLength(1); }
|
||||
}
|
||||
|
||||
public ITerrainChannel MakeCopy()
|
||||
{
|
||||
TerrainChannel copy = new TerrainChannel(false);
|
||||
copy.map = (double[,]) map.Clone();
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
public float[] GetFloatsSerialised()
|
||||
{
|
||||
float[] heights = new float[Width * Height];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < Width * Height; i++)
|
||||
{
|
||||
heights[i] = (float) map[i % Width, i / Width];
|
||||
}
|
||||
|
||||
return heights;
|
||||
}
|
||||
|
||||
public double[,] GetDoubles()
|
||||
{
|
||||
return map;
|
||||
}
|
||||
|
||||
public double this[int x, int y]
|
||||
{
|
||||
get { return map[x, y]; }
|
||||
set
|
||||
{
|
||||
if (map[x, y] != value)
|
||||
{
|
||||
taint[x / 16, y / 16] = true;
|
||||
map[x, y] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool Tainted(int x, int y)
|
||||
{
|
||||
if (taint[x / 16, y / 16])
|
||||
{
|
||||
taint[x / 16, y / 16] = false;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public TerrainChannel Copy()
|
||||
{
|
||||
TerrainChannel copy = new TerrainChannel(false);
|
||||
copy.map = (double[,]) map.Clone();
|
||||
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,46 +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 System;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain
|
||||
{
|
||||
public class TerrainException : Exception
|
||||
{
|
||||
public TerrainException() : base()
|
||||
{
|
||||
}
|
||||
|
||||
public TerrainException(string msg) : base(msg)
|
||||
{
|
||||
}
|
||||
|
||||
public TerrainException(string msg, Exception e) : base(msg, e)
|
||||
{
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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.Environment.Modules.World.Terrain
|
||||
{
|
||||
public class TerrainException : Exception
|
||||
{
|
||||
public TerrainException() : base()
|
||||
{
|
||||
}
|
||||
|
||||
public TerrainException(string msg) : base(msg)
|
||||
{
|
||||
}
|
||||
|
||||
public TerrainException(string msg, Exception e) : base(msg, e)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,133 +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 System;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain
|
||||
{
|
||||
public static class TerrainUtil
|
||||
{
|
||||
public static double MetersToSphericalStrength(double size)
|
||||
{
|
||||
return Math.Pow(2, size);
|
||||
}
|
||||
|
||||
public static double SphericalFactor(double x, double y, double rx, double ry, double size)
|
||||
{
|
||||
return size * size - ((x - rx) * (x - rx) + (y - ry) * (y - ry));
|
||||
}
|
||||
|
||||
public static double GetBilinearInterpolate(double x, double y, ITerrainChannel map)
|
||||
{
|
||||
int w = map.Width;
|
||||
int h = map.Height;
|
||||
|
||||
if (x > w - 2.0)
|
||||
x = w - 2.0;
|
||||
if (y > h - 2.0)
|
||||
y = h - 2.0;
|
||||
if (x < 0.0)
|
||||
x = 0.0;
|
||||
if (y < 0.0)
|
||||
y = 0.0;
|
||||
|
||||
int stepSize = 1;
|
||||
double h00 = map[(int) x, (int) y];
|
||||
double h10 = map[(int) x + stepSize, (int) y];
|
||||
double h01 = map[(int) x, (int) y + stepSize];
|
||||
double h11 = map[(int) x + stepSize, (int) y + stepSize];
|
||||
double h1 = h00;
|
||||
double h2 = h10;
|
||||
double h3 = h01;
|
||||
double h4 = h11;
|
||||
double a00 = h1;
|
||||
double a10 = h2 - h1;
|
||||
double a01 = h3 - h1;
|
||||
double a11 = h1 - h2 - h3 + h4;
|
||||
double partialx = x - (int) x;
|
||||
double partialz = y - (int) y;
|
||||
double hi = a00 + (a10 * partialx) + (a01 * partialz) + (a11 * partialx * partialz);
|
||||
return hi;
|
||||
}
|
||||
|
||||
private static double Noise(double x, double y)
|
||||
{
|
||||
int n = (int) x + (int) (y * 749);
|
||||
n = (n << 13) ^ n;
|
||||
return (1.0 - ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0);
|
||||
}
|
||||
|
||||
private static double SmoothedNoise1(double x, double y)
|
||||
{
|
||||
double corners = (Noise(x - 1, y - 1) + Noise(x + 1, y - 1) + Noise(x - 1, y + 1) + Noise(x + 1, y + 1)) / 16;
|
||||
double sides = (Noise(x - 1, y) + Noise(x + 1, y) + Noise(x, y - 1) + Noise(x, y + 1)) / 8;
|
||||
double center = Noise(x, y) / 4;
|
||||
return corners + sides + center;
|
||||
}
|
||||
|
||||
private static double Interpolate(double x, double y, double z)
|
||||
{
|
||||
return (x * (1.0 - z)) + (y * z);
|
||||
}
|
||||
|
||||
private static double InterpolatedNoise(double x, double y)
|
||||
{
|
||||
int integer_X = (int) (x);
|
||||
double fractional_X = x - integer_X;
|
||||
|
||||
int integer_Y = (int) y;
|
||||
double fractional_Y = y - integer_Y;
|
||||
|
||||
double v1 = SmoothedNoise1(integer_X, integer_Y);
|
||||
double v2 = SmoothedNoise1(integer_X + 1, integer_Y);
|
||||
double v3 = SmoothedNoise1(integer_X, integer_Y + 1);
|
||||
double v4 = SmoothedNoise1(integer_X + 1, integer_Y + 1);
|
||||
|
||||
double i1 = Interpolate(v1, v2, fractional_X);
|
||||
double i2 = Interpolate(v3, v4, fractional_X);
|
||||
|
||||
return Interpolate(i1, i2, fractional_Y);
|
||||
}
|
||||
|
||||
public static double PerlinNoise2D(double x, double y, int octaves, double persistence)
|
||||
{
|
||||
double frequency = 0.0;
|
||||
double amplitude = 0.0;
|
||||
double total = 0.0;
|
||||
|
||||
for (int i = 0; i < octaves; i++)
|
||||
{
|
||||
frequency = Math.Pow(2, i);
|
||||
amplitude = Math.Pow(persistence, i);
|
||||
|
||||
total += InterpolatedNoise(x * frequency, y * frequency) * amplitude;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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 OpenSim.Region.Environment.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain
|
||||
{
|
||||
public static class TerrainUtil
|
||||
{
|
||||
public static double MetersToSphericalStrength(double size)
|
||||
{
|
||||
return Math.Pow(2, size);
|
||||
}
|
||||
|
||||
public static double SphericalFactor(double x, double y, double rx, double ry, double size)
|
||||
{
|
||||
return size * size - ((x - rx) * (x - rx) + (y - ry) * (y - ry));
|
||||
}
|
||||
|
||||
public static double GetBilinearInterpolate(double x, double y, ITerrainChannel map)
|
||||
{
|
||||
int w = map.Width;
|
||||
int h = map.Height;
|
||||
|
||||
if (x > w - 2.0)
|
||||
x = w - 2.0;
|
||||
if (y > h - 2.0)
|
||||
y = h - 2.0;
|
||||
if (x < 0.0)
|
||||
x = 0.0;
|
||||
if (y < 0.0)
|
||||
y = 0.0;
|
||||
|
||||
int stepSize = 1;
|
||||
double h00 = map[(int) x, (int) y];
|
||||
double h10 = map[(int) x + stepSize, (int) y];
|
||||
double h01 = map[(int) x, (int) y + stepSize];
|
||||
double h11 = map[(int) x + stepSize, (int) y + stepSize];
|
||||
double h1 = h00;
|
||||
double h2 = h10;
|
||||
double h3 = h01;
|
||||
double h4 = h11;
|
||||
double a00 = h1;
|
||||
double a10 = h2 - h1;
|
||||
double a01 = h3 - h1;
|
||||
double a11 = h1 - h2 - h3 + h4;
|
||||
double partialx = x - (int) x;
|
||||
double partialz = y - (int) y;
|
||||
double hi = a00 + (a10 * partialx) + (a01 * partialz) + (a11 * partialx * partialz);
|
||||
return hi;
|
||||
}
|
||||
|
||||
private static double Noise(double x, double y)
|
||||
{
|
||||
int n = (int) x + (int) (y * 749);
|
||||
n = (n << 13) ^ n;
|
||||
return (1.0 - ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0);
|
||||
}
|
||||
|
||||
private static double SmoothedNoise1(double x, double y)
|
||||
{
|
||||
double corners = (Noise(x - 1, y - 1) + Noise(x + 1, y - 1) + Noise(x - 1, y + 1) + Noise(x + 1, y + 1)) / 16;
|
||||
double sides = (Noise(x - 1, y) + Noise(x + 1, y) + Noise(x, y - 1) + Noise(x, y + 1)) / 8;
|
||||
double center = Noise(x, y) / 4;
|
||||
return corners + sides + center;
|
||||
}
|
||||
|
||||
private static double Interpolate(double x, double y, double z)
|
||||
{
|
||||
return (x * (1.0 - z)) + (y * z);
|
||||
}
|
||||
|
||||
private static double InterpolatedNoise(double x, double y)
|
||||
{
|
||||
int integer_X = (int) (x);
|
||||
double fractional_X = x - integer_X;
|
||||
|
||||
int integer_Y = (int) y;
|
||||
double fractional_Y = y - integer_Y;
|
||||
|
||||
double v1 = SmoothedNoise1(integer_X, integer_Y);
|
||||
double v2 = SmoothedNoise1(integer_X + 1, integer_Y);
|
||||
double v3 = SmoothedNoise1(integer_X, integer_Y + 1);
|
||||
double v4 = SmoothedNoise1(integer_X + 1, integer_Y + 1);
|
||||
|
||||
double i1 = Interpolate(v1, v2, fractional_X);
|
||||
double i2 = Interpolate(v3, v4, fractional_X);
|
||||
|
||||
return Interpolate(i1, i2, fractional_Y);
|
||||
}
|
||||
|
||||
public static double PerlinNoise2D(double x, double y, int octaves, double persistence)
|
||||
{
|
||||
double frequency = 0.0;
|
||||
double amplitude = 0.0;
|
||||
double total = 0.0;
|
||||
|
||||
for (int i = 0; i < octaves; i++)
|
||||
{
|
||||
frequency = Math.Pow(2, i);
|
||||
amplitude = Math.Pow(persistence, i);
|
||||
|
||||
total += InterpolatedNoise(x * frequency, y * frequency) * amplitude;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,59 +1,59 @@
|
|||
using System;
|
||||
using NUnit.Framework;
|
||||
using OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class TerrainTest
|
||||
{
|
||||
[Test]
|
||||
public void BrushTest()
|
||||
{
|
||||
TerrainChannel x = new TerrainChannel(256, 256);
|
||||
ITerrainPaintableEffect effect = new RaiseSphere();
|
||||
|
||||
effect.PaintEffect(x, 128.0, 128.0, 50, 0.1);
|
||||
Assert.That(x[128, 128] > 0.0, "Raise brush not raising values.");
|
||||
Assert.That(x[0, 128] > 0.0, "Raise brush lowering edge values.");
|
||||
|
||||
x = new TerrainChannel(256, 256);
|
||||
effect = new LowerSphere();
|
||||
|
||||
effect.PaintEffect(x, 128.0, 128.0, 50, 0.1);
|
||||
Assert.That(x[128, 128] < 0.0, "Lower not lowering values.");
|
||||
Assert.That(x[0, 128] < 0.0, "Lower brush affecting edge values.");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TerrainChannelTest()
|
||||
{
|
||||
TerrainChannel x = new TerrainChannel(256, 256);
|
||||
Assert.That(x[0, 0] == 0.0, "Terrain not initialising correctly.");
|
||||
|
||||
x[0, 0] = 1.0;
|
||||
Assert.That(x[0, 0] == 1.0, "Terrain not setting values correctly.");
|
||||
|
||||
x[0, 0] = 0;
|
||||
x[0, 0] += 5.0;
|
||||
x[0, 0] -= 1.0;
|
||||
Assert.That(x[0, 0] == 4.0, "Terrain addition/subtraction error.");
|
||||
|
||||
x[0, 0] = Math.PI;
|
||||
double[,] doublesExport = x.GetDoubles();
|
||||
Assert.That(doublesExport[0, 0] == Math.PI, "Export to double[,] array not working correctly.");
|
||||
|
||||
x[0, 0] = 1.0;
|
||||
float[] floatsExport = x.GetFloatsSerialised();
|
||||
Assert.That(floatsExport[0] == 1.0f, "Export to float[] not working correctly.");
|
||||
|
||||
x[0, 0] = 1.0;
|
||||
Assert.That(x.Tainted(0, 0), "Terrain channel tainting not working correctly.");
|
||||
Assert.That(!x.Tainted(0, 0), "Terrain channel tainting not working correctly.");
|
||||
|
||||
TerrainChannel y = x.Copy();
|
||||
Assert.That(!ReferenceEquals(x, y), "Terrain copy not duplicating correctly.");
|
||||
Assert.That(!ReferenceEquals(x.GetDoubles(), y.GetDoubles()), "Terrain array not duplicating correctly.");
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
using OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules.World.Terrain.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class TerrainTest
|
||||
{
|
||||
[Test]
|
||||
public void BrushTest()
|
||||
{
|
||||
TerrainChannel x = new TerrainChannel(256, 256);
|
||||
ITerrainPaintableEffect effect = new RaiseSphere();
|
||||
|
||||
effect.PaintEffect(x, 128.0, 128.0, 50, 0.1);
|
||||
Assert.That(x[128, 128] > 0.0, "Raise brush not raising values.");
|
||||
Assert.That(x[0, 128] > 0.0, "Raise brush lowering edge values.");
|
||||
|
||||
x = new TerrainChannel(256, 256);
|
||||
effect = new LowerSphere();
|
||||
|
||||
effect.PaintEffect(x, 128.0, 128.0, 50, 0.1);
|
||||
Assert.That(x[128, 128] < 0.0, "Lower not lowering values.");
|
||||
Assert.That(x[0, 128] < 0.0, "Lower brush affecting edge values.");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TerrainChannelTest()
|
||||
{
|
||||
TerrainChannel x = new TerrainChannel(256, 256);
|
||||
Assert.That(x[0, 0] == 0.0, "Terrain not initialising correctly.");
|
||||
|
||||
x[0, 0] = 1.0;
|
||||
Assert.That(x[0, 0] == 1.0, "Terrain not setting values correctly.");
|
||||
|
||||
x[0, 0] = 0;
|
||||
x[0, 0] += 5.0;
|
||||
x[0, 0] -= 1.0;
|
||||
Assert.That(x[0, 0] == 4.0, "Terrain addition/subtraction error.");
|
||||
|
||||
x[0, 0] = Math.PI;
|
||||
double[,] doublesExport = x.GetDoubles();
|
||||
Assert.That(doublesExport[0, 0] == Math.PI, "Export to double[,] array not working correctly.");
|
||||
|
||||
x[0, 0] = 1.0;
|
||||
float[] floatsExport = x.GetFloatsSerialised();
|
||||
Assert.That(floatsExport[0] == 1.0f, "Export to float[] not working correctly.");
|
||||
|
||||
x[0, 0] = 1.0;
|
||||
Assert.That(x.Tainted(0, 0), "Terrain channel tainting not working correctly.");
|
||||
Assert.That(!x.Tainted(0, 0), "Terrain channel tainting not working correctly.");
|
||||
|
||||
TerrainChannel y = x.Copy();
|
||||
Assert.That(!ReferenceEquals(x, y), "Terrain copy not duplicating correctly.");
|
||||
Assert.That(!ReferenceEquals(x.GetDoubles(), y.GetDoubles()), "Terrain array not duplicating correctly.");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,251 +1,251 @@
|
|||
/*
|
||||
* 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.Timers;
|
||||
using Axiom.Math;
|
||||
using libsecondlife;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules
|
||||
{
|
||||
/// <summary>
|
||||
/// Version 2.0 - Very hacky compared to the original. Will fix original and release as 0.3 later.
|
||||
/// </summary>
|
||||
public class TreePopulatorModule : IRegionModule
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private Scene m_scene;
|
||||
|
||||
public double m_tree_density = 50.0; // Aim for this many per region
|
||||
public double m_tree_updates = 1000.0; // MS between updates
|
||||
private List<LLUUID> m_trees;
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource config)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_tree_density = config.Configs["Trees"].GetDouble("tree_density", m_tree_density);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
|
||||
m_trees = new List<LLUUID>();
|
||||
m_scene = scene;
|
||||
|
||||
m_scene.EventManager.OnPluginConsole += new EventManager.OnPluginConsoleDelegate(EventManager_OnPluginConsole);
|
||||
|
||||
Timer CalculateTrees = new Timer(m_tree_updates);
|
||||
CalculateTrees.Elapsed += new ElapsedEventHandler(CalculateTrees_Elapsed);
|
||||
CalculateTrees.Start();
|
||||
m_log.Debug("[TREES]: Initialised tree module");
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "TreePopulatorModule"; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void EventManager_OnPluginConsole(string[] args)
|
||||
{
|
||||
if (args[0] == "tree")
|
||||
{
|
||||
m_log.Debug("[TREES]: New tree planting");
|
||||
CreateTree(new LLVector3(128.0f, 128.0f, 0.0f));
|
||||
}
|
||||
}
|
||||
|
||||
private void growTrees()
|
||||
{
|
||||
foreach (LLUUID tree in m_trees)
|
||||
{
|
||||
if (m_scene.Entities.ContainsKey(tree))
|
||||
{
|
||||
SceneObjectPart s_tree = ((SceneObjectGroup) m_scene.Entities[tree]).RootPart;
|
||||
|
||||
// 100 seconds to grow 1m
|
||||
s_tree.Scale += new LLVector3(0.1f, 0.1f, 0.1f);
|
||||
s_tree.SendFullUpdateToAllClients();
|
||||
//s_tree.ScheduleTerseUpdate();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_trees.Remove(tree);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void seedTrees()
|
||||
{
|
||||
foreach (LLUUID tree in m_trees)
|
||||
{
|
||||
if (m_scene.Entities.ContainsKey(tree))
|
||||
{
|
||||
SceneObjectPart s_tree = ((SceneObjectGroup) m_scene.Entities[tree]).RootPart;
|
||||
|
||||
if (s_tree.Scale.X > 0.5)
|
||||
{
|
||||
if (Util.RandomClass.NextDouble() > 0.75)
|
||||
{
|
||||
SpawnChild(s_tree);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_trees.Remove(tree);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void killTrees()
|
||||
{
|
||||
foreach (LLUUID tree in m_trees)
|
||||
{
|
||||
double killLikelyhood = 0.0;
|
||||
|
||||
if (m_scene.Entities.ContainsKey(tree))
|
||||
{
|
||||
SceneObjectPart selectedTree = ((SceneObjectGroup) m_scene.Entities[tree]).RootPart;
|
||||
double selectedTreeScale = Math.Sqrt(Math.Pow(selectedTree.Scale.X, 2) +
|
||||
Math.Pow(selectedTree.Scale.Y, 2) +
|
||||
Math.Pow(selectedTree.Scale.Z, 2));
|
||||
|
||||
foreach (LLUUID picktree in m_trees)
|
||||
{
|
||||
if (picktree != tree)
|
||||
{
|
||||
SceneObjectPart pickedTree = ((SceneObjectGroup) m_scene.Entities[picktree]).RootPart;
|
||||
|
||||
double pickedTreeScale = Math.Sqrt(Math.Pow(pickedTree.Scale.X, 2) +
|
||||
Math.Pow(pickedTree.Scale.Y, 2) +
|
||||
Math.Pow(pickedTree.Scale.Z, 2));
|
||||
|
||||
double pickedTreeDistance = Math.Sqrt(Math.Pow(Math.Abs(pickedTree.AbsolutePosition.X - selectedTree.AbsolutePosition.X), 2) +
|
||||
Math.Pow(Math.Abs(pickedTree.AbsolutePosition.Y - selectedTree.AbsolutePosition.Y), 2) +
|
||||
Math.Pow(Math.Abs(pickedTree.AbsolutePosition.Z - selectedTree.AbsolutePosition.Z), 2));
|
||||
|
||||
killLikelyhood += (selectedTreeScale / (pickedTreeScale * pickedTreeDistance)) * 0.1;
|
||||
}
|
||||
}
|
||||
|
||||
if (Util.RandomClass.NextDouble() < killLikelyhood)
|
||||
{
|
||||
m_scene.RemoveEntity(selectedTree.ParentGroup);
|
||||
m_trees.Remove(selectedTree.ParentGroup.UUID);
|
||||
|
||||
m_scene.ForEachClient(delegate(IClientAPI controller)
|
||||
{
|
||||
controller.SendKillObject(m_scene.RegionInfo.RegionHandle,
|
||||
selectedTree.LocalId);
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
selectedTree.SetText(killLikelyhood.ToString(), new Vector3(1.0f, 1.0f, 1.0f), 1.0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_trees.Remove(tree);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SpawnChild(SceneObjectPart s_tree)
|
||||
{
|
||||
LLVector3 position = new LLVector3();
|
||||
|
||||
position.X = s_tree.AbsolutePosition.X + (1 * (-1 * Util.RandomClass.Next(1)));
|
||||
if (position.X > 255)
|
||||
position.X = 255;
|
||||
if (position.X < 0)
|
||||
position.X = 0;
|
||||
position.Y = s_tree.AbsolutePosition.Y + (1 * (-1 * Util.RandomClass.Next(1)));
|
||||
if (position.Y > 255)
|
||||
position.Y = 255;
|
||||
if (position.Y < 0)
|
||||
position.Y = 0;
|
||||
|
||||
double randX = ((Util.RandomClass.NextDouble() * 2.0) - 1.0) * (s_tree.Scale.X * 3);
|
||||
double randY = ((Util.RandomClass.NextDouble() * 2.0) - 1.0) * (s_tree.Scale.X * 3);
|
||||
|
||||
position.X += (float) randX;
|
||||
position.Y += (float) randY;
|
||||
|
||||
CreateTree(position);
|
||||
}
|
||||
|
||||
private void CreateTree(LLVector3 position)
|
||||
{
|
||||
position.Z = (float) m_scene.Heightmap[(int) position.X, (int) position.Y];
|
||||
|
||||
SceneObjectGroup tree =
|
||||
m_scene.AddTree(new LLVector3(0.1f, 0.1f, 0.1f),
|
||||
LLQuaternion.Identity,
|
||||
position,
|
||||
Tree.Cypress1,
|
||||
false);
|
||||
|
||||
m_trees.Add(tree.UUID);
|
||||
tree.SendGroupFullUpdate();
|
||||
}
|
||||
|
||||
private void CalculateTrees_Elapsed(object sender, ElapsedEventArgs e)
|
||||
{
|
||||
growTrees();
|
||||
seedTrees();
|
||||
killTrees();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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.Timers;
|
||||
using Axiom.Math;
|
||||
using libsecondlife;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Environment.Interfaces;
|
||||
using OpenSim.Region.Environment.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Environment.Modules
|
||||
{
|
||||
/// <summary>
|
||||
/// Version 2.0 - Very hacky compared to the original. Will fix original and release as 0.3 later.
|
||||
/// </summary>
|
||||
public class TreePopulatorModule : IRegionModule
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private Scene m_scene;
|
||||
|
||||
public double m_tree_density = 50.0; // Aim for this many per region
|
||||
public double m_tree_updates = 1000.0; // MS between updates
|
||||
private List<LLUUID> m_trees;
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource config)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_tree_density = config.Configs["Trees"].GetDouble("tree_density", m_tree_density);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
|
||||
m_trees = new List<LLUUID>();
|
||||
m_scene = scene;
|
||||
|
||||
m_scene.EventManager.OnPluginConsole += new EventManager.OnPluginConsoleDelegate(EventManager_OnPluginConsole);
|
||||
|
||||
Timer CalculateTrees = new Timer(m_tree_updates);
|
||||
CalculateTrees.Elapsed += new ElapsedEventHandler(CalculateTrees_Elapsed);
|
||||
CalculateTrees.Start();
|
||||
m_log.Debug("[TREES]: Initialised tree module");
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "TreePopulatorModule"; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void EventManager_OnPluginConsole(string[] args)
|
||||
{
|
||||
if (args[0] == "tree")
|
||||
{
|
||||
m_log.Debug("[TREES]: New tree planting");
|
||||
CreateTree(new LLVector3(128.0f, 128.0f, 0.0f));
|
||||
}
|
||||
}
|
||||
|
||||
private void growTrees()
|
||||
{
|
||||
foreach (LLUUID tree in m_trees)
|
||||
{
|
||||
if (m_scene.Entities.ContainsKey(tree))
|
||||
{
|
||||
SceneObjectPart s_tree = ((SceneObjectGroup) m_scene.Entities[tree]).RootPart;
|
||||
|
||||
// 100 seconds to grow 1m
|
||||
s_tree.Scale += new LLVector3(0.1f, 0.1f, 0.1f);
|
||||
s_tree.SendFullUpdateToAllClients();
|
||||
//s_tree.ScheduleTerseUpdate();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_trees.Remove(tree);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void seedTrees()
|
||||
{
|
||||
foreach (LLUUID tree in m_trees)
|
||||
{
|
||||
if (m_scene.Entities.ContainsKey(tree))
|
||||
{
|
||||
SceneObjectPart s_tree = ((SceneObjectGroup) m_scene.Entities[tree]).RootPart;
|
||||
|
||||
if (s_tree.Scale.X > 0.5)
|
||||
{
|
||||
if (Util.RandomClass.NextDouble() > 0.75)
|
||||
{
|
||||
SpawnChild(s_tree);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_trees.Remove(tree);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void killTrees()
|
||||
{
|
||||
foreach (LLUUID tree in m_trees)
|
||||
{
|
||||
double killLikelyhood = 0.0;
|
||||
|
||||
if (m_scene.Entities.ContainsKey(tree))
|
||||
{
|
||||
SceneObjectPart selectedTree = ((SceneObjectGroup) m_scene.Entities[tree]).RootPart;
|
||||
double selectedTreeScale = Math.Sqrt(Math.Pow(selectedTree.Scale.X, 2) +
|
||||
Math.Pow(selectedTree.Scale.Y, 2) +
|
||||
Math.Pow(selectedTree.Scale.Z, 2));
|
||||
|
||||
foreach (LLUUID picktree in m_trees)
|
||||
{
|
||||
if (picktree != tree)
|
||||
{
|
||||
SceneObjectPart pickedTree = ((SceneObjectGroup) m_scene.Entities[picktree]).RootPart;
|
||||
|
||||
double pickedTreeScale = Math.Sqrt(Math.Pow(pickedTree.Scale.X, 2) +
|
||||
Math.Pow(pickedTree.Scale.Y, 2) +
|
||||
Math.Pow(pickedTree.Scale.Z, 2));
|
||||
|
||||
double pickedTreeDistance = Math.Sqrt(Math.Pow(Math.Abs(pickedTree.AbsolutePosition.X - selectedTree.AbsolutePosition.X), 2) +
|
||||
Math.Pow(Math.Abs(pickedTree.AbsolutePosition.Y - selectedTree.AbsolutePosition.Y), 2) +
|
||||
Math.Pow(Math.Abs(pickedTree.AbsolutePosition.Z - selectedTree.AbsolutePosition.Z), 2));
|
||||
|
||||
killLikelyhood += (selectedTreeScale / (pickedTreeScale * pickedTreeDistance)) * 0.1;
|
||||
}
|
||||
}
|
||||
|
||||
if (Util.RandomClass.NextDouble() < killLikelyhood)
|
||||
{
|
||||
m_scene.RemoveEntity(selectedTree.ParentGroup);
|
||||
m_trees.Remove(selectedTree.ParentGroup.UUID);
|
||||
|
||||
m_scene.ForEachClient(delegate(IClientAPI controller)
|
||||
{
|
||||
controller.SendKillObject(m_scene.RegionInfo.RegionHandle,
|
||||
selectedTree.LocalId);
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
selectedTree.SetText(killLikelyhood.ToString(), new Vector3(1.0f, 1.0f, 1.0f), 1.0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_trees.Remove(tree);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SpawnChild(SceneObjectPart s_tree)
|
||||
{
|
||||
LLVector3 position = new LLVector3();
|
||||
|
||||
position.X = s_tree.AbsolutePosition.X + (1 * (-1 * Util.RandomClass.Next(1)));
|
||||
if (position.X > 255)
|
||||
position.X = 255;
|
||||
if (position.X < 0)
|
||||
position.X = 0;
|
||||
position.Y = s_tree.AbsolutePosition.Y + (1 * (-1 * Util.RandomClass.Next(1)));
|
||||
if (position.Y > 255)
|
||||
position.Y = 255;
|
||||
if (position.Y < 0)
|
||||
position.Y = 0;
|
||||
|
||||
double randX = ((Util.RandomClass.NextDouble() * 2.0) - 1.0) * (s_tree.Scale.X * 3);
|
||||
double randY = ((Util.RandomClass.NextDouble() * 2.0) - 1.0) * (s_tree.Scale.X * 3);
|
||||
|
||||
position.X += (float) randX;
|
||||
position.Y += (float) randY;
|
||||
|
||||
CreateTree(position);
|
||||
}
|
||||
|
||||
private void CreateTree(LLVector3 position)
|
||||
{
|
||||
position.Z = (float) m_scene.Heightmap[(int) position.X, (int) position.Y];
|
||||
|
||||
SceneObjectGroup tree =
|
||||
m_scene.AddTree(new LLVector3(0.1f, 0.1f, 0.1f),
|
||||
LLQuaternion.Identity,
|
||||
position,
|
||||
Tree.Cypress1,
|
||||
false);
|
||||
|
||||
m_trees.Add(tree.UUID);
|
||||
tree.SendGroupFullUpdate();
|
||||
}
|
||||
|
||||
private void CalculateTrees_Elapsed(object sender, ElapsedEventArgs e)
|
||||
{
|
||||
growTrees();
|
||||
seedTrees();
|
||||
killTrees();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -658,7 +658,6 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
float physicsFPS = 0;
|
||||
int agentsInScene = m_innerScene.GetRootAgentCount() + m_innerScene.GetChildAgentCount();
|
||||
|
||||
|
||||
if (agentsInScene > 21)
|
||||
{
|
||||
if (m_update_entities == 1)
|
||||
|
@ -676,7 +675,6 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
frameMS = System.Environment.TickCount;
|
||||
try
|
||||
{
|
||||
|
@ -687,7 +685,6 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
if (m_frame == Int32.MaxValue)
|
||||
m_frame = 0;
|
||||
|
||||
|
||||
physicsMS2 = System.Environment.TickCount;
|
||||
if ((m_frame % m_update_physics == 0) && m_physics_enabled)
|
||||
m_innerScene.UpdatePreparePhysics();
|
||||
|
|
|
@ -112,7 +112,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
private PhysicsActor _parent = null;
|
||||
private PhysicsActor m_taintparent = null;
|
||||
|
||||
|
||||
private bool iscolliding = false;
|
||||
private bool m_isphysical = false;
|
||||
private bool m_isSelected = false;
|
||||
|
@ -129,7 +128,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
public bool outofBounds = false;
|
||||
private float m_density = 10.000006836f; // Aluminum g/cm3;
|
||||
|
||||
|
||||
public bool _zeroFlag = false;
|
||||
private bool m_lastUpdateSent = false;
|
||||
|
||||
|
@ -1761,8 +1759,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
|
||||
public override bool Flying
|
||||
{
|
||||
get { return false; //no flying prims for you
|
||||
}
|
||||
// no flying prims for you
|
||||
get { return false; }
|
||||
set { }
|
||||
}
|
||||
|
||||
|
@ -1832,8 +1830,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
|
||||
public override PrimitiveBaseShape Shape
|
||||
{
|
||||
set {
|
||||
|
||||
set
|
||||
{
|
||||
_pbs = value;
|
||||
m_taintshape = true;
|
||||
}
|
||||
|
@ -1851,13 +1849,12 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
returnVelocity.Z = (m_lastVelocity.Z + _velocity.Z)/2;
|
||||
return returnVelocity;
|
||||
}
|
||||
set {
|
||||
set
|
||||
{
|
||||
_velocity = value;
|
||||
|
||||
m_taintVelocity = value;
|
||||
_parent_scene.AddPhysicsActorTaint(this);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1898,7 +1895,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
|
||||
public override PhysicsVector RotationalVelocity
|
||||
{
|
||||
get {
|
||||
get
|
||||
{
|
||||
PhysicsVector pv = new PhysicsVector(0, 0, 0);
|
||||
if (_zeroFlag)
|
||||
return pv;
|
||||
|
@ -1911,6 +1909,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
}
|
||||
set { m_rotationalVelocity = value; }
|
||||
}
|
||||
|
||||
public override void CrossingFailure()
|
||||
{
|
||||
m_crossingfailures++;
|
||||
|
@ -1918,7 +1917,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
{
|
||||
base.RaiseOutOfBounds(_position);
|
||||
return;
|
||||
|
||||
}
|
||||
else if (m_crossingfailures == 5)
|
||||
{
|
||||
|
@ -1942,7 +1940,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
m_taintparent = null;
|
||||
}
|
||||
|
||||
|
||||
public override void LockAngularMotion(PhysicsVector axis)
|
||||
{
|
||||
// reverse the zero/non zero values for ODE.
|
||||
|
@ -1958,7 +1955,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
// no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit!
|
||||
if (_parent != null)
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1973,7 +1969,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
|
||||
PhysicsVector l_position = new PhysicsVector();
|
||||
|
||||
|
||||
// kluge to keep things in bounds. ODE lets dead avatars drift away (they should be removed!)
|
||||
//if (vec.X < 0.0f) { vec.X = 0.0f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); }
|
||||
//if (vec.Y < 0.0f) { vec.Y = 0.0f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); }
|
||||
|
@ -2014,7 +2009,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
// Disables the prim's movement physics....
|
||||
// It's a hack and will generate a console message if it fails.
|
||||
|
||||
|
||||
//IsPhysical = false;
|
||||
if (_parent == null)
|
||||
base.RaiseOutOfBounds(_position);
|
||||
|
@ -2052,10 +2046,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
_zeroFlag = false;
|
||||
}
|
||||
|
||||
|
||||
if (_zeroFlag)
|
||||
{
|
||||
|
||||
_velocity.X = 0.0f;
|
||||
_velocity.Y = 0.0f;
|
||||
_velocity.Z = 0.0f;
|
||||
|
@ -2197,8 +2189,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
d.JointAttach(Amotor, Body, IntPtr.Zero);
|
||||
d.JointSetAMotorMode(Amotor, dAMotorEuler);
|
||||
|
||||
|
||||
|
||||
d.JointSetAMotorNumAxes(Amotor,(int)axisnum);
|
||||
int i = 0;
|
||||
|
||||
|
@ -2235,11 +2225,9 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 0.000000000001f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0.000000000001f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 0.000000000001f);
|
||||
|
||||
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.FudgeFactor, 0f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.FMax, m_tensor);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue