Merge branch 'master' of brain.opensimulator.org:/var/git/opensim

0.9.1.0-post-fixes
Melanie 2019-07-27 12:10:28 +01:00
commit d6723dab37
83 changed files with 4787 additions and 2668 deletions

View File

@ -249,7 +249,7 @@ namespace OpenSim.Groups
// There might be some problem with the thread we're generating this on but not
// doing the update at this time causes problems (Mantis #7920 and #7915)
// TODO: move sending this update to a later time in the rootification of the client.
if(!sp.haveGroupInformation)
if(!sp.m_haveGroupInformation)
SendAgentGroupDataUpdate(sp.ControllingClient, false);
}

View File

@ -173,6 +173,7 @@ namespace OpenSim.Framework
/// Position the Agent's Avatar starts in the region
/// </summary>
public Vector3 startpos;
public float startfar = -1.0f;
public Dictionary<string, object> ServiceURLs;
@ -219,6 +220,8 @@ namespace OpenSim.Framework
args["channel"] = OSD.FromString(Channel);
args["mac"] = OSD.FromString(Mac);
args["id0"] = OSD.FromString(Id0);
if(startfar > 0)
args["far"] = OSD.FromReal(startfar);
if (Appearance != null)
{
@ -327,6 +330,9 @@ namespace OpenSim.Framework
if (args["start_pos"] != null)
Vector3.TryParse(args["start_pos"].AsString(), out startpos);
if(args["far"] != null)
startfar = (float)args["far"].AsReal();
//m_log.InfoFormat("[AGENTCIRCUITDATA]: agentid={0}, child={1}, startpos={2}", AgentID, child, startpos);
try

View File

@ -79,6 +79,7 @@ namespace OpenSim.Framework
user.LoginInfo.InventoryFolder = validcircuit.InventoryFolder;
user.LoginInfo.BaseFolder = validcircuit.BaseFolder;
user.LoginInfo.StartPos = validcircuit.startpos;
user.LoginInfo.StartFar = (float)validcircuit.startfar;
}
else
{
@ -175,7 +176,8 @@ namespace OpenSim.Framework
{
m_agentCircuits[(uint) agentData.circuitcode].firstname = agentData.firstname;
m_agentCircuits[(uint) agentData.circuitcode].lastname = agentData.lastname;
m_agentCircuits[(uint) agentData.circuitcode].startpos = agentData.startpos;
m_agentCircuits[(uint)agentData.circuitcode].startpos = agentData.startpos;
m_agentCircuits[(uint)agentData.circuitcode].startfar = agentData.startfar;
// Updated for when we don't know them before calling Scene.NewUserConnection
m_agentCircuits[(uint) agentData.circuitcode].SecureSessionID = agentData.SecureSessionID;

View File

@ -398,7 +398,8 @@ namespace OpenSim.Framework
// Scripted
public ControllerData[] Controllers;
public string CallbackURI;
public string CallbackURI; // to remove
public string NewCallbackURI;
// These two must have the same Count
public List<ISceneObject> AttachmentObjects;
@ -528,6 +529,9 @@ namespace OpenSim.Framework
if ((CallbackURI != null) && (!CallbackURI.Equals("")))
args["callback_uri"] = OSD.FromString(CallbackURI);
if ((NewCallbackURI != null) && (!NewCallbackURI.Equals("")))
args["cb_uri"] = OSD.FromString(NewCallbackURI);
// Attachment objects for fatpack messages
if (AttachmentObjects != null)
{
@ -811,12 +815,7 @@ namespace OpenSim.Framework
}
// end of code to remove
}
/* moved above
if (args.ContainsKey("packed_appearance") && (args["packed_appearance"]).Type == OSDType.Map)
Appearance = new AvatarAppearance((OSDMap)args["packed_appearance"]);
else
m_log.WarnFormat("[CHILDAGENTDATAUPDATE] No packed appearance");
*/
if ((args["controllers"] != null) && (args["controllers"]).Type == OSDType.Array)
{
OSDArray controls = (OSDArray)(args["controllers"]);
@ -834,6 +833,9 @@ namespace OpenSim.Framework
if (args["callback_uri"] != null)
CallbackURI = args["callback_uri"].AsString();
if (args["cb_uri"] != null)
NewCallbackURI = args["cb_uri"].AsString();
// Attachment objects
if (args["attach_objects"] != null && args["attach_objects"].Type == OSDType.Array)
{

View File

@ -153,7 +153,7 @@ namespace OpenSim.Framework
private bool m_DenyAnonymous = false;
public bool DenyAnonymous
{
get { return m_DenyAnonymous; }
get { return (DoDenyAnonymous && m_DenyAnonymous); }
set { m_DenyAnonymous = value; }
}
@ -233,7 +233,7 @@ namespace OpenSim.Framework
private bool m_DenyMinors = false;
public bool DenyMinors
{
get { return m_DenyMinors; }
get { return (DoDenyMinors && m_DenyMinors); }
set { m_DenyMinors = value; }
}
@ -379,14 +379,14 @@ namespace OpenSim.Framework
if (!HasAccess(avatarID))
{
if (DoDenyMinors && DenyMinors)
if (DenyMinors)
{
if ((userFlags & 32) == 0)
{
return true;
}
}
if (DoDenyAnonymous && DenyAnonymous)
if (DenyAnonymous)
{
if ((userFlags & 4) == 0)
{

View File

@ -596,22 +596,33 @@ namespace OpenSim.Framework
public PrimUpdateFlags Flags
{
get { return m_flags; }
set { m_flags = value; }
}
public virtual void Update()
{
// we are on the new one
if (m_flags.HasFlag(PrimUpdateFlags.CancelKill))
m_flags = PrimUpdateFlags.FullUpdatewithAnim;
{
if (m_flags.HasFlag(PrimUpdateFlags.UpdateProbe))
m_flags = PrimUpdateFlags.UpdateProbe;
else
m_flags = PrimUpdateFlags.FullUpdatewithAnim;
}
}
public virtual void Update(EntityUpdate oldupdate)
{
// we are on the new one
PrimUpdateFlags updateFlags = oldupdate.Flags;
if (updateFlags.HasFlag(PrimUpdateFlags.UpdateProbe))
updateFlags &= ~PrimUpdateFlags.UpdateProbe;
if (m_flags.HasFlag(PrimUpdateFlags.CancelKill))
{
m_flags = PrimUpdateFlags.FullUpdatewithAnim;
if(m_flags.HasFlag(PrimUpdateFlags.UpdateProbe))
m_flags = PrimUpdateFlags.UpdateProbe;
else
m_flags = PrimUpdateFlags.FullUpdatewithAnim;
}
else
m_flags |= updateFlags;
@ -679,6 +690,7 @@ namespace OpenSim.Framework
FullUpdatewithAnim = FullUpdate | Animations,
UpdateProbe = 0x10000000, // 1 << 28
SendInTransit = 0x20000000, // 1 << 29
CancelKill = 0x40000000, // 1 << 30
Kill = 0x80000000 // 1 << 31
@ -696,6 +708,7 @@ namespace OpenSim.Framework
public interface IClientAPI
{
Vector3 StartPos { get; set; }
float StartFar { get; set; }
UUID AgentId { get; }
@ -1097,8 +1110,6 @@ namespace OpenSim.Framework
void SendCachedTextureResponse(ISceneEntity avatar, int serial, List<CachedTextureResponseArg> cachedTextures);
void SendStartPingCheck(byte seq);
/// <summary>
/// Tell the client that an object has been deleted
/// </summary>
@ -1108,7 +1119,7 @@ namespace OpenSim.Framework
// void SendPartFullUpdate(ISceneEntity ent, uint? parentID);
void SendAnimations(UUID[] animID, int[] seqs, UUID sourceAgentId, UUID[] objectIDs);
void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args);
void SendRegionHandshake();
/// <summary>
/// Send chat to the viewer.
@ -1224,7 +1235,8 @@ namespace OpenSim.Framework
/// <param name="node"></param>
void SendBulkUpdateInventory(InventoryNodeBase node);
void SendXferPacket(ulong xferID, uint packet, byte[] data, bool isTaskInventory);
void SendXferPacket(ulong xferID, uint packet,
byte[] XferData, int XferDataOffset, int XferDatapktLen, bool isTaskInventory);
void SendAbortXferPacket(ulong xferID);
@ -1502,6 +1514,6 @@ namespace OpenSim.Framework
void SendAgentTerseUpdate(ISceneEntity presence);
void SendPlacesReply(UUID queryID, UUID transactionID, PlacesReplyData[] data);
void CheckViewerCaps();
uint GetViewerCaps();
}
}

View File

@ -98,6 +98,6 @@ namespace OpenSim.Region.Framework.Interfaces
void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id);
void Subdivide(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id);
void sendClientInitialLandInfo(IClientAPI remoteClient);
void sendClientInitialLandInfo(IClientAPI remoteClient, bool overlay);
}
}

View File

@ -70,14 +70,6 @@ namespace OpenSim.Framework
AvatarAppearance Appearance { get; set; }
/// <summary>
/// Send initial scene data to the client controlling this agent
/// </summary>
/// <remarks>
/// This includes scene object data and the appearance data of other avatars.
/// </remarks>
void SendInitialDataToMe();
/// <summary>
/// Direction in which the scene presence is looking.
/// </summary>
/// <remarks>Will be Vector3.Zero for a child agent.</remarks>

View File

@ -42,11 +42,13 @@ namespace OpenSim.Framework
public UUID SecureSession = UUID.Zero;
public UUID Session;
public Vector3 StartPos;
public float StartFar;
public AvatarAppearance Appearance;
public Login()
{
StartPos = new Vector3(128, 128, 70);
StartFar = -1;
}
}
}

View File

@ -1039,6 +1039,7 @@ namespace OpenSim.Framework
const byte LightEP = 0x20;
const byte SculptEP = 0x30;
const byte ProjectionEP = 0x40;
//const byte MeshEP = 0x60;
const byte MeshFlagsEP = 0x70;
int TotalBytesLength = 1; // ExtraParamsNum
@ -1121,7 +1122,10 @@ namespace OpenSim.Framework
if (_sculptEntry)
{
returnBytes[i] = SculptEP;
//if(_sculptType == 5)
// returnBytes[i] = MeshEP;
//else
returnBytes[i] = SculptEP;
i += 2;
returnBytes[i] = 17;
i += 4;
@ -1164,6 +1168,7 @@ namespace OpenSim.Framework
const ushort LightEP = 0x20;
const ushort SculptEP = 0x30;
const ushort ProjectionEP = 0x40;
const ushort MeshEP = 0x60;
const ushort MeshFlagsEP = 0x70;
switch (type)
@ -1186,6 +1191,7 @@ namespace OpenSim.Framework
ReadLightData(data, 0);
break;
case MeshEP:
case SculptEP:
if (!inUse)
{
@ -1231,6 +1237,7 @@ namespace OpenSim.Framework
const byte LightEP = 0x20;
const byte SculptEP = 0x30;
const byte ProjectionEP = 0x40;
const byte MeshEP = 0x60;
const byte MeshFlagsEP = 0x70;
byte extraParamCount = data[0];
@ -1252,6 +1259,7 @@ namespace OpenSim.Framework
i += 16;
break;
case MeshEP:
case SculptEP:
ReadSculptData(data, i);
i += 17;

View File

@ -180,6 +180,7 @@ namespace OpenSim.Framework
private Dictionary<String, String> m_extraSettings = new Dictionary<string, string>();
public UUID CacheID { get; set;}
// Apparently, we're applying the same estatesettings regardless of whether it's local or remote.
// MT: Yes. Estates can't span trust boundaries. Therefore, it can be
@ -196,6 +197,7 @@ namespace OpenSim.Framework
public RegionInfo(string description, string filename, bool skipConsoleConfig, IConfigSource configSource, string configName)
{
// m_configSource = configSource;
CacheID = UUID.Random();
if (filename.ToLower().EndsWith(".ini"))
{
@ -255,6 +257,7 @@ namespace OpenSim.Framework
ReadNiniConfig(source, name);
m_serverURI = string.Empty;
CacheID = UUID.Random();
}
public RegionInfo(uint legacyRegionLocX, uint legacyRegionLocY, IPEndPoint internalEndPoint, string externalUri)
@ -266,11 +269,13 @@ namespace OpenSim.Framework
m_internalEndPoint = internalEndPoint;
m_externalHostName = externalUri;
m_serverURI = string.Empty;
CacheID = UUID.Random();
}
public RegionInfo()
{
m_serverURI = string.Empty;
CacheID = UUID.Random();
}
public EstateSettings EstateSettings

View File

@ -33,7 +33,7 @@ namespace OpenSim.Framework
{
public float billableFactor;
public uint estateID;
public byte maxAgents;
public int maxAgents;
public float objectBonusFactor;
public uint parentEstateID;
public int pricePerMeter;
@ -48,5 +48,7 @@ namespace OpenSim.Framework
public float waterHeight;
public string simName;
public string regionType;
public int AgentCapacity;
public int ObjectsCapacity;
}
}

View File

@ -309,7 +309,8 @@ namespace OpenSim.Framework.Servers.HttpServer
{
Thread.ResetAbort();
// Shouldn't set this to 'false', the normal shutdown should cause things to exit
// m_running = false;
// but robust is still not normal neither is mono
m_running = false;
}
catch (Exception e)
{

View File

@ -77,6 +77,9 @@ namespace OpenSim.Region.ClientStack.LindenCaps
{
RegisterCaps(agentID, caps);
};
ISimulatorFeaturesModule simFeatures = scene.RequestModuleInterface<ISimulatorFeaturesModule>();
if(simFeatures != null)
simFeatures.AddFeature("AvatarHoverHeightEnabled",OSD.FromBoolean(true));
}
public void PostInitialise() {}

View File

@ -61,7 +61,7 @@ namespace OpenSim.Region.ClientStack.Linden
string assetName, string description, UUID assetID, UUID inventoryItem, UUID parentFolder,
byte[] data, string inventoryType, string assetType,
int cost, UUID texturesFolder, int nreqtextures, int nreqmeshs, int nreqinstances,
bool IsAtestUpload, ref string error, ref int nextOwnerMask, ref int groupMask, ref int everyoneMask);
bool IsAtestUpload, ref string error, ref int nextOwnerMask, ref int groupMask, ref int everyoneMask, int[] meshesSides);
public delegate UUID UpdateItem(UUID itemID, byte[] data);
@ -505,7 +505,7 @@ namespace OpenSim.Region.ClientStack.Linden
case FileAgentInventoryState.processRequest:
case FileAgentInventoryState.processUpload:
LLSDAssetUploadError resperror = new LLSDAssetUploadError();
resperror.message = "Uploader busy processing previus request";
resperror.message = "Uploader busy processing previous request";
resperror.identifier = UUID.Zero;
LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse();
@ -529,6 +529,7 @@ namespace OpenSim.Region.ClientStack.Linden
int nreqmeshs= 0;
int nreqinstances = 0;
bool IsAtestUpload = false;
int[] meshesSides = null;
string assetName = llsdRequest.name;
@ -578,9 +579,8 @@ namespace OpenSim.Region.ClientStack.Linden
string error;
int modelcost;
if (!m_ModelCost.MeshModelCost(llsdRequest.asset_resources, baseCost, out modelcost,
meshcostdata, out error, ref warning))
meshcostdata, out error, ref warning, out meshesSides))
{
LLSDAssetUploadError resperror = new LLSDAssetUploadError();
resperror.message = error;
@ -668,7 +668,7 @@ namespace OpenSim.Region.ClientStack.Linden
new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type,
llsdRequest.asset_type, uploaderPath, m_HostCapsObj.HttpListener, m_dumpAssetsToFile, cost,
texturesFolder, nreqtextures, nreqmeshs, nreqinstances, IsAtestUpload,
llsdRequest.next_owner_mask, llsdRequest.group_mask, llsdRequest.everyone_mask);
llsdRequest.next_owner_mask, llsdRequest.group_mask, llsdRequest.everyone_mask, meshesSides);
m_HostCapsObj.HttpListener.AddStreamHandler(
new BinaryStreamHandler(
@ -713,7 +713,7 @@ namespace OpenSim.Region.ClientStack.Linden
string assetType, int cost,
UUID texturesFolder, int nreqtextures, int nreqmeshs, int nreqinstances,
bool IsAtestUpload, ref string error,
ref int nextOwnerMask, ref int groupMask, ref int everyoneMask)
ref int nextOwnerMask, ref int groupMask, ref int everyoneMask, int[] meshesSides)
{
lock (m_ModelCost)
m_FileAgentInventoryState = FileAgentInventoryState.processUpload;
@ -967,7 +967,12 @@ namespace OpenSim.Region.ClientStack.Linden
{
int meshindx = inner_instance_list["mesh"].AsInteger();
if (meshAssets.Count > meshindx)
pbs = PrimitiveBaseShape.CreateMesh(face_list.Count, meshAssets[meshindx]);
{
if(meshesSides != null && meshesSides.Length > meshindx)
pbs = PrimitiveBaseShape.CreateMesh(meshesSides[i], meshAssets[meshindx]);
else
pbs = PrimitiveBaseShape.CreateMesh(face_list.Count, meshAssets[meshindx]);
}
}
if(pbs == null) // fallback
pbs = PrimitiveBaseShape.CreateBox();
@ -1012,17 +1017,25 @@ namespace OpenSim.Region.ClientStack.Linden
textureEntry.FaceTextures[face] = f;
}
pbs.TextureEntry = textureEntry.GetBytes();
if(face_list.Count > 0)
{
int last = face_list.Count - 1;
// we do need a better te compacting code
textureEntry.DefaultTexture = textureEntry.FaceTextures[last];
textureEntry.FaceTextures[last] = null;
pbs.TextureEntry = textureEntry.GetBytes(last);
}
Vector3 position = inner_instance_list["position"].AsVector3();
Quaternion rotation = inner_instance_list["rotation"].AsQuaternion();
// for now viwers do send fixed defaults
// but this may change
// int physicsShapeType = inner_instance_list["physics_shape_type"].AsInteger();
byte physicsShapeType = (byte)PhysShapeType.convex; // default is simple convex
// int material = inner_instance_list["material"].AsInteger();
if (inner_instance_list.ContainsKey("physics_shape_type"))
physicsShapeType = (byte)inner_instance_list["physics_shape_type"].AsInteger();
byte material = (byte)Material.Wood;
if (inner_instance_list.ContainsKey("material"))
material = (byte)inner_instance_list["material"].AsInteger();
SceneObjectPart prim
= new SceneObjectPart(owner_id, pbs, position, Quaternion.Identity, Vector3.Zero);
@ -2006,13 +2019,13 @@ namespace OpenSim.Region.ClientStack.Linden
private int m_nextOwnerMask;
private int m_groupMask;
private int m_everyoneMask;
private int[] m_meshesSides;
public AssetUploader(string assetName, string description, UUID assetID, UUID inventoryItem,
UUID parentFolderID, string invType, string assetType, string path,
IHttpServer httpServer, bool dumpAssetsToFile,
int totalCost, UUID texturesFolder, int nreqtextures, int nreqmeshs, int nreqinstances,
bool IsAtestUpload, int nextOwnerMask, int groupMask, int everyoneMask)
bool IsAtestUpload, int nextOwnerMask, int groupMask, int everyoneMask, int[] meshesSides)
{
m_assetName = assetName;
m_assetDes = description;
@ -2040,6 +2053,8 @@ namespace OpenSim.Region.ClientStack.Linden
m_nextOwnerMask = nextOwnerMask;
m_groupMask = groupMask;
m_everyoneMask = everyoneMask;
m_meshesSides = meshesSides;
}
/// <summary>
@ -2080,7 +2095,7 @@ namespace OpenSim.Region.ClientStack.Linden
{
handlerUpLoad(m_assetName, m_assetDes, newAssetID, inv, parentFolder, data, m_invType, m_assetType,
m_cost, m_texturesFolder, m_nreqtextures, m_nreqmeshs, m_nreqinstances, m_IsAtestUpload,
ref m_error, ref m_nextOwnerMask, ref m_groupMask, ref m_everyoneMask);
ref m_error, ref m_nextOwnerMask, ref m_groupMask, ref m_everyoneMask, m_meshesSides);
}
uploadComplete.new_next_owner_mask = m_nextOwnerMask;

View File

@ -40,7 +40,7 @@ using OpenSim.Region.Framework;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Framework.Capabilities;
using ComponentAce.Compression.Libs.zlib;
using System.IO.Compression;
using OSDArray = OpenMetaverse.StructuredData.OSDArray;
using OSDMap = OpenMetaverse.StructuredData.OSDMap;
@ -129,6 +129,7 @@ namespace OpenSim.Region.ClientStack.Linden
public int medLODSize;
public int lowLODSize;
public int lowestLODSize;
public int highLODsides;
// normalized fee based on compressed data sizes
public float costFee;
// physics cost
@ -144,11 +145,11 @@ namespace OpenSim.Region.ClientStack.Linden
// avatarSkeleton if mesh includes a avatar skeleton
// useAvatarCollider if we should use physics mesh for avatar
public bool MeshModelCost(LLSDAssetResource resources, int basicCost, out int totalcost,
LLSDAssetUploadResponseData meshcostdata, out string error, ref string warning)
LLSDAssetUploadResponseData meshcostdata, out string error, ref string warning, out int[] meshesSides)
{
totalcost = 0;
error = string.Empty;
meshesSides = null;
bool avatarSkeleton = false;
if (resources == null ||
@ -203,13 +204,14 @@ namespace OpenSim.Region.ClientStack.Linden
if (resources.mesh_list != null && resources.mesh_list.Array.Count > 0)
{
numberMeshs = resources.mesh_list.Array.Count;
meshesSides = new int[numberMeshs];
for (int i = 0; i < numberMeshs; i++)
{
ameshCostParam curCost = new ameshCostParam();
byte[] data = (byte[])resources.mesh_list.Array[i];
if (!MeshCost(data, curCost,out curskeleton, out curAvatarPhys, out error))
if (!MeshCost(data, curCost, out curskeleton, out curAvatarPhys, out error))
{
return false;
}
@ -225,6 +227,7 @@ namespace OpenSim.Region.ClientStack.Linden
}
meshsCosts.Add(curCost);
meshsfee += curCost.costFee;
meshesSides[i] = curCost.highLODsides;
}
haveMeshs = true;
}
@ -275,6 +278,7 @@ namespace OpenSim.Region.ClientStack.Linden
float sqdiam = scale.LengthSquared();
ameshCostParam curCost = meshsCosts[mesh];
float mesh_streaming = streamingCost(curCost, sqdiam);
meshcostdata.model_streaming_cost += mesh_streaming;
@ -339,6 +343,7 @@ namespace OpenSim.Region.ClientStack.Linden
private bool MeshCost(byte[] data, ameshCostParam cost,out bool skeleton, out bool avatarPhys, out string error)
{
cost.highLODSize = 0;
cost.highLODsides = 0;
cost.medLODSize = 0;
cost.lowLODSize = 0;
cost.lowestLODSize = 0;
@ -430,7 +435,8 @@ namespace OpenSim.Region.ClientStack.Linden
submesh_offset = -1;
// only look for LOD meshs sizes
int nsides = 0;
int lod_ntriangles = 0;
if (map.ContainsKey("high_lod"))
{
@ -440,6 +446,15 @@ namespace OpenSim.Region.ClientStack.Linden
submesh_offset = tmpmap["offset"].AsInteger() + start;
if (tmpmap.ContainsKey("size"))
highlod_size = tmpmap["size"].AsInteger();
if (submesh_offset >= 0 && highlod_size > 0)
{
if (!submesh(data, submesh_offset, highlod_size, out lod_ntriangles, out nsides))
{
error = "Model data parsing error";
return false;
}
}
}
if (submesh_offset < 0 || highlod_size <= 0)
@ -483,6 +498,7 @@ namespace OpenSim.Region.ClientStack.Linden
}
cost.highLODSize = highlod_size;
cost.highLODsides = nsides;
cost.medLODSize = medlod_size;
cost.lowLODSize = lowlod_size;
cost.lowestLODSize = lowestlod_size;
@ -495,6 +511,7 @@ namespace OpenSim.Region.ClientStack.Linden
else if (map.ContainsKey("physics_shape")) // old naming
tmpmap = (OSDMap)map["physics_shape"];
int phys_nsides = 0;
if(tmpmap != null)
{
if (tmpmap.ContainsKey("offset"))
@ -502,10 +519,9 @@ namespace OpenSim.Region.ClientStack.Linden
if (tmpmap.ContainsKey("size"))
physmesh_size = tmpmap["size"].AsInteger();
if (submesh_offset >= 0 || physmesh_size > 0)
if (submesh_offset >= 0 && physmesh_size > 0)
{
if (!submesh(data, submesh_offset, physmesh_size, out phys_ntriangles))
if (!submesh(data, submesh_offset, physmesh_size, out phys_ntriangles, out phys_nsides))
{
error = "Model data parsing error";
return false;
@ -541,34 +557,30 @@ namespace OpenSim.Region.ClientStack.Linden
}
// parses a LOD or physics mesh component
private bool submesh(byte[] data, int offset, int size, out int ntriangles)
private bool submesh(byte[] data, int offset, int size, out int ntriangles, out int nsides)
{
ntriangles = 0;
nsides = 0;
OSD decodedMeshOsd = new OSD();
byte[] meshBytes = new byte[size];
System.Buffer.BlockCopy(data, offset, meshBytes, 0, size);
try
{
using (MemoryStream inMs = new MemoryStream(meshBytes))
using (MemoryStream outMs = new MemoryStream())
{
using (MemoryStream outMs = new MemoryStream())
using (MemoryStream inMs = new MemoryStream(data, offset, size))
{
using (ZOutputStream zOut = new ZOutputStream(outMs))
using (DeflateStream decompressionStream = new DeflateStream(inMs, CompressionMode.Decompress))
{
byte[] readBuffer = new byte[4096];
byte[] readBuffer = new byte[2048];
inMs.Read(readBuffer, 0, 2); // skip first 2 bytes in header
int readLen = 0;
while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0)
{
zOut.Write(readBuffer, 0, readLen);
}
zOut.Flush();
outMs.Seek(0, SeekOrigin.Begin);
byte[] decompressedBuf = outMs.GetBuffer();
decodedMeshOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf);
while ((readLen = decompressionStream.Read(readBuffer, 0, readBuffer.Length)) > 0)
outMs.Write(readBuffer, 0, readLen);
}
}
outMs.Seek(0, SeekOrigin.Begin);
decodedMeshOsd = OSDParser.DeserializeLLSDBinary(outMs);
}
}
catch
@ -599,6 +611,7 @@ namespace OpenSim.Region.ClientStack.Linden
}
else
return false;
nsides++;
}
}
@ -612,29 +625,24 @@ namespace OpenSim.Region.ClientStack.Linden
nhulls = 1;
OSD decodedMeshOsd = new OSD();
byte[] meshBytes = new byte[size];
System.Buffer.BlockCopy(data, offset, meshBytes, 0, size);
try
{
using (MemoryStream inMs = new MemoryStream(meshBytes))
using (MemoryStream outMs = new MemoryStream(4 * size))
{
using (MemoryStream outMs = new MemoryStream())
using (MemoryStream inMs = new MemoryStream(data, offset, size))
{
using (ZOutputStream zOut = new ZOutputStream(outMs))
using (DeflateStream decompressionStream = new DeflateStream(inMs, CompressionMode.Decompress))
{
byte[] readBuffer = new byte[4096];
byte[] readBuffer = new byte[8192];
inMs.Read(readBuffer, 0, 2); // skip first 2 bytes in header
int readLen = 0;
while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0)
{
zOut.Write(readBuffer, 0, readLen);
}
zOut.Flush();
outMs.Seek(0, SeekOrigin.Begin);
byte[] decompressedBuf = outMs.GetBuffer();
decodedMeshOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf);
while ((readLen = decompressionStream.Read(readBuffer, 0, readBuffer.Length)) > 0)
outMs.Write(readBuffer, 0, readLen);
}
}
outMs.Seek(0, SeekOrigin.Begin);
decodedMeshOsd = OSDParser.DeserializeLLSDBinary(outMs);
}
}
catch
@ -716,7 +724,7 @@ namespace OpenSim.Region.ClientStack.Linden
int m = curCost.medLODSize - 384;
int h = curCost.highLODSize - 384;
// use previus higher LOD size on missing ones
// use previous higher LOD size on missing ones
if (m <= 0)
m = h;
if (l <= 0)

View File

