Merge branch 'master-core' into mantis5110

viewer-2-initial-appearance
Jonathan Freedman 2010-11-21 20:01:48 -08:00
commit b7f5e82843
68 changed files with 2022 additions and 1124 deletions

View File

@ -1584,6 +1584,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
destinationItem.InvType = item.InvType;
destinationItem.CreatorId = item.CreatorId;
destinationItem.CreatorIdAsUuid = item.CreatorIdAsUuid;
destinationItem.CreatorData = item.CreatorData;
destinationItem.NextPermissions = item.NextPermissions;
destinationItem.CurrentPermissions = item.CurrentPermissions;
destinationItem.BasePermissions = item.BasePermissions;
@ -1636,6 +1637,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
destinationItem.InvType = item.InvType;
destinationItem.CreatorId = item.CreatorId;
destinationItem.CreatorIdAsUuid = item.CreatorIdAsUuid;
destinationItem.CreatorData = item.CreatorData;
destinationItem.NextPermissions = item.NextPermissions;
destinationItem.CurrentPermissions = item.CurrentPermissions;
destinationItem.BasePermissions = item.BasePermissions;
@ -1743,6 +1745,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
destinationItem.InvType = item.InvType;
destinationItem.CreatorId = item.CreatorId;
destinationItem.CreatorIdAsUuid = item.CreatorIdAsUuid;
destinationItem.CreatorData = item.CreatorData;
destinationItem.NextPermissions = item.NextPermissions;
destinationItem.CurrentPermissions = item.CurrentPermissions;
destinationItem.BasePermissions = item.BasePermissions;
@ -2026,7 +2029,8 @@ namespace OpenSim.ApplicationPlugins.RemoteController
inventoryItem.InvType = GetIntegerAttribute(item,"invtype",-1);
inventoryItem.CreatorId = GetStringAttribute(item,"creatorid","");
inventoryItem.CreatorIdAsUuid = (UUID)GetStringAttribute(item,"creatoruuid","");
inventoryItem.NextPermissions = GetUnsignedAttribute(perms,"next",0x7fffffff);
inventoryItem.CreatorData = GetStringAttribute(item, "creatordata", "");
inventoryItem.NextPermissions = GetUnsignedAttribute(perms, "next", 0x7fffffff);
inventoryItem.CurrentPermissions = GetUnsignedAttribute(perms,"current",0x7fffffff);
inventoryItem.BasePermissions = GetUnsignedAttribute(perms,"base",0x7fffffff);
inventoryItem.EveryOnePermissions = GetUnsignedAttribute(perms,"everyone",0x7fffffff);

View File

@ -1295,6 +1295,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
rdata.writer.WriteAttributeString("folder", String.Empty, i.Folder.ToString());
rdata.writer.WriteAttributeString("owner", String.Empty, i.Owner.ToString());
rdata.writer.WriteAttributeString("creator", String.Empty, i.CreatorId);
rdata.writer.WriteAttributeString("creatordata", String.Empty, i.CreatorData);
rdata.writer.WriteAttributeString("creationdate", String.Empty, i.CreationDate.ToString());
rdata.writer.WriteAttributeString("invtype", String.Empty, i.InvType.ToString());
rdata.writer.WriteAttributeString("assettype", String.Empty, i.AssetType.ToString());

View File

@ -1090,7 +1090,7 @@ namespace OpenSim.Data.MySQL
// depending on the MySQL connector version, CHAR(36) may be already converted to Guid!
prim.UUID = DBGuid.FromDB(row["UUID"]);
prim.CreatorID = DBGuid.FromDB(row["CreatorID"]);
prim.CreatorIdentification = (string)row["CreatorID"];
prim.OwnerID = DBGuid.FromDB(row["OwnerID"]);
prim.GroupID = DBGuid.FromDB(row["GroupID"]);
prim.LastOwnerID = DBGuid.FromDB(row["LastOwnerID"]);
@ -1243,7 +1243,7 @@ namespace OpenSim.Data.MySQL
taskItem.Name = (String)row["name"];
taskItem.Description = (String)row["description"];
taskItem.CreationDate = Convert.ToUInt32(row["creationDate"]);
taskItem.CreatorID = DBGuid.FromDB(row["creatorID"]);
taskItem.CreatorIdentification = (String)row["creatorID"];
taskItem.OwnerID = DBGuid.FromDB(row["ownerID"]);
taskItem.LastOwnerID = DBGuid.FromDB(row["lastOwnerID"]);
taskItem.GroupID = DBGuid.FromDB(row["groupID"]);
@ -1453,7 +1453,7 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("TouchName", prim.TouchName);
// permissions
cmd.Parameters.AddWithValue("ObjectFlags", (uint)prim.Flags);
cmd.Parameters.AddWithValue("CreatorID", prim.CreatorID.ToString());
cmd.Parameters.AddWithValue("CreatorID", prim.CreatorIdentification.ToString());
cmd.Parameters.AddWithValue("OwnerID", prim.OwnerID.ToString());
cmd.Parameters.AddWithValue("GroupID", prim.GroupID.ToString());
cmd.Parameters.AddWithValue("LastOwnerID", prim.LastOwnerID.ToString());
@ -1583,7 +1583,7 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("name", taskItem.Name);
cmd.Parameters.AddWithValue("description", taskItem.Description);
cmd.Parameters.AddWithValue("creationDate", taskItem.CreationDate);
cmd.Parameters.AddWithValue("creatorID", taskItem.CreatorID);
cmd.Parameters.AddWithValue("creatorID", taskItem.CreatorIdentification);
cmd.Parameters.AddWithValue("ownerID", taskItem.OwnerID);
cmd.Parameters.AddWithValue("lastOwnerID", taskItem.LastOwnerID);
cmd.Parameters.AddWithValue("groupID", taskItem.GroupID);

View File

@ -99,3 +99,11 @@ BEGIN;
alter table inventoryitems modify column creatorID varchar(128) not NULL default '00000000-0000-0000-0000-000000000000';
COMMIT;
:VERSION 6 # ------------
BEGIN;
alter table inventoryitems modify column creatorID varchar(255) not NULL default '00000000-0000-0000-0000-000000000000';
COMMIT;

View File

@ -817,3 +817,12 @@ ALTER TABLE `land` ADD COLUMN `MediaLoop` BOOLEAN NOT NULL DEFAULT FALSE;
ALTER TABLE `land` ADD COLUMN `ObscureMusic` BOOLEAN NOT NULL DEFAULT FALSE;
ALTER TABLE `land` ADD COLUMN `ObscureMedia` BOOLEAN NOT NULL DEFAULT FALSE;
COMMIT;
:VERSION 37 #---------------------
BEGIN;
ALTER TABLE `prims` MODIFY COLUMN `CreatorID` VARCHAR(255) NOT NULL DEFAULT '';
ALTER TABLE `primitems` MODIFY COLUMN `CreatorID` VARCHAR(255) NOT NULL DEFAULT '';
COMMIT;

View File

@ -156,7 +156,7 @@ namespace OpenSim.Data.SQLite
item.InvType = Convert.ToInt32(row["invType"]);
item.Folder = new UUID((string) row["parentFolderID"]);
item.Owner = new UUID((string) row["avatarID"]);
item.CreatorId = (string)row["creatorsID"];
item.CreatorIdentification = (string)row["creatorsID"];
item.Name = (string) row["inventoryName"];
item.Description = (string) row["inventoryDescription"];
@ -201,7 +201,7 @@ namespace OpenSim.Data.SQLite
row["invType"] = item.InvType;
row["parentFolderID"] = item.Folder.ToString();
row["avatarID"] = item.Owner.ToString();
row["creatorsID"] = item.CreatorId.ToString();
row["creatorsID"] = item.CreatorIdentification.ToString();
row["inventoryName"] = item.Name;
row["inventoryDescription"] = item.Description;

View File

@ -1243,7 +1243,7 @@ namespace OpenSim.Data.SQLite
prim.TouchName = (String) row["TouchName"];
// permissions
prim.ObjectFlags = Convert.ToUInt32(row["ObjectFlags"]);
prim.CreatorID = new UUID((String) row["CreatorID"]);
prim.CreatorIdentification = (String) row["CreatorID"];
prim.OwnerID = new UUID((String) row["OwnerID"]);
prim.GroupID = new UUID((String) row["GroupID"]);
prim.LastOwnerID = new UUID((String) row["LastOwnerID"]);
@ -1385,7 +1385,7 @@ namespace OpenSim.Data.SQLite
taskItem.Name = (String)row["name"];
taskItem.Description = (String)row["description"];
taskItem.CreationDate = Convert.ToUInt32(row["creationDate"]);
taskItem.CreatorID = new UUID((String)row["creatorID"]);
taskItem.CreatorIdentification = (String)row["creatorID"];
taskItem.OwnerID = new UUID((String)row["ownerID"]);
taskItem.LastOwnerID = new UUID((String)row["lastOwnerID"]);
taskItem.GroupID = new UUID((String)row["groupID"]);
@ -1583,7 +1583,7 @@ namespace OpenSim.Data.SQLite
row["TouchName"] = prim.TouchName;
// permissions
row["ObjectFlags"] = prim.ObjectFlags;
row["CreatorID"] = prim.CreatorID.ToString();
row["CreatorID"] = prim.CreatorIdentification.ToString();
row["OwnerID"] = prim.OwnerID.ToString();
row["GroupID"] = prim.GroupID.ToString();
row["LastOwnerID"] = prim.LastOwnerID.ToString();
@ -1716,7 +1716,7 @@ namespace OpenSim.Data.SQLite
row["name"] = taskItem.Name;
row["description"] = taskItem.Description;
row["creationDate"] = taskItem.CreationDate;
row["creatorID"] = taskItem.CreatorID.ToString();
row["creatorID"] = taskItem.CreatorIdentification.ToString();
row["ownerID"] = taskItem.OwnerID.ToString();
row["lastOwnerID"] = taskItem.LastOwnerID.ToString();
row["groupID"] = taskItem.GroupID.ToString();

View File

@ -150,7 +150,7 @@ namespace OpenSim.Data.SQLiteLegacy
item.InvType = Convert.ToInt32(row["invType"]);
item.Folder = new UUID((string) row["parentFolderID"]);
item.Owner = new UUID((string) row["avatarID"]);
item.CreatorId = (string)row["creatorsID"];
item.CreatorIdentification = (string)row["creatorsID"];
item.Name = (string) row["inventoryName"];
item.Description = (string) row["inventoryDescription"];
@ -195,7 +195,7 @@ namespace OpenSim.Data.SQLiteLegacy
row["invType"] = item.InvType;
row["parentFolderID"] = item.Folder.ToString();
row["avatarID"] = item.Owner.ToString();
row["creatorsID"] = item.CreatorId.ToString();
row["creatorsID"] = item.CreatorIdentification.ToString();
row["inventoryName"] = item.Name;
row["inventoryDescription"] = item.Description;

View File

@ -1198,7 +1198,7 @@ namespace OpenSim.Data.SQLiteLegacy
prim.TouchName = (String) row["TouchName"];
// permissions
prim.Flags = (PrimFlags)Convert.ToUInt32(row["ObjectFlags"]);
prim.CreatorID = new UUID((String) row["CreatorID"]);
prim.CreatorIdentification = (String) row["CreatorID"];
prim.OwnerID = new UUID((String) row["OwnerID"]);
prim.GroupID = new UUID((String) row["GroupID"]);
prim.LastOwnerID = new UUID((String) row["LastOwnerID"]);
@ -1334,7 +1334,7 @@ namespace OpenSim.Data.SQLiteLegacy
taskItem.Name = (String)row["name"];
taskItem.Description = (String)row["description"];
taskItem.CreationDate = Convert.ToUInt32(row["creationDate"]);
taskItem.CreatorID = new UUID((String)row["creatorID"]);
taskItem.CreatorIdentification = (String)row["creatorID"];
taskItem.OwnerID = new UUID((String)row["ownerID"]);
taskItem.LastOwnerID = new UUID((String)row["lastOwnerID"]);
taskItem.GroupID = new UUID((String)row["groupID"]);
@ -1531,7 +1531,7 @@ namespace OpenSim.Data.SQLiteLegacy
row["TouchName"] = prim.TouchName;
// permissions
row["ObjectFlags"] = (uint)prim.Flags;
row["CreatorID"] = prim.CreatorID.ToString();
row["CreatorID"] = prim.CreatorIdentification.ToString();
row["OwnerID"] = prim.OwnerID.ToString();
row["GroupID"] = prim.GroupID.ToString();
row["LastOwnerID"] = prim.LastOwnerID.ToString();
@ -1664,7 +1664,7 @@ namespace OpenSim.Data.SQLiteLegacy
row["name"] = taskItem.Name;
row["description"] = taskItem.Description;
row["creationDate"] = taskItem.CreationDate;
row["creatorID"] = taskItem.CreatorID.ToString();
row["creatorID"] = taskItem.CreatorIdentification.ToString();
row["ownerID"] = taskItem.OwnerID.ToString();
row["lastOwnerID"] = taskItem.LastOwnerID.ToString();
row["groupID"] = taskItem.GroupID.ToString();

View File

@ -473,9 +473,11 @@ namespace OpenSim.Framework.Console
y = -1;
}
string commandLine = cmdline.ToString();
if (isCommand)
{
string[] cmd = Commands.Resolve(Parser.Parse(cmdline.ToString()));
string[] cmd = Commands.Resolve(Parser.Parse(commandLine));
if (cmd.Length != 0)
{
@ -491,8 +493,11 @@ namespace OpenSim.Framework.Console
}
}
//AddToHistory(cmdline.ToString());
return cmdline.ToString();
// If we're not echoing to screen (e.g. a password) then we probably don't want it in history
if (echo && commandLine != "")
AddToHistory(commandLine);
return commandLine;
default:
break;
}

View File

@ -39,5 +39,6 @@ namespace OpenSim.Framework
void ExtraFromXmlString(string xmlstr);
string GetStateSnapshot();
void SetState(string xmlstr, IScene s);
bool HasGroupChanged { get; set; }
}
}

View File

@ -117,6 +117,56 @@ namespace OpenSim.Framework
}
protected UUID m_creatorIdAsUuid = UUID.Zero;
protected string m_creatorData;
public string CreatorData // = <profile url>;<name>
{
get { return m_creatorData; }
set { m_creatorData = value; }
}
/// <summary>
/// Used by the DB layer to retrieve / store the entire user identification.
/// The identification can either be a simple UUID or a string of the form
/// uuid[;profile_url[;name]]
/// </summary>
public string CreatorIdentification
{
get
{
if (m_creatorData != null && m_creatorData != string.Empty)
return m_creatorId + ';' + m_creatorData;
else
return m_creatorId;
}
set
{
if ((value == null) || (value != null && value == string.Empty))
{
m_creatorData = string.Empty;
return;
}
if (!value.Contains(";")) // plain UUID
{
m_creatorId = value;
}
else // <uuid>[;<endpoint>[;name]]
{
string name = "Unknown User";
string[] parts = value.Split(';');
if (parts.Length >= 1)
m_creatorId = parts[0];
if (parts.Length >= 2)
m_creatorData = parts[1];
if (parts.Length >= 3)
name = parts[2];
m_creatorData += ';' + name;
}
}
}
/// <value>
/// The description of the inventory item (must be less than 64 characters)
/// </value>

View File

@ -102,6 +102,7 @@ namespace OpenSim.Framework
private uint _baseMask = FULL_MASK_PERMISSIONS_GENERAL;
private uint _creationDate = 0;
private UUID _creatorID = UUID.Zero;
private string _creatorData = String.Empty;
private string _description = String.Empty;
private uint _everyoneMask = FULL_MASK_PERMISSIONS_GENERAL;
private uint _flags = 0;
@ -160,6 +161,61 @@ namespace OpenSim.Framework
}
}
public string CreatorData // = <profile url>;<name>
{
get { return _creatorData; }
set { _creatorData = value; }
}
/// <summary>
/// Used by the DB layer to retrieve / store the entire user identification.
/// The identification can either be a simple UUID or a string of the form
/// uuid[;profile_url[;name]]
/// </summary>
public string CreatorIdentification
{
get
{
if (_creatorData != null && _creatorData != string.Empty)
return _creatorID.ToString() + ';' + _creatorData;
else
return _creatorID.ToString();
}
set
{
if ((value == null) || (value != null && value == string.Empty))
{
_creatorData = string.Empty;
return;
}
if (!value.Contains(";")) // plain UUID
{
UUID uuid = UUID.Zero;
UUID.TryParse(value, out uuid);
_creatorID = uuid;
}
else // <uuid>[;<endpoint>[;name]]
{
string name = "Unknown User";
string[] parts = value.Split(';');
if (parts.Length >= 1)
{
UUID uuid = UUID.Zero;
UUID.TryParse(parts[0], out uuid);
_creatorID = uuid;
}
if (parts.Length >= 2)
_creatorData = parts[1];
if (parts.Length >= 3)
name = parts[2];
_creatorData += ';' + name;
}
}
}
public string Description {
get {
return _description;

View File

@ -451,6 +451,14 @@ namespace OpenSim.Framework
return (x + y - (min >> 1) - (min >> 2) + (min >> 4));
}
/// <summary>
/// Are the co-ordinates of the new region visible from the old region?
/// </summary>
/// <param name="oldx">Old region x-coord</param>
/// <param name="newx">New region x-coord</param>
/// <param name="oldy">Old region y-coord</param>
/// <param name="newy">New region y-coord</param>
/// <returns></returns>
public static bool IsOutsideView(uint oldx, uint newx, uint oldy, uint newy)
{
// Eventually this will be a function of the draw distance / camera position too.

View File

@ -30,6 +30,7 @@ using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using System.Timers;
using log4net;
using Nini.Config;
@ -264,9 +265,10 @@ namespace OpenSim
LoadOar);
m_console.Commands.AddCommand("region", false, "save oar",
"save oar [-v|version=N] [<OAR path>]",
"save oar [-v|--version=N] [-p|--profile=url] [<OAR path>]",
"Save a region's data to an OAR archive.",
"-v|version=N generates scene objects as per older versions of the serialization (e.g. -v=0)" + Environment.NewLine
"-v|--version=N generates scene objects as per older versions of the serialization (e.g. -v=0)" + Environment.NewLine
+ "-p|--profile=url adds the url of the profile service to the saved user information" + Environment.NewLine
+ "The OAR path must be a filesystem path."
+ " If this is not given then the oar is saved to region.oar in the current directory.",
SaveOar);
@ -285,16 +287,15 @@ namespace OpenSim
m_console.Commands.AddCommand("region", false, "show users",
"show users [full]",
"Show user data", HandleShow);
"Show user data for users currently on the region",
"Without the 'full' option, only users actually on the region are shown."
+ " With the 'full' option child agents of users in neighbouring regions are also shown.",
HandleShow);
m_console.Commands.AddCommand("region", false, "show connections",
"show connections",
"Show connection data", HandleShow);
m_console.Commands.AddCommand("region", false, "show users full",
"show users full",
String.Empty, HandleShow);
m_console.Commands.AddCommand("region", false, "show modules",
"show modules",
"Show module data", HandleShow);
@ -304,8 +305,12 @@ namespace OpenSim
"Show region data", HandleShow);
m_console.Commands.AddCommand("region", false, "show queues",
"show queues",
"Show queue data", HandleShow);
"show queues [full]",
"Show queue data for each client",
"Without the 'full' option, only users actually on the region are shown."
+ " With the 'full' option child agents of users in neighbouring regions are also shown.",
HandleShow);
m_console.Commands.AddCommand("region", false, "show ratings",
"show ratings",
"Show rating data", HandleShow);
@ -876,7 +881,7 @@ namespace OpenSim
{
agents = m_sceneManager.GetCurrentSceneAvatars();
}
MainConsole.Instance.Output(String.Format("\nAgents connected: {0}\n", agents.Count));
MainConsole.Instance.Output(
@ -953,7 +958,7 @@ namespace OpenSim
break;
case "queues":
Notice(GetQueuesReport());
Notice(GetQueuesReport(showParams));
break;
case "ratings":
@ -983,43 +988,91 @@ namespace OpenSim
}
/// <summary>
/// print UDP Queue data for each client
/// Generate UDP Queue data report for each client
/// </summary>
/// <param name="showParams"></param>
/// <returns></returns>
private string GetQueuesReport()
private string GetQueuesReport(string[] showParams)
{
string report = String.Empty;
bool showChildren = false;
if (showParams.Length > 1 && showParams[1] == "full")
showChildren = true;
StringBuilder report = new StringBuilder();
int columnPadding = 2;
int maxNameLength = 18;
int maxRegionNameLength = 14;
int maxTypeLength = 4;
int totalInfoFieldsLength = maxNameLength + columnPadding + maxRegionNameLength + columnPadding + maxTypeLength + columnPadding;
report.AppendFormat("{0,-" + maxNameLength + "}{1,-" + columnPadding + "}", "User", "");
report.AppendFormat("{0,-" + maxRegionNameLength + "}{1,-" + columnPadding + "}", "Region", "");
report.AppendFormat("{0,-" + maxTypeLength + "}{1,-" + columnPadding + "}", "Type", "");
report.AppendFormat(
"{0,9} {1,9} {2,9} {3,8} {4,7} {5,7} {6,7} {7,7} {8,9} {9,7} {10,7}\n",
"Packets",
"Packets",
"Bytes",
"Bytes",
"Bytes",
"Bytes",
"Bytes",
"Bytes",
"Bytes",
"Bytes",
"Bytes");
report.AppendFormat("{0,-" + totalInfoFieldsLength + "}", "");
report.AppendFormat(
"{0,9} {1,9} {2,9} {3,8} {4,7} {5,7} {6,7} {7,7} {8,9} {9,7} {10,7}\n",
"Out",
"In",
"Unacked",
"Resend",
"Land",
"Wind",
"Cloud",
"Task",
"Texture",
"Asset",
"State");
m_sceneManager.ForEachScene(
delegate(Scene scene)
{
scene.ForEachClient(
delegate(IClientAPI client)
{
if (client is IStatsCollector)
{
bool isChild = scene.PresenceChildStatus(client.AgentId);
if (isChild && !showChildren)
return;
string name = client.Name;
string regionName = scene.RegionInfo.RegionName;
report.AppendFormat(
"{0,-" + maxNameLength + "}{1,-" + columnPadding + "}",
name.Length > maxNameLength ? name.Substring(0, maxNameLength) : name, "");
report.AppendFormat(
"{0,-" + maxRegionNameLength + "}{1,-" + columnPadding + "}",
regionName.Length > maxRegionNameLength ? regionName.Substring(0, maxRegionNameLength) : regionName, "");
report.AppendFormat(
"{0,-" + maxTypeLength + "}{1,-" + columnPadding + "}",
isChild ? "Cd" : "Rt", "");
m_sceneManager.ForEachScene(delegate(Scene scene)
{
scene.ForEachClient(delegate(IClientAPI client)
{
if (client is IStatsCollector)
{
report = report + client.FirstName +
" " + client.LastName;
IStatsCollector stats = (IStatsCollector)client;
report.AppendLine(stats.Report());
}
});
});
IStatsCollector stats =
(IStatsCollector) client;
report = report + string.Format("{0,7} {1,7} {2,7} {3,7} {4,7} {5,7} {6,7} {7,7} {8,7} {9,7}\n",
"Send",
"In",
"Out",
"Resend",
"Land",
"Wind",
"Cloud",
"Task",
"Texture",
"Asset");
report = report + stats.Report() +
"\n";
}
});
});
return report;
return report.ToString();
}
/// <summary>

