mirror of
https://github.com/opensim/opensim.git
synced 2026-05-15 11:25:39 +08:00
285 lines
11 KiB
C#
285 lines
11 KiB
C#
/*
|
|
* 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.IO;
|
|
using System.Reflection;
|
|
using System.Xml;
|
|
using log4net;
|
|
using Nwc.XmlRpc;
|
|
using OpenMetaverse;
|
|
using OpenSim.Data;
|
|
using OpenSim.Framework;
|
|
using OpenSim.Framework.Communications;
|
|
using OpenSim.Framework.Servers;
|
|
|
|
|
|
namespace OpenSim.Grid.GridServer.Modules
|
|
{
|
|
public class GridDBService : IRegionProfileService
|
|
{
|
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
|
|
|
private List<IGridDataPlugin> _plugins = new List<IGridDataPlugin>();
|
|
private List<ILogDataPlugin> _logplugins = new List<ILogDataPlugin>();
|
|
|
|
/// <summary>
|
|
/// Adds a list of grid and log data plugins, as described by
|
|
/// `provider' and `connect', to `_plugins' and `_logplugins',
|
|
/// respectively.
|
|
/// </summary>
|
|
/// <param name="provider">
|
|
/// The filename of the inventory server plugin DLL.
|
|
/// </param>
|
|
/// <param name="connect">
|
|
/// The connection string for the storage backend.
|
|
/// </param>
|
|
public void AddPlugin(string provider, string connect)
|
|
{
|
|
_plugins = DataPluginFactory.LoadDataPlugins<IGridDataPlugin>(provider, connect);
|
|
_logplugins = DataPluginFactory.LoadDataPlugins<ILogDataPlugin>(provider, connect);
|
|
}
|
|
|
|
public int GetNumberOfPlugins()
|
|
{
|
|
return _plugins.Count;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Logs a piece of information to the database
|
|
/// </summary>
|
|
/// <param name="target">What you were operating on (in grid server, this will likely be the region UUIDs)</param>
|
|
/// <param name="method">Which method is being called?</param>
|
|
/// <param name="args">What arguments are being passed?</param>
|
|
/// <param name="priority">How high priority is this? 1 = Max, 6 = Verbose</param>
|
|
/// <param name="message">The message to log</param>
|
|
private void logToDB(string target, string method, string args, int priority, string message)
|
|
{
|
|
foreach (ILogDataPlugin plugin in _logplugins)
|
|
{
|
|
try
|
|
{
|
|
plugin.saveLog("Gridserver", target, method, args, priority, message);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
m_log.Warn("[storage]: Unable to write log via " + plugin.Name);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns a region by argument
|
|
/// </summary>
|
|
/// <param name="uuid">A UUID key of the region to return</param>
|
|
/// <returns>A SimProfileData for the region</returns>
|
|
public RegionProfileData GetRegion(UUID uuid)
|
|
{
|
|
foreach (IGridDataPlugin plugin in _plugins)
|
|
{
|
|
try
|
|
{
|
|
return plugin.GetProfileByUUID(uuid);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
m_log.Warn("[storage]: GetRegion - " + e.Message);
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns a region by argument
|
|
/// </summary>
|
|
/// <param name="uuid">A regionHandle of the region to return</param>
|
|
/// <returns>A SimProfileData for the region</returns>
|
|
public RegionProfileData GetRegion(ulong handle)
|
|
{
|
|
foreach (IGridDataPlugin plugin in _plugins)
|
|
{
|
|
try
|
|
{
|
|
return plugin.GetProfileByHandle(handle);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
m_log.Debug("[storage]: " + ex.Message);
|
|
m_log.Warn("[storage]: Unable to find region " + handle.ToString() + " via " + plugin.Name);
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns a region by argument
|
|
/// </summary>
|
|
/// <param name="regionName">A partial regionName of the region to return</param>
|
|
/// <returns>A SimProfileData for the region</returns>
|
|
public RegionProfileData GetRegion(string regionName)
|
|
{
|
|
foreach (IGridDataPlugin plugin in _plugins)
|
|
{
|
|
try
|
|
{
|
|
return plugin.GetProfileByString(regionName);
|
|
}
|
|
catch
|
|
{
|
|
m_log.Warn("[storage]: Unable to find region " + regionName + " via " + plugin.Name);
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public List<RegionProfileData> GetRegions(uint xmin, uint ymin, uint xmax, uint ymax)
|
|
{
|
|
List<RegionProfileData> regions = new List<RegionProfileData>();
|
|
|
|
foreach (IGridDataPlugin plugin in _plugins)
|
|
{
|
|
try
|
|
{
|
|
regions.AddRange(plugin.GetProfilesInRange(xmin, ymin, xmax, ymax));
|
|
}
|
|
catch
|
|
{
|
|
m_log.Warn("[storage]: Unable to query regionblock via " + plugin.Name);
|
|
}
|
|
}
|
|
|
|
return regions;
|
|
}
|
|
|
|
public List<RegionProfileData> GetRegions(string name, int maxNum)
|
|
{
|
|
List<RegionProfileData> regions = new List<RegionProfileData>();
|
|
foreach (IGridDataPlugin plugin in _plugins)
|
|
{
|
|
try
|
|
{
|
|
int num = maxNum - regions.Count;
|
|
List<RegionProfileData> profiles = plugin.GetRegionsByName(name, (uint)num);
|
|
if (profiles != null) regions.AddRange(profiles);
|
|
}
|
|
catch
|
|
{
|
|
m_log.Warn("[storage]: Unable to query regionblock via " + plugin.Name);
|
|
}
|
|
}
|
|
|
|
return regions;
|
|
}
|
|
|
|
public DataResponse AddUpdateRegion(RegionProfileData sim, RegionProfileData existingSim)
|
|
{
|
|
DataResponse insertResponse = DataResponse.RESPONSE_ERROR;
|
|
foreach (IGridDataPlugin plugin in _plugins)
|
|
{
|
|
try
|
|
{
|
|
if (existingSim == null)
|
|
{
|
|
insertResponse = plugin.StoreProfile(sim);
|
|
}
|
|
else
|
|
{
|
|
insertResponse = plugin.StoreProfile(sim);
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
m_log.Warn("[LOGIN END]: " +
|
|
"Unable to login region " + sim.ToString() + " via " + plugin.Name);
|
|
m_log.Warn("[LOGIN END]: " + e.ToString());
|
|
}
|
|
}
|
|
return insertResponse;
|
|
}
|
|
|
|
public DataResponse DeleteRegion(string uuid)
|
|
{
|
|
DataResponse insertResponse = DataResponse.RESPONSE_ERROR;
|
|
foreach (IGridDataPlugin plugin in _plugins)
|
|
{
|
|
//OpenSim.Data.MySQL.MySQLGridData dbengine = new OpenSim.Data.MySQL.MySQLGridData();
|
|
try
|
|
{
|
|
//Nice are we not using multiple databases?
|
|
//MySQLGridData mysqldata = (MySQLGridData)(plugin);
|
|
|
|
//DataResponse insertResponse = mysqldata.DeleteProfile(TheSim);
|
|
insertResponse = plugin.DeleteProfile(uuid);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
m_log.Error("storage Unable to delete region " + uuid + " via " + plugin.Name);
|
|
//MainLog.Instance.Warn("storage", e.ToString());
|
|
insertResponse = DataResponse.RESPONSE_ERROR;
|
|
}
|
|
}
|
|
return insertResponse;
|
|
}
|
|
|
|
public string CheckReservations(RegionProfileData theSim, XmlNode authkeynode)
|
|
{
|
|
foreach (IGridDataPlugin plugin in _plugins)
|
|
{
|
|
try
|
|
{
|
|
//Check reservations
|
|
ReservationData reserveData =
|
|
plugin.GetReservationAtPoint(theSim.regionLocX, theSim.regionLocY);
|
|
if ((reserveData != null && reserveData.gridRecvKey == theSim.regionRecvKey) ||
|
|
(reserveData == null && authkeynode.InnerText != theSim.regionRecvKey))
|
|
{
|
|
plugin.StoreProfile(theSim);
|
|
m_log.Info("[grid]: New sim added to grid (" + theSim.regionName + ")");
|
|
logToDB(theSim.ToString(), "RestSetSimMethod", String.Empty, 5,
|
|
"Region successfully updated and connected to grid.");
|
|
}
|
|
else
|
|
{
|
|
m_log.Warn("[grid]: " +
|
|
"Unable to update region (RestSetSimMethod): Incorrect reservation auth key.");
|
|
// Wanted: " + reserveData.gridRecvKey + ", Got: " + theSim.regionRecvKey + ".");
|
|
return "Unable to update region (RestSetSimMethod): Incorrect auth key.";
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
m_log.Warn("[GRID]: GetRegionPlugin Handle " + plugin.Name + " unable to add new sim: " +
|
|
e.ToString());
|
|
}
|
|
}
|
|
return "OK";
|
|
}
|
|
}
|
|
}
|