@ -233,7 +233,7 @@ namespace OpenSim.Region.ClientStack.Linden
else
{
m_log.WarnFormat(
"[EVENTQUEUE]: (Enqueue) No queue found for agent {0} in region {2}",
"[EVENTQUEUE]: (Enqueue) No queue found for agent {0} in region {1}",
avatarID, m_scene.Name);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -148,7 +148,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// milliseconds or longer will be resent</summary>
/// <remarks>Calculated from <seealso cref="SRTT"/> and <seealso cref="RTTVAR"/> using the
/// guidelines in RFC 2988</remarks>
public int RTO;
public int m_RTO;
/// <summary>Number of bytes received since the last acknowledgement was sent out. This is used
/// to loosely follow the TCP delayed ACK algorithm in RFC 1122 (4.2.3.2)</summary>
public int BytesSinceLastACK;
@ -190,12 +190,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private byte[] m_packedThrottles;
private int m_defaultRTO = 1000; // 1sec is the recommendation in the RFC
private int m_maxRTO = 60000;
private int m_maxRTO = 10000;
public bool m_deliverPackets = true;
private float m_burstTime;
public int m_lastStartpingTimeMS;
public double m_lastStartpingTimeMS;
public int m_pingMS;
public int PingTimeMS
@ -242,7 +242,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (maxRTO != 0)
m_maxRTO = maxRTO;
m_burstTime = rates.BrustTime;
m_burstTime = rates.BurstTime;
float m_burst = rates.ClientMaxRate * m_burstTime;
// Create a token bucket throttle for this client that has the scene token bucket as a parent
@ -251,7 +251,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Create an array of token buckets for this clients different throttle categories
m_throttleCategories = new TokenBucket[THROTTLE_CATEGORY_COUNT];
m_burst = rates.Total * rates.BrustTime;
m_burst = rates.Total * rates.BurstTime;
for (int i = 0; i < THROTTLE_CATEGORY_COUNT; i++)
{
@ -260,11 +260,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Initialize the packet outboxes, where packets sit while they are waiting for tokens
m_packetOutboxes[i] = new DoubleLocklessQueue<OutgoingPacket>();
// Initialize the token buckets that control the throttling for each category
m_throttleCategories[i] = new TokenBucket(m_throttleClient, rates.GetRate(type), m_burst);
//m_throttleCategories[i] = new TokenBucket(m_throttleClient, rates.GetRate(type), m_burst);
float rate = rates.GetRate(type);
float burst = rate * rates.BurstTime;
m_throttleCategories[i] = new TokenBucket(m_throttleClient, rate , burst);
}
// Default the retransmission timeout to one second
RTO = m_defaultRTO;
m_RTO = m_defaultRTO;
// Initialize this to a sane value to prevent early disconnects
TickLastPacketReceived = Environment.TickCount & Int32.MaxValue;
@ -443,7 +446,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
int total = resend + land + wind + cloud + task + texture + asset;
float m_burst = total * m_burstTime;
//float m_burst = total * m_burstTime;
if (ThrottleDebugLevel > 0)
{
@ -453,7 +456,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
TokenBucket bucket;
/*
bucket = m_throttleCategories[(int)ThrottleOutPacketType.Resend];
bucket.RequestedDripRate = resend;
bucket.RequestedBurst = m_burst;
@ -481,6 +484,34 @@ namespace OpenSim.Region.ClientStack.LindenUDP
bucket = m_throttleCategories[(int)ThrottleOutPacketType.Texture];
bucket.RequestedDripRate = texture;
bucket.RequestedBurst = m_burst;
*/
bucket = m_throttleCategories[(int)ThrottleOutPacketType.Resend];
bucket.RequestedDripRate = resend;
bucket.RequestedBurst = resend * m_burstTime;
bucket = m_throttleCategories[(int)ThrottleOutPacketType.Land];
bucket.RequestedDripRate = land;
bucket.RequestedBurst = land * m_burstTime;
bucket = m_throttleCategories[(int)ThrottleOutPacketType.Wind];
bucket.RequestedDripRate = wind;
bucket.RequestedBurst = wind * m_burstTime;
bucket = m_throttleCategories[(int)ThrottleOutPacketType.Cloud];
bucket.RequestedDripRate = cloud;
bucket.RequestedBurst = cloud * m_burstTime;
bucket = m_throttleCategories[(int)ThrottleOutPacketType.Asset];
bucket.RequestedDripRate = asset;
bucket.RequestedBurst = asset * m_burstTime;
bucket = m_throttleCategories[(int)ThrottleOutPacketType.Task];
bucket.RequestedDripRate = task;
bucket.RequestedBurst = task * m_burstTime;
bucket = m_throttleCategories[(int)ThrottleOutPacketType.Texture];
bucket.RequestedDripRate = texture;
bucket.RequestedBurst = texture * m_burstTime;
// Reset the packed throttles cached data
m_packedThrottles = null;
@ -719,57 +750,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
/// <summary>
/// Called when an ACK packet is received and a round-trip time for a
/// packet is calculated. This is used to calculate the smoothed
/// round-trip time, round trip time variance, and finally the
/// retransmission timeout
/// Called when we get a ping update
/// </summary>
/// <param name="r">Round-trip time of a single packet and its
/// <param name="r"> ping time in ms
/// acknowledgement</param>
public void UpdateRoundTrip(float r)
public void UpdateRoundTrip(int p)
{
const float ALPHA = 0.125f;
const float BETA = 0.25f;
const float K = 4.0f;
p *= 5;
if( p> m_maxRTO)
p = m_maxRTO;
else if(p < m_defaultRTO)
p = m_defaultRTO;
if (RTTVAR == 0.0f)
{
// First RTT measurement
SRTT = r;
RTTVAR = r * 0.5f;
}
else
{
// Subsequence RTT measurement
RTTVAR = (1.0f - BETA) * RTTVAR + BETA * Math.Abs(SRTT - r);
SRTT = (1.0f - ALPHA) * SRTT + ALPHA * r;
}
int rto = (int)(SRTT + Math.Max(m_udpServer.TickCountResolution, K * RTTVAR));
// Clamp the retransmission timeout to manageable values
rto = Utils.Clamp(rto, m_defaultRTO, m_maxRTO);
RTO = rto;
//if (RTO != rto)
// m_log.Debug("[LLUDPCLIENT]: Setting RTO to " + RTO + "ms from " + rto + "ms with an RTTVAR of " +
//RTTVAR + " based on new RTT of " + r + "ms");
}
/// <summary>
/// Exponential backoff of the retransmission timeout, per section 5.5
/// of RFC 2988
/// </summary>
public void BackoffRTO()
{
// Reset SRTT and RTTVAR, we assume they are bogus since things
// didn't work out and we're backing off the timeout
SRTT = 0.0f;
RTTVAR = 0.0f;
// Double the retransmission timeout
RTO = Math.Min(RTO * 2, m_maxRTO);
m_RTO = p;
}
const double MIN_CALLBACK_MS = 20.0;

View File

@ -229,11 +229,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
StatVerbosity.Debug));
}
public virtual bool HandlesRegion(Location x)
{
return m_udpServer.HandlesRegion(x);
}
public virtual void Start()
{
m_udpServer.Start();
@ -256,7 +251,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <summary>Maximum transmission unit, or UDP packet size, for the LLUDP protocol</summary>
public const int MTU = 1400;
public const int MAXPAYLOAD = 1250;
public const int MAXPAYLOAD = 1200;
/// <summary>Number of forced client logouts due to no receipt of packets before timeout.</summary>
public int ClientLogoutsDueToNoReceives { get; protected set; }
@ -279,11 +274,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// OnQueueEmpty event is triggered for textures</summary>
public readonly int TextureSendLimit;
/// <summary>Handlers for incoming packets</summary>
//PacketEventDictionary packetEvents = new PacketEventDictionary();
/// <summary>Incoming packets that are awaiting handling</summary>
//protected OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>();
protected BlockingCollection<IncomingPacket> packetInbox = new BlockingCollection<IncomingPacket>();
/// <summary>Bandwidth throttle for this UDP server</summary>
@ -303,9 +293,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <summary>Reference to the scene this UDP server is attached to</summary>
public Scene Scene { get; protected set; }
/// <summary>The X/Y coordinates of the scene this UDP server is attached to</summary>
protected Location m_location;
/// <summary>The size of the receive buffer for the UDP socket. This value
/// is passed up to the operating system and used in the system networking
/// stack. Use zero to leave this value as the default</summary>
@ -374,12 +361,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// </summary>
public int IncomingOrphanedPacketCount { get; protected set; }
/// <summary>
/// Queue some low priority but potentially high volume async requests so that they don't overwhelm available
/// threadpool threads.
/// </summary>
// public JobEngine IpahEngine { get; protected set; }
public bool SupportViewerObjectsCache = true;
/// <summary>
/// Run queue empty processing within a single persistent thread.
/// </summary>
@ -444,6 +426,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_disableFacelights = config.GetBoolean("DisableFacelights", false);
m_ackTimeout = 1000 * config.GetInt("AckTimeout", 60);
m_pausedAckTimeout = 1000 * config.GetInt("PausedAckTimeout", 300);
SupportViewerObjectsCache = config.GetBoolean("SupportViewerObjectsCache", SupportViewerObjectsCache);
}
else
{
@ -477,8 +460,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
Throttle = new TokenBucket(null, sceneThrottleBps, sceneThrottleBps * 10e-3f);
ThrottleRates = new ThrottleRates(configSource);
Random rnd = new Random(Util.EnvironmentTickCount());
// if (usePools)
// EnablePools();
}
@ -556,13 +537,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
Scene = (Scene)scene;
m_location = new Location(Scene.RegionInfo.RegionHandle);
/*
IpahEngine
= new JobEngine(
string.Format("Incoming Packet Async Handling Engine ({0})", Scene.Name),
"INCOMING PACKET ASYNC HANDLING ENGINE");
*/
OqrEngine = new JobEngine(
string.Format("Outgoing Queue Refill Engine ({0})", Scene.Name),
"OUTGOING QUEUE REFILL ENGINE");
@ -689,11 +664,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
commands.Register();
}
public bool HandlesRegion(Location x)
{
return x == m_location;
}
public int GetTotalQueuedOutgoingPackets()
{
int total = 0;
@ -844,13 +814,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
bool doZerocode = (data[0] & Helpers.MSG_ZEROCODED) != 0;
bool doCopy = true;
// Frequency analysis of outgoing packet sizes shows a large clump of packets at each end of the spectrum.
// The vast majority of packets are less than 200 bytes, although due to asset transfers and packet splitting
// there are a decent number of packets in the 1000-1140 byte range. We allocate one of two sizes of data here
// to accomodate for both common scenarios and provide ample room for ACK appending in both
//int bufferSize = (dataLength > 180) ? LLUDPServer.MTU : 200;
//UDPPacketBuffer buffer = new UDPPacketBuffer(udpClient.RemoteEndPoint, bufferSize);
UDPPacketBuffer buffer = GetNewUDPBuffer(udpClient.RemoteEndPoint);
// Zerocode if needed
@ -993,7 +956,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
bool highPriority = false;
if(zerocode)
if (zerocode)
buffer = ZeroEncode(buffer);
if (category != ThrottleOutPacketType.Unknown && (category & ThrottleOutPacketType.HighPriority) != 0)
@ -1012,49 +975,116 @@ namespace OpenSim.Region.ClientStack.LindenUDP
SendPacketFinal(outgoingPacket);
}
public void SendUDPPacket(LLUDPClient udpClient, UDPPacketBuffer buffer, ThrottleOutPacketType category)
{
bool highPriority = false;
if (category != ThrottleOutPacketType.Unknown && (category & ThrottleOutPacketType.HighPriority) != 0)
{
category = (ThrottleOutPacketType)((int)category & 127);
highPriority = true;
}
OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null);
// If we were not provided a method for handling unacked, use the UDPServer default method
if ((outgoingPacket.Buffer.Data[0] & Helpers.MSG_RELIABLE) != 0)
outgoingPacket.UnackedMethod = delegate (OutgoingPacket oPacket) { ResendUnacked(oPacket); };
if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, false, highPriority))
SendPacketFinal(outgoingPacket);
}
static private readonly byte[] PacketAckHeader = new byte[] {
0,
0, 0, 0, 0, // sequence number
0, // extra
0xff, 0xff, 0xff, 0xfb // ID 65531 (low frequency bigendian)
};
public void SendAcks(LLUDPClient udpClient)
{
if(udpClient.PendingAcks.Count == 0)
return;
UDPPacketBuffer buf = GetNewUDPBuffer(udpClient.RemoteEndPoint);
Buffer.BlockCopy(PacketAckHeader, 0, buf.Data, 0, 10);
byte[] data = buf.Data;
// count at position 10
int pos = 11;
uint ack;
if (udpClient.PendingAcks.Dequeue(out ack))
int count = 0;
while (udpClient.PendingAcks.Dequeue(out ack))
{
List<PacketAckPacket.PacketsBlock> blocks = new List<PacketAckPacket.PacketsBlock>();
PacketAckPacket.PacketsBlock block = new PacketAckPacket.PacketsBlock();
block.ID = ack;
blocks.Add(block);
Utils.UIntToBytes(ack, data, pos); pos += 4;
++count;
while (udpClient.PendingAcks.Dequeue(out ack))
if (count == 255)
{
block = new PacketAckPacket.PacketsBlock();
block.ID = ack;
blocks.Add(block);
data[10] = 255;
buf.DataLength = pos;
SendUDPPacket(udpClient, buf, ThrottleOutPacketType.Unknown);
buf = GetNewUDPBuffer(udpClient.RemoteEndPoint);
Buffer.BlockCopy(PacketAckHeader, 0, buf.Data, 0, 10);
data = buf.Data;
pos = 11;
count = 0;
}
PacketAckPacket packet = new PacketAckPacket();
packet.Header.Reliable = false;
packet.Packets = blocks.ToArray();
SendPacket(udpClient, packet, ThrottleOutPacketType.Unknown, true, null);
}
if (count > 0)
{
data[10] = (byte)count;
buf.DataLength = pos;
SendUDPPacket(udpClient, buf, ThrottleOutPacketType.Unknown);
}
}
static private readonly byte[] StartPingCheckHeader = new byte[] {
0,
0, 0, 0, 0, // sequence number
0, // extra
1 // ID 1 (high frequency)
};
public void SendPing(LLUDPClient udpClient)
{
StartPingCheckPacket pc = (StartPingCheckPacket)PacketPool.Instance.GetPacket(PacketType.StartPingCheck);
UDPPacketBuffer buf = GetNewUDPBuffer(udpClient.RemoteEndPoint);
Buffer.BlockCopy(StartPingCheckHeader, 0, buf.Data, 0, 7);
byte[] data = buf.Data;
pc.PingID.PingID = (byte)udpClient.CurrentPingSequence++;
// We *could* get OldestUnacked, but it would hurt performance and not provide any benefit
pc.PingID.OldestUnacked = 0;
data[7] = udpClient.CurrentPingSequence++;
// older seq number of our un ack packets, so viewers could clean deduplication lists TODO
//Utils.UIntToBytes(0, data, 8);
data[8] = 0;
data[9] = 0;
data[10] = 0;
data[11] = 0;
SendPacket(udpClient, pc, ThrottleOutPacketType.Unknown, false, null);
udpClient.m_lastStartpingTimeMS = Util.EnvironmentTickCount();
buf.DataLength = 12;
SendUDPPacket(udpClient, buf, ThrottleOutPacketType.Unknown);
udpClient.m_lastStartpingTimeMS = Util.GetTimeStampMS();
}
static private readonly byte[] CompletePingCheckHeader = new byte[] {
0,
0, 0, 0, 0, // sequence number
0, // extra
2 // ID 1 (high frequency)
};
public void CompletePing(LLUDPClient udpClient, byte pingID)
{
CompletePingCheckPacket completePing = new CompletePingCheckPacket();
completePing.PingID.PingID = pingID;
SendPacket(udpClient, completePing, ThrottleOutPacketType.Unknown, false, null);
UDPPacketBuffer buf = GetNewUDPBuffer(udpClient.RemoteEndPoint);
Buffer.BlockCopy(CompletePingCheckHeader, 0, buf.Data, 0, 7);
byte[] data = buf.Data;
data[7] = pingID;
buf.DataLength = 8;
SendUDPPacket(udpClient, buf, ThrottleOutPacketType.Unknown);
}
public void HandleUnacked(LLClientView client)
@ -1090,13 +1120,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
// Get a list of all of the packets that have been sitting unacked longer than udpClient.RTO
List<OutgoingPacket> expiredPackets = udpClient.NeedAcks.GetExpiredPackets(udpClient.RTO);
List<OutgoingPacket> expiredPackets = udpClient.NeedAcks.GetExpiredPackets(udpClient.m_RTO);
if (expiredPackets != null)
{
//m_log.Debug("[LLUDPSERVER]: Handling " + expiredPackets.Count + " packets to " + udpClient.AgentID + ", RTO=" + udpClient.RTO);
// Exponential backoff of the retransmission timeout
udpClient.BackoffRTO();
for (int i = 0; i < expiredPackets.Count; ++i)
expiredPackets[i].UnackedMethod(expiredPackets[i]);
}
@ -1144,8 +1171,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
int dataLength = buffer.DataLength;
// NOTE: I'm seeing problems with some viewers when ACKs are appended to zerocoded packets so I've disabled that here
if (!isZerocoded && !isResend && outgoingPacket.UnackedMethod == null)
// only append acks on plain reliable messages
if (flags == Helpers.MSG_RELIABLE && outgoingPacket.UnackedMethod == null)
{
// Keep appending ACKs until there is no room left in the buffer or there are
// no more ACKs to append
@ -1184,7 +1211,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Stats tracking
Interlocked.Increment(ref udpClient.PacketsSent);
PacketsSentCount++;
SyncSend(buffer);
// Keep track of when this packet was sent out (right now)
@ -1315,11 +1341,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (packet.Type == PacketType.UseCircuitCode)
{
// And if there is a UseCircuitCode pending, also drop it
lock (m_pendingCache)
{
if (m_pendingCache.Contains(endPoint))
{
FreeUDPBuffer(buffer);
SendAckImmediate(endPoint, packet.Header.Sequence); // i hear you shutup
return;
}
@ -1328,6 +1356,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
Util.FireAndForget(HandleUseCircuitCode, new object[] { endPoint, packet });
FreeUDPBuffer(buffer);
SendAckImmediate(endPoint, packet.Header.Sequence);
return;
}
}
@ -1482,11 +1511,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
else if (packet.Type == PacketType.CompletePingCheck)
{
int t = Util.EnvironmentTickCountSubtract(udpClient.m_lastStartpingTimeMS);
int c = udpClient.m_pingMS;
c = 800 * c + 200 * t;
c /= 1000;
udpClient.m_pingMS = c;
double t = Util.GetTimeStampMS() - udpClient.m_lastStartpingTimeMS;
double c = 0.8 * udpClient.m_pingMS;
c += 0.2 * t;
int p = (int)c;
udpClient.m_pingMS = p;
udpClient.UpdateRoundTrip(p);
return;
}
@ -1651,7 +1681,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
// Now we know we can handle more data
Thread.Sleep(200);
//Thread.Sleep(200);
// Obtain the pending queue and remove it from the cache
Queue<UDPPacketBuffer> queue = null;
@ -1666,8 +1696,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_pendingCache.Remove(endPoint);
}
client.CheckViewerCaps();
m_log.DebugFormat("[LLUDPSERVER]: Client created, processing pending queue, {0} entries", queue.Count);
// Reinject queued packets
while (queue.Count > 0)
@ -1678,18 +1706,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
queue = null;
// Send ack straight away to let the viewer know that the connection is active.
// The client will be null if it already exists (e.g. if on a region crossing the client sends a use
// circuit code to the existing child agent. This is not particularly obvious.
SendAckImmediate(endPoint, uccp.Header.Sequence);
// We only want to send initial data to new clients, not ones which are being converted from child to root.
if (client != null)
{
bool tp = (aCircuit.teleportFlags > 0);
// Let's delay this for TP agents, otherwise the viewer doesn't know where to get resources from
if (!tp)
client.SceneAgent.SendInitialDataToMe();
if(aCircuit.teleportFlags <= 0)
client.SendRegionHandshake();
}
}
else
@ -1705,8 +1725,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
// m_log.DebugFormat(
// "[LLUDPSERVER]: Handling UseCircuitCode request from {0} took {1}ms",
// buffer.RemoteEndPoint, (DateTime.Now - startTime).Milliseconds);
// "[LLUDPSERVER]: Handling UseCircuitCode request from {0} took {1}ms",
// buffer.RemoteEndPoint, (DateTime.Now - startTime).Milliseconds);
}
catch (Exception e)
@ -1720,117 +1740,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
e.StackTrace);
}
}
/*
protected void HandleCompleteMovementIntoRegion(object o)
{
IPEndPoint endPoint = null;
IClientAPI client = null;
try
{
object[] array = (object[])o;
endPoint = (IPEndPoint)array[0];
CompleteAgentMovementPacket packet = (CompleteAgentMovementPacket)array[1];
m_log.DebugFormat(
"[LLUDPSERVER]: Handling CompleteAgentMovement request from {0} in {1}", endPoint, Scene.Name);
// Determine which agent this packet came from
// We need to wait here because in when using the OpenSimulator V2 teleport protocol to travel to a destination
// simulator with no existing child presence, the viewer (at least LL 3.3.4) will send UseCircuitCode
// and then CompleteAgentMovement immediately without waiting for an ack. As we are now handling these
// packets asynchronously, we need to account for this thread proceeding more quickly than the
// UseCircuitCode thread.
int count = 40;
while (count-- > 0)
{
if (Scene.TryGetClient(endPoint, out client))
{
if (!client.IsActive)
{
// This check exists to catch a condition where the client has been closed by another thread
// but has not yet been removed from the client manager (and possibly a new connection has
// not yet been established).
m_log.DebugFormat(
"[LLUDPSERVER]: Received a CompleteAgentMovement from {0} for {1} in {2} but client is not active yet. Waiting.",
endPoint, client.Name, Scene.Name);
}
else if (client.SceneAgent == null)
{
// This check exists to catch a condition where the new client has been added to the client
// manager but the SceneAgent has not yet been set in Scene.AddNewAgent(). If we are too
// eager, then the new ScenePresence may not have registered a listener for this messsage
// before we try to process it.
// XXX: A better long term fix may be to add the SceneAgent before the client is added to
// the client manager
m_log.DebugFormat(
"[LLUDPSERVER]: Received a CompleteAgentMovement from {0} for {1} in {2} but client SceneAgent not set yet. Waiting.",
endPoint, client.Name, Scene.Name);
}
else
{
break;
}
}
else
{
m_log.DebugFormat(
"[LLUDPSERVER]: Received a CompleteAgentMovement from {0} in {1} but no client exists yet. Waiting.",
endPoint, Scene.Name);
}
Thread.Sleep(200);
}
if (client == null)
{
m_log.DebugFormat(
"[LLUDPSERVER]: No client found for CompleteAgentMovement from {0} in {1} after wait. Dropping.",
endPoint, Scene.Name);
return;
}
else if (!client.IsActive || client.SceneAgent == null)
{
// This check exists to catch a condition where the client has been closed by another thread
// but has not yet been removed from the client manager.
// The packet could be simply ignored but it is useful to know if this condition occurred for other debugging
// purposes.
m_log.DebugFormat(
"[LLUDPSERVER]: Received a CompleteAgentMovement from {0} for {1} in {2} but client is not active after wait. Dropping.",
endPoint, client.Name, Scene.Name);
return;
}
IncomingPacket incomingPacket1;
// Inbox insertion
if (UsePools)
{
incomingPacket1 = m_incomingPacketPool.GetObject();
incomingPacket1.Client = (LLClientView)client;
incomingPacket1.Packet = packet;
}
else
{
incomingPacket1 = new IncomingPacket((LLClientView)client, packet);
}
packetInbox.Enqueue(incomingPacket1);
}
catch (Exception e)
{
m_log.ErrorFormat(
"[LLUDPSERVER]: CompleteAgentMovement handling from endpoint {0}, client {1} {2} failed. Exception {3}{4}",
endPoint != null ? endPoint.ToString() : "n/a",
client != null ? client.Name : "unknown",
client != null ? client.AgentId.ToString() : "unknown",
e.Message,
e.StackTrace);
}
}
*/
/// <summary>
/// Send an ack immediately to the given endpoint.
@ -1898,7 +1807,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
if (Scene.TryGetClient(agentID, out client))
{
if (client.SceneAgent != null)
if (client.SceneAgent != null &&
client.CircuitCode == circuitCode &&
client.SessionId == sessionID &&
client.RemoteEndPoint == remoteEndPoint &&
client.SceneAgent.ControllingClient.SecureSessionId == sessionInfo.LoginInfo.SecureSession)
return client;
Scene.CloseAgent(agentID, true);
}

View File

@ -26,6 +26,7 @@
*/
using System;
using System.Text;
using OpenSim.Framework;
using Nini.Config;
using OpenMetaverse;
@ -275,5 +276,86 @@ namespace OpenSim.Region.ClientStack.LindenUDP
v.ToBytes(m_tmp, 0);
AddBytes(m_tmp, 16);
}
// maxlen <= 255 and includes null termination byte
public void AddShortString(string str, int maxlen)
{
if (String.IsNullOrEmpty(str))
{
AddZeros(1);
return;
}
--maxlen; // account for null term
bool NullTerm = str.EndsWith("\0");
byte[] data = Util.UTF8.GetBytes(str);
int len = data.Length;
if(NullTerm)
--len;
if(len <= maxlen)
{
AddByte((byte)(len + 1));
AddBytes(data, len);
AddZeros(1);
return;
}
if ((data[maxlen] & 0x80) != 0)
{
while (maxlen > 0 && (data[maxlen] & 0xc0) != 0xc0)
maxlen--;
}
AddByte((byte)(maxlen + 1));
AddBytes(data, maxlen);
AddZeros(1);
}
// maxlen <= 255 and includes null termination byte, maxchars == max len of utf8 source
public void AddShortString(string str, int maxchars, int maxlen)
{
if (String.IsNullOrEmpty(str))
{
AddZeros(1);
return;
}
--maxlen; // account for null term
bool NullTerm = false;
byte[] data;
if (str.Length > maxchars)
{
data = Util.UTF8.GetBytes(str.Substring(0,maxchars));
}
else
{
NullTerm = str.EndsWith("\0");
data = Util.UTF8.GetBytes(str);
}
int len = data.Length;
if (NullTerm)
--len;
if (len <= maxlen)
{
AddByte((byte)(len + 1));
AddBytes(data, len);
AddZeros(1);
return;
}
if ((data[maxlen] & 0x80) != 0)
{
while (maxlen > 0 && (data[maxlen] & 0xc0) != 0xc0)
maxlen--;
}
AddByte((byte)(maxlen + 1));
AddBytes(data, maxlen);
AddZeros(1);
}
}
}

View File

@ -67,7 +67,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public Int64 MinimumAdaptiveThrottleRate;
public int ClientMaxRate;
public float BrustTime;
public float BurstTime;
/// <summary>
/// Default constructor
@ -94,8 +94,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (ClientMaxRate > 1000000)
ClientMaxRate = 1000000; // no more than 8Mbps
BrustTime = (float)throttleConfig.GetInt("client_throttle_burtsTimeMS", 10);
BrustTime *= 1e-3f;
BurstTime = (float)throttleConfig.GetInt("client_throttle_burtsTimeMS", 10);
BurstTime *= 1e-3f;
// Adaptive is broken
// AdaptiveThrottlesEnabled = throttleConfig.GetBoolean("enable_adaptive_throttles", false);

View File

@ -45,22 +45,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private static Int32 m_counter = 0;
// private Int32 m_identifier;
protected const float m_timeScale = 1e-3f;
/// <summary>
/// This is the number of m_minimumDripRate bytes
/// allowed in a burst
/// roughtly, with this settings, the maximum time system will take
/// to recheck a bucket in ms
///
/// minimum recovery rate, ie bandwith
/// </summary>
protected const float m_quantumsPerBurst = 5;
protected const float MINDRIPRATE = 500;
/// <summary>
/// </summary>
protected const float m_minimumDripRate = 1500;
// minimum and maximim burst size, ie max number of bytes token can have
protected const float MINBURST = 1500; // can't be less than one MTU or it will block
protected const float MAXBURST = 7500;
/// <summary>Time of the last drip</summary>
protected double m_lastDrip;
@ -109,10 +103,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
get { return m_burst; }
set {
float rate = (value < 0 ? 0 : value);
if (rate < 1.5f * m_minimumDripRate)
rate = 1.5f * m_minimumDripRate;
else if (rate > m_minimumDripRate * m_quantumsPerBurst)
rate = m_minimumDripRate * m_quantumsPerBurst;
if (rate < MINBURST)
rate = MINBURST;
else if (rate > MAXBURST)
rate = MAXBURST;
m_burst = rate;
}
@ -122,8 +116,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
get {
float rate = RequestedBurst * BurstModifier();
if (rate < m_minimumDripRate)
rate = m_minimumDripRate;
if (rate < MINBURST)
rate = MINBURST;
return (float)rate;
}
}
@ -159,8 +153,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return rate;
rate *= m_parent.DripRateModifier();
if (rate < m_minimumDripRate)
rate = m_minimumDripRate;
if (rate < MINDRIPRATE)
rate = MINDRIPRATE;
return (float)rate;
}

View File