View File

@ -6016,8 +6016,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
SoundTrigger handlerSoundTrigger = OnSoundTrigger;
if (handlerSoundTrigger != null)
{
handlerSoundTrigger(soundTriggerPacket.SoundData.SoundID, soundTriggerPacket.SoundData.OwnerID,
soundTriggerPacket.SoundData.ObjectID, soundTriggerPacket.SoundData.ParentID,
// UUIDS are sent as zeroes by the client, substitute agent's id
handlerSoundTrigger(soundTriggerPacket.SoundData.SoundID, AgentId,
AgentId, AgentId,
soundTriggerPacket.SoundData.Gain, soundTriggerPacket.SoundData.Position,
soundTriggerPacket.SoundData.Handle, 0);

View File

@ -246,11 +246,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
throw new NotImplementedException();
}
/// <summary>
/// Return statistics information about client packet queues.
/// </summary>
///
/// FIXME: This should really be done in a more sensible manner rather than sending back a formatted string.
///
/// <returns></returns>
public string GetStats()
{
// TODO: ???
return string.Format("{0,7} {1,7} {2,7} {3,7} {4,7} {5,7} {6,7} {7,7} {8,7} {9,7}",
0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
return string.Format(
"{0,9} {1,9} {2,9} {3,8} {4,7} {5,7} {6,7} {7,7} {8,9} {9,7} {10,7}",
PacketsSent,
PacketsReceived,
UnackedBytes,
m_throttleCategories[(int)ThrottleOutPacketType.Resend].Content,
m_throttleCategories[(int)ThrottleOutPacketType.Land].Content,
m_throttleCategories[(int)ThrottleOutPacketType.Wind].Content,
m_throttleCategories[(int)ThrottleOutPacketType.Cloud].Content,
m_throttleCategories[(int)ThrottleOutPacketType.Task].Content,
m_throttleCategories[(int)ThrottleOutPacketType.Texture].Content,
m_throttleCategories[(int)ThrottleOutPacketType.Asset].Content,
m_throttleCategories[(int)ThrottleOutPacketType.State].Content);
}
public void SendPacketStats()

View File

@ -273,6 +273,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
if (objatt != null)
{
// Loading the inventory from XML will have set this, but
// there is no way the object could have changed yet,
// since scripts aren't running yet. So, clear it here.
objatt.HasGroupChanged = false;
bool tainted = false;
if (AttachmentPt != 0 && AttachmentPt != objatt.GetAttachmentPoint())
tainted = true;
@ -470,6 +474,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero);
group.DetachToInventoryPrep();
m_log.Debug("[ATTACHMENTS MODULE]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint()).ToString());
// If an item contains scripts, it's always changed.
// This ensures script state is saved on detach
foreach (SceneObjectPart p in group.Parts)
if (p.Inventory.ContainsScripts())
group.HasGroupChanged = true;
UpdateKnownItem(remoteClient, group, group.GetFromItemID(), group.OwnerID);
m_scene.DeleteSceneObject(group, false);
return;
@ -478,25 +489,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
}
}
public void UpdateAttachmentPosition(IClientAPI client, SceneObjectGroup sog, Vector3 pos)
{
// If this is an attachment, then we need to save the modified
// object back into the avatar's inventory. First we save the
// attachment point information, then we update the relative
// positioning (which caused this method to get driven in the
// first place. Then we have to mark the object as NOT an
// attachment. This is necessary in order to correctly save
// and retrieve GroupPosition information for the attachment.
// Then we save the asset back into the appropriate inventory
// entry. Finally, we restore the object's attachment status.
byte attachmentPoint = sog.GetAttachmentPoint();
sog.UpdateGroupPosition(pos);
sog.RootPart.IsAttachment = false;
sog.AbsolutePosition = sog.RootPart.AttachedPos;
UpdateKnownItem(client, sog, sog.GetFromItemID(), sog.OwnerID);
sog.SetAttachmentPoint(attachmentPoint);
}
/// <summary>
/// Update the attachment asset for the new sog details if they have changed.
/// </summary>
@ -508,7 +500,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
/// <param name="grp"></param>
/// <param name="itemID"></param>
/// <param name="agentID"></param>
protected void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp, UUID itemID, UUID agentID)
public void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp, UUID itemID, UUID agentID)
{
if (grp != null)
{
@ -523,7 +515,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
grp.UUID, grp.GetAttachmentPoint());
string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp);
InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
item = m_scene.InventoryService.GetItem(item);
@ -617,7 +608,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
// In case it is later dropped again, don't let
// it get cleaned up
so.RootPart.RemFlag(PrimFlags.TemporaryOnRez);
so.HasGroupChanged = false;
}
}
}

View File

@ -55,6 +55,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
private Dictionary<UUID,long> m_savequeue = new Dictionary<UUID,long>();
private Dictionary<UUID,long> m_sendqueue = new Dictionary<UUID,long>();
private object m_setAppearanceLock = new object();
#region RegionModule Members
public void Initialise(Scene scene, IConfigSource config)
@ -69,6 +71,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
{
m_savetime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSave",Convert.ToString(m_savetime)));
m_sendtime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSend",Convert.ToString(m_sendtime)));
// m_log.InfoFormat("[AVFACTORY] configured for {0} save and {1} send",m_savetime,m_sendtime);
}
}
@ -117,26 +120,28 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
if (sp == null)
{
m_log.WarnFormat("[AVATAR FACTORY MODULE]: SetAppearance unable to find presence for {0}", client.AgentId);
m_log.WarnFormat("[AVFACTORY]: SetAppearance unable to find presence for {0}", client.AgentId);
return false;
}
bool cached = true;
bool defonly = true; // are we only using default textures
// Process the texture entry
for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
{
int idx = AvatarAppearance.BAKE_INDICES[i];
Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx];
if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE)
if (! CheckBakedTextureAsset(client,face.TextureID,idx))
{
sp.Appearance.Texture.FaceTextures[idx] = null;
cached = false;
}
if (face == null || face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE)
continue;
defonly = false; // found a non-default texture reference
if (! CheckBakedTextureAsset(client,face.TextureID,idx))
return false;
}
return cached;
// If we only found default textures, then the appearance is not cached
return (defonly ? false : true);
}
/// <summary>
@ -146,44 +151,59 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
/// <param name="visualParam"></param>
public void SetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams)
{
// m_log.WarnFormat("[AVATAR FACTORY MODULE]: SetAppearance for {0}",client.AgentId);
ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
if (sp == null)
{
m_log.WarnFormat("[AVATAR FACTORY MODULE]: SetAppearance unable to find presence for {0}",client.AgentId);
m_log.WarnFormat("[AVFACTORY]: SetAppearance unable to find presence for {0}",client.AgentId);
return;
}
// m_log.WarnFormat("[AVFACTORY]: Start SetAppearance for {0}",client.AgentId);
bool changed = false;
// Process the texture entry
if (textureEntry != null)
// Process the texture entry transactionally, this doesn't guarantee that Appearance is
// going to be handled correctly but it does serialize the updates to the appearance
lock (m_setAppearanceLock)
{
changed = sp.Appearance.SetTextureEntries(textureEntry);
for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
if (textureEntry != null)
{
int idx = AvatarAppearance.BAKE_INDICES[i];
Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx];
if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE)
Util.FireAndForget(delegate(object o) {
if (! CheckBakedTextureAsset(client,face.TextureID,idx))
client.SendRebakeAvatarTextures(face.TextureID);
});
}
}
changed = sp.Appearance.SetTextureEntries(textureEntry);
// Process the visual params, this may change height as well
if (visualParams != null)
{
if (sp.Appearance.SetVisualParams(visualParams))
{
changed = true;
if (sp.Appearance.AvatarHeight > 0)
sp.SetHeight(sp.Appearance.AvatarHeight);
// m_log.WarnFormat("[AVFACTORY]: Prepare to check textures for {0}",client.AgentId);
for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
{
int idx = AvatarAppearance.BAKE_INDICES[i];
Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx];
if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE)
Util.FireAndForget(delegate(object o) {
if (! CheckBakedTextureAsset(client,face.TextureID,idx))
client.SendRebakeAvatarTextures(face.TextureID);
});
}
// m_log.WarnFormat("[AVFACTORY]: Complete texture check for {0}",client.AgentId);
}
// Process the visual params, this may change height as well
if (visualParams != null)
{
if (sp.Appearance.SetVisualParams(visualParams))
{
changed = true;
if (sp.Appearance.AvatarHeight > 0)
sp.SetHeight(sp.Appearance.AvatarHeight);
}
}
// Send the appearance back to the avatar, not clear that this is needed
sp.ControllingClient.SendAvatarDataImmediate(sp);
// AvatarAppearance avp = sp.Appearance;
// sp.ControllingClient.SendAppearance(avp.Owner,avp.VisualParams,avp.Texture.GetBytes());
}
// If something changed in the appearance then queue an appearance save
if (changed)
@ -192,10 +212,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
// And always queue up an appearance update to send out
QueueAppearanceSend(client.AgentId);
// Send the appearance back to the avatar
// AvatarAppearance avp = sp.Appearance;
// sp.ControllingClient.SendAvatarDataImmediate(sp);
// sp.ControllingClient.SendAppearance(avp.Owner,avp.VisualParams,avp.Texture.GetBytes());
// m_log.WarnFormat("[AVFACTORY]: Complete SetAppearance for {0}:\n{1}",client.AgentId,sp.Appearance.ToString());
}
/// <summary>
@ -209,7 +226,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
{
if (m_scene.AssetService.Get(textureID.ToString()) == null)
{
m_log.WarnFormat("[AVATAR FACTORY MODULE]: Missing baked texture {0} ({1}) for avatar {2}",
m_log.WarnFormat("[AVFACTORY]: Missing baked texture {0} ({1}) for avatar {2}",
textureID, idx, client.Name);
return false;
}
@ -220,10 +237,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
public void QueueAppearanceSend(UUID agentid)
{
// m_log.WarnFormat("[AVATAR FACTORY MODULE]: Queue appearance send for {0}", agentid);
// m_log.WarnFormat("[AVFACTORY]: Queue appearance send for {0}", agentid);
// 100 nanoseconds (ticks) we should wait
long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_sendtime * 10000000);
// 10000 ticks per millisecond, 1000 milliseconds per second
long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_sendtime * 1000 * 10000);
lock (m_sendqueue)
{
m_sendqueue[agentid] = timestamp;
@ -233,10 +250,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
public void QueueAppearanceSave(UUID agentid)
{
// m_log.WarnFormat("[AVATAR FACTORY MODULE]: Queue appearance save for {0}", agentid);
// m_log.WarnFormat("[AVFACTORY]: Queue appearance save for {0}", agentid);
// 100 nanoseconds (ticks) we should wait
long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 10000000);
// 10000 ticks per millisecond, 1000 milliseconds per second
long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 1000 * 10000);
lock (m_savequeue)
{
m_savequeue[agentid] = timestamp;
@ -249,15 +266,15 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
ScenePresence sp = m_scene.GetScenePresence(agentid);
if (sp == null)
{
m_log.WarnFormat("[AVATAR FACTORY MODULE]: Agent {0} no longer in the scene", agentid);
m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid);
return;
}
// m_log.WarnFormat("[AVATAR FACTORY MODULE]: Handle appearance send for {0}", agentid);
// m_log.WarnFormat("[AVFACTORY]: Handle appearance send for {0}", agentid);
// Send the appearance to everyone in the scene
sp.SendAppearanceToAllOtherAgents();
sp.ControllingClient.SendAvatarDataImmediate(sp);
// sp.ControllingClient.SendAvatarDataImmediate(sp);
// Send the appearance back to the avatar
// AvatarAppearance avp = sp.Appearance;
@ -279,10 +296,12 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
ScenePresence sp = m_scene.GetScenePresence(agentid);
if (sp == null)
{
m_log.WarnFormat("[AVATAR FACTORY MODULE]: Agent {0} no longer in the scene", agentid);
m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid);
return;
}
// m_log.WarnFormat("[AVFACTORY] avatar {0} save appearance",agentid);
m_scene.AvatarService.SetAppearance(agentid, sp.Appearance);
}
@ -330,11 +349,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
if (sp == null)
{
m_log.WarnFormat("[AVATAR FACTORY MODULE]: SendWearables unable to find presence for {0}", client.AgentId);
m_log.WarnFormat("[AVFACTORY]: SendWearables unable to find presence for {0}", client.AgentId);
return;
}
// m_log.WarnFormat("[AVATAR FACTORY MODULE]: Received request for wearables of {0}", client.AgentId);
// m_log.WarnFormat("[AVFACTORY]: Received request for wearables of {0}", client.AgentId);
client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++);
}
@ -349,11 +368,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
if (sp == null)
{
m_log.WarnFormat("[AVATAR FACTORY MODULE]: AvatarIsWearing unable to find presence for {0}", client.AgentId);
m_log.WarnFormat("[AVFACTORY]: AvatarIsWearing unable to find presence for {0}", client.AgentId);
return;
}
// m_log.WarnFormat("[AVATAR FACTORY MODULE]: AvatarIsWearing called for {0}", client.AgentId);
// m_log.WarnFormat("[AVFACTORY]: AvatarIsWearing called for {0}", client.AgentId);
AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance, false);
@ -368,6 +387,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
// This could take awhile since it needs to pull inventory
SetAppearanceAssets(sp.UUID, ref avatAppearance);
// could get fancier with the locks here, but in the spirit of "last write wins"
// this should work correctly
sp.Appearance = avatAppearance;
m_scene.AvatarService.SetAppearance(client.AgentId, sp.Appearance);
}
@ -398,7 +419,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
else
{
m_log.ErrorFormat(
"[AVATAR FACTORY MODULE]: Can't find inventory item {0} for {1}, setting to default",
"[AVFACTORY]: Can't find inventory item {0} for {1}, setting to default",
appearance.Wearables[i][j].ItemID, (WearableType)i);
appearance.Wearables[i].RemoveItem(appearance.Wearables[i][j].ItemID);
@ -408,7 +429,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
}
else
{
m_log.WarnFormat("[AVATAR FACTORY MODULE]: user {0} has no inventory, appearance isn't going to work", userID);
m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID);
}
}
}

View File

@ -115,10 +115,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule
// Try to find the avatar wielding the killing object
killingAvatar = deadAvatar.Scene.GetScenePresence(part.OwnerID);
if (killingAvatar == null)
deadAvatarMessage = String.Format("You impaled yourself on {0} owned by {1}!", part.Name, deadAvatar.Scene.GetUserName(part.OwnerID));
{
IUserManagement userManager = deadAvatar.Scene.RequestModuleInterface<IUserManagement>();
string userName = "Unkown User";
if (userManager != null)
userName = userManager.GetUserName(part.OwnerID);
deadAvatarMessage = String.Format("You impaled yourself on {0} owned by {1}!", part.Name, userName);
}
else
{
// killingAvatarMessage = String.Format("You fragged {0}!", deadAvatar.Name);
// killingAvatarMessage = String.Format("You fragged {0}!", deadAvatar.Name);
deadAvatarMessage = String.Format("You got killed by {0}!", killingAvatar.Name);
}
}

View File

@ -1200,11 +1200,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
}
m_log.Debug("[ENTITY TRANSFER MODULE]: Completed inform client about neighbour " + endPoint.ToString());
}
}
/// <summary>
/// Return the list of regions that are considered to be neighbours to the given scene.
/// </summary>
/// <param name="pScene"></param>
/// <param name="pRegionLocX"></param>
/// <param name="pRegionLocY"></param>
/// <returns></returns>
protected List<GridRegion> RequestNeighbours(Scene pScene, uint pRegionLocX, uint pRegionLocY)
{
RegionInfo m_regionInfo = pScene.RegionInfo;

View File

@ -370,6 +370,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
item = new InventoryItemBase();
item.CreatorId = objectGroup.RootPart.CreatorID.ToString();
item.CreatorData = objectGroup.RootPart.CreatorData;
item.ID = UUID.Random();
item.InvType = (int)InventoryType.Object;
item.Folder = folder.ID;
@ -569,12 +570,20 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
{
group.RootPart.Flags |= PrimFlags.Phantom;
group.RootPart.IsAttachment = true;
}
// If we're rezzing an attachment then don't ask AddNewSceneObject() to update the client since
// we'll be doing that later on. Scheduling more than one full update during the attachment
// process causes some clients to fail to display the attachment properly.
m_Scene.AddNewSceneObject(group, true, false);
// If we're rezzing an attachment then don't ask
// AddNewSceneObject() to update the client since
// we'll be doing that later on. Scheduling more
// than one full update during the attachment
// process causes some clients to fail to display
// the attachment properly.
// Also, don't persist attachments.
m_Scene.AddNewSceneObject(group, false, false);
}
else
{
m_Scene.AddNewSceneObject(group, true, false);
}
// m_log.InfoFormat("ray end point for inventory rezz is {0} {1} {2} ", RayEnd.X, RayEnd.Y, RayEnd.Z);
// if attachment we set it's asset id so object updates can reflect that

