29 using System.Collections.Generic;
30 using System.Reflection;
34 using OpenSim.Framework;
35 using OpenSim.Framework.Client;
36 using OpenSim.Region.Framework.Interfaces;
37 using OpenSim.Region.Framework.Scenes;
38 using OpenSim.Framework.Console;
39 using OpenSim.Region.PhysicsModules.SharedBase;
42 namespace OpenSim.
Region.RegionCombinerModule
44 [Extension(Path =
"/OpenSim/RegionModules", NodeName =
"RegionModule", Id =
"RegionCombinerModule")]
47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
52 get {
return "RegionCombinerModule"; }
55 public Type ReplaceableInterface
63 private bool m_combineContiguousRegions =
false;
71 private Dictionary<UUID, RegionConnections> m_regions =
new Dictionary<UUID, RegionConnections>();
76 private Dictionary<UUID, Scene> m_startingScenes =
new Dictionary<UUID, Scene>();
80 IConfig myConfig = source.Configs[
"Startup"];
81 m_combineContiguousRegions = myConfig.GetBoolean(
"CombineContiguousRegions",
false);
82 if (m_combineContiguousRegions)
83 m_log.ErrorFormat(
"[REGION COMBINER MODULE]: THIS MODULE IS BEING MARKED OBSOLETE AND MAY SOON BE REMOVED. PLEASE USE VARREGIONS INSTEAD.");
85 MainConsole.Instance.Commands.AddCommand(
86 "RegionCombinerModule",
false,
"fix-phantoms",
"fix-phantoms",
87 "Fixes phantom objects after an import to a megaregion or a change from a megaregion back to normal regions",
97 if (m_combineContiguousRegions)
103 lock (m_startingScenes)
104 m_startingScenes.Remove(scene.RegionInfo.originRegionID);
109 lock (m_startingScenes)
110 m_startingScenes.Add(scene.RegionInfo.originRegionID, scene);
112 if (m_combineContiguousRegions)
114 RegionLoadedDoWork(scene);
116 scene.EventManager.OnNewPresence += NewPresence;
123 return m_regions.ContainsKey(regionId);
130 if (m_regions.ContainsKey(regionId))
134 return new Vector2((
float)rootConn.
XEnd, (
float)rootConn.
YEnd);
138 throw new Exception(
string.Format(
"Region with id {0} not found", regionId));
146 if (xx < 0 || yy < 0)
151 if (currentRegion == rootRegion.
RegionId)
154 if (xx < rootRegion.
XEnd && yy < rootRegion.
YEnd)
165 if (currentRegion == childRegion.
RegionId)
168 Vector3 positionInMegaregion = childRegion.Offset;
169 positionInMegaregion.X += xx;
170 positionInMegaregion.Y += yy;
171 if (positionInMegaregion.X < rootRegion.
XEnd && positionInMegaregion.Y < rootRegion.
YEnd)
192 throttleData = presence.ControllingClient.GetThrottlesPacked(1);
194 catch (NotImplementedException)
199 if (throttleData == null)
202 if (throttleData.Length == 0)
205 if (throttleData.Length != 28)
211 if (!BitConverter.IsLittleEndian)
213 byte[] newData =
new byte[7 * 4];
214 Buffer.BlockCopy(throttleData, 0, newData, 0, 7 * 4);
216 for (
int i = 0; i < 7; i++)
217 Array.Reverse(newData, i * 4, 4);
223 adjData = throttleData;
227 int resend = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4;
228 int land = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4;
229 int wind = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4;
230 int cloud = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4;
231 int task = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4;
232 int texture = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4;
233 int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
239 byte[] data =
new byte[7 * 4];
242 Buffer.BlockCopy(Utils.FloatToBytes(resend), 0, data, ii, 4); ii += 4;
243 Buffer.BlockCopy(Utils.FloatToBytes(land * 50), 0, data, ii, 4); ii += 4;
244 Buffer.BlockCopy(Utils.FloatToBytes(wind), 0, data, ii, 4); ii += 4;
245 Buffer.BlockCopy(Utils.FloatToBytes(cloud), 0, data, ii, 4); ii += 4;
246 Buffer.BlockCopy(Utils.FloatToBytes(task), 0, data, ii, 4); ii += 4;
247 Buffer.BlockCopy(Utils.FloatToBytes(texture), 0, data, ii, 4); ii += 4;
248 Buffer.BlockCopy(Utils.FloatToBytes(asset), 0, data, ii, 4);
252 presence.ControllingClient.SetChildAgentThrottle(data);
254 catch (NotImplementedException)
261 private void RegionLoadedDoWork(
Scene scene)
270 RegionConnections newConn =
new RegionConnections();
271 newConn.ConnectedRegions =
new List<RegionData>();
272 newConn.RegionScene = scene;
273 newConn.RegionLandChannel = scene.LandChannel;
274 newConn.RegionId = scene.RegionInfo.originRegionID;
275 newConn.X = scene.RegionInfo.RegionLocX;
276 newConn.Y = scene.RegionInfo.RegionLocY;
277 newConn.XEnd = scene.RegionInfo.RegionSizeX;
278 newConn.YEnd = scene.RegionInfo.RegionSizeX;
282 bool connectedYN =
false;
284 foreach (RegionConnections rootConn
in m_regions.Values)
453 if (rootConn.PosX + rootConn.XEnd >= newConn.PosX && rootConn.PosY >= newConn.PosY)
455 connectedYN = DoWorkForOneRegionOverPlusXY(rootConn, newConn, scene);
463 if (rootConn.PosX >= newConn.PosX && rootConn.PosY + rootConn.YEnd >= newConn.PosY)
465 connectedYN = DoWorkForOneRegionOverPlusXY(rootConn, newConn, scene);
473 if (rootConn.PosX + rootConn.XEnd >= newConn.PosX && rootConn.PosY + rootConn.YEnd >= newConn.PosY)
475 connectedYN = DoWorkForOneRegionOverPlusXY(rootConn, newConn, scene);
483 DoWorkForRootRegion(newConn, scene);
488 private bool DoWorkForOneRegionOverPlusXY(RegionConnections rootConn, RegionConnections newConn,
Scene scene)
491 Vector3 offset = Vector3.Zero;
492 offset.X = newConn.PosX - rootConn.PosX;
493 offset.Y = newConn.PosY - rootConn.PosY;
497 Vector3 extents = Vector3.Zero;
498 extents.X = Math.Max(rootConn.XEnd, offset.X + newConn.RegionScene.RegionInfo.RegionSizeX);
499 extents.Y = Math.Max(rootConn.YEnd, offset.Y + newConn.RegionScene.RegionInfo.RegionSizeY);
501 rootConn.UpdateExtents(extents);
504 "[REGION COMBINER MODULE]: Root region {0} is to the west of region {1}, Offset: {2}, Extents: {3}",
505 rootConn.RegionScene.RegionInfo.RegionName,
506 newConn.RegionScene.RegionInfo.RegionName, offset, extents);
508 RegionData ConnectedRegion =
new RegionData();
509 ConnectedRegion.Offset = offset;
510 ConnectedRegion.RegionId = scene.RegionInfo.originRegionID;
511 ConnectedRegion.RegionScene = scene;
512 rootConn.ConnectedRegions.Add(ConnectedRegion);
515 rootConn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents);
518 scene.PhysicsScene.Combine(rootConn.RegionScene.PhysicsScene, offset, Vector3.Zero);
522 scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised());
525 if (rootConn.ClientEventForwarder != null)
526 rootConn.ClientEventForwarder.AddSceneToEventForwarding(scene);
616 private void DoWorkForRootRegion(RegionConnections rootConn,
Scene scene)
618 m_log.DebugFormat(
"[REGION COMBINER MODULE]: Adding root region {0}", scene.RegionInfo.RegionName);
620 RegionData rdata =
new RegionData();
621 rdata.Offset = Vector3.Zero;
622 rdata.RegionId = scene.RegionInfo.originRegionID;
623 rdata.RegionScene = scene;
625 rootConn.RegionLandChannel = scene.LandChannel;
628 RegionCombinerLargeLandChannel lnd =
new RegionCombinerLargeLandChannel(rdata, scene.
LandChannel,
629 rootConn.ConnectedRegions);
631 scene.LandChannel = lnd;
636 foreach (RegionData r
in rootConn.ConnectedRegions)
638 ForwardPermissionRequests(rootConn, r.RegionScene);
642 rootConn.ClientEventForwarder =
new RegionCombinerClientEventForwarder(rootConn);
645 scene.EventManager.OnNewPresence += SetCoarseLocationDelegate;
648 m_regions.Add(scene.RegionInfo.originRegionID, rootConn);
652 private void SetCoarseLocationDelegate(
ScenePresence presence)
654 presence.SetSendCoarseLocationMethod(SendCoarseLocationUpdates);
659 private void SendCoarseLocationUpdates(UUID sceneId,
ScenePresence presence, List<Vector3> coarseLocations, List<UUID> avatarUUIDs)
661 RegionConnections connectiondata = null;
664 if (m_regions.ContainsKey(sceneId))
665 connectiondata = m_regions[sceneId];
670 List<Vector3> CoarseLocations =
new List<Vector3>();
671 List<UUID> AvatarUUIDs =
new List<UUID>();
673 connectiondata.RegionScene.ForEachRootScenePresence(delegate(
ScenePresence sp)
677 CoarseLocations.Add(sp.AbsolutePosition);
678 AvatarUUIDs.Add(sp.UUID);
682 DistributeCoarseLocationUpdates(CoarseLocations, AvatarUUIDs, connectiondata, presence);
685 private void DistributeCoarseLocationUpdates(List<Vector3> locations, List<UUID> uuids,
686 RegionConnections connectiondata,
ScenePresence rootPresence)
688 RegionData[] rdata = connectiondata.ConnectedRegions.ToArray();
690 Dictionary<Vector2, RegionCoarseLocationStruct> updates =
new Dictionary<Vector2, RegionCoarseLocationStruct>();
693 RegionCoarseLocationStruct rootupdatedata =
new RegionCoarseLocationStruct();
694 rootupdatedata.Locations =
new List<Vector3>();
695 rootupdatedata.Uuids =
new List<UUID>();
696 rootupdatedata.Offset = Vector2.Zero;
698 rootupdatedata.UserAPI = rootPresence.ControllingClient;
700 if (rootupdatedata.UserAPI != null)
701 updates.Add(Vector2.Zero, rootupdatedata);
704 foreach (RegionData regiondata
in rdata)
706 Vector2 offset =
new Vector2(regiondata.Offset.X, regiondata.Offset.Y);
707 RegionCoarseLocationStruct updatedata =
new RegionCoarseLocationStruct();
708 updatedata.Locations =
new List<Vector3>();
709 updatedata.Uuids =
new List<UUID>();
710 updatedata.Offset = offset;
712 if (offset == Vector2.Zero)
713 updatedata.UserAPI = rootPresence.ControllingClient;
715 updatedata.UserAPI = LocateUsersChildAgentIClientAPI(offset, rootPresence.
UUID, rdata);
717 if (updatedata.UserAPI != null)
718 updates.Add(offset, updatedata);
722 for (
int i = 0; i < locations.Count; i++)
730 if (!updates.ContainsKey(offset))
733 RegionCoarseLocationStruct updatedata =
new RegionCoarseLocationStruct();
734 updatedata.Locations =
new List<Vector3>();
735 updatedata.Uuids =
new List<UUID>();
736 updatedata.Offset = offset;
738 if (offset == Vector2.Zero)
739 updatedata.UserAPI = rootPresence.ControllingClient;
741 updatedata.UserAPI = LocateUsersChildAgentIClientAPI(offset, rootPresence.
UUID, rdata);
743 updates.Add(offset,updatedata);
746 updates[offset].Locations.Add(locations[i]);
747 updates[offset].Uuids.Add(uuids[i]);
751 foreach (Vector2 offset
in updates.Keys)
753 if (updates[offset].UserAPI != null)
755 updates[offset].UserAPI.SendCoarseLocationUpdate(updates[offset].Uuids,updates[offset].Locations);
767 private IClientAPI LocateUsersChildAgentIClientAPI(Vector2 offset, UUID uUID, RegionData[] rdata)
770 foreach (RegionData r
in rdata)
772 if (r.Offset.X == offset.X && r.Offset.Y == offset.Y)
774 return r.RegionScene.SceneGraph.GetControllingClient(uUID);
818 VirtualRegion.Permissions.OnBypassPermissions += BigRegion.PermissionModule.BypassPermissions;
819 VirtualRegion.Permissions.OnSetBypassPermissions += BigRegion.PermissionModule.SetBypassPermissions;
820 VirtualRegion.Permissions.OnPropagatePermissions += BigRegion.PermissionModule.PropagatePermissions;
821 VirtualRegion.Permissions.OnGenerateClientFlags += BigRegion.PermissionModule.GenerateClientFlags;
822 VirtualRegion.Permissions.OnAbandonParcel += BigRegion.PermissionModule.CanAbandonParcel;
823 VirtualRegion.Permissions.OnReclaimParcel += BigRegion.PermissionModule.CanReclaimParcel;
824 VirtualRegion.Permissions.OnDeedParcel += BigRegion.PermissionModule.CanDeedParcel;
825 VirtualRegion.Permissions.OnDeedObject += BigRegion.PermissionModule.CanDeedObject;
826 VirtualRegion.Permissions.OnIsGod += BigRegion.PermissionModule.IsGod;
827 VirtualRegion.Permissions.OnDuplicateObject += BigRegion.PermissionModule.CanDuplicateObject;
828 VirtualRegion.Permissions.OnDeleteObject += BigRegion.PermissionModule.CanDeleteObject;
829 VirtualRegion.Permissions.OnEditObject += BigRegion.PermissionModule.CanEditObject;
830 VirtualRegion.Permissions.OnEditParcelProperties += BigRegion.PermissionModule.CanEditParcelProperties;
831 VirtualRegion.Permissions.OnInstantMessage += BigRegion.PermissionModule.CanInstantMessage;
832 VirtualRegion.Permissions.OnInventoryTransfer += BigRegion.PermissionModule.CanInventoryTransfer;
833 VirtualRegion.Permissions.OnIssueEstateCommand += BigRegion.PermissionModule.CanIssueEstateCommand;
834 VirtualRegion.Permissions.OnMoveObject += BigRegion.PermissionModule.CanMoveObject;
835 VirtualRegion.Permissions.OnObjectEntry += BigRegion.PermissionModule.CanObjectEntry;
836 VirtualRegion.Permissions.OnReturnObjects += BigRegion.PermissionModule.CanReturnObjects;
837 VirtualRegion.Permissions.OnRezObject += BigRegion.PermissionModule.CanRezObject;
838 VirtualRegion.Permissions.OnRunConsoleCommand += BigRegion.PermissionModule.CanRunConsoleCommand;
839 VirtualRegion.Permissions.OnRunScript += BigRegion.PermissionModule.CanRunScript;
840 VirtualRegion.Permissions.OnCompileScript += BigRegion.PermissionModule.CanCompileScript;
841 VirtualRegion.Permissions.OnSellParcel += BigRegion.PermissionModule.CanSellParcel;
842 VirtualRegion.Permissions.OnTakeObject += BigRegion.PermissionModule.CanTakeObject;
843 VirtualRegion.Permissions.OnTakeCopyObject += BigRegion.PermissionModule.CanTakeCopyObject;
844 VirtualRegion.Permissions.OnTerraformLand += BigRegion.PermissionModule.CanTerraformLand;
845 VirtualRegion.Permissions.OnLinkObject += BigRegion.PermissionModule.CanLinkObject;
846 VirtualRegion.Permissions.OnDelinkObject += BigRegion.PermissionModule.CanDelinkObject;
847 VirtualRegion.Permissions.OnBuyLand += BigRegion.PermissionModule.CanBuyLand;
848 VirtualRegion.Permissions.OnViewNotecard += BigRegion.PermissionModule.CanViewNotecard;
849 VirtualRegion.Permissions.OnViewScript += BigRegion.PermissionModule.CanViewScript;
850 VirtualRegion.Permissions.OnEditNotecard += BigRegion.PermissionModule.CanEditNotecard;
851 VirtualRegion.Permissions.OnEditScript += BigRegion.PermissionModule.CanEditScript;
852 VirtualRegion.Permissions.OnCreateObjectInventory += BigRegion.PermissionModule.CanCreateObjectInventory;
853 VirtualRegion.Permissions.OnEditObjectInventory += BigRegion.PermissionModule.CanEditObjectInventory;
854 VirtualRegion.Permissions.OnCopyObjectInventory += BigRegion.PermissionModule.CanCopyObjectInventory;
855 VirtualRegion.Permissions.OnDeleteObjectInventory += BigRegion.PermissionModule.CanDeleteObjectInventory;
856 VirtualRegion.Permissions.OnResetScript += BigRegion.PermissionModule.CanResetScript;
857 VirtualRegion.Permissions.OnCreateUserInventory += BigRegion.PermissionModule.CanCreateUserInventory;
858 VirtualRegion.Permissions.OnCopyUserInventory += BigRegion.PermissionModule.CanCopyUserInventory;
859 VirtualRegion.Permissions.OnEditUserInventory += BigRegion.PermissionModule.CanEditUserInventory;
860 VirtualRegion.Permissions.OnDeleteUserInventory += BigRegion.PermissionModule.CanDeleteUserInventory;
861 VirtualRegion.Permissions.OnTeleport += BigRegion.PermissionModule.CanTeleport;
864 #region console commands
868 List<Scene> scenes =
new List<Scene>(m_startingScenes.Values);
870 foreach (
Scene s
in scenes)
872 MainConsole.Instance.OutputFormat(
"Fixing phantoms for {0}", s.RegionInfo.RegionName);
874 s.ForEachSOG(so => so.AbsolutePosition = so.AbsolutePosition);
Vector2 GetSizeOfMegaregion(UUID regionId)
Gets the size of megaregion.
uint YEnd
The size of the megaregion in meters.
bool PositionIsInMegaregion(UUID currentRegion, int xx, int yy)
Tests to see of position (relative to the region) is within the megaregion
uint XEnd
The size of the megaregion in meters.
bool IsRootForMegaregion(UUID regionId)
Does the given id belong to the root region of a megaregion?
void Close()
This is the inverse to Initialise. After a Close(), this instance won't be usable anymore...
void RegionLoaded(Scene scene)
This will be called once for every scene loaded. In a shared module this will be multiple times in on...
RegionCombinerPermissionModule PermissionModule
void Initialise(IConfigSource source)
This is called to initialize the region module. For shared modules, this is called exactly once...
List< RegionData > ConnectedRegions
void ForwardPermissionRequests(RegionConnections BigRegion, Scene VirtualRegion)
void FixPhantoms(string module, string[] cmdparams)
Scene RegionScene
Root Region Scene
void RemoveRegion(Scene scene)
This is called whenever a Scene is removed. For shared modules, this can happen several times...
void AddRegion(Scene scene)
This is called whenever a Scene is added. For shared modules, this can happen several times...
void PostInitialise()
This is called exactly once after all the shared region-modules have been instanciated and IRegionMod...
UUID RegionId
Root Region ID