Donating Diva OfflineIM as an addon in a single dll, OpenSim.Addons.OpenSim.dll
parent
8b1b8a3921
commit
5e709b087c
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* 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.Collections.Generic;
|
||||||
|
using OpenSim.Data;
|
||||||
|
using OpenMetaverse;
|
||||||
|
|
||||||
|
namespace OpenSim.OfflineIM
|
||||||
|
{
|
||||||
|
public class OfflineIMData
|
||||||
|
{
|
||||||
|
public UUID PrincipalID;
|
||||||
|
public Dictionary<string, string> Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public interface IOfflineIMData
|
||||||
|
{
|
||||||
|
OfflineIMData[] Get(string field, string val);
|
||||||
|
long GetCount(string field, string key);
|
||||||
|
bool Store(OfflineIMData data);
|
||||||
|
bool Delete(string field, string val);
|
||||||
|
void DeleteOld();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Data.MySQL;
|
||||||
|
|
||||||
|
using OpenMetaverse;
|
||||||
|
using MySql.Data.MySqlClient;
|
||||||
|
|
||||||
|
namespace OpenSim.OfflineIM
|
||||||
|
{
|
||||||
|
public class MySQLOfflineIMData : MySQLGenericTableHandler<OfflineIMData>, IOfflineIMData
|
||||||
|
{
|
||||||
|
protected override Assembly Assembly
|
||||||
|
{
|
||||||
|
// WARNING! Moving migrations to this assembly!!!
|
||||||
|
get { return GetType().Assembly; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public MySQLOfflineIMData(string connectionString, string realm)
|
||||||
|
: base(connectionString, realm, "IM_Store")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DeleteOld()
|
||||||
|
{
|
||||||
|
uint now = (uint)Util.UnixTimeSinceEpoch();
|
||||||
|
|
||||||
|
using (MySqlCommand cmd = new MySqlCommand())
|
||||||
|
{
|
||||||
|
cmd.CommandText = String.Format("delete from {0} where TMStamp < ?tstamp", m_Realm);
|
||||||
|
cmd.Parameters.AddWithValue("?tstamp", now - 14 * 24 * 60 * 60); // > 2 weeks old
|
||||||
|
|
||||||
|
ExecuteNonQuery(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,267 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using log4net;
|
||||||
|
using Mono.Addins;
|
||||||
|
using Nini.Config;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Framework.Servers;
|
||||||
|
using OpenSim.Framework.Client;
|
||||||
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
|
using OpenSim.Region.Framework.Scenes;
|
||||||
|
using OpenSim.Services.Interfaces;
|
||||||
|
|
||||||
|
namespace OpenSim.OfflineIM
|
||||||
|
{
|
||||||
|
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "OfflineIMConnectorModule")]
|
||||||
|
public class OfflineIMRegionModule : ISharedRegionModule, IOfflineIMService
|
||||||
|
{
|
||||||
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
private bool m_Enabled = false;
|
||||||
|
private List<Scene> m_SceneList = new List<Scene>();
|
||||||
|
IMessageTransferModule m_TransferModule = null;
|
||||||
|
private bool m_ForwardOfflineGroupMessages = true;
|
||||||
|
|
||||||
|
private IOfflineIMService m_OfflineIMService;
|
||||||
|
|
||||||
|
public void Initialise(IConfigSource config)
|
||||||
|
{
|
||||||
|
IConfig cnf = config.Configs["Messaging"];
|
||||||
|
if (cnf == null)
|
||||||
|
return;
|
||||||
|
if (cnf != null && cnf.GetString("OfflineMessageModule", string.Empty) != Name)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_Enabled = true;
|
||||||
|
|
||||||
|
string serviceLocation = cnf.GetString("OfflineMessageURL", string.Empty);
|
||||||
|
if (serviceLocation == string.Empty)
|
||||||
|
m_OfflineIMService = new OfflineIMService(config);
|
||||||
|
else
|
||||||
|
m_OfflineIMService = new OfflineIMServiceRemoteConnector(serviceLocation);
|
||||||
|
|
||||||
|
m_ForwardOfflineGroupMessages = cnf.GetBoolean("ForwardOfflineGroupMessages", m_ForwardOfflineGroupMessages);
|
||||||
|
m_log.DebugFormat("[OfflineIM.V2]: Offline messages enabled by {0}", Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddRegion(Scene scene)
|
||||||
|
{
|
||||||
|
if (!m_Enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
scene.RegisterModuleInterface<IOfflineIMService>(this);
|
||||||
|
m_SceneList.Add(scene);
|
||||||
|
scene.EventManager.OnNewClient += OnNewClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RegionLoaded(Scene scene)
|
||||||
|
{
|
||||||
|
if (!m_Enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_TransferModule == null)
|
||||||
|
{
|
||||||
|
m_TransferModule = scene.RequestModuleInterface<IMessageTransferModule>();
|
||||||
|
if (m_TransferModule == null)
|
||||||
|
{
|
||||||
|
scene.EventManager.OnNewClient -= OnNewClient;
|
||||||
|
|
||||||
|
m_SceneList.Clear();
|
||||||
|
|
||||||
|
m_log.Error("[OfflineIM.V2]: No message transfer module is enabled. Disabling offline messages");
|
||||||
|
}
|
||||||
|
m_TransferModule.OnUndeliveredMessage += UndeliveredMessage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveRegion(Scene scene)
|
||||||
|
{
|
||||||
|
if (!m_Enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_SceneList.Remove(scene);
|
||||||
|
scene.EventManager.OnNewClient -= OnNewClient;
|
||||||
|
m_TransferModule.OnUndeliveredMessage -= UndeliveredMessage;
|
||||||
|
|
||||||
|
scene.ForEachClient(delegate(IClientAPI client)
|
||||||
|
{
|
||||||
|
client.OnRetrieveInstantMessages -= RetrieveInstantMessages;
|
||||||
|
client.OnMuteListRequest -= OnMuteListRequest;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PostInitialise()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get { return "Offline Message Module V2"; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type ReplaceableInterface
|
||||||
|
{
|
||||||
|
get { return null; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Close()
|
||||||
|
{
|
||||||
|
m_SceneList.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Scene FindScene(UUID agentID)
|
||||||
|
{
|
||||||
|
foreach (Scene s in m_SceneList)
|
||||||
|
{
|
||||||
|
ScenePresence presence = s.GetScenePresence(agentID);
|
||||||
|
if (presence != null && !presence.IsChildAgent)
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IClientAPI FindClient(UUID agentID)
|
||||||
|
{
|
||||||
|
foreach (Scene s in m_SceneList)
|
||||||
|
{
|
||||||
|
ScenePresence presence = s.GetScenePresence(agentID);
|
||||||
|
if (presence != null && !presence.IsChildAgent)
|
||||||
|
return presence.ControllingClient;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnNewClient(IClientAPI client)
|
||||||
|
{
|
||||||
|
client.OnRetrieveInstantMessages += RetrieveInstantMessages;
|
||||||
|
client.OnMuteListRequest += OnMuteListRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RetrieveInstantMessages(IClientAPI client)
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[OfflineIM.V2]: Retrieving stored messages for {0}", client.AgentId);
|
||||||
|
|
||||||
|
List<GridInstantMessage> msglist = m_OfflineIMService.GetMessages(client.AgentId);
|
||||||
|
|
||||||
|
if (msglist == null)
|
||||||
|
m_log.DebugFormat("[OfflineIM.V2]: WARNING null message list.");
|
||||||
|
|
||||||
|
foreach (GridInstantMessage im in msglist)
|
||||||
|
{
|
||||||
|
if (im.dialog == (byte)InstantMessageDialog.InventoryOffered)
|
||||||
|
// send it directly or else the item will be given twice
|
||||||
|
client.SendInstantMessage(im);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Send through scene event manager so all modules get a chance
|
||||||
|
// to look at this message before it gets delivered.
|
||||||
|
//
|
||||||
|
// Needed for proper state management for stored group
|
||||||
|
// invitations
|
||||||
|
//
|
||||||
|
Scene s = FindScene(client.AgentId);
|
||||||
|
if (s != null)
|
||||||
|
s.EventManager.TriggerIncomingInstantMessage(im);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apparently this is needed in order for the viewer to request the IMs.
|
||||||
|
private void OnMuteListRequest(IClientAPI client, uint crc)
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[OfflineIM.V2] Got mute list request for crc {0}", crc);
|
||||||
|
string filename = "mutes" + client.AgentId.ToString();
|
||||||
|
|
||||||
|
IXfer xfer = client.Scene.RequestModuleInterface<IXfer>();
|
||||||
|
if (xfer != null)
|
||||||
|
{
|
||||||
|
xfer.AddNewFile(filename, new Byte[0]);
|
||||||
|
client.SendMuteListUpdate(filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UndeliveredMessage(GridInstantMessage im)
|
||||||
|
{
|
||||||
|
if (im.dialog != (byte)InstantMessageDialog.MessageFromObject &&
|
||||||
|
im.dialog != (byte)InstantMessageDialog.MessageFromAgent &&
|
||||||
|
im.dialog != (byte)InstantMessageDialog.GroupNotice &&
|
||||||
|
im.dialog != (byte)InstantMessageDialog.GroupInvitation &&
|
||||||
|
im.dialog != (byte)InstantMessageDialog.InventoryOffered)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_ForwardOfflineGroupMessages)
|
||||||
|
{
|
||||||
|
if (im.dialog == (byte)InstantMessageDialog.GroupNotice ||
|
||||||
|
im.dialog == (byte)InstantMessageDialog.GroupInvitation)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Scene scene = FindScene(new UUID(im.fromAgentID));
|
||||||
|
if (scene == null)
|
||||||
|
scene = m_SceneList[0];
|
||||||
|
|
||||||
|
string reason = string.Empty;
|
||||||
|
bool success = m_OfflineIMService.StoreMessage(im, out reason);
|
||||||
|
|
||||||
|
if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent)
|
||||||
|
{
|
||||||
|
IClientAPI client = FindClient(new UUID(im.fromAgentID));
|
||||||
|
if (client == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
client.SendInstantMessage(new GridInstantMessage(
|
||||||
|
null, new UUID(im.toAgentID),
|
||||||
|
"System", new UUID(im.fromAgentID),
|
||||||
|
(byte)InstantMessageDialog.MessageFromAgent,
|
||||||
|
"User is not logged in. " +
|
||||||
|
(success ? "Message saved." : "Message not saved: " + reason),
|
||||||
|
false, new Vector3()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#region IOfflineIM
|
||||||
|
|
||||||
|
public List<GridInstantMessage> GetMessages(UUID principalID)
|
||||||
|
{
|
||||||
|
return m_OfflineIMService.GetMessages(principalID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool StoreMessage(GridInstantMessage im, out string reason)
|
||||||
|
{
|
||||||
|
return m_OfflineIMService.StoreMessage(im, out reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using Mono.Addins;
|
||||||
|
|
||||||
|
// General Information about an assembly is controlled through the following
|
||||||
|
// set of attributes. Change these attribute values to modify the information
|
||||||
|
// associated with an assembly.
|
||||||
|
[assembly: AssemblyTitle("OpenSim.Addons.OfflineIM")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("http://opensimulator.org")]
|
||||||
|
[assembly: AssemblyProduct("OpenSim.Addons.OfflineIM")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright (c) OpenSimulator.org Developers")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
// Setting ComVisible to false makes the types in this assembly not visible
|
||||||
|
// to COM components. If you need to access a type in this assembly from
|
||||||
|
// COM, set the ComVisible attribute to true on that type.
|
||||||
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||||
|
[assembly: Guid("a16a9905-4393-4872-9fca-4c81bedbd9f2")]
|
||||||
|
|
||||||
|
// Version information for an assembly consists of the following four values:
|
||||||
|
//
|
||||||
|
// Major Version
|
||||||
|
// Minor Version
|
||||||
|
// Build Number
|
||||||
|
// Revision
|
||||||
|
//
|
||||||
|
[assembly: AssemblyVersion("0.7.5.*")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||||
|
|
||||||
|
[assembly: Addin("OpenSim.OfflineIM", "0.1")]
|
||||||
|
[assembly: AddinDependency("OpenSim", "0.5")]
|
|
@ -0,0 +1,143 @@
|
||||||
|
/*
|
||||||
|
* 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.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Server.Base;
|
||||||
|
using OpenSim.Services.Interfaces;
|
||||||
|
|
||||||
|
using OpenMetaverse;
|
||||||
|
using log4net;
|
||||||
|
using Nini.Config;
|
||||||
|
|
||||||
|
namespace OpenSim.OfflineIM
|
||||||
|
{
|
||||||
|
public class OfflineIMServiceRemoteConnector : IOfflineIMService
|
||||||
|
{
|
||||||
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
private string m_ServerURI = string.Empty;
|
||||||
|
private object m_Lock = new object();
|
||||||
|
|
||||||
|
public OfflineIMServiceRemoteConnector(string url)
|
||||||
|
{
|
||||||
|
m_ServerURI = url;
|
||||||
|
m_log.DebugFormat("[OfflineIM.V2.RemoteConnector]: Offline IM server at {0}", m_ServerURI);
|
||||||
|
}
|
||||||
|
|
||||||
|
public OfflineIMServiceRemoteConnector(IConfigSource config)
|
||||||
|
{
|
||||||
|
IConfig cnf = config.Configs["Messaging"];
|
||||||
|
if (cnf == null)
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("[OfflineIM.V2.RemoteConnector]: Missing Messaging configuration");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_ServerURI = cnf.GetString("OfflineMessageURL", string.Empty);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#region IOfflineIMService
|
||||||
|
public List<GridInstantMessage> GetMessages(UUID principalID)
|
||||||
|
{
|
||||||
|
List<GridInstantMessage> ims = new List<GridInstantMessage>();
|
||||||
|
|
||||||
|
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||||
|
sendData["PrincipalID"] = principalID;
|
||||||
|
Dictionary<string, object> ret = MakeRequest("GET", sendData);
|
||||||
|
|
||||||
|
if (ret == null)
|
||||||
|
return ims;
|
||||||
|
|
||||||
|
if (!ret.ContainsKey("RESULT"))
|
||||||
|
return ims;
|
||||||
|
|
||||||
|
if (ret["RESULT"].ToString() == "NULL")
|
||||||
|
return ims;
|
||||||
|
|
||||||
|
foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
|
||||||
|
{
|
||||||
|
GridInstantMessage m = OfflineIMDataUtils.GridInstantMessage((Dictionary<string, object>)v);
|
||||||
|
ims.Add(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ims;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool StoreMessage(GridInstantMessage im, out string reason)
|
||||||
|
{
|
||||||
|
reason = string.Empty;
|
||||||
|
Dictionary<string, object> sendData = OfflineIMDataUtils.GridInstantMessage(im);
|
||||||
|
|
||||||
|
Dictionary<string, object> ret = MakeRequest("STORE", sendData);
|
||||||
|
|
||||||
|
if (ret == null)
|
||||||
|
{
|
||||||
|
reason = "Bad response from server";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
string result = ret["RESULT"].ToString();
|
||||||
|
if (result == "NULL" || result.ToLower() == "false")
|
||||||
|
{
|
||||||
|
reason = ret["REASON"].ToString();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Make Request
|
||||||
|
|
||||||
|
private Dictionary<string, object> MakeRequest(string method, Dictionary<string, object> sendData)
|
||||||
|
{
|
||||||
|
sendData["METHOD"] = method;
|
||||||
|
|
||||||
|
string reply = string.Empty;
|
||||||
|
lock (m_Lock)
|
||||||
|
reply = SynchronousRestFormsRequester.MakeRequest("POST",
|
||||||
|
m_ServerURI + "/offlineim",
|
||||||
|
ServerUtils.BuildQueryString(sendData));
|
||||||
|
|
||||||
|
Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(
|
||||||
|
reply);
|
||||||
|
|
||||||
|
return replyData;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,215 @@
|
||||||
|
/*
|
||||||
|
* 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.Text;
|
||||||
|
using System.Xml;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using Nini.Config;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Server.Base;
|
||||||
|
using OpenSim.Services.Interfaces;
|
||||||
|
using OpenSim.Framework.Servers.HttpServer;
|
||||||
|
using OpenSim.Server.Handlers.Base;
|
||||||
|
using log4net;
|
||||||
|
using OpenMetaverse;
|
||||||
|
|
||||||
|
namespace OpenSim.OfflineIM
|
||||||
|
{
|
||||||
|
public class OfflineIMServiceRobustConnector : ServiceConnector
|
||||||
|
{
|
||||||
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
private IOfflineIMService m_OfflineIMService;
|
||||||
|
private string m_ConfigName = "Messaging";
|
||||||
|
|
||||||
|
public OfflineIMServiceRobustConnector(IConfigSource config, IHttpServer server, string configName) :
|
||||||
|
base(config, server, configName)
|
||||||
|
{
|
||||||
|
if (configName != String.Empty)
|
||||||
|
m_ConfigName = configName;
|
||||||
|
|
||||||
|
m_log.DebugFormat("[OfflineIM.V2.RobustConnector]: Starting with config name {0}", m_ConfigName);
|
||||||
|
|
||||||
|
m_OfflineIMService = new OfflineIMService(config);
|
||||||
|
|
||||||
|
server.AddStreamHandler(new OfflineIMServicePostHandler(m_OfflineIMService));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class OfflineIMServicePostHandler : BaseStreamHandler
|
||||||
|
{
|
||||||
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
private IOfflineIMService m_OfflineIMService;
|
||||||
|
|
||||||
|
public OfflineIMServicePostHandler(IOfflineIMService service) :
|
||||||
|
base("POST", "/offlineim")
|
||||||
|
{
|
||||||
|
m_OfflineIMService = service;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override byte[] Handle(string path, Stream requestData,
|
||||||
|
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||||
|
{
|
||||||
|
StreamReader sr = new StreamReader(requestData);
|
||||||
|
string body = sr.ReadToEnd();
|
||||||
|
sr.Close();
|
||||||
|
body = body.Trim();
|
||||||
|
|
||||||
|
//m_log.DebugFormat("[XXX]: query String: {0}", body);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Dictionary<string, object> request =
|
||||||
|
ServerUtils.ParseQueryString(body);
|
||||||
|
|
||||||
|
if (!request.ContainsKey("METHOD"))
|
||||||
|
return FailureResult();
|
||||||
|
|
||||||
|
string method = request["METHOD"].ToString();
|
||||||
|
request.Remove("METHOD");
|
||||||
|
|
||||||
|
m_log.DebugFormat("[OfflineIM.V2.Handler]: {0}", method);
|
||||||
|
switch (method)
|
||||||
|
{
|
||||||
|
case "GET":
|
||||||
|
return HandleGet(request);
|
||||||
|
case "STORE":
|
||||||
|
return HandleStore(request);
|
||||||
|
}
|
||||||
|
m_log.DebugFormat("[OFFLINE IM HANDLER]: unknown method request: {0}", method);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[OFFLINE IM HANDLER]: Exception {0}", e.StackTrace);
|
||||||
|
}
|
||||||
|
|
||||||
|
return FailureResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] HandleStore(Dictionary<string, object> request)
|
||||||
|
{
|
||||||
|
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||||
|
|
||||||
|
GridInstantMessage im = OfflineIMDataUtils.GridInstantMessage(request);
|
||||||
|
|
||||||
|
string reason = string.Empty;
|
||||||
|
|
||||||
|
bool success = m_OfflineIMService.StoreMessage(im, out reason);
|
||||||
|
|
||||||
|
result["RESULT"] = success.ToString();
|
||||||
|
if (!success)
|
||||||
|
result["REASON"] = reason;
|
||||||
|
|
||||||
|
string xmlString = ServerUtils.BuildXmlResponse(result);
|
||||||
|
|
||||||
|
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
||||||
|
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] HandleGet(Dictionary<string, object> request)
|
||||||
|
{
|
||||||
|
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||||
|
|
||||||
|
if (!request.ContainsKey("PrincipalID"))
|
||||||
|
NullResult(result, "Bad network data");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UUID principalID = new UUID(request["PrincipalID"].ToString());
|
||||||
|
List<GridInstantMessage> ims = m_OfflineIMService.GetMessages(principalID);
|
||||||
|
|
||||||
|
Dictionary<string, object> dict = new Dictionary<string, object>();
|
||||||
|
int i = 0;
|
||||||
|
foreach (GridInstantMessage m in ims)
|
||||||
|
dict["im-" + i++] = OfflineIMDataUtils.GridInstantMessage(m);
|
||||||
|
|
||||||
|
result["RESULT"] = dict;
|
||||||
|
}
|
||||||
|
|
||||||
|
string xmlString = ServerUtils.BuildXmlResponse(result);
|
||||||
|
|
||||||
|
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
||||||
|
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Helpers
|
||||||
|
|
||||||
|
private void NullResult(Dictionary<string, object> result, string reason)
|
||||||
|
{
|
||||||
|
result["RESULT"] = "NULL";
|
||||||
|
result["REASON"] = reason;
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] FailureResult()
|
||||||
|
{
|
||||||
|
return BoolResult(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] SuccessResult()
|
||||||
|
{
|
||||||
|
return BoolResult(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] BoolResult(bool value)
|
||||||
|
{
|
||||||
|
XmlDocument doc = new XmlDocument();
|
||||||
|
|
||||||
|
XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration,
|
||||||
|
"", "");
|
||||||
|
|
||||||
|
doc.AppendChild(xmlnode);
|
||||||
|
|
||||||
|
XmlElement rootElement = doc.CreateElement("", "ServerResponse",
|
||||||
|
"");
|
||||||
|
|
||||||
|
doc.AppendChild(rootElement);
|
||||||
|
|
||||||
|
XmlElement result = doc.CreateElement("", "RESULT", "");
|
||||||
|
result.AppendChild(doc.CreateTextNode(value.ToString()));
|
||||||
|
|
||||||
|
rootElement.AppendChild(result);
|
||||||
|
|
||||||
|
return DocToBytes(doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] DocToBytes(XmlDocument doc)
|
||||||
|
{
|
||||||
|
MemoryStream ms = new MemoryStream();
|
||||||
|
XmlTextWriter xw = new XmlTextWriter(ms, null);
|
||||||
|
xw.Formatting = Formatting.Indented;
|
||||||
|
doc.WriteTo(xw);
|
||||||
|
xw.Flush();
|
||||||
|
|
||||||
|
return ms.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
:VERSION 1 # --------------------------
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
|
||||||
|
CREATE TABLE `im_offline` (
|
||||||
|
`ID` MEDIUMINT NOT NULL AUTO_INCREMENT,
|
||||||
|
`PrincipalID` char(36) NOT NULL default '',
|
||||||
|
`Message` text NOT NULL,
|
||||||
|
`TMStamp` timestamp NOT NULL,
|
||||||
|
PRIMARY KEY (`ID`),
|
||||||
|
KEY `PrincipalID` (`PrincipalID`)
|
||||||
|
) ENGINE=MyISAM;
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
:VERSION 2 # --------------------------
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
|
||||||
|
INSERT INTO `im_offline` SELECT * from `diva_im_offline`;
|
||||||
|
DROP TABLE `diva_im_offline`;
|
||||||
|
|
||||||
|
COMMIT;
|
|
@ -0,0 +1,131 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
using System.Text;
|
||||||
|
using System.Timers;
|
||||||
|
using System.Xml;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
using log4net;
|
||||||
|
using Nini.Config;
|
||||||
|
|
||||||
|
using OpenMetaverse;
|
||||||
|
using OpenSim.Data;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Services.Interfaces;
|
||||||
|
|
||||||
|
namespace OpenSim.OfflineIM
|
||||||
|
{
|
||||||
|
public class OfflineIMService : OfflineIMServiceBase, IOfflineIMService
|
||||||
|
{
|
||||||
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
private const int MAX_IM = 25;
|
||||||
|
|
||||||
|
private XmlSerializer m_serializer;
|
||||||
|
private static bool m_Initialized = false;
|
||||||
|
|
||||||
|
public OfflineIMService(IConfigSource config)
|
||||||
|
: base(config)
|
||||||
|
{
|
||||||
|
m_serializer = new XmlSerializer(typeof(GridInstantMessage));
|
||||||
|
if (!m_Initialized)
|
||||||
|
{
|
||||||
|
m_Database.DeleteOld();
|
||||||
|
m_Initialized = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<GridInstantMessage> GetMessages(UUID principalID)
|
||||||
|
{
|
||||||
|
List<GridInstantMessage> ims = new List<GridInstantMessage>();
|
||||||
|
|
||||||
|
OfflineIMData[] messages = m_Database.Get("PrincipalID", principalID.ToString());
|
||||||
|
|
||||||
|
if (messages == null || (messages != null && messages.Length == 0))
|
||||||
|
return ims;
|
||||||
|
|
||||||
|
foreach (OfflineIMData m in messages)
|
||||||
|
{
|
||||||
|
using (MemoryStream mstream = new MemoryStream(Encoding.UTF8.GetBytes(m.Data["Message"])))
|
||||||
|
{
|
||||||
|
GridInstantMessage im = (GridInstantMessage)m_serializer.Deserialize(mstream);
|
||||||
|
ims.Add(im);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then, delete them
|
||||||
|
m_Database.Delete("PrincipalID", principalID.ToString());
|
||||||
|
|
||||||
|
return ims;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool StoreMessage(GridInstantMessage im, out string reason)
|
||||||
|
{
|
||||||
|
reason = string.Empty;
|
||||||
|
|
||||||
|
// TODO Check limits
|
||||||
|
UUID principalID = new UUID(im.toAgentID);
|
||||||
|
long count = m_Database.GetCount("PrincipalID", principalID.ToString());
|
||||||
|
if (count >= MAX_IM)
|
||||||
|
{
|
||||||
|
reason = "Number of offline IMs has maxed out";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
string imXml = string.Empty;
|
||||||
|
using (MemoryStream mstream = new MemoryStream())
|
||||||
|
{
|
||||||
|
XmlWriterSettings settings = new XmlWriterSettings();
|
||||||
|
settings.Encoding = Encoding.UTF8;
|
||||||
|
|
||||||
|
using (XmlWriter writer = XmlWriter.Create(mstream, settings))
|
||||||
|
{
|
||||||
|
m_serializer.Serialize(writer, im);
|
||||||
|
writer.Flush();
|
||||||
|
|
||||||
|
mstream.Position = 0;
|
||||||
|
using (StreamReader sreader = new StreamReader(mstream))
|
||||||
|
{
|
||||||
|
imXml = sreader.ReadToEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OfflineIMData data = new OfflineIMData();
|
||||||
|
data.PrincipalID = principalID;
|
||||||
|
data.Data = new Dictionary<string, string>();
|
||||||
|
data.Data["Message"] = imXml;
|
||||||
|
|
||||||
|
return m_Database.Store(data);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,83 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using Nini.Config;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Data;
|
||||||
|
using OpenSim.Services.Interfaces;
|
||||||
|
using OpenSim.Services.Base;
|
||||||
|
|
||||||
|
namespace OpenSim.OfflineIM
|
||||||
|
{
|
||||||
|
public class OfflineIMServiceBase : ServiceBase
|
||||||
|
{
|
||||||
|
protected IOfflineIMData m_Database = null;
|
||||||
|
|
||||||
|
public OfflineIMServiceBase(IConfigSource config)
|
||||||
|
: base(config)
|
||||||
|
{
|
||||||
|
string dllName = String.Empty;
|
||||||
|
string connString = String.Empty;
|
||||||
|
string realm = "im_offline";
|
||||||
|
|
||||||
|
//
|
||||||
|
// Try reading the [DatabaseService] section, if it exists
|
||||||
|
//
|
||||||
|
IConfig dbConfig = config.Configs["DatabaseService"];
|
||||||
|
if (dbConfig != null)
|
||||||
|
{
|
||||||
|
if (dllName == String.Empty)
|
||||||
|
dllName = dbConfig.GetString("StorageProvider", String.Empty);
|
||||||
|
if (connString == String.Empty)
|
||||||
|
connString = dbConfig.GetString("ConnectionString", String.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// [Messaging] section overrides [DatabaseService], if it exists
|
||||||
|
//
|
||||||
|
IConfig imConfig = config.Configs["Messaging"];
|
||||||
|
if (imConfig != null)
|
||||||
|
{
|
||||||
|
dllName = imConfig.GetString("StorageProvider", dllName);
|
||||||
|
connString = imConfig.GetString("ConnectionString", connString);
|
||||||
|
realm = imConfig.GetString("Realm", realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// We tried, but this doesn't exist. We can't proceed.
|
||||||
|
//
|
||||||
|
if (dllName.Equals(String.Empty))
|
||||||
|
throw new Exception("No StorageProvider configured");
|
||||||
|
|
||||||
|
m_Database = LoadPlugin<IOfflineIMData>(dllName, new Object[] { connString, realm });
|
||||||
|
if (m_Database == null)
|
||||||
|
throw new Exception("Could not find a storage interface in the given module " + dllName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -531,14 +531,20 @@
|
||||||
|
|
||||||
|
|
||||||
[Messaging]
|
[Messaging]
|
||||||
;# {OfflineMessageModule} {} {Module to use for offline message storage} {OfflineMessageModule *}
|
;# {OfflineMessageModule} {} {Module to use for offline message storage} {OfflineMessageModule "Offline Message Module V2" *}
|
||||||
;; Module to handle offline messaging. The core module requires an external
|
;; Module to handle offline messaging. The core module requires an external
|
||||||
;; web service to do this. See OpenSim wiki.
|
;; web service to do this. See OpenSim wiki.
|
||||||
; OfflineMessageModule = OfflineMessageModule
|
; OfflineMessageModule = OfflineMessageModule
|
||||||
|
;; Or, alternatively, use this one, which works for both standalones and grids
|
||||||
|
; OfflineMessageModule = "Offline Message Module V2"
|
||||||
|
|
||||||
;# {OfflineMessageURL} {OfflineMessageModule:OfflineMessageModule} {URL of offline messaging service} {}
|
;# {OfflineMessageURL} {OfflineMessageModule:OfflineMessageModule Offline Message Module V2:Offline Message Module V2} {URL of offline messaging service} {}
|
||||||
;; URL of web service for offline message storage
|
;; URL of web service for offline message storage. Leave it commented if your service is local to the sim.
|
||||||
; OfflineMessageURL = http://yourserver/Offline.php
|
; OfflineMessageURL = http://yourserver/Offline.php or http://yourrobustserver:8003
|
||||||
|
|
||||||
|
;# {StorageProvider} {Offline Message Module V2:Offline Message Module V2} {DLL that provides the storage interface} {OpenSim.Addons.OfflineIM}
|
||||||
|
;; For standalones, use the service directly. This is the storage dll.
|
||||||
|
; StorageProvider = OpenSim.Addons.OfflineIM.dll
|
||||||
|
|
||||||
;# {MuteListModule} {OfflineMessageModule:OfflineMessageModule} {} {} MuteListModule
|
;# {MuteListModule} {OfflineMessageModule:OfflineMessageModule} {} {} MuteListModule
|
||||||
;; Mute list handler (not yet implemented). MUST BE SET to allow offline
|
;; Mute list handler (not yet implemented). MUST BE SET to allow offline
|
||||||
|
|
|
@ -51,6 +51,8 @@ GridUserServiceConnector = "8003/OpenSim.Server.Handlers.dll:GridUserServiceConn
|
||||||
FriendsServiceConnector = "8003/OpenSim.Server.Handlers.dll:FriendsServiceConnector"
|
FriendsServiceConnector = "8003/OpenSim.Server.Handlers.dll:FriendsServiceConnector"
|
||||||
MapAddServiceConnector = "8003/OpenSim.Server.Handlers.dll:MapAddServiceConnector"
|
MapAddServiceConnector = "8003/OpenSim.Server.Handlers.dll:MapAddServiceConnector"
|
||||||
MapGetServiceConnector = "8002/OpenSim.Server.Handlers.dll:MapGetServiceConnector"
|
MapGetServiceConnector = "8002/OpenSim.Server.Handlers.dll:MapGetServiceConnector"
|
||||||
|
;; Uncomment this if you want offline IM to work
|
||||||
|
;OfflineIMServiceConnector = "8003/OpenSim.Addons.OfflineIM.dll:OfflineIMServiceRobustConnector"
|
||||||
|
|
||||||
;; Additions for Hypergrid
|
;; Additions for Hypergrid
|
||||||
|
|
||||||
|
@ -545,15 +547,7 @@ HGAssetServiceConnector = "HGAssetService@8002/OpenSim.Server.Handlers.dll:Asset
|
||||||
InGatekeeper = True
|
InGatekeeper = True
|
||||||
|
|
||||||
[Messaging]
|
[Messaging]
|
||||||
; If you have an Offline IM server, set the vars in this section, so that
|
; OfflineIM
|
||||||
; incomming IMs to local users from foreign grids can be saved
|
StorageProvider = "OpenSim.Addons.OfflineIM.dll"
|
||||||
;
|
OfflineIMService = "OpenSim.Addons.OfflineIM.dll:OfflineIMService"
|
||||||
;# {OfflineMessageURL} {OfflineMessageModule:OfflineMessageModule} {URL of offline messaging service} {}
|
|
||||||
;; URL of web service for offline message storage
|
|
||||||
; OfflineMessageURL = http://yourserver/Offline.php
|
|
||||||
|
|
||||||
;; Control whether group messages are forwarded to offline users.
|
|
||||||
;; Default is true.
|
|
||||||
;; This applies to the core groups module (Flotsam) only.
|
|
||||||
; ForwardOfflineGroupMessages = true
|
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,9 @@ GridUserServiceConnector = "8003/OpenSim.Server.Handlers.dll:GridUserServiceConn
|
||||||
FriendsServiceConnector = "8003/OpenSim.Server.Handlers.dll:FriendsServiceConnector"
|
FriendsServiceConnector = "8003/OpenSim.Server.Handlers.dll:FriendsServiceConnector"
|
||||||
MapAddServiceConnector = "8003/OpenSim.Server.Handlers.dll:MapAddServiceConnector"
|
MapAddServiceConnector = "8003/OpenSim.Server.Handlers.dll:MapAddServiceConnector"
|
||||||
MapGetServiceConnector = "8002/OpenSim.Server.Handlers.dll:MapGetServiceConnector"
|
MapGetServiceConnector = "8002/OpenSim.Server.Handlers.dll:MapGetServiceConnector"
|
||||||
|
;; Uncomment this if you want offline IM to work
|
||||||
|
;OfflineIMServiceConnector = "8003/OpenSim.Addons.OfflineIM.dll:OfflineIMServiceRobustConnector"
|
||||||
|
|
||||||
|
|
||||||
; * This is common for all services, it's the network setup for the entire
|
; * This is common for all services, it's the network setup for the entire
|
||||||
; * server instance, if none is specified above
|
; * server instance, if none is specified above
|
||||||
|
@ -329,6 +332,10 @@ MapGetServiceConnector = "8002/OpenSim.Server.Handlers.dll:MapGetServiceConnecto
|
||||||
; HasProxy = false
|
; HasProxy = false
|
||||||
|
|
||||||
|
|
||||||
|
[Messaging]
|
||||||
|
; OfflineIM
|
||||||
|
StorageProvider = "OpenSim.Addons.OfflineIM.dll"
|
||||||
|
OfflineIMService = "OpenSim.Addons.OfflineIM.dll:OfflineIMService"
|
||||||
|
|
||||||
[GridInfoService]
|
[GridInfoService]
|
||||||
; These settings are used to return information on a get_grid_info call.
|
; These settings are used to return information on a get_grid_info call.
|
||||||
|
|
50
prebuild.xml
50
prebuild.xml
|
@ -2521,6 +2521,56 @@
|
||||||
</Match>
|
</Match>
|
||||||
</Files>
|
</Files>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
||||||
|
<!-- Addons -->
|
||||||
|
|
||||||
|
<Project frameworkVersion="v3_5" name="OpenSim.Addons.OfflineIM" path="OpenSim/Addons/OfflineIM" type="Library">
|
||||||
|
<Configuration name="Debug">
|
||||||
|
<Options>
|
||||||
|
<OutputPath>../../../bin/</OutputPath>
|
||||||
|
</Options>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration name="Release">
|
||||||
|
<Options>
|
||||||
|
<OutputPath>../../../bin/</OutputPath>
|
||||||
|
</Options>
|
||||||
|
</Configuration>
|
||||||
|
|
||||||
|
<ReferencePath>../../../bin/</ReferencePath>
|
||||||
|
<Reference name="System"/>
|
||||||
|
<Reference name="System.Core"/>
|
||||||
|
<Reference name="System.Data"/>
|
||||||
|
<Reference name="System.Web"/>
|
||||||
|
<Reference name="System.Xml"/>
|
||||||
|
|
||||||
|
<Reference name="Nini" path="../../../bin/"/>
|
||||||
|
<Reference name="Mono.Addins" path="../../../bin/"/>
|
||||||
|
<Reference name="MySql.Data" path="../../../bin/"/>
|
||||||
|
<Reference name="log4net" path="../../../bin/"/>
|
||||||
|
<Reference name="OpenMetaverse" path="../../../bin/"/>
|
||||||
|
<Reference name="OpenMetaverseTypes" path="../../../bin/"/>
|
||||||
|
|
||||||
|
<Reference name="OpenSim.Framework"/>
|
||||||
|
<Reference name="OpenSim.Data"/>
|
||||||
|
<Reference name="OpenSim.Data.MySQL"/>
|
||||||
|
<Reference name="OpenSim.Framework.Servers.HttpServer"/>
|
||||||
|
<Reference name="OpenSim.Services.Base"/>
|
||||||
|
<Reference name="OpenSim.Services.Interfaces"/>
|
||||||
|
<Reference name="OpenSim.Region.Framework"/>
|
||||||
|
<Reference name="OpenSim.Server.Base"/>
|
||||||
|
<Reference name="OpenSim.Server.Handlers"/>
|
||||||
|
|
||||||
|
<!-- To allow regions to have mono addins -->
|
||||||
|
<Reference name="Mono.Addins" path="../../../bin/" />
|
||||||
|
|
||||||
|
<Files>
|
||||||
|
<Match pattern="*.cs" recurse="true">
|
||||||
|
<Exclude pattern="Tests" />
|
||||||
|
</Match>
|
||||||
|
<Match buildAction="EmbeddedResource" path="Resources" pattern="*.migrations"/>
|
||||||
|
</Files>
|
||||||
|
</Project>
|
||||||
|
|
||||||
|
|
||||||
<!-- Tools -->
|
<!-- Tools -->
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue