@@ -264,16 +264,16 @@ public class QueryFilter

public Dictionary<string, uint> andBitfieldNandFilters = new Dictionary<string, uint>();

public Dictionary<string, int> andGreaterThanFilters = new Dictionary<string, int>();
public Dictionary<string, int> orGreaterThanFilters = new Dictionary<string, int>();
public Dictionary<string, object> andGreaterThanFilters = new Dictionary<string, object>();
public Dictionary<string, object> orGreaterThanFilters = new Dictionary<string, object>();

public Dictionary<string, int> andGreaterThanEqFilters = new Dictionary<string, int>();
public Dictionary<string, int> orGreaterThanEqFilters = new Dictionary<string, int>();
public Dictionary<string, object> andGreaterThanEqFilters = new Dictionary<string, object>();
public Dictionary<string, object> orGreaterThanEqFilters = new Dictionary<string, object>();

public Dictionary<string, int> andLessThanFilters = new Dictionary<string, int>();
public Dictionary<string, int> orLessThanFilters = new Dictionary<string, int>();
public Dictionary<string, object> andLessThanFilters = new Dictionary<string, object>();
public Dictionary<string, object> orLessThanFilters = new Dictionary<string, object>();

public Dictionary<string, int> andLessThanEqFilters = new Dictionary<string, int>();
public Dictionary<string, object> andLessThanEqFilters = new Dictionary<string, object>();

public Dictionary<string, object> andNotFilters = new Dictionary<string, object>();

@@ -485,10 +485,10 @@ public string ToSQL(char prepared, out Dictionary<string, object> ps)
#region greater than

parts = new List<string>();
foreach (KeyValuePair<string, int> where in andGreaterThanFilters)
foreach (KeyValuePair<string, object> where in andGreaterThanFilters)
{
string key = prepared.ToString() + "where_gtAND_" + (++i) + preparedKey(where.Key);
ps[key] = where.Value;
ps[key] = float.Parse((where.Value).ToString());
parts.Add(string.Format("{0} > {1}", where.Key, key));
}
if (parts.Count > 0)
@@ -498,10 +498,10 @@ public string ToSQL(char prepared, out Dictionary<string, object> ps)
}

parts = new List<string>();
foreach (KeyValuePair<string, int> where in orGreaterThanFilters)
foreach (KeyValuePair<string, object> where in orGreaterThanFilters)
{
string key = prepared.ToString() + "where_gtOR_" + (++i) + preparedKey(where.Key);
ps[key] = where.Value;
ps[key] = float.Parse((where.Value).ToString());
parts.Add(string.Format("{0} > {1}", where.Key, key));
}
if (parts.Count > 0)
@@ -511,10 +511,10 @@ public string ToSQL(char prepared, out Dictionary<string, object> ps)
}

parts = new List<string>();
foreach (KeyValuePair<string, int> where in andGreaterThanEqFilters)
foreach (KeyValuePair<string, object> where in andGreaterThanEqFilters)
{
string key = prepared.ToString() + "where_gteqAND_" + (++i) + preparedKey(where.Key);
ps[key] = where.Value;
ps[key] = float.Parse((where.Value).ToString());
parts.Add(string.Format("{0} >= {1}", where.Key, key));
}
if (parts.Count > 0)
@@ -524,10 +524,10 @@ public string ToSQL(char prepared, out Dictionary<string, object> ps)
}

parts = new List<string>();
foreach (KeyValuePair<string, int> where in orGreaterThanEqFilters)
foreach (KeyValuePair<string, object> where in orGreaterThanEqFilters)
{
string key = prepared.ToString() + "where_gteqOR_" + (++i) + preparedKey(where.Key);
ps[key] = where.Value;
ps[key] = float.Parse((where.Value).ToString());
parts.Add(string.Format("{0} >= {1}", where.Key, key));
}
if (parts.Count > 0)
@@ -541,10 +541,10 @@ public string ToSQL(char prepared, out Dictionary<string, object> ps)
#region less than

parts = new List<string>();
foreach (KeyValuePair<string, int> where in andLessThanFilters)
foreach (KeyValuePair<string, object> where in andLessThanFilters)
{
string key = prepared.ToString() + "where_ltAND_" + (++i) + preparedKey(where.Key);
ps[key] = where.Value;
ps[key] = float.Parse((where.Value).ToString());
parts.Add(string.Format("{0} < {1}", where.Key, key));
}
if (parts.Count > 0)
@@ -554,10 +554,10 @@ public string ToSQL(char prepared, out Dictionary<string, object> ps)
}

parts = new List<string>();
foreach (KeyValuePair<string, int> where in orLessThanFilters)
foreach (KeyValuePair<string, object> where in orLessThanFilters)
{
string key = prepared.ToString() + "where_ltOR_" + (++i) + preparedKey(where.Key);
ps[key] = where.Value;
ps[key] = float.Parse((where.Value).ToString());
parts.Add(string.Format("{0} < {1}", where.Key, key));
}
if (parts.Count > 0)
@@ -567,10 +567,10 @@ public string ToSQL(char prepared, out Dictionary<string, object> ps)
}

parts = new List<string>();
foreach (KeyValuePair<string, int> where in andLessThanEqFilters)
foreach (KeyValuePair<string, object> where in andLessThanEqFilters)
{
string key = prepared.ToString() + "where_lteqAND_" + (++i) + preparedKey(where.Key);
ps[key] = where.Value;
ps[key] = float.Parse((where.Value).ToString());
parts.Add(string.Format("{0} <= {1}", where.Key, key));
}
if (parts.Count > 0)
@@ -117,6 +117,16 @@ public interface IGridService
/// <returns></returns>
List<GridRegion> GetRegionRange (UUID scopeID, int xmin, int xmax, int ymin, int ymax);

/// <summary>
/// Get all regions within the range of specified center.
/// </summary>
/// <param name="scopeID"></param>
/// <param name="centerX"></param>
/// <param name="centerY"></param>
/// <param name="squareRangeFromCenterInMeters"></param>
/// <returns></returns>
List<GridRegion> GetRegionRange(UUID scopeID, float centerX, float centerY, uint squareRangeFromCenterInMeters);

/// <summary>
/// Get the neighbors of the given region
/// </summary>
@@ -46,21 +46,32 @@ public interface IRegionData : IAuroraDataPlugin
List<GridRegion> Get(RegionFlags flags, Dictionary<string, bool> sort);
List<GridRegion> Get(uint start, uint count, uint EstateID, RegionFlags flags, Dictionary<string, bool> sort);
List<GridRegion> Get(RegionFlags includeFlags, RegionFlags excludeFlags, uint? start, uint? count, Dictionary<string, bool> sort);

/// <summary>
/// Gets the number of regions matching the specified flags
/// </summary>
/// <param name="includeFlags"></param>
/// <param name="excludeFlags"></param>
/// <returns></returns>
uint Count(RegionFlags includeFlags, RegionFlags excludeFlags);

/// <summary>
/// Gets the neighbouring regions, taking into account variable-sized regions
/// </summary>
/// <param name="regionID"></param>
/// <param name="ScopeID"></param>
/// <param name="squareRangeFromCenterInMeters">because calculating circular radii would be a complex.</param>
/// <returns>If the return result is of zero length the region does not exist.</returns>
List<GridRegion> GetNeighbours(UUID regionID, UUID ScopeID, uint squareRangeFromCenterInMeters);
List<GridRegion> GetNeighbours(UUID regionID, UUID ScopeID, uint squareRangeFromCenterInMeters);

/// <summary>
/// Gets all regions within squareRangeFromCenterInMeters meters of centerX and centerY
/// </summary>
/// <param name="centerX"></param>
/// <param name="centerY"></param>
/// <param name="squareRangeFromCenterInMeters"></param>
/// <returns></returns>
List<GridRegion> Get(UUID scopeID, UUID excludeRegion, float centerX, float centerY, uint squareRangeFromCenterInMeters);

uint Count(uint EstateID, RegionFlags flags);

@@ -106,7 +106,7 @@ public List<FriendInfo> GetFriends(UUID PrincipalID)
List<FriendInfo> friends = m_localService.GetFriends(PrincipalID);
if (friends == null || friends.Count == 0)
friends = (List<FriendInfo>)DoRemoteForced(PrincipalID);
return friends;
return friends ?? new List<FriendInfo>();
}