View File

@ -0,0 +1,310 @@
/*
* 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 OpenSim.Framework;
using OpenSim.Region.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
using OpenMetaverse;
using log4net;
using Nini.Config;
namespace OpenSim.Region.CoreModules.Framework.UserManagement
{
struct UserData
{
public UUID Id;
public string FirstName;
public string LastName;
public string ProfileURL;
}
public class UserManagementModule : ISharedRegionModule, IUserManagement
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private List<Scene> m_Scenes = new List<Scene>();
// The cache
Dictionary<UUID, UserData> m_UserCache = new Dictionary<UUID, UserData>();
#region ISharedRegionModule
public void Initialise(IConfigSource config)
{
//m_Enabled = config.Configs["Modules"].GetBoolean("LibraryModule", m_Enabled);
//if (m_Enabled)
//{
// IConfig libConfig = config.Configs["LibraryService"];
// if (libConfig != null)
// {
// string dllName = libConfig.GetString("LocalServiceModule", string.Empty);
// m_log.Debug("[LIBRARY MODULE]: Library service dll is " + dllName);
// if (dllName != string.Empty)
// {
// Object[] args = new Object[] { config };
// m_Library = ServerUtils.LoadPlugin<ILibraryService>(dllName, args);
// }
// }
//}
}
public bool IsSharedModule
{
get { return true; }
}
public string Name
{
get { return "UserManagement Module"; }
}
public Type ReplaceableInterface
{
get { return null; }
}
public void AddRegion(Scene scene)
{
m_Scenes.Add(scene);
scene.RegisterModuleInterface<IUserManagement>(this);
scene.EventManager.OnNewClient += new EventManager.OnNewClientDelegate(EventManager_OnNewClient);
}
public void RemoveRegion(Scene scene)
{
scene.UnregisterModuleInterface<IUserManagement>(this);
m_Scenes.Remove(scene);
}
public void RegionLoaded(Scene scene)
{
}
public void PostInitialise()
{
foreach (Scene s in m_Scenes)
{
// let's sniff all the user names referenced by objects in the scene
m_log.DebugFormat("[USER MANAGEMENT MODULE]: Caching creators' data from {0} ({1} objects)...", s.RegionInfo.RegionName, s.GetEntities().Length);
s.ForEachSOG(delegate(SceneObjectGroup sog) { CacheCreators(sog); });
}
}
public void Close()
{
m_Scenes.Clear();
m_UserCache.Clear();
}
#endregion ISharedRegionModule
#region Event Handlers
void EventManager_OnNewClient(IClientAPI client)
{
client.OnNameFromUUIDRequest += new UUIDNameRequest(HandleUUIDNameRequest);
}
void HandleUUIDNameRequest(UUID uuid, IClientAPI remote_client)
{
if (m_Scenes[0].LibraryService != null && (m_Scenes[0].LibraryService.LibraryRootFolder.Owner == uuid))
{
remote_client.SendNameReply(uuid, "Mr", "OpenSim");
}
else
{
string[] names = GetUserNames(uuid);
if (names.Length == 2)
{
remote_client.SendNameReply(uuid, names[0], names[1]);
}
}
}
#endregion Event Handlers
private void CacheCreators(SceneObjectGroup sog)
{
//m_log.DebugFormat("[USER MANAGEMENT MODULE]: processing {0} {1}; {2}", sog.RootPart.Name, sog.RootPart.CreatorData, sog.RootPart.CreatorIdentification);
AddUser(sog.RootPart.CreatorID, sog.RootPart.CreatorData);
foreach (SceneObjectPart sop in sog.Parts)
{
AddUser(sop.CreatorID, sop.CreatorData);
foreach (TaskInventoryItem item in sop.TaskInventory.Values)
AddUser(item.CreatorID, item.CreatorData);
}
}
private string[] GetUserNames(UUID uuid)
{
string[] returnstring = new string[2];
if (m_UserCache.ContainsKey(uuid))
{
returnstring[0] = m_UserCache[uuid].FirstName;
returnstring[1] = m_UserCache[uuid].LastName;
return returnstring;
}
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, uuid);
if (account != null)
{
returnstring[0] = account.FirstName;
returnstring[1] = account.LastName;
UserData user = new UserData();
user.FirstName = account.FirstName;
user.LastName = account.LastName;
lock (m_UserCache)
m_UserCache[uuid] = user;
}
else
{
returnstring[0] = "Unknown";
returnstring[1] = "User";
}
return returnstring;
}
#region IUserManagement
public string GetUserName(UUID uuid)
{
string[] names = GetUserNames(uuid);
if (names.Length == 2)
{
string firstname = names[0];
string lastname = names[1];
return firstname + " " + lastname;
}
return "(hippos)";
}
public void AddUser(UUID id, string creatorData)
{
if (m_UserCache.ContainsKey(id))
return;
UserData user = new UserData();
user.Id = id;
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, id);
if (account != null)
{
user.FirstName = account.FirstName;
user.LastName = account.LastName;
// user.ProfileURL = we should initialize this to the default
}
else
{
if (creatorData != null && creatorData != string.Empty)
{
//creatorData = <endpoint>;<name>
string[] parts = creatorData.Split(';');
if (parts.Length >= 1)
{
user.ProfileURL = parts[0];
try
{
Uri uri = new Uri(parts[0]);
user.LastName = "@" + uri.Authority;
}
catch
{
m_log.DebugFormat("[SCENE]: Unable to parse Uri {0}", parts[0]);
user.LastName = "@unknown";
}
}
if (parts.Length >= 2)
user.FirstName = parts[1].Replace(' ', '.');
}
else
{
user.FirstName = "Unknown";
user.LastName = "User";
}
}
lock (m_UserCache)
m_UserCache[id] = user;
m_log.DebugFormat("[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}", user.Id, user.FirstName, user.LastName, user.ProfileURL);
}
//public void AddUser(UUID uuid, string userData)
//{
// if (m_UserCache.ContainsKey(uuid))
// return;
// UserData user = new UserData();
// user.Id = uuid;
// // userData = <profile url>;<name>
// string[] parts = userData.Split(';');
// if (parts.Length >= 1)
// user.ProfileURL = parts[0].Trim();
// if (parts.Length >= 2)
// {
// string[] name = parts[1].Trim().Split(' ');
// if (name.Length >= 1)
// user.FirstName = name[0];
// if (name.Length >= 2)
// user.LastName = name[1];
// else
// user.LastName = "?";
// }
// lock (m_UserCache)
// m_UserCache.Add(uuid, user);
// m_log.DebugFormat("[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}", user.Id, user.FirstName, user.LastName, user.ProfileURL);
//}
#endregion IUserManagement
}
}

View File

@ -8,6 +8,7 @@
</Dependencies>
<Extension path = "/OpenSim/RegionModules">
<RegionModule id="UserManagementModule" type="OpenSim.Region.CoreModules.Framework.UserManagement.UserManagementModule" />
<RegionModule id="EntityTransferModule" type="OpenSim.Region.CoreModules.Framework.EntityTransfer.EntityTransferModule" />
<RegionModule id="HGEntityTransferModule" type="OpenSim.Region.CoreModules.Framework.EntityTransfer.HGEntityTransferModule" />
<RegionModule id="InventoryAccessModule" type="OpenSim.Region.CoreModules.Framework.InventoryAccess.BasicInventoryAccessModule" />

View File

@ -49,6 +49,21 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
private IInventoryService m_InventoryService;
private Scene m_Scene;
private IUserManagement m_UserManager;
private IUserManagement UserManager
{
get
{
if (m_UserManager == null)
{
m_UserManager = m_Scene.RequestModuleInterface<IUserManagement>();
}
return m_UserManager;
}
}
private bool m_Enabled = false;
public Type ReplaceableInterface
@ -115,6 +130,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
return;
scene.RegisterModuleInterface<IInventoryService>(this);
if (m_Scene == null)
m_Scene = scene;
}
public void RemoveRegion(Scene scene)
@ -163,7 +181,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
public InventoryCollection GetFolderContent(UUID userID, UUID folderID)
{
return m_InventoryService.GetFolderContent(userID, folderID);
InventoryCollection invCol = m_InventoryService.GetFolderContent(userID, folderID);
if (UserManager != null)
foreach (InventoryItemBase item in invCol.Items)
UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData);
return invCol;
}
public List<InventoryItemBase> GetFolderItems(UUID userID, UUID folderID)

View File

@ -47,9 +47,23 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
private bool m_Enabled = false;
private bool m_Initialized = false;
// private Scene m_Scene;
private Scene m_Scene;
private InventoryServicesConnector m_RemoteConnector;
private IUserManagement m_UserManager;
private IUserManagement UserManager
{
get
{
if (m_UserManager == null)
{
m_UserManager = m_Scene.RequestModuleInterface<IUserManagement>();
}
return m_UserManager;
}
}
public Type ReplaceableInterface
{
get { return null; }
@ -116,6 +130,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
scene.RegisterModuleInterface<IInventoryService>(this);
m_cache.AddRegion(scene);
if (m_Scene == null)
m_Scene = scene;
}
public void RemoveRegion(Scene scene)
@ -186,7 +203,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
UUID sessionID = GetSessionID(userID);
try
{
return m_RemoteConnector.GetFolderContent(userID.ToString(), folderID, sessionID);
InventoryCollection invCol = m_RemoteConnector.GetFolderContent(userID.ToString(), folderID, sessionID);
foreach (InventoryItemBase item in invCol.Items)
UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData);
return invCol;
}
catch (Exception e)
{

View File

@ -56,7 +56,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
/// The maximum major version of OAR that we can read. Minor versions shouldn't need a max number since version
/// bumps here should be compatible.
/// </summary>
public static int MAX_MAJOR_VERSION = 0;
public static int MAX_MAJOR_VERSION = 1;
protected Scene m_scene;
protected Stream m_loadStream;
@ -78,6 +78,19 @@ namespace OpenSim.Region.CoreModules.World.Archiver
/// </summary>
private IDictionary<UUID, bool> m_validUserUuids = new Dictionary<UUID, bool>();
private IUserManagement m_UserMan;
private IUserManagement UserManager
{
get
{
if (m_UserMan == null)
{
m_UserMan = m_scene.RequestModuleInterface<IUserManagement>();
}
return m_UserMan;
}
}
public ArchiveReadRequest(Scene scene, string loadPath, bool merge, bool skipAssets, Guid requestId)
{
m_scene = scene;
@ -251,8 +264,13 @@ namespace OpenSim.Region.CoreModules.World.Archiver
foreach (SceneObjectPart part in sceneObject.Parts)
{
if (!ResolveUserUuid(part.CreatorID))
part.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner;
if (part.CreatorData == null || part.CreatorData == string.Empty)
{
if (!ResolveUserUuid(part.CreatorID))
part.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner;
}
if (UserManager != null)
UserManager.AddUser(part.CreatorID, part.CreatorData);
if (!ResolveUserUuid(part.OwnerID))
part.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
@ -276,10 +294,13 @@ namespace OpenSim.Region.CoreModules.World.Archiver
{
kvp.Value.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
}
if (!ResolveUserUuid(kvp.Value.CreatorID))
if (kvp.Value.CreatorData == null || kvp.Value.CreatorData == string.Empty)
{
kvp.Value.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner;
if (!ResolveUserUuid(kvp.Value.CreatorID))
kvp.Value.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner;
}
if (UserManager != null)
UserManager.AddUser(kvp.Value.CreatorID, kvp.Value.CreatorData);
}
}
}

View File

@ -49,7 +49,17 @@ namespace OpenSim.Region.CoreModules.World.Archiver
public class ArchiveWriteRequestPreparation
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// The minimum major version of OAR that we can write.
/// </summary>
public static int MIN_MAJOR_VERSION = 0;
/// <summary>
/// The maximum major version of OAR that we can write.
/// </summary>
public static int MAX_MAJOR_VERSION = 1;
protected Scene m_scene;
protected Stream m_saveStream;
protected Guid m_requestId;
@ -101,110 +111,137 @@ namespace OpenSim.Region.CoreModules.World.Archiver
/// <exception cref="System.IO.IOException">if there was an io problem with creating the file</exception>
public void ArchiveRegion(Dictionary<string, object> options)
{
Dictionary<UUID, AssetType> assetUuids = new Dictionary<UUID, AssetType>();
EntityBase[] entities = m_scene.GetEntities();
List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>();
/*
foreach (ILandObject lo in m_scene.LandChannel.AllParcels())
{
if (name == lo.LandData.Name)
try
{
Dictionary<UUID, AssetType> assetUuids = new Dictionary<UUID, AssetType>();
EntityBase[] entities = m_scene.GetEntities();
List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>();
/*
foreach (ILandObject lo in m_scene.LandChannel.AllParcels())
{
// This is the parcel we want
if (name == lo.LandData.Name)
{
// This is the parcel we want
}
}
*/
// Filter entities so that we only have scene objects.
// FIXME: Would be nicer to have this as a proper list in SceneGraph, since lots of methods
// end up having to do this
foreach (EntityBase entity in entities)
{
if (entity is SceneObjectGroup)
{
SceneObjectGroup sceneObject = (SceneObjectGroup)entity;
if (!sceneObject.IsDeleted && !sceneObject.IsAttachment)
sceneObjects.Add((SceneObjectGroup)entity);
}
}
*/
// Filter entities so that we only have scene objects.
// FIXME: Would be nicer to have this as a proper list in SceneGraph, since lots of methods
// end up having to do this
foreach (EntityBase entity in entities)
{
if (entity is SceneObjectGroup)
UuidGatherer assetGatherer = new UuidGatherer(m_scene.AssetService);
foreach (SceneObjectGroup sceneObject in sceneObjects)
{
SceneObjectGroup sceneObject = (SceneObjectGroup)entity;
if (!sceneObject.IsDeleted && !sceneObject.IsAttachment)
sceneObjects.Add((SceneObjectGroup)entity);
assetGatherer.GatherAssetUuids(sceneObject, assetUuids);
}
m_log.DebugFormat(
"[ARCHIVER]: {0} scene objects to serialize requiring save of {1} assets",
sceneObjects.Count, assetUuids.Count);
// Make sure that we also request terrain texture assets
RegionSettings regionSettings = m_scene.RegionInfo.RegionSettings;
if (regionSettings.TerrainTexture1 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_1)
assetUuids[regionSettings.TerrainTexture1] = AssetType.Texture;
if (regionSettings.TerrainTexture2 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_2)
assetUuids[regionSettings.TerrainTexture2] = AssetType.Texture;
if (regionSettings.TerrainTexture3 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_3)
assetUuids[regionSettings.TerrainTexture3] = AssetType.Texture;
if (regionSettings.TerrainTexture4 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_4)
assetUuids[regionSettings.TerrainTexture4] = AssetType.Texture;
TarArchiveWriter archiveWriter = new TarArchiveWriter(m_saveStream);
// Asynchronously request all the assets required to perform this archive operation
ArchiveWriteRequestExecution awre
= new ArchiveWriteRequestExecution(
sceneObjects,
m_scene.RequestModuleInterface<ITerrainModule>(),
m_scene.RequestModuleInterface<IRegionSerialiserModule>(),
m_scene,
archiveWriter,
m_requestId,
options);
m_log.InfoFormat("[ARCHIVER]: Creating archive file. This may take some time.");
// Write out control file. This has to be done first so that subsequent loaders will see this file first
// XXX: I know this is a weak way of doing it since external non-OAR aware tar executables will not do this
archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, CreateControlFile(options));
m_log.InfoFormat("[ARCHIVER]: Added control file to archive.");
new AssetsRequest(
new AssetsArchiver(archiveWriter), assetUuids,
m_scene.AssetService, awre.ReceivedAllAssets).Execute();
}
UuidGatherer assetGatherer = new UuidGatherer(m_scene.AssetService);
foreach (SceneObjectGroup sceneObject in sceneObjects)
catch (Exception)
{
assetGatherer.GatherAssetUuids(sceneObject, assetUuids);
}
m_log.DebugFormat(
"[ARCHIVER]: {0} scene objects to serialize requiring save of {1} assets",
sceneObjects.Count, assetUuids.Count);
// Make sure that we also request terrain texture assets
RegionSettings regionSettings = m_scene.RegionInfo.RegionSettings;
if (regionSettings.TerrainTexture1 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_1)
assetUuids[regionSettings.TerrainTexture1] = AssetType.Texture;
if (regionSettings.TerrainTexture2 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_2)
assetUuids[regionSettings.TerrainTexture2] = AssetType.Texture;
if (regionSettings.TerrainTexture3 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_3)
assetUuids[regionSettings.TerrainTexture3] = AssetType.Texture;
if (regionSettings.TerrainTexture4 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_4)
assetUuids[regionSettings.TerrainTexture4] = AssetType.Texture;
TarArchiveWriter archiveWriter = new TarArchiveWriter(m_saveStream);
// Asynchronously request all the assets required to perform this archive operation
ArchiveWriteRequestExecution awre
= new ArchiveWriteRequestExecution(
sceneObjects,
m_scene.RequestModuleInterface<ITerrainModule>(),
m_scene.RequestModuleInterface<IRegionSerialiserModule>(),
m_scene,
archiveWriter,
m_requestId,
options);
m_log.InfoFormat("[ARCHIVER]: Creating archive file. This may take some time.");
// Write out control file. This has to be done first so that subsequent loaders will see this file first
// XXX: I know this is a weak way of doing it since external non-OAR aware tar executables will not do this
archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, Create0p2ControlFile(options));
m_log.InfoFormat("[ARCHIVER]: Added control file to archive.");
new AssetsRequest(
new AssetsArchiver(archiveWriter), assetUuids,
m_scene.AssetService, awre.ReceivedAllAssets).Execute();
m_saveStream.Close();
throw;
}
}
/// <summary>
/// Create the control file for the most up to date archive
/// </summary>
/// <returns></returns>
public static string Create0p2ControlFile(Dictionary<string, object> options)
public static string CreateControlFile(Dictionary<string, object> options)
{
int majorVersion = 0, minorVersion = 5;
int majorVersion = MAX_MAJOR_VERSION, minorVersion = 0;
if (options.ContainsKey("version"))
{
minorVersion = 0;
string[] parts = options["version"].ToString().Split('.');
if (parts.Length >= 1)
majorVersion = Int32.Parse(parts[0]);
if (parts.Length >= 2)
minorVersion = Int32.Parse(parts[1]);
{
majorVersion = Int32.Parse(parts[0]);
if (parts.Length >= 2)
minorVersion = Int32.Parse(parts[1]);
}
}
if (majorVersion < MIN_MAJOR_VERSION || majorVersion > MAX_MAJOR_VERSION)
{
throw new Exception(
string.Format(
"OAR version number for save must be between {0} and {1}",
MIN_MAJOR_VERSION, MAX_MAJOR_VERSION));
}
else if (majorVersion == MAX_MAJOR_VERSION)
{
// Force 1.0
minorVersion = 0;
}
else if (majorVersion == MIN_MAJOR_VERSION)
{
// Force 0.4
minorVersion = 4;
}
m_log.InfoFormat("[ARCHIVER]: Creating version {0}.{1} OAR", majorVersion, minorVersion);
// if (majorVersion == 1)
// {
// m_log.WarnFormat("[ARCHIVER]: Please be aware that version 1.0 OARs are not compatible with OpenSim 0.7.0.2 and earlier. Please use the --version=0 option if you want to produce a compatible OAR");
// }
if (majorVersion == 1)
{
m_log.WarnFormat("[ARCHIVER]: Please be aware that version 1.0 OARs are not compatible with OpenSim 0.7.0.2 and earlier. Please use the --version=0 option if you want to produce a compatible OAR");
}
StringWriter sw = new StringWriter();
XmlTextWriter xtw = new XmlTextWriter(sw);

View File

@ -126,6 +126,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
OptionSet ops = new OptionSet();
ops.Add("v|version=", delegate(string v) { options["version"] = v; });
ops.Add("p|profile=", delegate(string v) { options["profile"] = v; });
List<string> mainParams = ops.Parse(cmdparams);

View File

@ -122,13 +122,13 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
}
/// <summary>
/// Test saving a V0.2 OpenSim Region Archive.
/// Test saving an OpenSim Region Archive.
/// </summary>
[Test]
public void TestSaveOarV0_2()
public void TestSaveOar()
{
TestHelper.InMethod();
//log4net.Config.XmlConfigurator.Configure();
// log4net.Config.XmlConfigurator.Configure();
SceneObjectPart part1 = CreateSceneObjectPart1();
SceneObjectGroup sog1 = new SceneObjectGroup(part1);
@ -212,10 +212,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
}
/// <summary>
/// Test loading a V0.2 OpenSim Region Archive.
/// Test loading an OpenSim Region Archive.
/// </summary>
[Test]
public void TestLoadOarV0_2()
public void TestLoadOar()
{
TestHelper.InMethod();
// log4net.Config.XmlConfigurator.Configure();
@ -230,7 +230,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
// upset load
tar.WriteDir(ArchiveConstants.TERRAINS_PATH);
tar.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, ArchiveWriteRequestPreparation.Create0p2ControlFile(new Dictionary<string, Object>()));
tar.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, ArchiveWriteRequestPreparation.CreateControlFile(new Dictionary<string, Object>()));
SceneObjectPart part1 = CreateSceneObjectPart1();
SceneObjectGroup object1 = new SceneObjectGroup(part1);
@ -317,10 +317,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
}
/// <summary>
/// Test loading the region settings of a V0.2 OpenSim Region Archive.
/// Test loading the region settings of an OpenSim Region Archive.
/// </summary>
[Test]
public void TestLoadOarV0_2RegionSettings()
public void TestLoadOarRegionSettings()
{
TestHelper.InMethod();
//log4net.Config.XmlConfigurator.Configure();
@ -329,7 +329,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream);
tar.WriteDir(ArchiveConstants.TERRAINS_PATH);
tar.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, ArchiveWriteRequestPreparation.Create0p2ControlFile(new Dictionary<string, Object>()));
tar.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, ArchiveWriteRequestPreparation.CreateControlFile(new Dictionary<string, Object>()));
RegionSettings rs = new RegionSettings();
rs.AgentLimit = 17;
@ -409,10 +409,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
}
/// <summary>
/// Test merging a V0.2 OpenSim Region Archive into an existing scene
/// Test merging an OpenSim Region Archive into an existing scene
/// </summary>
//[Test]
public void TestMergeOarV0_2()
public void TestMergeOar()
{
TestHelper.InMethod();
//XmlConfigurator.Configure();

View File

@ -771,8 +771,14 @@ namespace OpenSim.Region.CoreModules.World.Estate
for (int i = 0; i < uuidarr.Length; i++)
{
// string lookupname = m_scene.CommsManager.UUIDNameRequestString(uuidarr[i]);
m_scene.GetUserName(uuidarr[i]);
IUserManagement userManager = m_scene.RequestModuleInterface<IUserManagement>();
string userName = "Unkown User";
if (userManager != null)
userName = userManager.GetUserName(uuidarr[i]);
// we drop it. It gets cached though... so we're ready for the next request.
// diva commnent 11/21/2010: uh?!? wft?
}
}
#endregion