@ -215,14 +215,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// As with other network applications, assume that an acknowledged packet is an
// indication that the network can handle a little more load, speed up the transmission
ackedPacket.Client.FlowThrottle.AcknowledgePackets(1);
if (!pendingAcknowledgement.FromResend)
{
// Calculate the round-trip time for this packet and its ACK
int rtt = pendingAcknowledgement.RemoveTime - ackedPacket.TickCount;
if (rtt > 0)
ackedPacket.Client.UpdateRoundTrip(rtt);
}
}
else
{

View File

@ -50,8 +50,8 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private object timeTickLock = new object();
private double lastTimeTick = 0.0;
private double lastFilesExpire = 0.0;
private int lastTimeTick = 0;
private int lastFilesExpire = 0;
private bool inTimeTick = false;
public struct XferRequest
@ -66,15 +66,15 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
{
public byte[] Data;
public int refsCount;
public double timeStampMS;
public int timeStampMS;
}
#region INonSharedRegionModule Members
public void Initialise(IConfigSource config)
{
lastTimeTick = Util.GetTimeStampMS() + 30000.0;
lastFilesExpire = lastTimeTick + 180000.0;
lastTimeTick = (int)Util.GetTimeStampMS() + 30000;
lastFilesExpire = lastTimeTick + 180000;
}
public void AddRegion(Scene scene)
@ -121,10 +121,9 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
{
if(!inTimeTick)
{
double now = Util.GetTimeStampMS();
if(now - lastTimeTick > 1750.0)
int now = (int)Util.GetTimeStampMS();
if(now - lastTimeTick > 750)
{
if(Transfers.Count == 0 && NewFiles.Count == 0)
lastTimeTick = now;
else
@ -163,7 +162,7 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
{
lock (NewFiles)
{
double now = Util.GetTimeStampMS();
int now = (int)Util.GetTimeStampMS();
if (NewFiles.ContainsKey(fileName))
{
NewFiles[fileName].refsCount++;
@ -183,18 +182,18 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
}
#endregion
public void expireFiles(double now)
public void expireFiles(int now)
{
lock (NewFiles)
{
// hopefully we will not have many files so nasty code will do it
if(now - lastFilesExpire > 120000.0)
if(now - lastFilesExpire > 120000)
{
lastFilesExpire = now;
List<string> expires = new List<string>();
foreach(string fname in NewFiles.Keys)
{
if(NewFiles[fname].refsCount == 0 && now - NewFiles[fname].timeStampMS > 120000.0)
if(NewFiles[fname].refsCount == 0 && now - NewFiles[fname].timeStampMS > 120000)
expires.Add(fname);
}
foreach(string fname in expires)
@ -230,7 +229,7 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
}
}
public void transfersTimeTick(double now)
public void transfersTimeTick(int now)
{
XferDownLoad[] xfrs;
lock(Transfers)
@ -241,6 +240,7 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
xfrs = new XferDownLoad[Transfers.Count];
Transfers.Values.CopyTo(xfrs,0);
}
foreach(XferDownLoad xfr in xfrs)
{
if(xfr.checkTime(now))
@ -272,14 +272,15 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
if (!Transfers.ContainsKey(xferID))
{
byte[] fileData = NewFiles[fileName].Data;
int burstSize = remoteClient.GetAgentThrottleSilent((int)ThrottleOutPacketType.Asset) >> 11;
if(Transfers.Count > 1)
burstSize /= Transfers.Count;
int burstSize = remoteClient.GetAgentThrottleSilent((int)ThrottleOutPacketType.Task) >> 10;
burstSize *= remoteClient.PingTimeMS;
burstSize >>= 10; // ping is ms, 1 round trip
if(burstSize > 32)
burstSize = 32;
XferDownLoad transaction =
new XferDownLoad(fileName, fileData, xferID, remoteClient, burstSize);
Transfers.Add(xferID, transaction);
transaction.StartSend();
// The transaction for this file is on its way
@ -320,27 +321,27 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
public class XferDownLoad
{
public IClientAPI Client;
public IClientAPI remoteClient;
public byte[] Data = new byte[0];
public string FileName = String.Empty;
public ulong XferID = 0;
public bool isDeleted = false;
private object myLock = new object();
private double lastsendTimeMS;
private int lastACKTimeMS;
private int LastPacket;
private int lastBytes;
private int lastSentPacket;
private int lastAckPacket;
private int burstSize;
private int retries = 0;
private int burstSize; // additional packets, so can be zero
private int retries;
public XferDownLoad(string fileName, byte[] data, ulong xferID, IClientAPI client, int burstsz)
{
FileName = fileName;
Data = data;
XferID = xferID;
Client = client;
remoteClient = client;
burstSize = burstsz;
}
@ -352,7 +353,7 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
{
if(!isDeleted)
{
Data = new byte[0];
Data = null;
isDeleted = true;
}
}
@ -381,30 +382,29 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
lastBytes = 1024;
LastPacket--;
}
}
lastAckPacket = -1;
lastSentPacket = -1;
retries = 0;
double now = Util.GetTimeStampMS();
SendBurst(now);
SendBurst();
return;
}
}
private void SendBurst(double now)
private void SendBurst()
{
int start = lastAckPacket + 1;
int end = start + burstSize;
if (end > LastPacket)
end = LastPacket;
while(start <= end)
SendPacket(start++ , now);
while (start <= end)
SendPacket(start++);
lastACKTimeMS = (int)Util.GetTimeStampMS() + 1000; // reset timeout with some slack for queues delays
}
private void SendPacket(int pkt, double now)
private void SendPacket(int pkt)
{
if(pkt > LastPacket)
return;
@ -422,23 +422,9 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
pktid = (uint)pkt;
}
byte[] transferData;
if(pkt == 0)
{
transferData = new byte[pktsize + 4];
Array.Copy(Utils.IntToBytes(Data.Length), 0, transferData, 0, 4);
Array.Copy(Data, 0, transferData, 4, pktsize);
}
else
{
transferData = new byte[pktsize];
Array.Copy(Data, pkt << 10, transferData, 0, pktsize);
}
Client.SendXferPacket(XferID, pktid, transferData, false);
remoteClient.SendXferPacket(XferID, pktid, Data, pkt << 10, pktsize, true);
lastSentPacket = pkt;
lastsendTimeMS = now;
}
/// <summary>
@ -453,39 +439,49 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
if(isDeleted)
return true;
packet &= 0x7fffffff;
if(lastAckPacket < packet)
packet &= 0x7fffffff;
if (lastAckPacket < packet)
lastAckPacket = (int)packet;
if(lastAckPacket == LastPacket)
else if (lastAckPacket == LastPacket)
{
done();
return true;
}
double now = Util.GetTimeStampMS();
SendPacket(lastSentPacket + 1, now);
lastACKTimeMS = (int)Util.GetTimeStampMS();
retries = 0;
SendPacket(lastSentPacket + 1);
return false;
}
}
public bool checkTime(double now)
public bool checkTime(int now)
{
if(Monitor.TryEnter(myLock))
if (Monitor.TryEnter(myLock))
{
if(!isDeleted)
if (!isDeleted)
{
double timeMS = now - lastsendTimeMS;
if(timeMS > 60000.0)
done();
else if(timeMS > 3500.0 && retries++ < 3)
int timeMS = now - lastACKTimeMS;
int tout = 5 * remoteClient.PingTimeMS;
if (tout < 1000)
tout = 1000;
else if(tout > 10000)
tout = 10000;
if (timeMS > tout)
{
burstSize >>= 1;
SendBurst(now);
if (++retries > 4)
done();
else
{
burstSize = lastSentPacket - lastAckPacket;
SendBurst();
}
}
}
bool isdel = isDeleted;
Monitor.Exit(myLock);
return isDeleted;
return isdel;
}
return false;
}

View File

@ -142,8 +142,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat.Tests
// We must update the scenes in order to make the root new root agents trigger position updates in their
// children.
sceneWest.Update(1);
sceneEast.Update(1);
sceneWest.Update(4);
sceneEast.Update(4);
sp1.DrawDistance += 64;
sp2.DrawDistance += 64;
sceneWest.Update(2);
sceneEast.Update(2);
// Check child positions are correct.
Assert.AreEqual(
@ -233,8 +237,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat.Tests
// We must update the scenes in order to make the root new root agents trigger position updates in their
// children.
sceneNorth.Update(1);
sceneSouth.Update(1);
sceneNorth.Update(4);
sceneSouth.Update(4);
sp1.DrawDistance += 64;
sp2.DrawDistance += 64;
sceneNorth.Update(2);
sceneSouth.Update(2);
// Check child positions are correct.
Assert.AreEqual(

View File

@ -256,7 +256,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
private void OnMakeRootAgent(ScenePresence sp)
{
if(sp.gotCrossUpdate)
if(sp.m_gotCrossUpdate)
return;
RecacheFriends(sp.ControllingClient);

View File

@ -54,14 +54,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static readonly string LogHeader = "[ENTITY TRANSFER MODULE]";
public const int DefaultMaxTransferDistance = 4095;
public const bool WaitForAgentArrivedAtDestinationDefault = true;
/// <summary>
/// The maximum distance, in standard region units (256m) that an agent is allowed to transfer.
/// </summary>
public int MaxTransferDistance { get; set; }
/// <summary>
/// If true then on a teleport, the source region waits for a callback from the destination region. If
/// a callback fails to arrive within a set time then the user is pulled back into the source region.
@ -227,11 +221,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
WaitForAgentArrivedAtDestination
= transferConfig.GetBoolean("wait_for_callback", WaitForAgentArrivedAtDestinationDefault);
MaxTransferDistance = transferConfig.GetInt("max_distance", DefaultMaxTransferDistance);
}
else
{
MaxTransferDistance = DefaultMaxTransferDistance;
}
m_entityTransferStateMachine = new EntityTransferStateMachine(this);
@ -639,29 +628,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
return true;
}
/// <summary>
/// Determines whether this instance is within the max transfer distance.
/// </summary>
/// <param name="sourceRegion"></param>
/// <param name="destRegion"></param>
/// <returns>
/// <c>true</c> if this instance is within max transfer distance; otherwise, <c>false</c>.
/// </returns>
private bool IsWithinMaxTeleportDistance(RegionInfo sourceRegion, GridRegion destRegion)
{
if(MaxTransferDistance == 0)
return true;
// m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Source co-ords are x={0} y={1}", curRegionX, curRegionY);
//
// m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Final dest is x={0} y={1} {2}@{3}",
// destRegionX, destRegionY, finalDestination.RegionID, finalDestination.ServerURI);
// Insanely, RegionLoc on RegionInfo is the 256m map co-ord whilst GridRegion.RegionLoc is the raw meters position.
return Math.Abs(sourceRegion.RegionLocX - destRegion.RegionCoordX) <= MaxTransferDistance
&& Math.Abs(sourceRegion.RegionLocY - destRegion.RegionCoordY) <= MaxTransferDistance;
}
/// <summary>
/// Wraps DoTeleportInternal() and manages the transfer state.
/// </summary>
@ -722,18 +688,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
RegionInfo sourceRegion = sp.Scene.RegionInfo;
if (!IsWithinMaxTeleportDistance(sourceRegion, finalDestination))
{
sp.ControllingClient.SendTeleportFailed(
string.Format(
"Can't teleport to {0} ({1},{2}) from {3} ({4},{5}), destination is more than {6} regions way",
finalDestination.RegionName, finalDestination.RegionCoordX, finalDestination.RegionCoordY,
sourceRegion.RegionName, sourceRegion.RegionLocX, sourceRegion.RegionLocY,
MaxTransferDistance));
return;
}
ulong destinationHandle = finalDestination.RegionHandle;
// Let's do DNS resolution only once in this process, please!
@ -1103,6 +1057,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
}
}
}
else
{
if(!sp.IsInLocalTransit || sp.RegionViewDistance == 0)
{
// this will be closed by callback
if (agentCircuit.ChildrenCapSeeds != null)
agentCircuit.ChildrenCapSeeds.Remove(sp.RegionHandle);
}
}
string capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);;
@ -1175,7 +1138,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
agent.SenderWantsToWaitForRoot = true;
//SetCallbackURL(agent, sp.Scene.RegionInfo);
if(!sp.IsInLocalTransit || sp.RegionViewDistance == 0)
SetNewCallbackURL(agent, sp.Scene.RegionInfo);
// Reset the do not close flag. This must be done before the destination opens child connections (here
// triggered by UpdateAgent) to avoid race conditions. However, we also want to reset it as late as possible
@ -1183,11 +1147,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// in no close.
sp.DoNotCloseAfterTeleport = false;
// we still need to flag this as child here
// a close from receiving region seems possible to happen before we reach sp.MakeChildAgent below
// causing the agent to be loggout out from grid incorrectly
sp.IsChildAgent = true;
// Send the Update. If this returns true, we know the client has contacted the destination
// via CompleteMovementIntoRegion, so we can let go.
// If it returns false, something went wrong, and we need to abort.
if (!UpdateAgent(reg, finalDestination, agent, sp, ctx))
{
sp.IsChildAgent = false;
if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
{
m_interRegionTeleportAborts.Value++;
@ -1208,7 +1177,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
return;
}
m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp);
//shut this up for now
m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
//m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp);
sp.HasMovedAway(!(OutSideViewRange || logout));
@ -1224,25 +1196,33 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
sp.closeAllChildAgents();
else
sp.CloseChildAgents(childRegionsToClose);
}
// Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone
// goes by HG hook
if (NeedsClosing(reg, OutSideViewRange))
// if far jump we do need to close anyways
if (NeedsClosing(reg, OutSideViewRange))
{
int count = 60;
do
{
if (!sp.Scene.IncomingPreCloseClient(sp))
{
sp.IsInTransit = false;
Thread.Sleep(250);
if(sp.IsDeleted)
return;
}
if(!sp.IsInTransit)
break;
} while (--count > 0);
// viewers and target region take extra time to process the tp
Thread.Sleep(15000);
if (!sp.IsDeleted)
{
m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: Closing agent {0} in {1} after teleport", sp.Name, Scene.Name);
"[ENTITY TRANSFER MODULE]: Closing agent {0} in {1} after teleport {2}", sp.Name, Scene.Name, sp.IsInTransit?"timeout":"");
sp.Scene.CloseAgent(sp.UUID, false);
}
sp.IsInTransit = false;
return;
}
// otherwise keep child
sp.IsInTransit = false;
}
/// <summary>
@ -1313,9 +1293,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
{
agent.CallbackURI = region.ServerURI + "agent/" + agent.AgentID.ToString() + "/" + region.RegionID.ToString() + "/release/";
//m_log.DebugFormat(
// "[ENTITY TRANSFER MODULE]: Set release callback URL to {0} in {1}",
// agent.CallbackURI, region.RegionName);
}
protected virtual void SetNewCallbackURL(AgentData agent, RegionInfo region)
{
agent.NewCallbackURI = region.ServerURI + "agent/" + agent.AgentID.ToString() + "/" + region.RegionID.ToString() + "/release/";
m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: Set release callback URL to {0} in {1}",
agent.CallbackURI, region.RegionName);
agent.NewCallbackURI, region.RegionName);
}
/// <summary>
@ -1590,6 +1579,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
public ScenePresence CrossAsync(ScenePresence agent, bool isFlying)
{
if(agent.RegionViewDistance == 0)
return agent;
Vector3 newpos;
EntityTransferContext ctx = new EntityTransferContext();
string failureReason;
@ -1810,11 +1802,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
cAgent.Position = pos;
cAgent.ChildrenCapSeeds = agent.KnownRegions;
childRegionsToClose = agent.GetChildAgentsToClose(neighbourRegion.RegionHandle, neighbourRegion.RegionSizeX, neighbourRegion.RegionSizeY);
if(cAgent.ChildrenCapSeeds != null)
if(ctx.OutboundVersion < 0.7f)
{
foreach(ulong regh in childRegionsToClose)
cAgent.ChildrenCapSeeds.Remove(regh);
childRegionsToClose = agent.GetChildAgentsToClose(neighbourRegion.RegionHandle, neighbourRegion.RegionSizeX, neighbourRegion.RegionSizeY);
if(cAgent.ChildrenCapSeeds != null)
{
foreach(ulong regh in childRegionsToClose)
cAgent.ChildrenCapSeeds.Remove(regh);
}
}
if (isFlying)
@ -1879,7 +1874,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID);
Vector3 vel2 = Vector3.Zero;
if((agent.crossingFlags & 2) != 0)
if((agent.m_crossingFlags & 2) != 0)
vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0);
if (m_eqModule != null)
@ -1905,10 +1900,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if(childRegionsToClose != null)
agent.CloseChildAgents(childRegionsToClose);
if((agent.crossingFlags & 8) == 0)
if((agent.m_crossingFlags & 8) == 0)
agent.ClearControls(); // don't let attachments delete (called in HasMovedAway) disturb taken controls on viewers
agent.HasMovedAway((agent.crossingFlags & 8) == 0);
agent.HasMovedAway((agent.m_crossingFlags & 8) == 0);
agent.MakeChildAgent(neighbourRegion.RegionHandle);
@ -1957,12 +1952,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (seeds.ContainsKey(regionhandler))
seeds.Remove(regionhandler);
/*
List<ulong> oldregions = new List<ulong>(seeds.Keys);
if (oldregions.Contains(currentRegionHandler))
oldregions.Remove(currentRegionHandler);
*/
if (!seeds.ContainsKey(currentRegionHandler))
seeds.Add(currentRegionHandler, sp.ControllingClient.RequestClientInfo().CapsPath);
@ -1971,6 +1961,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
agent.BaseFolder = UUID.Zero;
agent.InventoryFolder = UUID.Zero;
agent.startpos = sp.AbsolutePosition + CalculateOffset(sp, region);
agent.startfar = sp.DrawDistance;
agent.child = true;
agent.Appearance = new AvatarAppearance();
agent.Appearance.AvatarHeight = sp.Appearance.AvatarHeight;
@ -1999,24 +1990,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
agent.Mac = currentAgentCircuit.Mac;
agent.Id0 = currentAgentCircuit.Id0;
}
/*
AgentPosition agentpos = null;
if (oldregions.Count > 0)
{
agentpos = new AgentPosition();
agentpos.AgentID = new UUID(sp.UUID.Guid);
agentpos.SessionID = sp.ControllingClient.SessionId;
agentpos.Size = sp.Appearance.AvatarSize;
agentpos.Center = sp.CameraPosition;
agentpos.Far = sp.DrawDistance;
agentpos.Position = sp.AbsolutePosition;
agentpos.Velocity = sp.Velocity;
agentpos.RegionHandle = currentRegionHandler;
agentpos.Throttles = sp.ControllingClient.GetThrottlesPacked(1);
agentpos.ChildrenCapSeeds = seeds;
}
*/
IPEndPoint external = region.ExternalEndPoint;
if (external != null)
{
@ -2025,20 +1999,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
InformClientOfNeighbourCompleted,
d);
}
/*
if(oldregions.Count >0)
{
uint neighbourx;
uint neighboury;
UUID scope = sp.Scene.RegionInfo.ScopeID;
foreach (ulong handler in oldregions)
{
Utils.LongToUInts(handler, out neighbourx, out neighboury);
GridRegion neighbour = sp.Scene.GridService.GetRegionByPosition(scope, (int)neighbourx, (int)neighboury);
sp.Scene.SimulationService.UpdateAgent(neighbour, agentpos);
}
}
*/
}
#endregion
@ -2048,6 +2008,44 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
private delegate void InformClientOfNeighbourDelegate(
ScenePresence avatar, AgentCircuitData a, GridRegion reg, IPEndPoint endPoint, bool newAgent);
List<GridRegion> RegionsInView(Vector3 pos, RegionInfo curregion, List<GridRegion> fullneighbours, float viewrange)
{
List<GridRegion> ret = new List<GridRegion>();
if(fullneighbours.Count == 0 || viewrange == 0)
return ret;
int curX = (int)Util.RegionToWorldLoc(curregion.RegionLocX) + (int)pos.X;
int minX = curX - (int)viewrange;
int maxX = curX + (int)viewrange;
int curY = (int)Util.RegionToWorldLoc(curregion.RegionLocY) + (int)pos.Y;
int minY = curY - (int)viewrange;
int maxY = curY + (int)viewrange;
int rtmp;
foreach (GridRegion r in fullneighbours)
{
OpenSim.Framework.RegionFlags? regionFlags = r.RegionFlags;
if (regionFlags != null)
{
if ((regionFlags & OpenSim.Framework.RegionFlags.RegionOnline) == 0)
continue;
}
rtmp = r.RegionLocX;
if (maxX < rtmp)
continue;
if (minX > rtmp + r.RegionSizeX)
continue;
rtmp = r.RegionLocY;
if (maxY < rtmp)
continue;
if (minY > rtmp + r.RegionSizeY)
continue;
ret.Add(r);
}
return ret;
}
/// <summary>
/// This informs all neighbouring regions about agent "avatar".
/// and as important informs the avatar about then
@ -2055,22 +2053,24 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
/// <param name="sp"></param>
public void EnableChildAgents(ScenePresence sp)
{
// assumes that out of view range regions are disconnected by the previus region
// assumes that out of view range regions are disconnected by the previous region
List<GridRegion> neighbours = new List<GridRegion>();
Scene spScene = sp.Scene;
RegionInfo m_regionInfo = spScene.RegionInfo;
RegionInfo regionInfo = spScene.RegionInfo;
if (m_regionInfo != null)
if (regionInfo == null)
return;
ulong currentRegionHandler = regionInfo.RegionHandle;
List<GridRegion> neighbours;
if (sp.RegionViewDistance > 0)
{
neighbours = GetNeighbors(sp, m_regionInfo.RegionLocX, m_regionInfo.RegionLocY);
List<GridRegion> fullneighbours = GetNeighbors(sp);
neighbours = RegionsInView(sp.AbsolutePosition, regionInfo, fullneighbours, sp.RegionViewDistance);
}
else
{
m_log.Debug("[ENTITY TRANSFER MODULE]: m_regionInfo was null in EnableChildAgents, is this a NPC?");
}
ulong currentRegionHandler = m_regionInfo.RegionHandle;
neighbours = new List<GridRegion>();
LinkedList<ulong> previousRegionNeighbourHandles;
Dictionary<ulong, string> seeds;
@ -2106,13 +2106,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
List<AgentCircuitData> cagents = new List<AgentCircuitData>();
List<ulong> newneighbours = new List<ulong>();
bool notHG = (sp.TeleportFlags & Constants.TeleportFlags.ViaHGLogin) == 0;
foreach (GridRegion neighbour in neighbours)
{
ulong handler = neighbour.RegionHandle;
if (notHG && previousRegionNeighbourHandles.Contains(handler))
if (previousRegionNeighbourHandles.Contains(handler))
{
// agent already knows this region
previousRegionNeighbourHandles.Remove(handler);
@ -2130,7 +2128,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
agent.child = true;
agent.Appearance = new AvatarAppearance();
agent.Appearance.AvatarHeight = sp.Appearance.AvatarHeight;
agent.startfar = sp.DrawDistance;
if (currentAgentCircuit != null)
{
agent.ServiceURLs = currentAgentCircuit.ServiceURLs;
@ -2159,13 +2157,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
foreach (ulong handler in previousRegionNeighbourHandles)
seeds.Remove(handler);
if(notHG) // does not work on HG
{
toclose = new List<ulong>(previousRegionNeighbourHandles);
// sp.CloseChildAgents(toclose);
}
else
toclose = new List<ulong>();
toclose = new List<ulong>(previousRegionNeighbourHandles);
}
else
toclose = new List<ulong>();
@ -2197,7 +2189,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
Util.FireAndForget(delegate
{
Thread.Sleep(500); // the original delay that was at InformClientOfNeighbourAsync start
int count = 0;
IPEndPoint ipe;
@ -2220,10 +2211,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
}
count++;
}
else if (notHG && !previousRegionNeighbourHandles.Contains(handler))
else if (!previousRegionNeighbourHandles.Contains(handler))
{
spScene.SimulationService.UpdateAgent(neighbour, agentpos);
}
if (sp.IsDeleted)
return;
}
catch (Exception e)
{
@ -2240,6 +2233,214 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
}
}
public void CheckChildAgents(ScenePresence sp)
{
// assumes that out of view range regions are disconnected by the previous region
Scene spScene = sp.Scene;
RegionInfo regionInfo = spScene.RegionInfo;
if (regionInfo == null)
return;
ulong currentRegionHandler = regionInfo.RegionHandle;
List<GridRegion> neighbours;
if (sp.RegionViewDistance > 0)
{
List<GridRegion> fullneighbours = GetNeighbors(sp);
neighbours = RegionsInView(sp.AbsolutePosition, regionInfo, fullneighbours, sp.RegionViewDistance);
}
else
neighbours = new List<GridRegion>();
LinkedList<ulong> previousRegionNeighbourHandles = new LinkedList<ulong>(sp.KnownRegions.Keys);
IClientAPI spClient = sp.ControllingClient;
AgentCircuitData currentAgentCircuit =
spScene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
List<AgentCircuitData> cagents = new List<AgentCircuitData>();
List<GridRegion> newneighbours = new List<GridRegion>();
foreach (GridRegion neighbour in neighbours)
{
ulong handler = neighbour.RegionHandle;
if (previousRegionNeighbourHandles.Contains(handler))
{
// agent already knows this region
previousRegionNeighbourHandles.Remove(handler);
continue;
}
if (handler == currentRegionHandler)
continue;
// a new region to add
AgentCircuitData agent = spClient.RequestClientInfo();
agent.BaseFolder = UUID.Zero;
agent.InventoryFolder = UUID.Zero;
agent.startpos = sp.AbsolutePosition + CalculateOffset(sp, neighbour);
agent.child = true;
agent.Appearance = new AvatarAppearance();
agent.Appearance.AvatarHeight = sp.Appearance.AvatarHeight;
agent.startfar = sp.DrawDistance;
if (currentAgentCircuit != null)
{
agent.ServiceURLs = currentAgentCircuit.ServiceURLs;
agent.IPAddress = currentAgentCircuit.IPAddress;
agent.Viewer = currentAgentCircuit.Viewer;
agent.Channel = currentAgentCircuit.Channel;
agent.Mac = currentAgentCircuit.Mac;
agent.Id0 = currentAgentCircuit.Id0;
}
newneighbours.Add(neighbour);
agent.CapsPath = CapsUtil.GetRandomCapsObjectPath();
sp.AddNeighbourRegion(neighbour, agent.CapsPath);
agent.ChildrenCapSeeds = null;
cagents.Add(agent);
}
List<ulong> toclose;
// previousRegionNeighbourHandles now contains regions to forget
if (previousRegionNeighbourHandles.Count > 0)
{
if (previousRegionNeighbourHandles.Contains(currentRegionHandler))
previousRegionNeighbourHandles.Remove(currentRegionHandler);
foreach (ulong handler in previousRegionNeighbourHandles)
sp.KnownRegions.Remove(handler);
toclose = new List<ulong>(previousRegionNeighbourHandles);
}
else
toclose = new List<ulong>();
ICapabilitiesModule capsModule = spScene.CapsModule;
if (capsModule != null)
capsModule.SetChildrenSeed(sp.UUID, sp.KnownRegions);
if (toclose.Count > 0)
sp.CloseChildAgents(toclose);
if (newneighbours.Count > 0)
{
int count = 0;
IPEndPoint ipe;
foreach (GridRegion neighbour in newneighbours)
{
try
{
ipe = neighbour.ExternalEndPoint;
if (ipe != null)
InformClientOfNeighbourAsync(sp, cagents[count], neighbour, ipe, true);
else
{
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: lost DNS resolution for neighbour {0}", neighbour.ExternalHostName);
}
count++;
if (sp.IsDeleted)
return;
}
catch (Exception e)
{
m_log.ErrorFormat(
"[ENTITY TRANSFER MODULE]: Error creating child agent at {0} ({1} ({2}, {3}). {4}",
neighbour.ExternalHostName,
neighbour.RegionHandle,
neighbour.RegionLocX,
neighbour.RegionLocY,
e);
}
}
}
}
public void CloseOldChildAgents(ScenePresence sp)
{
Scene spScene = sp.Scene;
RegionInfo regionInfo = spScene.RegionInfo;
if (regionInfo == null)
return;
ulong currentRegionHandler = regionInfo.RegionHandle;
List<GridRegion> neighbours;
if (sp.RegionViewDistance > 0)
{
List<GridRegion> fullneighbours = GetNeighbors(sp);
neighbours = RegionsInView(sp.AbsolutePosition, regionInfo, fullneighbours, sp.RegionViewDistance);
}
else
neighbours = new List<GridRegion>();
LinkedList<ulong> previousRegionNeighbourHandles;
Dictionary<ulong, string> seeds;
ICapabilitiesModule capsModule = spScene.CapsModule;
if (capsModule != null)
{
seeds = new Dictionary<ulong, string>(capsModule.GetChildrenSeeds(sp.UUID));
previousRegionNeighbourHandles = new LinkedList<ulong>(seeds.Keys);
}
else
{
seeds = new Dictionary<ulong, string>();
previousRegionNeighbourHandles = new LinkedList<ulong>();
}
IClientAPI spClient = sp.ControllingClient;
// This will fail if the user aborts login
try
{
if (!seeds.ContainsKey(currentRegionHandler))
seeds.Add(currentRegionHandler, spClient.RequestClientInfo().CapsPath);
}
catch
{
return;
}
foreach (GridRegion neighbour in neighbours)
{
ulong handler = neighbour.RegionHandle;
if (previousRegionNeighbourHandles.Contains(handler))
previousRegionNeighbourHandles.Remove(handler);
}
List<ulong> toclose;
// previousRegionNeighbourHandles now contains regions to forget
if (previousRegionNeighbourHandles.Count == 0)
return;
if (previousRegionNeighbourHandles.Contains(currentRegionHandler))
previousRegionNeighbourHandles.Remove(currentRegionHandler);
foreach (ulong handler in previousRegionNeighbourHandles)
seeds.Remove(handler);
toclose = new List<ulong>(previousRegionNeighbourHandles);
if (capsModule != null)
capsModule.SetChildrenSeed(sp.UUID, seeds);
sp.KnownRegions = seeds;
sp.SetNeighbourRegionSizeInfo(neighbours);
Util.FireAndForget(delegate
{
sp.CloseChildAgents(toclose);
});
}
// Computes the difference between two region bases.
// Returns a vector of world coordinates (meters) from base of first region to the second.
// The first region is the home region of the passed scene presence.
@ -2440,6 +2641,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
}
// all this code should be moved to scene replacing the now bad one there
// cache Neighbors
List<GridRegion> Neighbors = null;
DateTime LastNeighborsTime = DateTime.MinValue;
/// <summary>
/// Return the list of online regions that are considered to be neighbours to the given scene.
/// </summary>
@ -2447,39 +2653,41 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
/// <param name="pRegionLocX"></param>
/// <param name="pRegionLocY"></param>
/// <returns></returns>
protected List<GridRegion> GetNeighbors(ScenePresence avatar, uint pRegionLocX, uint pRegionLocY)
protected List<GridRegion> GetNeighbors(ScenePresence avatar)
{
Scene pScene = avatar.Scene;
RegionInfo m_regionInfo = pScene.RegionInfo;
uint dd = (uint)pScene.MaxRegionViewDistance;
if(dd <= 1)
return new List<GridRegion>();
if (Neighbors != null && (DateTime.UtcNow - LastNeighborsTime).TotalSeconds < 30)
{
return Neighbors;
}
RegionInfo regionInfo = pScene.RegionInfo;
List<GridRegion> neighbours;
uint dd = (uint)avatar.RegionViewDistance;
dd--;
// until avatar movement updates client connections, we need to send at least this current region immediate neighbors
uint ddX = Math.Max(dd, Constants.RegionSize);
uint ddY = Math.Max(dd, Constants.RegionSize);
uint startX = Util.RegionToWorldLoc(regionInfo.RegionLocX);
uint endX = startX + regionInfo.RegionSizeX;
uint startY = Util.RegionToWorldLoc(regionInfo.RegionLocY);
uint endY = startY + regionInfo.RegionSizeY;
ddX--;
ddY--;
startX -= dd;
startY -= dd;
endX += dd;
endY += dd;
// reference to region edges. Should be avatar position
uint startX = Util.RegionToWorldLoc(pRegionLocX);
uint endX = startX + m_regionInfo.RegionSizeX;
uint startY = Util.RegionToWorldLoc(pRegionLocY);
uint endY = startY + m_regionInfo.RegionSizeY;
startX -= ddX;
startY -= ddY;
endX += ddX;
endY += ddY;
neighbours
= avatar.Scene.GridService.GetRegionRange(
m_regionInfo.ScopeID, (int)startX, (int)endX, (int)startY, (int)endY);
neighbours = avatar.Scene.GridService.GetRegionRange(
regionInfo.ScopeID, (int)startX, (int)endX, (int)startY, (int)endY);
// The r.RegionFlags == null check only needs to be made for simulators before 2015-01-14 (pre 0.8.1).
neighbours.RemoveAll( r => r.RegionID == m_regionInfo.RegionID );
neighbours.RemoveAll( r => r.RegionID == regionInfo.RegionID );
Neighbors = neighbours;
LastNeighborsTime = DateTime.UtcNow;
return neighbours;
}
#endregion
@ -2488,7 +2696,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
public void AgentArrivedAtDestination(UUID id)
{
m_entityTransferStateMachine.SetAgentArrivedAtDestination(id);
ScenePresence sp = Scene.GetScenePresence(id);
if(sp == null || sp.IsDeleted || !sp.IsInTransit)
return;
//Scene.CloseAgent(sp.UUID, false);
sp.IsInTransit = false;
//m_entityTransferStateMachine.SetAgentArrivedAtDestination(id);
}
#endregion