[CanBeReflected(ThreatLevel = OpenSim.Services.Interfaces.ThreatLevel.Low)]
@@ -170,6 +170,19 @@ public List<GridRegion> GetRegionRange(UUID scopeID, int xmin, int xmax, int ymi
return r;
}

[CanBeReflected(ThreatLevel = OpenSim.Services.Interfaces.ThreatLevel.Low)]
public List<GridRegion> GetRegionRange(UUID scopeID, float centerX, float centerY, uint squareRangeFromCenterInMeters)
{
List<GridRegion> r = m_localService.GetRegionRange(scopeID, centerX, centerY, squareRangeFromCenterInMeters);
List<GridRegion> remoteRegions = (List<GridRegion>)DoRemoteForced(scopeID, centerX, centerY, squareRangeFromCenterInMeters);
if (remoteRegions != null)
{
UpdateGridRegionsForIWC(ref remoteRegions);
r.AddRange(remoteRegions);
}
return r;
}

[CanBeReflected(ThreatLevel = OpenSim.Services.Interfaces.ThreatLevel.Low)]
public List<GridRegion> GetDefaultRegions(UUID scopeID)
{
@@ -83,8 +83,7 @@ public bool RegisterRegionWithGrid(IScene scene, bool returnResponseFirstTime, b
//Set it from the regionInfo if it knows anything
}

scene.RequestModuleInterface<ISimulationBase>().EventManager.FireGenericEventHandler("PreRegisterRegion",
region);
scene.RequestModuleInterface<ISimulationBase>().EventManager.FireGenericEventHandler("PreRegisterRegion", region);

//Tell the grid service about us
RegisterRegion error = GridService.RegisterRegion(region, s.SessionID);
@@ -43,28 +43,132 @@ public class LocalGridConnector : IRegionData

#region IRegionData Members

public void Initialize(IGenericData GenericData, IConfigSource source, IRegistryCore simBase,
string defaultConnectionString)
{
if (source.Configs["AuroraConnectors"].GetString("AbuseReportsConnector", "LocalConnector") ==
"LocalConnector")
public void Initialize(IGenericData GenericData, IConfigSource source, IRegistryCore simBase, string defaultConnectionString)
{
if (source.Configs["AuroraConnectors"].GetString("GridConnector", "LocalConnector") == "LocalConnector")
{
GD = GenericData;

string connectionString = defaultConnectionString;
if (source.Configs[Name] != null)
connectionString = source.Configs[Name].GetString("ConnectionString", defaultConnectionString);
GD = GenericData;

string connectionString = (source.Configs[Name] != null) ? connectionString = source.Configs[Name].GetString("ConnectionString", defaultConnectionString) : defaultConnectionString;

GD.ConnectToDatabase(connectionString, "GridRegions",
source.Configs["AuroraConnectors"].GetBoolean("ValidateTables", true));
GD.ConnectToDatabase(connectionString, "GridRegions", source.Configs["AuroraConnectors"].GetBoolean("ValidateTables", true));

DataManager.DataManager.RegisterPlugin(this);
DataManager.DataManager.RegisterPlugin(this);

MainConsole.Instance.Commands.AddCommand("fix missing region owner", "fix missing region owner", "Attempts to fix missing region owners in the database.", delegate(string[] cmd)
{
FixMissingRegionOwners();
});
}
}

public string Name
{
get { return "IRegionData"; }
}

private void FixMissingRegionOwners(){
QueryFilter filter = new QueryFilter();
filter.andFilters["OwnerUUID"] = UUID.Zero;

List<GridRegion> borked = ParseQuery(GD.Query(new string[1] { "*" }, m_realm, filter, null, null, null));

if(borked.Count < 1){
MainConsole.Instance.Debug("[LocalGridConnector] No regions found with missing owners.");
}
IEstateConnector estatePlugin = Aurora.DataManager.DataManager.RequestPlugin<IEstateConnector>();

if(estatePlugin == null){
MainConsole.Instance.Error("[LocalGridConnector] " + borked.Count + " regions found with missing owners, but could not get IEstateConnector plugin.");
return;
}else{
MainConsole.Instance.Error("[LocalGridConnector] " + borked.Count + " regions found with missing owners, attempting fix.");
}

Dictionary<int, List<GridRegion>> borkedByEstate = new Dictionary<int, List<GridRegion>>();
foreach (GridRegion region in borked)
{
int estateID = estatePlugin.GetEstateID(region.RegionID);
if (!borkedByEstate.ContainsKey(estateID))
{
borkedByEstate[estateID] = new List<GridRegion>();
}
borkedByEstate[estateID].Add(region);
}

Dictionary<int, UUID> estateOwnerIDs = new Dictionary<int, UUID>();
uint estateFail = 0;
foreach (int estateID in borkedByEstate.Keys)
{
EstateSettings es = estatePlugin.GetEstateSettings(estateID);
if (es == null)
{
MainConsole.Instance.Error("[LocalGridConnector] Cannot fix missing owner for regions in Estate " + estateID + ", could not get estate settings.");
}else if (es.EstateOwner == UUID.Zero)
{
MainConsole.Instance.Error("[LocalGridConnector] Cannot fix missing owner for regions in Estate " + estateID + ", Estate Owner is also missing.");
}
if (es == null || es.EstateOwner == UUID.Zero)
{
++estateFail;
continue;
}
estateOwnerIDs[estateID] = es.EstateOwner;
}

if (estateFail > 0)
{
if (estateFail == borkedByEstate.Count)
{
MainConsole.Instance.Error("[LocalGridConnector] " + borked.Count + " regions found with missing owners, could not locate any estate settings from IEstateConnector plugin.");
return;
}
else
{
MainConsole.Instance.Error("[LocalGridConnector] " + borked.Count + " regions found with missing owners, could not locate estate settings for " + estateFail + " estates.");
}
}

uint storeSuccess = 0;
uint storeFail = 0;
int borkedCount = borked.Count;
foreach (KeyValuePair<int, UUID> kvp in estateOwnerIDs)
{
List<GridRegion> regions = borkedByEstate[kvp.Key];
foreach (GridRegion region in regions)
{
region.EstateOwner = kvp.Value;
if (!Store(region))
{
MainConsole.Instance.Error("[LocalGridConnector] Failed to fix missing region for " + region.RegionName + " (" + region.RegionID + ")");
++storeFail;
}else{
++storeSuccess;
borked.Remove(region);
}
}
}

if (storeFail > 0)
{
MainConsole.Instance.Error("[LocalGridConnector] " + borkedCount + " regions found with missing owners, fix failed on " + storeFail + " regions, fix attempted on " + storeSuccess + " regions.");
}
else if (storeSuccess != borked.Count)
{
MainConsole.Instance.Error("[LocalGridConnector] " + borkedCount + " regions found with missing owners, fix attempted on " + storeSuccess + " regions.");
}
else
{
MainConsole.Instance.Info("[LocalGridConnector] All regions found with missing owners should have their owners restored.");
}
if(borked.Count > 0){
List<string> blurbs = new List<string>(borked.Count);
foreach (GridRegion region in borked)
{
blurbs.Add(region.RegionName + " (" + region.RegionID + ")");
}
MainConsole.Instance.Info("[LocalGridConnector] Failed to fix missing region owners for regions " + string.Join(", ", blurbs.ToArray()));
}
}

public List<GridRegion> Get(string regionName, UUID scopeID)
@@ -247,27 +351,35 @@ public List<GridRegion> GetNeighbours(UUID regionID, UUID scopeID, uint squareRa

if (region != null)
{
QueryFilter filter = new QueryFilter();

filter.andNotFilters["RegionUUID"] = region.RegionID; // no need to refetch the same region ID

int centerX = region.RegionLocX + (region.RegionSizeX / 2); // calculate center of region
int centerY = region.RegionLocY + (region.RegionSizeY / 2); // calculate center of region

filter.andGreaterThanEqFilters["(LocX + SizeX)"] = centerX - (int)squareRangeFromCenterInMeters;
filter.andGreaterThanEqFilters["(LocY + SizeY)"] = centerY - (int)squareRangeFromCenterInMeters;
filter.andLessThanEqFilters["(LocX - SizeX)"] = centerX - (int)squareRangeFromCenterInMeters;
filter.andLessThanEqFilters["(LocY - SizeY)"] = centerY - (int)squareRangeFromCenterInMeters;
regions = Get(scopeID, region.RegionID, centerX, centerY, squareRangeFromCenterInMeters);
}

Dictionary<string, bool> sort = new Dictionary<string,bool>(3);
sort["LocZ"] = true;
sort["LocX"] = true;
sort["LocY"] = true;
return regions;
}

public List<GridRegion> Get(UUID scopeID, UUID excludeRegion, float centerX, float centerY, uint squareRangeFromCenterInMeters)
{
QueryFilter filter = new QueryFilter();

regions = ParseQuery(GD.Query(new string[] { "*" }, m_realm, filter, sort, null, null));
if (excludeRegion != UUID.Zero)
{
filter.andNotFilters["RegionUUID"] = excludeRegion;
}
filter.andFilters["ScopeID"] = scopeID;
filter.andGreaterThanEqFilters["(LocX + SizeX)"] = centerX - squareRangeFromCenterInMeters;
filter.andGreaterThanEqFilters["(LocY + SizeY)"] = centerY - squareRangeFromCenterInMeters;
filter.andLessThanEqFilters["(LocX - SizeX)"] = centerX + squareRangeFromCenterInMeters;
filter.andLessThanEqFilters["(LocY - SizeY)"] = centerY + squareRangeFromCenterInMeters;

return regions;
Dictionary<string, bool> sort = new Dictionary<string, bool>(3);
sort["LocZ"] = true;
sort["LocX"] = true;
sort["LocY"] = true;

return ParseQuery(GD.Query(new string[] { "*" }, m_realm, filter, sort, null, null));
}

public uint Count(uint estateID, RegionFlags flags)
@@ -299,9 +411,11 @@ public uint Count(uint estateID, RegionFlags flags)
}

public bool Store(GridRegion region)
{
List<string> keys = new List<string>();
List<object> values = new List<object>();
{
if (region.EstateOwner == UUID.Zero)
{
MainConsole.Instance.Error("[LocalGridConnector] Attempt to store region with owner of UUID.Zero detected:" + (new System.Diagnostics.StackTrace()).GetFrame(1).ToString());
}

Dictionary<string, object> row = new Dictionary<string, object>(14);
row["ScopeID"] = region.ScopeID;
@@ -389,8 +503,10 @@ protected List<GridRegion> ParseQuery(List<string> query)
{
for (int i = 0; i < query.Count; i += 14)
{
GridRegion data = new GridRegion();
OSDMap map = (OSDMap)OSDParser.DeserializeJson(query[i + 13]);
GridRegion data = new GridRegion();
OSDMap map = (OSDMap)OSDParser.DeserializeJson(query[i + 13]);
map["owner_uuid"] = (!map.ContainsKey("owner_uuid") || map["owner_uuid"].AsUUID() == UUID.Zero) ? OSD.FromUUID(UUID.Parse(query[i + 6])) : map["owner_uuid"];
map["EstateOwner"] = (!map.ContainsKey("EstateOwner") || map["EstateOwner"].AsUUID() == UUID.Zero) ? OSD.FromUUID(UUID.Parse(query[i + 6])) : map["EstateOwner"];
data.FromOSD(map);

//Check whether it should be down
@@ -1486,8 +1486,8 @@ public GroupNoticeData GetGroupNoticeData(UUID requestingAgentID, UUID noticeID)
}

QueryFilter filter = new QueryFilter();
filter.andFilters["NoticeID"] = noticeID;
List<string> notice = data.Query(new[]{
filter.andFilters["NoticeID"] = noticeID;
string[] fields = new string[9]{
"GroupID",
"Timestamp",
"FromName",
@@ -1497,7 +1497,13 @@ public GroupNoticeData GetGroupNoticeData(UUID requestingAgentID, UUID noticeID)
"Message",
"AssetType",
"ItemName"
}, "osgroupnotice", filter, null, null, null);
};
List<string> notice = data.Query(fields, "osgroupnotice", filter, null, null, null);

if (notice.Count != fields.Length)
{
return null;
}

GroupNoticeData GND = new GroupNoticeData
{
@@ -1527,7 +1533,11 @@ public GroupNoticeInfo GetGroupNotice(UUID requestingAgentID, UUID noticeID)

QueryFilter filter = new QueryFilter();
filter.andFilters["NoticeID"] = noticeID;
<<<<<<< HEAD
List<string> notice = data.Query(new[]{
=======
string[] fields = new string[9]{
>>>>>>> 991c21e46800651b0744735899783d2b934bbb46
"GroupID",
"Timestamp",
"FromName",
@@ -1537,7 +1547,13 @@ public GroupNoticeInfo GetGroupNotice(UUID requestingAgentID, UUID noticeID)
"Message",
"AssetType",
"ItemName"
}, "osgroupnotice", filter, null, null, null);
};
List<string> notice = data.Query(fields, "osgroupnotice", filter, null, null, null);

if (notice.Count != fields.Length)
{
return null;
}

GroupNoticeData GND = new GroupNoticeData
{
@@ -587,7 +587,8 @@ public void UpdateRegionInfo (RegionInfo oldRegion, RegionInfo region)
{
if(scene.RegionInfo.RegionID == region.RegionID)
{
bool needsGridUpdate = scene.RegionInfo.RegionName != region.RegionName ||
bool needsGridUpdate =
scene.RegionInfo.RegionName != region.RegionName ||
scene.RegionInfo.RegionLocX != region.RegionLocX ||
scene.RegionInfo.RegionLocY != region.RegionLocY ||
scene.RegionInfo.RegionLocZ != region.RegionLocZ ||
@@ -596,10 +597,12 @@ public void UpdateRegionInfo (RegionInfo oldRegion, RegionInfo region)
//scene.RegionInfo.RegionSizeX != region.RegionSizeX //Don't allow for size updates on the fly, that needs a restart
//scene.RegionInfo.RegionSizeY != region.RegionSizeY
//scene.RegionInfo.RegionSizeZ != region.RegionSizeZ
;
bool needsRegistration = scene.RegionInfo.RegionName != region.RegionName ||
;
bool needsRegistration =
scene.RegionInfo.RegionName != region.RegionName ||
scene.RegionInfo.RegionLocX != region.RegionLocX ||
scene.RegionInfo.RegionLocY != region.RegionLocY;
scene.RegionInfo.RegionLocY != region.RegionLocY
;

region.RegionSettings = scene.RegionInfo.RegionSettings;
region.EstateSettings = scene.RegionInfo.EstateSettings;
@@ -119,7 +119,7 @@ public virtual void AddNewUrls(string key, OSDMap urls)
{
if (kvp.Value.Type == OSDType.String)
m_autoConfig[kvp.Key] = kvp.Value;
else
else if (kvp.Value.Type != OSDType.Boolean) // "Success" coming from IWC
m_autoConfig[kvp.Key] = string.Join(",", ((OSDArray)kvp.Value).ConvertAll<string>((osd) => osd).ToArray());
}
else
@@ -715,6 +715,14 @@ public virtual List<GridRegion> GetRegionRange(UUID scopeID, int xmin, int xmax,
return m_Database.Get(xmin, ymin, xmax, ymax, scopeID);
}

[CanBeReflected(ThreatLevel = OpenSim.Services.Interfaces.ThreatLevel.Low)]
public virtual List<GridRegion> GetRegionRange(UUID scopeID, float centerX, float centerY, uint squareRangeFromCenterInMeters)
{
object remoteValue = DoRemote(scopeID, centerX, centerY, squareRangeFromCenterInMeters);

return (remoteValue != null || m_doRemoteOnly) ? (List<GridRegion>)remoteValue : m_Database.Get(scopeID, UUID.Zero, centerX, centerY, squareRangeFromCenterInMeters);
}

/// <summary>
/// Get the cached list of neighbors or a new list
/// </summary>
@@ -97,6 +97,7 @@
EstateConnector = LocalConnector
DirectoryServiceConnector = LocalConnector
ParcelConnector = LocalConnector
GridConnector = LocalConnector

MuteListConnector = IWCConnector
OfflineMessagesConnector = IWCConnector