View File

@ -189,6 +189,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.BuySell
InventoryItemBase item = new InventoryItemBase();
item.CreatorId = part.CreatorID.ToString();
item.CreatorData = part.CreatorData;
item.ID = UUID.Random();
item.Owner = remoteClient.AgentId;

View File

@ -106,14 +106,20 @@ namespace OpenSim.Region.CoreModules.World.Sound
{
SceneObjectPart part = m_scene.GetSceneObjectPart(objectID);
if (part == null)
return;
SceneObjectGroup grp = part.ParentGroup;
if (grp.IsAttachment && grp.GetAttachmentPoint() > 30)
{
objectID = ownerID;
parentID = ownerID;
ScenePresence sp;
if (!m_scene.TryGetScenePresence(objectID, out sp))
return;
}
else
{
SceneObjectGroup grp = part.ParentGroup;
if (grp.IsAttachment && grp.GetAttachmentPoint() > 30)
{
objectID = ownerID;
parentID = ownerID;
}
}
m_scene.ForEachScenePresence(delegate(ScenePresence sp)

View File

@ -122,11 +122,20 @@ namespace OpenSim.Region.Framework.Interfaces
void ShowDetachInUserInventory(UUID itemID, IClientAPI remoteClient);
/// <summary>
/// Update the position of an attachment
/// Update the user inventory with a changed attachment
/// </summary>
/// <param name="client"></param>
/// <param name="sog"></param>
/// <param name="pos"></param>
void UpdateAttachmentPosition(IClientAPI client, SceneObjectGroup sog, Vector3 pos);
/// <param name="remoteClient">
/// A <see cref="IClientAPI"/>
/// </param>
/// <param name="grp">
/// A <see cref="SceneObjectGroup"/>
/// </param>
/// <param name="itemID">
/// A <see cref="UUID"/>
/// </param>
/// <param name="agentID">
/// A <see cref="UUID"/>
/// </param>
void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp, UUID itemID, UUID agentID);
}
}
}

View File

@ -183,6 +183,7 @@ namespace OpenSim.Region.Framework.Interfaces
/// <returns>false if the item did not exist, true if the update occurred successfully</returns>
bool UpdateInventoryItem(TaskInventoryItem item);
bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents);
bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged);
/// <summary>
/// Remove an item from this entity's inventory

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using OpenMetaverse;
namespace OpenSim.Region.Framework.Interfaces
{
public interface IUserManagement
{
string GetUserName(UUID uuid);
void AddUser(UUID uuid, string userData);
}
}

View File

@ -426,6 +426,7 @@ namespace OpenSim.Region.Framework.Scenes
InventoryItemBase itemCopy = new InventoryItemBase();
itemCopy.Owner = recipient;
itemCopy.CreatorId = item.CreatorId;
itemCopy.CreatorData = item.CreatorData;
itemCopy.ID = UUID.Random();
itemCopy.AssetID = item.AssetID;
itemCopy.Description = item.Description;
@ -699,13 +700,13 @@ namespace OpenSim.Region.Framework.Scenes
if (remoteClient.AgentId == oldAgentID)
{
CreateNewInventoryItem(
remoteClient, item.CreatorId, newFolderID, newName, item.Flags, callbackID, asset, (sbyte)item.InvType,
remoteClient, item.CreatorId, item.CreatorData, newFolderID, newName, item.Flags, callbackID, asset, (sbyte)item.InvType,
item.BasePermissions, item.CurrentPermissions, item.EveryOnePermissions, item.NextPermissions, item.GroupPermissions, Util.UnixTimeSinceEpoch());
}
else
{
CreateNewInventoryItem(
remoteClient, item.CreatorId, newFolderID, newName, item.Flags, callbackID, asset, (sbyte)item.InvType,
remoteClient, item.CreatorId, item.CreatorData, newFolderID, newName, item.Flags, callbackID, asset, (sbyte)item.InvType,
item.NextPermissions, item.NextPermissions, item.EveryOnePermissions & item.NextPermissions, item.NextPermissions, item.GroupPermissions, Util.UnixTimeSinceEpoch());
}
}
@ -755,11 +756,11 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="asset"></param>
/// <param name="invType"></param>
/// <param name="nextOwnerMask"></param>
private void CreateNewInventoryItem(IClientAPI remoteClient, string creatorID, UUID folderID, string name, uint flags, uint callbackID,
private void CreateNewInventoryItem(IClientAPI remoteClient, string creatorID, string creatorData, UUID folderID, string name, uint flags, uint callbackID,
AssetBase asset, sbyte invType, uint nextOwnerMask, int creationDate)
{
CreateNewInventoryItem(
remoteClient, creatorID, folderID, name, flags, callbackID, asset, invType,
remoteClient, creatorID, creatorData, folderID, name, flags, callbackID, asset, invType,
(uint)PermissionMask.All, (uint)PermissionMask.All, 0, nextOwnerMask, 0, creationDate);
}
@ -774,12 +775,13 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="nextOwnerMask"></param>
/// <param name="creationDate"></param>
private void CreateNewInventoryItem(
IClientAPI remoteClient, string creatorID, UUID folderID, string name, uint flags, uint callbackID, AssetBase asset, sbyte invType,
IClientAPI remoteClient, string creatorID, string creatorData, UUID folderID, string name, uint flags, uint callbackID, AssetBase asset, sbyte invType,
uint baseMask, uint currentMask, uint everyoneMask, uint nextOwnerMask, uint groupMask, int creationDate)
{
InventoryItemBase item = new InventoryItemBase();
item.Owner = remoteClient.AgentId;
item.CreatorId = creatorID;
item.CreatorData = creatorData;
item.ID = UUID.Random();
item.AssetID = asset.FullID;
item.Description = asset.Description;
@ -859,7 +861,7 @@ namespace OpenSim.Region.Framework.Scenes
AssetBase asset = CreateAsset(name, description, assetType, data, remoteClient.AgentId);
AssetService.Store(asset);
CreateNewInventoryItem(remoteClient, remoteClient.AgentId.ToString(), folderID, asset.Name, 0, callbackID, asset, invType, nextOwnerMask, creationDate);
CreateNewInventoryItem(remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, asset.Name, 0, callbackID, asset, invType, nextOwnerMask, creationDate);
}
else
{
@ -901,7 +903,7 @@ namespace OpenSim.Region.Framework.Scenes
asset.Description = description;
CreateNewInventoryItem(
remoteClient, remoteClient.AgentId.ToString(), folderID, name, 0, callbackID, asset, invType,
remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, name, 0, callbackID, asset, invType,
(uint)PermissionMask.All, (uint)PermissionMask.All, (uint)PermissionMask.All,
(uint)PermissionMask.All, (uint)PermissionMask.All, Util.UnixTimeSinceEpoch());
}
@ -1025,6 +1027,7 @@ namespace OpenSim.Region.Framework.Scenes
agentItem.ID = UUID.Random();
agentItem.CreatorId = taskItem.CreatorID.ToString();
agentItem.CreatorData = taskItem.CreatorData;
agentItem.Owner = destAgent;
agentItem.AssetID = taskItem.AssetID;
agentItem.Description = taskItem.Description;
@ -1226,6 +1229,7 @@ namespace OpenSim.Region.Framework.Scenes
destTaskItem.ItemID = UUID.Random();
destTaskItem.CreatorID = srcTaskItem.CreatorID;
destTaskItem.CreatorData = srcTaskItem.CreatorData;
destTaskItem.AssetID = srcTaskItem.AssetID;
destTaskItem.GroupID = destPart.GroupID;
destTaskItem.OwnerID = destPart.OwnerID;
@ -1638,6 +1642,7 @@ namespace OpenSim.Region.Framework.Scenes
destTaskItem.ItemID = UUID.Random();
destTaskItem.CreatorID = srcTaskItem.CreatorID;
destTaskItem.CreatorData = srcTaskItem.CreatorData;
destTaskItem.AssetID = srcTaskItem.AssetID;
destTaskItem.GroupID = destPart.GroupID;
destTaskItem.OwnerID = destPart.OwnerID;
@ -1844,6 +1849,7 @@ namespace OpenSim.Region.Framework.Scenes
InventoryItemBase item = new InventoryItemBase();
item.CreatorId = grp.RootPart.CreatorID.ToString();
item.CreatorData = grp.RootPart.CreatorData;
item.Owner = remoteClient.AgentId;
item.ID = UUID.Random();
item.AssetID = asset.FullID;

View File

@ -462,22 +462,6 @@ namespace OpenSim.Region.Framework.Scenes
);
}
public void HandleUUIDNameRequest(UUID uuid, IClientAPI remote_client)
{
if (LibraryService != null && (LibraryService.LibraryRootFolder.Owner == uuid))
{
remote_client.SendNameReply(uuid, "Mr", "OpenSim");
}
else
{
string[] names = GetUserNames(uuid);
if (names.Length == 2)
{
remote_client.SendNameReply(uuid, names[0], names[1]);
}
}
}
/// <summary>
/// Handle a fetch inventory request from the client

View File

@ -185,6 +185,8 @@ namespace OpenSim.Region.Framework.Scenes
private Timer m_mapGenerationTimer = new Timer();
private bool m_generateMaptiles;
private Dictionary<UUID, string[]> m_UserNamesCache = new Dictionary<UUID, string[]>();
#endregion Fields
#region Properties
@ -792,36 +794,6 @@ namespace OpenSim.Region.Framework.Scenes
return m_simulatorVersion;
}
public string[] GetUserNames(UUID uuid)
{
string[] returnstring = new string[0];
UserAccount account = UserAccountService.GetUserAccount(RegionInfo.ScopeID, uuid);
if (account != null)
{
returnstring = new string[2];
returnstring[0] = account.FirstName;
returnstring[1] = account.LastName;
}
return returnstring;
}
public string GetUserName(UUID uuid)
{
string[] names = GetUserNames(uuid);
if (names.Length == 2)
{
string firstname = names[0];
string lastname = names[1];
return firstname + " " + lastname;
}
return "(hippos)";
}
/// <summary>
/// Another region is up.
///
@ -2808,7 +2780,7 @@ namespace OpenSim.Region.Framework.Scenes
public virtual void SubscribeToClientGridEvents(IClientAPI client)
{
client.OnNameFromUUIDRequest += HandleUUIDNameRequest;
//client.OnNameFromUUIDRequest += HandleUUIDNameRequest;
client.OnMoneyTransferRequest += ProcessMoneyTransferRequest;
client.OnAvatarPickerRequest += ProcessAvatarPickerRequest;
client.OnSetStartLocationRequest += SetHomeRezPoint;
@ -2935,7 +2907,7 @@ namespace OpenSim.Region.Framework.Scenes
public virtual void UnSubscribeToClientGridEvents(IClientAPI client)
{
client.OnNameFromUUIDRequest -= HandleUUIDNameRequest;
//client.OnNameFromUUIDRequest -= HandleUUIDNameRequest;
client.OnMoneyTransferRequest -= ProcessMoneyTransferRequest;
client.OnAvatarPickerRequest -= ProcessAvatarPickerRequest;
client.OnSetStartLocationRequest -= SetHomeRezPoint;
@ -3152,7 +3124,6 @@ namespace OpenSim.Region.Framework.Scenes
List<ulong> regions = new List<ulong>(avatar.KnownChildRegionHandles);
regions.Remove(RegionInfo.RegionHandle);
m_sceneGridService.SendCloseChildAgentConnections(agentID, regions);
}
m_eventManager.TriggerClientClosed(agentID, this);
}
@ -3164,6 +3135,9 @@ namespace OpenSim.Region.Framework.Scenes
m_eventManager.TriggerOnRemovePresence(agentID);
if (avatar != null && (!avatar.IsChildAgent))
avatar.SaveChangedAttachments();
ForEachClient(
delegate(IClientAPI client)
{

View File

@ -259,7 +259,7 @@ namespace OpenSim.Region.Framework.Scenes
protected internal bool AddRestoredSceneObject(
SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates)
{
if (!alreadyPersisted)
if (attachToBackup && (!alreadyPersisted))
{
sceneObject.ForceInventoryPersistence();
sceneObject.HasGroupChanged = true;
@ -282,8 +282,10 @@ namespace OpenSim.Region.Framework.Scenes
/// </returns>
protected internal bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates)
{
// Ensure that we persist this new scene object
sceneObject.HasGroupChanged = true;
// Ensure that we persist this new scene object if it's not an
// attachment
if (attachToBackup)
sceneObject.HasGroupChanged = true;
return AddSceneObject(sceneObject, attachToBackup, sendClientUpdates);
}
@ -1279,8 +1281,13 @@ namespace OpenSim.Region.Framework.Scenes
{
if (group.IsAttachment || (group.RootPart.Shape.PCode == 9 && group.RootPart.Shape.State != 0))
{
if (m_parentScene.AttachmentsModule != null)
m_parentScene.AttachmentsModule.UpdateAttachmentPosition(remoteClient, group, pos);
// Set the new attachment point data in the object
byte attachmentPoint = group.GetAttachmentPoint();
group.UpdateGroupPosition(pos);
group.RootPart.IsAttachment = false;
group.AbsolutePosition = group.RootPart.AttachedPos;
group.SetAttachmentPoint(attachmentPoint);
group.HasGroupChanged = true;
}
else
{

View File

@ -491,13 +491,15 @@ namespace OpenSim.Region.Framework.Scenes
XmlNodeList nodes = doc.GetElementsByTagName("SavedScriptState");
if (nodes.Count > 0)
{
m_savedScriptState = new Dictionary<UUID, string>();
if (m_savedScriptState == null)
m_savedScriptState = new Dictionary<UUID, string>();
foreach (XmlNode node in nodes)
{
if (node.Attributes["UUID"] != null)
{
UUID itemid = new UUID(node.Attributes["UUID"].Value);
m_savedScriptState.Add(itemid, node.InnerXml);
if (itemid != UUID.Zero)
m_savedScriptState[itemid] = node.InnerXml;
}
}
}

View File

@ -435,6 +435,7 @@ namespace OpenSim.Region.Framework.Scenes
private DateTime m_expires;
private DateTime m_rezzed;
private bool m_createSelected = false;
private string m_creatorData = string.Empty;
public UUID CreatorID
{
@ -448,6 +449,61 @@ namespace OpenSim.Region.Framework.Scenes
}
}
public string CreatorData // = <profile url>;<name>
{
get { return m_creatorData; }
set { m_creatorData = value; }
}
/// <summary>
/// Used by the DB layer to retrieve / store the entire user identification.
/// The identification can either be a simple UUID or a string of the form
/// uuid[;profile_url[;name]]
/// </summary>
public string CreatorIdentification
{
get
{
if (m_creatorData != null && m_creatorData != string.Empty)
return _creatorID.ToString() + ';' + m_creatorData;
else
return _creatorID.ToString();
}
set
{
if ((value == null) || (value != null && value == string.Empty))
{
m_creatorData = string.Empty;
return;
}
if (!value.Contains(";")) // plain UUID
{
UUID uuid = UUID.Zero;
UUID.TryParse(value, out uuid);
_creatorID = uuid;
}
else // <uuid>[;<endpoint>[;name]]
{
string name = "Unknown User";
string[] parts = value.Split(';');
if (parts.Length >= 1)
{
UUID uuid = UUID.Zero;
UUID.TryParse(parts[0], out uuid);
_creatorID = uuid;
}
if (parts.Length >= 2)
m_creatorData = parts[1];
if (parts.Length >= 3)
name = parts[2];
m_creatorData += ';' + name;
}
}
}
/// <summary>
/// A relic from when we we thought that prims contained folder objects. In
/// reality, prim == folder

View File

@ -127,8 +127,6 @@ namespace OpenSim.Region.Framework.Scenes
if (0 == m_items.Count)
return;
HasInventoryChanged = true;
m_part.ParentGroup.HasGroupChanged = true;
IList<TaskInventoryItem> items = GetInventoryItems();
m_items.Clear();
@ -144,17 +142,6 @@ namespace OpenSim.Region.Framework.Scenes
{
lock (Items)
{
if (Items.Count == 0)
{
return;
}
HasInventoryChanged = true;
if (m_part.ParentGroup != null)
{
m_part.ParentGroup.HasGroupChanged = true;
}
IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
Items.Clear();
@ -208,8 +195,15 @@ namespace OpenSim.Region.Framework.Scenes
}
}
HasInventoryChanged = true;
m_part.ParentGroup.HasGroupChanged = true;
// Don't let this set the HasGroupChanged flag for attachments
// as this happens during rez and we don't want a new asset
// for each attachment each time
if (!m_part.ParentGroup.RootPart.IsAttachment)
{
HasInventoryChanged = true;
m_part.ParentGroup.HasGroupChanged = true;
}
List<TaskInventoryItem> items = GetInventoryItems();
foreach (TaskInventoryItem item in items)
{
@ -674,13 +668,19 @@ namespace OpenSim.Region.Framework.Scenes
/// <returns>false if the item did not exist, true if the update occurred successfully</returns>
public bool UpdateInventoryItem(TaskInventoryItem item)
{
return UpdateInventoryItem(item, true);
return UpdateInventoryItem(item, true, true);
}
public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents)
{
return UpdateInventoryItem(item, fireScriptEvents, true);
}
public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged)
{
TaskInventoryItem it = GetInventoryItem(item.ItemID);
if (it != null)
{
item.ParentID = m_part.UUID;
item.ParentPartID = m_part.UUID;
@ -702,9 +702,11 @@ namespace OpenSim.Region.Framework.Scenes
if (fireScriptEvents)
m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
HasInventoryChanged = true;
m_part.ParentGroup.HasGroupChanged = true;
if (considerChanged)
{
HasInventoryChanged = true;
m_part.ParentGroup.HasGroupChanged = true;
}
return true;
}
else

View File

@ -3746,5 +3746,28 @@ namespace OpenSim.Region.Framework.Scenes
m_reprioritization_called = false;
}
}
public void SaveChangedAttachments()
{
// Need to copy this list because DetachToInventoryPrep mods it
List<SceneObjectGroup> attachments = new List<SceneObjectGroup>(Attachments.ToArray());
IAttachmentsModule attachmentsModule = m_scene.AttachmentsModule;
if (attachmentsModule != null)
{
foreach (SceneObjectGroup grp in attachments)
{
if (grp.HasGroupChanged) // Resizer scripts?
{
grp.RootPart.IsAttachment = false;
grp.AbsolutePosition = grp.RootPart.AttachedPos;
// grp.DetachToInventoryPrep();
attachmentsModule.UpdateKnownItem(ControllingClient,
grp, grp.GetFromItemID(), grp.OwnerID);
grp.RootPart.IsAttachment = true;
}
}
}
}
}
}