View File

@ -68,7 +68,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.GridUser
if (sp.IsNPC)
return;
if(sp.gotCrossUpdate)
if(sp.m_gotCrossUpdate)
{
Util.FireAndForget(delegate
{

View File

@ -50,7 +50,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
public void AddRegion(Scene scene)
{
scene.EventManager.OnMakeRootAgent += OnMakeRootAgent;
scene.EventManager.OnNewClient += OnNewClient;
m_PresenceService.LogoutRegionAgents(scene.RegionInfo.RegionID);
@ -61,7 +60,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
public void RemoveRegion(Scene scene)
{
scene.EventManager.OnMakeRootAgent -= OnMakeRootAgent;
scene.EventManager.OnNewClient -= OnNewClient;
m_PresenceService.LogoutRegionAgents(scene.RegionInfo.RegionID);
}
@ -71,7 +69,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
if (sp.IsNPC)
return;
if(sp.gotCrossUpdate)
sp.ControllingClient.OnConnectionClosed += OnConnectionClose;
if (sp.m_gotCrossUpdate)
{
Util.FireAndForget(delegate
{
@ -89,11 +89,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
m_PresenceService.ReportAgent(sp.ControllingClient.SessionId, sp.Scene.RegionInfo.RegionID);
}
public void OnNewClient(IClientAPI client)
{
client.OnConnectionClosed += OnConnectionClose;
}
public void OnConnectionClose(IClientAPI client)
{
if (client != null && client.SceneAgent != null && !client.SceneAgent.IsChildAgent)

View File

@ -574,7 +574,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
Scene.RegionInfo.RegionSettings.Save();
TriggerRegionInfoChange();
sendRegionHandshakeToAll();
sendRegionInfoPacketToAll();
// sendRegionInfoPacketToAll();
}
private void handleCommitEstateTerrainTextureRequest(IClientAPI remoteClient)
@ -1404,7 +1404,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
RegionInfoForEstateMenuArgs args = new RegionInfoForEstateMenuArgs();
args.billableFactor = Scene.RegionInfo.EstateSettings.BillableFactor;
args.estateID = Scene.RegionInfo.EstateSettings.EstateID;
args.maxAgents = (byte)Scene.RegionInfo.RegionSettings.AgentLimit;
args.maxAgents = Scene.RegionInfo.RegionSettings.AgentLimit;
args.objectBonusFactor = (float)Scene.RegionInfo.RegionSettings.ObjectBonus;
args.parentEstateID = Scene.RegionInfo.EstateSettings.ParentEstateID;
args.pricePerMeter = Scene.RegionInfo.EstateSettings.PricePerMeter;
@ -1419,6 +1419,8 @@ namespace OpenSim.Region.CoreModules.World.Estate
args.waterHeight = (float)Scene.RegionInfo.RegionSettings.WaterHeight;
args.simName = Scene.RegionInfo.RegionName;
args.regionType = Scene.RegionInfo.RegionType;
args.AgentCapacity = Scene.RegionInfo.AgentCapacity;
args.ObjectsCapacity = Scene.RegionInfo.ObjectCapacity;
remote_client.SendRegionInfoToEstateMenu(args);
}
@ -1518,42 +1520,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
public void sendRegionHandshake(IClientAPI remoteClient)
{
RegionHandshakeArgs args = new RegionHandshakeArgs();
args.isEstateManager = Scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(remoteClient.AgentId);
if (Scene.RegionInfo.EstateSettings.EstateOwner != UUID.Zero && Scene.RegionInfo.EstateSettings.EstateOwner == remoteClient.AgentId)
args.isEstateManager = true;
args.billableFactor = Scene.RegionInfo.EstateSettings.BillableFactor;
args.terrainStartHeight0 = (float)Scene.RegionInfo.RegionSettings.Elevation1SW;
args.terrainHeightRange0 = (float)Scene.RegionInfo.RegionSettings.Elevation2SW;
args.terrainStartHeight1 = (float)Scene.RegionInfo.RegionSettings.Elevation1NW;
args.terrainHeightRange1 = (float)Scene.RegionInfo.RegionSettings.Elevation2NW;
args.terrainStartHeight2 = (float)Scene.RegionInfo.RegionSettings.Elevation1SE;
args.terrainHeightRange2 = (float)Scene.RegionInfo.RegionSettings.Elevation2SE;
args.terrainStartHeight3 = (float)Scene.RegionInfo.RegionSettings.Elevation1NE;
args.terrainHeightRange3 = (float)Scene.RegionInfo.RegionSettings.Elevation2NE;
args.simAccess = Scene.RegionInfo.AccessLevel;
args.waterHeight = (float)Scene.RegionInfo.RegionSettings.WaterHeight;
args.regionFlags = GetRegionFlags();
args.regionName = Scene.RegionInfo.RegionName;
args.SimOwner = Scene.RegionInfo.EstateSettings.EstateOwner;
args.terrainBase0 = UUID.Zero;
args.terrainBase1 = UUID.Zero;
args.terrainBase2 = UUID.Zero;
args.terrainBase3 = UUID.Zero;
args.terrainDetail0 = Scene.RegionInfo.RegionSettings.TerrainTexture1;
args.terrainDetail1 = Scene.RegionInfo.RegionSettings.TerrainTexture2;
args.terrainDetail2 = Scene.RegionInfo.RegionSettings.TerrainTexture3;
args.terrainDetail3 = Scene.RegionInfo.RegionSettings.TerrainTexture4;
// m_log.DebugFormat("[ESTATE MANAGEMENT MODULE]: Sending terrain texture 1 {0} for region {1}", args.terrainDetail0, Scene.RegionInfo.RegionName);
// m_log.DebugFormat("[ESTATE MANAGEMENT MODULE]: Sending terrain texture 2 {0} for region {1}", args.terrainDetail1, Scene.RegionInfo.RegionName);
// m_log.DebugFormat("[ESTATE MANAGEMENT MODULE]: Sending terrain texture 3 {0} for region {1}", args.terrainDetail2, Scene.RegionInfo.RegionName);
// m_log.DebugFormat("[ESTATE MANAGEMENT MODULE]: Sending terrain texture 4 {0} for region {1}", args.terrainDetail3, Scene.RegionInfo.RegionName);
remoteClient.SendRegionHandshake(Scene.RegionInfo,args);
remoteClient.SendRegionHandshake();
}
public void handleEstateChangeInfo(IClientAPI remoteClient, UUID invoice, UUID senderID, UInt32 parms1, UInt32 parms2)
@ -1673,7 +1640,6 @@ namespace OpenSim.Region.CoreModules.World.Estate
client.OnRegionInfoRequest += HandleRegionInfoRequest;
client.OnEstateCovenantRequest += HandleEstateCovenantRequest;
client.OnLandStatRequest += HandleLandStatRequest;
sendRegionHandshake(client);
}
@ -1681,39 +1647,43 @@ namespace OpenSim.Region.CoreModules.World.Estate
{
RegionFlags flags = RegionFlags.None;
if (Scene.RegionInfo.EstateSettings.FixedSun)
flags |= RegionFlags.SunFixed;
if (Scene.RegionInfo.EstateSettings.PublicAccess)
flags |= (RegionFlags.PublicAllowed |
RegionFlags.ExternallyVisible);
if (Scene.RegionInfo.EstateSettings.AllowVoice)
flags |= RegionFlags.AllowVoice;
if (Scene.RegionInfo.EstateSettings.AllowDirectTeleport)
flags |= RegionFlags.AllowDirectTeleport;
if (Scene.RegionInfo.EstateSettings.DenyAnonymous)
flags |= RegionFlags.DenyAnonymous;
if (Scene.RegionInfo.EstateSettings.DenyIdentified)
flags |= RegionFlags.DenyIdentified;
if (Scene.RegionInfo.EstateSettings.DenyTransacted)
flags |= RegionFlags.DenyTransacted;
if (Scene.RegionInfo.EstateSettings.AbuseEmailToEstateOwner)
flags |= RegionFlags.AbuseEmailToEstateOwner;
if (Scene.RegionInfo.EstateSettings.BlockDwell)
flags |= RegionFlags.BlockDwell;
if (Scene.RegionInfo.EstateSettings.EstateSkipScripts)
flags |= RegionFlags.EstateSkipScripts;
if (Scene.RegionInfo.EstateSettings.ResetHomeOnTeleport)
flags |= RegionFlags.ResetHomeOnTeleport;
if (Scene.RegionInfo.EstateSettings.TaxFree)
flags |= RegionFlags.TaxFree;
if (Scene.RegionInfo.EstateSettings.AllowLandmark)
flags |= RegionFlags.AllowLandmark;
if (Scene.RegionInfo.EstateSettings.AllowParcelChanges)
flags |= RegionFlags.AllowParcelChanges;
if (Scene.RegionInfo.EstateSettings.AllowSetHome)
flags |= RegionFlags.AllowSetHome;
if (Scene.RegionInfo.EstateSettings.ResetHomeOnTeleport)
flags |= RegionFlags.ResetHomeOnTeleport;
if (Scene.RegionInfo.EstateSettings.FixedSun)
flags |= RegionFlags.SunFixed;
if (Scene.RegionInfo.EstateSettings.TaxFree) // this is now wrong means ALLOW_ACCESS_OVERRIDE
flags |= RegionFlags.TaxFree;
if (Scene.RegionInfo.EstateSettings.PublicAccess) //??
flags |= (RegionFlags.PublicAllowed | RegionFlags.ExternallyVisible);
if (Scene.RegionInfo.EstateSettings.BlockDwell)
flags |= RegionFlags.BlockDwell;
if (Scene.RegionInfo.EstateSettings.AllowDirectTeleport)
flags |= RegionFlags.AllowDirectTeleport;
if (Scene.RegionInfo.EstateSettings.EstateSkipScripts)
flags |= RegionFlags.EstateSkipScripts;
if (Scene.RegionInfo.EstateSettings.DenyAnonymous)
flags |= RegionFlags.DenyAnonymous;
if (Scene.RegionInfo.EstateSettings.DenyIdentified) // unused?
flags |= RegionFlags.DenyIdentified;
if (Scene.RegionInfo.EstateSettings.DenyTransacted) // unused?
flags |= RegionFlags.DenyTransacted;
if (Scene.RegionInfo.EstateSettings.AllowParcelChanges)
flags |= RegionFlags.AllowParcelChanges;
if (Scene.RegionInfo.EstateSettings.AbuseEmailToEstateOwner) // now is block fly
flags |= RegionFlags.AbuseEmailToEstateOwner;
if (Scene.RegionInfo.EstateSettings.AllowVoice)
flags |= RegionFlags.AllowVoice;
if (Scene.RegionInfo.EstateSettings.DenyMinors)
flags |= (RegionFlags)(1 << 30);
flags |= RegionFlags.DenyAgeUnverified;
return (uint)flags;
}

View File

@ -247,11 +247,11 @@ namespace OpenSim.Region.CoreModules.World.Land
m_landManagementModule.setParcelOtherCleanTime(remoteClient, localID, otherCleanTime);
}
}
public void sendClientInitialLandInfo(IClientAPI remoteClient)
public void sendClientInitialLandInfo(IClientAPI remoteClient, bool overlay)
{
if (m_landManagementModule != null)
{
m_landManagementModule.sendClientInitialLandInfo(remoteClient);
m_landManagementModule.sendClientInitialLandInfo(remoteClient, overlay);
}
}
#endregion

View File

@ -491,7 +491,7 @@ namespace OpenSim.Region.CoreModules.World.Land
return;
}
public void sendClientInitialLandInfo(IClientAPI remoteClient)
public void sendClientInitialLandInfo(IClientAPI remoteClient, bool overlay)
{
ScenePresence avatar;
@ -507,7 +507,8 @@ namespace OpenSim.Region.CoreModules.World.Land
avatar.currentParcelUUID = over.LandData.GlobalID;
over.SendLandUpdateToClient(avatar.ControllingClient);
}
SendParcelOverlay(remoteClient);
if(overlay)
SendParcelOverlay(remoteClient);
}
public void SendLandUpdate(ScenePresence avatar, ILandObject over)
@ -998,6 +999,39 @@ namespace OpenSim.Region.CoreModules.World.Land
}
}
public ILandObject GetLandObjectinLandUnits(int x, int y)
{
if (m_landList.Count == 0 || m_landIDList == null)
return null;
lock (m_landIDList)
{
try
{
return m_landList[m_landIDList[x, y]];
}
catch (IndexOutOfRangeException)
{
return null;
}
}
}
public int GetLandObjectIDinLandUnits(int x, int y)
{
lock (m_landIDList)
{
try
{
return m_landIDList[x, y];
}
catch (IndexOutOfRangeException)
{
return -1;
}
}
}
// Create a 'parcel is here' bitmap for the parcel identified by the passed landID
private bool[,] CreateBitmapForID(int landID)
{
@ -1282,18 +1316,9 @@ namespace OpenSim.Region.CoreModules.World.Land
#region Parcel Updating
/// <summary>
/// Send the parcel overlay blocks to the client. We send the overlay packets
/// around a location and limited by the 'parcelLayerViewDistance'. This number
/// is usually 128 and the code is arranged so it sends all the parcel overlay
/// information for a whole region if the region is legacy sized (256x256). If
/// the region is larger, only the parcel layer information is sent around
/// the point specified. This reduces the problem of parcel layer information
/// blocks increasing exponentially as region size increases.
/// Send the parcel overlay blocks to the client.
/// </summary>
/// <param name="remote_client">The object representing the client</param>
/// <param name="xPlace">X position in the region to send surrounding parcel layer info</param>
/// <param name="yPlace">y position in the region to send surrounding parcel layer info</param>
/// <param name="layerViewDistance">Distance from x,y position to send parcel layer info</param>
public void SendParcelOverlay(IClientAPI remote_client)
{
if (remote_client.SceneAgent.PresenceType == PresenceType.Npc)
@ -1301,99 +1326,133 @@ namespace OpenSim.Region.CoreModules.World.Land
const int LAND_BLOCKS_PER_PACKET = 1024;
int curID;
int southID;
byte[] byteArray = new byte[LAND_BLOCKS_PER_PACKET];
int byteArrayCount = 0;
int sequenceID = 0;
int sx = (int)m_scene.RegionInfo.RegionSizeX / LandUnit;
byte curByte;
byte tmpByte;
// Layer data is in LandUnit (4m) chunks
for (int y = 0; y < m_scene.RegionInfo.RegionSizeY; y += LandUnit)
for (int y = 0; y < m_scene.RegionInfo.RegionSizeY / LandUnit; ++y)
{
for (int x = 0; x < m_scene.RegionInfo.RegionSizeX; x += LandUnit)
for (int x = 0; x < sx;)
{
byte tempByte = 0; //This represents the byte for the current 4x4
curID = GetLandObjectIDinLandUnits(x,y);
if(curID < 0)
continue;
ILandObject currentParcelBlock = GetLandObject(x, y);
ILandObject currentParcel = GetLandObject(curID);
if (currentParcel == null)
continue;
if (currentParcelBlock != null)
// types
if (currentParcel.LandData.OwnerID == remote_client.AgentId)
{
// types
if (currentParcelBlock.LandData.OwnerID == remote_client.AgentId)
{
//Owner Flag
tempByte = (byte)LandChannel.LAND_TYPE_OWNED_BY_REQUESTER;
}
else if (currentParcelBlock.LandData.IsGroupOwned && remote_client.IsGroupMember(currentParcelBlock.LandData.GroupID))
{
tempByte = (byte)LandChannel.LAND_TYPE_OWNED_BY_GROUP;
}
else if (currentParcelBlock.LandData.SalePrice > 0 &&
(currentParcelBlock.LandData.AuthBuyerID == UUID.Zero ||
currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId))
{
//Sale type
tempByte = (byte)LandChannel.LAND_TYPE_IS_FOR_SALE;
}
else if (currentParcelBlock.LandData.OwnerID == UUID.Zero)
{
//Public type
tempByte = (byte)LandChannel.LAND_TYPE_PUBLIC; // this does nothing, its zero
}
// LAND_TYPE_IS_BEING_AUCTIONED still unsuported
else
{
//Other Flag
tempByte = (byte)LandChannel.LAND_TYPE_OWNED_BY_OTHER;
}
//Owner Flag
curByte = LandChannel.LAND_TYPE_OWNED_BY_REQUESTER;
}
else if (currentParcel.LandData.IsGroupOwned && remote_client.IsGroupMember(currentParcel.LandData.GroupID))
{
curByte = LandChannel.LAND_TYPE_OWNED_BY_GROUP;
}
else if (currentParcel.LandData.SalePrice > 0 &&
(currentParcel.LandData.AuthBuyerID == UUID.Zero ||
currentParcel.LandData.AuthBuyerID == remote_client.AgentId))
{
//Sale type
curByte = LandChannel.LAND_TYPE_IS_FOR_SALE;
}
else if (currentParcel.LandData.OwnerID == UUID.Zero)
{
//Public type
curByte = LandChannel.LAND_TYPE_PUBLIC; // this does nothing, its zero
}
// LAND_TYPE_IS_BEING_AUCTIONED still unsuported
else
{
//Other
curByte = LandChannel.LAND_TYPE_OWNED_BY_OTHER;
}
// now flags
// border control
// now flags
// local sound
if ((currentParcel.LandData.Flags & (uint)ParcelFlags.SoundLocal) != 0)
curByte |= (byte)LandChannel.LAND_FLAG_LOCALSOUND;
ILandObject westParcel = null;
ILandObject southParcel = null;
if (x > 0)
// hide avatars
if (!currentParcel.LandData.SeeAVs)
curByte |= (byte)LandChannel.LAND_FLAG_HIDEAVATARS;
// border flags for current
if (y == 0)
{
curByte |= LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH;
tmpByte = curByte;
}
else
{
tmpByte = curByte;
southID = GetLandObjectIDinLandUnits(x, (y - 1));
if (southID >= 0 && southID != curID)
tmpByte |= LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH;
}
tmpByte |= LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST;
byteArray[byteArrayCount] = tmpByte;
byteArrayCount++;
if (byteArrayCount >= LAND_BLOCKS_PER_PACKET)
{
remote_client.SendLandParcelOverlay(byteArray, sequenceID);
byteArrayCount = 0;
sequenceID++;
byteArray = new byte[LAND_BLOCKS_PER_PACKET];
}
// keep adding while on same parcel, checking south border
if (y == 0)
{
// all have south border and that is already on curByte
while (++x < sx && GetLandObjectIDinLandUnits(x, y) == curID)
{
westParcel = GetLandObject((x - 1), y);
byteArray[byteArrayCount] = curByte;
byteArrayCount++;
if (byteArrayCount >= LAND_BLOCKS_PER_PACKET)
{
remote_client.SendLandParcelOverlay(byteArray, sequenceID);
byteArrayCount = 0;
sequenceID++;
byteArray = new byte[LAND_BLOCKS_PER_PACKET];
}
}
if (y > 0)
}
else
{
while (++x < sx && GetLandObjectIDinLandUnits(x, y) == curID)
{
southParcel = GetLandObject(x, (y - 1));
}
// need to check south one by one
southID = GetLandObjectIDinLandUnits(x, (y - 1));
if (southID >= 0 && southID != curID)
{
tmpByte = curByte;
tmpByte |= LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH;
byteArray[byteArrayCount] = tmpByte;
}
else
byteArray[byteArrayCount] = curByte;
if (x == 0)
{
tempByte |= (byte)LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST;
}
else if (westParcel != null && westParcel != currentParcelBlock)
{
tempByte |= (byte)LandChannel.LAND_FLAG_PROPERTY_BORDER_WEST;
}
if (y == 0)
{
tempByte |= (byte)LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH;
}
else if (southParcel != null && southParcel != currentParcelBlock)
{
tempByte |= (byte)LandChannel.LAND_FLAG_PROPERTY_BORDER_SOUTH;
}
// local sound
if ((currentParcelBlock.LandData.Flags & (uint)ParcelFlags.SoundLocal) != 0)
tempByte |= (byte)LandChannel.LAND_FLAG_LOCALSOUND;
// hide avatars
if (!currentParcelBlock.LandData.SeeAVs)
tempByte |= (byte)LandChannel.LAND_FLAG_HIDEAVATARS;
byteArray[byteArrayCount] = tempByte;
byteArrayCount++;
if (byteArrayCount >= LAND_BLOCKS_PER_PACKET)
{
remote_client.SendLandParcelOverlay(byteArray, sequenceID);
byteArrayCount = 0;
sequenceID++;
byteArray = new byte[LAND_BLOCKS_PER_PACKET];
byteArrayCount++;
if (byteArrayCount >= LAND_BLOCKS_PER_PACKET)
{
remote_client.SendLandParcelOverlay(byteArray, sequenceID);
byteArrayCount = 0;
sequenceID++;
byteArray = new byte[LAND_BLOCKS_PER_PACKET];
}
}
}
}

View File

@ -1841,7 +1841,7 @@ namespace OpenSim.Region.CoreModules.World.Land
UUID lgid = LandData.GlobalID;
m_scene.ForEachRootScenePresence(delegate(ScenePresence sp)
{
if(sp.IsNPC || sp.IsLoggingIn || sp.IsDeleted || sp.currentParcelUUID != lgid)
if(sp.IsNPC || sp.IsDeleted || sp.currentParcelUUID != lgid)
return;
cur += (now - sp.ParcelDwellTickMS);
sp.ParcelDwellTickMS = now;

View File

@ -219,9 +219,13 @@ namespace OpenSim.Region.CoreModules.World.Media.Moap
lock (media)
me = media[face];
// TODO: Really need a proper copy constructor down in libopenmetaverse
if (me != null)
me = MediaEntry.FromOSD(me.GetOSD());
{
Primitive.TextureEntry te = part.Shape.Textures;
Primitive.TextureEntryFace teFace = te.GetFace((uint)face);
if (teFace != null && teFace.MediaFlags)
me = MediaEntry.FromOSD(me.GetOSD());
}
}
// m_log.DebugFormat("[MOAP]: GetMediaEntry for {0} face {1} found {2}", part.Name, face, me);
@ -336,15 +340,40 @@ namespace OpenSim.Region.CoreModules.World.Media.Moap
return string.Empty;
}
if (null == part.Shape.Media)
if (part.Shape.Media == null)
return string.Empty;
ObjectMediaResponse resp = new ObjectMediaResponse();
MediaEntry[] currentML = part.Shape.Media.ToArray();
int nentries = currentML.Length;
int nsides = part.GetNumberOfSides();
if(nentries > nsides)
nentries = nsides;
Primitive.TextureEntry te = part.Shape.Textures;
bool isnull = true;
for(int face = 0; face < nentries; ++face)
{
Primitive.TextureEntryFace teFace = te.GetFace((uint)face);
if(!teFace.MediaFlags)
currentML[face] = null;
else
isnull = false;
}
if(isnull)
{
//remove the damm thing
part.Shape.Media = null;
part.MediaUrl = null;
return string.Empty;
}
ObjectMediaResponse resp = new ObjectMediaResponse();
resp.PrimID = primId;
lock (part.Shape.Media)
resp.FaceMedia = part.Shape.Media.ToArray();
resp.FaceMedia = currentML;
resp.Version = part.MediaUrl;

View File

@ -790,7 +790,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
try
{
using (Bitmap img = (Bitmap)m_imgDecoder.DecodeToImage(asset))
ret = new warp_Texture(img);
ret = new warp_Texture(img, 8); // reduce textures size to 256x256
}
catch (Exception e)
{

View File

@ -406,16 +406,10 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
WorkManager.StartThread(
process,
string.Format("MapItemRequestThread ({0})", m_scene.RegionInfo.RegionName),
ThreadPriority.BelowNormal,
true,
false);
string.Format("MapItemRequestThread ({0})", m_scene.RegionInfo.RegionName));
WorkManager.StartThread(
MapBlockSendThread,
string.Format("MapBlockSendThread ({0})", m_scene.RegionInfo.RegionName),
ThreadPriority.BelowNormal,
true,
false);
string.Format("MapBlockSendThread ({0})", m_scene.RegionInfo.RegionName));
}
/// <summary>
@ -482,7 +476,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
// viewers only ask for green dots to each region now
// except at login with regionhandle 0
// possible on some other rare ocasions
// use previus hack of sending all items with the green dots
// use previous hack of sending all items with the green dots
bool adultRegion;
if (regionhandle == 0)
@ -1189,6 +1183,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
return;
GetAndSendBlocksInternal(req.client, req.minX, req.minY, req.maxX, req.maxY, req.flags);
Watchdog.UpdateThread();
}
thisRunData.Clear();

