Merge branch 'master' of ssh://opensimulator.org/var/git/opensim

dsg
Dan Lake 2011-06-14 23:16:02 -07:00
commit fc67a9212e
38 changed files with 1584 additions and 219 deletions

View File

@ -25,8 +25,8 @@ COMMIT;
BEGIN;
ALTER TABLE `Friends` MODIFY COLUMN PrincipalID varchar(255) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000';
ALTER TABLE `Friends` DROP PRIMARY KEY;
ALTER TABLE `Friends` ADD PRIMARY KEY(PrincipalID(36), Friend(36));
ALTER TABLE `Friends` MODIFY COLUMN PrincipalID varchar(255) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000';
COMMIT;

View File

@ -182,6 +182,9 @@ namespace OpenSim.Framework.Serialization.External
case "FixedSun":
settings.FixedSun = bool.Parse(xtr.ReadElementContentAsString());
break;
case "SunPosition":
settings.SunPosition = double.Parse(xtr.ReadElementContentAsString());
break;
}
}
@ -237,8 +240,9 @@ namespace OpenSim.Framework.Serialization.External
xtw.WriteElementString("TerrainLowerLimit", settings.TerrainLowerLimit.ToString());
xtw.WriteElementString("UseEstateSun", settings.UseEstateSun.ToString());
xtw.WriteElementString("FixedSun", settings.FixedSun.ToString());
// XXX: Need to expose interface to get sun phase information from sun module
// xtw.WriteStartElement("SunPhase",
xtw.WriteElementString("SunPosition", settings.SunPosition.ToString());
// Note: 'SunVector' isn't saved because this value is owned by the Sun Module, which
// calculates it automatically according to the date and other factors.
xtw.WriteEndElement();
xtw.WriteEndElement();

View File