View File

@ -34,6 +34,7 @@ using System.Xml;
using log4net;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
namespace OpenSim.Region.Framework.Scenes.Serialization
@ -46,6 +47,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
public class SceneObjectSerializer
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static IUserManagement m_UserManagement;
/// <summary>
/// Deserialize a scene object from the original xml format
@ -270,6 +273,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
#region SOPXmlProcessors initialization
m_SOPXmlProcessors.Add("AllowedDrop", ProcessAllowedDrop);
m_SOPXmlProcessors.Add("CreatorID", ProcessCreatorID);
m_SOPXmlProcessors.Add("CreatorData", ProcessCreatorData);
m_SOPXmlProcessors.Add("FolderID", ProcessFolderID);
m_SOPXmlProcessors.Add("InventorySerial", ProcessInventorySerial);
m_SOPXmlProcessors.Add("TaskInventory", ProcessTaskInventory);
@ -327,6 +331,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
m_TaskInventoryXmlProcessors.Add("BasePermissions", ProcessTIBasePermissions);
m_TaskInventoryXmlProcessors.Add("CreationDate", ProcessTICreationDate);
m_TaskInventoryXmlProcessors.Add("CreatorID", ProcessTICreatorID);
m_TaskInventoryXmlProcessors.Add("CreatorData", ProcessTICreatorData);
m_TaskInventoryXmlProcessors.Add("Description", ProcessTIDescription);
m_TaskInventoryXmlProcessors.Add("EveryonePermissions", ProcessTIEveryonePermissions);
m_TaskInventoryXmlProcessors.Add("Flags", ProcessTIFlags);
@ -412,6 +417,11 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
obj.CreatorID = ReadUUID(reader, "CreatorID");
}
private static void ProcessCreatorData(SceneObjectPart obj, XmlTextReader reader)
{
obj.CreatorData = reader.ReadElementContentAsString("CreatorData", String.Empty);
}
private static void ProcessFolderID(SceneObjectPart obj, XmlTextReader reader)
{
obj.FolderID = ReadUUID(reader, "FolderID");
@ -698,6 +708,11 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
item.CreatorID = ReadUUID(reader, "CreatorID");
}
private static void ProcessTICreatorData(TaskInventoryItem item, XmlTextReader reader)
{
item.CreatorData = reader.ReadElementContentAsString("CreatorData", String.Empty);
}
private static void ProcessTIDescription(TaskInventoryItem item, XmlTextReader reader)
{
item.Description = reader.ReadElementContentAsString("Description", String.Empty);
@ -735,7 +750,10 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
private static void ProcessTIOldItemID(TaskInventoryItem item, XmlTextReader reader)
{
item.OldItemID = ReadUUID(reader, "OldItemID");
ReadUUID(reader, "OldItemID");
// On deserialization, the old item id MUST BE UUID.Zero!!!!!
// Setting this to the saved value will BREAK script persistence!
// item.OldItemID = ReadUUID(reader, "OldItemID");
}
private static void ProcessTILastOwnerID(TaskInventoryItem item, XmlTextReader reader)
@ -1074,11 +1092,23 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
writer.WriteAttributeString("xmlns:xsd", "http://www.w3.org/2001/XMLSchema");
writer.WriteElementString("AllowedDrop", sop.AllowedDrop.ToString().ToLower());
WriteUUID(writer, "CreatorID", sop.CreatorID, options);
if (sop.CreatorData != null && sop.CreatorData != string.Empty)
writer.WriteElementString("CreatorData", sop.CreatorData);
else if (options.ContainsKey("profile"))
{
if (m_UserManagement == null)
m_UserManagement = sop.ParentGroup.Scene.RequestModuleInterface<IUserManagement>();
string name = m_UserManagement.GetUserName(sop.CreatorID);
writer.WriteElementString("CreatorData", (string)options["profile"] + "/" + sop.CreatorID + ";" + name);
}
WriteUUID(writer, "FolderID", sop.FolderID, options);
writer.WriteElementString("InventorySerial", sop.InventorySerial.ToString());
WriteTaskInventory(writer, sop.TaskInventory, options);
WriteTaskInventory(writer, sop.TaskInventory, options, sop.ParentGroup.Scene);
WriteUUID(writer, "UUID", sop.UUID, options);
writer.WriteElementString("LocalId", sop.LocalId.ToString());
@ -1202,7 +1232,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
writer.WriteElementString(name, flagsStr);
}
static void WriteTaskInventory(XmlTextWriter writer, TaskInventoryDictionary tinv, Dictionary<string, object> options)
static void WriteTaskInventory(XmlTextWriter writer, TaskInventoryDictionary tinv, Dictionary<string, object> options, Scene scene)
{
if (tinv.Count > 0) // otherwise skip this
{
@ -1215,7 +1245,20 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
WriteUUID(writer, "AssetID", item.AssetID, options);
writer.WriteElementString("BasePermissions", item.BasePermissions.ToString());
writer.WriteElementString("CreationDate", item.CreationDate.ToString());
WriteUUID(writer, "CreatorID", item.CreatorID, options);
if (item.CreatorData != null && item.CreatorData != string.Empty)
writer.WriteElementString("CreatorData", item.CreatorData);
else if (options.ContainsKey("profile"))
{
if (m_UserManagement == null)
m_UserManagement = scene.RequestModuleInterface<IUserManagement>();
string name = m_UserManagement.GetUserName(item.CreatorID);
writer.WriteElementString("CreatorData", (string)options["profile"] + "/" + item.CreatorID + ";" + name);
}
writer.WriteElementString("Description", item.Description);
writer.WriteElementString("EveryonePermissions", item.EveryonePermissions.ToString());
writer.WriteElementString("Flags", item.Flags.ToString());

View File

@ -1,104 +0,0 @@
/*
* 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.Reflection;
using System.Text;
using System.Collections;
namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
{
public class FreeSwitchDialplan
{
private static readonly ILog m_log =
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public Hashtable HandleDialplanRequest(string Context, string Realm, Hashtable request)
{
m_log.DebugFormat("[FreeSwitchVoice] HandleDialplanRequest called with {0}",request.ToString());
Hashtable response = new Hashtable();
foreach (DictionaryEntry item in request)
{
m_log.InfoFormat("[FreeSwitchDirectory] requestBody item {0} {1}",item.Key, item.Value);
}
string requestcontext = (string) request["Hunt-Context"];
response["content_type"] = "text/xml";
response["keepalive"] = false;
response["int_response_code"] = 200;
if (Context != String.Empty && Context != requestcontext)
{
m_log.Debug("[FreeSwitchDirectory] returning empty as it's for another context");
response["str_response_string"] = "";
} else {
response["str_response_string"] = String.Format(@"<?xml version=""1.0"" encoding=""utf-8""?>
<document type=""freeswitch/xml"">
<section name=""dialplan"">
<context name=""{0}"">" +
/* <!-- dial via SIP uri -->
<extension name=""sip_uri"">
<condition field=""destination_number"" expression=""^sip:(.*)$"">
<action application=""bridge"" data=""sofia/${use_profile}/$1""/>
<!--<action application=""bridge"" data=""$1""/>-->
</condition>
</extension>*/
@"<extension name=""opensim_conferences"">
<condition field=""destination_number"" expression=""^confctl-(.*)$"">
<action application=""answer""/>
<action application=""conference"" data=""$1-{1}@{0}""/>
</condition>
</extension>
<extension name=""opensim_conf"">
<condition field=""destination_number"" expression=""^conf-(.*)$"">
<action application=""answer""/>
<action application=""conference"" data=""$1-{1}@{0}""/>
</condition>
</extension>
<extension name=""avatar"">
<condition field=""destination_number"" expression=""^(x.*)$"">
<action application=""bridge"" data=""user/$1""/>
</condition>
</extension>
</context>
</section>
</document>", Context, Realm);
}
return response;
}
}
}

View File