View File

@ -90,6 +90,8 @@ namespace OpenSim.Region.Framework.Interfaces
void AgentArrivedAtDestination(UUID agent);
void EnableChildAgents(ScenePresence agent);
void CheckChildAgents(ScenePresence agent);
void CloseOldChildAgents(ScenePresence agent);
void EnableChildAgent(ScenePresence agent, GridRegion region);

View File

@ -153,10 +153,23 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="remoteClient"></param>
public void RequestPrim(uint primLocalID, IClientAPI remoteClient)
{
SceneObjectGroup sog = GetGroupByPrim(primLocalID);
SceneObjectPart part = GetSceneObjectPart(primLocalID);
if (part != null)
{
SceneObjectGroup sog = part.ParentGroup;
if(!sog.IsDeleted)
{
PrimUpdateFlags update = PrimUpdateFlags.FullUpdate;
if (sog.RootPart.Shape.MeshFlagEntry)
update = PrimUpdateFlags.FullUpdatewithAnim;
part.SendUpdate(remoteClient, update);
}
}
if (sog != null)
sog.SendFullAnimUpdateToClient(remoteClient);
//SceneObjectGroup sog = GetGroupByPrim(primLocalID);
//if (sog != null)
//sog.SendFullAnimUpdateToClient(remoteClient);
}
/// <summary>

View File

@ -170,8 +170,6 @@ namespace OpenSim.Region.Framework.Scenes
}
private bool m_scripts_enabled;
public SynchronizeSceneHandler SynchronizeScene;
public bool ClampNegativeZ
{
get { return m_clampNegativeZ; }
@ -277,6 +275,12 @@ namespace OpenSim.Region.Framework.Scenes
get { return m_maxRegionViewDistance; }
}
protected float m_minRegionViewDistance = 96f;
public float MinRegionViewDistance
{
get { return m_minRegionViewDistance; }
}
private List<string> m_AllowedViewers = new List<string>();
private List<string> m_BannedViewers = new List<string>();
@ -922,6 +926,7 @@ namespace OpenSim.Region.Framework.Scenes
m_defaultDrawDistance = startupConfig.GetFloat("DefaultDrawDistance", m_defaultDrawDistance);
m_maxDrawDistance = startupConfig.GetFloat("MaxDrawDistance", m_maxDrawDistance);
m_maxRegionViewDistance = startupConfig.GetFloat("MaxRegionsViewDistance", m_maxRegionViewDistance);
m_minRegionViewDistance = startupConfig.GetFloat("MinRegionsViewDistance", m_minRegionViewDistance);
// old versions compatibility
LegacySitOffsets = startupConfig.GetBoolean("LegacySitOffsets", LegacySitOffsets);
@ -932,6 +937,11 @@ namespace OpenSim.Region.Framework.Scenes
if (m_maxRegionViewDistance > m_maxDrawDistance)
m_maxRegionViewDistance = m_maxDrawDistance;
if(m_minRegionViewDistance < 96f)
m_minRegionViewDistance = 96f;
if(m_minRegionViewDistance > m_maxRegionViewDistance)
m_minRegionViewDistance = m_maxRegionViewDistance;
UseBackup = startupConfig.GetBoolean("UseSceneBackup", UseBackup);
if (!UseBackup)
m_log.InfoFormat("[SCENE]: Backup has been disabled for {0}", RegionInfo.RegionName);
@ -1006,11 +1016,9 @@ namespace OpenSim.Region.Framework.Scenes
m_useTrashOnDelete = startupConfig.GetBoolean("UseTrashOnDelete",m_useTrashOnDelete);
m_trustBinaries = startupConfig.GetBoolean("TrustBinaries", m_trustBinaries);
m_allowScriptCrossings = startupConfig.GetBoolean("AllowScriptCrossing", m_allowScriptCrossings);
m_dontPersistBefore =
startupConfig.GetLong("MinimumTimeBeforePersistenceConsidered", DEFAULT_MIN_TIME_FOR_PERSISTENCE);
m_dontPersistBefore = startupConfig.GetLong("MinimumTimeBeforePersistenceConsidered", DEFAULT_MIN_TIME_FOR_PERSISTENCE);
m_dontPersistBefore *= 10000000;
m_persistAfter =
startupConfig.GetLong("MaximumTimeBeforePersistenceConsidered", DEFAULT_MAX_TIME_FOR_PERSISTENCE);
m_persistAfter = startupConfig.GetLong("MaximumTimeBeforePersistenceConsidered", DEFAULT_MAX_TIME_FOR_PERSISTENCE);
m_persistAfter *= 10000000;
m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine");
@ -1290,7 +1298,6 @@ namespace OpenSim.Region.Framework.Scenes
{
if (RegionInfo.RegionHandle != otherRegion.RegionHandle)
{
if (isNeighborRegion(otherRegion))
{
// Let the grid service module know, so this can be cached
@ -1300,9 +1307,6 @@ namespace OpenSim.Region.Framework.Scenes
{
ForEachRootScenePresence(delegate(ScenePresence agent)
{
//agent.ControllingClient.new
//this.CommsManager.InterRegion.InformRegionOfChildAgent(otherRegion.RegionHandle, agent.ControllingClient.RequestClientInfo());
List<ulong> old = new List<ulong>();
old.Add(otherRegion.RegionHandle);
agent.DropOldNeighbours(old);
@ -1328,7 +1332,7 @@ namespace OpenSim.Region.Framework.Scenes
public bool isNeighborRegion(GridRegion otherRegion)
{
int tmp = otherRegion.RegionLocX - (int)RegionInfo.WorldLocX; ;
int tmp = otherRegion.RegionLocX - (int)RegionInfo.WorldLocX;
if (tmp < -otherRegion.RegionSizeX && tmp > RegionInfo.RegionSizeX)
return false;
@ -1695,9 +1699,6 @@ namespace OpenSim.Region.Framework.Scenes
{
if (PhysicsEnabled)
physicsFPS = m_sceneGraph.UpdatePhysics(FrameTime);
if (SynchronizeScene != null)
SynchronizeScene(this);
}
tmpMS2 = Util.GetTimeStampMS();
@ -1775,30 +1776,6 @@ namespace OpenSim.Region.Framework.Scenes
// Region ready should always be set
Ready = true;
IConfig restartConfig = m_config.Configs["RestartModule"];
if (restartConfig != null)
{
string markerPath = restartConfig.GetString("MarkerPath", String.Empty);
if (markerPath != String.Empty)
{
string path = Path.Combine(markerPath, RegionInfo.RegionID.ToString() + ".ready");
try
{
string pidstring = System.Diagnostics.Process.GetCurrentProcess().Id.ToString();
FileStream fs = File.Create(path);
System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
Byte[] buf = enc.GetBytes(pidstring);
fs.Write(buf, 0, buf.Length);
fs.Close();
}
catch (Exception)
{
}
}
}
}
else
{
@ -4818,6 +4795,20 @@ Label_GroupsDone:
return true;
}
/// <summary>
/// Tries to teleport agent within region.
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="position"></param>
/// <param name="lookAt"></param>
/// <param name="teleportFlags"></param>
public void RequestLocalTeleport(ScenePresence sp, Vector3 position, Vector3 vel,
Vector3 lookat, int flags)
{
sp.LocalTeleport(position, vel, lookat, flags);
}
/// <summary>
/// Tries to teleport agent to another region.
/// </summary>

View File

@ -119,6 +119,21 @@ namespace OpenSim.Region.Framework.Scenes
// private PrimCountTaintedDelegate handlerPrimCountTainted = null;
public bool IsViewerCachable
{
get
{
// needs more exclusion ?
return(Backup && !IsTemporary && !inTransit && !IsSelected && !UsesPhysics && !IsAttachmentCheckFull() &&
!RootPart.Shape.MeshFlagEntry && // animations are not sent correctly for now
RootPart.KeyframeMotion == null &&
(DateTime.UtcNow.Ticks - timeLastChanged > 36000000000) && //36000000000 is one hour
RootPart.Velocity.LengthSquared() < 1e8f && // should not be needed
RootPart.Acceleration.LengthSquared() < 1e4f // should not be needed
);
}
}
/// <summary>
/// Signal whether the non-inventory attributes of any prims in the group have changed
/// since the group's last persistent backup
@ -128,7 +143,8 @@ namespace OpenSim.Region.Framework.Scenes
private long timeLastChanged = 0;
private long m_maxPersistTime = 0;
private long m_minPersistTime = 0;
// private Random m_rand;
public int PseudoCRC;
/// <summary>
/// This indicates whether the object has changed such that it needs to be repersisted to permenant storage
@ -145,40 +161,26 @@ namespace OpenSim.Region.Framework.Scenes
{
if (value)
{
if (Backup)
{
m_scene.SceneGraph.FireChangeBackup(this);
}
PseudoCRC = (int)(DateTime.UtcNow.Ticks); ;
timeLastChanged = DateTime.UtcNow.Ticks;
if (!m_hasGroupChanged)
timeFirstChanged = DateTime.UtcNow.Ticks;
timeFirstChanged = timeLastChanged;
if (m_rootPart != null && m_scene != null)
{
/*
if (m_rand == null)
{
byte[] val = new byte[16];
m_rootPart.UUID.ToBytes(val, 0);
m_rand = new Random(BitConverter.ToInt32(val, 0));
}
*/
if (m_scene.GetRootAgentCount() == 0)
{
//If the region is empty, this change has been made by an automated process
//and thus we delay the persist time by a random amount between 1.5 and 2.5.
// float factor = 1.5f + (float)(m_rand.NextDouble());
float factor = 2.0f;
m_maxPersistTime = (long)((float)m_scene.m_persistAfter * factor);
m_minPersistTime = (long)((float)m_scene.m_dontPersistBefore * factor);
m_maxPersistTime = (long)(m_scene.m_persistAfter * factor);
m_minPersistTime = (long)(m_scene.m_dontPersistBefore * factor);
}
else
{
//If the region is not empty, we want to obey the minimum and maximum persist times
//but add a random factor so we stagger the object persistance a little
// m_maxPersistTime = (long)((float)m_scene.m_persistAfter * (1.0d - (m_rand.NextDouble() / 5.0d))); //Multiply by 1.0-1.5
// m_minPersistTime = (long)((float)m_scene.m_dontPersistBefore * (1.0d + (m_rand.NextDouble() / 2.0d))); //Multiply by 0.8-1.0
m_maxPersistTime = m_scene.m_persistAfter;
m_minPersistTime = m_scene.m_dontPersistBefore;
}
@ -768,9 +770,9 @@ namespace OpenSim.Region.Framework.Scenes
}
if(av.IsNPC)
av.crossingFlags = 0;
av.m_crossingFlags = 0;
else
av.crossingFlags = cflags;
av.m_crossingFlags = cflags;
av.PrevSitOffset = av.OffsetPosition;
av.ParentID = 0;
@ -819,7 +821,7 @@ namespace OpenSim.Region.Framework.Scenes
if(entityTransfer.CrossAgentCreateFarChild(av,destination, newpos, ctx))
crossedfar = true;
else
av.crossingFlags = 0;
av.m_crossingFlags = 0;
}
if(crossedfar)
@ -832,7 +834,7 @@ namespace OpenSim.Region.Framework.Scenes
av.IsInTransit = true;
m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar {0} to {1}", av.Name, val);
if(av.crossingFlags > 0)
if(av.m_crossingFlags > 0)
entityTransfer.CrossAgentToNewRegionAsync(av, newpos, destination, false, ctx);
if (av.IsChildAgent)
@ -847,7 +849,7 @@ namespace OpenSim.Region.Framework.Scenes
av.ParentPart = null;
// In any case
av.IsInTransit = false;
av.crossingFlags = 0;
av.m_crossingFlags = 0;
m_log.DebugFormat("[SCENE OBJECT]: Crossing agent {0} {1} completed.", av.Firstname, av.Lastname);
}
else
@ -863,7 +865,7 @@ namespace OpenSim.Region.Framework.Scenes
oldp.X = Util.Clamp<float>(oldp.X, 0.5f, sog.m_scene.RegionInfo.RegionSizeX - 0.5f);
oldp.Y = Util.Clamp<float>(oldp.Y, 0.5f, sog.m_scene.RegionInfo.RegionSizeY - 0.5f);
av.AbsolutePosition = oldp;
av.crossingFlags = 0;
av.m_crossingFlags = 0;
av.sitAnimation = "SIT";
av.IsInTransit = false;
if(av.Animator!= null)
@ -924,7 +926,7 @@ namespace OpenSim.Region.Framework.Scenes
ScenePresence av = avinfo.av;
av.ParentUUID = UUID.Zero;
av.ParentID = avinfo.ParentID;
av.crossingFlags = 0;
av.m_crossingFlags = 0;
}
}
avsToCross.Clear();
@ -1330,6 +1332,7 @@ namespace OpenSim.Region.Framework.Scenes
public SceneObjectGroup()
{
m_lastCollisionSoundMS = Util.GetTimeStampMS() + 1000.0;
PseudoCRC = (int)(DateTime.UtcNow.Ticks);
}
/// <summary>
@ -2441,6 +2444,21 @@ namespace OpenSim.Region.Framework.Scenes
}
}
public void SendUpdateProbes(IClientAPI remoteClient)
{
PrimUpdateFlags update = PrimUpdateFlags.UpdateProbe;
RootPart.SendUpdate(remoteClient, update);
SceneObjectPart[] parts = m_parts.GetArray();
for (int i = 0; i < parts.Length; i++)
{
SceneObjectPart part = parts[i];
if (part != RootPart)
part.SendUpdate(remoteClient, update);
}
}
#region Copying
/// <summary>
@ -2516,6 +2534,7 @@ namespace OpenSim.Region.Framework.Scenes
}
dupe.InvalidatePartsLinkMaps();
dupe.PseudoCRC = (int)(DateTime.UtcNow.Ticks);
m_dupeInProgress = false;
return dupe;
}
@ -2769,6 +2788,7 @@ namespace OpenSim.Region.Framework.Scenes
}
}
PseudoCRC = (int)(DateTime.UtcNow.Ticks);
rpart.ScheduleFullUpdate();
}
@ -2808,6 +2828,7 @@ namespace OpenSim.Region.Framework.Scenes
part.ResetIDs(part.LinkNum); // Don't change link nums
m_parts.Add(part.UUID, part);
}
PseudoCRC = (int)(DateTime.UtcNow.Ticks);
}
}
@ -3117,7 +3138,6 @@ namespace OpenSim.Region.Framework.Scenes
}
}
// 'linkPart' == the root of the group being linked into this group
SceneObjectPart linkPart = objectGroup.m_rootPart;
@ -3160,7 +3180,6 @@ namespace OpenSim.Region.Framework.Scenes
axPos *= Quaternion.Conjugate(parentRot);
linkPart.OffsetPosition = axPos;
// If there is only one SOP in a SOG, the LinkNum is zero. I.e., not a linkset.
// Now that we know this SOG has at least two SOPs in it, the new root
// SOP becomes the first in the linkset.
@ -3193,8 +3212,7 @@ namespace OpenSim.Region.Framework.Scenes
linkPart.CreateSelected = true;
// let physics know preserve part volume dtc messy since UpdatePrimFlags doesn't look to parent changes for now
linkPart.UpdatePrimFlags(grpusephys, grptemporary, (IsPhantom || (linkPart.Flags & PrimFlags.Phantom) != 0), linkPart.VolumeDetectActive, true);
linkPart.UpdatePrimFlags(grpusephys, grptemporary, (IsPhantom || (linkPart.Flags & PrimFlags.Phantom) != 0), linkPart.VolumeDetectActive || RootPart.VolumeDetectActive, true);
// If the added SOP is physical, also tell the physics engine about the link relationship.
if (linkPart.PhysActor != null && m_rootPart.PhysActor != null && m_rootPart.PhysActor.IsPhysical)

View File

@ -312,7 +312,6 @@ namespace OpenSim.Region.Framework.Scenes
private Quaternion m_sitTargetOrientation = Quaternion.Identity;
private Vector3 m_sitTargetPosition;
private string m_sitAnimation = "SIT";
private bool m_occupied; // KF if any av is sitting on this prim
private string m_text = String.Empty;
private string m_touchName = String.Empty;
private UndoRedoState m_UndoRedo = null;
@ -1001,7 +1000,7 @@ namespace OpenSim.Region.Framework.Scenes
get
{
PhysicsActor actor = PhysActor;
if (actor != null)
if (actor != null && actor.IsPhysical)
{
m_acceleration = actor.Acceleration;
}
@ -1038,8 +1037,8 @@ namespace OpenSim.Region.Framework.Scenes
{
get
{
if (m_text.Length > 256) // yes > 254
return m_text.Substring(0, 256);
if (m_text.Length > 254)
return m_text.Substring(0, 254);
return m_text;
}
set { m_text = value; }
@ -1179,9 +1178,10 @@ namespace OpenSim.Region.Framework.Scenes
set
{
string old = m_mediaUrl;
m_mediaUrl = value;
if (ParentGroup != null)
if (ParentGroup != null && old != m_mediaUrl)
ParentGroup.HasGroupChanged = true;
}
}
@ -1385,13 +1385,6 @@ namespace OpenSim.Region.Framework.Scenes
}
}
[XmlIgnore]
public bool IsOccupied // KF If an av is sittingon this prim
{
get { return m_occupied; }
set { m_occupied = value; }
}
/// <summary>
/// ID of the avatar that is sat on us if we have a sit target. If there is no such avatar then is UUID.Zero
/// </summary>
@ -2338,10 +2331,7 @@ namespace OpenSim.Region.Framework.Scenes
{
ParentGroup.Scene.RemovePhysicalPrim(1);
Velocity = new Vector3(0, 0, 0);
Acceleration = new Vector3(0, 0, 0);
AngularVelocity = new Vector3(0, 0, 0);
APIDActive = false;
Stop();
if (pa.Phantom && !VolumeDetectActive)
{
@ -2475,13 +2465,10 @@ namespace OpenSim.Region.Framework.Scenes
public uint GetEffectiveObjectFlags()
{
// Commenting this section of code out since it doesn't actually do anything, as enums are handled by
// value rather than reference
// PrimFlags f = _flags;
// if (m_parentGroup == null || m_parentGroup.RootPart == this)
// f &= ~(PrimFlags.Touch | PrimFlags.Money);
return (uint)Flags | (uint)LocalFlags;
uint eff = (uint)Flags | (uint)LocalFlags;
if(m_inventory == null || m_inventory.Count == 0)
eff |= (uint)PrimFlags.InventoryEmpty;
return eff;
}
// some of this lines need be moved to other place later
@ -3896,15 +3883,15 @@ namespace OpenSim.Region.Framework.Scenes
{
if (Shape.SculptEntry && !ignoreSculpt)
return PrimType.SCULPT;
if ((Shape.ProfileCurve & 0x07) == (byte)ProfileShape.Square)
ProfileShape ps = (ProfileShape)(Shape.ProfileCurve & 0x07);
if (ps == ProfileShape.Square)
{
if (Shape.PathCurve == (byte)Extrusion.Straight)
return PrimType.BOX;
else if (Shape.PathCurve == (byte)Extrusion.Curve1)
return PrimType.TUBE;
}
else if ((Shape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
else if (ps == ProfileShape.Circle)
{
if (Shape.PathCurve == (byte)Extrusion.Straight || Shape.PathCurve == (byte)Extrusion.Flexible)
return PrimType.CYLINDER;
@ -3912,12 +3899,12 @@ namespace OpenSim.Region.Framework.Scenes
else if (Shape.PathCurve == (byte)Extrusion.Curve1)
return PrimType.TORUS;
}
else if ((Shape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle)
else if (ps == ProfileShape.HalfCircle)
{
if (Shape.PathCurve == (byte)Extrusion.Curve1 || Shape.PathCurve == (byte)Extrusion.Curve2)
return PrimType.SPHERE;
}
else if ((Shape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
else if (ps == ProfileShape.EquilateralTriangle)
{
if (Shape.PathCurve == (byte)Extrusion.Straight || Shape.PathCurve == (byte)Extrusion.Flexible)
return PrimType.PRISM;
@ -4004,9 +3991,10 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="text"></param>
public void SetText(string text)
{
Text = text;
string oldtext = m_text;
m_text = text;
if (ParentGroup != null)
if (ParentGroup != null && oldtext != text)
{
ParentGroup.HasGroupChanged = true;
ScheduleFullUpdate();
@ -4021,11 +4009,18 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="alpha"></param>
public void SetText(string text, Vector3 color, double alpha)
{
Color oldcolor = Color;
string oldtext = m_text;
Color = Color.FromArgb((int) (alpha*0xff),
(int) (color.X*0xff),
(int) (color.Y*0xff),
(int) (color.Z*0xff));
SetText(text);
m_text = text;
if(ParentGroup != null && (oldcolor != Color || oldtext != m_text))
{
ParentGroup.HasGroupChanged = true;
ScheduleFullUpdate();
}
}
public void StoreUndoState(ObjectChangeType change)
@ -4722,14 +4717,13 @@ namespace OpenSim.Region.Framework.Scenes
if ((SetPhantom && !UsePhysics && !SetVD) || ParentGroup.IsAttachment || PhysicsShapeType == (byte)PhysShapeType.none
|| (Shape.PathCurve == (byte)Extrusion.Flexible))
{
Stop();
if (pa != null)
{
if(wasUsingPhysics)
ParentGroup.Scene.RemovePhysicalPrim(1);
RemoveFromPhysics();
}
Stop();
}
else
@ -5130,7 +5124,13 @@ namespace OpenSim.Region.Framework.Scenes
if (changeFlags == 0)
return;
m_shape.TextureEntry = newTex.GetBytes(9);
// we do need better compacter do just the trivial case
if(nsides == 1 && newTex.FaceTextures[0] != null)
{
newTex.DefaultTexture = newTex.GetFace(0);
newTex.FaceTextures[0] = null;
}
m_shape.TextureEntry = newTex.GetBytes(nsides);
TriggerScriptChangedEvent(changeFlags);
ParentGroup.HasGroupChanged = true;
ScheduleUpdate(PrimUpdateFlags.Textures);

File diff suppressed because it is too large Load Diff

View File

@ -556,7 +556,7 @@ namespace OpenSim.Region.Framework.Scenes
sb[27].StatID = (uint)Stats.PhysicsLodTasks;
sb[27].StatValue = 0;
sb[28].StatID = (uint)Stats.ScriptEps; // we actuall have this, but not messing array order AGAIN
sb[28].StatID = (uint)Stats.ScriptEps; // we actually have this, but not messing array order AGAIN
sb[28].StatValue = (float)Math.Round(m_scriptEventsPerSecond * updateTimeFactor);
sb[29].StatID = (uint)Stats.SimAIStepTimeMS;

View File

@ -155,11 +155,15 @@ namespace OpenSim.Region.Framework.Scenes.Tests
sp1SceneA.AbsolutePosition = so1StartPos;
sp1SceneA.HandleAgentRequestSit(sp1SceneA.ControllingClient, sp1SceneA.UUID, so1.UUID, Vector3.Zero);
sceneA.Update(4);
sceneB.Update(4);
// Cross
sceneA.SceneGraph.UpdatePrimGroupPosition(
so1.LocalId, new Vector3(so1StartPos.X, so1StartPos.Y - 20, so1StartPos.Z), sp1SceneA.ControllingClient);
// crossing is async
sceneA.Update(4);
sceneB.Update(4);
Thread.Sleep(500);
SceneObjectGroup so1PostCross;
@ -171,6 +175,9 @@ namespace OpenSim.Region.Framework.Scenes.Tests
TestClient sceneBTc = ((TestClient)sp1SceneBPostCross.ControllingClient);
sceneBTc.CompleteMovement();
sceneA.Update(4);
sceneB.Update(4);
Assert.IsFalse(sp1SceneBPostCross.IsChildAgent, "sp1SceneAPostCross.IsChildAgent unexpectedly true");
Assert.IsTrue(sp1SceneBPostCross.IsSatOnObject);
@ -188,6 +195,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests
sceneB.SceneGraph.UpdatePrimGroupPosition(
so1PostCross.LocalId, new Vector3(so1PostCrossPos.X, so1PostCrossPos.Y + 20, so1PostCrossPos.Z), sp1SceneBPostCross.ControllingClient);
sceneA.Update(4);
sceneB.Update(4);
// crossing is async
Thread.Sleep(500);

View File

@ -212,6 +212,9 @@ namespace OpenSim.Region.Framework.Scenes.Tests
ScenePresence sp = SceneHelpers.AddScenePresence(sceneA, userId);
sp.AbsolutePosition = new Vector3(30, 31, 32);
sceneA.Update(4);
sceneB.Update(4);
List<TestClient> destinationTestClients = new List<TestClient>();
EntityTransferHelpers.SetupSendRegionTeleportTriggersDestinationClientCreateAndCompleteMovement(
(TestClient)sp.ControllingClient, destinationTestClients);
@ -224,11 +227,14 @@ namespace OpenSim.Region.Framework.Scenes.Tests
(uint)TeleportFlags.ViaLocation);
// Assert.That(sceneA.GetScenePresence(userId), Is.Null);
sceneA.Update(4);
sceneB.Update(4);
ScenePresence sceneBSp = sceneB.GetScenePresence(userId);
Assert.That(sceneBSp, Is.Not.Null);
Assert.That(sceneBSp.Scene.RegionInfo.RegionName, Is.EqualTo(sceneB.RegionInfo.RegionName));
Assert.That(sceneBSp.AbsolutePosition, Is.EqualTo(teleportPosition));
Assert.That(sceneBSp.AbsolutePosition.X, Is.EqualTo(teleportPosition.X));
Assert.That(sceneBSp.AbsolutePosition.Y, Is.EqualTo(teleportPosition.Y));
//Assert.That(sceneA.GetRootAgentCount(), Is.EqualTo(0));
//Assert.That(sceneA.GetChildAgentCount(), Is.EqualTo(0));
@ -239,7 +245,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
// Lookat is sent to the client only - sp.Lookat does not yield the same thing (calculation from camera
// position instead).
// Assert.That(sp.Lookat, Is.EqualTo(teleportLookAt));
// Assert.That(sp.Lookat, Is.EqualTo(teleportLookAt));
}
/// <summary>
@ -310,7 +316,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests
ScenePresence sceneASp = sceneA.GetScenePresence(userId);
Assert.That(sceneASp, Is.Not.Null);
Assert.That(sceneASp.Scene.RegionInfo.RegionName, Is.EqualTo(sceneA.RegionInfo.RegionName));
Assert.That(sceneASp.AbsolutePosition, Is.EqualTo(preTeleportPosition));
Assert.That(sceneASp.AbsolutePosition.X, Is.EqualTo(preTeleportPosition.X));
Assert.That(sceneASp.AbsolutePosition.Y, Is.EqualTo(preTeleportPosition.Y));
Assert.That(sceneA.GetRootAgentCount(), Is.EqualTo(1));
Assert.That(sceneA.GetChildAgentCount(), Is.EqualTo(0));
@ -369,6 +376,9 @@ namespace OpenSim.Region.Framework.Scenes.Tests
ScenePresence sp = SceneHelpers.AddScenePresence(sceneA, userId);
sp.AbsolutePosition = preTeleportPosition;
sceneA.Update(4);
sceneB.Update(4);
// Make sceneB refuse CreateAgent
sceneB.LoginsEnabled = false;
@ -379,14 +389,18 @@ namespace OpenSim.Region.Framework.Scenes.Tests
teleportLookAt,
(uint)TeleportFlags.ViaLocation);
// ((TestClient)sp.ControllingClient).CompleteTeleportClientSide();
// ((TestClient)sp.ControllingClient).CompleteTeleportClientSide();
sceneA.Update(4);
sceneB.Update(4);
Assert.That(sceneB.GetScenePresence(userId), Is.Null);
ScenePresence sceneASp = sceneA.GetScenePresence(userId);
Assert.That(sceneASp, Is.Not.Null);
Assert.That(sceneASp.Scene.RegionInfo.RegionName, Is.EqualTo(sceneA.RegionInfo.RegionName));
Assert.That(sceneASp.AbsolutePosition, Is.EqualTo(preTeleportPosition));
Assert.That(sceneASp.AbsolutePosition.X, Is.EqualTo(preTeleportPosition.X));
Assert.That(sceneASp.AbsolutePosition.Y, Is.EqualTo(preTeleportPosition.Y));
Assert.That(sceneA.GetRootAgentCount(), Is.EqualTo(1));
Assert.That(sceneA.GetChildAgentCount(), Is.EqualTo(0));
@ -458,6 +472,9 @@ namespace OpenSim.Region.Framework.Scenes.Tests
ScenePresence sp = SceneHelpers.AddScenePresence(sceneA, userId);
sp.AbsolutePosition = preTeleportPosition;
sceneA.Update(4);
sceneB.Update(4);
sceneA.RequestTeleportLocation(
sp.ControllingClient,
sceneB.RegionInfo.RegionHandle,
@ -468,13 +485,16 @@ namespace OpenSim.Region.Framework.Scenes.Tests
// FIXME: Not setting up InformClientOfNeighbour on the TestClient means that it does not initiate
// communication with the destination region. But this is a very non-obvious way of doing it - really we
// should be forced to expicitly set this up.
sceneA.Update(4);
sceneB.Update(4);
Assert.That(sceneB.GetScenePresence(userId), Is.Null);
ScenePresence sceneASp = sceneA.GetScenePresence(userId);
Assert.That(sceneASp, Is.Not.Null);
Assert.That(sceneASp.Scene.RegionInfo.RegionName, Is.EqualTo(sceneA.RegionInfo.RegionName));
Assert.That(sceneASp.AbsolutePosition, Is.EqualTo(preTeleportPosition));
Assert.That(sceneASp.AbsolutePosition.X, Is.EqualTo(preTeleportPosition.X));
Assert.That(sceneASp.AbsolutePosition.Y, Is.EqualTo(preTeleportPosition.Y));
Assert.That(sceneA.GetRootAgentCount(), Is.EqualTo(1));
Assert.That(sceneA.GetChildAgentCount(), Is.EqualTo(0));
@ -614,6 +634,9 @@ namespace OpenSim.Region.Framework.Scenes.Tests
ScenePresence beforeSceneASp = SceneHelpers.AddScenePresence(sceneA, tc, acd);
beforeSceneASp.AbsolutePosition = new Vector3(30, 31, 32);
sceneA.Update(4);
sceneB.Update(4);
Assert.That(beforeSceneASp, Is.Not.Null);
Assert.That(beforeSceneASp.IsChildAgent, Is.False);
@ -638,6 +661,9 @@ namespace OpenSim.Region.Framework.Scenes.Tests
teleportLookAt,
(uint)TeleportFlags.ViaLocation);
sceneA.Update(4);
sceneB.Update(4);
ScenePresence afterSceneASp = sceneA.GetScenePresence(userId);
Assert.That(afterSceneASp, Is.Not.Null);
Assert.That(afterSceneASp.IsChildAgent, Is.True);
@ -646,7 +672,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests
Assert.That(afterSceneBSp, Is.Not.Null);
Assert.That(afterSceneBSp.IsChildAgent, Is.False);
Assert.That(afterSceneBSp.Scene.RegionInfo.RegionName, Is.EqualTo(sceneB.RegionInfo.RegionName));
Assert.That(afterSceneBSp.AbsolutePosition, Is.EqualTo(teleportPosition));
Assert.That(afterSceneBSp.AbsolutePosition.X, Is.EqualTo(teleportPosition.X));
Assert.That(afterSceneBSp.AbsolutePosition.Y, Is.EqualTo(teleportPosition.Y));
Assert.That(sceneA.GetRootAgentCount(), Is.EqualTo(0));
Assert.That(sceneA.GetChildAgentCount(), Is.EqualTo(1));

View File

@ -524,6 +524,8 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
set { }
}
public float StartFar { get; set; }
public bool TryGet<T>(out T iface)
{
iface = default(T);
@ -932,7 +934,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
OnSetAppearance(this, appearance.Texture, (byte[])appearance.VisualParams.Clone(),appearance.AvatarSize, new WearableCacheItem[0]);
}
public void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args)
public void SendRegionHandshake()
{
m_log.Info("[IRCd ClientStack] Completing Handshake to Region");
@ -943,7 +945,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
if (OnCompleteMovementToRegion != null)
{
OnCompleteMovementToRegion(this, true);
OnCompleteMovementToRegion(this, false);
}
}
@ -967,11 +969,6 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
}
public void SendStartPingCheck(byte seq)
{
}
public void SendKillObject(List<uint> localID)
{
@ -1160,7 +1157,8 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
}
public void SendXferPacket(ulong xferID, uint packet, byte[] data, bool isTaskInventory)
public void SendXferPacket(ulong xferID, uint packet,
byte[] XferData, int XferDataOffset, int XferDatapktLen, bool isTaskInventory)
{
}
@ -1778,7 +1776,10 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
return 0;
}
public void CheckViewerCaps() { }
public uint GetViewerCaps()
{
return 0;
}
}
}

View File

@ -278,7 +278,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
// There might be some problem with the thread we're generating this on but not
// doing the update at this time causes problems (Mantis #7920 and #7915)
// TODO: move sending this update to a later time in the rootification of the client.
if(!sp.haveGroupInformation)
if(!sp.m_haveGroupInformation)
SendAgentGroupDataUpdate(sp.ControllingClient, false);
}

View File

@ -133,7 +133,7 @@ namespace OpenSim.Region.OptionalModules.Materials
if(m_changed.Count == 0)
return;
if(forcedBackup)
if (forcedBackup)
{
toStore = new List<FaceMaterial>(m_changed.Keys);
m_changed.Clear();
@ -154,16 +154,29 @@ namespace OpenSim.Region.OptionalModules.Materials
m_changed.Remove(fm);
}
}
}
if(toStore.Count > 0)
Util.FireAndForget(delegate
{
if (forcedBackup)
{
foreach(FaceMaterial fm in toStore)
foreach (FaceMaterial fm in toStore)
{
AssetBase a = MakeAsset(fm, false);
m_scene.AssetService.Store(a);
}
});
}
else
{
Util.FireAndForget(delegate
{
foreach (FaceMaterial fm in toStore)
{
AssetBase a = MakeAsset(fm, false);
m_scene.AssetService.Store(a);
}
});
}
}
}