@ -412,7 +412,7 @@ namespace OpenSim.Framework.Servers.HttpServer
// OpenSim.Framework.WebUtil.OSHeaderRequestID
if (request.Headers["opensim-request-id"] != null)
reqnum = String.Format("{0}:{1}",request.RemoteIPEndPoint,request.Headers["opensim-request-id"]);
// m_log.DebugFormat("[BASE HTTP SERVER]: <{0}> handle request for {1}",reqnum,request.RawUrl);
//m_log.DebugFormat("[BASE HTTP SERVER]: <{0}> handle request for {1}",reqnum,request.RawUrl);
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US", true);
@ -440,7 +440,7 @@ namespace OpenSim.Framework.Servers.HttpServer
string path = request.RawUrl;
string handlerKey = GetHandlerKey(request.HttpMethod, path);
// m_log.DebugFormat("[BASE HTTP SERVER]: Handling {0} request for {1}", request.HttpMethod, path);
//m_log.DebugFormat("[BASE HTTP SERVER]: Handling {0} request for {1}", request.HttpMethod, path);
if (TryGetStreamHandler(handlerKey, out requestHandler))
{

View File

@ -0,0 +1,152 @@
/*
* 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 OpenSimulator 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 log4net;
using Nini.Config;
using Mono.Addins;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
using OpenSim.Framework;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
using Caps = OpenSim.Framework.Capabilities.Caps;
namespace OpenSim.Region.ClientStack.Linden
{
/// <summary>
/// SimulatorFeatures capability. This is required for uploading Mesh.
/// Since is accepts an open-ended response, we also send more information
/// for viewers that care to interpret it.
///
/// NOTE: Part of this code was adapted from the Aurora project, specifically
/// the normal part of the response in the capability handler.
/// </summary>
///
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
public class SimulatorFeaturesModule : ISharedRegionModule
{
private static readonly ILog m_log =
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private Scene m_scene;
private string m_MapImageServerURL = string.Empty;
private string m_SearchURL = string.Empty;
#region ISharedRegionModule Members
public void Initialise(IConfigSource source)
{
IConfig config = source.Configs["SimulatorFeatures"];
if (config == null)
return;
m_MapImageServerURL = config.GetString("MapImageServerURI", string.Empty);
if (m_MapImageServerURL != string.Empty)
{
m_MapImageServerURL = m_MapImageServerURL.Trim();
if (!m_MapImageServerURL.EndsWith("/"))
m_MapImageServerURL = m_MapImageServerURL + "/";
}
m_SearchURL = config.GetString("SearchServerURI", string.Empty);
}
public void AddRegion(Scene s)
{
m_scene = s;
m_scene.EventManager.OnRegisterCaps += RegisterCaps;
}
public void RemoveRegion(Scene s)
{
m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
}
public void RegionLoaded(Scene s)
{
}
public void PostInitialise()
{
}
public void Close() { }
public string Name { get { return "SimulatorFeaturesModule"; } }
public Type ReplaceableInterface
{
get { return null; }
}
#endregion
public void RegisterCaps(UUID agentID, Caps caps)
{
IRequestHandler reqHandler = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), SimulatorFeatures);
caps.RegisterHandler("SimulatorFeatures", reqHandler);
}
private Hashtable SimulatorFeatures(Hashtable mDhttpMethod)
{
m_log.DebugFormat("[SIMULATOR FEATURES MODULE]: SimulatorFeatures request");
OSDMap data = new OSDMap();
data["MeshRezEnabled"] = true;
data["MeshUploadEnabled"] = true;
data["MeshXferEnabled"] = true;
data["PhysicsMaterialsEnabled"] = true;
OSDMap typesMap = new OSDMap();
typesMap["convex"] = true;
typesMap["none"] = true;
typesMap["prim"] = true;
data["PhysicsShapeTypes"] = typesMap;
// Extra information for viewers that want to use it
OSDMap gridServicesMap = new OSDMap();
if (m_MapImageServerURL != string.Empty)
gridServicesMap["map-server-url"] = m_MapImageServerURL;
if (m_SearchURL != string.Empty)
gridServicesMap["search"] = m_SearchURL;
data["GridServices"] = gridServicesMap;
//Send back data
Hashtable responsedata = new Hashtable();
responsedata["int_response_code"] = 200;
responsedata["content_type"] = "text/plain";
responsedata["keepalive"] = false;
responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(data);
return responsedata;
}
}
}

View File

@ -64,13 +64,13 @@ namespace Flotsam.RegionModules.AssetCache
private bool m_Enabled;
private const string m_ModuleName = "FlotsamAssetCache";
private const string m_DefaultCacheDirectory = m_ModuleName;
private const string m_DefaultCacheDirectory = "./assetcache";
private string m_CacheDirectory = m_DefaultCacheDirectory;
private readonly List<char> m_InvalidChars = new List<char>();
private int m_LogLevel = 0;
private ulong m_HitRateDisplay = 1; // How often to display hit statistics, given in requests
private ulong m_HitRateDisplay = 100; // How often to display hit statistics, given in requests
private static ulong m_Requests;
private static ulong m_RequestsForInprogress;
@ -87,14 +87,14 @@ namespace Flotsam.RegionModules.AssetCache
#endif
private ExpiringCache<string, AssetBase> m_MemoryCache;
private bool m_MemoryCacheEnabled = true;
private bool m_MemoryCacheEnabled = false;
// Expiration is expressed in hours.
private const double m_DefaultMemoryExpiration = 1.0;
private const double m_DefaultMemoryExpiration = 2;
private const double m_DefaultFileExpiration = 48;
private TimeSpan m_MemoryExpiration = TimeSpan.FromHours(m_DefaultMemoryExpiration);
private TimeSpan m_FileExpiration = TimeSpan.FromHours(m_DefaultFileExpiration);
private TimeSpan m_FileExpirationCleanupTimer = TimeSpan.FromHours(m_DefaultFileExpiration);
private TimeSpan m_FileExpirationCleanupTimer = TimeSpan.FromHours(0.166);
private static int m_CacheDirectoryTiers = 1;
private static int m_CacheDirectoryTierLen = 3;
@ -141,26 +141,38 @@ namespace Flotsam.RegionModules.AssetCache
IConfig assetConfig = source.Configs["AssetCache"];
if (assetConfig == null)
{
m_log.Warn("[FLOTSAM ASSET CACHE]: AssetCache missing from OpenSim.ini, using defaults.");
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Cache Directory", m_DefaultCacheDirectory);
return;
m_log.Warn(
"[FLOTSAM ASSET CACHE]: AssetCache section missing from config (not copied config-include/FlotsamCache.ini.example? Using defaults.");
}
else
{
m_CacheDirectory = assetConfig.GetString("CacheDirectory", m_DefaultCacheDirectory);
m_MemoryCacheEnabled = assetConfig.GetBoolean("MemoryCacheEnabled", m_MemoryCacheEnabled);
m_MemoryExpiration = TimeSpan.FromHours(assetConfig.GetDouble("MemoryCacheTimeout", m_DefaultMemoryExpiration));
#if WAIT_ON_INPROGRESS_REQUESTS
m_WaitOnInprogressTimeout = assetConfig.GetInt("WaitOnInprogressTimeout", 3000);
#endif
m_LogLevel = assetConfig.GetInt("LogLevel", m_LogLevel);
m_HitRateDisplay = (ulong)assetConfig.GetLong("HitRateDisplay", (long)m_HitRateDisplay);
m_FileExpiration = TimeSpan.FromHours(assetConfig.GetDouble("FileCacheTimeout", m_DefaultFileExpiration));
m_FileExpirationCleanupTimer
= TimeSpan.FromHours(
assetConfig.GetDouble("FileCleanupTimer", m_FileExpirationCleanupTimer.TotalHours));
m_CacheDirectoryTiers = assetConfig.GetInt("CacheDirectoryTiers", m_CacheDirectoryTiers);
m_CacheDirectoryTierLen = assetConfig.GetInt("CacheDirectoryTierLength", m_CacheDirectoryTierLen);
m_CacheWarnAt = assetConfig.GetInt("CacheWarnAt", m_CacheWarnAt);
m_DeepScanBeforePurge = assetConfig.GetBoolean("DeepScanBeforePurge", m_DeepScanBeforePurge);
}
m_CacheDirectory = assetConfig.GetString("CacheDirectory", m_DefaultCacheDirectory);
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Cache Directory", m_CacheDirectory);
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Cache Directory {0}", m_CacheDirectory);
m_MemoryCacheEnabled = assetConfig.GetBoolean("MemoryCacheEnabled", false);
m_MemoryExpiration = TimeSpan.FromHours(assetConfig.GetDouble("MemoryCacheTimeout", m_DefaultMemoryExpiration));
#if WAIT_ON_INPROGRESS_REQUESTS
m_WaitOnInprogressTimeout = assetConfig.GetInt("WaitOnInprogressTimeout", 3000);
#endif
m_LogLevel = assetConfig.GetInt("LogLevel", 0);
m_HitRateDisplay = (ulong)assetConfig.GetInt("HitRateDisplay", 1000);
m_FileExpiration = TimeSpan.FromHours(assetConfig.GetDouble("FileCacheTimeout", m_DefaultFileExpiration));
m_FileExpirationCleanupTimer = TimeSpan.FromHours(assetConfig.GetDouble("FileCleanupTimer", m_DefaultFileExpiration));
if ((m_FileExpiration > TimeSpan.Zero) && (m_FileExpirationCleanupTimer > TimeSpan.Zero))
{
m_CacheCleanTimer = new System.Timers.Timer(m_FileExpirationCleanupTimer.TotalMilliseconds);
@ -170,7 +182,6 @@ namespace Flotsam.RegionModules.AssetCache
m_CacheCleanTimer.Start();
}
m_CacheDirectoryTiers = assetConfig.GetInt("CacheDirectoryTiers", 1);
if (m_CacheDirectoryTiers < 1)
{
m_CacheDirectoryTiers = 1;
@ -180,7 +191,6 @@ namespace Flotsam.RegionModules.AssetCache
m_CacheDirectoryTiers = 3;
}
m_CacheDirectoryTierLen = assetConfig.GetInt("CacheDirectoryTierLength", 3);
if (m_CacheDirectoryTierLen < 1)
{
m_CacheDirectoryTierLen = 1;
@ -190,14 +200,10 @@ namespace Flotsam.RegionModules.AssetCache
m_CacheDirectoryTierLen = 4;
}
m_CacheWarnAt = assetConfig.GetInt("CacheWarnAt", 30000);
m_DeepScanBeforePurge = assetConfig.GetBoolean("DeepScanBeforePurge", false);
MainConsole.Instance.Commands.AddCommand(this.Name, true, "fcache status", "fcache status", "Display cache status", HandleConsoleCommand);
MainConsole.Instance.Commands.AddCommand(this.Name, true, "fcache clear", "fcache clear [file] [memory]", "Remove all assets in the file and/or memory cache", HandleConsoleCommand);
MainConsole.Instance.Commands.AddCommand(this.Name, true, "fcache assets", "fcache assets", "Attempt a deep scan and cache of all assets in all scenes", HandleConsoleCommand);
MainConsole.Instance.Commands.AddCommand(this.Name, true, "fcache expire", "fcache expire <datetime>", "Purge cached assets older then the specified date/time", HandleConsoleCommand);
MainConsole.Instance.Commands.AddCommand(Name, true, "fcache status", "fcache status", "Display cache status", HandleConsoleCommand);
MainConsole.Instance.Commands.AddCommand(Name, true, "fcache clear", "fcache clear [file] [memory]", "Remove all assets in the cache. If file or memory is specified then only this cache is cleared.", HandleConsoleCommand);
MainConsole.Instance.Commands.AddCommand(Name, true, "fcache assets", "fcache assets", "Attempt a deep scan and cache of all assets in all scenes", HandleConsoleCommand);
MainConsole.Instance.Commands.AddCommand(Name, true, "fcache expire", "fcache expire <datetime>", "Purge cached assets older then the specified date/time", HandleConsoleCommand);
}
}
}
@ -723,24 +729,39 @@ namespace Flotsam.RegionModules.AssetCache
break;
case "clear":
if (cmdparams.Length < 3)
if (cmdparams.Length < 2)
{
m_log.Warn("[FLOTSAM ASSET CACHE] Please specify memory and/or file cache.");
m_log.Warn("[FLOTSAM ASSET CACHE] Usage is fcache clear [file] [memory]");
break;
}
bool clearMemory = false, clearFile = false;
if (cmdparams.Length == 2)
{
clearMemory = true;
clearFile = true;
}
foreach (string s in cmdparams)
{
if (s.ToLower() == "memory")
{
m_MemoryCache.Clear();
m_log.Info("[FLOTSAM ASSET CACHE] Memory cache cleared.");
}
clearMemory = true;
else if (s.ToLower() == "file")
{
ClearFileCache();
m_log.Info("[FLOTSAM ASSET CACHE] File cache cleared.");
}
clearFile = true;
}
if (clearMemory)
{
m_MemoryCache.Clear();
m_log.Info("[FLOTSAM ASSET CACHE] Memory cache cleared.");
}
if (clearFile)
{
ClearFileCache();
m_log.Info("[FLOTSAM ASSET CACHE] File cache cleared.");
}
break;

View File

@ -29,6 +29,8 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Threading;
using log4net;
using Nini.Config;
using Nwc.XmlRpc;
@ -194,46 +196,46 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
//}
private void CollectOnlineFriendsElsewhere(UUID userID, List<string> foreignFriends)
{
// let's divide the friends on a per-domain basis
Dictionary<string, List<string>> friendsPerDomain = new Dictionary<string, List<string>>();
foreach (string friend in foreignFriends)
{
UUID friendID;
if (!UUID.TryParse(friend, out friendID))
{
// it's a foreign friend
string url = string.Empty, tmp = string.Empty;
if (Util.ParseUniversalUserIdentifier(friend, out friendID, out url, out tmp, out tmp, out tmp))
{
if (!friendsPerDomain.ContainsKey(url))
friendsPerDomain[url] = new List<string>();
friendsPerDomain[url].Add(friend);
}
}
}
//private void CollectOnlineFriendsElsewhere(UUID userID, List<string> foreignFriends)
//{
// // let's divide the friends on a per-domain basis
// Dictionary<string, List<string>> friendsPerDomain = new Dictionary<string, List<string>>();
// foreach (string friend in foreignFriends)
// {
// UUID friendID;
// if (!UUID.TryParse(friend, out friendID))
// {
// // it's a foreign friend
// string url = string.Empty, tmp = string.Empty;
// if (Util.ParseUniversalUserIdentifier(friend, out friendID, out url, out tmp, out tmp, out tmp))
// {
// if (!friendsPerDomain.ContainsKey(url))
// friendsPerDomain[url] = new List<string>();
// friendsPerDomain[url].Add(friend);
// }
// }
// }
// Now, call those worlds
// // Now, call those worlds
foreach (KeyValuePair<string, List<string>> kvp in friendsPerDomain)
{
List<string> ids = new List<string>();
foreach (string f in kvp.Value)
ids.Add(f);
UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key);
List<UUID> online = uConn.GetOnlineFriends(userID, ids);
// Finally send the notifications to the user
// this whole process may take a while, so let's check at every
// iteration that the user is still here
IClientAPI client = LocateClientObject(userID);
if (client != null)
client.SendAgentOnline(online.ToArray());
else
break;
}
// foreach (KeyValuePair<string, List<string>> kvp in friendsPerDomain)
// {
// List<string> ids = new List<string>();
// foreach (string f in kvp.Value)
// ids.Add(f);
// UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key);
// List<UUID> online = uConn.GetOnlineFriends(userID, ids);
// // Finally send the notifications to the user
// // this whole process may take a while, so let's check at every
// // iteration that the user is still here
// IClientAPI client = LocateClientObject(userID);
// if (client != null)
// client.SendAgentOnline(online.ToArray());
// else
// break;
// }
}
//}
protected override void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online)
{
@ -280,8 +282,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
ids.Add(f.Friend);
UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key);
List<UUID> friendsOnline = uConn.StatusNotification(ids, userID, online);
// need to debug this here
if (online)
if (online && friendsOnline.Count > 0)
{
IClientAPI client = LocateClientObject(userID);
if (client != null)
@ -302,15 +304,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
if (Util.ParseUniversalUserIdentifier(fid, out agentID, out url, out first, out last, out tmp))
{
IUserManagement userMan = m_Scenes[0].RequestModuleInterface<IUserManagement>();
userMan.AddUser(agentID, url + ";" + first + " " + last);
userMan.AddUser(agentID, first, last, url);
try // our best
{
string[] parts = userMan.GetUserName(agentID).Split();
first = parts[0];
last = parts[1];
}
catch { }
return true;
}
return false;

View File

@ -147,7 +147,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
protected void SaveInvItem(InventoryItemBase inventoryItem, string path, Dictionary<string, object> options, IUserAccountService userAccountService)
{
if (options.ContainsKey("verbose"))
m_log.InfoFormat("[INVENTORY ARCHIVER]: Saving item {0} with asset {1}", inventoryItem.ID, inventoryItem.AssetID);
m_log.InfoFormat(
"[INVENTORY ARCHIVER]: Saving item {0} {1} with asset {2}",
inventoryItem.ID, inventoryItem.Name, inventoryItem.AssetID);
string filename = path + CreateArchiveItemName(inventoryItem);

View File

@ -148,9 +148,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
base.AgentHasMovedAway(sp, logout);
if (logout)
{
// Reset the map
ResetMap(sp);
// Log them out of this grid
m_aScene.PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
}
@ -285,28 +282,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
}
protected void ResetMap(ScenePresence sp)
{
List<GridRegion> regions = m_Scenes[0].GridService.GetRegionRange(m_Scenes[0].RegionInfo.ScopeID, 0, 17000 * (int)Constants.RegionSize, 0, 17000 * (int)Constants.RegionSize);
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Resetting {0} tiles on the map", regions.Count);
if (regions != null)
{
List<MapBlockData> mapBlocks = new List<MapBlockData>();
foreach (GridRegion r in regions)
{
MapBlockData mblock = new MapBlockData();
mblock.X = (ushort)(r.RegionLocX / Constants.RegionSize);
mblock.Y = (ushort)(r.RegionLocY / Constants.RegionSize);
mblock.Name = "";
mblock.Access = 254; // means 'simulator is offline'. We need this because the viewer ignores 255's
mblock.MapImageId = UUID.Zero;
mapBlocks.Add(mblock);
}
sp.ControllingClient.SendMapBlock(mapBlocks, 0);
}
}
#endregion
#region IUserAgentVerificationModule

View File

@ -41,7 +41,10 @@ namespace OpenSim.Region.CoreModules.Hypergrid
{
public class HGWorldMapModule : WorldMapModule
{
//private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
// Remember the map area that each client has been exposed to in this region
private Dictionary<UUID, List<MapBlockData>> m_SeenMapBlocks = new Dictionary<UUID, List<MapBlockData>>();
#region INonSharedRegionModule Members
@ -52,6 +55,13 @@ namespace OpenSim.Region.CoreModules.Hypergrid
m_Enabled = true;
}
public override void AddRegion(Scene scene)
{
base.AddRegion(scene);
scene.EventManager.OnClientClosed += new EventManager.ClientClosed(EventManager_OnClientClosed);
}
public override string Name
{
get { return "HGWorldMap"; }
@ -59,65 +69,70 @@ namespace OpenSim.Region.CoreModules.Hypergrid
#endregion
//protected override void GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
//{
// List<MapBlockData> mapBlocks = new List<MapBlockData>();
// List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID,
// minX * (int)Constants.RegionSize, maxX * (int)Constants.RegionSize,
// minY * (int)Constants.RegionSize, maxY * (int)Constants.RegionSize);
// foreach (GridRegion r in regions)
// {
// uint x = 0, y = 0;
// long handle = 0;
// if (r.RegionSecret != null && r.RegionSecret != string.Empty)
// {
// if (long.TryParse(r.RegionSecret, out handle))
// {
// Utils.LongToUInts((ulong)handle, out x, out y);
// x = x / Constants.RegionSize;
// y = y / Constants.RegionSize;
// }
// }
// if (handle == 0 ||
// // Check the distance from the current region
// (handle != 0 && Math.Abs((int)(x - m_scene.RegionInfo.RegionLocX)) < 4096 && Math.Abs((int)(y - m_scene.RegionInfo.RegionLocY)) < 4096))
// {
// MapBlockData block = new MapBlockData();
// MapBlockFromGridRegion(block, r);
// mapBlocks.Add(block);
// }
// }
// // Different from super
// //FillInMap(mapBlocks, minX, minY, maxX, maxY);
// //
// remoteClient.SendMapBlock(mapBlocks, 0);
//}
private void FillInMap(List<MapBlockData> mapBlocks, int minX, int minY, int maxX, int maxY)
void EventManager_OnClientClosed(UUID clientID, Scene scene)
{
for (int x = minX; x <= maxX; x++)
ScenePresence sp = scene.GetScenePresence(clientID);
if (sp != null)
{
for (int y = minY; y <= maxY; y++)
if (m_SeenMapBlocks.ContainsKey(clientID))
{
MapBlockData mblock = mapBlocks.Find(delegate(MapBlockData mb) { return ((mb.X == x) && (mb.Y == y)); });
if (mblock == null)
List<MapBlockData> mapBlocks = m_SeenMapBlocks[clientID];
foreach (MapBlockData b in mapBlocks)
{
mblock = new MapBlockData();
mblock.X = (ushort)x;
mblock.Y = (ushort)y;
mblock.Name = "";
mblock.Access = 254; // means 'simulator is offline'. We need this because the viewer ignores 255's
mblock.MapImageId = UUID.Zero;
mapBlocks.Add(mblock);
b.Name = string.Empty;
b.Access = 254; // means 'simulator is offline'. We need this because the viewer ignores 255's
}
m_log.DebugFormat("[HG MAP]: Reseting {0} blocks", mapBlocks.Count);
sp.ControllingClient.SendMapBlock(mapBlocks, 0);
m_SeenMapBlocks.Remove(clientID);
}
}
}
protected override List<MapBlockData> GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
{
List<MapBlockData> mapBlocks = base.GetAndSendBlocks(remoteClient, minX, minY, maxX, maxY, flag);
lock (m_SeenMapBlocks)
{
if (!m_SeenMapBlocks.ContainsKey(remoteClient.AgentId))
{
m_SeenMapBlocks.Add(remoteClient.AgentId, mapBlocks);
}
else
{
List<MapBlockData> seen = m_SeenMapBlocks[remoteClient.AgentId];
List<MapBlockData> newBlocks = new List<MapBlockData>();
foreach (MapBlockData b in mapBlocks)
if (seen.Find(delegate(MapBlockData bdata) { return bdata.X == b.X && bdata.Y == b.Y; }) == null)
newBlocks.Add(b);
seen.AddRange(newBlocks);
}
}
return mapBlocks;
}
}
class MapArea
{
public int minX;
public int minY;
public int maxX;
public int maxY;
public MapArea(int mix, int miy, int max, int may)
{
minX = mix;
minY = miy;
maxX = max;
maxY = may;
}
public void Print()
{
Console.WriteLine(String.Format(" --> Area is minX={0} minY={1} minY={2} maxY={3}", minX, minY, maxY, maxY));
}
}
}

View File

@ -0,0 +1,111 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator 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 System.Collections.Generic;
using log4net;
using Mono.Addins;
using Nini.Config;
using OpenSim.Framework;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Server.Base;
using OpenSim.Server.Handlers.Base;
using OpenSim.Server.Handlers.MapImage;
using OpenSim.Services.Interfaces;
namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.MapImage
{
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
public class MapImageServiceInConnectorModule : ISharedRegionModule
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static bool m_Enabled = false;
private IConfigSource m_Config;
bool m_Registered = false;
#region IRegionModule interface
public void Initialise(IConfigSource config)
{
m_Config = config;
IConfig moduleConfig = config.Configs["Modules"];
if (moduleConfig != null)
{
m_Enabled = moduleConfig.GetBoolean("MapImageServiceInConnector", false);
if (m_Enabled)
{
m_log.Info("[MAP SERVICE IN CONNECTOR]: MapImage Service In Connector enabled");
new MapGetServiceConnector(m_Config, MainServer.Instance, "MapImageService");
}
}
}
public void PostInitialise()
{
}
public void Close()
{
}
public Type ReplaceableInterface
{
get { return null; }
}
public string Name
{
get { return "MapImageServiceIn"; }
}
public void AddRegion(Scene scene)
{
if (!m_Enabled)
return;
}
public void RemoveRegion(Scene scene)
{
if (!m_Enabled)
return;
}
public void RegionLoaded(Scene scene)
{
if (!m_Enabled)
return;
}
#endregion
}
}

View File

@ -0,0 +1,232 @@
/*
* 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 OpenSimulator 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.Net;
using System.IO;
using System.Timers;
using System.Drawing;
using System.Drawing.Imaging;
using log4net;
using Mono.Addins;
using Nini.Config;
using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
using OpenSim.Server.Base;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage
{
/// <summary>
/// </summary>
/// <remarks>
/// </remarks>
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
public class MapImageServiceModule : ISharedRegionModule
{
private static readonly ILog m_log =
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private bool m_enabled = false;
private IMapImageService m_MapService;
private string m_serverUrl = String.Empty;
private Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>();
private int m_refreshtime = 0;
private int m_lastrefresh = 0;
private System.Timers.Timer m_refreshTimer = new System.Timers.Timer();
#region ISharedRegionModule
public Type ReplaceableInterface { get { return null; } }
public string Name { get { return "MapImageServiceModule"; } }
public void RegionLoaded(Scene scene) { }
public void Close() { }
public void PostInitialise() { }
///<summary>
///
///</summary>
public void Initialise(IConfigSource source)
{
IConfig moduleConfig = source.Configs["Modules"];
if (moduleConfig != null)
{
string name = moduleConfig.GetString("MapImageService", "");
if (name != Name)
return;
}
IConfig config = source.Configs["MapImageService"];
if (config == null)
return;
int refreshminutes = Convert.ToInt32(config.GetString("RefreshTime"));
if (refreshminutes <= 0)
{
m_log.WarnFormat("[MAP IMAGE SERVICE MODULE]: No refresh time given in config. Module disabled.");
return;
}
m_refreshtime = refreshminutes * 60 * 1000; // convert from minutes to ms
string service = config.GetString("LocalServiceModule", string.Empty);
if (service == string.Empty)
{
m_log.WarnFormat("[MAP IMAGE SERVICE MODULE]: No service dll given in config. Unable to proceed.");
return;
}
Object[] args = new Object[] { source };
m_MapService = ServerUtils.LoadPlugin<IMapImageService>(service, args);
m_refreshTimer.Enabled = true;
m_refreshTimer.AutoReset = true;
m_refreshTimer.Interval = m_refreshtime;
m_refreshTimer.Elapsed += new ElapsedEventHandler(HandleMaptileRefresh);
m_log.InfoFormat("[MAP IMAGE SERVICE MODULE]: enabled with refresh time {0}min and service object {1}",
refreshminutes, service);
m_enabled = true;
}
///<summary>
///
///</summary>
///<summary>
///
///</summary>
public void AddRegion(Scene scene)
{
if (! m_enabled)
return;
// Every shared region module has to maintain an indepedent list of
// currently running regions
lock (m_scenes)
m_scenes[scene.RegionInfo.RegionID] = scene;
scene.EventManager.OnPrimsLoaded += new EventManager.PrimsLoaded(EventManager_OnPrimsLoaded);
}
///<summary>
///
///</summary>
public void RemoveRegion(Scene scene)
{
if (! m_enabled)
return;
lock (m_scenes)
m_scenes.Remove(scene.RegionInfo.RegionID);
}
#endregion ISharedRegionModule
void EventManager_OnPrimsLoaded(Scene s)
{
UploadMapTile(s);
}
///<summary>
///
///</summary>
private void HandleMaptileRefresh(object sender, EventArgs ea)
{
// this approach is a bit convoluted becase we want to wait for the
// first upload to happen on startup but after all the objects are
// loaded and initialized
if (m_lastrefresh > 0 && Util.EnvironmentTickCountSubtract(m_lastrefresh) < m_refreshtime)
return;
m_log.DebugFormat("[MAP IMAGE SERVICE MODULE]: map refresh!");
lock (m_scenes)
{
foreach (IScene scene in m_scenes.Values)
{
try
{
UploadMapTile(scene);
}
catch (Exception ex)
{
m_log.WarnFormat("[MAP IMAGE SERVICE MODULE]: something bad happened {0}", ex.Message);
}
}
}
m_lastrefresh = Util.EnvironmentTickCount();
}
///<summary>
///
///</summary>
private void UploadMapTile(IScene scene)
{
m_log.DebugFormat("[MAP IMAGE SERVICE MODULE]: upload maptile for {0}", scene.RegionInfo.RegionName);
// Create a PNG map tile and upload it to the AddMapTile API
byte[] jpgData = Utils.EmptyBytes;
IMapImageGenerator tileGenerator = scene.RequestModuleInterface<IMapImageGenerator>();
if (tileGenerator == null)
{
m_log.Warn("[MAP IMAGE SERVICE MODULE]: Cannot upload PNG map tile without an ImageGenerator");
return;
}
using (Image mapTile = tileGenerator.CreateMapTile())
{
using (MemoryStream stream = new MemoryStream())
{
mapTile.Save(stream, ImageFormat.Jpeg);
jpgData = stream.ToArray();
}
}
string reason = string.Empty;
if (!m_MapService.AddMapTile((int)scene.RegionInfo.RegionLocX, (int)scene.RegionInfo.RegionLocY, jpgData, out reason))
{
m_log.DebugFormat("[MAP IMAGE SERVICE MODULE]: Unable to upload tile image for {0} at {1}-{2}: {3}",
scene.RegionInfo.RegionName, scene.RegionInfo.RegionLocX, scene.RegionInfo.RegionLocY, reason);
}
}
}
}

View File

@ -488,6 +488,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
currentRegionSettings.Elevation2SE = loadedRegionSettings.Elevation2SE;
currentRegionSettings.Elevation2SW = loadedRegionSettings.Elevation2SW;
currentRegionSettings.FixedSun = loadedRegionSettings.FixedSun;
currentRegionSettings.SunPosition = loadedRegionSettings.SunPosition;
currentRegionSettings.ObjectBonus = loadedRegionSettings.ObjectBonus;
currentRegionSettings.RestrictPushing = loadedRegionSettings.RestrictPushing;
currentRegionSettings.TerrainLowerLimit = loadedRegionSettings.TerrainLowerLimit;
@ -500,6 +501,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
currentRegionSettings.WaterHeight = loadedRegionSettings.WaterHeight;
currentRegionSettings.Save();
m_scene.TriggerEstateSunUpdate();
IEstateModule estateModule = m_scene.RequestModuleInterface<IEstateModule>();

View File

@ -198,11 +198,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver
m_log.ErrorFormat(
"[ARCHIVER]: (... {0} more not shown)", uuids.Count - MAX_UUID_DISPLAY_ON_TIMEOUT);
m_log.Error("[ARCHIVER]: OAR save aborted. PLEASE DO NOT USE THIS OAR, IT WILL BE INCOMPLETE.");
m_log.Error("[ARCHIVER]: Archive save aborted. PLEASE DO NOT USE THIS ARCHIVE, IT WILL BE INCOMPLETE.");
}
catch (Exception e)
{
m_log.ErrorFormat("[ARCHIVER]: Timeout handler exception {0}", e);
m_log.ErrorFormat("[ARCHIVER]: Timeout handler exception {0}{1}", e.Message, e.StackTrace);
}
finally
{

View File

@ -440,6 +440,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
rs.Elevation2SE = 9.2;
rs.Elevation2SW = 2.1;
rs.FixedSun = true;
rs.SunPosition = 12.0;
rs.ObjectBonus = 1.4;
rs.RestrictPushing = true;
rs.TerrainLowerLimit = 0.4;
@ -485,6 +486,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
Assert.That(loadedRs.Elevation2SE, Is.EqualTo(9.2));
Assert.That(loadedRs.Elevation2SW, Is.EqualTo(2.1));
Assert.That(loadedRs.FixedSun, Is.True);
Assert.AreEqual(12.0, loadedRs.SunPosition);
Assert.That(loadedRs.ObjectBonus, Is.EqualTo(1.4));
Assert.That(loadedRs.RestrictPushing, Is.True);
Assert.That(loadedRs.TerrainLowerLimit, Is.EqualTo(0.4));

View File

@ -52,7 +52,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
public class Warp3DImageModule : IMapImageGenerator, INonSharedRegionModule
{
private static readonly UUID TEXTURE_METADATA_MAGIC = new UUID("802dc0e0-f080-4931-8b57-d1be8611c4f3");
private static readonly Color4 WATER_COLOR = new Color4(29, 71, 95, 216);
private static readonly Color4 WATER_COLOR = new Color4(29, 72, 96, 216);
private static readonly ILog m_log =
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@ -61,7 +61,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
private IRendering m_primMesher;
private IConfigSource m_config;
private Dictionary<UUID, Color4> m_colors = new Dictionary<UUID, Color4>();
private bool m_useAntiAliasing = true; // TODO: Make this a config option
private bool m_useAntiAliasing = false; // TODO: Make this a config option
private bool m_Enabled = false;
#region IRegionModule Members
@ -192,8 +192,8 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
#endregion Camera
renderer.Scene.addLight("Light1", new warp_Light(new warp_Vector(0.2f, 0.2f, 1f), 0xffffff, 320, 80));
renderer.Scene.addLight("Light2", new warp_Light(new warp_Vector(-1f, -1f, 1f), 0xffffff, 100, 40));
renderer.Scene.addLight("Light1", new warp_Light(new warp_Vector(1.0f, 0.5f, 1f), 0xffffff, 0, 320, 40));
renderer.Scene.addLight("Light2", new warp_Light(new warp_Vector(-1f, -1f, 1f), 0xffffff, 0, 100, 40));
CreateWater(renderer);
CreateTerrain(renderer, textureTerrain);
@ -237,6 +237,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
renderer.Scene.sceneobject("Water").setPos(127.5f, waterHeight, 127.5f);
renderer.AddMaterial("WaterColor", ConvertColor(WATER_COLOR));
renderer.Scene.material("WaterColor").setReflectivity(0); // match water color with standard map module thanks lkalif
renderer.Scene.material("WaterColor").setTransparency((byte)((1f - WATER_COLOR.A) * 255f));
renderer.SetObjectMaterial("Water", "WaterColor");
}
@ -322,6 +323,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
warp_Material material = new warp_Material(texture);
material.setReflectivity(50);
renderer.Scene.addMaterial("TerrainColor", material);
renderer.Scene.material("TerrainColor").setReflectivity(0); // reduces tile seams a bit thanks lkalif
renderer.SetObjectMaterial("Terrain", "TerrainColor");
}
@ -653,4 +655,4 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
return result;
}
}
}
}

View File

@ -836,7 +836,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
block.Access = 254; // means 'simulator is offline'
response.Add(block);
}
remoteClient.SendMapBlock(response, 0);
if ((flag & 2) == 2) // V2 !!!
remoteClient.SendMapBlock(response, 2);
else
remoteClient.SendMapBlock(response, 0);
}
else
{
@ -845,7 +848,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
}
}
protected virtual void GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
protected virtual List<MapBlockData> GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
{
List<MapBlockData> mapBlocks = new List<MapBlockData>();
List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID,
@ -859,7 +862,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
MapBlockFromGridRegion(block, r);
mapBlocks.Add(block);
}
remoteClient.SendMapBlock(mapBlocks, 0);
if ((flag & 2) == 2) // V2 !!!
remoteClient.SendMapBlock(mapBlocks, 2);
else
remoteClient.SendMapBlock(mapBlocks, 0);
return mapBlocks;
}
protected void MapBlockFromGridRegion(MapBlockData block, GridRegion r)

View File

@ -1171,7 +1171,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
writer.WriteElementString("R", sop.Color.R.ToString(Utils.EnUsCulture));
writer.WriteElementString("G", sop.Color.G.ToString(Utils.EnUsCulture));
writer.WriteElementString("B", sop.Color.B.ToString(Utils.EnUsCulture));
writer.WriteElementString("A", sop.Color.G.ToString(Utils.EnUsCulture));
writer.WriteElementString("A", sop.Color.A.ToString(Utils.EnUsCulture));
writer.WriteEndElement();
writer.WriteElementString("Text", sop.Text);

View File

@ -0,0 +1,183 @@
/*
* 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 OpenSimulator 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.Reflection;
using System.Xml;
using Nini.Config;
using log4net;
using OpenSim.Server.Base;
using OpenSim.Services.Interfaces;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Server.Handlers.Base;
namespace OpenSim.Server.Handlers.MapImage
{
public class MapAddServiceConnector : ServiceConnector
{
private IMapImageService m_MapService;
private string m_ConfigName = "MapImageService";
public MapAddServiceConnector(IConfigSource config, IHttpServer server, string configName) :
base(config, server, configName)
{
IConfig serverConfig = config.Configs[m_ConfigName];
if (serverConfig == null)
throw new Exception(String.Format("No section {0} in config file", m_ConfigName));
string gridService = serverConfig.GetString("LocalServiceModule",
String.Empty);
if (gridService == String.Empty)
throw new Exception("No LocalServiceModule in config file");
Object[] args = new Object[] { config };
m_MapService = ServerUtils.LoadPlugin<IMapImageService>(gridService, args);
server.AddStreamHandler(new MapServerPostHandler(m_MapService));
}
}
class MapServerPostHandler : BaseStreamHandler
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private IMapImageService m_MapService;
public MapServerPostHandler(IMapImageService service) :
base("POST", "/map")
{
m_MapService = service;
}
public override byte[] Handle(string path, Stream requestData, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{
m_log.DebugFormat("[MAP SERVICE IMAGE HANDLER]: Received {0}", path);
StreamReader sr = new StreamReader(requestData);
string body = sr.ReadToEnd();
sr.Close();
body = body.Trim();
try
{
Dictionary<string, object> request = ServerUtils.ParseQueryString(body);
if (!request.ContainsKey("X") || !request.ContainsKey("Y") || !request.ContainsKey("DATA"))
{
httpResponse.StatusCode = (int)OSHttpStatusCode.ClientErrorBadRequest;
return FailureResult("Bad request.");
}
int x = 0, y = 0;
Int32.TryParse(request["X"].ToString(), out x);
Int32.TryParse(request["Y"].ToString(), out y);
string type = "image/jpeg";
if (request.ContainsKey("TYPE"))
type = request["TYPE"].ToString();
byte[] data = Convert.FromBase64String(request["DATA"].ToString());
string reason = string.Empty;
bool result = m_MapService.AddMapTile(x, y, data, out reason);
if (result)
return SuccessResult();
else
return FailureResult(reason);
}
catch (Exception e)
{
m_log.ErrorFormat("[MAP SERVICE IMAGE HANDLER]: Exception {0} {1}", e.Message, e.StackTrace);
}
return FailureResult("Unexpected server error");
}
private byte[] SuccessResult()
{
XmlDocument doc = new XmlDocument();
XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration,
"", "");
doc.AppendChild(xmlnode);
XmlElement rootElement = doc.CreateElement("", "ServerResponse",
"");
doc.AppendChild(rootElement);
XmlElement result = doc.CreateElement("", "Result", "");
result.AppendChild(doc.CreateTextNode("Success"));
rootElement.AppendChild(result);
return DocToBytes(doc);
}
private byte[] FailureResult(string msg)
{
XmlDocument doc = new XmlDocument();
XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration,
"", "");
doc.AppendChild(xmlnode);
XmlElement rootElement = doc.CreateElement("", "ServerResponse",
"");
doc.AppendChild(rootElement);
XmlElement result = doc.CreateElement("", "Result", "");
result.AppendChild(doc.CreateTextNode("Failure"));
rootElement.AppendChild(result);
XmlElement message = doc.CreateElement("", "Message", "");
message.AppendChild(doc.CreateTextNode(msg));
rootElement.AppendChild(message);
return DocToBytes(doc);
}
private byte[] DocToBytes(XmlDocument doc)
{
MemoryStream ms = new MemoryStream();
XmlTextWriter xw = new XmlTextWriter(ms, null);
xw.Formatting = Formatting.Indented;
doc.WriteTo(xw);
xw.Flush();
return ms.ToArray();
}
}
}

View File

@ -0,0 +1,105 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator 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.Net;
using System.Reflection;
using Nini.Config;
using log4net;
using OpenSim.Server.Base;
using OpenSim.Services.Interfaces;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Server.Handlers.Base;
namespace OpenSim.Server.Handlers.MapImage
{
public class MapGetServiceConnector : ServiceConnector
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private IMapImageService m_MapService;
private string m_ConfigName = "MapImageService";
public MapGetServiceConnector(IConfigSource config, IHttpServer server, string configName) :
base(config, server, configName)
{
IConfig serverConfig = config.Configs[m_ConfigName];
if (serverConfig == null)
throw new Exception(String.Format("No section {0} in config file", m_ConfigName));
string gridService = serverConfig.GetString("LocalServiceModule",
String.Empty);
if (gridService == String.Empty)
throw new Exception("No LocalServiceModule in config file");
Object[] args = new Object[] { config };
m_MapService = ServerUtils.LoadPlugin<IMapImageService>(gridService, args);
server.AddStreamHandler(new MapServerGetHandler(m_MapService));
}
}
class MapServerGetHandler : BaseStreamHandler
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private IMapImageService m_MapService;
public MapServerGetHandler(IMapImageService service) :
base("GET", "/map")
{
m_MapService = service;
}
public override byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{
byte[] result = new byte[0];
string format = string.Empty;
result = m_MapService.GetMapTile(path.Trim('/'), out format);
if (result.Length > 0)
{
httpResponse.StatusCode = (int)HttpStatusCode.OK;
if (format.Equals(".png"))
httpResponse.ContentType = "image/png";
else if (format.Equals(".jpg") || format.Equals(".jpeg"))
httpResponse.ContentType = "image/jpeg";
}
else
{
httpResponse.StatusCode = (int)HttpStatusCode.NotFound;
httpResponse.ContentType = "text/plain";
}
return result;
}
}
}

View File

@ -51,22 +51,31 @@ namespace OpenSim.Services.Connectors.Hypergrid
MethodBase.GetCurrentMethod().DeclaringType);
string m_ServerURL;
public UserAgentServiceConnector(string url)
public UserAgentServiceConnector(string url) : this(url, true)
{
}
public UserAgentServiceConnector(string url, bool dnsLookup)
{
m_ServerURL = url;
// Doing this here, because XML-RPC or mono have some strong ideas about
// caching DNS translations.
try
if (dnsLookup)
{
Uri m_Uri = new Uri(m_ServerURL);
IPAddress ip = Util.GetHostFromDNS(m_Uri.Host);
m_ServerURL = m_ServerURL.Replace(m_Uri.Host, ip.ToString());
if (!m_ServerURL.EndsWith("/"))
m_ServerURL += "/";
}
catch (Exception e)
{
m_log.DebugFormat("[USER AGENT CONNECTOR]: Malformed Uri {0}: {1}", m_ServerURL, e.Message);
// Doing this here, because XML-RPC or mono have some strong ideas about
// caching DNS translations.
try
{
Uri m_Uri = new Uri(m_ServerURL);
IPAddress ip = Util.GetHostFromDNS(m_Uri.Host);
m_ServerURL = m_ServerURL.Replace(m_Uri.Host, ip.ToString());
if (!m_ServerURL.EndsWith("/"))
m_ServerURL += "/";
}
catch (Exception e)
{
m_log.DebugFormat("[USER AGENT CONNECTOR]: Malformed Uri {0}: {1}", m_ServerURL, e.Message);
}
}
m_log.DebugFormat("[USER AGENT CONNECTOR]: new connector to {0} ({1})", url, m_ServerURL);
}
@ -427,7 +436,7 @@ namespace OpenSim.Services.Connectors.Hypergrid
XmlRpcResponse response = null;
try
{
response = request.Send(m_ServerURL, 10000);
response = request.Send(m_ServerURL, 6000);
}
catch (Exception e)
{

View File

@ -0,0 +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 OpenSimulator 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 log4net;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Reflection;
using Nini.Config;
using OpenSim.Framework;
using OpenSim.Framework.Console;
using OpenSim.Framework.Communications;
using OpenSim.Server.Base;
using OpenSim.Services.Interfaces;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
namespace OpenSim.Services.Connectors
{
public class MapImageServicesConnector : IMapImageService
{
private static readonly ILog m_log =
LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
private string m_ServerURI = String.Empty;
private IImprovedAssetCache m_Cache = null;
public MapImageServicesConnector()
{
}
public MapImageServicesConnector(string serverURI)
{
m_ServerURI = serverURI.TrimEnd('/');
}
public MapImageServicesConnector(IConfigSource source)
{
Initialise(source);
}
public virtual void Initialise(IConfigSource source)
{
IConfig config = source.Configs["MapImageService"];
if (config == null)
{
m_log.Error("[MAP IMAGE CONNECTOR]: MapImageService missing");
throw new Exception("MapImage connector init error");
}
string serviceURI = config.GetString("MapImageServerURI",
String.Empty);
if (serviceURI == String.Empty)
{
m_log.Error("[MAP IMAGE CONNECTOR]: No Server URI named in section MapImageService");
throw new Exception("MapImage connector init error");
}
m_ServerURI = serviceURI;
m_ServerURI = serviceURI.TrimEnd('/');
}
public bool AddMapTile(int x, int y, byte[] jpgData, out string reason)
{
reason = string.Empty;
int tickstart = Util.EnvironmentTickCount();
Dictionary<string, object> sendData = new Dictionary<string, object>();
sendData["X"] = x.ToString();
sendData["Y"] = y.ToString();
sendData["TYPE"] = "image/jpeg";
sendData["DATA"] = Convert.ToBase64String(jpgData);
string reqString = ServerUtils.BuildQueryString(sendData);
try
{
string reply = SynchronousRestFormsRequester.MakeRequest("POST",
m_ServerURI + "/map",
reqString);
if (reply != string.Empty)
{
Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
if (replyData.ContainsKey("Result") && (replyData["Result"].ToString().ToLower() == "success"))
{
return true;
}
else if (replyData.ContainsKey("Result") && (replyData["Result"].ToString().ToLower() == "failure"))
{
m_log.DebugFormat("[MAP IMAGE CONNECTOR]: Registration failed: {0}", replyData["Message"].ToString());
reason = replyData["Message"].ToString();
return false;
}
else if (!replyData.ContainsKey("Result"))
{
m_log.DebugFormat("[MAP IMAGE CONNECTOR]: reply data does not contain result field");
}
else
{
m_log.DebugFormat("[MAP IMAGE CONNECTOR]: unexpected result {0}", replyData["Result"].ToString());
reason = "Unexpected result " + replyData["Result"].ToString();
}
}
else
m_log.DebugFormat("[MAP IMAGE CONNECTOR]: RegisterRegion received null reply");
}
catch (Exception e)
{
m_log.DebugFormat("[MAP IMAGE CONNECTOR]: Exception when contacting grid server: {0}", e.Message);
}
finally
{
// This just dumps a warning for any operation that takes more than 100 ms
int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
m_log.DebugFormat("[MAP IMAGE CONNECTOR]: map tile uploaded in {0}ms", tickdiff);
}
return false;
}
public byte[] GetMapTile(string fileName, out string format)
{
format = string.Empty;
new Exception("GetMapTile method not Implemented");
return null;
}
}
}

View File

@ -31,8 +31,10 @@ using OpenMetaverse;
namespace OpenSim.Services.Interfaces
{
public interface IMapService
public interface IMapImageService
{
List<MapBlockData> GetMapBlocks(UUID scopeID, int minX, int minY, int maxX, int maxY);
//List<MapBlockData> GetMapBlocks(UUID scopeID, int minX, int minY, int maxX, int maxY);
bool AddMapTile(int x, int y, byte[] imageData, out string reason);
byte[] GetMapTile(string fileName, out string format);
}
}

View File

@ -112,6 +112,14 @@ namespace OpenSim.Services.LLLoginService
m_AllowedClients = m_LoginServerConfig.GetString("AllowedClients", string.Empty);
m_DeniedClients = m_LoginServerConfig.GetString("DeniedClients", string.Empty);
// Clean up some of these vars
if (m_MapTileURL != String.Empty)
{
m_MapTileURL = m_MapTileURL.Trim();
if (!m_MapTileURL.EndsWith("/"))
m_MapTileURL = m_MapTileURL + "/";
}
// These are required; the others aren't
if (accountService == string.Empty || authService == string.Empty)
throw new Exception("LoginService is missing service specifications");

View File

@ -0,0 +1,298 @@
/*
* 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 OpenSimulator 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.
*
* The design of this map service is based on SimianGrid's PHP-based
* map service. See this URL for the original PHP version:
* https://github.com/openmetaversefoundation/simiangrid/
*/
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Net;
using System.Reflection;
using Nini.Config;
using log4net;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Console;
using OpenSim.Services.Interfaces;
namespace OpenSim.Services.MapImageService
{
public class MapImageService : IMapImageService
{
private static readonly ILog m_log =
LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
private const int ZOOM_LEVELS = 8;
private const int IMAGE_WIDTH = 256;
private const int HALF_WIDTH = 128;
private const int JPEG_QUALITY = 80;
private static string m_TilesStoragePath = "maptiles";
private static object m_Sync = new object();
private static bool m_Initialized = false;
private static string m_WaterTileFile = string.Empty;
private static Color m_Watercolor = Color.FromArgb(29, 71, 95);
public MapImageService(IConfigSource config)
{
if (!m_Initialized)
{
m_Initialized = true;
m_log.Debug("[MAP IMAGE SERVICE]: Starting MapImage service");
IConfig serviceConfig = config.Configs["MapImageService"];
if (serviceConfig != null)
{
m_TilesStoragePath = serviceConfig.GetString("TilesStoragePath", m_TilesStoragePath);
if (!Directory.Exists(m_TilesStoragePath))
Directory.CreateDirectory(m_TilesStoragePath);
m_WaterTileFile = Path.Combine(m_TilesStoragePath, "water.jpg");
if (!File.Exists(m_WaterTileFile))
{
Bitmap waterTile = new Bitmap(IMAGE_WIDTH, IMAGE_WIDTH);
FillImage(waterTile, m_Watercolor);
waterTile.Save(m_WaterTileFile);
}
}
}
}
#region IMapImageService
public bool AddMapTile(int x, int y, byte[] imageData, out string reason)
{
reason = string.Empty;
string fileName = GetFileName(1, x, y);
lock (m_Sync)
{
try
{
using (FileStream f = File.Open(fileName, FileMode.OpenOrCreate, FileAccess.Write))
f.Write(imageData, 0, imageData.Length);
}
catch (Exception e)
{
m_log.WarnFormat("[MAP IMAGE SERVICE]: Unable to save image file {0}: {1}", fileName, e);
reason = e.Message;
return false;
}
// Also save in png format?
// Stitch seven more aggregate tiles together
for (uint zoomLevel = 2; zoomLevel <= ZOOM_LEVELS; zoomLevel++)
{
// Calculate the width (in full resolution tiles) and bottom-left
// corner of the current zoom level
int width = (int)Math.Pow(2, (double)(zoomLevel - 1));
int x1 = x - (x % width);
int y1 = y - (y % width);
if (!CreateTile(zoomLevel, x1, y1))
{
m_log.WarnFormat("[MAP IMAGE SERVICE]: Unable to create tile for {0} at zoom level {1}", fileName, zoomLevel);
reason = string.Format("Map tile at zoom level {0} failed", zoomLevel);
return false;
}
}
}
return true;
}
public byte[] GetMapTile(string fileName, out string format)
{
format = ".jpg";
string fullName = Path.Combine(m_TilesStoragePath, fileName);
if (File.Exists(fullName))
{
format = Path.GetExtension(fileName).ToLower();
//m_log.DebugFormat("[MAP IMAGE SERVICE]: Found file {0}, extension {1}", fileName, format);
return File.ReadAllBytes(fullName);
}
else if (File.Exists(m_WaterTileFile))
{
return File.ReadAllBytes(m_WaterTileFile);
}
else
{
m_log.DebugFormat("[MAP IMAGE SERVICE]: unable to get file {0}", fileName);
return new byte[0];
}
}
#endregion
private string GetFileName(uint zoomLevel, int x, int y)
{
string extension = "jpg";
return Path.Combine(m_TilesStoragePath, string.Format("map-{0}-{1}-{2}-objects.{3}", zoomLevel, x, y, extension));
}
private Bitmap GetInputTileImage(string fileName)
{
try
{
if (File.Exists(fileName))
return new Bitmap(fileName);
}
catch (Exception e)
{
m_log.WarnFormat("[MAP IMAGE SERVICE]: Unable to read image data from {0}: {1}", fileName, e);
}
return null;
}
private Bitmap GetOutputTileImage(string fileName)
{
try
{
if (File.Exists(fileName))
return new Bitmap(fileName);
else
{
// Create a new output tile with a transparent background
Bitmap bm = new Bitmap(IMAGE_WIDTH, IMAGE_WIDTH, PixelFormat.Format24bppRgb);
bm.MakeTransparent();
return bm;
}
}
catch (Exception e)
{
m_log.WarnFormat("[MAP IMAGE SERVICE]: Unable to read image data from {0}: {1}", fileName, e);
}
return null;
}
private bool CreateTile(uint zoomLevel, int x, int y)
{
m_log.DebugFormat("[MAP IMAGE SERVICE]: Create tile for {0} {1}, zoom {2}", x, y, zoomLevel);
int prevWidth = (int)Math.Pow(2, (double)zoomLevel - 2);
int thisWidth = (int)Math.Pow(2, (double)zoomLevel - 1);
// Convert x and y to the bottom left tile for this zoom level
int xIn = x - (x % prevWidth);
int yIn = y - (y % prevWidth);
// Convert x and y to the bottom left tile for the next zoom level
int xOut = x - (x % thisWidth);
int yOut = y - (y % thisWidth);
// Try to open the four input tiles from the previous zoom level
Bitmap inputBL = GetInputTileImage(GetFileName(zoomLevel - 1, xIn, yIn));
Bitmap inputBR = GetInputTileImage(GetFileName(zoomLevel - 1, xIn + prevWidth, yIn));
Bitmap inputTL = GetInputTileImage(GetFileName(zoomLevel - 1, xIn, yIn + prevWidth));
Bitmap inputTR = GetInputTileImage(GetFileName(zoomLevel - 1, xIn + prevWidth, yIn + prevWidth));
// Open the output tile (current zoom level)
string outputFile = GetFileName(zoomLevel, xOut, yOut);
Bitmap output = GetOutputTileImage(outputFile);
if (output == null)
return false;
FillImage(output, m_Watercolor);
if (inputBL != null)
{
ImageCopyResampled(output, inputBL, 0, HALF_WIDTH, 0, 0);
inputBL.Dispose();
}
if (inputBR != null)
{
ImageCopyResampled(output, inputBR, HALF_WIDTH, HALF_WIDTH, 0, 0);
inputBR.Dispose();
}
if (inputTL != null)
{
ImageCopyResampled(output, inputTL, 0, 0, 0, 0);
inputTL.Dispose();
}
if (inputTR != null)
{
ImageCopyResampled(output, inputTR, HALF_WIDTH, 0, 0, 0);
inputTR.Dispose();
}
// Write the modified output
try
{
using (Bitmap final = new Bitmap(output))
{
output.Dispose();
final.Save(outputFile, ImageFormat.Jpeg);
}
}
catch (Exception e)
{
m_log.WarnFormat("[MAP IMAGE SERVICE]: Oops on saving {0} {1}", outputFile, e);
}
// Save also as png?
return true;
}
#region Image utilities
private void FillImage(Bitmap bm, Color c)
{
for (int x = 0; x < bm.Width; x++)
for (int y = 0; y < bm.Height; y++)
bm.SetPixel(x, y, c);
}
private void ImageCopyResampled(Bitmap output, Bitmap input, int destX, int destY, int srcX, int srcY)
{
int resamplingRateX = 2; // (input.Width - srcX) / (output.Width - destX);
int resamplingRateY = 2; // (input.Height - srcY) / (output.Height - destY);
for (int x = destX; x < destX + HALF_WIDTH; x++)
for (int y = destY; y < destY + HALF_WIDTH; y++)
{
Color p = input.GetPixel(srcX + (x - destX) * resamplingRateX, srcY + (y - destY) * resamplingRateY);
output.SetPixel(x, y, p);
}
}
#endregion
}
}

View File

@ -29,5 +29,5 @@ port = 8003
[PresenceService]
LocalServiceModule = "OpenSim.Services.PresenceService.dll:PresenceService"
StorageProvider = "OpenSim.Data.MySQL.dll"
ConnectionString = "Data Source=localhost;Database=opensim;User ID=opensim;Password=opensim123;"
ConnectionString = "Data Source=localhost;Database=opensim;User ID=opensim;Password=opensim123;Old Guids=true;"

View File

@ -29,5 +29,5 @@ port = 8003
[UserAccountService]
LocalServiceModule = "OpenSim.Services.UserAccountService.dll:UserAccountService"
StorageProvider = "OpenSim.Data.MySQL.dll"
ConnectionString = "Data Source=localhost;Database=opensim;User ID=opensim;Password=opensim123;"
ConnectionString = "Data Source=localhost;Database=opensim;User ID=opensim;Password=opensim123;Old Guids=true;"

View File

@ -307,6 +307,14 @@
; serving this cap from the simulators may lead to poor performace.
Cap_WebFetchInventoryDescendents = ""
[SimulatorFeatures]
; Experimental new information sent in SimulatorFeatures cap for Kokua viewers
; meant to override the MapImage and search server url given at login, and varying
; on a sim-basis.
; Viewers that don't understand it, will ignore it
;MapImageServerURI = "http://127.0.0.1:9000/
;SearchServerURI = "http://127.0.0.1:9000/
[Chat]
;# {whisper_distance} {} {Distance at which a whisper is heard, in meters?} {} 10
;; Distance in meters that whispers should travel.

View File

@ -21,7 +21,7 @@
; * [[<ConfigName>@]<port>/]<dll name>[:<class name>]
; *
[Startup]
ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003/OpenSim.Server.Handlers.dll:XInventoryInConnector,8004/OpenSim.Server.Handlers.dll:FreeswitchServerConnector,8003/OpenSim.Server.Handlers.dll:GridServiceConnector,8002/OpenSim.Server.Handlers.dll:GridInfoServerInConnector,8003/OpenSim.Server.Handlers.dll:AuthenticationServiceConnector,8002/OpenSim.Server.Handlers.dll:OpenIdServerConnector,8003/OpenSim.Server.Handlers.dll:AvatarServiceConnector,8002/OpenSim.Server.Handlers.dll:LLLoginServiceInConnector,8003/OpenSim.Server.Handlers.dll:PresenceServiceConnector,8003/OpenSim.Server.Handlers.dll:UserAccountServiceConnector,8003/OpenSim.Server.Handlers.dll:GridUserServiceConnector,8003/OpenSim.Server.Handlers.dll:FriendsServiceConnector,8002/OpenSim.Server.Handlers.dll:GatekeeperServiceInConnector,8002/OpenSim.Server.Handlers.dll:UserAgentServerConnector,HGInventoryService@8002/OpenSim.Server.Handlers.dll:XInventoryInConnector,HGAssetService@8002/OpenSim.Server.Handlers.dll:AssetServiceConnector,8002/OpenSim.Server.Handlers.dll:HeloServiceInConnector,8002/OpenSim.Server.Handlers.dll:HGFriendsServerConnector,8002/OpenSim.Server.Handlers.dll:InstantMessageServerConnector"
ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003/OpenSim.Server.Handlers.dll:XInventoryInConnector,8004/OpenSim.Server.Handlers.dll:FreeswitchServerConnector,8003/OpenSim.Server.Handlers.dll:GridServiceConnector,8002/OpenSim.Server.Handlers.dll:GridInfoServerInConnector,8003/OpenSim.Server.Handlers.dll:AuthenticationServiceConnector,8002/OpenSim.Server.Handlers.dll:OpenIdServerConnector,8003/OpenSim.Server.Handlers.dll:AvatarServiceConnector,8002/OpenSim.Server.Handlers.dll:LLLoginServiceInConnector,8003/OpenSim.Server.Handlers.dll:PresenceServiceConnector,8003/OpenSim.Server.Handlers.dll:UserAccountServiceConnector,8003/OpenSim.Server.Handlers.dll:GridUserServiceConnector,8003/OpenSim.Server.Handlers.dll:FriendsServiceConnector,8002/OpenSim.Server.Handlers.dll:GatekeeperServiceInConnector,8002/OpenSim.Server.Handlers.dll:UserAgentServerConnector,HGInventoryService@8002/OpenSim.Server.Handlers.dll:XInventoryInConnector,HGAssetService@8002/OpenSim.Server.Handlers.dll:AssetServiceConnector,8002/OpenSim.Server.Handlers.dll:HeloServiceInConnector,8002/OpenSim.Server.Handlers.dll:HGFriendsServerConnector,8002/OpenSim.Server.Handlers.dll:InstantMessageServerConnector,8003/OpenSim.Server.Handlers.dll:MapAddServiceConnector,8002/OpenSim.Server.Handlers.dll:MapGetServiceConnector"
; * This is common for all services, it's the network setup for the entire
; * server instance, if none is specified above
@ -206,6 +206,9 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003
WelcomeMessage = "Welcome, Avatar!"
AllowRemoteSetLoginLevel = "false"
; For V2 map
; MapTileURL = "http://127.0.0.1:8002";
; If you run this login server behind a proxy, set this to true
; HasProxy = false
@ -237,6 +240,9 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003
;AllowedClients = ""
;DeniedClients = ""
[MapImageService]
LocalServiceModule = "OpenSim.Services.MapImageService.dll:MapImageService"
[GridInfoService]
; These settings are used to return information on a get_grid_info call.
; Client launcher scripts and third-party clients make use of this to

View File

@ -13,7 +13,7 @@
; * [[<ConfigName>@]<port>/]<dll name>[:<class name>]
; *
[Startup]
ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003/OpenSim.Server.Handlers.dll:XInventoryInConnector,8004/OpenSim.Server.Handlers.dll:FreeswitchServerConnector,8003/OpenSim.Server.Handlers.dll:GridServiceConnector,8002/OpenSim.Server.Handlers.dll:GridInfoServerInConnector,8003/OpenSim.Server.Handlers.dll:AuthenticationServiceConnector,8002/OpenSim.Server.Handlers.dll:OpenIdServerConnector,8003/OpenSim.Server.Handlers.dll:AvatarServiceConnector,8002/OpenSim.Server.Handlers.dll:LLLoginServiceInConnector,8003/OpenSim.Server.Handlers.dll:PresenceServiceConnector,8003/OpenSim.Server.Handlers.dll:UserAccountServiceConnector,8003/OpenSim.Server.Handlers.dll:GridUserServiceConnector,8003/OpenSim.Server.Handlers.dll:FriendsServiceConnector"
ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003/OpenSim.Server.Handlers.dll:XInventoryInConnector,8004/OpenSim.Server.Handlers.dll:FreeswitchServerConnector,8003/OpenSim.Server.Handlers.dll:GridServiceConnector,8002/OpenSim.Server.Handlers.dll:GridInfoServerInConnector,8003/OpenSim.Server.Handlers.dll:AuthenticationServiceConnector,8002/OpenSim.Server.Handlers.dll:OpenIdServerConnector,8003/OpenSim.Server.Handlers.dll:AvatarServiceConnector,8002/OpenSim.Server.Handlers.dll:LLLoginServiceInConnector,8003/OpenSim.Server.Handlers.dll:PresenceServiceConnector,8003/OpenSim.Server.Handlers.dll:UserAccountServiceConnector,8003/OpenSim.Server.Handlers.dll:GridUserServiceConnector,8003/OpenSim.Server.Handlers.dll:FriendsServiceConnector,8003/OpenSim.Server.Handlers.dll:MapAddServiceConnector,8002/OpenSim.Server.Handlers.dll:MapGetServiceConnector"
; * This is common for all services, it's the network setup for the entire
; * server instance, if none is specified above
@ -191,8 +191,8 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003
WelcomeMessage = "Welcome, Avatar!"
AllowRemoteSetLoginLevel = "false"
; For snowglobe's web map
; MapTileURL = "";
; For V2 map
; MapTileURL = "http://127.0.0.1:8002";
; If you run this login server behind a proxy, set this to true
; HasProxy = false
@ -214,6 +214,9 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003
;AllowedClients = ""
;DeniedClients = ""
[MapImageService]
LocalServiceModule = "OpenSim.Services.MapImageService.dll:MapImageService"
[GridInfoService]
; These settings are used to return information on a get_grid_info call.
; Client launcher scripts and third-party clients make use of this to

View File

@ -1,13 +1,14 @@
[AssetCache]
;;
;; Options for CenmoeAssetCache
;; Options for CenomeAssetCache
;;
; 256 MB (default: 134217728)
MaxSize = 268435456
; Max size of the cache in bytes
; 134217728 = 128 MB, 26843556 = 256 MB, etc (default: 134217728)
MaxSize = 134217728
; How many assets it is possible to store cache (default: 4096)
MaxCount = 16384
; How many assets it is possible to store in the cache (default: 4096)
MaxCount = 4096
; Expiration time - 1 hour (default: 30 minutes)
ExpirationTime = 60
; Expiration time in minutes (default: 30)
ExpirationTime = 30

View File

@ -29,7 +29,7 @@
; How long {in hours} to keep assets cached on disk, .5 == 30 minutes
; Specify 0 if you do not want your disk cache to expire
FileCacheTimeout = 0
FileCacheTimeout = 48
; How often {in hours} should the disk be checked for expired filed
; Specify 0 to disable expiration checking
@ -38,6 +38,7 @@
; If WAIT_ON_INPROGRESS_REQUESTS has been defined then this specifies how
; long (in miliseconds) to block a request thread while trying to complete
; an existing write to disk.
; NOTE: THIS PARAMETER IS NOT CURRENTLY USED BY THE CACHE
; WaitOnInprogressTimeout = 3000
; Number of tiers to use for cache directories (current valid

View File

@ -21,6 +21,7 @@
EntityTransferModule = "BasicEntityTransferModule"
InventoryAccessModule = "BasicInventoryAccessModule"
LandServices = "RemoteLandServicesConnector"
MapImageService = "MapImageServiceModule"
LandServiceInConnector = true
NeighbourServiceInConnector = true
@ -50,3 +51,8 @@
[Friends]
Connector = "OpenSim.Services.Connectors.dll:FriendsServicesConnector"
[MapImageService]
LocalServiceModule = "OpenSim.Services.Connectors.dll:MapImageServicesConnector"
; in minutes
RefreshTime = 60

View File

@ -10,9 +10,9 @@
; Uncomment these lines if you want to use mysql storage
; Change the connection string to your db details
;StorageProvider = "OpenSim.Data.MySQL.dll"
;ConnectionString = "Data Source=localhost;Database=opensim;User ID=opensim;Password=***;"
;ConnectionString = "Data Source=localhost;Database=opensim;User ID=opensim;Password=***;Old Guids=true;"
; Uncomment this line if you are using MySQL and want to use a different database for estates
;EstateConnectionString = "Data Source=localhost;Database=opensim;User ID=opensim;Password=***;"
;EstateConnectionString = "Data Source=localhost;Database=opensim;User ID=opensim;Password=***;Old Guids=true;"
; MSSQL
; Uncomment these lines if you want to use MSSQL storage
@ -116,6 +116,9 @@
;
UserAgentServerURI = "http://mygridserver.com:8002"
[MapImageService]
MapImageServerURI = "http://mygridserver.com:8003"
[Modules]
;; Choose 0 or 1 cache modules, and the corresponding config file, if it exists.
;; Copy the config .example file into your own .ini file and change configs there

View File

@ -25,6 +25,7 @@
InventoryAccessModule = "HGInventoryAccessModule"
LandServices = "RemoteLandServicesConnector"
FriendsModule = "HGFriendsModule"
MapImageService = "MapImageServiceModule"
LandServiceInConnector = true
NeighbourServiceInConnector = true
@ -76,4 +77,9 @@
LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGInstantMessageService"
GridService = "OpenSim.Services.Connectors.dll:GridServicesConnector"
PresenceService = "OpenSim.Services.Connectors.dll:PresenceServicesConnector"
UserAgentService = "OpenSim.Services.Connectors.dll:UserAgentServiceConnector"
UserAgentService = "OpenSim.Services.Connectors.dll:UserAgentServiceConnector"
[MapImageService]
LocalServiceModule = "OpenSim.Services.Connectors.dll:MapImageServicesConnector"
; in minutes
RefreshTime = 60

View File

@ -17,10 +17,12 @@
AvatarServices = "LocalAvatarServicesConnector"
EntityTransferModule = "BasicEntityTransferModule"
InventoryAccessModule = "BasicInventoryAccessModule"
MapImageService = "MapImageServiceModule"
LibraryModule = true
LLLoginServiceInConnector = true
GridInfoServiceInConnector = true
MapImageServiceInConnector = true
[Profile]
Module = "BasicProfileModule"
@ -91,6 +93,11 @@
WelcomeMessage = "Welcome, Avatar!"
[MapImageService]
LocalServiceModule = "OpenSim.Services.MapImageService.dll:MapImageService"
; in minutes
RefreshTime = 60
;; This should always be the very last thing on this file
[Includes]
Include-Common = "config-include/StandaloneCommon.ini"

View File

@ -99,6 +99,9 @@
SRV_FriendsServerURI = "http://127.0.0.1:9000"
SRV_IMServerURI = "http://127.0.0.1:9000"
;; For Viewer 2
MapTileURL = "http://127.0.0.1:9000/"
;; Regular expressions for controlling which client versions are accepted/denied.
;; An empty string means nothing is checked.
;;

View File

@ -18,9 +18,10 @@
GridUserServices = "LocalGridUserServicesConnector"
SimulationServices = "RemoteSimulationConnectorModule"
AvatarServices = "LocalAvatarServicesConnector"
MapImageService = "MapImageServiceModule"
EntityTransferModule = "HGEntityTransferModule"
InventoryAccessModule = "HGInventoryAccessModule"
FriendsModule = "HGFriendsModule"
FriendsModule = "HGFriendsModule"
InventoryServiceInConnector = true
AssetServiceInConnector = true
@ -31,6 +32,7 @@
GridInfoServiceInConnector = true
AuthenticationServiceInConnector = true
SimulationServiceInConnector = true
MapImageServiceInConnector = true
[Profile]
Module = "BasicProfileModule"
@ -116,7 +118,12 @@
GridService = "OpenSim.Services.GridService.dll:GridService"
AvatarService = "OpenSim.Services.AvatarService.dll:AvatarService"
FriendsService = "OpenSim.Services.FriendsService.dll:FriendsService"
[MapImageService]
LocalServiceModule = "OpenSim.Services.MapImageService.dll:MapImageService"
; in minutes
RefreshTime = 60
[GatekeeperService]
LocalServiceModule = "OpenSim.Services.HypergridService.dll:GatekeeperService"
;; for the service

View File

@ -1269,6 +1269,36 @@
</Files>
</Project>
<Project frameworkVersion="v3_5" name="OpenSim.Services.MapImageService" path="OpenSim/Services/MapImageService" type="Library">
<Configuration name="Debug">
<Options>
<OutputPath>../../../bin/</OutputPath>
</Options>
</Configuration>
<Configuration name="Release">
<Options>
<OutputPath>../../../bin/</OutputPath>
</Options>
</Configuration>
<ReferencePath>../../../bin/</ReferencePath>
<Reference name="System"/>
<Reference name="System.Drawing"/>
<Reference name="OpenMetaverseTypes" path="../../../bin/"/>
<Reference name="OpenMetaverse" path="../../../bin/"/>
<Reference name="OpenSim.Framework"/>
<Reference name="OpenSim.Framework.Console"/>
<Reference name="OpenSim.Framework.Servers.HttpServer"/>
<Reference name="OpenSim.Services.Interfaces"/>
<Reference name="OpenSim.Services.Base"/>
<Reference name="Nini" path="../../../bin/"/>
<Reference name="log4net" path="../../../bin/"/>
<Files>
<Match pattern="*.cs" recurse="true"/>
</Files>
</Project>
<Project frameworkVersion="v3_5" name="OpenSim.Server.Handlers" path="OpenSim/Server/Handlers" type="Library">
<Configuration name="Debug">
<Options>