@ -1,348 +0,0 @@
/*
* 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.Reflection;
using System.Text;
using System.Collections;
namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
{
public class FreeSwitchDirectory
{
private static readonly ILog m_log =
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public Hashtable HandleDirectoryRequest(string Context, string Realm, Hashtable request)
{
Hashtable response = new Hashtable();
string domain = (string) request["domain"];
if (domain != Realm) {
response["content_type"] = "text/xml";
response["keepalive"] = false;
response["int_response_code"] = 200;
response["str_response_string"] = "";
} else {
m_log.DebugFormat("[FreeSwitchDirectory] HandleDirectoryRequest called with {0}",request.ToString());
// information in the request we might be interested in
// Request 1 sip_auth for users account
//Event-Calling-Function=sofia_reg_parse_auth
//Event-Calling-Line-Number=1494
//action=sip_auth
//sip_user_agent=Vivox-SDK-2.1.3010.6151-Mac%20(Feb-11-2009/16%3A42%3A41)
//sip_auth_username=xhZuXKmRpECyr2AARJYyGgg%3D%3D (==)
//sip_auth_realm=9.20.151.43
//sip_contact_user=xhZuXKmRpECyr2AARJYyGgg%3D%3D (==)
//sip_contact_host=192.168.0.3 // this shouldnt really be a local IP, investigate STUN servers
//sip_to_user=xhZuXKmRpECyr2AARJYyGgg%3D%3D
//sip_to_host=9.20.151.43
//sip_auth_method=REGISTER
//user=xhZuXKmRpECyr2AARJYyGgg%3D%3D
//domain=9.20.151.43
//ip=9.167.220.137 // this is the correct IP rather than sip_contact_host above when through a vpn or NAT setup
foreach (DictionaryEntry item in request)
{
m_log.InfoFormat("[FreeSwitchDirectory] requestBody item {0} {1}", item.Key, item.Value);
}
string eventCallingFunction = (string) request["Event-Calling-Function"];
if (eventCallingFunction == null)
{
eventCallingFunction = "sofia_reg_parse_auth";
}
if (eventCallingFunction.Length == 0)
{
eventCallingFunction = "sofia_reg_parse_auth";
}
if (eventCallingFunction == "sofia_reg_parse_auth")
{
string sipAuthMethod = (string)request["sip_auth_method"];
if (sipAuthMethod == "REGISTER")
{
response = HandleRegister(Context, Realm, request);
}
else if (sipAuthMethod == "INVITE")
{
response = HandleInvite(Context, Realm, request);
}
else
{
m_log.ErrorFormat("[FreeSwitchVoice] HandleDirectoryRequest unknown sip_auth_method {0}",sipAuthMethod);
response["int_response_code"] = 404;
response["content_type"] = "text/xml";
response["str_response_string"] = "";
}
}
else if (eventCallingFunction == "switch_xml_locate_user")
{
response = HandleLocateUser(Realm, request);
}
else if (eventCallingFunction == "user_data_function") // gets called when an avatar to avatar call is made
{
response = HandleLocateUser(Realm, request);
}
else if (eventCallingFunction == "user_outgoing_channel")
{
response = HandleRegister(Context, Realm, request);
}
else if (eventCallingFunction == "config_sofia") // happens once on freeswitch startup
{
response = HandleConfigSofia(Context, Realm, request);
}
else if (eventCallingFunction == "switch_load_network_lists")
{
//response = HandleLoadNetworkLists(request);
response["int_response_code"] = 404;
response["keepalive"] = false;
response["content_type"] = "text/xml";
response["str_response_string"] = "";
}
else
{
m_log.ErrorFormat("[FreeSwitchVoice] HandleDirectoryRequest unknown Event-Calling-Function {0}",eventCallingFunction);
response["int_response_code"] = 404;
response["keepalive"] = false;
response["content_type"] = "text/xml";
response["str_response_string"] = "";
}
}
return response;
}
private Hashtable HandleRegister(string Context, string Realm, Hashtable request)
{
m_log.Info("[FreeSwitchDirectory] HandleRegister called");
// TODO the password we return needs to match that sent in the request, this is hard coded for now
string password = "1234";
string domain = (string) request["domain"];
string user = (string) request["user"];
Hashtable response = new Hashtable();
response["content_type"] = "text/xml";
response["keepalive"] = false;
response["int_response_code"] = 200;
response["str_response_string"] = String.Format(
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" +
"<document type=\"freeswitch/xml\">\r\n" +
"<section name=\"directory\" description=\"User Directory\">\r\n" +
"<domain name=\"{0}\">\r\n" +
"<user id=\"{1}\">\r\n" +
"<params>\r\n" +
"<param name=\"password\" value=\"{2}\" />\r\n" +
"<param name=\"dial-string\" value=\"{{sip_contact_user={1}}}{{presence_id=${{dialed_user}}@${{dialed_domain}}}}${{sofia_contact(${{dialed_user}}@${{dialed_domain}})}}\"/>\r\n" +
"</params>\r\n" +
"<variables>\r\n" +
"<variable name=\"user_context\" value=\"{3}\" />\r\n" +
"<variable name=\"presence_id\" value=\"{1}@{0}\"/>"+
"</variables>\r\n" +
"</user>\r\n" +
"</domain>\r\n" +
"</section>\r\n" +
"</document>\r\n",
domain , user, password, Context);
return response;
}
private Hashtable HandleInvite(string Context, string Realm, Hashtable request)
{
m_log.Info("[FreeSwitchDirectory] HandleInvite called");
// TODO the password we return needs to match that sent in the request, this is hard coded for now
string password = "1234";
string domain = (string) request["domain"];
string user = (string) request["user"];
string sipRequestUser = (string) request["sip_request_user"];
Hashtable response = new Hashtable();
response["content_type"] = "text/xml";
response["keepalive"] = false;
response["int_response_code"] = 200;
response["str_response_string"] = String.Format(
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" +
"<document type=\"freeswitch/xml\">\r\n" +
"<section name=\"directory\" description=\"User Directory\">\r\n" +
"<domain name=\"{0}\">\r\n" +
"<user id=\"{1}\">\r\n" +
"<params>\r\n" +
"<param name=\"password\" value=\"{2}\" />\r\n" +
"<param name=\"dial-string\" value=\"{{sip_contact_user={1}}}{{presence_id=${1}@${{dialed_domain}}}}${{sofia_contact(${1}@${{dialed_domain}})}}\"/>\r\n" +
"</params>\r\n" +
"<variables>\r\n" +
"<variable name=\"user_context\" value=\"{4}\" />\r\n" +
"<variable name=\"presence_id\" value=\"{1}@$${{domain}}\"/>"+
"</variables>\r\n" +
"</user>\r\n" +
"<user id=\"{3}\">\r\n" +
"<params>\r\n" +
"<param name=\"password\" value=\"{2}\" />\r\n" +
"<param name=\"dial-string\" value=\"{{sip_contact_user={1}}}{{presence_id=${3}@${{dialed_domain}}}}${{sofia_contact(${3}@${{dialed_domain}})}}\"/>\r\n" +
"</params>\r\n" +
"<variables>\r\n" +
"<variable name=\"user_context\" value=\"{4}\" />\r\n" +
"<variable name=\"presence_id\" value=\"{3}@$${{domain}}\"/>"+
"</variables>\r\n" +
"</user>\r\n" +
"</domain>\r\n" +
"</section>\r\n" +
"</document>\r\n",
domain , user, password,sipRequestUser, Context);
return response;
}
private Hashtable HandleLocateUser(String Realm, Hashtable request)
{
m_log.Info("[FreeSwitchDirectory] HandleLocateUser called");
// TODO the password we return needs to match that sent in the request, this is hard coded for now
string domain = (string) request["domain"];
string user = (string) request["user"];
Hashtable response = new Hashtable();
response["content_type"] = "text/xml";
response["keepalive"] = false;
response["int_response_code"] = 200;
response["str_response_string"] = String.Format(
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" +
"<document type=\"freeswitch/xml\">\r\n" +
"<section name=\"directory\" description=\"User Directory\">\r\n" +
"<domain name=\"{0}\">\r\n" +
"<params>\r\n" +
"<param name=\"dial-string\" value=\"{{sip_contact_user=${{dialed_user}}}}{{presence_id=${{dialed_user}}@${{dialed_domain}}}}${{sofia_contact(${{dialed_user}}@${{dialed_domain}})}}\"/>\r\n" +
"</params>\r\n" +
"<user id=\"{1}\">\r\n" +
"<variables>\r\n"+
"<variable name=\"default_gateway\" value=\"$${{default_provider}}\"/>\r\n"+
"<variable name=\"presence_id\" value=\"{1}@$${{domain}}\"/>"+
"</variables>\r\n"+
"</user>\r\n" +
"</domain>\r\n" +
"</section>\r\n" +
"</document>\r\n",
domain , user);
return response;
}
private Hashtable HandleConfigSofia(string Context, string Realm, Hashtable request)
{
m_log.Info("[FreeSwitchDirectory] HandleConfigSofia called");
// TODO the password we return needs to match that sent in the request, this is hard coded for now
string domain = (string) request["domain"];
Hashtable response = new Hashtable();
response["content_type"] = "text/xml";
response["keepalive"] = false;
response["int_response_code"] = 200;
response["str_response_string"] = String.Format(
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" +
"<document type=\"freeswitch/xml\">\r\n" +
"<section name=\"directory\" description=\"User Directory\">\r\n" +
"<domain name=\"{0}\">\r\n" +
"<params>\r\n" +
"<param name=\"dial-string\" value=\"{{sip_contact_user=${{dialed_user}}}}{{presence_id=${{dialed_user}}@${{dialed_domain}}}}${{sofia_contact(${{dialed_user}}@${{dialed_domain}})}}\"/>\r\n" +
"</params>\r\n" +
"<groups name=\"default\">\r\n"+
"<users>\r\n"+
"<user id=\"$${{default_provider}}\">\r\n"+
"<gateways>\r\n"+
"<gateway name=\"$${{default_provider}}\">\r\n"+
"<param name=\"username\" value=\"$${{default_provider_username}}\"/>\r\n"+
"<param name=\"password\" value=\"$${{default_provider_password}}\"/>\r\n"+
"<param name=\"from-user\" value=\"$${{default_provider_username}}\"/>\r\n"+
"<param name=\"from-domain\" value=\"$${{default_provider_from_domain}}\"/>\r\n"+
"<param name=\"expire-seconds\" value=\"600\"/>\r\n"+
"<param name=\"register\" value=\"$${{default_provider_register}}\"/>\r\n"+
"<param name=\"retry-seconds\" value=\"30\"/>\r\n"+
"<param name=\"extension\" value=\"$${{default_provider_contact}}\"/>\r\n"+
"<param name=\"contact-params\" value=\"domain_name=$${{domain}}\"/>\r\n"+
"<param name=\"context\" value=\"{1}\"/>\r\n"+
"</gateway>\r\n"+
"</gateways>\r\n"+
"<params>\r\n"+
"<param name=\"password\" value=\"$${{default_provider_password}}\"/>\r\n"+
"</params>\r\n"+
"</user>\r\n"+
"</users>"+
"</groups>\r\n" +
"<variables>\r\n"+
"<variable name=\"default_gateway\" value=\"$${{default_provider}}\"/>\r\n"+
"</variables>\r\n"+
"</domain>\r\n" +
"</section>\r\n" +
"</document>\r\n",
domain, Context);
return response;
}
// private Hashtable HandleLoadNetworkLists(Hashtable request)
// {
// m_log.Info("[FreeSwitchDirectory] HandleLoadNetworkLists called");
//
// // TODO the password we return needs to match that sent in the request, this is hard coded for now
// string domain = (string) request["domain"];
//
// Hashtable response = new Hashtable();
// response["content_type"] = "text/xml";
// response["keepalive"] = false;
// response["int_response_code"] = 200;
// response["str_response_string"] = String.Format(
// "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" +
// "<document type=\"freeswitch/xml\">\r\n" +
// "<section name=\"directory\" description=\"User Directory\">\r\n" +
// "<domain name=\"{0}\">\r\n" +
// "<params>\r\n" +
// "<param name=\"dial-string\" value=\"{{presence_id=${{dialed_user}}@${{dialed_domain}}}}${{sofia_contact(${{dialed_user}}@${{dialed_domain}})}}\"/>\r\n" +
// "</params>\r\n" +
// "<groups name=\"default\"><users/></groups>\r\n" +
// "<variables>\r\n"+
// "<variable name=\"default_gateway\" value=\"$${{default_provider}}\"/>\r\n"+
// "</variables>\r\n"+
// "</domain>\r\n" +
// "</section>\r\n" +
// "</document>\r\n",
// domain);
//
//
// return response;
// }
}
}

View File

@ -37,10 +37,12 @@ using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
using log4net;
using Nini.Config;
using Nwc.XmlRpc;
using OpenSim.Framework;
using Mono.Addins;
using OpenSim.Framework.Capabilities;
using OpenSim.Framework.Servers;
@ -49,28 +51,27 @@ using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using Caps = OpenSim.Framework.Capabilities.Caps;
using System.Text.RegularExpressions;
using OpenSim.Server.Base;
using OpenSim.Services.Interfaces;
using OSDMap = OpenMetaverse.StructuredData.OSDMap;
namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
{
public class FreeSwitchVoiceModule : IRegionModule, IVoiceModule
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "FreeSwitchVoiceModule")]
public class FreeSwitchVoiceModule : INonSharedRegionModule, IVoiceModule
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private bool UseProxy = false;
// Capability string prefixes
private static readonly string m_parcelVoiceInfoRequestPath = "0007/";
private static readonly string m_provisionVoiceAccountRequestPath = "0008/";
private static readonly string m_chatSessionRequestPath = "0009/";
// Control info
private static bool m_WOF = true;
private static bool m_pluginEnabled = false;
private static bool m_Enabled = false;
// FreeSwitch server is going to contact us and ask us all
// sorts of things.
private static string m_freeSwitchServerUser;
private static string m_freeSwitchServerPass;
// SLVoice client will do a GET on this prefix
private static string m_freeSwitchAPIPrefix;
@ -84,143 +85,147 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
private static string m_freeSwitchRealm;
private static string m_freeSwitchSIPProxy;
private static bool m_freeSwitchAttemptUseSTUN;
// private static string m_freeSwitchSTUNServer;
private static string m_freeSwitchEchoServer;
private static int m_freeSwitchEchoPort;
private static string m_freeSwitchDefaultWellKnownIP;
private static int m_freeSwitchDefaultTimeout;
// private static int m_freeSwitchSubscribeRetry;
private static string m_freeSwitchUrlResetPassword;
// private static IPEndPoint m_FreeSwitchServiceIP;
private int m_freeSwitchServicePort;
private uint m_freeSwitchServicePort;
private string m_openSimWellKnownHTTPAddress;
private string m_freeSwitchContext;
private FreeSwitchDirectory m_FreeSwitchDirectory;
private FreeSwitchDialplan m_FreeSwitchDialplan;
private readonly Dictionary<string, string> m_UUIDName = new Dictionary<string, string>();
private Dictionary<string, string> m_ParcelAddress = new Dictionary<string, string>();
private Scene m_scene;
private Scene m_Scene;
private IConfig m_Config;
private IConfig m_config;
private IFreeswitchService m_FreeswitchService;
public void Initialise(Scene scene, IConfigSource config)
public void Initialise(IConfigSource config)
{
m_scene = scene;
m_config = config.Configs["FreeSwitchVoice"];
m_Config = config.Configs["FreeSwitchVoice"];
if (null == m_config)
if (m_Config == null)
{
m_log.Info("[FreeSwitchVoice] no config found, plugin disabled");
return;
}
if (!m_config.GetBoolean("enabled", false))
if (!m_Config.GetBoolean("Enabled", false))
{
m_log.Info("[FreeSwitchVoice] plugin disabled by configuration");
return;
}
// This is only done the FIRST time this method is invoked.
if (m_WOF)
try
{
m_pluginEnabled = true;
m_WOF = false;
string serviceDll = m_Config.GetString("LocalServiceModule",
String.Empty);
try
if (serviceDll == String.Empty)
{
m_freeSwitchServerUser = m_config.GetString("freeswitch_server_user", String.Empty);
m_freeSwitchServerPass = m_config.GetString("freeswitch_server_pass", String.Empty);
m_freeSwitchAPIPrefix = m_config.GetString("freeswitch_api_prefix", String.Empty);
// XXX: get IP address of HTTP server. (This can be this OpenSim server or another, or could be a dedicated grid service or may live on the freeswitch server)
string serviceIP = m_config.GetString("freeswitch_service_server", String.Empty);
int servicePort = m_config.GetInt("freeswitch_service_port", 80);
IPAddress serviceIPAddress = IPAddress.Parse(serviceIP);
// m_FreeSwitchServiceIP = new IPEndPoint(serviceIPAddress, servicePort);
m_freeSwitchServicePort = servicePort;
m_freeSwitchRealm = m_config.GetString("freeswitch_realm", String.Empty);
m_freeSwitchSIPProxy = m_config.GetString("freeswitch_sip_proxy", m_freeSwitchRealm);
m_freeSwitchAttemptUseSTUN = m_config.GetBoolean("freeswitch_attempt_stun", true);
// m_freeSwitchSTUNServer = m_config.GetString("freeswitch_stun_server", m_freeSwitchRealm);
m_freeSwitchEchoServer = m_config.GetString("freeswitch_echo_server", m_freeSwitchRealm);
m_freeSwitchEchoPort = m_config.GetInt("freeswitch_echo_port", 50505);
m_freeSwitchDefaultWellKnownIP = m_config.GetString("freeswitch_well_known_ip", m_freeSwitchRealm);
m_openSimWellKnownHTTPAddress = m_config.GetString("opensim_well_known_http_address", serviceIPAddress.ToString());
m_freeSwitchDefaultTimeout = m_config.GetInt("freeswitch_default_timeout", 5000);
// m_freeSwitchSubscribeRetry = m_config.GetInt("freeswitch_subscribe_retry", 120);
m_freeSwitchUrlResetPassword = m_config.GetString("freeswitch_password_reset_url", String.Empty);
m_freeSwitchContext = m_config.GetString("freeswitch_context", "default");
if (String.IsNullOrEmpty(m_freeSwitchServerUser) ||
String.IsNullOrEmpty(m_freeSwitchServerPass) ||
String.IsNullOrEmpty(m_freeSwitchRealm) ||
String.IsNullOrEmpty(m_freeSwitchAPIPrefix))
{
m_log.Error("[FreeSwitchVoice] plugin mis-configured");
m_log.Info("[FreeSwitchVoice] plugin disabled: incomplete configuration");
return;
}
// set up http request handlers for
// - prelogin: viv_get_prelogin.php
// - signin: viv_signin.php
// - buddies: viv_buddy.php
// - ???: viv_watcher.php
// - signout: viv_signout.php
if (UseProxy)
{
MainServer.Instance.AddHTTPHandler(String.Format("{0}/", m_freeSwitchAPIPrefix),
ForwardProxyRequest);
}
else
{
MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix),
FreeSwitchSLVoiceGetPreloginHTTPHandler);
// RestStreamHandler h = new
// RestStreamHandler("GET",
// String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix), FreeSwitchSLVoiceGetPreloginHTTPHandler);
// MainServer.Instance.AddStreamHandler(h);
MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_signin.php", m_freeSwitchAPIPrefix),
FreeSwitchSLVoiceSigninHTTPHandler);
// set up http request handlers to provide
// on-demand FreeSwitch configuration to
// FreeSwitch's mod_curl_xml
MainServer.Instance.AddHTTPHandler(String.Format("{0}/freeswitch-config", m_freeSwitchAPIPrefix),
FreeSwitchConfigHTTPHandler);
MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_buddy.php", m_freeSwitchAPIPrefix),
FreeSwitchSLVoiceBuddyHTTPHandler);
}
m_log.InfoFormat("[FreeSwitchVoice] using FreeSwitch server {0}", m_freeSwitchRealm);
m_FreeSwitchDirectory = new FreeSwitchDirectory();
m_FreeSwitchDialplan = new FreeSwitchDialplan();
m_pluginEnabled = true;
m_WOF = false;
m_log.Info("[FreeSwitchVoice] plugin enabled");
}
catch (Exception e)
{
m_log.ErrorFormat("[FreeSwitchVoice] plugin initialization failed: {0}", e.Message);
m_log.DebugFormat("[FreeSwitchVoice] plugin initialization failed: {0}", e.ToString());
m_log.Error("[FreeSwitchVoice]: No LocalServiceModule named in section FreeSwitchVoice");
return;
}
Object[] args = new Object[] { config };
m_FreeswitchService = ServerUtils.LoadPlugin<IFreeswitchService>(serviceDll, args);
string jsonConfig = m_FreeswitchService.GetJsonConfig();
m_log.Debug("[FreeSwitchVoice]: Configuration string: " + jsonConfig);
OSDMap map = (OSDMap)OSDParser.DeserializeJson(jsonConfig);
m_freeSwitchAPIPrefix = map["APIPrefix"].AsString();
m_freeSwitchRealm = map["Realm"].AsString();
m_freeSwitchSIPProxy = map["SIPProxy"].AsString();
m_freeSwitchAttemptUseSTUN = map["AttemptUseSTUN"].AsBoolean();
m_freeSwitchEchoServer = map["EchoServer"].AsString();
m_freeSwitchEchoPort = map["EchoPort"].AsInteger();
m_freeSwitchDefaultWellKnownIP = map["DefaultWellKnownIP"].AsString();
m_freeSwitchDefaultTimeout = map["DefaultTimeout"].AsInteger();
m_freeSwitchUrlResetPassword = String.Empty;
m_freeSwitchContext = map["Context"].AsString();
if (String.IsNullOrEmpty(m_freeSwitchRealm) ||
String.IsNullOrEmpty(m_freeSwitchAPIPrefix))
{
m_log.Error("[FreeSwitchVoice] plugin mis-configured");
m_log.Info("[FreeSwitchVoice] plugin disabled: incomplete configuration");
return;
}
// set up http request handlers for
// - prelogin: viv_get_prelogin.php
// - signin: viv_signin.php
// - buddies: viv_buddy.php
// - ???: viv_watcher.php
// - signout: viv_signout.php
MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix),
FreeSwitchSLVoiceGetPreloginHTTPHandler);
// RestStreamHandler h = new
// RestStreamHandler("GET",
// String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix), FreeSwitchSLVoiceGetPreloginHTTPHandler);
// MainServer.Instance.AddStreamHandler(h);
MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_signin.php", m_freeSwitchAPIPrefix),
FreeSwitchSLVoiceSigninHTTPHandler);
MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_buddy.php", m_freeSwitchAPIPrefix),
FreeSwitchSLVoiceBuddyHTTPHandler);
m_log.InfoFormat("[FreeSwitchVoice] using FreeSwitch server {0}", m_freeSwitchRealm);
m_Enabled = true;
m_log.Info("[FreeSwitchVoice] plugin enabled");
}
catch (Exception e)
{
m_log.ErrorFormat("[FreeSwitchVoice] plugin initialization failed: {0}", e.Message);
m_log.DebugFormat("[FreeSwitchVoice] plugin initialization failed: {0}", e.ToString());
return;
}
if (m_pluginEnabled)
// This here is a region module trying to make a global setting.
// Not really a good idea but it's Windows only, so I can't test.
try
{
ServicePointManager.ServerCertificateValidationCallback += CustomCertificateValidation;
}
catch (NotImplementedException)
{
try
{
#pragma warning disable 0612, 0618
// Mono does not implement the ServicePointManager.ServerCertificateValidationCallback yet! Don't remove this!
ServicePointManager.CertificatePolicy = new MonoCert();
#pragma warning restore 0612, 0618
}
catch (Exception)
{
// COmmented multiline spam log message
//m_log.Error("[FreeSwitchVoice]: Certificate validation handler change not supported. You may get ssl certificate validation errors teleporting from your region to some SSL regions.");
}
}
}
public void AddRegion(Scene scene)
{
m_Scene = scene;
// We generate these like this: The region's external host name
// as defined in Regions.ini is a good address to use. It's a
// dotted quad (or should be!) and it can reach this host from
// a client. The port is grabbed from the region's HTTP server.
m_openSimWellKnownHTTPAddress = m_Scene.RegionInfo.ExternalHostName;
m_freeSwitchServicePort = MainServer.Instance.Port;
if (m_Enabled)
{
// we need to capture scene in an anonymous method
// here as we need it later in the callbacks
@ -228,36 +233,21 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
{
OnRegisterCaps(scene, agentID, caps);
};
try
{
ServicePointManager.ServerCertificateValidationCallback += CustomCertificateValidation;
}
catch (NotImplementedException)
{
try
{
#pragma warning disable 0612, 0618
// Mono does not implement the ServicePointManager.ServerCertificateValidationCallback yet! Don't remove this!
ServicePointManager.CertificatePolicy = new MonoCert();
#pragma warning restore 0612, 0618
}
catch (Exception)
{
m_log.Error("[FreeSwitchVoice]: Certificate validation handler change not supported. You may get ssl certificate validation errors teleporting from your region to some SSL regions.");
}
}
}
}
public void PostInitialise()
public void RemoveRegion(Scene scene)
{
if (m_pluginEnabled)
}
public void RegionLoaded(Scene scene)
{
if (m_Enabled)
{
m_log.Info("[FreeSwitchVoice] registering IVoiceModule with the scene");
// register the voice interface for this module, so the script engine can call us
m_scene.RegisterModuleInterface<IVoiceModule>(this);
scene.RegisterModuleInterface<IVoiceModule>(this);
}
}
@ -270,9 +260,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
get { return "FreeSwitchVoiceModule"; }
}
public bool IsSharedModule
public Type ReplaceableInterface
{
get { return true; }
get { return null; }
}
// <summary>
@ -725,46 +715,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
response["int_response_code"] = 200;
return response;
/*
<level0>
<status>OK</status><body><status>Ok</status><cookie_name>lib_session</cookie_name>
* <cookie>xMj1QJSc7TA-G7XqcW6QXAg==:1290551700:050d35c6fef96f132f780d8039ff7592::</cookie>
* <auth_token>xMj1QJSc7TA-G7XqcW6QXAg==:1290551700:050d35c6fef96f132f780d8039ff7592::</auth_token>
* <primary>1</primary>
* <account_id>7449</account_id>
* <displayname>Teravus Ousley</displayname></body></level0>
*/
}
public Hashtable FreeSwitchConfigHTTPHandler(Hashtable request)
{
m_log.DebugFormat("[FreeSwitchVoice] FreeSwitchConfigHTTPHandler called with {0}", (string)request["body"]);
Hashtable response = new Hashtable();
response["str_response_string"] = string.Empty;
// all the params come as NVPs in the request body
Hashtable requestBody = parseRequestBody((string) request["body"]);
// is this a dialplan or directory request
string section = (string) requestBody["section"];
if (section == "directory")
response = m_FreeSwitchDirectory.HandleDirectoryRequest(m_freeSwitchContext, m_freeSwitchRealm, requestBody);
else if (section == "dialplan")
response = m_FreeSwitchDialplan.HandleDialplanRequest(m_freeSwitchContext, m_freeSwitchRealm, requestBody);
else
m_log.WarnFormat("[FreeSwitchVoice]: section was {0}", section);
// XXX: re-generate dialplan:
// - conf == region UUID
// - conf number = region port
// -> TODO Initialise(): keep track of regions via events
// re-generate accounts for all avatars
// -> TODO Initialise(): keep track of avatars via events
Regex normalizeEndLines = new Regex(@"\r\n", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.Multiline);
m_log.DebugFormat("[FreeSwitchVoice] FreeSwitchConfigHTTPHandler return {0}",normalizeEndLines.Replace(((string)response["str_response_string"]), ""));
return response;
}
public Hashtable parseRequestBody(string body)

View File