View File

@ -562,6 +562,8 @@ namespace OpenSim.Region.OptionalModules.World.NPC
set { }
}
public float StartFar { get; set; }
public virtual UUID AgentId
{
get { return m_uuid; }
@ -668,10 +670,6 @@ namespace OpenSim.Region.OptionalModules.World.NPC
{
}
public virtual void SendStartPingCheck(byte seq)
{
}
public virtual void SendAvatarPickerReply(AvatarPickerReplyAgentDataArgs AgentData, List<AvatarPickerReplyDataArgs> Data)
{
}
@ -870,9 +868,11 @@ namespace OpenSim.Region.OptionalModules.World.NPC
{
}
public virtual void SendXferPacket(ulong xferID, uint packet, byte[] data, bool isTaskInventory)
public virtual void SendXferPacket(ulong xferID, uint packet,
byte[] XferData, int XferDataOffset, int XferDatapktLen, bool isTaskInventory)
{
}
public virtual void SendAbortXferPacket(ulong xferID)
{
@ -928,7 +928,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
{
}
public virtual void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args)
public virtual void SendRegionHandshake()
{
if (OnRegionHandShakeReply != null)
{
@ -1388,7 +1388,10 @@ namespace OpenSim.Region.OptionalModules.World.NPC
return 0;
}
public void CheckViewerCaps() { }
public uint GetViewerCaps()
{
return 0;
}
}
}

View File

@ -597,28 +597,22 @@ namespace OpenSim.Region.PhysicsModule.Meshing
{
OSD decodedOsd = null;
using (MemoryStream inMs = new MemoryStream(meshBytes))
using (MemoryStream outMs = new MemoryStream())
{
using (MemoryStream outMs = new MemoryStream())
using (MemoryStream inMs = new MemoryStream(meshBytes))
{
using (DeflateStream decompressionStream = new DeflateStream(inMs, CompressionMode.Decompress))
{
byte[] readBuffer = new byte[2048];
byte[] readBuffer = new byte[8192];
inMs.Read(readBuffer, 0, 2); // skip first 2 bytes in header
int readLen = 0;
while ((readLen = decompressionStream.Read(readBuffer, 0, readBuffer.Length)) > 0)
outMs.Write(readBuffer, 0, readLen);
outMs.Flush();
outMs.Seek(0, SeekOrigin.Begin);
byte[] decompressedBuf = outMs.GetBuffer();
decodedOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf);
}
}
outMs.Seek(0, SeekOrigin.Begin);
decodedOsd = OSDParser.DeserializeLLSDBinary(outMs);
}
return decodedOsd;
}

View File

@ -1603,7 +1603,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
}
else
{
Vector3 a = _velocity; // previus velocity
Vector3 a = _velocity; // previous velocity
SetSmooth(ref _velocity,ref vel,2);
a = (_velocity - a) * invtimeStep;
SetSmooth(ref _acceleration,ref a,2);
@ -1921,6 +1921,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
_position = newPos;
m_freemove = false;
_zeroFlag = false;
m_pidControllerActive = true;
}
@ -1976,8 +1977,8 @@ namespace OpenSim.Region.PhysicsModule.ubOde
private void changeTargetVelocity(Vector3 newVel)
{
m_pidControllerActive = true;
m_freemove = false;
//m_pidControllerActive = true;
//m_freemove = false;
_target_velocity = newVel;
if (Body != IntPtr.Zero)
SafeNativeMethods.BodyEnable(Body);

View File

@ -425,31 +425,24 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
return false; // no mesh data in asset
OSD decodedMeshOsd = new OSD();
byte[] meshBytes = new byte[physSize];
System.Buffer.BlockCopy(primShape.SculptData, physOffset, meshBytes, 0, physSize);
try
{
using (MemoryStream inMs = new MemoryStream(meshBytes))
using (MemoryStream outMs = new MemoryStream(4 * physSize))
{
using (MemoryStream outMs = new MemoryStream())
using (MemoryStream inMs = new MemoryStream(primShape.SculptData, physOffset, physSize))
{
using (DeflateStream decompressionStream = new DeflateStream(inMs, CompressionMode.Decompress))
{
byte[] readBuffer = new byte[2048];
byte[] readBuffer = new byte[8192];
inMs.Read(readBuffer, 0, 2); // skip first 2 bytes in header
int readLen = 0;
while ((readLen = decompressionStream.Read(readBuffer, 0, readBuffer.Length)) > 0)
outMs.Write(readBuffer, 0, readLen);
outMs.Seek(0, SeekOrigin.Begin);
byte[] decompressedBuf = outMs.GetBuffer();
decodedMeshOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf);
}
}
outMs.Seek(0, SeekOrigin.Begin);
decodedMeshOsd = OSDParser.DeserializeLLSDBinary(outMs);
}
}
catch (Exception e)

View File

@ -2403,6 +2403,70 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
ScriptSleep(m_sleepMsOnSetLinkTexture);
}
protected void SetTextureParams(SceneObjectPart part, string texture, double scaleU, double ScaleV,
double offsetU, double offsetV, double rotation, int face)
{
if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
return;
UUID textureID = new UUID();
bool dotexture = true;
if(String.IsNullOrEmpty(texture) || texture == ScriptBaseClass.NULL_KEY)
dotexture = false;
else
{
textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture);
if (textureID == UUID.Zero)
{
if (!UUID.TryParse(texture, out textureID))
dotexture = false;
}
}
Primitive.TextureEntry tex = part.Shape.Textures;
int nsides = GetNumberOfSides(part);
if (face >= 0 && face < nsides)
{
Primitive.TextureEntryFace texface = tex.CreateFace((uint)face);
if (dotexture)
texface.TextureID = textureID;
texface.RepeatU = (float)scaleU;
texface.RepeatV = (float)ScaleV;
texface.OffsetU = (float)offsetU;
texface.OffsetV = (float)offsetV;
texface.Rotation = (float)rotation;
tex.FaceTextures[face] = texface;
part.UpdateTextureEntry(tex);
return;
}
else if (face == ScriptBaseClass.ALL_SIDES)
{
for (uint i = 0; i < nsides; i++)
{
if (tex.FaceTextures[i] != null)
{
if (dotexture)
tex.FaceTextures[i].TextureID = textureID;
tex.FaceTextures[i].RepeatU = (float)scaleU;
tex.FaceTextures[i].RepeatV = (float)ScaleV;
tex.FaceTextures[i].OffsetU = (float)offsetU;
tex.FaceTextures[i].OffsetV = (float)offsetV;
tex.FaceTextures[i].Rotation = (float)rotation;
}
}
if (dotexture)
tex.DefaultTexture.TextureID = textureID;
tex.DefaultTexture.RepeatU = (float)scaleU;
tex.DefaultTexture.RepeatV = (float)ScaleV;
tex.DefaultTexture.OffsetU = (float)offsetU;
tex.DefaultTexture.OffsetV = (float)offsetV;
tex.DefaultTexture.Rotation = (float)rotation;
part.UpdateTextureEntry(tex);
return;
}
}
protected void SetTexture(SceneObjectPart part, string texture, int face)
{
if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
@ -3830,6 +3894,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (m_item.PermsGranter != m_host.OwnerID)
return;
SceneObjectGroup grp = m_host.ParentGroup;
if (grp == null || grp.IsDeleted || grp.IsAttachment)
return;
if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_ATTACH) != 0)
AttachToAvatar(attachmentPoint);
}
@ -7991,13 +8059,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
public void llSetTouchText(string text)
{
m_host.AddScriptLPS(1);
m_host.TouchName = text;
if(text.Length <= 9)
m_host.TouchName = text;
else
m_host.TouchName = text.Substring(0, 9);
}
public void llSetSitText(string text)
{
m_host.AddScriptLPS(1);
m_host.SitName = text;
if (text.Length <= 9)
m_host.SitName = text;
else
m_host.SitName = text.Substring(0, 9);
}
public void llSetCameraEyeOffset(LSL_Vector offset)
@ -9722,11 +9796,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return new LSL_List();
}
SetTexture(part, tex, face);
ScaleTexture(part, repeats.x, repeats.y, face);
OffsetTexture(part, offsets.x, offsets.y, face);
RotateTexture(part, rotation, face);
SetTextureParams(part, tex, repeats.x, repeats.y, offsets.x, offsets.y, rotation, face);
break;
case ScriptBaseClass.PRIM_COLOR:
@ -10360,17 +10430,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
}
string mapname = rules.Data[idx++].ToString();
UUID mapID = ScriptUtils.GetAssetIdFromItemName(m_host, mapname, (int)AssetType.Texture);
if (mapID == UUID.Zero)
UUID mapID = UUID.Zero;
if (!string.IsNullOrEmpty(mapname))
{
if (!UUID.TryParse(mapname, out mapID))
mapID = ScriptUtils.GetAssetIdFromItemName(m_host, mapname, (int)AssetType.Texture);
if (mapID == UUID.Zero)
{
Error(originFunc, string.Format("Error running rule #{0} -> PRIM_NORMAL: arg #{1} - must be a UUID or a texture name on object inventory", rulesParsed, idx - idxStart - 1));
return new LSL_List();
if (!UUID.TryParse(mapname, out mapID))
{
Error(originFunc, string.Format("Error running rule #{0} -> PRIM_NORMAL: arg #{1} - must be a UUID or a texture name on object inventory", rulesParsed, idx - idxStart - 1));
return new LSL_List();
}
}
}
LSL_Vector mnrepeat;
try
{
@ -10427,17 +10499,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
}
string smapname = rules.Data[idx++].ToString();
UUID smapID = ScriptUtils.GetAssetIdFromItemName(m_host, smapname, (int)AssetType.Texture);
if (smapID == UUID.Zero)
UUID smapID = UUID.Zero;
if(!string.IsNullOrEmpty(smapname))
{
if (!UUID.TryParse(smapname, out smapID))
smapID = ScriptUtils.GetAssetIdFromItemName(m_host, smapname, (int)AssetType.Texture);
if (smapID == UUID.Zero)
{
Error(originFunc, string.Format("Error running rule #{0} -> PRIM_SPECULAR: arg #{1} - must be a UUID or a texture name on object inventory", rulesParsed, idx - idxStart - 1));
return new LSL_List();
if (!UUID.TryParse(smapname, out smapID))
{
Error(originFunc, string.Format("Error running rule #{0} -> PRIM_SPECULAR: arg #{1} - must be a UUID or a texture name on object inventory", rulesParsed, idx - idxStart - 1));
return new LSL_List();
}
}
}
LSL_Vector msrepeat;
try
{
@ -10653,24 +10727,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
FaceMaterial mat = null;
UUID oldid = texface.MaterialID;
if(oldid != UUID.Zero)
mat = m_materialsModule.GetMaterialCopy(oldid);
if(mapID != UUID.Zero)
{
if(oldid != UUID.Zero)
mat = m_materialsModule.GetMaterialCopy(oldid);
if(mat == null)
mat = new FaceMaterial();
if(mat == null)
mat = new FaceMaterial();
mat.NormalMapID = mapID;
mat.NormalOffsetX = offsetX;
mat.NormalOffsetY = offsetY;
mat.NormalRepeatX = repeatX;
mat.NormalRepeatY = repeatY;
mat.NormalRotation = rot;
mat.NormalMapID = mapID;
mat.NormalOffsetX = offsetX;
mat.NormalOffsetY = offsetY;
mat.NormalRepeatX = repeatX;
mat.NormalRepeatY = repeatY;
mat.NormalRotation = rot;
UUID id = m_materialsModule.AddNewMaterial(mat);
if(oldid == id)
mapID = m_materialsModule.AddNewMaterial(mat);
}
if(oldid == mapID)
return false;
texface.MaterialID = id;
texface.MaterialID = mapID;
part.Shape.TextureEntry = tex.GetBytes(9);
m_materialsModule.RemoveMaterial(oldid);
return true;
@ -10715,29 +10792,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
FaceMaterial mat = null;
UUID oldid = texface.MaterialID;
if(oldid != UUID.Zero)
mat = m_materialsModule.GetMaterialCopy(oldid);
if (mapID != UUID.Zero)
{
if (oldid != UUID.Zero)
mat = m_materialsModule.GetMaterialCopy(oldid);
if(mat == null)
mat = new FaceMaterial();
if (mat == null)
mat = new FaceMaterial();
mat.SpecularMapID = mapID;
mat.SpecularOffsetX = offsetX;
mat.SpecularOffsetY = offsetY;
mat.SpecularRepeatX = repeatX;
mat.SpecularRepeatY = repeatY;
mat.SpecularRotation = rot;
mat.SpecularLightColorR = colorR;
mat.SpecularLightColorG = colorG;
mat.SpecularLightColorB = colorB;
mat.SpecularLightExponent = gloss;
mat.EnvironmentIntensity = env;
mat.SpecularMapID = mapID;
mat.SpecularOffsetX = offsetX;
mat.SpecularOffsetY = offsetY;
mat.SpecularRepeatX = repeatX;
mat.SpecularRepeatY = repeatY;
mat.SpecularRotation = rot;
mat.SpecularLightColorR = colorR;
mat.SpecularLightColorG = colorG;
mat.SpecularLightColorB = colorB;
mat.SpecularLightExponent = gloss;
mat.EnvironmentIntensity = env;
UUID id = m_materialsModule.AddNewMaterial(mat);
if(oldid == id)
mapID = m_materialsModule.AddNewMaterial(mat);
}
if(oldid == mapID)
return false;
texface.MaterialID = id;
texface.MaterialID = mapID;
part.Shape.TextureEntry = tex.GetBytes(9);
m_materialsModule.RemoveMaterial(oldid);
return true;
@ -14111,15 +14192,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
m_host.AddScriptLPS(1);
LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition).LandData;
if (land.OwnerID == m_host.OwnerID)
if (land.OwnerID == m_host.OwnerID && land.ParcelAccessList.Count > 0)
{
var todelete = new List<LandAccessEntry>();
foreach (LandAccessEntry entry in land.ParcelAccessList)
{
if (entry.Flags == AccessList.Ban)
{
land.ParcelAccessList.Remove(entry);
}
todelete.Add(entry);
}
foreach (LandAccessEntry entry in todelete)
land.ParcelAccessList.Remove(entry);
}
ScriptSleep(m_sleepMsOnResetLandBanList);
}
@ -14128,15 +14210,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
m_host.AddScriptLPS(1);
LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition).LandData;
if (land.OwnerID == m_host.OwnerID)
if (land.OwnerID == m_host.OwnerID && land.ParcelAccessList.Count > 0)
{
var todelete = new List<LandAccessEntry>();
foreach (LandAccessEntry entry in land.ParcelAccessList)
{
if (entry.Flags == AccessList.Access)
{
land.ParcelAccessList.Remove(entry);
}
todelete.Add(entry);
}
foreach (LandAccessEntry entry in todelete)
land.ParcelAccessList.Remove(entry);
}
ScriptSleep(m_sleepMsOnResetLandPassList);
}

View File

@ -145,6 +145,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
protected IUrlModule m_UrlModule = null;
protected ISoundModule m_SoundModule = null;
internal IConfig m_osslconfig;
internal TimeZoneInfo PSTTimeZone = null;
public void Initialize(
IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item)
@ -201,7 +202,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
default:
break;
}
}
try
{
PSTTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
}
catch
{
PSTTimeZone = null;
}
if(PSTTimeZone == null)
{
try
{
PSTTimeZone = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
}
catch
{
PSTTimeZone = null;
}
}
}
public override Object InitializeLifetimeService()
{
@ -903,6 +924,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
}
// Teleport functions
public void osLocalTeleportAgent(LSL_Key agent, LSL_Types.Vector3 position, LSL_Types.Vector3 velocity, LSL_Types.Vector3 lookat, LSL_Integer flags)
{
UUID agentId;
if (!UUID.TryParse(agent, out agentId))
return;
ScenePresence presence = World.GetScenePresence(agentId);
if (presence == null || presence.IsDeleted || presence.IsInTransit)
return;
Vector3 pos = presence.AbsolutePosition;
if (!checkAllowAgentTPbyLandOwner(agentId, pos))
return;
World.RequestLocalTeleport(presence, position, velocity, lookat, flags);
}
public void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat)
{
// High because there is no security check. High griefer potential
@ -3780,7 +3818,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
public LSL_List osGetPrimitiveParams(LSL_Key prim, LSL_List rules)
{
CheckThreatLevel(ThreatLevel.High, "osGetPrimitiveParams");
CheckThreatLevel();
InitLSL();
return m_LSL_Api.GetPrimitiveParamsEx(prim, rules);
@ -3788,7 +3826,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
public void osSetPrimitiveParams(LSL_Key prim, LSL_List rules)
{
CheckThreatLevel(ThreatLevel.High, "osSetPrimitiveParams");
CheckThreatLevel();
InitLSL();
m_LSL_Api.SetPrimitiveParamsEx(prim, rules, "osSetPrimitiveParams");
@ -3797,15 +3835,40 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
/// <summary>
/// Set parameters for light projection in host prim
/// </summary>
public void osSetProjectionParams(bool projection, LSL_Key texture, double fov, double focus, double amb)
public void osSetProjectionParams(LSL_Integer projection, LSL_Key texture, LSL_Float fov, LSL_Float focus, LSL_Float amb)
{
osSetProjectionParams(UUID.Zero.ToString(), projection, texture, fov, focus, amb);
SetProjectionParams(m_host, projection, texture, fov, focus, amb);
}
/// <summary>
/// Set parameters for light projection of a linkset prim
/// </summary>
public void osSetProjectionParams(LSL_Integer linknum, LSL_Integer projection, LSL_Key texture, LSL_Float fov, LSL_Float focus, LSL_Float amb)
{
if (linknum == ScriptBaseClass.LINK_THIS || linknum == m_host.LinkNum)
{
SetProjectionParams(m_host, projection, texture, fov, focus, amb);
return;
}
if (linknum < 0 || linknum > m_host.ParentGroup.PrimCount)
return;
if(linknum < 2 && m_host.LinkNum < 2)
{
SetProjectionParams(m_host, projection, texture, fov, focus, amb);
return;
}
SceneObjectPart obj = m_host.ParentGroup.GetLinkNumPart(linknum);
if(obj != null)
SetProjectionParams(obj, projection, texture, fov, focus, amb);
}
/// <summary>
/// Set parameters for light projection with uuid of target prim
/// </summary>
public void osSetProjectionParams(LSL_Key prim, bool projection, LSL_Key texture, double fov, double focus, double amb)
public void osSetProjectionParams(LSL_Key prim, LSL_Integer llprojection, LSL_Key texture, LSL_Float fov, LSL_Float focus, LSL_Float amb)
{
CheckThreatLevel(ThreatLevel.High, "osSetProjectionParams");
@ -3820,7 +3883,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (obj == null)
return;
}
SetProjectionParams(obj, llprojection, texture, fov, focus, amb);
}
private void SetProjectionParams(SceneObjectPart obj, LSL_Integer llprojection, LSL_Key texture, LSL_Float fov, LSL_Float focus, LSL_Float amb)
{
bool projection = llprojection != 0;
obj.Shape.ProjectionEntry = projection;
obj.Shape.ProjectionTextureUUID = new UUID(texture);
obj.Shape.ProjectionFOV = (float)fov;
@ -5441,5 +5509,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return String.Empty;
return detectedParams.Key.ToString();
}
// returns PST or PDT wall clock
public LSL_Float osGetPSTWallclock()
{
m_host.AddScriptLPS(1);
if(PSTTimeZone == null)
return DateTime.Now.TimeOfDay.TotalSeconds;
DateTime time = TimeZoneInfo.ConvertTime(DateTime.UtcNow, PSTTimeZone);
return time.TimeOfDay.TotalSeconds;
}
}
}

View File

@ -150,6 +150,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
string osGetAgentIP(string agent);
// Teleport commands
void osLocalTeleportAgent(LSL_Key agent, LSL_Types.Vector3 position, LSL_Types.Vector3 velocity, LSL_Types.Vector3 lookat, LSL_Integer flags);
void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
void osTeleportAgent(string agent, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
@ -393,8 +394,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
void osForceOtherSit(string avatar, string target);
LSL_List osGetPrimitiveParams(LSL_Key prim, LSL_List rules);
void osSetPrimitiveParams(LSL_Key prim, LSL_List rules);
void osSetProjectionParams(bool projection, LSL_Key texture, double fov, double focus, double amb);
void osSetProjectionParams(LSL_Key prim, bool projection, LSL_Key texture, double fov, double focus, double amb);
void osSetProjectionParams(LSL_Integer projection, LSL_Key texture, LSL_Float fov, LSL_Float focus, LSL_Float amb);
void osSetProjectionParams(LSL_Key prim, LSL_Integer projection, LSL_Key texture, LSL_Float fov, LSL_Float focus, LSL_Float amb);
void osSetProjectionParams(LSL_Integer linknumber, LSL_Integer projection, LSL_Key texture, LSL_Float fov, LSL_Float focus, LSL_Float amb);
LSL_List osGetAvatarList();
LSL_List osGetNPCList();
@ -549,5 +551,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
LSL_String osGetInventoryName(LSL_Key itemId);
LSL_String osGetInventoryDesc(LSL_String itemNameOrId);
LSL_Key osGetLastChangedEventKey();
LSL_Float osGetPSTWallclock();
}
}

View File

@ -35,7 +35,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
public partial class ScriptBaseClass
{
// SCRIPTS CONSTANTS
public static readonly LSLInteger OS_APIVERSION = 3;
public static readonly LSLInteger OS_APIVERSION = 4;
public static readonly LSLInteger TRUE = 1;
public static readonly LSLInteger FALSE = 0;
@ -189,6 +189,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
public const int VEHICLE_RANGE_BLOCK = 45;
public const int VEHICLE_ROLL_FRAME = 46;
public const int VEHICLE_FLAG_NO_DEFLECTION_UP = 1;
public const int VEHICLE_FLAG_NO_FLY_UP = 1; //legacy
public const int VEHICLE_FLAG_LIMIT_ROLL_ONLY = 2;
public const int VEHICLE_FLAG_HOVER_WATER_ONLY = 4;
public const int VEHICLE_FLAG_HOVER_TERRAIN_ONLY = 8;
@ -898,6 +899,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
//ApiDesc osTeleportObject flag: the rotation is the final rotation, otherwise is a added rotation
public const int OSTPOBJ_SETROT = 0x4;
//ApiDesc osLocalTeleportAgent no flags
public const int OS_LTPAG_NONE = 0x0;
//ApiDesc osLocalTeleportAgent use velocity
public const int OS_LTPAG_USEVEL = 0x1;
//ApiDesc osLocalTeleportAgent use lookat
public const int OS_LTPAG_USELOOKAT = 0x2;
//ApiDesc osLocalTeleportAgent align lookat to velocity
public const int OS_LTPAG_ALGNLV = 0x4;
//ApiDesc osLocalTeleportAgent force fly
public const int OS_LTPAG_FORCEFLY = 0x8;
//ApiDesc osLocalTeleportAgent force no fly
public const int OS_LTPAG_FORCENOFLY = 0x16;
// Constants for Windlight
public const int WL_WATER_COLOR = 0;
public const int WL_WATER_FOG_DENSITY_EXPONENT = 1;

View File

@ -247,6 +247,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
// Teleport Functions
public void osLocalTeleportAgent(LSL_Key agent, vector position, vector velocity, vector lookat, LSL_Integer flags)
{
m_OSSL_Functions.osLocalTeleportAgent(agent, position, velocity, lookat, flags);
}
public void osTeleportAgent(string agent, string regionName, vector position, vector lookat)
{
m_OSSL_Functions.osTeleportAgent(agent, regionName, position, lookat);
@ -1035,16 +1040,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
m_OSSL_Functions.osSetPrimitiveParams(prim, rules);
}
public void osSetProjectionParams(bool projection, LSL_Key texture, double fov, double focus, double amb)
public void osSetProjectionParams(LSL_Integer projection, LSL_Key texture, double fov, double focus, double amb)
{
m_OSSL_Functions.osSetProjectionParams(projection, texture, fov, focus, amb);
}
public void osSetProjectionParams(LSL_Key prim, bool projection, LSL_Key texture, double fov, double focus, double amb)
public void osSetProjectionParams(LSL_Key prim, LSL_Integer projection, LSL_Key texture, double fov, double focus, double amb)
{
m_OSSL_Functions.osSetProjectionParams(prim, projection, texture, fov, focus, amb);
}
public void osSetProjectionParams(LSL_Integer linknumber, LSL_Integer projection, LSL_Key texture, LSL_Float fov, LSL_Float focus, LSL_Float amb)
{
m_OSSL_Functions.osSetProjectionParams(linknumber, projection, texture, fov, focus, amb);
}
public LSL_List osGetAvatarList()
{
return m_OSSL_Functions.osGetAvatarList();
@ -1381,5 +1391,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
{
return m_OSSL_Functions.osGetLastChangedEventKey();
}
public LSL_Float osGetPSTWallclock()
{
return m_OSSL_Functions.osGetPSTWallclock();
}
}
}

