mirror of
https://github.com/opensim/opensim.git
synced 2026-08-08 18:25:33 +08:00
Merge master into teravuswork
This commit is contained in:
@@ -891,10 +891,10 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
|
||||
|
||||
public void Close()
|
||||
{
|
||||
Close(true);
|
||||
Close(true, false);
|
||||
}
|
||||
|
||||
public void Close(bool sendStop)
|
||||
public void Close(bool sendStop, bool force)
|
||||
{
|
||||
Disconnect();
|
||||
}
|
||||
@@ -959,7 +959,8 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
|
||||
|
||||
}
|
||||
|
||||
public void SendChatMessage(string message, byte type, Vector3 fromPos, string fromName, UUID fromAgentID, byte source, byte audible)
|
||||
public void SendChatMessage(
|
||||
string message, byte type, Vector3 fromPos, string fromName, UUID fromAgentID, UUID ownerID, byte source, byte audible)
|
||||
{
|
||||
if (audible > 0 && message.Length > 0)
|
||||
IRC_SendChannelPrivmsg(fromName, message);
|
||||
|
||||
@@ -127,6 +127,9 @@ namespace OpenSim.Region.OptionalModules.Asset
|
||||
}
|
||||
|
||||
string fileName = rawAssetId;
|
||||
|
||||
if (!ConsoleUtil.CheckFileDoesNotExist(MainConsole.Instance, fileName))
|
||||
return;
|
||||
|
||||
using (FileStream fs = new FileStream(fileName, FileMode.CreateNew))
|
||||
{
|
||||
|
||||
@@ -146,7 +146,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments
|
||||
sb.AppendFormat("Attachments for {0}\n", sp.Name);
|
||||
|
||||
ConsoleDisplayTable ct = new ConsoleDisplayTable() { Indent = 2 };
|
||||
ct.Columns.Add(new ConsoleDisplayTableColumn("Attachment Name", 36));
|
||||
ct.Columns.Add(new ConsoleDisplayTableColumn("Attachment Name", 50));
|
||||
ct.Columns.Add(new ConsoleDisplayTableColumn("Local ID", 10));
|
||||
ct.Columns.Add(new ConsoleDisplayTableColumn("Item ID", 36));
|
||||
ct.Columns.Add(new ConsoleDisplayTableColumn("Attach Point", 14));
|
||||
|
||||
@@ -130,37 +130,37 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments
|
||||
SendConsoleOutput(agentID, String.Format("auto_grant_attach_perms set to {0}", val));
|
||||
}
|
||||
|
||||
private void llAttachToAvatarTemp(UUID host, UUID script, int attachmentPoint)
|
||||
private int llAttachToAvatarTemp(UUID host, UUID script, int attachmentPoint)
|
||||
{
|
||||
SceneObjectPart hostPart = m_scene.GetSceneObjectPart(host);
|
||||
|
||||
if (hostPart == null)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
if (hostPart.ParentGroup.IsAttachment)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
IAttachmentsModule attachmentsModule = m_scene.RequestModuleInterface<IAttachmentsModule>();
|
||||
if (attachmentsModule == null)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
TaskInventoryItem item = hostPart.Inventory.GetInventoryItem(script);
|
||||
if (item == null)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
if ((item.PermsMask & 32) == 0) // PERMISSION_ATTACH
|
||||
return;
|
||||
return 0;
|
||||
|
||||
ScenePresence target;
|
||||
if (!m_scene.TryGetScenePresence(item.PermsGranter, out target))
|
||||
return;
|
||||
return 0;
|
||||
|
||||
if (target.UUID != hostPart.ParentGroup.OwnerID)
|
||||
{
|
||||
uint effectivePerms = hostPart.ParentGroup.GetEffectivePermissions();
|
||||
|
||||
if ((effectivePerms & (uint)PermissionMask.Transfer) == 0)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
hostPart.ParentGroup.SetOwnerId(target.UUID);
|
||||
hostPart.ParentGroup.SetRootPartOwner(hostPart.ParentGroup.RootPart, target.UUID, target.ControllingClient.ActiveGroupId);
|
||||
@@ -183,7 +183,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments
|
||||
hostPart.ParentGroup.RootPart.ScheduleFullUpdate();
|
||||
}
|
||||
|
||||
attachmentsModule.AttachObject(target, hostPart.ParentGroup, (uint)attachmentPoint, false, true, true);
|
||||
return attachmentsModule.AttachObject(target, hostPart.ParentGroup, (uint)attachmentPoint, false, true, true) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,12 +231,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
|
||||
if (m_server == null || m_baseNick == null || m_ircChannel == null || m_user == null)
|
||||
throw new Exception("Invalid connector configuration");
|
||||
|
||||
// Generate an initial nickname if randomizing is enabled
|
||||
// Generate an initial nickname
|
||||
|
||||
if (m_randomizeNick)
|
||||
{
|
||||
m_nick = m_baseNick + Util.RandomClass.Next(1, 99);
|
||||
}
|
||||
else
|
||||
m_nick = m_baseNick;
|
||||
|
||||
m_log.InfoFormat("[IRC-Connector-{0}]: Initialization complete", idn);
|
||||
|
||||
|
||||
@@ -546,8 +546,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge
|
||||
c.SenderUUID = UUID.Zero;
|
||||
c.Scene = agent.Scene;
|
||||
|
||||
agent.ControllingClient.SendChatMessage(msg, (byte) ChatTypeEnum.Say, PosOfGod, m_whoami, UUID.Zero,
|
||||
(byte)ChatSourceType.Object, (byte)ChatAudibleLevel.Fully);
|
||||
agent.ControllingClient.SendChatMessage(
|
||||
msg, (byte) ChatTypeEnum.Say, PosOfGod, m_whoami, UUID.Zero, UUID.Zero,
|
||||
(byte)ChatSourceType.Object, (byte)ChatAudibleLevel.Fully);
|
||||
}
|
||||
|
||||
private static void checkStringParameters(XmlRpcRequest request, string[] param)
|
||||
|
||||
@@ -447,7 +447,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
|
||||
// settings allow voice, then whether parcel allows
|
||||
// voice, if all do retrieve or obtain the parcel
|
||||
// voice channel
|
||||
LandData land = scene.GetLandData(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
|
||||
LandData land = scene.GetLandData(avatar.AbsolutePosition);
|
||||
|
||||
//m_log.DebugFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": request: {4}, path: {5}, param: {6}",
|
||||
// scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, request, path, param);
|
||||
|
||||
@@ -623,7 +623,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
|
||||
// settings allow voice, then whether parcel allows
|
||||
// voice, if all do retrieve or obtain the parcel
|
||||
// voice channel
|
||||
LandData land = scene.GetLandData(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
|
||||
LandData land = scene.GetLandData(avatar.AbsolutePosition);
|
||||
|
||||
// m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": request: {4}, path: {5}, param: {6}",
|
||||
// scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, request, path, param);
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using log4net;
|
||||
using Mono.Addins;
|
||||
@@ -36,6 +37,8 @@ using OpenMetaverse.StructuredData;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
|
||||
|
||||
namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
|
||||
{
|
||||
@@ -45,6 +48,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private List<Scene> m_sceneList = new List<Scene>();
|
||||
private IPresenceService m_presenceService;
|
||||
|
||||
private IMessageTransferModule m_msgTransferModule = null;
|
||||
|
||||
@@ -54,6 +58,27 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
|
||||
private bool m_groupMessagingEnabled = false;
|
||||
private bool m_debugEnabled = true;
|
||||
|
||||
/// <summary>
|
||||
/// If enabled, module only tries to send group IMs to online users by querying cached presence information.
|
||||
/// </summary>
|
||||
private bool m_messageOnlineAgentsOnly;
|
||||
|
||||
/// <summary>
|
||||
/// Cache for online users.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Group ID is key, presence information for online members is value.
|
||||
/// Will only be non-null if m_messageOnlineAgentsOnly = true
|
||||
/// We cache here so that group messages don't constantly have to re-request the online user list to avoid
|
||||
/// attempted expensive sending of messages to offline users.
|
||||
/// The tradeoff is that a user that comes online will not receive messages consistently from all other users
|
||||
/// until caches have updated.
|
||||
/// Therefore, we set the cache expiry to just 20 seconds.
|
||||
/// </remarks>
|
||||
private ExpiringCache<UUID, PresenceInfo[]> m_usersOnlineCache;
|
||||
|
||||
private int m_usersOnlineCacheExpirySeconds = 20;
|
||||
|
||||
#region IRegionModuleBase Members
|
||||
|
||||
public void Initialise(IConfigSource config)
|
||||
@@ -83,10 +108,17 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
|
||||
return;
|
||||
}
|
||||
|
||||
m_messageOnlineAgentsOnly = groupsConfig.GetBoolean("MessageOnlineUsersOnly", false);
|
||||
|
||||
if (m_messageOnlineAgentsOnly)
|
||||
m_usersOnlineCache = new ExpiringCache<UUID, PresenceInfo[]>();
|
||||
|
||||
m_debugEnabled = groupsConfig.GetBoolean("DebugEnabled", true);
|
||||
}
|
||||
|
||||
m_log.Info("[GROUPS-MESSAGING]: GroupsMessagingModule starting up");
|
||||
m_log.InfoFormat(
|
||||
"[GROUPS-MESSAGING]: GroupsMessagingModule enabled with MessageOnlineOnly = {0}, DebugEnabled = {1}",
|
||||
m_messageOnlineAgentsOnly, m_debugEnabled);
|
||||
}
|
||||
|
||||
public void AddRegion(Scene scene)
|
||||
@@ -126,6 +158,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_presenceService == null)
|
||||
m_presenceService = scene.PresenceService;
|
||||
|
||||
m_sceneList.Add(scene);
|
||||
|
||||
@@ -207,12 +241,42 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
|
||||
public void SendMessageToGroup(GridInstantMessage im, UUID groupID)
|
||||
{
|
||||
List<GroupMembersData> groupMembers = m_groupData.GetGroupMembers(new UUID(im.fromAgentID), groupID);
|
||||
|
||||
if (m_debugEnabled)
|
||||
m_log.DebugFormat(
|
||||
"[GROUPS-MESSAGING]: SendMessageToGroup called for group {0} with {1} visible members",
|
||||
groupID, groupMembers.Count);
|
||||
|
||||
int groupMembersCount = groupMembers.Count;
|
||||
|
||||
if (m_messageOnlineAgentsOnly)
|
||||
{
|
||||
string[] t1 = groupMembers.ConvertAll<string>(gmd => gmd.AgentID.ToString()).ToArray();
|
||||
|
||||
// We cache in order not to overwhlem the presence service on large grids with many groups. This does
|
||||
// mean that members coming online will not see all group members until after m_usersOnlineCacheExpirySeconds has elapsed.
|
||||
// (assuming this is the same across all grid simulators).
|
||||
PresenceInfo[] onlineAgents;
|
||||
if (!m_usersOnlineCache.TryGetValue(groupID, out onlineAgents))
|
||||
{
|
||||
onlineAgents = m_presenceService.GetAgents(t1);
|
||||
m_usersOnlineCache.Add(groupID, onlineAgents, m_usersOnlineCacheExpirySeconds);
|
||||
}
|
||||
|
||||
HashSet<string> onlineAgentsUuidSet = new HashSet<string>();
|
||||
Array.ForEach<PresenceInfo>(onlineAgents, pi => onlineAgentsUuidSet.Add(pi.UserID));
|
||||
|
||||
groupMembers = groupMembers.Where(gmd => onlineAgentsUuidSet.Contains(gmd.AgentID.ToString())).ToList();
|
||||
|
||||
// if (m_debugEnabled)
|
||||
// m_log.DebugFormat(
|
||||
// "[GROUPS-MESSAGING]: SendMessageToGroup called for group {0} with {1} visible members, {2} online",
|
||||
// groupID, groupMembersCount, groupMembers.Count());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_debugEnabled)
|
||||
m_log.DebugFormat(
|
||||
"[GROUPS-MESSAGING]: SendMessageToGroup called for group {0} with {1} visible members",
|
||||
groupID, groupMembers.Count);
|
||||
}
|
||||
|
||||
int requestStartTick = Environment.TickCount;
|
||||
|
||||
foreach (GroupMembersData member in groupMembers)
|
||||
{
|
||||
if (m_groupData.hasAgentDroppedGroupChatSession(member.AgentID, groupID))
|
||||
@@ -254,6 +318,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
|
||||
ProcessMessageFromGroupSession(msg);
|
||||
}
|
||||
}
|
||||
|
||||
// Temporary for assessing how long it still takes to send messages to large online groups.
|
||||
if (m_messageOnlineAgentsOnly)
|
||||
m_log.DebugFormat(
|
||||
"[GROUPS-MESSAGING]: SendMessageToGroup for group {0} with {1} visible members, {2} online took {3}ms",
|
||||
groupID, groupMembersCount, groupMembers.Count(), Environment.TickCount - requestStartTick);
|
||||
}
|
||||
|
||||
#region SimGridEventHandlers
|
||||
|
||||
@@ -123,7 +123,36 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
|
||||
public void AddRegion(Scene scene)
|
||||
{
|
||||
if (m_groupsEnabled)
|
||||
{
|
||||
scene.RegisterModuleInterface<IGroupsModule>(this);
|
||||
scene.AddCommand(
|
||||
"debug",
|
||||
this,
|
||||
"debug groups verbose",
|
||||
"debug groups verbose <true|false>",
|
||||
"This setting turns on very verbose groups debugging",
|
||||
HandleDebugGroupsVerbose);
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleDebugGroupsVerbose(object modules, string[] args)
|
||||
{
|
||||
if (args.Length < 4)
|
||||
{
|
||||
MainConsole.Instance.Output("Usage: debug groups verbose <true|false>");
|
||||
return;
|
||||
}
|
||||
|
||||
bool verbose = false;
|
||||
if (!bool.TryParse(args[3], out verbose))
|
||||
{
|
||||
MainConsole.Instance.Output("Usage: debug groups verbose <true|false>");
|
||||
return;
|
||||
}
|
||||
|
||||
m_debugEnabled = verbose;
|
||||
|
||||
MainConsole.Instance.OutputFormat("{0} verbose logging set to {1}", Name, m_debugEnabled);
|
||||
}
|
||||
|
||||
public void RegionLoaded(Scene scene)
|
||||
|
||||
@@ -175,14 +175,15 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||
///
|
||||
/// </summary>
|
||||
// -----------------------------------------------------------------
|
||||
public bool CreateStore(string value, out UUID result)
|
||||
public bool CreateStore(string value, ref UUID result)
|
||||
{
|
||||
result = UUID.Zero;
|
||||
if (result == UUID.Zero)
|
||||
result = UUID.Random();
|
||||
|
||||
JsonStore map = null;
|
||||
|
||||
if (! m_enabled) return false;
|
||||
|
||||
UUID uuid = UUID.Random();
|
||||
JsonStore map = null;
|
||||
|
||||
try
|
||||
{
|
||||
@@ -195,9 +196,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||
}
|
||||
|
||||
lock (m_JsonValueStore)
|
||||
m_JsonValueStore.Add(uuid,map);
|
||||
m_JsonValueStore.Add(result,map);
|
||||
|
||||
result = uuid;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -231,7 +231,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||
if (! m_JsonValueStore.TryGetValue(storeID,out map))
|
||||
{
|
||||
m_log.InfoFormat("[JsonStore] Missing store {0}",storeID);
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -227,7 +227,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||
protected UUID JsonCreateStore(UUID hostID, UUID scriptID, string value)
|
||||
{
|
||||
UUID uuid = UUID.Zero;
|
||||
if (! m_store.CreateStore(value, out uuid))
|
||||
if (! m_store.CreateStore(value, ref uuid))
|
||||
GenerateRuntimeError("Failed to create Json store");
|
||||
|
||||
return uuid;
|
||||
|
||||
@@ -821,8 +821,11 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule
|
||||
{
|
||||
if (!CanEdit())
|
||||
return;
|
||||
|
||||
GetSOP().SendSound(asset.ToString(), volume, true, 0, 0, false, false);
|
||||
ISoundModule module = m_rootScene.RequestModuleInterface<ISoundModule>();
|
||||
if (module != null)
|
||||
{
|
||||
module.SendSound(GetSOP().UUID, asset, volume, true, 0, 0, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -181,7 +181,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
|
||||
}
|
||||
}
|
||||
|
||||
void OnOarFileLoaded(Guid requestId, string message)
|
||||
void OnOarFileLoaded(Guid requestId, List<UUID> loadedScenes, string message)
|
||||
{
|
||||
m_oarFileLoading = true;
|
||||
|
||||
|
||||
@@ -1,324 +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 System;
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
using Nini.Config;
|
||||
using log4net;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using Mono.Addins;
|
||||
using OpenMetaverse;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace OpenSim.Region.OptionalModules.Scripting.ScriptModuleComms
|
||||
{
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ScriptModuleCommsModule")]
|
||||
class ScriptModuleCommsModule : INonSharedRegionModule, IScriptModuleComms
|
||||
{
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private Dictionary<string,object> m_constants = new Dictionary<string,object>();
|
||||
|
||||
#region ScriptInvocation
|
||||
protected class ScriptInvocationData
|
||||
{
|
||||
public Delegate ScriptInvocationDelegate { get; private set; }
|
||||
public string FunctionName { get; private set; }
|
||||
public Type[] TypeSignature { get; private set; }
|
||||
public Type ReturnType { get; private set; }
|
||||
|
||||
public ScriptInvocationData(string fname, Delegate fn, Type[] callsig, Type returnsig)
|
||||
{
|
||||
FunctionName = fname;
|
||||
ScriptInvocationDelegate = fn;
|
||||
TypeSignature = callsig;
|
||||
ReturnType = returnsig;
|
||||
}
|
||||
}
|
||||
|
||||
private Dictionary<string,ScriptInvocationData> m_scriptInvocation = new Dictionary<string,ScriptInvocationData>();
|
||||
#endregion
|
||||
|
||||
private IScriptModule m_scriptModule = null;
|
||||
public event ScriptCommand OnScriptCommand;
|
||||
|
||||
#region RegionModuleInterface
|
||||
public void Initialise(IConfigSource config)
|
||||
{
|
||||
}
|
||||
|
||||
public void AddRegion(Scene scene)
|
||||
{
|
||||
scene.RegisterModuleInterface<IScriptModuleComms>(this);
|
||||
}
|
||||
|
||||
public void RemoveRegion(Scene scene)
|
||||
{
|
||||
}
|
||||
|
||||
public void RegionLoaded(Scene scene)
|
||||
{
|
||||
m_scriptModule = scene.RequestModuleInterface<IScriptModule>();
|
||||
|
||||
if (m_scriptModule != null)
|
||||
m_log.Info("[MODULE COMMANDS]: Script engine found, module active");
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "ScriptModuleCommsModule"; }
|
||||
}
|
||||
|
||||
public Type ReplaceableInterface
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ScriptModuleComms
|
||||
|
||||
public void RaiseEvent(UUID script, string id, string module, string command, string k)
|
||||
{
|
||||
ScriptCommand c = OnScriptCommand;
|
||||
|
||||
if (c == null)
|
||||
return;
|
||||
|
||||
c(script, id, module, command, k);
|
||||
}
|
||||
|
||||
public void DispatchReply(UUID script, int code, string text, string k)
|
||||
{
|
||||
if (m_scriptModule == null)
|
||||
return;
|
||||
|
||||
Object[] args = new Object[] {-1, code, text, k};
|
||||
|
||||
m_scriptModule.PostScriptEvent(script, "link_message", args);
|
||||
}
|
||||
|
||||
public void RegisterScriptInvocation(object target, string meth)
|
||||
{
|
||||
MethodInfo mi = target.GetType().GetMethod(meth,
|
||||
BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
|
||||
if (mi == null)
|
||||
{
|
||||
m_log.WarnFormat("[MODULE COMMANDS] Failed to register method {0}",meth);
|
||||
return;
|
||||
}
|
||||
|
||||
RegisterScriptInvocation(target, mi);
|
||||
}
|
||||
|
||||
public void RegisterScriptInvocation(object target, string[] meth)
|
||||
{
|
||||
foreach (string m in meth)
|
||||
RegisterScriptInvocation(target, m);
|
||||
}
|
||||
|
||||
public void RegisterScriptInvocation(object target, MethodInfo mi)
|
||||
{
|
||||
m_log.DebugFormat("[MODULE COMMANDS] Register method {0} from type {1}", mi.Name, target.GetType().Name);
|
||||
|
||||
Type delegateType;
|
||||
var typeArgs = mi.GetParameters()
|
||||
.Select(p => p.ParameterType)
|
||||
.ToList();
|
||||
|
||||
if (mi.ReturnType == typeof(void))
|
||||
{
|
||||
delegateType = Expression.GetActionType(typeArgs.ToArray());
|
||||
}
|
||||
else
|
||||
{
|
||||
typeArgs.Add(mi.ReturnType);
|
||||
delegateType = Expression.GetFuncType(typeArgs.ToArray());
|
||||
}
|
||||
|
||||
Delegate fcall = Delegate.CreateDelegate(delegateType, target, mi);
|
||||
|
||||
lock (m_scriptInvocation)
|
||||
{
|
||||
ParameterInfo[] parameters = fcall.Method.GetParameters ();
|
||||
if (parameters.Length < 2) // Must have two UUID params
|
||||
return;
|
||||
|
||||
// Hide the first two parameters
|
||||
Type[] parmTypes = new Type[parameters.Length - 2];
|
||||
for (int i = 2 ; i < parameters.Length ; i++)
|
||||
parmTypes[i - 2] = parameters[i].ParameterType;
|
||||
m_scriptInvocation[fcall.Method.Name] = new ScriptInvocationData(fcall.Method.Name, fcall, parmTypes, fcall.Method.ReturnType);
|
||||
}
|
||||
}
|
||||
|
||||
public Delegate[] GetScriptInvocationList()
|
||||
{
|
||||
List<Delegate> ret = new List<Delegate>();
|
||||
|
||||
lock (m_scriptInvocation)
|
||||
{
|
||||
foreach (ScriptInvocationData d in m_scriptInvocation.Values)
|
||||
ret.Add(d.ScriptInvocationDelegate);
|
||||
}
|
||||
return ret.ToArray();
|
||||
}
|
||||
|
||||
public string LookupModInvocation(string fname)
|
||||
{
|
||||
lock (m_scriptInvocation)
|
||||
{
|
||||
ScriptInvocationData sid;
|
||||
if (m_scriptInvocation.TryGetValue(fname,out sid))
|
||||
{
|
||||
if (sid.ReturnType == typeof(string))
|
||||
return "modInvokeS";
|
||||
else if (sid.ReturnType == typeof(int))
|
||||
return "modInvokeI";
|
||||
else if (sid.ReturnType == typeof(float))
|
||||
return "modInvokeF";
|
||||
else if (sid.ReturnType == typeof(UUID))
|
||||
return "modInvokeK";
|
||||
else if (sid.ReturnType == typeof(OpenMetaverse.Vector3))
|
||||
return "modInvokeV";
|
||||
else if (sid.ReturnType == typeof(OpenMetaverse.Quaternion))
|
||||
return "modInvokeR";
|
||||
else if (sid.ReturnType == typeof(object[]))
|
||||
return "modInvokeL";
|
||||
|
||||
m_log.WarnFormat("[MODULE COMMANDS] failed to find match for {0} with return type {1}",fname,sid.ReturnType.Name);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Delegate LookupScriptInvocation(string fname)
|
||||
{
|
||||
lock (m_scriptInvocation)
|
||||
{
|
||||
ScriptInvocationData sid;
|
||||
if (m_scriptInvocation.TryGetValue(fname,out sid))
|
||||
return sid.ScriptInvocationDelegate;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Type[] LookupTypeSignature(string fname)
|
||||
{
|
||||
lock (m_scriptInvocation)
|
||||
{
|
||||
ScriptInvocationData sid;
|
||||
if (m_scriptInvocation.TryGetValue(fname,out sid))
|
||||
return sid.TypeSignature;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Type LookupReturnType(string fname)
|
||||
{
|
||||
lock (m_scriptInvocation)
|
||||
{
|
||||
ScriptInvocationData sid;
|
||||
if (m_scriptInvocation.TryGetValue(fname,out sid))
|
||||
return sid.ReturnType;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public object InvokeOperation(UUID hostid, UUID scriptid, string fname, params object[] parms)
|
||||
{
|
||||
List<object> olist = new List<object>();
|
||||
olist.Add(hostid);
|
||||
olist.Add(scriptid);
|
||||
foreach (object o in parms)
|
||||
olist.Add(o);
|
||||
Delegate fn = LookupScriptInvocation(fname);
|
||||
return fn.DynamicInvoke(olist.ToArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Operation to for a region module to register a constant to be used
|
||||
/// by the script engine
|
||||
/// </summary>
|
||||
public void RegisterConstant(string cname, object value)
|
||||
{
|
||||
m_log.DebugFormat("[MODULE COMMANDS] register constant <{0}> with value {1}",cname,value.ToString());
|
||||
lock (m_constants)
|
||||
{
|
||||
m_constants.Add(cname,value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Operation to check for a registered constant
|
||||
/// </summary>
|
||||
public object LookupModConstant(string cname)
|
||||
{
|
||||
// m_log.DebugFormat("[MODULE COMMANDS] lookup constant <{0}>",cname);
|
||||
|
||||
lock (m_constants)
|
||||
{
|
||||
object value = null;
|
||||
if (m_constants.TryGetValue(cname,out value))
|
||||
return value;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get all registered constants
|
||||
/// </summary>
|
||||
public Dictionary<string, object> GetConstants()
|
||||
{
|
||||
Dictionary<string, object> ret = new Dictionary<string, object>();
|
||||
|
||||
lock (m_constants)
|
||||
{
|
||||
foreach (KeyValuePair<string, object> kvp in m_constants)
|
||||
ret[kvp.Key] = kvp.Value;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -148,7 +148,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
||||
OnInstantMessage(this, new GridInstantMessage(m_scene,
|
||||
m_uuid, m_firstname + " " + m_lastname,
|
||||
target, 0, false, message,
|
||||
UUID.Zero, false, Position, new byte[0]));
|
||||
UUID.Zero, false, Position, new byte[0], true));
|
||||
}
|
||||
|
||||
public void SendAgentOffline(UUID[] agentIDs)
|
||||
@@ -607,13 +607,15 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void SendChatMessage(string message, byte type, Vector3 fromPos, string fromName,
|
||||
UUID fromAgentID, byte source, byte audible)
|
||||
public virtual void SendChatMessage(
|
||||
string message, byte type, Vector3 fromPos, string fromName,
|
||||
UUID fromAgentID, UUID ownerID, byte source, byte audible)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void SendChatMessage(byte[] message, byte type, Vector3 fromPos, string fromName,
|
||||
UUID fromAgentID, byte source, byte audible)
|
||||
public virtual void SendChatMessage(
|
||||
byte[] message, byte type, Vector3 fromPos, string fromName,
|
||||
UUID fromAgentID, UUID ownerID, byte source, byte audible)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -909,11 +911,13 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
||||
|
||||
public void Close()
|
||||
{
|
||||
Close(true);
|
||||
Close(true, false);
|
||||
}
|
||||
|
||||
public void Close(bool sendStop)
|
||||
public void Close(bool sendStop, bool force)
|
||||
{
|
||||
// Remove ourselves from the scene
|
||||
m_scene.RemoveClient(AgentId, false);
|
||||
}
|
||||
|
||||
public void Start()
|
||||
|
||||
@@ -117,6 +117,12 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
|
||||
Assert.That(npc, Is.Not.Null);
|
||||
Assert.That(npc.Appearance.Texture.FaceTextures[8].TextureID, Is.EqualTo(originalFace8TextureId));
|
||||
Assert.That(m_umMod.GetUserName(npc.UUID), Is.EqualTo(string.Format("{0} {1}", npc.Firstname, npc.Lastname)));
|
||||
|
||||
IClientAPI client;
|
||||
Assert.That(m_scene.TryGetClient(npcId, out client), Is.True);
|
||||
|
||||
// Have to account for both SP and NPC.
|
||||
Assert.That(m_scene.AuthenticateHandler.GetAgentCircuits().Count, Is.EqualTo(2));
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -136,6 +142,11 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
|
||||
ScenePresence deletedNpc = m_scene.GetScenePresence(npcId);
|
||||
|
||||
Assert.That(deletedNpc, Is.Null);
|
||||
IClientAPI client;
|
||||
Assert.That(m_scene.TryGetClient(npcId, out client), Is.False);
|
||||
|
||||
// Have to account for SP still present.
|
||||
Assert.That(m_scene.AuthenticateHandler.GetAgentCircuits().Count, Is.EqualTo(1));
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
Reference in New Issue
Block a user