@ -2983,17 +2983,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if ((item.PermsMask & ScriptBaseClass.PERMISSION_ATTACH) != 0)
{
SceneObjectGroup grp = m_host.ParentGroup;
UUID itemID = grp.GetFromItemID();
ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
if (attachmentsModule != null)
attachmentsModule.ShowDetachInUserInventory(itemID, presence.ControllingClient);
Util.FireAndForget(DetachWrapper, m_host);
}
}
private void DetachWrapper(object o)
{
SceneObjectPart host = (SceneObjectPart)o;
SceneObjectGroup grp = host.ParentGroup;
UUID itemID = grp.GetFromItemID();
ScenePresence presence = World.GetScenePresence(host.OwnerID);
IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
if (attachmentsModule != null)
attachmentsModule.ShowDetachInUserInventory(itemID, presence.ControllingClient);
}
public void llTakeCamera(string avatar)
{
m_host.AddScriptLPS(1);
@ -8742,24 +8750,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
switch (data)
{
case 5: // DATA_SIM_POS
case ScriptBaseClass.DATA_SIM_POS:
if (info == null)
{
ScriptSleep(1000);
return UUID.Zero.ToString();
}
reply = new LSL_Vector(
info.RegionLocX * Constants.RegionSize,
info.RegionLocY * Constants.RegionSize,
info.RegionLocX,
info.RegionLocY,
0).ToString();
break;
case 6: // DATA_SIM_STATUS
case ScriptBaseClass.DATA_SIM_STATUS:
if (info != null)
reply = "up"; // Duh!
else
reply = "unknown";
break;
case 7: // DATA_SIM_RATING
case ScriptBaseClass.DATA_SIM_RATING:
if (info == null)
{
ScriptSleep(1000);
@ -8775,7 +8783,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
else
reply = "UNKNOWN";
break;
case 128:
case ScriptBaseClass.DATA_SIM_RELEASE:
if (ossl != null)
ossl.CheckThreatLevel(ThreatLevel.High, "llRequestSimulatorData");
reply = "OpenSim";

View File

@ -639,6 +639,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
//
CheckThreatLevel(ThreatLevel.High, "osTeleportAgent");
TeleportAgent(agent, regionName, position, lookat);
}
private void TeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat)
{
m_host.AddScriptLPS(1);
UUID agentId = new UUID();
if (UUID.TryParse(agent, out agentId))
@ -651,7 +656,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
== World.LandChannel.GetLandObject(
presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
{
// Check for hostname , attempt to make a hglink
// and convert the regionName to the target region
if (regionName.Contains(".") && regionName.Contains(":"))
@ -661,7 +665,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (regions != null && regions.Count > 0)
{
GridRegion regInfo = regions[0];
regionName = regInfo.RegionName;
string[] parts = regInfo.RegionName.Split(new char[] { ':' });
if (parts.Length > 2)
regionName = parts[2];
else
regionName = parts[0];
}
}
World.RequestTeleportLocation(presence.ControllingClient, regionName,
@ -674,13 +682,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
}
}
// Teleport functions
public void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat)
{
// High because there is no security check. High griefer potential
//
CheckThreatLevel(ThreatLevel.High, "osTeleportAgent");
TeleportAgent(agent, regionX, regionY, position, lookat);
}
private void TeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat)
{
ulong regionHandle = Util.UIntsToLong(((uint)regionX * (uint)Constants.RegionSize), ((uint)regionY * (uint)Constants.RegionSize));
m_host.AddScriptLPS(1);
@ -709,6 +721,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
osTeleportAgent(agent, World.RegionInfo.RegionName, position, lookat);
}
public void osTeleportOwner(string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat)
{
// Threat level None because this is what can already be done with the World Map in the viewer
CheckThreatLevel(ThreatLevel.None, "osTeleportOwner");
TeleportAgent(m_host.OwnerID.ToString(), regionName, position, lookat);
}
public void osTeleportOwner(LSL_Types.Vector3 position, LSL_Types.Vector3 lookat)
{
osTeleportOwner(World.RegionInfo.RegionName, position, lookat);
}
public void osTeleportOwner(int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat)
{
CheckThreatLevel(ThreatLevel.None, "osTeleportOwner");
TeleportAgent(m_host.OwnerID.ToString(), regionX, regionY, position, lookat);
}
// Functions that get information from the agent itself.
//
// osGetAgentIP - this is used to determine the IP address of
@ -2266,5 +2298,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
});
return result;
}
/// <summary>
/// Convert a unix time to a llGetTimestamp() like string
/// </summary>
/// <param name="unixTime"></param>
/// <returns></returns>
public LSL_String osUnixTimeToTimestamp(long time)
{
CheckThreatLevel(ThreatLevel.VeryLow, "osUnixTimeToTimestamp");
long baseTicks = 621355968000000000;
long tickResolution = 10000000;
long epochTicks = (time * tickResolution) + baseTicks;
DateTime date = new DateTime(epochTicks);
return date.ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ");
}
}
}
}

View File

@ -86,6 +86,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
void osTeleportAgent(string agent, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
void osTeleportOwner(string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
void osTeleportOwner(int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
void osTeleportOwner(LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
// Animation commands
void osAvatarPlayAnimation(string avatar, string animation);
@ -181,5 +184,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
LSL_List osGetAvatarList();
LSL_String osUnixTimeToTimestamp(long time);
}
}

View File

@ -227,6 +227,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
m_OSSL_Functions.osTeleportAgent(agent, position, lookat);
}
public void osTeleportOwner(string regionName, vector position, vector lookat)
{
m_OSSL_Functions.osTeleportOwner(regionName, position, lookat);
}
public void osTeleportOwner(int regionX, int regionY, vector position, vector lookat)
{
m_OSSL_Functions.osTeleportOwner(regionX, regionY, position, lookat);
}
public void osTeleportOwner(vector position, vector lookat)
{
m_OSSL_Functions.osTeleportOwner(position, lookat);
}
// Avatar info functions
public string osGetAgentIP(string agent)
{
@ -663,26 +678,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
{
return m_OSSL_Functions.osGetSimulatorMemory();
}
public void osKickAvatar(string FirstName,string SurName,string alert)
{
m_OSSL_Functions.osKickAvatar(FirstName, SurName, alert);
}
public void osSetSpeed(string UUID, float SpeedModifier)
{
m_OSSL_Functions.osSetSpeed(UUID, SpeedModifier);
}
public void osCauseDamage(string avatar, double damage)
{
m_OSSL_Functions.osCauseDamage(avatar, damage);
}
public void osCauseHealing(string avatar, double healing)
{
m_OSSL_Functions.osCauseHealing(avatar, healing);
}
public LSL_List osGetPrimitiveParams(LSL_Key prim, LSL_List rules)
{
return m_OSSL_Functions.osGetPrimitiveParams(prim, rules);
}
public void osSetPrimitiveParams(LSL_Key prim, LSL_List rules)
{
m_OSSL_Functions.osSetPrimitiveParams(prim, rules);
@ -702,5 +723,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
{
return m_OSSL_Functions.osGetAvatarList();
}
public LSL_String osUnixTimeToTimestamp(long time)
{
return m_OSSL_Functions.osUnixTimeToTimestamp(time);
}
}
}
}

View File

@ -26,18 +26,27 @@
*/
using System;
using System.Collections;
using System.Web;
using System.Reflection;
using Nini.Config;
using OpenSim.Server.Base;
using OpenSim.Services.Interfaces;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Server.Handlers.Base;
using log4net;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
namespace OpenSim.Server.Handlers.Freeswitch
{
public class FreeswitchServerConnector : ServiceConnector
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private IFreeswitchService m_FreeswitchService;
private string m_ConfigName = "FreeswitchService";
protected readonly string m_freeSwitchAPIPrefix = "/fsapi";
public FreeswitchServerConnector(IConfigSource config, IHttpServer server, string configName) :
base(config, server, configName)
@ -59,7 +68,61 @@ namespace OpenSim.Server.Handlers.Freeswitch
m_FreeswitchService =
ServerUtils.LoadPlugin<IFreeswitchService>(freeswitchService, args);
server.AddStreamHandler(new FreeswitchServerGetHandler(m_FreeswitchService));
server.AddHTTPHandler(String.Format("{0}/freeswitch-config", m_freeSwitchAPIPrefix), FreeSwitchConfigHTTPHandler);
server.AddHTTPHandler(String.Format("{0}/region-config", m_freeSwitchAPIPrefix), RegionConfigHTTPHandler);
}
public Hashtable FreeSwitchConfigHTTPHandler(Hashtable request)
{
Hashtable response = new Hashtable();
response["str_response_string"] = string.Empty;
response["content_type"] = "text/plain";
response["keepalive"] = false;
response["int_response_code"] = 500;
Hashtable requestBody = ParseRequestBody((string) request["body"]);
string section = (string) requestBody["section"];
if (section == "directory")
response = m_FreeswitchService.HandleDirectoryRequest(requestBody);
else if (section == "dialplan")
response = m_FreeswitchService.HandleDialplanRequest(requestBody);
else
m_log.WarnFormat("[FreeSwitchVoice]: section was {0}", section);
return response;
}
private Hashtable ParseRequestBody(string body)
{
Hashtable bodyParams = new Hashtable();
// split string
string [] nvps = body.Split(new Char [] {'&'});
foreach (string s in nvps)
{
if (s.Trim() != "")
{
string [] nvp = s.Split(new Char [] {'='});
bodyParams.Add(HttpUtility.UrlDecode(nvp[0]), HttpUtility.UrlDecode(nvp[1]));
}
}
return bodyParams;
}
public Hashtable RegionConfigHTTPHandler(Hashtable request)
{
Hashtable response = new Hashtable();
response["content_type"] = "text/json";
response["keepalive"] = false;
response["int_response_code"] = 200;
response["str_response_string"] = m_FreeswitchService.GetJsonConfig();
return response;
}
}
}

View File