View File

@ -69,7 +69,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
public static readonly string OBJECT_CODE_MAGIC = "YObjectCode";
// reserve positive version values for original xmr
public static int COMPILED_VERSION_VALUE = -1; // decremented when compiler or object file changes
public static int COMPILED_VERSION_VALUE = -2; // decremented when compiler or object file changes
public static readonly int CALL_FRAME_MEMUSE = 64;
public static readonly int STRING_LEN_TO_MEMUSE = 2;
@ -197,7 +197,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
public CallLabel openCallLabel = null; // only one call label can be open at a time
// - the call label is open from the time of CallPre() until corresponding CallPost()
// - so no non-trivial pushes/pops etc allowed between a CallPre() and a CallPost()
public List<ScriptMyLocal> HeapLocals = new List<ScriptMyLocal>();
private ScriptMyILGen _ilGen;
public ScriptMyILGen ilGen
{
@ -1258,6 +1258,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
// resume at the correct spot.
actCallLabels.Clear();
allCallLabels.Clear();
HeapLocals.Clear();
openCallLabel = null;
// Alloc stack space for local vars.
@ -1398,19 +1399,17 @@ namespace OpenSim.Region.ScriptEngine.Yengine
_ilGen = collector.WriteOutAll();
collector = null;
// Output code to restore stack frame from stream.
// It jumps back to the call labels within the function body.
List<ScriptMyLocal> activeTemps = null;
if(!isTrivial)
if (!isTrivial)
{
// Build list of locals and temps active at all the call labels.
// Build list of locals and temps active at all the call labels.
activeTemps = new List<ScriptMyLocal>();
foreach(CallLabel cl in allCallLabels)
{
foreach(ScriptMyLocal lcl in cl.callLabel.whereAmI.localsReadBeforeWritten)
foreach (CallLabel cl in allCallLabels)
{
if(!activeTemps.Contains(lcl))
foreach(ScriptMyLocal lcl in cl.callLabel.whereAmI.localsReadBeforeWritten)
{
if(!activeTemps.Contains(lcl))
{
activeTemps.Add(lcl);
}
}
@ -1452,11 +1451,34 @@ namespace OpenSim.Region.ScriptEngine.Yengine
}
// Output the 'real' return opcode.
// push return value
ilGen.MarkLabel(retLabel);
if(!(curDeclFunc.retType is TokenTypeVoid))
if (!(curDeclFunc.retType is TokenTypeVoid))
{
ilGen.Emit(curDeclFunc, OpCodes.Ldloc, retValue);
}
// pseudo free memory usage
foreach (ScriptMyLocal sml in HeapLocals)
{
Type t = sml.type;
if (t == typeof(HeapTrackerList))
{
ilGen.Emit(curDeclFunc, OpCodes.Ldloc, sml);
HeapTrackerList.GenFree(curDeclFunc, ilGen);
}
else if (t == typeof(HeapTrackerString))
{
ilGen.Emit(curDeclFunc, OpCodes.Ldloc, sml);
HeapTrackerString.GenFree(curDeclFunc, ilGen);
}
else if (t == typeof(HeapTrackerObject))
{
ilGen.Emit(curDeclFunc, OpCodes.Ldloc, sml);
HeapTrackerObject.GenFree(curDeclFunc, ilGen);
}
}
ilGen.Emit(curDeclFunc, OpCodes.Ret);
retLabel = null;
retValue = null;
@ -1675,11 +1697,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine
if(u != t)
{
if(t == typeof(HeapTrackerList))
HeapTrackerList.GenPop(curDeclFunc, ilGen);
HeapTrackerList.GenRestore(curDeclFunc, ilGen);
if(t == typeof(HeapTrackerObject))
HeapTrackerObject.GenPop(curDeclFunc, ilGen);
HeapTrackerObject.GenRestore(curDeclFunc, ilGen);
if(t == typeof(HeapTrackerString))
HeapTrackerString.GenPop(curDeclFunc, ilGen);
HeapTrackerString.GenRestore(curDeclFunc, ilGen);
}
else
{

View File

@ -2611,10 +2611,10 @@ namespace OpenSim.Region.ScriptEngine.Yengine
// everything required by any blocks it can branch to.
do
{
this.resolvedSomething = false;
this.resolveSequence++;
this.ResolveBlock((GraphNodeBlock)firstLin);
} while(this.resolvedSomething);
resolvedSomething = false;
resolveSequence++;
ResolveBlock((GraphNodeBlock)firstLin);
} while(resolvedSomething);
// Repeat the cutting loops as long as we keep finding stuff.
bool didSomething;
@ -2939,7 +2939,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
return;
// So we don't recurse forever on a backward branch.
currentBlock.hasBeenResolved = this.resolveSequence;
currentBlock.hasBeenResolved = resolveSequence;
// Assume we haven't written any locals yet.
List<ScriptMyLocal> localsWrittenSoFar = new List<ScriptMyLocal>();
@ -2975,7 +2975,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
!currentBlock.localsReadBeforeWritten.Contains(readByNextBlock))
{
currentBlock.localsReadBeforeWritten.Add(readByNextBlock);
this.resolvedSomething = true;
resolvedSomething = true;
}
}
}

View File

@ -1483,7 +1483,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
{
if(type.ToHeapTrackerType() != null)
{
this.localBuilder = scg.ilGen.DeclareLocal(type.ToHeapTrackerType(), name);
localBuilder = scg.ilGen.DeclareLocal(type.ToHeapTrackerType(), name);
scg.HeapLocals.Add(localBuilder);
scg.PushXMRInst();
scg.ilGen.Emit(type, OpCodes.Newobj, type.GetHeapTrackerCtor());
scg.ilGen.Emit(type, OpCodes.Stloc, localBuilder);
@ -1547,6 +1548,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
scg.ilGen.Emit(errorAt, OpCodes.Ldloc, localBuilder);
scg.ilGen.Emit(errorAt, OpCodes.Ldloc, htpop);
type.CallHeapTrackerPopMeth(errorAt, scg.ilGen);
scg.HeapLocals.Add(htpop);
}
else
{

View File

@ -130,7 +130,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
// Since we just wrote the .xmrobj file, maybe save disassembly.
if (m_Engine.m_ScriptDebugSaveIL)
{
string asmFileName = GetScriptFileName (m_ScriptObjCodeKey + ".yasm");
string asmFileName = GetScriptILFileName(m_ScriptObjCodeKey + ".yasm");
// m_log.Debug ("[YEngine]: MMRScriptCompileSaveILGen: saving to " + asmFileName);
asmFileWriter = File.CreateText (asmFileName);
}

View File

@ -125,7 +125,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
// Save new value in array, replacing one of same key if there.
// null means remove the value, ie, script did array[key] = undef.
if(value != null)
if (value != null)
{
dnary[key] = value;
}
@ -285,10 +285,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
public void RecvArrayObj(RecvArrayObjDelegate recvObj)
{
heapUse = inst.UpdateHeapUse(heapUse, EMPTYHEAP);
// Cause any enumeration to refill the array from the sorted dictionary.
// Since it is a sorted dictionary, any enumerations will be in the same
// order as on the sending side.
// Cause any enumeration to refill the array from the sorted dictionary.
// Since it is a sorted dictionary, any enumerations will be in the same
// order as on the sending side.
arrayValid = 0;
enumrValid = false;

View File

@ -1535,15 +1535,38 @@ namespace OpenSim.Region.ScriptEngine.Yengine
*/
public void QueueToStart(XMRInstance inst)
{
if(inst.m_IState != XMRInstState.ONSTARTQ)
if (inst.m_IState != XMRInstState.ONSTARTQ)
throw new Exception("bad state");
lock(m_StartQueue)
lock (m_StartQueue)
m_StartQueue.InsertTail(inst);
WakeUpOne();
}
public void QueueToYield(XMRInstance inst)
{
if (inst.m_IState != XMRInstState.ONYIELDQ)
throw new Exception("bad state");
lock (m_YieldQueue)
m_YieldQueue.InsertTail(inst);
WakeUpOne();
}
public void RemoveFromSleep(XMRInstance inst)
{
lock (m_SleepQueue)
{
if (inst.m_IState != XMRInstState.ONSLEEPQ)
return;
m_SleepQueue.Remove(inst);
inst.m_IState = XMRInstState.REMDFROMSLPQ;
}
}
/**
* @brief A script may be sleeping, in which case we wake it.
*/

View File

@ -58,11 +58,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
if(inst == null)
throw new ArgumentNullException("inst");
instance = inst;
}
~HeapTrackerBase()
{
usage = instance.UpdateHeapUse(usage, 0);
usage = 0;
}
}
@ -73,24 +69,33 @@ namespace OpenSim.Region.ScriptEngine.Yengine
{
private static FieldInfo listValueField = typeof(HeapTrackerList).GetField("value");
private static MethodInfo listSaveMethod = typeof(HeapTrackerList).GetMethod("Save");
private static MethodInfo listRestoreMethod = typeof(HeapTrackerList).GetMethod("Restore");
private static MethodInfo listFreeMethod = typeof(HeapTrackerList).GetMethod("Free");
public LSL_List value;
public HeapTrackerList(XMRInstAbstract inst) : base(inst) { }
public HeapTrackerList(XMRInstAbstract inst) : base(inst) {}
// generate CIL code to pop the value from the CIL stack
// generate CIL code to pop the value ie store in value
// input:
// 'this' pointer already pushed on CIL stack
// new value pushed on CIL stack
// new value
// output:
// 'this' pointer popped from stack
// new value popped from CIL stack
// heap usage updated
public static void GenPop(Token errorAt, ScriptMyILGen ilGen)
{
ilGen.Emit(errorAt, OpCodes.Call, listSaveMethod);
}
public static void GenRestore(Token errorAt, ScriptMyILGen ilGen)
{
ilGen.Emit(errorAt, OpCodes.Call, listRestoreMethod);
}
public static void GenFree(Token errorAt, ScriptMyILGen ilGen)
{
ilGen.Emit(errorAt, OpCodes.Call, listFreeMethod);
}
// generate CIL code to push the value on the CIL stack
// input:
// 'this' pointer already pushed on CIL stack
@ -106,23 +111,32 @@ namespace OpenSim.Region.ScriptEngine.Yengine
public void Save(LSL_List lis)
{
int newuse = Size(lis);
usage = instance.UpdateHeapUse(usage, newuse);
if (lis == null)
usage = instance.UpdateHeapUse(usage, 0);
else
usage = instance.UpdateHeapUse(usage, Size(lis));
value = lis;
}
public void Restore(LSL_List lis)
{
value = lis;
if (lis != null)
usage = Size(lis);
else
usage = 0;
}
public void Free()
{
usage = instance.UpdateHeapUse(usage, 0);
value = null;
instance = null;
}
//private static int counter = 5;
public static int Size(LSL_List lis)
{
// VS2017 in debug mode seems to have a problem running this statement quickly:
//SLOW: return (!typeof(LSL_List).IsValueType && (lis == null)) ? 0 : lis.Size;
//FAST: return 33;
//SLOW: return (lis == null) ? 0 : 99;
//FAST: return ++ counter;
// VS2017 in debug mode seems content to run this quickly though:
try
{
return lis.Size;
@ -141,6 +155,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
{
private static FieldInfo objectValueField = typeof(HeapTrackerObject).GetField("value");
private static MethodInfo objectSaveMethod = typeof(HeapTrackerObject).GetMethod("Save");
private static MethodInfo objectRestoreMethod = typeof(HeapTrackerObject).GetMethod("Restore");
private static MethodInfo objectFreeMethod = typeof(HeapTrackerObject).GetMethod("Free");
public const int HT_CHAR = 2;
public const int HT_DELE = 8;
@ -168,6 +184,16 @@ namespace OpenSim.Region.ScriptEngine.Yengine
ilGen.Emit(errorAt, OpCodes.Call, objectSaveMethod);
}
public static void GenRestore(Token errorAt, ScriptMyILGen ilGen)
{
ilGen.Emit(errorAt, OpCodes.Call, objectRestoreMethod);
}
public static void GenFree(Token errorAt, ScriptMyILGen ilGen)
{
ilGen.Emit(errorAt, OpCodes.Call, objectFreeMethod);
}
// generate CIL code to push the value on the CIL stack
// input:
// 'this' pointer already pushed on CIL stack
@ -188,6 +214,19 @@ namespace OpenSim.Region.ScriptEngine.Yengine
value = obj;
}
public void Restore(object obj)
{
value = obj;
usage = Size(obj);
}
public void Free()
{
usage = instance.UpdateHeapUse(usage, 0);
value = null;
instance = null;
}
// public so it can be used by XMRArray
public static int Size(object obj)
{
@ -204,8 +243,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
return HT_SING;
if(obj is int)
return HT_INT;
if(obj is LSL_Float)
return HT_SFLT;
if(obj is LSL_Float) // lsl floats are stupid doubles
return HT_DOUB;
if(obj is LSL_Integer)
return HT_INT;
if(obj is LSL_List)
@ -252,7 +291,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
public class HeapTrackerString: HeapTrackerBase
{
private static FieldInfo stringValueField = typeof(HeapTrackerString).GetField("value");
private static MethodInfo stringRestoreMethod = typeof(HeapTrackerString).GetMethod("Restore");
private static MethodInfo stringSaveMethod = typeof(HeapTrackerString).GetMethod("Save");
private static MethodInfo stringFreeMethod = typeof(HeapTrackerString).GetMethod("Free");
public string value;
@ -271,6 +312,16 @@ namespace OpenSim.Region.ScriptEngine.Yengine
ilGen.Emit(errorAt, OpCodes.Call, stringSaveMethod);
}
public static void GenRestore(Token errorAt, ScriptMyILGen ilGen)
{
ilGen.Emit(errorAt, OpCodes.Call, stringRestoreMethod);
}
public static void GenFree(Token errorAt, ScriptMyILGen ilGen)
{
ilGen.Emit(errorAt, OpCodes.Call, stringFreeMethod);
}
// generate CIL code to push the value on the CIL stack
// input:
// 'this' pointer already pushed on CIL stack
@ -291,6 +342,19 @@ namespace OpenSim.Region.ScriptEngine.Yengine
value = str;
}
public void Restore(string str)
{
value = str;
usage = Size(str);
}
public void Free()
{
usage = instance.UpdateHeapUse(usage, 0);
value = null;
instance = null;
}
public static int Size(string str)
{
return (str == null) ? 0 : str.Length * HeapTrackerObject.HT_CHAR;

View File

@ -60,7 +60,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
public Delegate[][] iarSDTIntfObjs;
private XMRInstAbstract instance;
private int heapUse;
private int arraysHeapUse;
private static readonly XMR_Array[] noArrays = new XMR_Array[0];
private static readonly char[] noChars = new char[0];
@ -81,20 +81,49 @@ namespace OpenSim.Region.ScriptEngine.Yengine
~XMRInstArrays()
{
heapUse = instance.UpdateHeapUse(heapUse, 0);
arraysHeapUse = instance.UpdateHeapUse(arraysHeapUse, 0);
}
public void AllocVarArrays(XMRInstArSizes ars)
public void Clear()
{
int newheapUse = 0;
if(iarArrays != null)
{
foreach(XMR_Array xa in iarArrays)
xa.__pub_clear();
}
if(iarChars != null)
iarChars = new char[iarChars.Length];
if (iarLists != null)
iarLists = new LSL_List[iarLists.Length];
if (iarObjects != null)
iarObjects = new object[iarObjects.Length];
if(iarStrings != null)
iarStrings = new string[iarStrings.Length];
if (iarFloats != null)
newheapUse += iarFloats.Length * HeapTrackerObject.HT_DOUB;
if (iarIntegers != null)
newheapUse += iarIntegers.Length * HeapTrackerObject.HT_INT;
if (iarRotations != null)
newheapUse += iarRotations.Length * HeapTrackerObject.HT_ROT;
if (iarVectors != null)
newheapUse += iarVectors.Length * HeapTrackerObject.HT_VEC;
arraysHeapUse = instance.UpdateHeapUse(0, newheapUse);
}
public void AllocVarArrays(XMRInstArSizes ars)
{
ClearOldArrays();
int newuse = arraysHeapUse +
ars.iasChars* HeapTrackerObject.HT_CHAR +
ars.iasFloats * HeapTrackerObject.HT_SFLT +
ars.iasIntegers * HeapTrackerObject.HT_INT +
ars.iasRotations * HeapTrackerObject.HT_ROT +
ars.iasVectors * HeapTrackerObject.HT_VEC +
ars.iasSDTIntfObjs * HeapTrackerObject.HT_DELE;
heapUse = instance.UpdateHeapUse(heapUse,
ars.iasChars * HeapTrackerObject.HT_CHAR +
ars.iasFloats * HeapTrackerObject.HT_SFLT +
ars.iasIntegers * HeapTrackerObject.HT_INT +
ars.iasRotations * HeapTrackerObject.HT_ROT +
ars.iasVectors * HeapTrackerObject.HT_VEC +
ars.iasSDTIntfObjs * HeapTrackerObject.HT_DELE);
arraysHeapUse = instance.UpdateHeapUse(arraysHeapUse, newuse);
iarArrays = (ars.iasArrays > 0) ? new XMR_Array[ars.iasArrays] : noArrays;
iarChars = (ars.iasChars > 0) ? new char[ars.iasChars] : noChars;
@ -114,9 +143,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
*/
public void PopList(int index, LSL_List lis)
{
LSL_List old = iarLists[index];
int newheapuse = heapUse + HeapTrackerList.Size(lis) - HeapTrackerList.Size(old);
heapUse = instance.UpdateHeapUse(heapUse, newheapuse);
int delta = HeapTrackerObject.Size(lis) - HeapTrackerObject.Size(iarLists[index]);
instance.UpdateHeapUse(0, delta);
Interlocked.Add(ref arraysHeapUse, delta);
iarLists[index] = lis;
}
@ -125,9 +154,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
*/
public void PopObject(int index, object obj)
{
object old = iarObjects[index];
int newheapuse = heapUse + HeapTrackerObject.Size(obj) - HeapTrackerObject.Size(old);
heapUse = instance.UpdateHeapUse(heapUse, newheapuse);
int delta = HeapTrackerObject.Size(obj) - HeapTrackerObject.Size(iarObjects[index]);
instance.UpdateHeapUse(0, delta);
Interlocked.Add(ref arraysHeapUse, delta);
iarObjects[index] = obj;
}
@ -136,9 +165,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
*/
public void PopString(int index, string str)
{
string old = iarStrings[index];
int newheapuse = heapUse + HeapTrackerString.Size(str) - HeapTrackerString.Size(old);
heapUse = instance.UpdateHeapUse(heapUse, newheapuse);
int delta = HeapTrackerString.Size(str) - HeapTrackerString.Size(iarStrings[index]);
instance.UpdateHeapUse(0, delta);
Interlocked.Add(ref arraysHeapUse, delta);
iarStrings[index] = str;
}
@ -181,11 +210,11 @@ namespace OpenSim.Region.ScriptEngine.Yengine
iarSDTClObjs = (XMRSDTypeClObj[])recver();
Delegate[][] dels = (Delegate[][])recver();
int newheapuse = heapUse;
int newheapuse = arraysHeapUse;
// value types simply are the size of the value * number of values
newheapuse += chrs.Length * HeapTrackerObject.HT_CHAR;
newheapuse += flts.Length * HeapTrackerObject.HT_SFLT;
newheapuse += flts.Length * HeapTrackerObject.HT_DOUB;
newheapuse += ints.Length * HeapTrackerObject.HT_INT;
newheapuse += rots.Length * HeapTrackerObject.HT_ROT;
newheapuse += vecs.Length * HeapTrackerObject.HT_VEC;
@ -204,7 +233,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
// others (XMR_Array, XMRSDTypeClObj) keep track of their own heap usage
// update script heap usage, throwing an exception before finalizing changes
heapUse = instance.UpdateHeapUse(heapUse, newheapuse);
arraysHeapUse = instance.UpdateHeapUse(arraysHeapUse, newheapuse);
iarChars = chrs;
iarFloats = flts;
@ -219,7 +248,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
private void ClearOldArrays()
{
int newheapuse = heapUse;
int newheapuse = arraysHeapUse;
iarArrays = null;
if(iarChars != null)
@ -272,7 +301,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
iarSDTIntfObjs = null;
}
heapUse = instance.UpdateHeapUse(heapUse, newheapuse);
arraysHeapUse = instance.UpdateHeapUse(arraysHeapUse, newheapuse);
}
}
@ -424,31 +453,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
\**************************************************/
protected int heapLimit;
private int heapUsed;
protected int heapUsed;
public virtual int UpdateHeapUse(int olduse, int newuse)
{
if(newuse <= olduse)
Interlocked.Add(ref heapUsed, newuse - olduse);
else
{
int newtotal, oldtotal;
do
{
oldtotal = Interlocked.Add(ref heapUsed, 0);
newtotal = oldtotal + newuse - olduse;
if(newtotal > heapLimit)
{
// System.GC.Collect ();
// System.GC.WaitForPendingFinalizers ();
oldtotal = Interlocked.Add(ref heapUsed, 0);
newtotal = oldtotal + newuse - olduse;
if(newtotal > heapLimit)
throw new OutOfHeapException(oldtotal, newtotal, heapLimit);
}
} while(Interlocked.CompareExchange(ref heapUsed, newtotal, oldtotal) != oldtotal);
}
int newtotal = Interlocked.Add(ref heapUsed, newuse - olduse);
if(newtotal > heapLimit)
throw new OutOfHeapException(newtotal + olduse - newuse, newtotal, heapLimit);
return newuse;
}

View File

@ -218,7 +218,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
// do not do llResetScript on entry
if(eventCode == ScriptEventCode.state_entry && stateCode == 0)
return;
ClearQueueExceptLinkMessages();
// do clear the events queue on reset
ClearQueue();
//ClearQueueExceptLinkMessages();
throw new ScriptResetException();
}
@ -583,6 +585,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
* Tell outer layers to cancel any event triggers, like llListen(),
* then tell outer layers which events the new state has handlers for.
* We also clear the event queue as per http://wiki.secondlife.com/wiki/State
* old scripts may want linked messages, but that is not as SL does now
*/
public override void StateChange()
{
@ -595,7 +598,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
// Tell whoever cares which event handlers the new state has.
m_Part.SetScriptEvents(m_ItemID, GetStateEventFlags(stateCode));
// Clear out any old events from the queue.
// keep link messages
//ClearQueueExceptLinkMessages();
// or Clear out all old events from the queue.
lock(m_QueueLock)
{
m_EventQueue.Clear();

View File

@ -236,6 +236,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
return GetScriptFileName(m_ScriptBasePath, filename);
}
public string GetScriptILFileName(string filename)
{
string path = Path.Combine(m_ScriptBasePath, "DebugIL");
Directory.CreateDirectory(path);
return Path.Combine(path, filename);
}
public static string GetScriptFileName(string scriptBasePath, string filename)
{
// Get old path, ie, all files lumped in a single huge directory.
@ -363,8 +370,33 @@ namespace OpenSim.Region.ScriptEngine.Yengine
lock(m_QueueLock)
{
m_Running = value;
if(!value)
if(value)
{
if (m_IState == XMRInstState.SUSPENDED && m_SuspendCount == 0)
{
if(eventCode != ScriptEventCode.None)
{
m_IState = XMRInstState.ONYIELDQ;
m_Engine.QueueToYield(this);
}
else if ((m_EventQueue != null) && (m_EventQueue.First != null))
{
m_IState = XMRInstState.ONSTARTQ;
m_Engine.QueueToStart(this);
}
else
m_IState = XMRInstState.IDLE;
}
else if(m_SuspendCount != 0)
m_IState = XMRInstState.IDLE;
}
else
{
if(m_IState == XMRInstState.ONSLEEPQ)
{
m_Engine.RemoveFromSleep(this);
m_IState = XMRInstState.SUSPENDED;
}
EmptyEventQueues();
}
}

View File

@ -80,10 +80,21 @@ namespace OpenSim.Region.ScriptEngine.Yengine
!m_HaveEventHandlers[(int)evc]) // don't bother if we don't have such a handler in any state
return;
// Not running means we ignore any incoming events.
// But queue if still constructing because m_Running is not yet valid.
// Not running means we ignore any incoming events.
// But queue if still constructing because m_Running is not yet valid.
if(!m_Running && !construct)
{
if(m_IState == XMRInstState.SUSPENDED)
{
if(evc == ScriptEventCode.state_entry && m_EventQueue.Count == 0)
{
LinkedListNode<EventParams> llns = new LinkedListNode<EventParams>(evt);
m_EventQueue.AddFirst(llns);
}
}
return;
}
if(m_minEventDelay != 0)
{
@ -250,13 +261,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
return XMRInstState.SUSPENDED;
}
// Make sure we aren't being migrated in or out and prevent that
// whilst we are in here. If migration has it locked, don't call
// back right away, delay a bit so we don't get in infinite loop.
// Make sure we aren't being migrated in or out and prevent that
// whilst we are in here. If migration has it locked, don't call
// back right away, delay a bit so we don't get in infinite loop.
m_RunOnePhase = "lock m_RunLock";
if(!Monitor.TryEnter(m_RunLock))
{
m_SleepUntil = now.AddMilliseconds(3);
m_SleepUntil = now.AddMilliseconds(15);
m_RunOnePhase = "return was locked";
return XMRInstState.ONSLEEPQ;
}
@ -273,6 +284,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine
return XMRInstState.DISPOSED;
}
if(!m_Running)
{
m_RunOnePhase = "return is not running";
return XMRInstState.SUSPENDED;
}
// Do some more of the last event if it didn't finish.
if(this.eventCode != ScriptEventCode.None)
{
@ -325,10 +342,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
if(m_EventQueue.First != null)
{
evt = m_EventQueue.First.Value;
if(m_DetachQuantum > 0)
evc = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode), evt.EventName);
if (m_DetachQuantum > 0)
{
evc = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode),
evt.EventName);
if(evc != ScriptEventCode.attach)
{
// This is the case where the attach event
@ -343,8 +359,6 @@ namespace OpenSim.Region.ScriptEngine.Yengine
}
}
m_EventQueue.RemoveFirst();
evc = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode),
evt.EventName);
if((int)evc >= 0)
m_EventCounts[(int)evc]--;
}
@ -730,11 +744,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
case XMRInstState.DISPOSED:
return;
// Some other thread is already resetting it, let it finish.
// Some other thread is already resetting it, let it finish.
case XMRInstState.RESETTING:
return;
case XMRInstState.SUSPENDED:
break;
default:
throw new Exception("bad state");
}
@ -744,17 +761,21 @@ namespace OpenSim.Region.ScriptEngine.Yengine
{
CheckRunLockInvariants(true);
// No other thread should have transitioned it from RESETTING.
if(m_IState != XMRInstState.RESETTING)
throw new Exception("bad state");
// No other thread should have transitioned it from RESETTING.
if (m_IState != XMRInstState.SUSPENDED)
{
if (m_IState != XMRInstState.RESETTING)
throw new Exception("bad state");
// Mark it idle now so it can get queued to process new stuff.
m_IState = XMRInstState.IDLE;
m_IState = XMRInstState.IDLE;
}
// Reset everything and queue up default's start_entry() event.
// Reset everything and queue up default's start_entry() event.
ClearQueue();
ResetLocked("external Reset");
// Mark it idle now so it can get queued to process new stuff.
CheckRunLockInvariants(true);
}
}
@ -820,6 +841,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
m_SleepUntil = DateTime.MinValue; // not doing llSleep()
m_ResetCount++; // has been reset once more
heapUsed = 0;
glblVars.Clear();
// Tell next call to 'default state_entry()' to reset all global
// vars to their initial values.
doGblInit = true;
@ -827,7 +851,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
// Throw away all its stack frames.
// If the script is resetting itself, there shouldn't be any stack frames.
// If the script is being reset by something else, we throw them away cuz we want to start from the beginning of an event handler.
stackFrames = null;
stackFrames = null;
// Set script to 'default' state and queue call to its
// 'state_entry()' event handler.
@ -937,7 +961,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
lock(m_QueueLock)
{
m_Suspended = false;
if((m_EventQueue != null) &&
m_DetachQuantum = 0;
m_DetachReady.Set();
if ((m_EventQueue != null) &&
(m_EventQueue.First != null) &&
(m_IState == XMRInstState.IDLE))
{

View File

@ -166,7 +166,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
if(inst == null)
break;
if(inst.m_IState != XMRInstState.ONSTARTQ)
if (inst.m_IState == XMRInstState.SUSPENDED)
continue;
if (inst.m_IState != XMRInstState.ONSTARTQ)
throw new Exception("bad state");
RunInstance(inst, tid);
if(m_SuspendScriptThreadFlag || m_Exiting)
@ -187,7 +189,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
if(inst != null)
{
if(inst.m_IState != XMRInstState.ONYIELDQ)
if (inst.m_IState == XMRInstState.SUSPENDED)
continue;
if (inst.m_IState != XMRInstState.ONYIELDQ)
throw new Exception("bad state");
RunInstance(inst, tid);
continue;

View File

@ -250,6 +250,8 @@ namespace OpenSim.Server.Base
}
}
MainServer.Stop();
MemoryWatchdog.Enabled = false;
Watchdog.Enabled = false;
WorkManager.Stop();

View File

@ -510,7 +510,7 @@ namespace OpenSim.Services.Connectors
try
{
newID = SynchronousRestObjectRequester.
MakeRequest<AssetBase, string>("POST", uri, asset, 100000, m_Auth);
MakeRequest<AssetBase, string>("POST", uri, asset, 10000, m_Auth);
}
catch
{

View File

@ -99,15 +99,8 @@ namespace OpenSim.Services.Connectors.Simulation
}
public bool CreateAgent(GridRegion source, GridRegion destination, AgentCircuitData aCircuit, uint flags, EntityTransferContext ctx, out string reason)
{
string tmp = String.Empty;
return CreateAgent(source, destination, aCircuit, flags, ctx, out tmp, out reason);
}
public bool CreateAgent(GridRegion source, GridRegion destination, AgentCircuitData aCircuit, uint flags, EntityTransferContext ctx, out string myipaddress, out string reason)
{
reason = String.Empty;
myipaddress = String.Empty;
if (destination == null)
{
@ -134,7 +127,6 @@ namespace OpenSim.Services.Connectors.Simulation
reason = data["reason"].AsString();
success = data["success"].AsBoolean();
myipaddress = data["your_ip"].AsString();
return success;
}
@ -149,7 +141,6 @@ namespace OpenSim.Services.Connectors.Simulation
reason = data["reason"].AsString();
success = data["success"].AsBoolean();
myipaddress = data["your_ip"].AsString();
m_log.WarnFormat(
"[REMOTE SIMULATION CONNECTOR]: Remote simulator {0} did not accept compressed transfer, suggest updating it.", destination.RegionName);
return success;

View File

@ -73,6 +73,7 @@ namespace OpenSim.Services.HypergridService
protected static FriendsSimConnector m_FriendsSimConnector; // grid
protected static string m_GridName;
protected static string m_MyExternalIP = "";
protected static int m_LevelOutsideContacts;
protected static bool m_ShowDetails;
@ -147,9 +148,20 @@ namespace OpenSim.Services.HypergridService
}
}
if (!m_GridName.EndsWith("/"))
m_GridName = m_GridName + "/";
if (!string.IsNullOrEmpty(m_GridName))
{
m_GridName = m_GridName.ToLowerInvariant();
if (!m_GridName.EndsWith("/"))
m_GridName = m_GridName + "/";
Uri gateURI;
if(!Uri.TryCreate(m_GridName, UriKind.Absolute, out gateURI))
throw new Exception(String.Format("[UserAgentService] could not parse gatekeeper uri"));
string host = gateURI.DnsSafeHost;
IPAddress ip = Util.GetHostFromDNS(host);
if(ip == null)
throw new Exception(String.Format("[UserAgentService] failed to resolve gatekeeper host"));
m_MyExternalIP = ip.ToString();
}
// Finally some cleanup
m_Database.DeleteOld();
@ -189,7 +201,6 @@ namespace OpenSim.Services.HypergridService
}
}
public GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt)
{
position = new Vector3(128, 128, 0); lookAt = Vector3.UnitY;
@ -222,7 +233,7 @@ namespace OpenSim.Services.HypergridService
m_log.DebugFormat("[USER AGENT SERVICE]: Request to login user {0} {1} (@{2}) to grid {3}",
agentCircuit.firstname, agentCircuit.lastname, (fromLogin ? agentCircuit.IPAddress : "stored IP"), gatekeeper.ServerURI);
string gridName = gatekeeper.ServerURI;
string gridName = gatekeeper.ServerURI.ToLowerInvariant();
UserAccount account = m_UserAccountService.GetUserAccount(UUID.Zero, agentCircuit.AgentID);
if (account == null)
@ -269,8 +280,13 @@ namespace OpenSim.Services.HypergridService
TravelingAgentInfo old = null;
TravelingAgentInfo travel = CreateTravelInfo(agentCircuit, region, fromLogin, out old);
if(!fromLogin && old != null && !string.IsNullOrEmpty(old.ClientIPAddress))
{
m_log.DebugFormat("[USER AGENT SERVICE]: stored IP = {0}. Old circuit IP: {1}", old.ClientIPAddress, agentCircuit.IPAddress);
agentCircuit.IPAddress = old.ClientIPAddress;
}
bool success = false;
string myExternalIP = string.Empty;
m_log.DebugFormat("[USER AGENT SERVICE]: this grid: {0}, desired grid: {1}, desired region: {2}", m_GridName, gridName, region.RegionID);
@ -282,7 +298,7 @@ namespace OpenSim.Services.HypergridService
{
//TODO: Should there not be a call to QueryAccess here?
EntityTransferContext ctx = new EntityTransferContext();
success = m_GatekeeperConnector.CreateAgent(source, region, agentCircuit, (uint)Constants.TeleportFlags.ViaLogin, ctx, out myExternalIP, out reason);
success = m_GatekeeperConnector.CreateAgent(source, region, agentCircuit, (uint)Constants.TeleportFlags.ViaLogin, ctx, out reason);
}
if (!success)
@ -300,14 +316,6 @@ namespace OpenSim.Services.HypergridService
// Everything is ok
if (!fromLogin)
{
// Update the perceived IP Address of our grid
m_log.DebugFormat("[USER AGENT SERVICE]: Gatekeeper sees me as {0}", myExternalIP);
}
travel.MyIpAddress = myExternalIP;
StoreTravelInfo(travel);
return true;
@ -384,10 +392,12 @@ namespace OpenSim.Services.HypergridService
TravelingAgentInfo travel = new TravelingAgentInfo(hgt);
bool result = travel.ClientIPAddress == reportedIP || travel.MyIpAddress == reportedIP; // NATed
bool result = travel.ClientIPAddress == reportedIP;
if(!result && !string.IsNullOrEmpty(m_MyExternalIP))
result = reportedIP == m_MyExternalIP; // NATed
m_log.DebugFormat("[USER AGENT SERVICE]: Comparing {0} with login IP {1} and MyIP {1}; result is {3}",
reportedIP, travel.ClientIPAddress, travel.MyIpAddress, result);
m_log.DebugFormat("[USER AGENT SERVICE]: Comparing {0} with login IP {1} and MyIP {2}; result is {3}",
reportedIP, travel.ClientIPAddress, m_MyExternalIP, result);
return result;
}
@ -704,7 +714,6 @@ namespace OpenSim.Services.HypergridService
hgt.Data["GridExternalName"] = travel.GridExternalName;
hgt.Data["ServiceToken"] = travel.ServiceToken;
hgt.Data["ClientIPAddress"] = travel.ClientIPAddress;
hgt.Data["MyIPAddress"] = travel.MyIpAddress;
m_Database.Store(hgt);
}
@ -719,7 +728,6 @@ namespace OpenSim.Services.HypergridService
public string GridExternalName = string.Empty;
public string ServiceToken = string.Empty;
public string ClientIPAddress = string.Empty; // as seen from this user agent service
public string MyIpAddress = string.Empty; // the user agent service's external IP, as seen from the next gatekeeper
public TravelingAgentInfo(HGTravelingData t)
{
@ -730,7 +738,6 @@ namespace OpenSim.Services.HypergridService
GridExternalName = t.Data["GridExternalName"];
ServiceToken = t.Data["ServiceToken"];
ClientIPAddress = t.Data["ClientIPAddress"];
MyIpAddress = t.Data["MyIPAddress"];
}
}
@ -743,7 +750,6 @@ namespace OpenSim.Services.HypergridService
GridExternalName = old.GridExternalName;
ServiceToken = old.ServiceToken;
ClientIPAddress = old.ClientIPAddress;
MyIpAddress = old.MyIpAddress;
}
}
}

