diff --git a/Programs/Simian/Extensions/GridLocal.cs b/Programs/Simian/Extensions/GridLocal.cs index 830e92ce..ec62267c 100644 --- a/Programs/Simian/Extensions/GridLocal.cs +++ b/Programs/Simian/Extensions/GridLocal.cs @@ -121,6 +121,26 @@ namespace Simian return grid.TryGetValue(handle, out region); } + public IList GetRegionsInArea(int minX, int minY, int maxX, int maxY) + { + lock (syncRoot) + { + IList regions = grid.FindAll( + delegate(RegionInfo region) + { + uint x, y; + Utils.LongToUInts(region.Handle, out x, out y); + x /= 256; + y /= 256; + + return (x >= minX && y >= minY && x <= maxX && y <= maxY); + } + ); + + return regions; + } + } + public ISceneProvider GetDefaultLocalScene() { if (server.Scenes.Count > 0) diff --git a/Programs/Simian/Extensions/SceneManager.cs b/Programs/Simian/Extensions/SceneManager.cs index 4243f7c7..d16d84b6 100644 --- a/Programs/Simian/Extensions/SceneManager.cs +++ b/Programs/Simian/Extensions/SceneManager.cs @@ -90,11 +90,12 @@ namespace Simian public ulong RegionHandle { get { return regionHandle; } } public UUID RegionID { get { return regionID; } } public string RegionName { get { return regionName; } set { regionName = value; } } - public RegionFlags RegionFlags { get { return RegionFlags.None; } } + public RegionFlags RegionFlags { get { return regionFlags; } } public IPEndPoint IPAndPort { get { return endpoint; } set { endpoint = value; } } public Vector3 DefaultPosition { get { return defaultPosition; } } public Vector3 DefaultLookAt { get { return defaultLookAt; } } - public float WaterHeight { get { return 20f; } } + public UUID MapTextureID { get { return mapTextureID; } } + public float WaterHeight { get { return waterHeight; } } public uint TerrainPatchWidth { get { return 16; } } public uint TerrainPatchHeight { get { return 16; } } public uint TerrainPatchCountWidth { get { return 16; } } @@ -110,6 +111,7 @@ namespace Simian int currentLocalID = 1; X509Certificate2 regionCert; ulong regionHandle; + RegionFlags regionFlags; UUID regionID = UUID.Random(); TerrainPatch[,] heightmap = new TerrainPatch[16, 16]; Vector2[,] windSpeeds = new Vector2[16, 16]; @@ -118,6 +120,8 @@ namespace Simian uint regionX; uint regionY; string regionName; + float waterHeight; + UUID mapTextureID; Vector3 defaultPosition = new Vector3(128f, 128f, 30f); Vector3 defaultLookAt = Vector3.UnitZ; /// Track the eight neighboring tiles around us @@ -138,6 +142,9 @@ namespace Simian this.endpoint = regionInfo.IPAndPort; this.regionID = regionInfo.ID; this.regionCert = regionCert; + this.regionFlags = regionInfo.Flags; + this.mapTextureID = regionInfo.MapTextureID; + this.waterHeight = regionInfo.WaterHeight; // Set the properties because this will automatically update the regionHandle RegionX = regionInfo.X; diff --git a/Programs/Simian/Interfaces/IGridProvider.cs b/Programs/Simian/Interfaces/IGridProvider.cs index a553e735..792cddbd 100644 --- a/Programs/Simian/Interfaces/IGridProvider.cs +++ b/Programs/Simian/Interfaces/IGridProvider.cs @@ -17,7 +17,10 @@ namespace Simian public Uri HttpServer; public UUID MapTextureID; public Uri Owner; + public RegionFlags Flags; + public int AgentCount; public Uri EnableClientCap; + public float WaterHeight; public uint X { @@ -84,6 +87,8 @@ namespace Simian bool TryGetRegion(UUID regionID, X509Certificate2 regionCert, out RegionInfo region); bool TryGetRegion(uint regionX, uint regionY, X509Certificate2 regionCert, out RegionInfo region); + IList GetRegionsInArea(int minX, int minY, int maxX, int maxY); + /// /// Gets the default scene running on this server /// diff --git a/Programs/Simian/Interfaces/ISceneProvider.cs b/Programs/Simian/Interfaces/ISceneProvider.cs index 535439f6..41a21743 100644 --- a/Programs/Simian/Interfaces/ISceneProvider.cs +++ b/Programs/Simian/Interfaces/ISceneProvider.cs @@ -139,6 +139,7 @@ namespace Simian ulong RegionHandle { get; } UUID RegionID { get; } string RegionName { get; set; } + UUID MapTextureID { get; } RegionFlags RegionFlags { get; } Vector3 DefaultLookAt { get; } Vector3 DefaultPosition { get; } diff --git a/Programs/Simian/SceneExtensions/LLMap.cs b/Programs/Simian/SceneExtensions/LLMap.cs index ce838209..8876b032 100644 --- a/Programs/Simian/SceneExtensions/LLMap.cs +++ b/Programs/Simian/SceneExtensions/LLMap.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.IO; using System.Net; using System.Xml; @@ -51,6 +52,9 @@ namespace Simian MapLayerRequestPacket request = (MapLayerRequestPacket)packet; GridLayerType type = (GridLayerType)request.AgentData.Flags; + // FIXME: Do this properly. Use the grid service to get the aggregated map layers + // (lots of map tiles in a single texture == layer) + MapLayerReplyPacket reply = new MapLayerReplyPacket(); reply.AgentData.AgentID = agent.ID; reply.AgentData.Flags = (uint)type; @@ -71,33 +75,82 @@ namespace Simian bool returnNonexistent = (request.AgentData.Flags == 0x10000); GridLayerType type = (GridLayerType)(request.AgentData.Flags &~0x10000); - // FIXME: Use returnNonexistent + IList regions = scene.Server.Grid.GetRegionsInArea(request.PositionData.MinX, request.PositionData.MinY, + request.PositionData.MaxX, request.PositionData.MaxY); MapBlockReplyPacket reply = new MapBlockReplyPacket(); reply.AgentData.AgentID = agent.ID; reply.AgentData.Flags = (uint)type; - reply.Data = new MapBlockReplyPacket.DataBlock[2]; + MapBlockReplyPacket.DataBlock[] blocks; - reply.Data[0] = new MapBlockReplyPacket.DataBlock(); - reply.Data[0].Access = (byte)SimAccess.Min; - reply.Data[0].Agents = (byte)scene.AgentCount(); - reply.Data[0].MapImageID = new UUID("89556747-24cb-43ed-920b-47caed15465f"); - reply.Data[0].Name = Utils.StringToBytes(scene.RegionName); - reply.Data[0].RegionFlags = (uint)scene.RegionFlags; - reply.Data[0].WaterHeight = (byte)scene.WaterHeight; - reply.Data[0].X = (ushort)scene.RegionX; - reply.Data[0].Y = (ushort)scene.RegionY; + if (returnNonexistent) + { + int blockCountX = request.PositionData.MaxX + 1 - request.PositionData.MinX; + int blockCountY = request.PositionData.MaxY + 1 - request.PositionData.MinY; + blocks = new MapBlockReplyPacket.DataBlock[blockCountX * blockCountY]; + int i = 0; - reply.Data[1] = new MapBlockReplyPacket.DataBlock(); - reply.Data[1].Access = (byte)SimAccess.Min; - reply.Data[1].Agents = 0; - reply.Data[1].MapImageID = HYPERGRID_MAP_TEXTURE; - reply.Data[1].Name = Utils.StringToBytes("HyperGrid Portal to OSGrid"); - reply.Data[1].RegionFlags = (uint)scene.RegionFlags; - reply.Data[1].WaterHeight = (byte)scene.WaterHeight; - reply.Data[1].X = (ushort)(scene.RegionX + 1); - reply.Data[1].Y = (ushort)scene.RegionY; + for (int y = request.PositionData.MinY; y <= request.PositionData.MaxY; y++) + { + for (int x = request.PositionData.MinX; x <= request.PositionData.MaxX; x++) + { + blocks[i] = new MapBlockReplyPacket.DataBlock(); + blocks[i].X = (ushort)x; + blocks[i].Y = (ushort)y; + + // See if we have data for this region + RegionInfo? region = null; + for (int j = 0; j < regions.Count; j++) + { + if (regions[j].X == x && regions[j].Y == y) + { + region = regions[j]; + break; + } + } + + if (region.HasValue) + { + blocks[i].Access = (byte)SimAccess.Min; + blocks[i].Agents = (byte)region.Value.AgentCount; + blocks[i].MapImageID = region.Value.MapTextureID; + blocks[i].Name = Utils.StringToBytes(region.Value.Name); + blocks[i].RegionFlags = (uint)region.Value.Flags; + blocks[i].WaterHeight = (byte)region.Value.WaterHeight; + } + else + { + blocks[i].Name = Utils.EmptyBytes; + blocks[i].MapImageID = WATER_TEXTURE; + } + + ++i; + } + } + } + else + { + blocks = new MapBlockReplyPacket.DataBlock[regions.Count]; + + for (int i = 0; i < regions.Count; i++) + { + RegionInfo region = regions[i]; + + blocks[i] = new MapBlockReplyPacket.DataBlock(); + blocks[i].X = (ushort)region.X; + blocks[i].Y = (ushort)region.Y; + blocks[i].Access = (byte)SimAccess.Min; + blocks[i].Agents = (byte)region.AgentCount; + blocks[i].MapImageID = region.MapTextureID; + blocks[i].Name = Utils.StringToBytes(region.Name); + blocks[i].RegionFlags = (uint)region.Flags; + blocks[i].WaterHeight = (byte)region.WaterHeight; + } + } + + // FIXME: Handle large numbers of blocks by splitting things up + reply.Data = blocks; scene.UDP.SendPacket(agent.ID, reply, PacketCategory.Transaction); } @@ -188,11 +241,12 @@ namespace Simian scene.UDP.SendPacket(agent.ID, reply, PacketCategory.Transaction); } - else if (request.Info.RegionHandle == Utils.UIntsToLong((scene.RegionX + 1) * 256, scene.RegionY * 256)) + // FIXME: Add XML config support for HyperGrid destinations + /*else if (request.Info.RegionHandle == Utils.UIntsToLong((scene.RegionX + 1) * 256, scene.RegionY * 256)) { // Special case: adjacent simulator is the HyperGrid portal HyperGridTeleport(agent, new Uri("http://osl2.nac.uci.edu:9006/"), request.Info.Position); - } + }*/ else { TeleportFailedPacket reply = new TeleportFailedPacket(); diff --git a/Programs/Simian/Simian.cs b/Programs/Simian/Simian.cs index ac306192..cd4d0344 100644 --- a/Programs/Simian/Simian.cs +++ b/Programs/Simian/Simian.cs @@ -198,6 +198,19 @@ namespace Simian string certFile = regionConfig.GetString("RegionCertificate", null); int staticObjectLimit = regionConfig.GetInt("StaticObjectLimit", 0); int physicalObjectLimit = regionConfig.GetInt("PhysicalObjectLimit", 0); + float waterHeight = regionConfig.GetFloat("WaterHeight", 0f); + + RegionFlags regionFlags = RegionFlags.None; + if (regionConfig.GetBoolean("AllowDamage")) regionFlags |= RegionFlags.AllowDamage; + if (regionConfig.GetBoolean("SunFixed")) regionFlags |= RegionFlags.SunFixed; + if (regionConfig.GetBoolean("BlockTerraform")) regionFlags |= RegionFlags.BlockTerraform; + if (regionConfig.GetBoolean("SkipScripts")) regionFlags |= RegionFlags.SkipScripts; + if (regionConfig.GetBoolean("SkipPhysics")) regionFlags |= RegionFlags.SkipPhysics; + if (regionConfig.GetBoolean("PublicAllowed")) regionFlags |= RegionFlags.PublicAllowed; + if (regionConfig.GetBoolean("NoFly")) regionFlags |= RegionFlags.NoFly; + if (regionConfig.GetBoolean("AllowDirectTeleport")) regionFlags |= RegionFlags.AllowDirectTeleport; + if (regionConfig.GetBoolean("RestrictPushObject")) regionFlags |= RegionFlags.RestrictPushObject; + if (regionConfig.GetBoolean("AllowParcelChanges")) regionFlags |= RegionFlags.AllowParcelChanges; if (String.IsNullOrEmpty(name) || regionX == 0 || regionY == 0 || String.IsNullOrEmpty(certFile)) { @@ -205,6 +218,9 @@ namespace Simian continue; } + // TODO: Real map tile image generation, perhaps? + UUID mapTextureID = new UUID("89556747-24cb-43ed-920b-47caed15465f"); + #endregion Config Parsing #region IPEndPoint Assignment @@ -261,6 +277,10 @@ namespace Simian regionInfo.HttpServer = HttpUri; regionInfo.IPAndPort = endpoint; regionInfo.Name = name; + regionInfo.MapTextureID = mapTextureID; + regionInfo.Flags = regionFlags; + regionInfo.AgentCount = 0; + regionInfo.WaterHeight = waterHeight; regionInfo.Online = true; // Create a capability for other regions to initiate a client connection to this region regionInfo.EnableClientCap = Capabilities.CreateCapability(scene.EnableClientCapHandler, false, null); diff --git a/bin/SimianData/RegionConfig/Baboon.ini b/bin/SimianData/RegionConfig/Baboon.ini index 068b586c..7ad477ef 100644 --- a/bin/SimianData/RegionConfig/Baboon.ini +++ b/bin/SimianData/RegionConfig/Baboon.ini @@ -21,8 +21,25 @@ RegionCertificate = JunkRegionCertificate.p12 ; region yet. This path is relative to the SimianData directory DefaultTerrain = flat30m.tga +; Default water level (in meters). This can be edited in-world, and the current +; state of the simulator will override the default here +WaterHeight = 20.0 + ; Maximum number of static (non-physical) objects allowed in the scene StaticObjectLimit = 16000 ; Maximum number of physical objects allowed in the scene. This includes avatars PhysicalObjectLimit = 1000 + +; Various default region settings. These can be edited in-world, and the current +; state of the simulator will override the defaults here +AllowDamage = false +SunFixed = false +BlockTerraform = false +SkipScripts = false +SkipPhysics = false +PublicAllowed = true +NoFly = false +AllowDirectTeleport = true +RestrictPushObject = false +AllowParcelChanges = true diff --git a/bin/SimianData/RegionConfig/Capuchin.ini b/bin/SimianData/RegionConfig/Capuchin.ini index 2eb30115..23700ac7 100644 --- a/bin/SimianData/RegionConfig/Capuchin.ini +++ b/bin/SimianData/RegionConfig/Capuchin.ini @@ -21,8 +21,25 @@ RegionCertificate = JunkRegionCertificate.p12 ; region yet. This path is relative to the SimianData directory DefaultTerrain = flat30m.tga +; Default water level (in meters). This can be edited in-world, and the current +; state of the simulator will override the default here +WaterHeight = 20.0 + ; Maximum number of static (non-physical) objects allowed in the scene StaticObjectLimit = 16000 ; Maximum number of physical objects allowed in the scene. This includes avatars PhysicalObjectLimit = 1000 + +; Various default region settings. These can be edited in-world, and the current +; state of the simulator will override the defaults here +AllowDamage = false +SunFixed = false +BlockTerraform = false +SkipScripts = false +SkipPhysics = false +PublicAllowed = true +NoFly = false +AllowDirectTeleport = true +RestrictPushObject = false +AllowParcelChanges = true diff --git a/bin/SimianData/RegionConfig/Chimpanzee.ini b/bin/SimianData/RegionConfig/Chimpanzee.ini index a20d29d2..78d36933 100644 --- a/bin/SimianData/RegionConfig/Chimpanzee.ini +++ b/bin/SimianData/RegionConfig/Chimpanzee.ini @@ -21,8 +21,25 @@ RegionCertificate = JunkRegionCertificate.p12 ; region yet. This path is relative to the SimianData directory DefaultTerrain = flat30m.tga +; Default water level (in meters). This can be edited in-world, and the current +; state of the simulator will override the default here +WaterHeight = 20.0 + ; Maximum number of static (non-physical) objects allowed in the scene StaticObjectLimit = 16000 ; Maximum number of physical objects allowed in the scene. This includes avatars PhysicalObjectLimit = 1000 + +; Various default region settings. These can be edited in-world, and the current +; state of the simulator will override the defaults here +AllowDamage = false +SunFixed = false +BlockTerraform = false +SkipScripts = false +SkipPhysics = false +PublicAllowed = true +NoFly = false +AllowDirectTeleport = true +RestrictPushObject = false +AllowParcelChanges = true diff --git a/bin/SimianData/RegionConfig/Macaque.ini b/bin/SimianData/RegionConfig/Macaque.ini index c221348d..5accc70d 100644 --- a/bin/SimianData/RegionConfig/Macaque.ini +++ b/bin/SimianData/RegionConfig/Macaque.ini @@ -21,8 +21,25 @@ RegionCertificate = JunkRegionCertificate.p12 ; region yet. This path is relative to the SimianData directory DefaultTerrain = flat30m.tga +; Default water level (in meters). This can be edited in-world, and the current +; state of the simulator will override the default here +WaterHeight = 20.0 + ; Maximum number of static (non-physical) objects allowed in the scene StaticObjectLimit = 16000 ; Maximum number of physical objects allowed in the scene. This includes avatars PhysicalObjectLimit = 1000 + +; Various default region settings. These can be edited in-world, and the current +; state of the simulator will override the defaults here +AllowDamage = false +SunFixed = false +BlockTerraform = false +SkipScripts = false +SkipPhysics = false +PublicAllowed = true +NoFly = false +AllowDirectTeleport = true +RestrictPushObject = false +AllowParcelChanges = true diff --git a/bin/SimianData/RegionConfig/Mandrill.ini b/bin/SimianData/RegionConfig/Mandrill.ini index 7e596be8..64d85a97 100644 --- a/bin/SimianData/RegionConfig/Mandrill.ini +++ b/bin/SimianData/RegionConfig/Mandrill.ini @@ -21,8 +21,25 @@ RegionCertificate = JunkRegionCertificate.p12 ; region yet. This path is relative to the SimianData directory DefaultTerrain = flat30m.tga +; Default water level (in meters). This can be edited in-world, and the current +; state of the simulator will override the default here +WaterHeight = 20.0 + ; Maximum number of static (non-physical) objects allowed in the scene StaticObjectLimit = 16000 ; Maximum number of physical objects allowed in the scene. This includes avatars PhysicalObjectLimit = 1000 + +; Various default region settings. These can be edited in-world, and the current +; state of the simulator will override the defaults here +AllowDamage = false +SunFixed = false +BlockTerraform = false +SkipScripts = false +SkipPhysics = false +PublicAllowed = true +NoFly = false +AllowDirectTeleport = true +RestrictPushObject = false +AllowParcelChanges = true diff --git a/bin/SimianData/RegionConfig/Marmoset.ini b/bin/SimianData/RegionConfig/Marmoset.ini index efb9b017..dcae28c3 100644 --- a/bin/SimianData/RegionConfig/Marmoset.ini +++ b/bin/SimianData/RegionConfig/Marmoset.ini @@ -21,8 +21,25 @@ RegionCertificate = JunkRegionCertificate.p12 ; region yet. This path is relative to the SimianData directory DefaultTerrain = flat30m.tga +; Default water level (in meters). This can be edited in-world, and the current +; state of the simulator will override the default here +WaterHeight = 20.0 + ; Maximum number of static (non-physical) objects allowed in the scene StaticObjectLimit = 16000 ; Maximum number of physical objects allowed in the scene. This includes avatars PhysicalObjectLimit = 1000 + +; Various default region settings. These can be edited in-world, and the current +; state of the simulator will override the defaults here +AllowDamage = false +SunFixed = false +BlockTerraform = false +SkipScripts = false +SkipPhysics = false +PublicAllowed = true +NoFly = false +AllowDirectTeleport = true +RestrictPushObject = false +AllowParcelChanges = true diff --git a/bin/SimianData/RegionConfig/Orangutan.ini b/bin/SimianData/RegionConfig/Orangutan.ini index 8e5208e1..7b47e2cb 100644 --- a/bin/SimianData/RegionConfig/Orangutan.ini +++ b/bin/SimianData/RegionConfig/Orangutan.ini @@ -21,8 +21,25 @@ RegionCertificate = JunkRegionCertificate.p12 ; region yet. This path is relative to the SimianData directory DefaultTerrain = flat30m.tga +; Default water level (in meters). This can be edited in-world, and the current +; state of the simulator will override the default here +WaterHeight = 20.0 + ; Maximum number of static (non-physical) objects allowed in the scene StaticObjectLimit = 16000 ; Maximum number of physical objects allowed in the scene. This includes avatars PhysicalObjectLimit = 1000 + +; Various default region settings. These can be edited in-world, and the current +; state of the simulator will override the defaults here +AllowDamage = false +SunFixed = false +BlockTerraform = false +SkipScripts = false +SkipPhysics = false +PublicAllowed = true +NoFly = false +AllowDirectTeleport = true +RestrictPushObject = false +AllowParcelChanges = true diff --git a/bin/SimianData/RegionConfig/Spider Monkey.ini b/bin/SimianData/RegionConfig/Spider Monkey.ini index 4acb46ba..510def53 100644 --- a/bin/SimianData/RegionConfig/Spider Monkey.ini +++ b/bin/SimianData/RegionConfig/Spider Monkey.ini @@ -21,8 +21,25 @@ RegionCertificate = JunkRegionCertificate.p12 ; region yet. This path is relative to the SimianData directory DefaultTerrain = flat30m.tga +; Default water level (in meters). This can be edited in-world, and the current +; state of the simulator will override the default here +WaterHeight = 20.0 + ; Maximum number of static (non-physical) objects allowed in the scene StaticObjectLimit = 16000 ; Maximum number of physical objects allowed in the scene. This includes avatars PhysicalObjectLimit = 1000 + +; Various default region settings. These can be edited in-world, and the current +; state of the simulator will override the defaults here +AllowDamage = false +SunFixed = false +BlockTerraform = false +SkipScripts = false +SkipPhysics = false +PublicAllowed = true +NoFly = false +AllowDirectTeleport = true +RestrictPushObject = false +AllowParcelChanges = true diff --git a/bin/SimianData/RegionConfig/Tamarin.ini b/bin/SimianData/RegionConfig/Tamarin.ini index b30e4e02..45ba13c8 100644 --- a/bin/SimianData/RegionConfig/Tamarin.ini +++ b/bin/SimianData/RegionConfig/Tamarin.ini @@ -21,8 +21,25 @@ RegionCertificate = JunkRegionCertificate.p12 ; region yet. This path is relative to the SimianData directory DefaultTerrain = flat30m.tga +; Default water level (in meters). This can be edited in-world, and the current +; state of the simulator will override the default here +WaterHeight = 20.0 + ; Maximum number of static (non-physical) objects allowed in the scene StaticObjectLimit = 16000 ; Maximum number of physical objects allowed in the scene. This includes avatars PhysicalObjectLimit = 1000 + +; Various default region settings. These can be edited in-world, and the current +; state of the simulator will override the defaults here +AllowDamage = false +SunFixed = false +BlockTerraform = false +SkipScripts = false +SkipPhysics = false +PublicAllowed = true +NoFly = false +AllowDirectTeleport = true +RestrictPushObject = false +AllowParcelChanges = true