@ -1,72 +0,0 @@
/*
* 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 Nini.Config;
using log4net;
using System;
using System.IO;
using System.Reflection;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using System.Xml.Serialization;
using OpenSim.Server.Base;
using OpenSim.Services.Interfaces;
using OpenSim.Framework;
using OpenSim.Framework.Servers.HttpServer;
namespace OpenSim.Server.Handlers.Freeswitch
{
public class FreeswitchServerGetHandler : BaseStreamHandler
{
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
//private IFreeswitchService m_FreeswitchService;
public FreeswitchServerGetHandler(IFreeswitchService service) :
base("GET", "/api")
{
//m_FreeswitchService = service;
}
public override byte[] Handle(string path, Stream request,
OSHttpRequest httpRequest, OSHttpResponse httpResponse)
{
byte[] result = new byte[0];
string[] p = SplitParams(path);
if (p.Length == 0)
return result;
// Process web request
return result;
}
}
}

View File

@ -601,6 +601,7 @@ namespace OpenSim.Server.Handlers.Asset
ret["BasePermissions"] = item.BasePermissions.ToString();
ret["CreationDate"] = item.CreationDate.ToString();
ret["CreatorId"] = item.CreatorId.ToString();
ret["CreatorData"] = item.CreatorData.ToString();
ret["CurrentPermissions"] = item.CurrentPermissions.ToString();
ret["Description"] = item.Description.ToString();
ret["EveryOnePermissions"] = item.EveryOnePermissions.ToString();
@ -646,6 +647,7 @@ namespace OpenSim.Server.Handlers.Asset
item.InvType = int.Parse(data["InvType"].ToString());
item.Folder = new UUID(data["Folder"].ToString());
item.CreatorId = data["CreatorId"].ToString();
item.CreatorData = data["CreatorData"].ToString();
item.Description = data["Description"].ToString();
item.NextPermissions = uint.Parse(data["NextPermissions"].ToString());
item.CurrentPermissions = uint.Parse(data["CurrentPermissions"].ToString());

View File

@ -162,6 +162,11 @@ namespace OpenSim.Server.Handlers.Simulation
return;
}
if (args.ContainsKey("modified"))
sog.HasGroupChanged = args["modified"].AsBoolean();
else
sog.HasGroupChanged = false;
if ((args["state"] != null) && s.AllowScriptCrossings)
{
stateXmlStr = args["state"].AsString();
@ -243,4 +248,4 @@ namespace OpenSim.Server.Handlers.Simulation
}
}
}
}

View File

@ -0,0 +1,104 @@
/*
* 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.IO;
using System.Collections;
using System.Reflection;
using Nini.Config;
using OpenSim.Framework;
using OpenSim.Framework.Communications;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Services.Interfaces;
using OpenSim.Server.Base;
using OpenMetaverse;
namespace OpenSim.Services.Connectors
{
public class RemoteFreeswitchConnector : IFreeswitchService
{
private static readonly ILog m_log =
LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
private string m_ServerURI = String.Empty;
public RemoteFreeswitchConnector()
{
}
public RemoteFreeswitchConnector(string serverURI)
{
m_ServerURI = serverURI.TrimEnd('/') + "/region-config";
}
public RemoteFreeswitchConnector(IConfigSource source)
{
Initialise(source);
}
public virtual void Initialise(IConfigSource source)
{
IConfig freeswitchConfig = source.Configs["FreeSwitchVoice"];
if (freeswitchConfig == null)
{
m_log.Error("[FREESWITCH CONNECTOR]: FreeSwitchVoice missing from OpenSim.ini");
throw new Exception("Freeswitch connector init error");
}
string serviceURI = freeswitchConfig.GetString("FreeswitchServiceURL",
String.Empty);
if (serviceURI == String.Empty)
{
m_log.Error("[FREESWITCH CONNECTOR]: No FreeswitchServiceURL named in section FreeSwitchVoice");
throw new Exception("Freeswitch connector init error");
}
m_ServerURI = serviceURI.TrimEnd('/') + "/region-config";
}
public Hashtable HandleDirectoryRequest(Hashtable requestBody)
{
// not used here
return new Hashtable();
}
public Hashtable HandleDialplanRequest(Hashtable requestBody)
{
// not used here
return new Hashtable();
}
public string GetJsonConfig()
{
m_log.DebugFormat("[FREESWITCH CONNECTOR]: Requesting config from {0}", m_ServerURI);
return SynchronousRestFormsRequester.MakeRequest("GET",
m_ServerURI, String.Empty);
}
}
}

View File

@ -312,6 +312,7 @@ namespace OpenSim.Services.Connectors
{ "InvType", item.InvType.ToString() },
{ "Folder", item.Folder.ToString() },
{ "CreatorId", item.CreatorId.ToString() },
{ "CreatorData", item.CreatorData.ToString() },
{ "Description", item.Description.ToString() },
{ "NextPermissions", item.NextPermissions.ToString() },
{ "CurrentPermissions", item.CurrentPermissions.ToString() },
@ -344,6 +345,7 @@ namespace OpenSim.Services.Connectors
{ "InvType", item.InvType.ToString() },
{ "Folder", item.Folder.ToString() },
{ "CreatorId", item.CreatorId.ToString() },
{ "CreatorData", item.CreatorData.ToString() },
{ "Description", item.Description.ToString() },
{ "NextPermissions", item.NextPermissions.ToString() },
{ "CurrentPermissions", item.CurrentPermissions.ToString() },
@ -556,6 +558,7 @@ namespace OpenSim.Services.Connectors
item.InvType = int.Parse(data["InvType"].ToString());
item.Folder = new UUID(data["Folder"].ToString());
item.CreatorId = data["CreatorId"].ToString();
item.CreatorData = data["CreatorData"].ToString();
item.Description = data["Description"].ToString();
item.NextPermissions = uint.Parse(data["NextPermissions"].ToString());
item.CurrentPermissions = uint.Parse(data["CurrentPermissions"].ToString());

View File

@ -612,6 +612,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
{ "Name", item.Name },
{ "Description", item.Description },
{ "CreatorID", item.CreatorId },
{ "CreatorData", item.CreatorData },
{ "ContentType", invContentType },
{ "ExtraData", OSDParser.SerializeJsonString(extraData) }
};
@ -776,6 +777,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
invItem.AssetType = SLUtil.ContentTypeToSLAssetType(item["ContentType"].AsString());
invItem.CreationDate = item["CreationDate"].AsInteger();
invItem.CreatorId = item["CreatorID"].AsString();
invItem.CreatorData = item["CreatorData"].AsString();
invItem.CreatorIdAsUuid = item["CreatorID"].AsUUID();
invItem.Description = item["Description"].AsString();
invItem.Folder = item["ParentID"].AsUUID();

View File

@ -506,6 +506,7 @@ namespace OpenSim.Services.Connectors.Simulation
OSDMap args = new OSDMap(2);
args["sog"] = OSD.FromString(sog.ToXml2());
args["extra"] = OSD.FromString(sog.ExtraToXmlString());
args["modified"] = OSD.FromBoolean(sog.HasGroupChanged);
string state = sog.GetStateSnapshot();
if (state.Length > 0)
args["state"] = OSD.FromString(state);

View File

@ -26,6 +26,7 @@
*/
using System;
using System.Text;
using System.Reflection;
using Nini.Config;
using log4net;
@ -33,19 +34,373 @@ using OpenSim.Framework;
using OpenSim.Data;
using OpenSim.Services.Interfaces;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
using System.Collections;
namespace OpenSim.Services.FreeswitchService
{
public class FreeswitchService : FreeswitchServiceBase, IFreeswitchService
{
//private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public FreeswitchService(IConfigSource config) : base(config)
{
// Perform initilialization here
}
public Hashtable HandleDialplanRequest(Hashtable request)
{
m_log.DebugFormat("[FreeSwitchVoice] HandleDialplanRequest called with {0}",request.ToString());
// Implement IFreeswitchService here
Hashtable response = new Hashtable();
foreach (DictionaryEntry item in request)
{
m_log.InfoFormat("[FreeSwitchDirectory] requestBody item {0} {1}",item.Key, item.Value);
}
string requestcontext = (string) request["Hunt-Context"];
response["content_type"] = "text/xml";
response["keepalive"] = false;
response["int_response_code"] = 200;
if (m_freeSwitchContext != String.Empty && m_freeSwitchContext != requestcontext)
{
m_log.Debug("[FreeSwitchDirectory] returning empty as it's for another context");
response["str_response_string"] = "";
}
else
{
response["str_response_string"] = String.Format(@"<?xml version=""1.0"" encoding=""utf-8""?>
<document type=""freeswitch/xml"">
<section name=""dialplan"">
<context name=""{0}"">" +
/* <!-- dial via SIP uri -->
<extension name=""sip_uri"">
<condition field=""destination_number"" expression=""^sip:(.*)$"">
<action application=""bridge"" data=""sofia/${use_profile}/$1""/>
<!--<action application=""bridge"" data=""$1""/>-->
</condition>
</extension>*/
@"<extension name=""opensim_conferences"">
<condition field=""destination_number"" expression=""^confctl-(.*)$"">
<action application=""answer""/>
<action application=""conference"" data=""$1-{1}@{0}""/>
</condition>
</extension>
<extension name=""opensim_conf"">
<condition field=""destination_number"" expression=""^conf-(.*)$"">
<action application=""answer""/>
<action application=""conference"" data=""$1-{1}@{0}""/>
</condition>
</extension>
<extension name=""avatar"">
<condition field=""destination_number"" expression=""^(x.*)$"">
<action application=""bridge"" data=""user/$1""/>
</condition>
</extension>
</context>
</section>
</document>", m_freeSwitchContext, m_freeSwitchRealm);
}
return response;
}
public Hashtable HandleDirectoryRequest(Hashtable request)
{
Hashtable response = new Hashtable();
string domain = (string) request["domain"];
if (domain != m_freeSwitchRealm) {
response["content_type"] = "text/xml";
response["keepalive"] = false;
response["int_response_code"] = 200;
response["str_response_string"] = "";
} else {
m_log.DebugFormat("[FreeSwitchDirectory] HandleDirectoryRequest called with {0}",request.ToString());
// information in the request we might be interested in
// Request 1 sip_auth for users account
//Event-Calling-Function=sofia_reg_parse_auth
//Event-Calling-Line-Number=1494
//action=sip_auth
//sip_user_agent=Vivox-SDK-2.1.3010.6151-Mac%20(Feb-11-2009/16%3A42%3A41)
//sip_auth_username=xhZuXKmRpECyr2AARJYyGgg%3D%3D (==)
//sip_auth_realm=9.20.151.43
//sip_contact_user=xhZuXKmRpECyr2AARJYyGgg%3D%3D (==)
//sip_contact_host=192.168.0.3 // this shouldnt really be a local IP, investigate STUN servers
//sip_to_user=xhZuXKmRpECyr2AARJYyGgg%3D%3D
//sip_to_host=9.20.151.43
//sip_auth_method=REGISTER
//user=xhZuXKmRpECyr2AARJYyGgg%3D%3D
//domain=9.20.151.43
//ip=9.167.220.137 // this is the correct IP rather than sip_contact_host above when through a vpn or NAT setup
foreach (DictionaryEntry item in request)
{
m_log.InfoFormat("[FreeSwitchDirectory] requestBody item {0} {1}", item.Key, item.Value);
}
string eventCallingFunction = (string) request["Event-Calling-Function"];
if (eventCallingFunction == null)
{
eventCallingFunction = "sofia_reg_parse_auth";
}
if (eventCallingFunction.Length == 0)
{
eventCallingFunction = "sofia_reg_parse_auth";
}
if (eventCallingFunction == "sofia_reg_parse_auth")
{
string sipAuthMethod = (string)request["sip_auth_method"];
if (sipAuthMethod == "REGISTER")
{
response = HandleRegister(m_freeSwitchContext, m_freeSwitchRealm, request);
}
else if (sipAuthMethod == "INVITE")
{
response = HandleInvite(m_freeSwitchContext, m_freeSwitchRealm, request);
}
else
{
m_log.ErrorFormat("[FreeSwitchVoice] HandleDirectoryRequest unknown sip_auth_method {0}",sipAuthMethod);
response["int_response_code"] = 404;
response["content_type"] = "text/xml";
response["str_response_string"] = "";
}
}
else if (eventCallingFunction == "switch_xml_locate_user")
{
response = HandleLocateUser(m_freeSwitchRealm, request);
}
else if (eventCallingFunction == "user_data_function") // gets called when an avatar to avatar call is made
{
response = HandleLocateUser(m_freeSwitchRealm, request);
}
else if (eventCallingFunction == "user_outgoing_channel")
{
response = HandleRegister(m_freeSwitchContext, m_freeSwitchRealm, request);
}
else if (eventCallingFunction == "config_sofia") // happens once on freeswitch startup
{
response = HandleConfigSofia(m_freeSwitchContext, m_freeSwitchRealm, request);
}
else if (eventCallingFunction == "switch_load_network_lists")
{
//response = HandleLoadNetworkLists(request);
response["int_response_code"] = 404;
response["keepalive"] = false;
response["content_type"] = "text/xml";
response["str_response_string"] = "";
}
else
{
m_log.ErrorFormat("[FreeSwitchVoice] HandleDirectoryRequest unknown Event-Calling-Function {0}",eventCallingFunction);
response["int_response_code"] = 404;
response["keepalive"] = false;
response["content_type"] = "text/xml";
response["str_response_string"] = "";
}
}
return response;
}
private Hashtable HandleRegister(string Context, string Realm, Hashtable request)
{
m_log.Info("[FreeSwitchDirectory] HandleRegister called");
// TODO the password we return needs to match that sent in the request, this is hard coded for now
string password = "1234";
string domain = (string) request["domain"];
string user = (string) request["user"];
Hashtable response = new Hashtable();
response["content_type"] = "text/xml";
response["keepalive"] = false;
response["int_response_code"] = 200;
response["str_response_string"] = String.Format(
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" +
"<document type=\"freeswitch/xml\">\r\n" +
"<section name=\"directory\" description=\"User Directory\">\r\n" +
"<domain name=\"{0}\">\r\n" +
"<user id=\"{1}\">\r\n" +
"<params>\r\n" +
"<param name=\"password\" value=\"{2}\" />\r\n" +
"<param name=\"dial-string\" value=\"{{sip_contact_user={1}}}{{presence_id=${{dialed_user}}@${{dialed_domain}}}}${{sofia_contact(${{dialed_user}}@${{dialed_domain}})}}\"/>\r\n" +
"</params>\r\n" +
"<variables>\r\n" +
"<variable name=\"user_context\" value=\"{3}\" />\r\n" +
"<variable name=\"presence_id\" value=\"{1}@{0}\"/>"+
"</variables>\r\n" +
"</user>\r\n" +
"</domain>\r\n" +
"</section>\r\n" +
"</document>\r\n",
domain , user, password, Context);
return response;
}
private Hashtable HandleInvite(string Context, string Realm, Hashtable request)
{
m_log.Info("[FreeSwitchDirectory] HandleInvite called");
// TODO the password we return needs to match that sent in the request, this is hard coded for now
string password = "1234";
string domain = (string) request["domain"];
string user = (string) request["user"];
string sipRequestUser = (string) request["sip_request_user"];
Hashtable response = new Hashtable();
response["content_type"] = "text/xml";
response["keepalive"] = false;
response["int_response_code"] = 200;
response["str_response_string"] = String.Format(
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" +
"<document type=\"freeswitch/xml\">\r\n" +
"<section name=\"directory\" description=\"User Directory\">\r\n" +
"<domain name=\"{0}\">\r\n" +
"<user id=\"{1}\">\r\n" +
"<params>\r\n" +
"<param name=\"password\" value=\"{2}\" />\r\n" +
"<param name=\"dial-string\" value=\"{{sip_contact_user={1}}}{{presence_id=${1}@${{dialed_domain}}}}${{sofia_contact(${1}@${{dialed_domain}})}}\"/>\r\n" +
"</params>\r\n" +
"<variables>\r\n" +
"<variable name=\"user_context\" value=\"{4}\" />\r\n" +
"<variable name=\"presence_id\" value=\"{1}@$${{domain}}\"/>"+
"</variables>\r\n" +
"</user>\r\n" +
"<user id=\"{3}\">\r\n" +
"<params>\r\n" +
"<param name=\"password\" value=\"{2}\" />\r\n" +
"<param name=\"dial-string\" value=\"{{sip_contact_user={1}}}{{presence_id=${3}@${{dialed_domain}}}}${{sofia_contact(${3}@${{dialed_domain}})}}\"/>\r\n" +
"</params>\r\n" +
"<variables>\r\n" +
"<variable name=\"user_context\" value=\"{4}\" />\r\n" +
"<variable name=\"presence_id\" value=\"{3}@$${{domain}}\"/>"+
"</variables>\r\n" +
"</user>\r\n" +
"</domain>\r\n" +
"</section>\r\n" +
"</document>\r\n",
domain , user, password,sipRequestUser, Context);
return response;
}
private Hashtable HandleLocateUser(String Realm, Hashtable request)
{
m_log.Info("[FreeSwitchDirectory] HandleLocateUser called");
// TODO the password we return needs to match that sent in the request, this is hard coded for now
string domain = (string) request["domain"];
string user = (string) request["user"];
Hashtable response = new Hashtable();
response["content_type"] = "text/xml";
response["keepalive"] = false;
response["int_response_code"] = 200;
response["str_response_string"] = String.Format(
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" +
"<document type=\"freeswitch/xml\">\r\n" +
"<section name=\"directory\" description=\"User Directory\">\r\n" +
"<domain name=\"{0}\">\r\n" +
"<params>\r\n" +
"<param name=\"dial-string\" value=\"{{sip_contact_user=${{dialed_user}}}}{{presence_id=${{dialed_user}}@${{dialed_domain}}}}${{sofia_contact(${{dialed_user}}@${{dialed_domain}})}}\"/>\r\n" +
"</params>\r\n" +
"<user id=\"{1}\">\r\n" +
"<variables>\r\n"+
"<variable name=\"default_gateway\" value=\"$${{default_provider}}\"/>\r\n"+
"<variable name=\"presence_id\" value=\"{1}@$${{domain}}\"/>"+
"</variables>\r\n"+
"</user>\r\n" +
"</domain>\r\n" +
"</section>\r\n" +
"</document>\r\n",
domain , user);
return response;
}
private Hashtable HandleConfigSofia(string Context, string Realm, Hashtable request)
{
m_log.Info("[FreeSwitchDirectory] HandleConfigSofia called");
// TODO the password we return needs to match that sent in the request, this is hard coded for now
string domain = (string) request["domain"];
Hashtable response = new Hashtable();
response["content_type"] = "text/xml";
response["keepalive"] = false;
response["int_response_code"] = 200;
response["str_response_string"] = String.Format(
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" +
"<document type=\"freeswitch/xml\">\r\n" +
"<section name=\"directory\" description=\"User Directory\">\r\n" +
"<domain name=\"{0}\">\r\n" +
"<params>\r\n" +
"<param name=\"dial-string\" value=\"{{sip_contact_user=${{dialed_user}}}}{{presence_id=${{dialed_user}}@${{dialed_domain}}}}${{sofia_contact(${{dialed_user}}@${{dialed_domain}})}}\"/>\r\n" +
"</params>\r\n" +
"<groups name=\"default\">\r\n"+
"<users>\r\n"+
"<user id=\"$${{default_provider}}\">\r\n"+
"<gateways>\r\n"+
"<gateway name=\"$${{default_provider}}\">\r\n"+
"<param name=\"username\" value=\"$${{default_provider_username}}\"/>\r\n"+
"<param name=\"password\" value=\"$${{default_provider_password}}\"/>\r\n"+
"<param name=\"from-user\" value=\"$${{default_provider_username}}\"/>\r\n"+
"<param name=\"from-domain\" value=\"$${{default_provider_from_domain}}\"/>\r\n"+
"<param name=\"expire-seconds\" value=\"600\"/>\r\n"+
"<param name=\"register\" value=\"$${{default_provider_register}}\"/>\r\n"+
"<param name=\"retry-seconds\" value=\"30\"/>\r\n"+
"<param name=\"extension\" value=\"$${{default_provider_contact}}\"/>\r\n"+
"<param name=\"contact-params\" value=\"domain_name=$${{domain}}\"/>\r\n"+
"<param name=\"context\" value=\"{1}\"/>\r\n"+
"</gateway>\r\n"+
"</gateways>\r\n"+
"<params>\r\n"+
"<param name=\"password\" value=\"$${{default_provider_password}}\"/>\r\n"+
"</params>\r\n"+
"</user>\r\n"+
"</users>"+
"</groups>\r\n" +
"<variables>\r\n"+
"<variable name=\"default_gateway\" value=\"$${{default_provider}}\"/>\r\n"+
"</variables>\r\n"+
"</domain>\r\n" +
"</section>\r\n" +
"</document>\r\n",
domain, Context);
return response;
}
public string GetJsonConfig()
{
OSDMap map = new OSDMap(9);
map.Add("Realm", m_freeSwitchRealm);
map.Add("SIPProxy", m_freeSwitchSIPProxy);
map.Add("AttemptUseSTUN", m_freeSwitchAttemptUseSTUN);
map.Add("EchoServer", m_freeSwitchEchoServer);
map.Add("EchoPort", m_freeSwitchEchoPort);
map.Add("DefaultWellKnownIP", m_freeSwitchDefaultWellKnownIP);
map.Add("DefaultTimeout", m_freeSwitchDefaultTimeout);
map.Add("Context", m_freeSwitchContext);
map.Add("APIPrefix", m_freeSwitchAPIPrefix);
return OSDParser.SerializeJsonString(map);
}
}
}

View File

@ -31,11 +31,28 @@ using Nini.Config;
using OpenSim.Framework;
using OpenSim.Services.Interfaces;
using OpenSim.Services.Base;
using log4net;
namespace OpenSim.Services.FreeswitchService
{
public class FreeswitchServiceBase : ServiceBase
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
protected string m_freeSwitchRealm;
protected string m_freeSwitchSIPProxy;
protected bool m_freeSwitchAttemptUseSTUN = false;
protected string m_freeSwitchEchoServer;
protected int m_freeSwitchEchoPort = 50505;
protected string m_freeSwitchDefaultWellKnownIP;
protected int m_freeSwitchDefaultTimeout = 5000;
protected string m_freeSwitchContext = "default";
protected string m_freeSwitchServerUser = "freeswitch";
protected string m_freeSwitchServerPass = "password";
protected readonly string m_freeSwitchAPIPrefix = "/fsapi";
protected bool m_Enabled = false;
public FreeswitchServiceBase(IConfigSource config) : base(config)
{
//
@ -44,7 +61,24 @@ namespace OpenSim.Services.FreeswitchService
IConfig freeswitchConfig = config.Configs["FreeswitchService"];
if (freeswitchConfig != null)
{
// Read config here !!
m_freeSwitchDefaultWellKnownIP = freeswitchConfig.GetString("ServerAddress", String.Empty);
if (m_freeSwitchDefaultWellKnownIP == String.Empty)
{
m_log.Error("[FREESWITCH]: No FreeswitchServerAddress given, can't continue");
return;
}
m_freeSwitchRealm = freeswitchConfig.GetString("Realm", m_freeSwitchDefaultWellKnownIP);
m_freeSwitchSIPProxy = freeswitchConfig.GetString("SIPProxy", m_freeSwitchDefaultWellKnownIP + ":5060");
m_freeSwitchEchoServer = freeswitchConfig.GetString("EchoServer", m_freeSwitchDefaultWellKnownIP);
m_freeSwitchEchoPort = freeswitchConfig.GetInt("EchoPort", m_freeSwitchEchoPort);
m_freeSwitchAttemptUseSTUN = freeswitchConfig.GetBoolean("AttemptSTUN", false); // This may not work
m_freeSwitchDefaultTimeout = freeswitchConfig.GetInt("DefaultTimeout", m_freeSwitchDefaultTimeout);
m_freeSwitchContext = freeswitchConfig.GetString("Context", m_freeSwitchContext);
m_freeSwitchServerUser = freeswitchConfig.GetString("UserName", m_freeSwitchServerUser);
m_freeSwitchServerPass = freeswitchConfig.GetString("Password", m_freeSwitchServerPass);
m_Enabled = true;
}
}
}

View File

@ -27,11 +27,14 @@
using System;
using OpenSim.Framework;
using System.Collections;
namespace OpenSim.Services.Interfaces
{
public interface IFreeswitchService
{
// Place anything the connector eeds to access here!
Hashtable HandleDirectoryRequest(Hashtable requestBody);
Hashtable HandleDialplanRequest(Hashtable requestBody);
string GetJsonConfig();
}
}

View File

@ -524,7 +524,7 @@ namespace OpenSim.Services.InventoryService
newItem.ID = item.inventoryID;
newItem.InvType = item.invType;
newItem.Folder = item.parentFolderID;
newItem.CreatorId = item.creatorID;
newItem.CreatorIdentification = item.creatorID;
newItem.Description = item.inventoryDescription;
newItem.NextPermissions = (uint)item.inventoryNextPermissions;
newItem.CurrentPermissions = (uint)item.inventoryCurrentPermissions;
@ -555,7 +555,7 @@ namespace OpenSim.Services.InventoryService
newItem.inventoryID = item.ID;
newItem.invType = item.InvType;
newItem.parentFolderID = item.Folder;
newItem.creatorID = item.CreatorId;
newItem.creatorID = item.CreatorIdentification;
newItem.inventoryDescription = item.Description;
newItem.inventoryNextPermissions = (int)item.NextPermissions;
newItem.inventoryCurrentPermissions = (int)item.CurrentPermissions;

View File

@ -28,6 +28,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Text.RegularExpressions;
@ -427,12 +428,9 @@ namespace OpenSim.Services.LLLoginService
{
m_log.WarnFormat("[LLOGIN SERVICE]: User {0} {1} does not have a valid home and this grid does not have default locations. Attempting to find random region",
account.FirstName, account.LastName);
defaults = m_GridService.GetRegionsByName(scopeID, "", 1);
if (defaults != null && defaults.Count > 0)
{
region = defaults[0];
region = FindAlternativeRegion(scopeID);
if (region != null)
where = "safe";
}
}
}
@ -459,12 +457,9 @@ namespace OpenSim.Services.LLLoginService
else
{
m_log.Info("[LLOGIN SERVICE]: Last Region Not Found Attempting to find random region");
defaults = m_GridService.GetRegionsByName(scopeID, "", 1);
if (defaults != null && defaults.Count > 0)
{
region = defaults[0];
region = FindAlternativeRegion(scopeID);
if (region != null)
where = "safe";
}
}
}
@ -564,6 +559,31 @@ namespace OpenSim.Services.LLLoginService
}
private GridRegion FindAlternativeRegion(UUID scopeID)
{
List<GridRegion> hyperlinks = null;
List<GridRegion> regions = m_GridService.GetFallbackRegions(scopeID, 1000 * (int)Constants.RegionSize, 1000 * (int)Constants.RegionSize);
if (regions != null && regions.Count > 0)
{
hyperlinks = m_GridService.GetHyperlinks(scopeID);
IEnumerable<GridRegion> availableRegions = regions.Except(hyperlinks);
if (availableRegions.Count() > 0)
return availableRegions.ElementAt(0);
}
// No fallbacks, try to find an arbitrary region that is not a hyperlink
// maxNumber is fixed for now; maybe use some search pattern with increasing maxSize here?
regions = m_GridService.GetRegionsByName(scopeID, "", 10);
if (regions != null && regions.Count > 0)
{
if (hyperlinks == null)
hyperlinks = m_GridService.GetHyperlinks(scopeID);
IEnumerable<GridRegion> availableRegions = regions.Except(hyperlinks);
if (availableRegions.Count() > 0)
return availableRegions.ElementAt(0);
}
return null;
}
private GridRegion FindForeignRegion(string domainName, uint port, string regionName, out GridRegion gatekeeper)
{
m_log.Debug("attempting to findforeignregion " + domainName + ":" + port.ToString() + ":" + regionName);

View File

@ -580,44 +580,33 @@
[FreeSwitchVoice]
;; In order for this to work you need a functioning FreeSWITCH PBX set up.
;; Configuration details at http://opensimulator.org/wiki/Freeswitch_Module
; enabled = false
; Enabled = false
;; FreeSWITCH server is going to contact us and ask us all sorts of things
; freeswitch_server_user = freeswitch
; freeswitch_server_pass = password
; freeswitch_api_prefix = /api
;; You need to load a local service for a standalone, and a remote service
;; for a grid region. Use one of the lines below, as appropriate
; LocalServiceModule = OpenSim.Services.FreeswitchService.dll:FreeswitchService
; LocalServiceModule = OpenSim.Services.Connectors.dll:RemoteFreeswitchConnector
;; external IP address of your OpenSim voice enabled region
;; note: all regions running on same OpenSim.exe will be enabled
; freeswitch_service_server = ip.address.of.your.sim
;; If using a remote module, specify the server URL
; FreeswitchServiceURL = http://my.grid.server:8003/fsapi
;; this should be the same port the region listens on
; freeswitch_service_port = 9000
; freeswitch_realm = ip.address.of.freeswitch.server
; freeswitch_sip_proxy = ip.address.of.freeswitch.server:5060
[FreeswitchService]
;; !!!!!!!!!!!!!!!!!!!!!!!!!!!
;; !!!!!!STANDALONE ONLY!!!!!!
;; !!!!!!!!!!!!!!!!!!!!!!!!!!!
;; IP of your FS server
;ServerAddress = 85.25.142.92
;; STUN = Simple Traversal of UDP through NATs
;; See http://wiki.freeswitch.org/wiki/NAT_Traversal
;; stun.freeswitch.org is not guaranteed to be running so use it in
;; production at your own risk
; freeswitch_attempt_stun = false
; freeswitch_stun_server = ip.address.of.stun.server
; freeswitch_echo_server = ip.address.of.freeswitch.server
; freeswitch_echo_port = 50505
; freeswitch_well_known_ip = ip.address.of.freeswitch.server
;; Type the address of your http server here, hostname is allowed.
;; This is provided so you can specify a hostname
;; This is used by client for account verification. By default, it's the
;; same as the freeswitch service server.
; opensim_well_known_http_address = Address_Of_Your_SIM_HTTP_Server
;; Timeouts
; freeswitch_default_timeout = 5000
; freeswitch_subscribe_retry = 120
;; Misc
; freeswitch_password_reset_url =
;; All other options are - well - optional
; Realm = "127.0.0.1"
; SIPProxy = "127.0.0.1:5060"
; EchoServer = "127.0.0.1"
; EchoPort = 50505
; AttemptSTUN = "false"
; DefaultTimeout = 5000
; Context = "default"
; UserName = "freeswitch"
; Password = "password"
[Groups]
;# {Enabled} {} {Enable groups?} {true false} false

View File

@ -69,6 +69,19 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003
; * This is the configuration for the freeswitch server in grid mode
[FreeswitchService]
LocalServiceModule = "OpenSim.Services.FreeswitchService.dll:FreeswitchService"
;; IP of your FS server
; ServerAddress = 127.0.0.1
;; All other options are - well - optional
; Realm = "127.0.0.1"
; SIPProxy = "127.0.0.1:5060"
; EchoServer = "127.0.0.1"
; EchoPort = 50505
; AttemptSTUN = "false"
; DefaultTimeout = 5000
; Context = "default"
; UserName = "freeswitch"
; Password = "password"
; * This is the new style authentication service. Currently, only MySQL
; * is implemented. "Realm" is the table that is used for user lookup.

View File

@ -1023,6 +1023,7 @@
<ReferencePath>../../../bin/</ReferencePath>
<Reference name="System"/>
<Reference name="OpenMetaverseTypes" path="../../../bin/"/>
<Reference name="OpenMetaverse.StructuredData" path="../../../bin/"/>
<Reference name="OpenMetaverse" path="../../../bin/"/>
<Reference name="OpenSim.Framework"/>
<Reference name="OpenSim.Framework.Console"/>
@ -1214,6 +1215,7 @@
<ReferencePath>../../../bin/</ReferencePath>
<Reference name="System"/>
<Reference name="System.Core"/>
<Reference name="OpenSim.Framework"/>
<Reference name="OpenSim.Framework.Capabilities"/>
<Reference name="OpenSim.Framework.Console"/>