View File

@ -369,6 +369,8 @@ namespace OpenSim.Tests.Common
set { }
}
public float StartFar { get; set; }
public virtual UUID AgentId
{
get { return m_agentId; }
@ -576,10 +578,6 @@ namespace OpenSim.Tests.Common
{
}
public virtual void SendStartPingCheck(byte seq)
{
}
public virtual void SendAvatarPickerReply(AvatarPickerReplyAgentDataArgs AgentData, List<AvatarPickerReplyDataArgs> Data)
{
}
@ -821,7 +819,8 @@ namespace OpenSim.Tests.Common
{
}
public virtual void SendXferPacket(ulong xferID, uint packet, byte[] data, bool isTaskInventory)
public virtual void SendXferPacket(ulong xferID, uint packet,
byte[] XferData, int XferDataOffset, int XferDatapktLen, bool isTaskInventory)
{
}
@ -880,7 +879,7 @@ namespace OpenSim.Tests.Common
{
}
public virtual void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args)
public virtual void SendRegionHandshake()
{
if (OnRegionHandShakeReply != null)
{
@ -1402,7 +1401,10 @@ namespace OpenSim.Tests.Common
{
}
public void CheckViewerCaps() { }
public uint GetViewerCaps()
{
return 0x1000;
}
}
}

View File

@ -119,6 +119,6 @@ namespace OpenSim.Tests.Common
public void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id) {}
public void Subdivide(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id) {}
public void sendClientInitialLandInfo(IClientAPI remoteClient) { }
public void sendClientInitialLandInfo(IClientAPI remoteClient, bool overlay) { }
}
}

View File

@ -927,14 +927,10 @@
[YEngine]
;; experimental engine
;; ONLY SUPORTS ONE REGION PER INSTANCE at this point
;; implements non preemptive microthreading, so fixing problems like llSleep or long events handlers
;; but those will suffer from timeslicing, so will be slower.
;; compiles LSL directly to IL, so only suports LSL scripting (no C# etc)
;; shares the Xengine APIs like LSL, OSSL, etc.
;; DANGER, do not use with HG, don't leave regions running alone with it.
;; TPs or crossings to/from Xengine will full recompile scripts losing state.
;; attachment scripts may misbehave, cars will stop on crossings, etc.
;; warning: scripts state is lost on TP or cross to Xengine regions (cars stop, etc)
;; ignore its extensions (subset of original XMRengine), those are still undefined.
Enabled = false
ScriptStackSize = 256
ScriptHeapSize = 256

View File

@ -164,15 +164,10 @@
; limit the maximum view range ( no effect still (does limit MaxRegionsViewDistance) )
;MaxDrawDistance = 512
; the maximum distance to tell a viewer to connect to a neighbour region, so it can be seen
; (it is limited by MaxDrawDistance above)
; less than 256 shows immediate neighbours; 256 to 511 also second imediate neighbours etc
; more than 511m can cause viewers problems specially in case of dense regions.
; curretly this distance is from current region borders.
; Warning: if relevant regions have different setting you may notice strange
; effects due to that asymmetry
; *****
; Other regions visibility depends on avatar position and view range
; the view range considered is limited the maximum and minimum distances:
;MaxRegionsViewDistance = 255
;MinRegionsViewDistance = 96
; If you have only one region in an instance, or to avoid the many bugs
; that you can trigger in modules by restarting a region, set this to
@ -454,7 +449,7 @@
; warp3D rendering height limits for prims (relative to rez position not bounding box)
; prims above RenderMaxHeight are excluded
; valid values: 100 t0 4086
; valid values: 100 to 4086
;RenderMaxHeight = 4086
; prims below RenderMinHeight are excluded
@ -690,23 +685,6 @@
[ClientStack.LindenUDP]
; The client socket receive buffer size determines how many
; incoming requests we can process; the default on .NET is 8192
; which is about 2 4k-sized UDP datagrams. On mono this is
; whatever the underlying operating system has as default; for
; example, ubuntu 8.04 or SLES11 have about 111k, which is about
; 27 4k-sized UDP datagrams (on linux platforms you can [as root]
; do "sysctl net.core.rmem_default" to find out what your system
; uses a default socket receive buffer size.
;
; client_socket_rcvbuf_size allows you to specify the receive
; buffer size LLUDPServer should use. NOTE: this will be limited
; by the system's settings for the maximum client receive buffer
; size (on linux systems you can set that with "sysctl -w
; net.core.rmem_max=X")
;
;client_socket_rcvbuf_size = 8388608
; Maximum outbound bytes per second for a single scene. This can be used to
; throttle total outbound UDP traffic for a simulator. The default value is
; 0, meaning no throttling at the scene level. The example given here is
@ -731,8 +709,8 @@
; Adaptive throttling attempts to limit network overload when multiple
; clients login by starting each connection more slowly. Disabled by
; default
;
enable_adaptive_throttles = false
; currently disabled
;enable_adaptive_throttles = false
; Per-client bytes per second rates for the various throttle categories.
; These are default values that will be overridden by clients. These
@ -748,7 +726,7 @@
;asset_default = 10500
; TextureSendLimit determines how many packets will be put on
; the outgoing queue each cycle. Like the settings above, this
; the lludp outgoing queue each cycle. Like the settings above, this
; is a balance between responsiveness to priority updates and
; total throughput. Higher numbers will give a better
; throughput at the cost of reduced responsiveness to client
@ -776,6 +754,11 @@
;
;PausedAckTimeout = 300
; Support viewers object cache, default true
; users may need to reduce viewer bandwitdh if some prims or terrain parts fail to rez.
; change to false if you need to use old viewers that do not support this feature
;
; SupportViewerObjectsCache = true
[ClientStack.LindenCaps]
;; Long list of capabilities taken from
@ -1729,17 +1712,12 @@
[Economy]
; the economy module in use
; default is the provided BetaGridLikeMoneyModule
; - This module is for demonstration only -
; The default economy module only implements just enough to allow free actions (transfer of objects, etc).
; There is no intention to implement anything further in core OpenSimulator.
; This functionality has to be provided by third party modules.
; To use other modules you need to override this setting on OpenSim.ini Economy (or startup) section
; economymodule = BetaGridLikeMoneyModule
; These economy values get used in the BetaGridLikeMoneyModule. - This module is for demonstration only -
; The default economy module only implements just enough to allow free actions (transfer of objects, etc).
; There is no intention to implement anything further in core OpenSimulator.
; This functionality has to be provided by third party modules.
; Economy values get used in the BetaGridLikeMoneyModule.
;; Enables selling things for $0. Default is true.
; SellEnabled = true
@ -1767,6 +1745,14 @@
;PriceObjectRent = 0
;PriceObjectScaleFactor = 10
;PriceParcelRent = 0
; Mesh upload settings, independent of economymodule
; Create inventory entries for textures uploaded with a model
; default is false, ie, do not create
; MeshModelAllowTextureToInventory = true
[XEngine]
; Enable this engine in this OpenSim instance

View File

@ -568,6 +568,8 @@
;;
;; To turn off basic dos protection, set the DOSMaxRequestsInTimeFrame to 0.
;; Allow banning via hashed MAC must be set in both [GatekeeperService] and [LoginService]
;DeniedMacs = "YOURLONGMACTRSING ANOTHERMAC"
[MapImageService]
LocalServiceModule = "OpenSim.Services.MapImageService.dll:MapImageService"
@ -663,6 +665,8 @@
;; Leave blank or commented for no exceptions.
; DisallowExcept = "http://myfriendgrid.com:8002, http://myboss.com:8002"
;; Allow banning via hashed MAC must be set in both [GatekeeperService] and [LoginService]
;DeniedMacs = "YOURLONGMACTRSING ANOTHERMAC"
[UserAgentService]
LocalServiceModule = "OpenSim.Services.HypergridService.dll:UserAgentService"

View File

@ -495,6 +495,8 @@
;;
;; To turn off basic dos protection, set the DOSMaxRequestsInTimeFrame to 0.
;; Allow banning via hashed MAC
;DeniedMacs = "YOURLONGMACTRSING ANOTHERMAC"
[MapImageService]
LocalServiceModule = "OpenSim.Services.MapImageService.dll:MapImageService"

View File

@ -1,4 +1,4 @@
20392e48-fad2-094e-bc5b-cda003a1e940
24121ec8-c0a3-099d-8d83-64feaa32418c
<llsd><map><key>llsd-lsl-syntax-version</key><integer>2</integer>
<key>controls</key>
<map>
@ -1513,7 +1513,7 @@
</map>
<key>OS_APIVERSION</key><map>
<key>type</key><string>integer</string>
<key>value</key><string>3</string>
<key>value</key><string>4</string>
</map>
<key>OS_ATTACH_MSG_ALL</key><map>
<key>type</key><string>integer</string>
@ -1539,6 +1539,36 @@
<key>type</key><string>integer</string>
<key>value</key><string>0x1</string>
</map>
<key>OS_LTPAG_ALGNLV</key><map>
<key>type</key><string>integer</string>
<key>value</key><string>0x4</string>
<key>tooltip</key><string>osLocalTeleportAgent align lookat to velocity</string>
</map>
<key>OS_LTPAG_FORCEFLY</key><map>
<key>type</key><string>integer</string>
<key>value</key><string>0x8</string>
<key>tooltip</key><string>osLocalTeleportAgent force fly</string>
</map>
<key>OS_LTPAG_FORCENOFLY</key><map>
<key>type</key><string>integer</string>
<key>value</key><string>0x16</string>
<key>tooltip</key><string>osLocalTeleportAgent force no fly</string>
</map>
<key>OS_LTPAG_NONE</key><map>
<key>type</key><string>integer</string>
<key>value</key><string>0x0</string>
<key>tooltip</key><string>osLocalTeleportAgent no flags</string>
</map>
<key>OS_LTPAG_USELOOKAT</key><map>
<key>type</key><string>integer</string>
<key>value</key><string>0x2</string>
<key>tooltip</key><string>osLocalTeleportAgent use lookat</string>
</map>
<key>OS_LTPAG_USEVEL</key><map>
<key>type</key><string>integer</string>
<key>value</key><string>0x1</string>
<key>tooltip</key><string>osLocalTeleportAgent use velocity</string>
</map>
<key>OS_NPC_CREATOR_OWNED</key><map>
<key>type</key><string>integer</string>
<key>value</key><string>0x1</string>
@ -6119,6 +6149,14 @@
</array>
</map>
<key>osApproxEquals</key>
<map>
<key>return</key><string>integer</string>
<key>arguments</key><array>
<map><key>va</key><map><key>type</key><string>vector</string></map></map>
<map><key>vb</key><map><key>type</key><string>vector</string></map></map>
</array>
</map>
<key>osApproxEquals</key>
<map>
<key>return</key><string>integer</string>
<key>arguments</key><array>
@ -6136,15 +6174,6 @@
</array>
</map>
<key>osApproxEquals</key>
<map>
<key>return</key><string>integer</string>
<key>arguments</key><array>
<map><key>va</key><map><key>type</key><string>vector</string></map></map>
<map><key>vb</key><map><key>type</key><string>vector</string></map></map>
<map><key>margin</key><map><key>type</key><string>float</string></map></map>
</array>
</map>
<key>osApproxEquals</key>
<map>
<key>return</key><string>integer</string>
<key>arguments</key><array>
@ -6159,6 +6188,7 @@
<key>arguments</key><array>
<map><key>va</key><map><key>type</key><string>vector</string></map></map>
<map><key>vb</key><map><key>type</key><string>vector</string></map></map>
<map><key>margin</key><map><key>type</key><string>float</string></map></map>
</array>
</map>
<key>osAvatarName2Key</key>
@ -6653,6 +6683,11 @@
<map><key>rules</key><map><key>type</key><string>list</string></map></map>
</array>
</map>
<key>osGetPSTWallclock</key>
<map>
<key>return</key><string>float</string>
<key>arguments</key><undef/>
</map>
<key>osGetRegionMapTexture</key>
<map>
<key>return</key><string>key</string>
@ -6776,6 +6811,16 @@
<key>return</key><string>string</string>
<key>arguments</key><undef/>
</map>
<key>osLocalTeleportAgent</key>
<map>
<key>arguments</key><array>
<map><key>agent</key><map><key>type</key><string>key</string></map></map>
<map><key>position</key><map><key>type</key><string>vector</string></map></map>
<map><key>velocity</key><map><key>type</key><string>vector</string></map></map>
<map><key>lookat</key><map><key>type</key><string>vector</string></map></map>
<map><key>flags</key><map><key>type</key><string>integer</string></map></map>
</array>
</map>
<key>osLoopSound</key>
<map>
<key>arguments</key><array>
@ -6865,6 +6910,7 @@
<map><key>name</key><map><key>type</key><string>string</string></map></map>
<map><key>position</key><map><key>type</key><string>vector</string></map></map>
<map><key>notecard</key><map><key>type</key><string>string</string></map></map>
<map><key>options</key><map><key>type</key><string>integer</string></map></map>
</array>
</map>
<key>osNpcCreate</key>
@ -6875,7 +6921,6 @@
<map><key>name</key><map><key>type</key><string>string</string></map></map>
<map><key>position</key><map><key>type</key><string>vector</string></map></map>
<map><key>notecard</key><map><key>type</key><string>string</string></map></map>
<map><key>options</key><map><key>type</key><string>integer</string></map></map>
</array>
</map>
<key>osNpcGetOwner</key>
@ -7354,6 +7399,17 @@
</array>
</map>
<key>osSetProjectionParams</key>
<map>
<key>arguments</key><array>
<map><key>linknumber</key><map><key>type</key><string>integer</string></map></map>
<map><key>projection</key><map><key>type</key><string>integer</string></map></map>
<map><key>texture</key><map><key>type</key><string>key</string></map></map>
<map><key>fov</key><map><key>type</key><string>float</string></map></map>
<map><key>focus</key><map><key>type</key><string>float</string></map></map>
<map><key>amb</key><map><key>type</key><string>float</string></map></map>
</array>
</map>
<key>osSetProjectionParams</key>
<map>
<key>arguments</key><array>
<map><key>prim</key><map><key>type</key><string>key</string></map></map>
@ -7525,6 +7581,7 @@
<key>arguments</key><array>
<map><key>src</key><map><key>type</key><string>string</string></map></map>
<map><key>start</key><map><key>type</key><string>integer</string></map></map>
<map><key>length</key><map><key>type</key><string>integer</string></map></map>
</array>
</map>
<key>osStringSubString</key>
@ -7533,7 +7590,6 @@
<key>arguments</key><array>
<map><key>src</key><map><key>type</key><string>string</string></map></map>
<map><key>start</key><map><key>type</key><string>integer</string></map></map>
<map><key>length</key><map><key>type</key><string>integer</string></map></map>
</array>
</map>
<key>osSunGetParam</key>
@ -7551,6 +7607,23 @@
</array>
</map>
<key>osTeleportAgent</key>
<map>
<key>arguments</key><array>
<map><key>agent</key><map><key>type</key><string>string</string></map></map>
<map><key>regionName</key><map><key>type</key><string>string</string></map></map>
<map><key>position</key><map><key>type</key><string>vector</string></map></map>
<map><key>lookat</key><map><key>type</key><string>vector</string></map></map>
</array>
</map>
<key>osTeleportAgent</key>
<map>
<key>arguments</key><array>
<map><key>agent</key><map><key>type</key><string>string</string></map></map>
<map><key>position</key><map><key>type</key><string>vector</string></map></map>
<map><key>lookat</key><map><key>type</key><string>vector</string></map></map>
</array>
</map>
<key>osTeleportAgent</key>
<map>
<key>arguments</key><array>
<map><key>agent</key><map><key>type</key><string>string</string></map></map>
@ -7560,23 +7633,6 @@
<map><key>lookat</key><map><key>type</key><string>vector</string></map></map>
</array>
</map>
<key>osTeleportAgent</key>
<map>
<key>arguments</key><array>
<map><key>agent</key><map><key>type</key><string>string</string></map></map>
<map><key>position</key><map><key>type</key><string>vector</string></map></map>
<map><key>lookat</key><map><key>type</key><string>vector</string></map></map>
</array>
</map>
<key>osTeleportAgent</key>
<map>
<key>arguments</key><array>
<map><key>agent</key><map><key>type</key><string>string</string></map></map>
<map><key>regionName</key><map><key>type</key><string>string</string></map></map>
<map><key>position</key><map><key>type</key><string>vector</string></map></map>
<map><key>lookat</key><map><key>type</key><string>vector</string></map></map>
</array>
</map>
<key>osTeleportObject</key>
<map>
<key>return</key><string>integer</string>
@ -7597,7 +7653,8 @@
<key>osTeleportOwner</key>
<map>
<key>arguments</key><array>
<map><key>regionName</key><map><key>type</key><string>string</string></map></map>
<map><key>regionX</key><map><key>type</key><string>integer</string></map></map>
<map><key>regionY</key><map><key>type</key><string>integer</string></map></map>
<map><key>position</key><map><key>type</key><string>vector</string></map></map>
<map><key>lookat</key><map><key>type</key><string>vector</string></map></map>
</array>
@ -7605,8 +7662,7 @@
<key>osTeleportOwner</key>
<map>
<key>arguments</key><array>
<map><key>regionX</key><map><key>type</key><string>integer</string></map></map>
<map><key>regionY</key><map><key>type</key><string>integer</string></map></map>
<map><key>regionName</key><map><key>type</key><string>string</string></map></map>
<map><key>position</key><map><key>type</key><string>vector</string></map></map>
<map><key>lookat</key><map><key>type</key><string>vector</string></map></map>
</array>

Binary file not shown.

View File

@ -5,21 +5,26 @@ bin\Prebuild.exe /target vs2015
setlocal ENABLEEXTENSIONS
set VALUE_NAME=MSBuildToolsPath
rem try find vs2017
if "%PROCESSOR_ARCHITECTURE%"=="x86" set PROGRAMS=%ProgramFiles%
if defined ProgramFiles(x86) set PROGRAMS=%ProgramFiles(x86)%
rem Try to find VS2019
for %%e in (Enterprise Professional Community) do (
if exist "%PROGRAMS%\Microsoft Visual Studio\2019\%%e\MSBuild\Current\Bin\MSBuild.exe" (
if exist "%PROGRAMS%\Microsoft Visual Studio\2017\%%e\MSBuild\15.0\Bin\MSBuild.exe" (
set ValueValue="%PROGRAMS%\Microsoft Visual Studio\2017\%%e\MSBuild\15.0\Bin\"
set ValueValue="%PROGRAMS%\Microsoft Visual Studio\2019\%%e\MSBuild\Current\Bin\MSBuild"
goto :found
)
)
rem try find vs2017
for %%e in (Enterprise Professional Community) do (
if exist "%PROGRAMS%\Microsoft Visual Studio\2017\%%e\MSBuild\15.0\Bin\MSBuild.exe" (
set ValueValue="%PROGRAMS%\Microsoft Visual Studio\2017\%%e\MSBuild\15.0\Bin\MSBuild"
goto :found
)
)
rem We have to use grep or find to locate the correct line, because reg query spits
rem out 4 lines before Windows 7 but 2 lines after Windows 7.
@ -35,7 +40,7 @@ if defined FOUNDGREP (
rem try vs2015
FOR /F "usebackq tokens=1-3" %%A IN (`REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\14.0" /v %VALUE_NAME% 2^>nul ^| %FINDCMD% "%VALUE_NAME%"`) DO (
set ValueValue=%%C
set ValueValue=%%C\msbuild
goto :found
)
@ -49,6 +54,8 @@ goto :done
:found
@echo Found msbuild at %ValueValue%
@echo Creating compile.bat
@echo %ValueValue%\msbuild opensim.sln > compile.bat
rem To compile in debug mode
@echo %ValueValue% opensim.sln > compile.bat
rem To compile in release mode comment line (add rem to start) above and uncomment next (remove rem)
rem @echo %ValueValue% /P:Config=Release opensim.sln > compile.bat
:done