Merging slimupdates2
commit
beed74096c
|
@ -1026,23 +1026,6 @@ namespace OpenSim.Client.MXP.ClientStack
|
||||||
// Need to translate to MXP somehow
|
// Need to translate to MXP somehow
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendAvatarData(SendAvatarData data)
|
|
||||||
{
|
|
||||||
//ScenePresence presence=((Scene)this.Scene).GetScenePresence(avatarID);
|
|
||||||
UUID ownerID = data.AvatarID;
|
|
||||||
MXPSendAvatarData(data.FirstName + " " + data.LastName, ownerID, UUID.Zero, data.AvatarID, data.AvatarLocalID, data.Position, data.Rotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendAvatarTerseUpdate(SendAvatarTerseData data)
|
|
||||||
{
|
|
||||||
MovementEventMessage me = new MovementEventMessage();
|
|
||||||
me.ObjectIndex = data.LocalID;
|
|
||||||
me.Location = ToOmVector(data.Position);
|
|
||||||
me.Orientation = ToOmQuaternion(data.Rotation);
|
|
||||||
|
|
||||||
Session.Send(me);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
|
public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
|
||||||
{
|
{
|
||||||
// Minimap function, not used.
|
// Minimap function, not used.
|
||||||
|
@ -1058,23 +1041,31 @@ namespace OpenSim.Client.MXP.ClientStack
|
||||||
// Need to translate to MXP somehow
|
// Need to translate to MXP somehow
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendPrimitiveToClient(SendPrimitiveData data)
|
public void SendAvatarDataImmediate(ISceneEntity avatar)
|
||||||
{
|
{
|
||||||
MXPSendPrimitive(data.localID, data.ownerID, data.acc, data.rvel, data.primShape, data.pos, data.objectID, data.vel,
|
//ScenePresence presence=((Scene)this.Scene).GetScenePresence(avatarID);
|
||||||
data.rotation, (uint)data.flags, data.text, data.color, data.parentID, data.particleSystem, data.clickAction,
|
ScenePresence presence = (ScenePresence)avatar;
|
||||||
data.material, data.textureanim);
|
UUID ownerID = presence.UUID;
|
||||||
|
MXPSendAvatarData(presence.Firstname + " " + presence.Lastname, ownerID, UUID.Zero, presence.UUID, presence.LocalId, presence.AbsolutePosition, presence.Rotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendPrimTerseUpdate(SendPrimitiveTerseData data)
|
public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
|
||||||
{
|
{
|
||||||
MovementEventMessage me = new MovementEventMessage();
|
//MovementEventMessage me = new MovementEventMessage();
|
||||||
me.ObjectIndex = data.LocalID;
|
//me.ObjectIndex = data.LocalID;
|
||||||
me.Location = ToOmVector(data.Position);
|
//me.Location = ToOmVector(data.Position);
|
||||||
me.Orientation = ToOmQuaternion(data.Rotation);
|
//me.Orientation = ToOmQuaternion(data.Rotation);
|
||||||
Session.Send(me);
|
|
||||||
|
//MXPSendPrimitive(data.localID, data.ownerID, data.acc, data.rvel, data.primShape, data.pos, data.objectID, data.vel,
|
||||||
|
// data.rotation, (uint)data.flags, data.text, data.color, data.parentID, data.particleSystem, data.clickAction,
|
||||||
|
// data.material, data.textureanim);
|
||||||
|
|
||||||
|
//Session.Send(me);
|
||||||
|
|
||||||
|
throw new System.NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler)
|
public void ReprioritizeUpdates(UpdatePriorityHandler handler)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -584,16 +584,6 @@ namespace OpenSim.Client.Sirikata.ClientStack
|
||||||
throw new System.NotImplementedException();
|
throw new System.NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendAvatarData(SendAvatarData data)
|
|
||||||
{
|
|
||||||
throw new System.NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendAvatarTerseUpdate(SendAvatarTerseData data)
|
|
||||||
{
|
|
||||||
throw new System.NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
|
public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
|
||||||
{
|
{
|
||||||
throw new System.NotImplementedException();
|
throw new System.NotImplementedException();
|
||||||
|
@ -609,22 +599,17 @@ namespace OpenSim.Client.Sirikata.ClientStack
|
||||||
throw new System.NotImplementedException();
|
throw new System.NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendPrimitiveToClient(SendPrimitiveData data)
|
public void SendAvatarDataImmediate(ISceneEntity avatar)
|
||||||
{
|
{
|
||||||
throw new System.NotImplementedException();
|
throw new System.NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendPrimTerseUpdate(SendPrimitiveTerseData data)
|
public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
|
||||||
{
|
{
|
||||||
throw new System.NotImplementedException();
|
throw new System.NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler)
|
public void ReprioritizeUpdates(UpdatePriorityHandler handler)
|
||||||
{
|
|
||||||
throw new System.NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items, List<InventoryFolderBase> folders, int version, bool fetchFolders, bool fetchItems)
|
|
||||||
{
|
{
|
||||||
throw new System.NotImplementedException();
|
throw new System.NotImplementedException();
|
||||||
}
|
}
|
||||||
|
@ -634,6 +619,11 @@ namespace OpenSim.Client.Sirikata.ClientStack
|
||||||
throw new System.NotImplementedException();
|
throw new System.NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items, List<InventoryFolderBase> folders, int version, bool fetchFolders, bool fetchItems)
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
public void SendInventoryItemDetails(UUID ownerID, InventoryItemBase item)
|
public void SendInventoryItemDetails(UUID ownerID, InventoryItemBase item)
|
||||||
{
|
{
|
||||||
throw new System.NotImplementedException();
|
throw new System.NotImplementedException();
|
||||||
|
|
|
@ -590,16 +590,6 @@ namespace OpenSim.Client.VWoHTTP.ClientStack
|
||||||
throw new System.NotImplementedException();
|
throw new System.NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendAvatarData(SendAvatarData data)
|
|
||||||
{
|
|
||||||
throw new System.NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendAvatarTerseUpdate(SendAvatarTerseData data)
|
|
||||||
{
|
|
||||||
throw new System.NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
|
public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
|
||||||
{
|
{
|
||||||
throw new System.NotImplementedException();
|
throw new System.NotImplementedException();
|
||||||
|
@ -615,17 +605,17 @@ namespace OpenSim.Client.VWoHTTP.ClientStack
|
||||||
throw new System.NotImplementedException();
|
throw new System.NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendPrimitiveToClient(SendPrimitiveData data)
|
public void SendAvatarDataImmediate(ISceneEntity avatar)
|
||||||
{
|
{
|
||||||
throw new System.NotImplementedException();
|
throw new System.NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendPrimTerseUpdate(SendPrimitiveTerseData data)
|
public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
|
||||||
{
|
{
|
||||||
throw new System.NotImplementedException();
|
throw new System.NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler)
|
public void ReprioritizeUpdates(UpdatePriorityHandler handler)
|
||||||
{
|
{
|
||||||
throw new System.NotImplementedException();
|
throw new System.NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
|
@ -571,207 +571,6 @@ namespace OpenSim.Framework
|
||||||
public float dwell;
|
public float dwell;
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct SendAvatarData
|
|
||||||
{
|
|
||||||
public readonly ulong RegionHandle;
|
|
||||||
public readonly string FirstName;
|
|
||||||
public readonly string LastName;
|
|
||||||
public readonly string GroupTitle;
|
|
||||||
public readonly UUID AvatarID;
|
|
||||||
public readonly uint AvatarLocalID;
|
|
||||||
public readonly Vector3 Position;
|
|
||||||
public readonly byte[] TextureEntry;
|
|
||||||
public readonly uint ParentID;
|
|
||||||
public readonly Quaternion Rotation;
|
|
||||||
|
|
||||||
public SendAvatarData(ulong regionHandle, string firstName, string lastName, string groupTitle, UUID avatarID,
|
|
||||||
uint avatarLocalID, Vector3 position, byte[] textureEntry, uint parentID, Quaternion rotation)
|
|
||||||
{
|
|
||||||
RegionHandle = regionHandle;
|
|
||||||
FirstName = firstName;
|
|
||||||
LastName = lastName;
|
|
||||||
GroupTitle = groupTitle;
|
|
||||||
AvatarID = avatarID;
|
|
||||||
AvatarLocalID = avatarLocalID;
|
|
||||||
Position = position;
|
|
||||||
TextureEntry = textureEntry;
|
|
||||||
ParentID = parentID;
|
|
||||||
Rotation = rotation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct SendAvatarTerseData
|
|
||||||
{
|
|
||||||
public readonly ulong RegionHandle;
|
|
||||||
public readonly ushort TimeDilation;
|
|
||||||
public readonly uint LocalID;
|
|
||||||
public readonly Vector3 Position;
|
|
||||||
public readonly Vector3 Velocity;
|
|
||||||
public readonly Vector3 Acceleration;
|
|
||||||
public readonly Quaternion Rotation;
|
|
||||||
public readonly Vector4 CollisionPlane;
|
|
||||||
public readonly UUID AgentID;
|
|
||||||
public readonly byte[] TextureEntry;
|
|
||||||
public readonly double Priority;
|
|
||||||
|
|
||||||
public SendAvatarTerseData(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, Vector3 velocity,
|
|
||||||
Vector3 acceleration, Quaternion rotation, Vector4 collisionPlane, UUID agentid, byte[] textureEntry, double priority)
|
|
||||||
{
|
|
||||||
RegionHandle = regionHandle;
|
|
||||||
TimeDilation = timeDilation;
|
|
||||||
LocalID = localID;
|
|
||||||
Position = position;
|
|
||||||
Velocity = velocity;
|
|
||||||
Acceleration = acceleration;
|
|
||||||
Rotation = rotation;
|
|
||||||
CollisionPlane = collisionPlane;
|
|
||||||
AgentID = agentid;
|
|
||||||
TextureEntry = textureEntry;
|
|
||||||
Priority = priority;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct SendPrimitiveTerseData
|
|
||||||
{
|
|
||||||
public readonly ulong RegionHandle;
|
|
||||||
public readonly ushort TimeDilation;
|
|
||||||
public readonly uint LocalID;
|
|
||||||
public readonly Vector3 Position;
|
|
||||||
public readonly Quaternion Rotation;
|
|
||||||
public readonly Vector3 Velocity;
|
|
||||||
public readonly Vector3 Acceleration;
|
|
||||||
public readonly Vector3 AngularVelocity;
|
|
||||||
public readonly UUID AssetID;
|
|
||||||
public readonly UUID OwnerID;
|
|
||||||
public readonly int AttachPoint;
|
|
||||||
public readonly byte[] TextureEntry;
|
|
||||||
public readonly double Priority;
|
|
||||||
|
|
||||||
public SendPrimitiveTerseData(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position,
|
|
||||||
Quaternion rotation, Vector3 velocity, Vector3 acceleration, Vector3 rotationalvelocity,
|
|
||||||
UUID assetID, UUID ownerID, int attachPoint, byte[] textureEntry, double priority)
|
|
||||||
{
|
|
||||||
RegionHandle = regionHandle;
|
|
||||||
TimeDilation = timeDilation;
|
|
||||||
LocalID = localID;
|
|
||||||
Position = position;
|
|
||||||
Rotation = rotation;
|
|
||||||
Velocity = velocity;
|
|
||||||
Acceleration = acceleration;
|
|
||||||
AngularVelocity = rotationalvelocity;
|
|
||||||
AssetID = assetID;
|
|
||||||
OwnerID = ownerID;
|
|
||||||
AttachPoint = attachPoint;
|
|
||||||
TextureEntry = textureEntry;
|
|
||||||
Priority = priority;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct SendPrimitiveData
|
|
||||||
{
|
|
||||||
private ulong m_regionHandle;
|
|
||||||
private ushort m_timeDilation;
|
|
||||||
private uint m_localID;
|
|
||||||
private PrimitiveBaseShape m_primShape;
|
|
||||||
private Vector3 m_pos;
|
|
||||||
private Vector3 m_vel;
|
|
||||||
private Vector3 m_acc;
|
|
||||||
private Quaternion m_rotation;
|
|
||||||
private Vector3 m_rvel;
|
|
||||||
private PrimFlags m_flags;
|
|
||||||
private UUID m_objectID;
|
|
||||||
private UUID m_ownerID;
|
|
||||||
private string m_text;
|
|
||||||
private byte[] m_color;
|
|
||||||
private uint m_parentID;
|
|
||||||
private byte[] m_particleSystem;
|
|
||||||
private byte m_clickAction;
|
|
||||||
private byte m_material;
|
|
||||||
private byte[] m_textureanim;
|
|
||||||
private bool m_attachment;
|
|
||||||
private uint m_AttachPoint;
|
|
||||||
private UUID m_AssetId;
|
|
||||||
private UUID m_SoundId;
|
|
||||||
private double m_SoundVolume;
|
|
||||||
private byte m_SoundFlags;
|
|
||||||
private double m_SoundRadius;
|
|
||||||
private double m_priority;
|
|
||||||
|
|
||||||
public SendPrimitiveData(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape,
|
|
||||||
Vector3 pos, Vector3 vel, Vector3 acc, Quaternion rotation, Vector3 rvel,
|
|
||||||
uint flags, UUID objectID, UUID ownerID, string text, byte[] color,
|
|
||||||
uint parentID, byte[] particleSystem, byte clickAction, byte material, double priority) :
|
|
||||||
this(regionHandle, timeDilation, localID, primShape, pos, vel, acc, rotation, rvel, flags, objectID,
|
|
||||||
ownerID, text, color, parentID, particleSystem, clickAction, material, new byte[0], false, 0, UUID.Zero,
|
|
||||||
UUID.Zero, 0, 0, 0, priority) { }
|
|
||||||
|
|
||||||
public SendPrimitiveData(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape,
|
|
||||||
Vector3 pos, Vector3 vel, Vector3 acc, Quaternion rotation, Vector3 rvel,
|
|
||||||
uint flags,
|
|
||||||
UUID objectID, UUID ownerID, string text, byte[] color, uint parentID,
|
|
||||||
byte[] particleSystem,
|
|
||||||
byte clickAction, byte material, byte[] textureanim, bool attachment,
|
|
||||||
uint AttachPoint, UUID AssetId, UUID SoundId, double SoundVolume, byte SoundFlags,
|
|
||||||
double SoundRadius, double priority)
|
|
||||||
{
|
|
||||||
this.m_regionHandle = regionHandle;
|
|
||||||
this.m_timeDilation = timeDilation;
|
|
||||||
this.m_localID = localID;
|
|
||||||
this.m_primShape = primShape;
|
|
||||||
this.m_pos = pos;
|
|
||||||
this.m_vel = vel;
|
|
||||||
this.m_acc = acc;
|
|
||||||
this.m_rotation = rotation;
|
|
||||||
this.m_rvel = rvel;
|
|
||||||
this.m_flags = (PrimFlags)flags;
|
|
||||||
this.m_objectID = objectID;
|
|
||||||
this.m_ownerID = ownerID;
|
|
||||||
this.m_text = text;
|
|
||||||
this.m_color = color;
|
|
||||||
this.m_parentID = parentID;
|
|
||||||
this.m_particleSystem = particleSystem;
|
|
||||||
this.m_clickAction = clickAction;
|
|
||||||
this.m_material = material;
|
|
||||||
this.m_textureanim = textureanim;
|
|
||||||
this.m_attachment = attachment;
|
|
||||||
this.m_AttachPoint = AttachPoint;
|
|
||||||
this.m_AssetId = AssetId;
|
|
||||||
this.m_SoundId = SoundId;
|
|
||||||
this.m_SoundVolume = SoundVolume;
|
|
||||||
this.m_SoundFlags = SoundFlags;
|
|
||||||
this.m_SoundRadius = SoundRadius;
|
|
||||||
this.m_priority = priority;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ulong regionHandle { get { return this.m_regionHandle; } }
|
|
||||||
public ushort timeDilation { get { return this.m_timeDilation; } }
|
|
||||||
public uint localID { get { return this.m_localID; } }
|
|
||||||
public PrimitiveBaseShape primShape { get { return this.m_primShape; } }
|
|
||||||
public Vector3 pos { get { return this.m_pos; } }
|
|
||||||
public Vector3 vel { get { return this.m_vel; } }
|
|
||||||
public Vector3 acc { get { return this.m_acc; } }
|
|
||||||
public Quaternion rotation { get { return this.m_rotation; } }
|
|
||||||
public Vector3 rvel { get { return this.m_rvel; } }
|
|
||||||
public PrimFlags flags { get { return this.m_flags; } }
|
|
||||||
public UUID objectID { get { return this.m_objectID; } }
|
|
||||||
public UUID ownerID { get { return this.m_ownerID; } }
|
|
||||||
public string text { get { return this.m_text; } }
|
|
||||||
public byte[] color { get { return this.m_color; } }
|
|
||||||
public uint parentID { get { return this.m_parentID; } }
|
|
||||||
public byte[] particleSystem { get { return this.m_particleSystem; } }
|
|
||||||
public byte clickAction { get { return this.m_clickAction; } }
|
|
||||||
public byte material { get { return this.m_material; } }
|
|
||||||
public byte[] textureanim { get { return this.m_textureanim; } }
|
|
||||||
public bool attachment { get { return this.m_attachment; } }
|
|
||||||
public uint AttachPoint { get { return this.m_AttachPoint; } }
|
|
||||||
public UUID AssetId { get { return this.m_AssetId; } }
|
|
||||||
public UUID SoundId { get { return this.m_SoundId; } }
|
|
||||||
public double SoundVolume { get { return this.m_SoundVolume; } }
|
|
||||||
public byte SoundFlags { get { return this.m_SoundFlags; } }
|
|
||||||
public double SoundRadius { get { return this.m_SoundRadius; } }
|
|
||||||
public double priority { get { return this.m_priority; } }
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct UpdatePriorityData {
|
public struct UpdatePriorityData {
|
||||||
private double m_priority;
|
private double m_priority;
|
||||||
private uint m_localID;
|
private uint m_localID;
|
||||||
|
@ -785,14 +584,46 @@ namespace OpenSim.Framework
|
||||||
public uint localID { get { return this.m_localID; } }
|
public uint localID { get { return this.m_localID; } }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Specifies the fields that have been changed when sending a prim or
|
||||||
|
/// avatar update
|
||||||
|
/// </summary>
|
||||||
[Flags]
|
[Flags]
|
||||||
public enum StateUpdateTypes
|
public enum PrimUpdateFlags : uint
|
||||||
{
|
{
|
||||||
None = 0,
|
None = 0,
|
||||||
AvatarTerse = 1,
|
AttachmentPoint = 1 << 0,
|
||||||
PrimitiveTerse = AvatarTerse << 1,
|
Material = 1 << 1,
|
||||||
PrimitiveFull = PrimitiveTerse << 1,
|
ClickAction = 1 << 2,
|
||||||
All = AvatarTerse | PrimitiveTerse | PrimitiveFull,
|
Scale = 1 << 3,
|
||||||
|
ParentID = 1 << 4,
|
||||||
|
PrimFlags = 1 << 5,
|
||||||
|
PrimData = 1 << 6,
|
||||||
|
MediaURL = 1 << 7,
|
||||||
|
ScratchPad = 1 << 8,
|
||||||
|
Textures = 1 << 9,
|
||||||
|
TextureAnim = 1 << 10,
|
||||||
|
NameValue = 1 << 11,
|
||||||
|
Position = 1 << 12,
|
||||||
|
Rotation = 1 << 13,
|
||||||
|
Velocity = 1 << 14,
|
||||||
|
Acceleration = 1 << 15,
|
||||||
|
AngularVelocity = 1 << 16,
|
||||||
|
CollisionPlane = 1 << 17,
|
||||||
|
Text = 1 << 18,
|
||||||
|
Particles = 1 << 19,
|
||||||
|
ExtraData = 1 << 20,
|
||||||
|
Sound = 1 << 21,
|
||||||
|
Joint = 1 << 22,
|
||||||
|
FullUpdate = UInt32.MaxValue
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class PrimUpdateFlagsExtensions
|
||||||
|
{
|
||||||
|
public static bool HasFlag(this PrimUpdateFlags updateFlags, PrimUpdateFlags flag)
|
||||||
|
{
|
||||||
|
return (updateFlags & flag) == flag;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IClientAPI
|
public interface IClientAPI
|
||||||
|
@ -1186,27 +1017,20 @@ namespace OpenSim.Framework
|
||||||
void SendMoneyBalance(UUID transaction, bool success, byte[] description, int balance);
|
void SendMoneyBalance(UUID transaction, bool success, byte[] description, int balance);
|
||||||
void SendPayPrice(UUID objectID, int[] payPrice);
|
void SendPayPrice(UUID objectID, int[] payPrice);
|
||||||
|
|
||||||
void SendAvatarData(SendAvatarData data);
|
|
||||||
|
|
||||||
void SendAvatarTerseUpdate(SendAvatarTerseData data);
|
|
||||||
|
|
||||||
void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations);
|
void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations);
|
||||||
|
|
||||||
void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID);
|
void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID);
|
||||||
void SetChildAgentThrottle(byte[] throttle);
|
void SetChildAgentThrottle(byte[] throttle);
|
||||||
|
|
||||||
void SendPrimitiveToClient(SendPrimitiveData data);
|
void SendAvatarDataImmediate(ISceneEntity avatar);
|
||||||
|
void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags);
|
||||||
void SendPrimTerseUpdate(SendPrimitiveTerseData data);
|
void ReprioritizeUpdates(UpdatePriorityHandler handler);
|
||||||
|
void FlushPrimUpdates();
|
||||||
void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler);
|
|
||||||
|
|
||||||
void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items,
|
void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items,
|
||||||
List<InventoryFolderBase> folders, int version, bool fetchFolders,
|
List<InventoryFolderBase> folders, int version, bool fetchFolders,
|
||||||
bool fetchItems);
|
bool fetchItems);
|
||||||
|
|
||||||
void FlushPrimUpdates();
|
|
||||||
|
|
||||||
void SendInventoryItemDetails(UUID ownerID, InventoryItemBase item);
|
void SendInventoryItemDetails(UUID ownerID, InventoryItemBase item);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using OpenMetaverse;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework
|
||||||
|
{
|
||||||
|
public interface ISceneEntity
|
||||||
|
{
|
||||||
|
UUID UUID { get; }
|
||||||
|
uint LocalId { get; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,236 @@
|
||||||
|
//
|
||||||
|
// Lazy.cs
|
||||||
|
//
|
||||||
|
// Authors:
|
||||||
|
// Zoltan Varga (vargaz@gmail.com)
|
||||||
|
// Marek Safar (marek.safar@gmail.com)
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 Novell
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
// a copy of this software and associated documentation files (the
|
||||||
|
// "Software"), to deal in the Software without restriction, including
|
||||||
|
// without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
// permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
// the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be
|
||||||
|
// included in all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Security.Permissions;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework
|
||||||
|
{
|
||||||
|
public enum LazyThreadSafetyMode
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
PublicationOnly,
|
||||||
|
ExecutionAndPublication
|
||||||
|
}
|
||||||
|
|
||||||
|
[SerializableAttribute]
|
||||||
|
[ComVisibleAttribute(false)]
|
||||||
|
[HostProtectionAttribute(SecurityAction.LinkDemand, Synchronization = true, ExternalThreading = true)]
|
||||||
|
public class Lazy<T>
|
||||||
|
{
|
||||||
|
T value;
|
||||||
|
bool inited;
|
||||||
|
LazyThreadSafetyMode mode;
|
||||||
|
Func<T> factory;
|
||||||
|
object monitor;
|
||||||
|
Exception exception;
|
||||||
|
|
||||||
|
public Lazy()
|
||||||
|
: this(LazyThreadSafetyMode.ExecutionAndPublication)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public Lazy(Func<T> valueFactory)
|
||||||
|
: this(valueFactory, LazyThreadSafetyMode.ExecutionAndPublication)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public Lazy(bool isThreadSafe)
|
||||||
|
: this(() => Activator.CreateInstance<T>(), isThreadSafe ? LazyThreadSafetyMode.ExecutionAndPublication : LazyThreadSafetyMode.None)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public Lazy(Func<T> valueFactory, bool isThreadSafe)
|
||||||
|
: this(valueFactory, isThreadSafe ? LazyThreadSafetyMode.ExecutionAndPublication : LazyThreadSafetyMode.None)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public Lazy(LazyThreadSafetyMode mode)
|
||||||
|
: this(() => Activator.CreateInstance<T>(), mode)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public Lazy(Func<T> valueFactory, LazyThreadSafetyMode mode)
|
||||||
|
{
|
||||||
|
if (valueFactory == null)
|
||||||
|
throw new ArgumentNullException("valueFactory");
|
||||||
|
this.factory = valueFactory;
|
||||||
|
if (mode != LazyThreadSafetyMode.None)
|
||||||
|
monitor = new object();
|
||||||
|
this.mode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't trigger expensive initialization
|
||||||
|
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||||
|
public T Value
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (inited)
|
||||||
|
return value;
|
||||||
|
if (exception != null)
|
||||||
|
throw exception;
|
||||||
|
|
||||||
|
return InitValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
T InitValue()
|
||||||
|
{
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case LazyThreadSafetyMode.None:
|
||||||
|
{
|
||||||
|
var init_factory = factory;
|
||||||
|
if (init_factory == null)
|
||||||
|
throw exception = new InvalidOperationException("The initialization function tries to access Value on this instance");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
factory = null;
|
||||||
|
T v = init_factory();
|
||||||
|
value = v;
|
||||||
|
Thread.MemoryBarrier();
|
||||||
|
inited = true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
exception = ex;
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LazyThreadSafetyMode.PublicationOnly:
|
||||||
|
{
|
||||||
|
var init_factory = factory;
|
||||||
|
T v;
|
||||||
|
|
||||||
|
//exceptions are ignored
|
||||||
|
if (init_factory != null)
|
||||||
|
v = init_factory();
|
||||||
|
else
|
||||||
|
v = default(T);
|
||||||
|
|
||||||
|
lock (monitor)
|
||||||
|
{
|
||||||
|
if (inited)
|
||||||
|
return value;
|
||||||
|
value = v;
|
||||||
|
Thread.MemoryBarrier();
|
||||||
|
inited = true;
|
||||||
|
factory = null;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LazyThreadSafetyMode.ExecutionAndPublication:
|
||||||
|
{
|
||||||
|
lock (monitor)
|
||||||
|
{
|
||||||
|
if (inited)
|
||||||
|
return value;
|
||||||
|
|
||||||
|
if (factory == null)
|
||||||
|
throw exception = new InvalidOperationException("The initialization function tries to access Value on this instance");
|
||||||
|
|
||||||
|
var init_factory = factory;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
factory = null;
|
||||||
|
T v = init_factory();
|
||||||
|
value = v;
|
||||||
|
Thread.MemoryBarrier();
|
||||||
|
inited = true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
exception = ex;
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw new InvalidOperationException("Invalid LazyThreadSafetyMode " + mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (monitor == null)
|
||||||
|
{
|
||||||
|
value = factory();
|
||||||
|
inited = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lock (monitor)
|
||||||
|
{
|
||||||
|
if (inited)
|
||||||
|
return value;
|
||||||
|
|
||||||
|
if (factory == null)
|
||||||
|
throw new InvalidOperationException("The initialization function tries to access Value on this instance");
|
||||||
|
|
||||||
|
var init_factory = factory;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
factory = null;
|
||||||
|
T v = init_factory();
|
||||||
|
value = v;
|
||||||
|
Thread.MemoryBarrier();
|
||||||
|
inited = true;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
factory = init_factory;
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsValueCreated
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return inited;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
if (inited)
|
||||||
|
return value.ToString();
|
||||||
|
else
|
||||||
|
return "Value is not created";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -50,43 +50,17 @@ using Nini.Config;
|
||||||
|
|
||||||
namespace OpenSim.Region.ClientStack.LindenUDP
|
namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
#region Enums
|
public class EntityUpdate
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Specifies the fields that have been changed when sending a prim or
|
|
||||||
/// avatar update
|
|
||||||
/// </summary>
|
|
||||||
[Flags]
|
|
||||||
public enum PrimUpdateFlags : uint
|
|
||||||
{
|
{
|
||||||
None = 0,
|
public ISceneEntity Entity;
|
||||||
AttachmentPoint = 1 << 0,
|
public PrimUpdateFlags Flags;
|
||||||
Material = 1 << 1,
|
|
||||||
ClickAction = 1 << 2,
|
|
||||||
Scale = 1 << 3,
|
|
||||||
ParentID = 1 << 4,
|
|
||||||
PrimFlags = 1 << 5,
|
|
||||||
PrimData = 1 << 6,
|
|
||||||
MediaURL = 1 << 7,
|
|
||||||
ScratchPad = 1 << 8,
|
|
||||||
Textures = 1 << 9,
|
|
||||||
TextureAnim = 1 << 10,
|
|
||||||
NameValue = 1 << 11,
|
|
||||||
Position = 1 << 12,
|
|
||||||
Rotation = 1 << 13,
|
|
||||||
Velocity = 1 << 14,
|
|
||||||
Acceleration = 1 << 15,
|
|
||||||
AngularVelocity = 1 << 16,
|
|
||||||
CollisionPlane = 1 << 17,
|
|
||||||
Text = 1 << 18,
|
|
||||||
Particles = 1 << 19,
|
|
||||||
ExtraData = 1 << 20,
|
|
||||||
Sound = 1 << 21,
|
|
||||||
Joint = 1 << 22,
|
|
||||||
FullUpdate = UInt32.MaxValue
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Enums
|
public EntityUpdate(ISceneEntity entity, PrimUpdateFlags flags)
|
||||||
|
{
|
||||||
|
Entity = entity;
|
||||||
|
Flags = flags;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public delegate bool PacketMethod(IClientAPI simClient, Packet packet);
|
public delegate bool PacketMethod(IClientAPI simClient, Packet packet);
|
||||||
|
|
||||||
|
@ -350,9 +324,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
private readonly IGroupsModule m_GroupsModule;
|
private readonly IGroupsModule m_GroupsModule;
|
||||||
|
|
||||||
private int m_cachedTextureSerial;
|
private int m_cachedTextureSerial;
|
||||||
protected PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_avatarTerseUpdates;
|
private PriorityQueue<double, EntityUpdate> m_entityUpdates;
|
||||||
private PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_primTerseUpdates;
|
|
||||||
private PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock> m_primFullUpdates;
|
|
||||||
|
|
||||||
/// <value>
|
/// <value>
|
||||||
/// List used in construction of data blocks for an object update packet. This is to stop us having to
|
/// List used in construction of data blocks for an object update packet. This is to stop us having to
|
||||||
|
@ -463,9 +435,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
m_scene = scene;
|
m_scene = scene;
|
||||||
|
|
||||||
m_avatarTerseUpdates = new PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
|
m_entityUpdates = new PriorityQueue<double, EntityUpdate>(m_scene.Entities.Count);
|
||||||
m_primTerseUpdates = new PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
|
|
||||||
m_primFullUpdates = new PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock>(m_scene.Entities.Count);
|
|
||||||
m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>();
|
m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>();
|
||||||
m_killRecord = new HashSet<uint>();
|
m_killRecord = new HashSet<uint>();
|
||||||
|
|
||||||
|
@ -1519,7 +1489,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
kill.Header.Reliable = true;
|
kill.Header.Reliable = true;
|
||||||
kill.Header.Zerocoded = true;
|
kill.Header.Zerocoded = true;
|
||||||
|
|
||||||
lock (m_primFullUpdates.SyncRoot)
|
lock (m_entityUpdates.SyncRoot)
|
||||||
{
|
{
|
||||||
m_killRecord.Add(localID);
|
m_killRecord.Add(localID);
|
||||||
OutPacket(kill, ThrottleOutPacketType.State);
|
OutPacket(kill, ThrottleOutPacketType.State);
|
||||||
|
@ -3419,71 +3389,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Send an ObjectUpdate packet with information about an avatar
|
/// Send an ObjectUpdate packet with information about an avatar
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void SendAvatarData(SendAvatarData data)
|
public void SendAvatarDataImmediate(ISceneEntity avatar)
|
||||||
{
|
{
|
||||||
|
ScenePresence presence = avatar as ScenePresence;
|
||||||
|
if (presence == null)
|
||||||
|
return;
|
||||||
|
|
||||||
ObjectUpdatePacket objupdate = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
|
ObjectUpdatePacket objupdate = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
|
||||||
objupdate.Header.Zerocoded = true;
|
objupdate.Header.Zerocoded = true;
|
||||||
|
|
||||||
objupdate.RegionData.RegionHandle = data.RegionHandle;
|
objupdate.RegionData.RegionHandle = presence.RegionHandle;
|
||||||
objupdate.RegionData.TimeDilation = ushort.MaxValue;
|
objupdate.RegionData.TimeDilation = ushort.MaxValue;
|
||||||
|
|
||||||
objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
|
objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
|
||||||
objupdate.ObjectData[0] = CreateAvatarUpdateBlock(data);
|
objupdate.ObjectData[0] = CreateAvatarUpdateBlock(presence);
|
||||||
|
|
||||||
OutPacket(objupdate, ThrottleOutPacketType.Task);
|
OutPacket(objupdate, ThrottleOutPacketType.Task);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Send a terse positional/rotation/velocity update about an avatar
|
|
||||||
/// to the client. This avatar can be that of the client itself.
|
|
||||||
/// </summary>
|
|
||||||
public virtual void SendAvatarTerseUpdate(SendAvatarTerseData data)
|
|
||||||
{
|
|
||||||
if (data.Priority == double.NaN)
|
|
||||||
{
|
|
||||||
m_log.Error("[LLClientView] SendAvatarTerseUpdate received a NaN priority, dropping update");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Quaternion rotation = data.Rotation;
|
|
||||||
if (rotation.W == 0.0f && rotation.X == 0.0f && rotation.Y == 0.0f && rotation.Z == 0.0f)
|
|
||||||
rotation = Quaternion.Identity;
|
|
||||||
|
|
||||||
ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = CreateImprovedTerseBlock(data);
|
|
||||||
|
|
||||||
lock (m_avatarTerseUpdates.SyncRoot)
|
|
||||||
m_avatarTerseUpdates.Enqueue(data.Priority, terseBlock, data.LocalID);
|
|
||||||
|
|
||||||
// If we received an update about our own avatar, process the avatar update priority queue immediately
|
|
||||||
if (data.AgentID == m_agentId)
|
|
||||||
ProcessAvatarTerseUpdates();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void ProcessAvatarTerseUpdates()
|
|
||||||
{
|
|
||||||
ImprovedTerseObjectUpdatePacket terse = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
|
|
||||||
terse.Header.Reliable = false;
|
|
||||||
terse.Header.Zerocoded = true;
|
|
||||||
|
|
||||||
//terse.RegionData = new ImprovedTerseObjectUpdatePacket.RegionDataBlock();
|
|
||||||
terse.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle;
|
|
||||||
terse.RegionData.TimeDilation = (ushort)(Scene.TimeDilation * ushort.MaxValue);
|
|
||||||
|
|
||||||
lock (m_avatarTerseUpdates.SyncRoot)
|
|
||||||
{
|
|
||||||
int count = Math.Min(m_avatarTerseUpdates.Count, m_udpServer.AvatarTerseUpdatesPerPacket);
|
|
||||||
if (count == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[count];
|
|
||||||
for (int i = 0; i < count; i++)
|
|
||||||
terse.ObjectData[i] = m_avatarTerseUpdates.Dequeue();
|
|
||||||
}
|
|
||||||
|
|
||||||
// HACK: Using the task category until the tiered reprioritization code is in
|
|
||||||
OutPacket(terse, ThrottleOutPacketType.Task);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
|
public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
|
||||||
{
|
{
|
||||||
if (!IsActive) return; // We don't need to update inactive clients.
|
if (!IsActive) return; // We don't need to update inactive clients.
|
||||||
|
@ -3528,172 +3451,187 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
#region Primitive Packet/Data Sending Methods
|
#region Primitive Packet/Data Sending Methods
|
||||||
|
|
||||||
public void SendPrimitiveToClient(SendPrimitiveData data)
|
/// <summary>
|
||||||
|
/// Generate one of the object update packets based on PrimUpdateFlags
|
||||||
|
/// and broadcast the packet to clients
|
||||||
|
/// </summary>
|
||||||
|
public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
|
||||||
{
|
{
|
||||||
// string text = data.text;
|
double priority;
|
||||||
// if (text.IndexOf("\n") >= 0)
|
|
||||||
// text = text.Remove(text.IndexOf("\n"));
|
|
||||||
// m_log.DebugFormat(
|
|
||||||
// "[CLIENT]: Placing request to send full info about prim {0} text {1} to client {2}",
|
|
||||||
// data.localID, text, Name);
|
|
||||||
|
|
||||||
if (data.priority == double.NaN)
|
|
||||||
{
|
|
||||||
m_log.Error("[LLClientView] SendPrimitiveToClient received a NaN priority, dropping update");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Quaternion rotation = data.rotation;
|
if (entity is SceneObjectPart)
|
||||||
if (rotation.W == 0.0f && rotation.X == 0.0f && rotation.Y == 0.0f && rotation.Z == 0.0f)
|
priority = ((SceneObjectPart)entity).ParentGroup.GetUpdatePriority(this);
|
||||||
rotation = Quaternion.Identity;
|
else if (entity is ScenePresence)
|
||||||
|
priority = ((ScenePresence)entity).GetUpdatePriority(this);
|
||||||
|
else
|
||||||
|
priority = 0.0d;
|
||||||
|
|
||||||
if (data.AttachPoint > 30 && data.ownerID != AgentId) // Someone else's HUD
|
lock (m_entityUpdates.SyncRoot)
|
||||||
return;
|
m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags), entity.LocalId);
|
||||||
if (data.primShape.State != 0 && data.parentID == 0 && data.primShape.PCode == 9)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ObjectUpdatePacket.ObjectDataBlock objectData = CreatePrimUpdateBlock(data);
|
|
||||||
|
|
||||||
lock (m_primFullUpdates.SyncRoot)
|
|
||||||
m_primFullUpdates.Enqueue(data.priority, objectData, data.localID);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProcessPrimFullUpdates()
|
private void ProcessEntityUpdates(int maxUpdates)
|
||||||
{
|
{
|
||||||
ObjectUpdatePacket outPacket = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
|
Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>();
|
||||||
outPacket.Header.Zerocoded = true;
|
Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>> compressedUpdateBlocks = new Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>>();
|
||||||
|
Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();
|
||||||
|
|
||||||
outPacket.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle;
|
if (maxUpdates <= 0) maxUpdates = Int32.MaxValue;
|
||||||
outPacket.RegionData.TimeDilation = (ushort)(Scene.TimeDilation * ushort.MaxValue);
|
int updatesThisCall = 0;
|
||||||
|
|
||||||
lock (m_primFullUpdates.SyncRoot)
|
lock (m_entityUpdates.SyncRoot)
|
||||||
{
|
{
|
||||||
int count = Math.Min(m_primFullUpdates.Count, m_udpServer.PrimFullUpdatesPerPacket);
|
EntityUpdate update;
|
||||||
if (count == 0)
|
while (updatesThisCall < maxUpdates && m_entityUpdates.TryDequeue(out update))
|
||||||
return;
|
|
||||||
|
|
||||||
m_fullUpdateDataBlocksBuilder.Clear();
|
|
||||||
|
|
||||||
for (int i = 0; i < count; i++)
|
|
||||||
{
|
{
|
||||||
ObjectUpdatePacket.ObjectDataBlock block = m_primFullUpdates.Dequeue();
|
++updatesThisCall;
|
||||||
|
|
||||||
if (!m_killRecord.Contains(block.ID))
|
#region UpdateFlags to packet type conversion
|
||||||
|
|
||||||
|
PrimUpdateFlags updateFlags = update.Flags;
|
||||||
|
|
||||||
|
bool canUseCompressed = true;
|
||||||
|
bool canUseImproved = true;
|
||||||
|
|
||||||
|
// Compressed object updates only make sense for LL primitives
|
||||||
|
if (!(update.Entity is SceneObjectPart))
|
||||||
|
canUseCompressed = false;
|
||||||
|
|
||||||
|
if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
|
||||||
{
|
{
|
||||||
m_fullUpdateDataBlocksBuilder.Add(block);
|
canUseCompressed = false;
|
||||||
|
canUseImproved = false;
|
||||||
// string text = Util.FieldToString(outPacket.ObjectData[i].Text);
|
|
||||||
// if (text.IndexOf("\n") >= 0)
|
|
||||||
// text = text.Remove(text.IndexOf("\n"));
|
|
||||||
// m_log.DebugFormat(
|
|
||||||
// "[CLIENT]: Sending full info about prim {0} text {1} to client {2}",
|
|
||||||
// outPacket.ObjectData[i].ID, text, Name);
|
|
||||||
}
|
}
|
||||||
// else
|
else
|
||||||
// {
|
{
|
||||||
// m_log.WarnFormat(
|
if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
|
||||||
// "[CLIENT]: Preventing full update for {0} after kill to {1}", block.ID, Name);
|
updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
|
||||||
// }
|
updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
|
||||||
|
updateFlags.HasFlag(PrimUpdateFlags.Joint))
|
||||||
|
{
|
||||||
|
canUseCompressed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
|
||||||
|
updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
|
||||||
|
updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
|
||||||
|
updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
|
||||||
|
updateFlags.HasFlag(PrimUpdateFlags.Text) ||
|
||||||
|
updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
|
||||||
|
updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
|
||||||
|
updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
|
||||||
|
updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
|
||||||
|
updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
|
||||||
|
updateFlags.HasFlag(PrimUpdateFlags.Material) ||
|
||||||
|
updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
|
||||||
|
updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
|
||||||
|
updateFlags.HasFlag(PrimUpdateFlags.Joint))
|
||||||
|
{
|
||||||
|
canUseImproved = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion UpdateFlags to packet type conversion
|
||||||
|
|
||||||
|
#region Block Construction
|
||||||
|
|
||||||
|
// TODO: Remove this once we can build compressed updates
|
||||||
|
canUseCompressed = false;
|
||||||
|
|
||||||
|
if (!canUseImproved && !canUseCompressed)
|
||||||
|
{
|
||||||
|
if (update.Entity is ScenePresence)
|
||||||
|
objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
|
||||||
|
else
|
||||||
|
objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
|
||||||
|
}
|
||||||
|
else if (!canUseImproved)
|
||||||
|
{
|
||||||
|
compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Block Construction
|
||||||
}
|
}
|
||||||
|
|
||||||
outPacket.ObjectData = m_fullUpdateDataBlocksBuilder.ToArray();
|
|
||||||
|
|
||||||
OutPacket(outPacket, ThrottleOutPacketType.State);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendPrimTerseUpdate(SendPrimitiveTerseData data)
|
|
||||||
{
|
|
||||||
if (data.Priority == double.NaN)
|
|
||||||
{
|
|
||||||
m_log.Error("[LLClientView] SendPrimTerseUpdate received a NaN priority, dropping update");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Quaternion rotation = data.Rotation;
|
#region Packet Sending
|
||||||
if (rotation.W == 0.0f && rotation.X == 0.0f && rotation.Y == 0.0f && rotation.Z == 0.0f)
|
|
||||||
rotation = Quaternion.Identity;
|
|
||||||
|
|
||||||
if (data.AttachPoint > 30 && data.OwnerID != AgentId) // Someone else's HUD
|
const float TIME_DILATION = 1.0f;
|
||||||
return;
|
ushort timeDilation = Utils.FloatToUInt16(TIME_DILATION, 0.0f, 1.0f);
|
||||||
|
|
||||||
ImprovedTerseObjectUpdatePacket.ObjectDataBlock objectData = CreateImprovedTerseBlock(data);
|
if (objectUpdateBlocks.IsValueCreated)
|
||||||
|
|
||||||
lock (m_primTerseUpdates.SyncRoot)
|
|
||||||
m_primTerseUpdates.Enqueue(data.Priority, objectData, data.LocalID);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ProcessPrimTerseUpdates()
|
|
||||||
{
|
|
||||||
ImprovedTerseObjectUpdatePacket outPacket = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
|
|
||||||
outPacket.Header.Reliable = false;
|
|
||||||
outPacket.Header.Zerocoded = true;
|
|
||||||
|
|
||||||
outPacket.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle;
|
|
||||||
outPacket.RegionData.TimeDilation = (ushort)(Scene.TimeDilation * ushort.MaxValue);
|
|
||||||
|
|
||||||
lock (m_primTerseUpdates.SyncRoot)
|
|
||||||
{
|
{
|
||||||
int count = Math.Min(m_primTerseUpdates.Count, m_udpServer.PrimTerseUpdatesPerPacket);
|
List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
|
||||||
if (count == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
outPacket.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[count];
|
ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
|
||||||
for (int i = 0; i < count; i++)
|
packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
|
||||||
outPacket.ObjectData[i] = m_primTerseUpdates.Dequeue();
|
packet.RegionData.TimeDilation = timeDilation;
|
||||||
|
packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
|
||||||
|
|
||||||
|
for (int i = 0; i < blocks.Count; i++)
|
||||||
|
packet.ObjectData[i] = blocks[i];
|
||||||
|
|
||||||
|
OutPacket(packet, ThrottleOutPacketType.Task, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
OutPacket(outPacket, ThrottleOutPacketType.State);
|
if (compressedUpdateBlocks.IsValueCreated)
|
||||||
|
{
|
||||||
|
List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
|
||||||
|
|
||||||
|
ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
|
||||||
|
packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
|
||||||
|
packet.RegionData.TimeDilation = timeDilation;
|
||||||
|
packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
|
||||||
|
|
||||||
|
for (int i = 0; i < blocks.Count; i++)
|
||||||
|
packet.ObjectData[i] = blocks[i];
|
||||||
|
|
||||||
|
OutPacket(packet, ThrottleOutPacketType.Task, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (terseUpdateBlocks.IsValueCreated)
|
||||||
|
{
|
||||||
|
List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
|
||||||
|
|
||||||
|
ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
|
||||||
|
packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
|
||||||
|
packet.RegionData.TimeDilation = timeDilation;
|
||||||
|
packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
|
||||||
|
|
||||||
|
for (int i = 0; i < blocks.Count; i++)
|
||||||
|
packet.ObjectData[i] = blocks[i];
|
||||||
|
|
||||||
|
OutPacket(packet, ThrottleOutPacketType.Task, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Packet Sending
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler)
|
public void ReprioritizeUpdates(UpdatePriorityHandler handler)
|
||||||
{
|
{
|
||||||
PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>.UpdatePriorityHandler terse_update_priority_handler =
|
//m_log.Debug("[CLIENT]: Reprioritizing prim updates for " + m_firstName + " " + m_lastName);
|
||||||
delegate(ref double priority, uint local_id)
|
|
||||||
{
|
PriorityQueue<double, EntityUpdate>.UpdatePriorityHandler update_priority_handler =
|
||||||
priority = handler(new UpdatePriorityData(priority, local_id));
|
|
||||||
return priority != double.NaN;
|
|
||||||
};
|
|
||||||
PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock>.UpdatePriorityHandler update_priority_handler =
|
|
||||||
delegate(ref double priority, uint local_id)
|
delegate(ref double priority, uint local_id)
|
||||||
{
|
{
|
||||||
priority = handler(new UpdatePriorityData(priority, local_id));
|
priority = handler(new UpdatePriorityData(priority, local_id));
|
||||||
return priority != double.NaN;
|
return priority != double.NaN;
|
||||||
};
|
};
|
||||||
|
|
||||||
if ((type & StateUpdateTypes.AvatarTerse) != 0)
|
lock (m_entityUpdates.SyncRoot)
|
||||||
{
|
m_entityUpdates.Reprioritize(update_priority_handler);
|
||||||
lock (m_avatarTerseUpdates.SyncRoot)
|
|
||||||
m_avatarTerseUpdates.Reprioritize(terse_update_priority_handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((type & StateUpdateTypes.PrimitiveFull) != 0)
|
|
||||||
{
|
|
||||||
lock (m_primFullUpdates.SyncRoot)
|
|
||||||
m_primFullUpdates.Reprioritize(update_priority_handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((type & StateUpdateTypes.PrimitiveTerse) != 0)
|
|
||||||
{
|
|
||||||
lock (m_primTerseUpdates.SyncRoot)
|
|
||||||
m_primTerseUpdates.Reprioritize(terse_update_priority_handler);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void FlushPrimUpdates()
|
public void FlushPrimUpdates()
|
||||||
{
|
{
|
||||||
while (m_primFullUpdates.Count > 0)
|
m_log.Debug("[CLIENT]: Flushing prim updates to " + m_firstName + " " + m_lastName);
|
||||||
{
|
|
||||||
ProcessPrimFullUpdates();
|
while (m_entityUpdates.Count > 0)
|
||||||
}
|
ProcessEntityUpdates(-1);
|
||||||
while (m_primTerseUpdates.Count > 0)
|
|
||||||
{
|
|
||||||
ProcessPrimTerseUpdates();
|
|
||||||
}
|
|
||||||
while (m_avatarTerseUpdates.Count > 0)
|
|
||||||
{
|
|
||||||
ProcessAvatarTerseUpdates();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion Primitive Packet/Data Sending Methods
|
#endregion Primitive Packet/Data Sending Methods
|
||||||
|
@ -3726,26 +3664,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
if ((categories & ThrottleOutPacketTypeFlags.Task) != 0)
|
if ((categories & ThrottleOutPacketTypeFlags.Task) != 0)
|
||||||
{
|
{
|
||||||
lock (m_avatarTerseUpdates.SyncRoot)
|
if (m_entityUpdates.Count > 0)
|
||||||
{
|
ProcessEntityUpdates(m_udpServer.PrimUpdatesPerCallback);
|
||||||
if (m_avatarTerseUpdates.Count > 0)
|
|
||||||
ProcessAvatarTerseUpdates();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((categories & ThrottleOutPacketTypeFlags.State) != 0)
|
|
||||||
{
|
|
||||||
lock (m_primFullUpdates.SyncRoot)
|
|
||||||
{
|
|
||||||
if (m_primFullUpdates.Count > 0)
|
|
||||||
ProcessPrimFullUpdates();
|
|
||||||
}
|
|
||||||
|
|
||||||
lock (m_primTerseUpdates.SyncRoot)
|
|
||||||
{
|
|
||||||
if (m_primTerseUpdates.Count > 0)
|
|
||||||
ProcessPrimTerseUpdates();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0)
|
if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0)
|
||||||
|
@ -4403,22 +4323,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
#region Helper Methods
|
#region Helper Methods
|
||||||
|
|
||||||
protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(SendAvatarTerseData data)
|
protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(ISceneEntity entity, bool sendTexture)
|
||||||
{
|
{
|
||||||
return CreateImprovedTerseBlock(true, data.LocalID, 0, data.CollisionPlane, data.Position, data.Velocity,
|
#region ScenePresence/SOP Handling
|
||||||
data.Acceleration, data.Rotation, Vector3.Zero, data.TextureEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(SendPrimitiveTerseData data)
|
bool avatar = (entity is ScenePresence);
|
||||||
{
|
uint localID = entity.LocalId;
|
||||||
return CreateImprovedTerseBlock(false, data.LocalID, data.AttachPoint, Vector4.Zero, data.Position, data.Velocity,
|
uint attachPoint;
|
||||||
data.Acceleration, data.Rotation, data.AngularVelocity, data.TextureEntry);
|
Vector4 collisionPlane;
|
||||||
}
|
Vector3 position, velocity, acceleration, angularVelocity;
|
||||||
|
Quaternion rotation;
|
||||||
|
byte[] textureEntry;
|
||||||
|
|
||||||
|
if (entity is ScenePresence)
|
||||||
|
{
|
||||||
|
ScenePresence presence = (ScenePresence)entity;
|
||||||
|
|
||||||
|
attachPoint = 0;
|
||||||
|
collisionPlane = presence.CollisionPlane;
|
||||||
|
position = presence.OffsetPosition;
|
||||||
|
velocity = presence.Velocity;
|
||||||
|
acceleration = Vector3.Zero;
|
||||||
|
angularVelocity = Vector3.Zero;
|
||||||
|
rotation = presence.Rotation;
|
||||||
|
|
||||||
|
if (sendTexture)
|
||||||
|
textureEntry = presence.Appearance.Texture.GetBytes();
|
||||||
|
else
|
||||||
|
textureEntry = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SceneObjectPart part = (SceneObjectPart)entity;
|
||||||
|
|
||||||
|
attachPoint = part.AttachmentPoint;
|
||||||
|
collisionPlane = Vector4.Zero;
|
||||||
|
position = part.RelativePosition;
|
||||||
|
velocity = part.Velocity;
|
||||||
|
acceleration = part.Acceleration;
|
||||||
|
angularVelocity = part.AngularVelocity;
|
||||||
|
rotation = part.RotationOffset;
|
||||||
|
|
||||||
|
if (sendTexture)
|
||||||
|
textureEntry = part.Shape.TextureEntry;
|
||||||
|
else
|
||||||
|
textureEntry = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion ScenePresence/SOP Handling
|
||||||
|
|
||||||
protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(bool avatar, uint localID, int attachPoint,
|
|
||||||
Vector4 collisionPlane, Vector3 position, Vector3 velocity, Vector3 acceleration, Quaternion rotation,
|
|
||||||
Vector3 angularVelocity, byte[] textureEntry)
|
|
||||||
{
|
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
byte[] data = new byte[(avatar ? 60 : 44)];
|
byte[] data = new byte[(avatar ? 60 : 44)];
|
||||||
|
|
||||||
|
@ -4490,12 +4443,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(SendAvatarData data)
|
protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data)
|
||||||
{
|
{
|
||||||
byte[] objectData = new byte[76];
|
byte[] objectData = new byte[76];
|
||||||
|
|
||||||
Vector4.UnitW.ToBytes(objectData, 0); // TODO: Collision plane support
|
data.CollisionPlane.ToBytes(objectData, 0);
|
||||||
data.Position.ToBytes(objectData, 16);
|
data.OffsetPosition.ToBytes(objectData, 16);
|
||||||
//data.Velocity.ToBytes(objectData, 28);
|
//data.Velocity.ToBytes(objectData, 28);
|
||||||
//data.Acceleration.ToBytes(objectData, 40);
|
//data.Acceleration.ToBytes(objectData, 40);
|
||||||
data.Rotation.ToBytes(objectData, 52);
|
data.Rotation.ToBytes(objectData, 52);
|
||||||
|
@ -4505,12 +4458,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
update.Data = Utils.EmptyBytes;
|
update.Data = Utils.EmptyBytes;
|
||||||
update.ExtraParams = new byte[1];
|
update.ExtraParams = new byte[1];
|
||||||
update.FullID = data.AvatarID;
|
update.FullID = data.UUID;
|
||||||
update.ID = data.AvatarLocalID;
|
update.ID = data.LocalId;
|
||||||
update.Material = (byte)Material.Flesh;
|
update.Material = (byte)Material.Flesh;
|
||||||
update.MediaURL = Utils.EmptyBytes;
|
update.MediaURL = Utils.EmptyBytes;
|
||||||
update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.FirstName + "\nLastName STRING RW SV " +
|
update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " +
|
||||||
data.LastName + "\nTitle STRING RW SV " + data.GroupTitle);
|
data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle);
|
||||||
update.ObjectData = objectData;
|
update.ObjectData = objectData;
|
||||||
update.ParentID = data.ParentID;
|
update.ParentID = data.ParentID;
|
||||||
update.PathCurve = 16;
|
update.PathCurve = 16;
|
||||||
|
@ -4519,102 +4472,116 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
update.PCode = (byte)PCode.Avatar;
|
update.PCode = (byte)PCode.Avatar;
|
||||||
update.ProfileCurve = 1;
|
update.ProfileCurve = 1;
|
||||||
update.PSBlock = Utils.EmptyBytes;
|
update.PSBlock = Utils.EmptyBytes;
|
||||||
update.Scale = new Vector3(0.45f,0.6f,1.9f);
|
update.Scale = new Vector3(0.45f, 0.6f, 1.9f);
|
||||||
update.Text = Utils.EmptyBytes;
|
update.Text = Utils.EmptyBytes;
|
||||||
update.TextColor = new byte[4];
|
update.TextColor = new byte[4];
|
||||||
update.TextureAnim = Utils.EmptyBytes;
|
update.TextureAnim = Utils.EmptyBytes;
|
||||||
update.TextureEntry = data.TextureEntry ?? Utils.EmptyBytes;
|
update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes;
|
||||||
update.UpdateFlags = (uint)(PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner | PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer | PrimFlags.ObjectOwnerModify);//61 + (9 << 8) + (130 << 16) + (16 << 24); // TODO: Replace these numbers with PrimFlags
|
update.UpdateFlags = (uint)(
|
||||||
|
PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner |
|
||||||
|
PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer |
|
||||||
|
PrimFlags.ObjectOwnerModify);
|
||||||
|
|
||||||
return update;
|
return update;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SendPrimitiveData data)
|
protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart data, UUID recipientID)
|
||||||
{
|
{
|
||||||
byte[] objectData = new byte[60];
|
byte[] objectData = new byte[60];
|
||||||
data.pos.ToBytes(objectData, 0);
|
data.RelativePosition.ToBytes(objectData, 0);
|
||||||
data.vel.ToBytes(objectData, 12);
|
data.Velocity.ToBytes(objectData, 12);
|
||||||
data.acc.ToBytes(objectData, 24);
|
data.Acceleration.ToBytes(objectData, 24);
|
||||||
data.rotation.ToBytes(objectData, 36);
|
data.RotationOffset.ToBytes(objectData, 36);
|
||||||
data.rvel.ToBytes(objectData, 48);
|
data.AngularVelocity.ToBytes(objectData, 48);
|
||||||
|
|
||||||
ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
|
ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
|
||||||
update.ClickAction = (byte)data.clickAction;
|
update.ClickAction = (byte)data.ClickAction;
|
||||||
update.CRC = 0;
|
update.CRC = 0;
|
||||||
update.ExtraParams = data.primShape.ExtraParams ?? Utils.EmptyBytes;
|
update.ExtraParams = data.Shape.ExtraParams ?? Utils.EmptyBytes;
|
||||||
update.FullID = data.objectID;
|
update.FullID = data.UUID;
|
||||||
update.ID = data.localID;
|
update.ID = data.LocalId;
|
||||||
//update.JointAxisOrAnchor = Vector3.Zero; // These are deprecated
|
//update.JointAxisOrAnchor = Vector3.Zero; // These are deprecated
|
||||||
//update.JointPivot = Vector3.Zero;
|
//update.JointPivot = Vector3.Zero;
|
||||||
//update.JointType = 0;
|
//update.JointType = 0;
|
||||||
update.Material = data.material;
|
update.Material = data.Material;
|
||||||
update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim
|
update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim
|
||||||
if (data.attachment)
|
if (data.IsAttachment)
|
||||||
{
|
{
|
||||||
update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.AssetId);
|
update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.FromItemID);
|
||||||
update.State = (byte)((data.AttachPoint % 16) * 16 + (data.AttachPoint / 16));
|
update.State = (byte)((data.AttachmentPoint % 16) * 16 + (data.AttachmentPoint / 16));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
update.NameValue = Utils.EmptyBytes;
|
update.NameValue = Utils.EmptyBytes;
|
||||||
update.State = data.primShape.State;
|
update.State = data.Shape.State;
|
||||||
}
|
}
|
||||||
update.ObjectData = objectData;
|
|
||||||
update.ParentID = data.parentID;
|
|
||||||
update.PathBegin = data.primShape.PathBegin;
|
|
||||||
update.PathCurve = data.primShape.PathCurve;
|
|
||||||
update.PathEnd = data.primShape.PathEnd;
|
|
||||||
update.PathRadiusOffset = data.primShape.PathRadiusOffset;
|
|
||||||
update.PathRevolutions = data.primShape.PathRevolutions;
|
|
||||||
update.PathScaleX = data.primShape.PathScaleX;
|
|
||||||
update.PathScaleY = data.primShape.PathScaleY;
|
|
||||||
update.PathShearX = data.primShape.PathShearX;
|
|
||||||
update.PathShearY = data.primShape.PathShearY;
|
|
||||||
update.PathSkew = data.primShape.PathSkew;
|
|
||||||
update.PathTaperX = data.primShape.PathTaperX;
|
|
||||||
update.PathTaperY = data.primShape.PathTaperY;
|
|
||||||
update.PathTwist = data.primShape.PathTwist;
|
|
||||||
update.PathTwistBegin = data.primShape.PathTwistBegin;
|
|
||||||
update.PCode = data.primShape.PCode;
|
|
||||||
update.ProfileBegin = data.primShape.ProfileBegin;
|
|
||||||
update.ProfileCurve = data.primShape.ProfileCurve;
|
|
||||||
update.ProfileEnd = data.primShape.ProfileEnd;
|
|
||||||
update.ProfileHollow = data.primShape.ProfileHollow;
|
|
||||||
update.PSBlock = data.particleSystem ?? Utils.EmptyBytes;
|
|
||||||
update.TextColor = data.color ?? Color4.Black.GetBytes(true);
|
|
||||||
update.TextureAnim = data.textureanim ?? Utils.EmptyBytes;
|
|
||||||
update.TextureEntry = data.primShape.TextureEntry ?? Utils.EmptyBytes;
|
|
||||||
update.Scale = data.primShape.Scale;
|
|
||||||
update.Text = Util.StringToBytes256(data.text);
|
|
||||||
update.UpdateFlags = (uint)data.flags;
|
|
||||||
|
|
||||||
if (data.SoundId != UUID.Zero)
|
update.ObjectData = objectData;
|
||||||
|
update.ParentID = data.ParentID;
|
||||||
|
update.PathBegin = data.Shape.PathBegin;
|
||||||
|
update.PathCurve = data.Shape.PathCurve;
|
||||||
|
update.PathEnd = data.Shape.PathEnd;
|
||||||
|
update.PathRadiusOffset = data.Shape.PathRadiusOffset;
|
||||||
|
update.PathRevolutions = data.Shape.PathRevolutions;
|
||||||
|
update.PathScaleX = data.Shape.PathScaleX;
|
||||||
|
update.PathScaleY = data.Shape.PathScaleY;
|
||||||
|
update.PathShearX = data.Shape.PathShearX;
|
||||||
|
update.PathShearY = data.Shape.PathShearY;
|
||||||
|
update.PathSkew = data.Shape.PathSkew;
|
||||||
|
update.PathTaperX = data.Shape.PathTaperX;
|
||||||
|
update.PathTaperY = data.Shape.PathTaperY;
|
||||||
|
update.PathTwist = data.Shape.PathTwist;
|
||||||
|
update.PathTwistBegin = data.Shape.PathTwistBegin;
|
||||||
|
update.PCode = data.Shape.PCode;
|
||||||
|
update.ProfileBegin = data.Shape.ProfileBegin;
|
||||||
|
update.ProfileCurve = data.Shape.ProfileCurve;
|
||||||
|
update.ProfileEnd = data.Shape.ProfileEnd;
|
||||||
|
update.ProfileHollow = data.Shape.ProfileHollow;
|
||||||
|
update.PSBlock = data.ParticleSystem ?? Utils.EmptyBytes;
|
||||||
|
update.TextColor = data.GetTextColor().GetBytes(false);
|
||||||
|
update.TextureAnim = data.TextureAnimation ?? Utils.EmptyBytes;
|
||||||
|
update.TextureEntry = data.Shape.TextureEntry ?? Utils.EmptyBytes;
|
||||||
|
update.Scale = data.Shape.Scale;
|
||||||
|
update.Text = Util.StringToBytes256(data.Text);
|
||||||
|
|
||||||
|
#region PrimFlags
|
||||||
|
|
||||||
|
PrimFlags flags = (PrimFlags)m_scene.Permissions.GenerateClientFlags(recipientID, data.UUID);
|
||||||
|
|
||||||
|
// Don't send the CreateSelected flag to everyone
|
||||||
|
flags &= ~PrimFlags.CreateSelected;
|
||||||
|
|
||||||
|
if (recipientID == data.OwnerID)
|
||||||
{
|
{
|
||||||
update.Sound = data.SoundId;
|
if ((data.Flags & PrimFlags.CreateSelected) != 0)
|
||||||
update.OwnerID = data.ownerID;
|
{
|
||||||
update.Gain = (float)data.SoundVolume;
|
// Only send this flag once, then unset it
|
||||||
|
flags |= PrimFlags.CreateSelected;
|
||||||
|
data.Flags &= ~PrimFlags.CreateSelected;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
update.UpdateFlags = (uint)flags;
|
||||||
|
|
||||||
|
#endregion PrimFlags
|
||||||
|
|
||||||
|
if (data.Sound != UUID.Zero)
|
||||||
|
{
|
||||||
|
update.Sound = data.Sound;
|
||||||
|
update.OwnerID = data.OwnerID;
|
||||||
|
update.Gain = (float)data.SoundGain;
|
||||||
update.Radius = (float)data.SoundRadius;
|
update.Radius = (float)data.SoundRadius;
|
||||||
update.Flags = data.SoundFlags;
|
update.Flags = data.SoundFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ((PCode)data.primShape.PCode)
|
switch ((PCode)data.Shape.PCode)
|
||||||
{
|
{
|
||||||
case PCode.Grass:
|
case PCode.Grass:
|
||||||
case PCode.Tree:
|
case PCode.Tree:
|
||||||
case PCode.NewTree:
|
case PCode.NewTree:
|
||||||
update.Data = new byte[] { data.primShape.State };
|
update.Data = new byte[] { data.Shape.State };
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// TODO: Support ScratchPad
|
|
||||||
//if (prim.ScratchPad != null)
|
|
||||||
//{
|
|
||||||
// update.Data = new byte[prim.ScratchPad.Length];
|
|
||||||
// Buffer.BlockCopy(prim.ScratchPad, 0, update.Data, 0, update.Data.Length);
|
|
||||||
//}
|
|
||||||
//else
|
|
||||||
//{
|
|
||||||
// update.Data = Utils.EmptyBytes;
|
|
||||||
//}
|
|
||||||
update.Data = Utils.EmptyBytes;
|
update.Data = Utils.EmptyBytes;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -4622,6 +4589,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
return update;
|
return update;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected ObjectUpdateCompressedPacket.ObjectDataBlock CreateCompressedUpdateBlock(SceneObjectPart part, PrimUpdateFlags updateFlags)
|
||||||
|
{
|
||||||
|
// TODO: Implement this
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public void SendNameReply(UUID profileId, string firstname, string lastname)
|
public void SendNameReply(UUID profileId, string firstname, string lastname)
|
||||||
{
|
{
|
||||||
UUIDNameReplyPacket packet = (UUIDNameReplyPacket)PacketPool.Instance.GetPacket(PacketType.UUIDNameReply);
|
UUIDNameReplyPacket packet = (UUIDNameReplyPacket)PacketPool.Instance.GetPacket(PacketType.UUIDNameReply);
|
||||||
|
@ -11644,7 +11617,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString()));
|
throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
internal TValue Dequeue()
|
internal bool TryDequeue(out TValue value)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < m_heaps.Length; ++i)
|
for (int i = 0; i < m_heaps.Length; ++i)
|
||||||
{
|
{
|
||||||
|
@ -11652,10 +11625,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
MinHeapItem item = m_heaps[i].RemoveMin();
|
MinHeapItem item = m_heaps[i].RemoveMin();
|
||||||
m_lookupTable.Remove(item.LocalID);
|
m_lookupTable.Remove(item.LocalID);
|
||||||
return item.Value;
|
value = item.Value;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString()));
|
|
||||||
|
value = default(TValue);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Reprioritize(UpdatePriorityHandler handler)
|
internal void Reprioritize(UpdatePriorityHandler handler)
|
||||||
|
|
|
@ -99,15 +99,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
/// <summary>The measured resolution of Environment.TickCount</summary>
|
/// <summary>The measured resolution of Environment.TickCount</summary>
|
||||||
public readonly float TickCountResolution;
|
public readonly float TickCountResolution;
|
||||||
/// <summary>Number of terse prim updates to put on the queue each time the
|
/// <summary>Number of prim updates to put on the queue each time the
|
||||||
/// OnQueueEmpty event is triggered for updates</summary>
|
/// OnQueueEmpty event is triggered for updates</summary>
|
||||||
public readonly int PrimTerseUpdatesPerPacket;
|
public readonly int PrimUpdatesPerCallback;
|
||||||
/// <summary>Number of terse avatar updates to put on the queue each time the
|
|
||||||
/// OnQueueEmpty event is triggered for updates</summary>
|
|
||||||
public readonly int AvatarTerseUpdatesPerPacket;
|
|
||||||
/// <summary>Number of full prim updates to put on the queue each time the
|
|
||||||
/// OnQueueEmpty event is triggered for updates</summary>
|
|
||||||
public readonly int PrimFullUpdatesPerPacket;
|
|
||||||
/// <summary>Number of texture packets to put on the queue each time the
|
/// <summary>Number of texture packets to put on the queue each time the
|
||||||
/// OnQueueEmpty event is triggered for textures</summary>
|
/// OnQueueEmpty event is triggered for textures</summary>
|
||||||
public readonly int TextureSendLimit;
|
public readonly int TextureSendLimit;
|
||||||
|
@ -191,9 +185,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
m_recvBufferSize = config.GetInt("client_socket_rcvbuf_size", 0);
|
m_recvBufferSize = config.GetInt("client_socket_rcvbuf_size", 0);
|
||||||
sceneThrottleBps = config.GetInt("scene_throttle_max_bps", 0);
|
sceneThrottleBps = config.GetInt("scene_throttle_max_bps", 0);
|
||||||
|
|
||||||
PrimTerseUpdatesPerPacket = config.GetInt("PrimTerseUpdatesPerPacket", 25);
|
PrimUpdatesPerCallback = config.GetInt("PrimUpdatesPerCallback", 100);
|
||||||
AvatarTerseUpdatesPerPacket = config.GetInt("AvatarTerseUpdatesPerPacket", 10);
|
|
||||||
PrimFullUpdatesPerPacket = config.GetInt("PrimFullUpdatesPerPacket", 100);
|
|
||||||
TextureSendLimit = config.GetInt("TextureSendLimit", 20);
|
TextureSendLimit = config.GetInt("TextureSendLimit", 20);
|
||||||
|
|
||||||
m_defaultRTO = config.GetInt("DefaultRTO", 0);
|
m_defaultRTO = config.GetInt("DefaultRTO", 0);
|
||||||
|
@ -201,9 +193,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PrimTerseUpdatesPerPacket = 25;
|
PrimUpdatesPerCallback = 100;
|
||||||
AvatarTerseUpdatesPerPacket = 10;
|
|
||||||
PrimFullUpdatesPerPacket = 100;
|
|
||||||
TextureSendLimit = 20;
|
TextureSendLimit = 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.GridUser
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[ACTIVITY DETECTOR]: Detected root presence {0} in {1}", sp.UUID, sp.Scene.RegionInfo.RegionName);
|
m_log.DebugFormat("[ACTIVITY DETECTOR]: Detected root presence {0} in {1}", sp.UUID, sp.Scene.RegionInfo.RegionName);
|
||||||
|
|
||||||
m_GridUserService.SetLastPosition(sp.UUID.ToString(), sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat);
|
m_GridUserService.SetLastPosition(sp.UUID.ToString(), sp.ControllingClient.SessionId, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnNewClient(IClientAPI client)
|
public void OnNewClient(IClientAPI client)
|
||||||
|
@ -109,7 +109,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.GridUser
|
||||||
{
|
{
|
||||||
// TODO: grab the parcel ID from ILandModule
|
// TODO: grab the parcel ID from ILandModule
|
||||||
// and send that along
|
// and send that along
|
||||||
m_GridUserService.SetLastPosition(sp.UUID.ToString(), sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat);
|
m_GridUserService.SetLastPosition(sp.UUID.ToString(), sp.ControllingClient.SessionId, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -162,9 +162,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.GridUser
|
||||||
return m_GridUserService.SetHome(userID, homeID, homePosition, homeLookAt);
|
return m_GridUserService.SetHome(userID, homeID, homePosition, homeLookAt);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool SetLastPosition(string userID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt)
|
public bool SetLastPosition(string userID, UUID sessionID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt)
|
||||||
{
|
{
|
||||||
return m_GridUserService.SetLastPosition(userID, regionID, lastPosition, lastLookAt);
|
return m_GridUserService.SetLastPosition(userID, sessionID, regionID, lastPosition, lastLookAt);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GridUserInfo GetGridUserInfo(string userID)
|
public GridUserInfo GetGridUserInfo(string userID)
|
||||||
|
|
|
@ -137,9 +137,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.GridUser
|
||||||
return m_RemoteConnector.SetHome(userID, regionID, position, lookAt);
|
return m_RemoteConnector.SetHome(userID, regionID, position, lookAt);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool SetLastPosition(string userID, UUID regionID, Vector3 position, Vector3 lookAt)
|
public bool SetLastPosition(string userID, UUID sessionID, UUID regionID, Vector3 position, Vector3 lookAt)
|
||||||
{
|
{
|
||||||
return m_RemoteConnector.SetLastPosition(userID, regionID, position, lookAt);
|
return m_RemoteConnector.SetLastPosition(userID, sessionID, regionID, position, lookAt);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GridUserInfo GetGridUserInfo(string userID)
|
public GridUserInfo GetGridUserInfo(string userID)
|
||||||
|
|
|
@ -154,6 +154,22 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||||
m_landManagementModule.UpdateLandObject(localID, data);
|
m_landManagementModule.UpdateLandObject(localID, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id)
|
||||||
|
{
|
||||||
|
if (m_landManagementModule != null)
|
||||||
|
{
|
||||||
|
m_landManagementModule.Join(start_x, start_y, end_x, end_y, attempting_user_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Subdivide(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id)
|
||||||
|
{
|
||||||
|
if (m_landManagementModule != null)
|
||||||
|
{
|
||||||
|
m_landManagementModule.Subdivide(start_x, start_y, end_x, end_y, attempting_user_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient)
|
public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient)
|
||||||
{
|
{
|
||||||
|
|
|
@ -948,6 +948,16 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||||
masterLandObject.SendLandUpdateToAvatarsOverMe();
|
masterLandObject.SendLandUpdateToAvatarsOverMe();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id)
|
||||||
|
{
|
||||||
|
join(start_x, start_y, end_x, end_y, attempting_user_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Subdivide(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id)
|
||||||
|
{
|
||||||
|
subdivide(start_x, start_y, end_x, end_y, attempting_user_id);
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Parcel Updating
|
#region Parcel Updating
|
||||||
|
|
|
@ -528,14 +528,6 @@ namespace OpenSim.Region.Examples.SimpleModule
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void SendAvatarData(SendAvatarData data)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void SendAvatarTerseUpdate(SendAvatarTerseData data)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
|
public virtual void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -548,15 +540,15 @@ namespace OpenSim.Region.Examples.SimpleModule
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void SendPrimitiveToClient(SendPrimitiveData data)
|
public void SendAvatarDataImmediate(ISceneEntity avatar)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void SendPrimTerseUpdate(SendPrimitiveTerseData data)
|
public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler)
|
public void ReprioritizeUpdates(UpdatePriorityHandler handler)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,5 +76,8 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||||
void setParcelObjectMaxOverride(overrideParcelMaxPrimCountDelegate overrideDel);
|
void setParcelObjectMaxOverride(overrideParcelMaxPrimCountDelegate overrideDel);
|
||||||
void setSimulatorObjectMaxOverride(overrideSimulatorMaxPrimCountDelegate overrideDel);
|
void setSimulatorObjectMaxOverride(overrideSimulatorMaxPrimCountDelegate overrideDel);
|
||||||
void SetParcelOtherCleanTime(IClientAPI remoteClient, int localID, int otherCleanTime);
|
void SetParcelOtherCleanTime(IClientAPI remoteClient, int localID, int otherCleanTime);
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,8 +68,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
#region Fields
|
#region Fields
|
||||||
|
|
||||||
protected Dictionary<UUID, ScenePresence> m_scenePresences = new Dictionary<UUID, ScenePresence>();
|
protected object m_presenceLock = new object();
|
||||||
protected ScenePresence[] m_scenePresenceArray = new ScenePresence[0];
|
protected Dictionary<UUID, ScenePresence> m_scenePresenceMap = new Dictionary<UUID, ScenePresence>();
|
||||||
|
protected List<ScenePresence> m_scenePresenceArray = new List<ScenePresence>();
|
||||||
|
|
||||||
// SceneObjects is not currently populated or used.
|
// SceneObjects is not currently populated or used.
|
||||||
//public Dictionary<UUID, SceneObjectGroup> SceneObjects;
|
//public Dictionary<UUID, SceneObjectGroup> SceneObjects;
|
||||||
|
@ -132,10 +133,12 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
protected internal void Close()
|
protected internal void Close()
|
||||||
{
|
{
|
||||||
lock (m_scenePresences)
|
lock (m_presenceLock)
|
||||||
{
|
{
|
||||||
m_scenePresences.Clear();
|
Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>();
|
||||||
m_scenePresenceArray = new ScenePresence[0];
|
List<ScenePresence> newlist = new List<ScenePresence>();
|
||||||
|
m_scenePresenceMap = newmap;
|
||||||
|
m_scenePresenceArray = newlist;
|
||||||
}
|
}
|
||||||
|
|
||||||
lock (m_dictionary_lock)
|
lock (m_dictionary_lock)
|
||||||
|
@ -518,34 +521,29 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
Entities[presence.UUID] = presence;
|
Entities[presence.UUID] = presence;
|
||||||
|
|
||||||
lock (m_scenePresences)
|
lock (m_presenceLock)
|
||||||
{
|
{
|
||||||
if (!m_scenePresences.ContainsKey(presence.UUID))
|
Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap);
|
||||||
{
|
List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray);
|
||||||
m_scenePresences.Add(presence.UUID, presence);
|
|
||||||
|
|
||||||
// Create a new array of ScenePresence references
|
if (!newmap.ContainsKey(presence.UUID))
|
||||||
int oldLength = m_scenePresenceArray.Length;
|
{
|
||||||
ScenePresence[] newArray = new ScenePresence[oldLength + 1];
|
newmap.Add(presence.UUID, presence);
|
||||||
Array.Copy(m_scenePresenceArray, newArray, oldLength);
|
newlist.Add(presence);
|
||||||
newArray[oldLength] = presence;
|
|
||||||
m_scenePresenceArray = newArray;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_scenePresences[presence.UUID] = presence;
|
// Remember the old presene reference from the dictionary
|
||||||
|
ScenePresence oldref = newmap[presence.UUID];
|
||||||
// Do a linear search through the array of ScenePresence references
|
// Replace the presence reference in the dictionary with the new value
|
||||||
// and update the modified entry
|
newmap[presence.UUID] = presence;
|
||||||
for (int i = 0; i < m_scenePresenceArray.Length; i++)
|
// Find the index in the list where the old ref was stored and update the reference
|
||||||
{
|
newlist[newlist.IndexOf(oldref)] = presence;
|
||||||
if (m_scenePresenceArray[i].UUID == presence.UUID)
|
|
||||||
{
|
|
||||||
m_scenePresenceArray[i] = presence;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Swap out the dictionary and list with new references
|
||||||
|
m_scenePresenceMap = newmap;
|
||||||
|
m_scenePresenceArray = newlist;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -561,25 +559,21 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
agentID);
|
agentID);
|
||||||
}
|
}
|
||||||
|
|
||||||
lock (m_scenePresences)
|
lock (m_presenceLock)
|
||||||
{
|
{
|
||||||
if (m_scenePresences.Remove(agentID))
|
Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap);
|
||||||
|
List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray);
|
||||||
|
|
||||||
|
// Remember the old presene reference from the dictionary
|
||||||
|
ScenePresence oldref = newmap[agentID];
|
||||||
|
// Remove the presence reference from the dictionary
|
||||||
|
if (newmap.Remove(agentID))
|
||||||
{
|
{
|
||||||
// Copy all of the elements from the previous array
|
// Find the index in the list where the old ref was stored and remove the reference
|
||||||
// into the new array except the removed element
|
newlist.RemoveAt(newlist.IndexOf(oldref));
|
||||||
int oldLength = m_scenePresenceArray.Length;
|
// Swap out the dictionary and list with new references
|
||||||
ScenePresence[] newArray = new ScenePresence[oldLength - 1];
|
m_scenePresenceMap = newmap;
|
||||||
int j = 0;
|
m_scenePresenceArray = newlist;
|
||||||
for (int i = 0; i < m_scenePresenceArray.Length; i++)
|
|
||||||
{
|
|
||||||
ScenePresence presence = m_scenePresenceArray[i];
|
|
||||||
if (presence.UUID != agentID)
|
|
||||||
{
|
|
||||||
newArray[j] = presence;
|
|
||||||
++j;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_scenePresenceArray = newArray;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -698,7 +692,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Request a copy of m_scenePresences in this World
|
/// Get a reference to the scene presence list. Changes to the list will be done in a copy
|
||||||
/// There is no guarantee that presences will remain in the scene after the list is returned.
|
/// There is no guarantee that presences will remain in the scene after the list is returned.
|
||||||
/// This list should remain private to SceneGraph. Callers wishing to iterate should instead
|
/// This list should remain private to SceneGraph. Callers wishing to iterate should instead
|
||||||
/// pass a delegate to ForEachScenePresence.
|
/// pass a delegate to ForEachScenePresence.
|
||||||
|
@ -706,8 +700,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private List<ScenePresence> GetScenePresences()
|
private List<ScenePresence> GetScenePresences()
|
||||||
{
|
{
|
||||||
lock (m_scenePresences)
|
return m_scenePresenceArray;
|
||||||
return new List<ScenePresence>(m_scenePresenceArray);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -717,12 +710,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// <returns>null if the presence was not found</returns>
|
/// <returns>null if the presence was not found</returns>
|
||||||
protected internal ScenePresence GetScenePresence(UUID agentID)
|
protected internal ScenePresence GetScenePresence(UUID agentID)
|
||||||
{
|
{
|
||||||
ScenePresence sp;
|
Dictionary<UUID, ScenePresence> presences = m_scenePresenceMap;
|
||||||
lock (m_scenePresences)
|
ScenePresence presence;
|
||||||
{
|
presences.TryGetValue(agentID, out presence);
|
||||||
m_scenePresences.TryGetValue(agentID, out sp);
|
return presence;
|
||||||
}
|
|
||||||
return sp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -733,7 +724,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// <returns>null if the presence was not found</returns>
|
/// <returns>null if the presence was not found</returns>
|
||||||
protected internal ScenePresence GetScenePresence(string firstName, string lastName)
|
protected internal ScenePresence GetScenePresence(string firstName, string lastName)
|
||||||
{
|
{
|
||||||
foreach (ScenePresence presence in GetScenePresences())
|
List<ScenePresence> presences = GetScenePresences();
|
||||||
|
foreach (ScenePresence presence in presences)
|
||||||
{
|
{
|
||||||
if (presence.Firstname == firstName && presence.Lastname == lastName)
|
if (presence.Firstname == firstName && presence.Lastname == lastName)
|
||||||
return presence;
|
return presence;
|
||||||
|
@ -748,7 +740,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// <returns>null if the presence was not found</returns>
|
/// <returns>null if the presence was not found</returns>
|
||||||
protected internal ScenePresence GetScenePresence(uint localID)
|
protected internal ScenePresence GetScenePresence(uint localID)
|
||||||
{
|
{
|
||||||
foreach (ScenePresence presence in GetScenePresences())
|
List<ScenePresence> presences = GetScenePresences();
|
||||||
|
foreach (ScenePresence presence in presences)
|
||||||
if (presence.LocalId == localID)
|
if (presence.LocalId == localID)
|
||||||
return presence;
|
return presence;
|
||||||
return null;
|
return null;
|
||||||
|
@ -756,10 +749,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
protected internal bool TryGetScenePresence(UUID agentID, out ScenePresence avatar)
|
protected internal bool TryGetScenePresence(UUID agentID, out ScenePresence avatar)
|
||||||
{
|
{
|
||||||
lock (m_scenePresences)
|
Dictionary<UUID, ScenePresence> presences = m_scenePresenceMap;
|
||||||
{
|
presences.TryGetValue(agentID, out avatar);
|
||||||
m_scenePresences.TryGetValue(agentID, out avatar);
|
|
||||||
}
|
|
||||||
return (avatar != null);
|
return (avatar != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1036,8 +1027,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
});
|
});
|
||||||
Parallel.ForEach<ScenePresence>(GetScenePresences(), protectedAction);
|
Parallel.ForEach<ScenePresence>(GetScenePresences(), protectedAction);
|
||||||
*/
|
*/
|
||||||
// For now, perform actiona serially
|
// For now, perform actions serially
|
||||||
foreach (ScenePresence sp in GetScenePresences())
|
List<ScenePresence> presences = GetScenePresences();
|
||||||
|
foreach (ScenePresence sp in presences)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
|
@ -104,7 +104,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
#endregion Enumerations
|
#endregion Enumerations
|
||||||
|
|
||||||
public class SceneObjectPart : IScriptHost
|
public class SceneObjectPart : IScriptHost, ISceneEntity
|
||||||
{
|
{
|
||||||
/// <value>
|
/// <value>
|
||||||
/// Denote all sides of the prim
|
/// Denote all sides of the prim
|
||||||
|
@ -712,6 +712,24 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Vector3 RelativePosition
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (IsRoot)
|
||||||
|
{
|
||||||
|
if (IsAttachment)
|
||||||
|
return AttachedPos;
|
||||||
|
else
|
||||||
|
return AbsolutePosition;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return OffsetPosition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Quaternion RotationOffset
|
public Quaternion RotationOffset
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
@ -973,7 +991,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
get { return AggregateScriptEvents; }
|
get { return AggregateScriptEvents; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Quaternion SitTargetOrientation
|
public Quaternion SitTargetOrientation
|
||||||
{
|
{
|
||||||
get { return m_sitTargetOrientation; }
|
get { return m_sitTargetOrientation; }
|
||||||
|
@ -2925,11 +2942,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
//if (LocalId != ParentGroup.RootPart.LocalId)
|
//if (LocalId != ParentGroup.RootPart.LocalId)
|
||||||
//isattachment = ParentGroup.RootPart.IsAttachment;
|
//isattachment = ParentGroup.RootPart.IsAttachment;
|
||||||
|
|
||||||
byte[] color = new byte[] {m_color.R, m_color.G, m_color.B, m_color.A};
|
remoteClient.SendPrimUpdate(this, PrimUpdateFlags.FullUpdate);
|
||||||
remoteClient.SendPrimitiveToClient(new SendPrimitiveData(m_regionHandle, m_parentGroup.GetTimeDilation(), LocalId, m_shape,
|
|
||||||
lPos, Velocity, Acceleration, RotationOffset, AngularVelocity, clientFlags, m_uuid, _ownerID,
|
|
||||||
m_text, color, _parentID, m_particleSystem, m_clickAction, (byte)m_material, m_TextureAnimation, IsAttachment,
|
|
||||||
AttachmentPoint,FromItemID, Sound, SoundGain, SoundFlags, SoundRadius, ParentGroup.GetUpdatePriority(remoteClient)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -4640,11 +4653,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
// Causes this thread to dig into the Client Thread Data.
|
// Causes this thread to dig into the Client Thread Data.
|
||||||
// Remember your locking here!
|
// Remember your locking here!
|
||||||
remoteClient.SendPrimTerseUpdate(new SendPrimitiveTerseData(m_regionHandle,
|
remoteClient.SendPrimUpdate(this, PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity);
|
||||||
m_parentGroup.GetTimeDilation(), LocalId, lPos,
|
|
||||||
RotationOffset, Velocity, Acceleration,
|
|
||||||
AngularVelocity, FromItemID,
|
|
||||||
OwnerID, (int)AttachmentPoint, null, ParentGroup.GetUpdatePriority(remoteClient)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddScriptLPS(int count)
|
public void AddScriptLPS(int count)
|
||||||
|
@ -4694,7 +4703,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
public Color4 GetTextColor()
|
public Color4 GetTextColor()
|
||||||
{
|
{
|
||||||
return new Color4((byte)Color.R, (byte)Color.G, (byte)Color.B, (byte)(0xFF - Color.A));
|
Color color = Color;
|
||||||
|
return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
public delegate void SendCourseLocationsMethod(UUID scene, ScenePresence presence);
|
public delegate void SendCourseLocationsMethod(UUID scene, ScenePresence presence);
|
||||||
|
|
||||||
public class ScenePresence : EntityBase
|
public class ScenePresence : EntityBase, ISceneEntity
|
||||||
{
|
{
|
||||||
// ~ScenePresence()
|
// ~ScenePresence()
|
||||||
// {
|
// {
|
||||||
|
@ -478,6 +478,12 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Vector3 OffsetPosition
|
||||||
|
{
|
||||||
|
get { return m_pos; }
|
||||||
|
set { m_pos = value; }
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Current velocity of the avatar.
|
/// Current velocity of the avatar.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -1036,8 +1042,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f));
|
AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f));
|
||||||
}
|
}
|
||||||
|
|
||||||
ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId,
|
ControllingClient.SendPrimUpdate(this, PrimUpdateFlags.Position);
|
||||||
AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient)));
|
//ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId,
|
||||||
|
// AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddNeighbourRegion(ulong regionHandle, string cap)
|
public void AddNeighbourRegion(ulong regionHandle, string cap)
|
||||||
|
@ -2360,8 +2367,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
//m_log.DebugFormat("[SCENEPRESENCE]: TerseUpdate: Pos={0} Rot={1} Vel={2}", m_pos, m_bodyRot, m_velocity);
|
//m_log.DebugFormat("[SCENEPRESENCE]: TerseUpdate: Pos={0} Rot={1} Vel={2}", m_pos, m_bodyRot, m_velocity);
|
||||||
|
|
||||||
remoteClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId,
|
remoteClient.SendPrimUpdate(this, PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity);
|
||||||
pos, velocity, Vector3.Zero, m_bodyRot, CollisionPlane, m_uuid, null, GetUpdatePriority(remoteClient)));
|
|
||||||
|
|
||||||
m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
|
m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
|
||||||
m_scene.StatsReporter.AddAgentUpdates(1);
|
m_scene.StatsReporter.AddAgentUpdates(1);
|
||||||
|
@ -2457,9 +2463,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
Vector3 pos = m_pos;
|
Vector3 pos = m_pos;
|
||||||
pos.Z += m_appearance.HipOffset;
|
pos.Z += m_appearance.HipOffset;
|
||||||
|
|
||||||
remoteAvatar.m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid,
|
remoteAvatar.m_controllingClient.SendAvatarDataImmediate(this);
|
||||||
LocalId, pos, m_appearance.Texture.GetBytes(),
|
|
||||||
m_parentID, m_bodyRot));
|
|
||||||
m_scene.StatsReporter.AddAgentUpdates(1);
|
m_scene.StatsReporter.AddAgentUpdates(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2527,8 +2531,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
Vector3 pos = m_pos;
|
Vector3 pos = m_pos;
|
||||||
pos.Z += m_appearance.HipOffset;
|
pos.Z += m_appearance.HipOffset;
|
||||||
|
|
||||||
m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId,
|
m_controllingClient.SendAvatarDataImmediate(this);
|
||||||
pos, m_appearance.Texture.GetBytes(), m_parentID, m_bodyRot));
|
|
||||||
|
|
||||||
SendInitialFullUpdateToAllClients();
|
SendInitialFullUpdateToAllClients();
|
||||||
SendAppearanceToAllOtherAgents();
|
SendAppearanceToAllOtherAgents();
|
||||||
|
@ -2638,9 +2641,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
Vector3 pos = m_pos;
|
Vector3 pos = m_pos;
|
||||||
pos.Z += m_appearance.HipOffset;
|
pos.Z += m_appearance.HipOffset;
|
||||||
|
|
||||||
m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId,
|
m_controllingClient.SendAvatarDataImmediate(this);
|
||||||
pos, m_appearance.Texture.GetBytes(), m_parentID, m_bodyRot));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetWearable(int wearableId, AvatarWearable wearable)
|
public void SetWearable(int wearableId, AvatarWearable wearable)
|
||||||
|
@ -3906,7 +3907,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
private void Reprioritize(object sender, ElapsedEventArgs e)
|
private void Reprioritize(object sender, ElapsedEventArgs e)
|
||||||
{
|
{
|
||||||
m_controllingClient.ReprioritizeUpdates(StateUpdateTypes.All, UpdatePriority);
|
m_controllingClient.ReprioritizeUpdates(UpdatePriority);
|
||||||
|
|
||||||
lock (m_reprioritization_timer)
|
lock (m_reprioritization_timer)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1045,16 +1045,6 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendAvatarData(SendAvatarData data)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendAvatarTerseUpdate(SendAvatarTerseData data)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
|
public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -1065,22 +1055,22 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetChildAgentThrottle(byte[] throttle)
|
public void SendAvatarDataImmediate(ISceneEntity avatar)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendPrimitiveToClient(SendPrimitiveData data)
|
public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendPrimTerseUpdate(SendPrimitiveTerseData data)
|
public void ReprioritizeUpdates(UpdatePriorityHandler handler)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler)
|
public void FlushPrimUpdates()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1090,11 +1080,6 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void FlushPrimUpdates()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendInventoryItemDetails(UUID ownerID, InventoryItemBase item)
|
public void SendInventoryItemDetails(UUID ownerID, InventoryItemBase item)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -1420,6 +1405,11 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual void SetChildAgentThrottle(byte[] throttle)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public byte[] GetThrottlesPacked(float multiplier)
|
public byte[] GetThrottlesPacked(float multiplier)
|
||||||
{
|
{
|
||||||
return new byte[0];
|
return new byte[0];
|
||||||
|
|
|
@ -618,14 +618,6 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void SendAvatarData(SendAvatarData data)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void SendAvatarTerseUpdate(SendAvatarTerseData data)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
|
public virtual void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -638,15 +630,15 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void SendPrimitiveToClient(SendPrimitiveData data)
|
public void SendAvatarDataImmediate(ISceneEntity avatar)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void SendPrimTerseUpdate(SendPrimitiveTerseData data)
|
public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler)
|
public void ReprioritizeUpdates(UpdatePriorityHandler handler)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -140,6 +140,16 @@ public class RegionCombinerLargeLandChannel : ILandChannel
|
||||||
RootRegionLandChannel.UpdateLandObject(localID, data);
|
RootRegionLandChannel.UpdateLandObject(localID, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id)
|
||||||
|
{
|
||||||
|
RootRegionLandChannel.Join(start_x, start_y, end_x, end_y, attempting_user_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Subdivide(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id)
|
||||||
|
{
|
||||||
|
RootRegionLandChannel.Subdivide(start_x, start_y, end_x, end_y, attempting_user_id);
|
||||||
|
}
|
||||||
|
|
||||||
public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient)
|
public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient)
|
||||||
{
|
{
|
||||||
RootRegionLandChannel.ReturnObjectsInParcel(localID, returnType, agentIDs, taskIDs, remoteClient);
|
RootRegionLandChannel.ReturnObjectsInParcel(localID, returnType, agentIDs, taskIDs, remoteClient);
|
||||||
|
|
|
@ -1129,7 +1129,89 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Routines for creating and managing parcels programmatically
|
||||||
|
public void osParcelJoin(LSL_Vector pos1, LSL_Vector pos2)
|
||||||
|
{
|
||||||
|
CheckThreatLevel(ThreatLevel.High, "osParcelJoin");
|
||||||
|
m_host.AddScriptLPS(1);
|
||||||
|
|
||||||
|
int startx = (int)(pos1.x < pos2.x ? pos1.x : pos2.x);
|
||||||
|
int starty = (int)(pos1.y < pos2.y ? pos1.y : pos2.y);
|
||||||
|
int endx = (int)(pos1.x > pos2.x ? pos1.x : pos2.x);
|
||||||
|
int endy = (int)(pos1.y > pos2.y ? pos1.y : pos2.y);
|
||||||
|
|
||||||
|
World.LandChannel.Join(startx,starty,endx,endy,m_host.OwnerID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void osParcelSubdivide(LSL_Vector pos1, LSL_Vector pos2)
|
||||||
|
{
|
||||||
|
CheckThreatLevel(ThreatLevel.High, "osParcelSubdivide");
|
||||||
|
m_host.AddScriptLPS(1);
|
||||||
|
|
||||||
|
int startx = (int)(pos1.x < pos2.x ? pos1.x : pos2.x);
|
||||||
|
int starty = (int)(pos1.y < pos2.y ? pos1.y : pos2.y);
|
||||||
|
int endx = (int)(pos1.x > pos2.x ? pos1.x : pos2.x);
|
||||||
|
int endy = (int)(pos1.y > pos2.y ? pos1.y : pos2.y);
|
||||||
|
|
||||||
|
World.LandChannel.Subdivide(startx,starty,endx,endy,m_host.OwnerID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void osParcelSetDetails(LSL_Vector pos, LSL_List rules)
|
||||||
|
{
|
||||||
|
CheckThreatLevel(ThreatLevel.High, "osParcelSetDetails");
|
||||||
|
m_host.AddScriptLPS(1);
|
||||||
|
|
||||||
|
// Get a reference to the land data and make sure the owner of the script
|
||||||
|
// can modify it
|
||||||
|
|
||||||
|
ILandObject startLandObject = World.LandChannel.GetLandObject((int)pos.x, (int)pos.y);
|
||||||
|
if (startLandObject == null)
|
||||||
|
{
|
||||||
|
OSSLShoutError("There is no land at that location");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! World.Permissions.CanEditParcel(m_host.OwnerID, startLandObject))
|
||||||
|
{
|
||||||
|
OSSLShoutError("You do not have permission to modify the parcel");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new land data object we can modify
|
||||||
|
LandData newLand = startLandObject.LandData.Copy();
|
||||||
|
UUID uuid;
|
||||||
|
|
||||||
|
// Process the rules, not sure what the impact would be of changing owner or group
|
||||||
|
for (int idx = 0; idx < rules.Length; )
|
||||||
|
{
|
||||||
|
int code = rules.GetLSLIntegerItem(idx++);
|
||||||
|
string arg = rules.GetLSLStringItem(idx++);
|
||||||
|
switch (code)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
newLand.Name = arg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
newLand.Description = arg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
CheckThreatLevel(ThreatLevel.VeryHigh, "osParcelSetDetails");
|
||||||
|
if (UUID.TryParse(arg , out uuid))
|
||||||
|
newLand.OwnerID = uuid;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
CheckThreatLevel(ThreatLevel.VeryHigh, "osParcelSetDetails");
|
||||||
|
if (UUID.TryParse(arg , out uuid))
|
||||||
|
newLand.GroupID = uuid;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
World.LandChannel.UpdateLandObject(newLand.LocalID,newLand);
|
||||||
|
}
|
||||||
|
|
||||||
public double osList2Double(LSL_Types.list src, int index)
|
public double osList2Double(LSL_Types.list src, int index)
|
||||||
{
|
{
|
||||||
|
|
|
@ -123,6 +123,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
|
||||||
void osWindParamSet(string plugin, string param, float value);
|
void osWindParamSet(string plugin, string param, float value);
|
||||||
float osWindParamGet(string plugin, string param);
|
float osWindParamGet(string plugin, string param);
|
||||||
|
|
||||||
|
// Parcel commands
|
||||||
|
void osParcelJoin(vector pos1, vector pos2);
|
||||||
|
void osParcelSubdivide(vector pos1, vector pos2);
|
||||||
|
void osParcelSetDetails(vector pos, LSL_List rules);
|
||||||
|
|
||||||
string osGetScriptEngineName();
|
string osGetScriptEngineName();
|
||||||
string osGetSimulatorVersion();
|
string osGetSimulatorVersion();
|
||||||
|
|
|
@ -106,6 +106,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
|
||||||
// return m_OSSL_Functions.osWindParamGet(plugin, param);
|
// return m_OSSL_Functions.osWindParamGet(plugin, param);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
public void osParcelJoin(vector pos1, vector pos2)
|
||||||
|
{
|
||||||
|
m_OSSL_Functions.osParcelJoin(pos1,pos2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void osParcelSubdivide(vector pos1, vector pos2)
|
||||||
|
{
|
||||||
|
m_OSSL_Functions.osParcelSubdivide(pos1, pos2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void osParcelSetDetails(vector pos, LSL_List rules)
|
||||||
|
{
|
||||||
|
m_OSSL_Functions.osParcelSetDetails(pos,rules);
|
||||||
|
}
|
||||||
|
|
||||||
public double osList2Double(LSL_Types.list src, int index)
|
public double osList2Double(LSL_Types.list src, int index)
|
||||||
{
|
{
|
||||||
return m_OSSL_Functions.osList2Double(src, index);
|
return m_OSSL_Functions.osList2Double(src, index);
|
||||||
|
|
|
@ -156,6 +156,7 @@ namespace OpenSim.Server.Handlers.GridUser
|
||||||
byte[] SetPosition(Dictionary<string, object> request)
|
byte[] SetPosition(Dictionary<string, object> request)
|
||||||
{
|
{
|
||||||
string user = string.Empty;
|
string user = string.Empty;
|
||||||
|
UUID sessionID = UUID.Zero;
|
||||||
UUID region = UUID.Zero;
|
UUID region = UUID.Zero;
|
||||||
Vector3 position = new Vector3(128, 128, 70);
|
Vector3 position = new Vector3(128, 128, 70);
|
||||||
Vector3 look = Vector3.Zero;
|
Vector3 look = Vector3.Zero;
|
||||||
|
@ -166,7 +167,7 @@ namespace OpenSim.Server.Handlers.GridUser
|
||||||
if (!UnpackArgs(request, out user, out region, out position, out look))
|
if (!UnpackArgs(request, out user, out region, out position, out look))
|
||||||
return FailureResult();
|
return FailureResult();
|
||||||
|
|
||||||
if (m_GridUserService.SetLastPosition(user, region, position, look))
|
if (m_GridUserService.SetLastPosition(user, sessionID, region, position, look))
|
||||||
return SuccessResult();
|
return SuccessResult();
|
||||||
|
|
||||||
return FailureResult();
|
return FailureResult();
|
||||||
|
|
|
@ -123,7 +123,7 @@ namespace OpenSim.Services.Connectors
|
||||||
return Set(sendData, userID, regionID, position, lookAt);
|
return Set(sendData, userID, regionID, position, lookAt);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool SetLastPosition(string userID, UUID regionID, Vector3 position, Vector3 lookAt)
|
public bool SetLastPosition(string userID, UUID sessionID, UUID regionID, Vector3 position, Vector3 lookAt)
|
||||||
{
|
{
|
||||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||||
//sendData["SCOPEID"] = scopeID.ToString();
|
//sendData["SCOPEID"] = scopeID.ToString();
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Region.Framework.Scenes;
|
||||||
|
using OpenSim.Services.Interfaces;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using log4net;
|
||||||
|
|
||||||
|
namespace OpenSim.Services.Connectors.SimianGrid
|
||||||
|
{
|
||||||
|
public class SimianActivityDetector
|
||||||
|
{
|
||||||
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
private IGridUserService m_GridUserService;
|
||||||
|
private Scene m_aScene;
|
||||||
|
|
||||||
|
public SimianActivityDetector(IGridUserService guservice)
|
||||||
|
{
|
||||||
|
m_GridUserService = guservice;
|
||||||
|
m_log.DebugFormat("[SIMIAN ACTIVITY DETECTOR]: Started");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddRegion(Scene scene)
|
||||||
|
{
|
||||||
|
// For now the only events we listen to are these
|
||||||
|
// But we could trigger the position update more often
|
||||||
|
scene.EventManager.OnMakeRootAgent += OnMakeRootAgent;
|
||||||
|
scene.EventManager.OnNewClient += OnNewClient;
|
||||||
|
scene.EventManager.OnAvatarEnteringNewParcel += OnEnteringNewParcel;
|
||||||
|
|
||||||
|
if (m_aScene == null)
|
||||||
|
m_aScene = scene;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveRegion(Scene scene)
|
||||||
|
{
|
||||||
|
scene.EventManager.OnMakeRootAgent -= OnMakeRootAgent;
|
||||||
|
scene.EventManager.OnNewClient -= OnNewClient;
|
||||||
|
scene.EventManager.OnAvatarEnteringNewParcel -= OnEnteringNewParcel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnMakeRootAgent(ScenePresence sp)
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[SIMIAN ACTIVITY DETECTOR]: Detected root presence {0} in {1}", sp.UUID, sp.Scene.RegionInfo.RegionName);
|
||||||
|
m_GridUserService.SetLastPosition(sp.UUID.ToString(), sp.ControllingClient.SessionId, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnNewClient(IClientAPI client)
|
||||||
|
{
|
||||||
|
client.OnConnectionClosed += OnConnectionClose;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnConnectionClose(IClientAPI client)
|
||||||
|
{
|
||||||
|
if (client.IsLoggingOut)
|
||||||
|
{
|
||||||
|
object sp = null;
|
||||||
|
Vector3 position = new Vector3(128, 128, 0);
|
||||||
|
Vector3 lookat = new Vector3(0, 1, 0);
|
||||||
|
|
||||||
|
if (client.Scene.TryGetScenePresence(client.AgentId, out sp))
|
||||||
|
{
|
||||||
|
if (sp is ScenePresence)
|
||||||
|
{
|
||||||
|
if (((ScenePresence)sp).IsChildAgent)
|
||||||
|
return;
|
||||||
|
|
||||||
|
position = ((ScenePresence)sp).AbsolutePosition;
|
||||||
|
lookat = ((ScenePresence)sp).Lookat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_log.DebugFormat("[SIMIAN ACTIVITY DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName);
|
||||||
|
m_GridUserService.LoggedOut(client.AgentId.ToString(), client.Scene.RegionInfo.RegionID, position, lookat);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnEnteringNewParcel(ScenePresence sp, int localLandID, UUID regionID)
|
||||||
|
{
|
||||||
|
m_GridUserService.SetLastPosition(sp.UUID.ToString(), sp.ControllingClient.SessionId, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -58,6 +58,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
|
||||||
MethodBase.GetCurrentMethod().DeclaringType);
|
MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
private string m_serverUrl = String.Empty;
|
private string m_serverUrl = String.Empty;
|
||||||
|
private SimianActivityDetector m_activityDetector;
|
||||||
|
|
||||||
#region ISharedRegionModule
|
#region ISharedRegionModule
|
||||||
|
|
||||||
|
@ -66,7 +67,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
|
||||||
public void PostInitialise() { }
|
public void PostInitialise() { }
|
||||||
public void Close() { }
|
public void Close() { }
|
||||||
|
|
||||||
public SimianPresenceServiceConnector() { }
|
public SimianPresenceServiceConnector() { m_activityDetector = new SimianActivityDetector(this); }
|
||||||
public string Name { get { return "SimianPresenceServiceConnector"; } }
|
public string Name { get { return "SimianPresenceServiceConnector"; } }
|
||||||
public void AddRegion(Scene scene)
|
public void AddRegion(Scene scene)
|
||||||
{
|
{
|
||||||
|
@ -75,9 +76,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
|
||||||
scene.RegisterModuleInterface<IPresenceService>(this);
|
scene.RegisterModuleInterface<IPresenceService>(this);
|
||||||
scene.RegisterModuleInterface<IGridUserService>(this);
|
scene.RegisterModuleInterface<IGridUserService>(this);
|
||||||
|
|
||||||
scene.EventManager.OnMakeRootAgent += MakeRootAgentHandler;
|
m_activityDetector.AddRegion(scene);
|
||||||
scene.EventManager.OnNewClient += NewClientHandler;
|
|
||||||
scene.EventManager.OnSignificantClientMovement += SignificantClientMovementHandler;
|
|
||||||
|
|
||||||
LogoutRegionAgents(scene.RegionInfo.RegionID);
|
LogoutRegionAgents(scene.RegionInfo.RegionID);
|
||||||
}
|
}
|
||||||
|
@ -89,9 +88,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
|
||||||
scene.UnregisterModuleInterface<IPresenceService>(this);
|
scene.UnregisterModuleInterface<IPresenceService>(this);
|
||||||
scene.UnregisterModuleInterface<IGridUserService>(this);
|
scene.UnregisterModuleInterface<IGridUserService>(this);
|
||||||
|
|
||||||
scene.EventManager.OnMakeRootAgent -= MakeRootAgentHandler;
|
m_activityDetector.RemoveRegion(scene);
|
||||||
scene.EventManager.OnNewClient -= NewClientHandler;
|
|
||||||
scene.EventManager.OnSignificantClientMovement -= SignificantClientMovementHandler;
|
|
||||||
|
|
||||||
LogoutRegionAgents(scene.RegionInfo.RegionID);
|
LogoutRegionAgents(scene.RegionInfo.RegionID);
|
||||||
}
|
}
|
||||||
|
@ -193,29 +190,8 @@ namespace OpenSim.Services.Connectors.SimianGrid
|
||||||
|
|
||||||
public bool ReportAgent(UUID sessionID, UUID regionID)
|
public bool ReportAgent(UUID sessionID, UUID regionID)
|
||||||
{
|
{
|
||||||
return ReportAgent(sessionID, regionID, Vector3.Zero, Vector3.Zero);
|
// Not needed for SimianGrid
|
||||||
}
|
return true;
|
||||||
|
|
||||||
protected bool ReportAgent(UUID sessionID, UUID regionID, Vector3 position, Vector3 lookAt)
|
|
||||||
{
|
|
||||||
//m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Updating session data for agent with sessionID " + sessionID);
|
|
||||||
|
|
||||||
NameValueCollection requestArgs = new NameValueCollection
|
|
||||||
{
|
|
||||||
{ "RequestMethod", "UpdateSession" },
|
|
||||||
{ "SessionID", sessionID.ToString() },
|
|
||||||
{ "SceneID", regionID.ToString() },
|
|
||||||
{ "ScenePosition", position.ToString() },
|
|
||||||
{ "SceneLookAt", lookAt.ToString() }
|
|
||||||
};
|
|
||||||
|
|
||||||
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
|
|
||||||
bool success = response["Success"].AsBoolean();
|
|
||||||
|
|
||||||
if (!success)
|
|
||||||
m_log.Warn("[SIMIAN PRESENCE CONNECTOR]: Failed to update agent session " + sessionID + ": " + response["Message"].AsString());
|
|
||||||
|
|
||||||
return success;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public PresenceInfo GetAgent(UUID sessionID)
|
public PresenceInfo GetAgent(UUID sessionID)
|
||||||
|
@ -274,14 +250,27 @@ namespace OpenSim.Services.Connectors.SimianGrid
|
||||||
|
|
||||||
public GridUserInfo LoggedIn(string userID)
|
public GridUserInfo LoggedIn(string userID)
|
||||||
{
|
{
|
||||||
// never implemented at the sim
|
// Never implemented at the sim
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool LoggedOut(string userID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt)
|
public bool LoggedOut(string userID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt)
|
||||||
{
|
{
|
||||||
// Not needed for simian grid, event handler is doing it
|
// Save our last position as user data
|
||||||
return true;
|
NameValueCollection requestArgs = new NameValueCollection
|
||||||
|
{
|
||||||
|
{ "RequestMethod", "AddUserData" },
|
||||||
|
{ "UserID", userID.ToString() },
|
||||||
|
{ "LastLocation", SerializeLocation(regionID, lastPosition, lastLookAt) }
|
||||||
|
};
|
||||||
|
|
||||||
|
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
|
||||||
|
bool success = response["Success"].AsBoolean();
|
||||||
|
|
||||||
|
if (!success)
|
||||||
|
m_log.Warn("[SIMIAN PRESENCE CONNECTOR]: Failed to set last location for " + userID + ": " + response["Message"].AsString());
|
||||||
|
|
||||||
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool SetHome(string userID, UUID regionID, Vector3 position, Vector3 lookAt)
|
public bool SetHome(string userID, UUID regionID, Vector3 position, Vector3 lookAt)
|
||||||
|
@ -304,10 +293,9 @@ namespace OpenSim.Services.Connectors.SimianGrid
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool SetLastPosition(string userID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt)
|
public bool SetLastPosition(string userID, UUID sessionID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt)
|
||||||
{
|
{
|
||||||
// Not needed for simian grid, presence detection is doing it
|
return UpdateSession(sessionID, regionID, lastPosition, lastLookAt);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public GridUserInfo GetGridUserInfo(string user)
|
public GridUserInfo GetGridUserInfo(string user)
|
||||||
|
@ -334,54 +322,6 @@ namespace OpenSim.Services.Connectors.SimianGrid
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Presence Detection
|
|
||||||
|
|
||||||
private void MakeRootAgentHandler(ScenePresence sp)
|
|
||||||
{
|
|
||||||
m_log.DebugFormat("[PRESENCE DETECTOR]: Detected root presence {0} in {1}", sp.UUID, sp.Scene.RegionInfo.RegionName);
|
|
||||||
|
|
||||||
ReportAgent(sp.ControllingClient.SessionId, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat);
|
|
||||||
SetLastLocation(sp.UUID, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void NewClientHandler(IClientAPI client)
|
|
||||||
{
|
|
||||||
client.OnConnectionClosed += LogoutHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SignificantClientMovementHandler(IClientAPI client)
|
|
||||||
{
|
|
||||||
ScenePresence sp;
|
|
||||||
if (client.Scene is Scene && ((Scene)client.Scene).TryGetScenePresence(client.AgentId, out sp))
|
|
||||||
ReportAgent(sp.ControllingClient.SessionId, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void LogoutHandler(IClientAPI client)
|
|
||||||
{
|
|
||||||
if (client.IsLoggingOut)
|
|
||||||
{
|
|
||||||
client.OnConnectionClosed -= LogoutHandler;
|
|
||||||
|
|
||||||
object obj;
|
|
||||||
if (client.Scene.TryGetScenePresence(client.AgentId, out obj) && obj is ScenePresence)
|
|
||||||
{
|
|
||||||
// The avatar is still in the scene, we can get the exact logout position
|
|
||||||
ScenePresence sp = (ScenePresence)obj;
|
|
||||||
SetLastLocation(client.AgentId, client.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// The avatar was already removed from the scene, store LastLocation using the most recent session data
|
|
||||||
m_log.Warn("[PRESENCE]: " + client.Name + " has already been removed from the scene, storing approximate LastLocation");
|
|
||||||
SetLastLocation(client.SessionId);
|
|
||||||
}
|
|
||||||
|
|
||||||
LogoutAgent(client.SessionId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Presence Detection
|
|
||||||
|
|
||||||
#region Helpers
|
#region Helpers
|
||||||
|
|
||||||
private OSDMap GetUserData(UUID userID)
|
private OSDMap GetUserData(UUID userID)
|
||||||
|
@ -453,57 +393,60 @@ namespace OpenSim.Services.Connectors.SimianGrid
|
||||||
return presences;
|
return presences;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
private bool UpdateSession(UUID sessionID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt)
|
||||||
/// Fetch the last known avatar location with GetSession and persist it
|
|
||||||
/// as user data with AddUserData
|
|
||||||
/// </summary>
|
|
||||||
private bool SetLastLocation(UUID sessionID)
|
|
||||||
{
|
{
|
||||||
|
// Save our current location as session data
|
||||||
NameValueCollection requestArgs = new NameValueCollection
|
NameValueCollection requestArgs = new NameValueCollection
|
||||||
{
|
{
|
||||||
{ "RequestMethod", "GetSession" },
|
{ "RequestMethod", "UpdateSession" },
|
||||||
{ "SessionID", sessionID.ToString() }
|
{ "SessionID", sessionID.ToString() },
|
||||||
|
{ "SceneID", regionID.ToString() },
|
||||||
|
{ "ScenePosition", lastPosition.ToString() },
|
||||||
|
{ "SceneLookAt", lastLookAt.ToString() }
|
||||||
};
|
};
|
||||||
|
|
||||||
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
|
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
|
||||||
bool success = response["Success"].AsBoolean();
|
bool success = response["Success"].AsBoolean();
|
||||||
|
|
||||||
if (success)
|
|
||||||
{
|
|
||||||
UUID userID = response["UserID"].AsUUID();
|
|
||||||
UUID sceneID = response["SceneID"].AsUUID();
|
|
||||||
Vector3 position = response["ScenePosition"].AsVector3();
|
|
||||||
Vector3 lookAt = response["SceneLookAt"].AsVector3();
|
|
||||||
|
|
||||||
return SetLastLocation(userID, sceneID, position, lookAt);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_log.Warn("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve presence information for session " + sessionID +
|
|
||||||
" while saving last location: " + response["Message"].AsString());
|
|
||||||
}
|
|
||||||
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool SetLastLocation(UUID userID, UUID sceneID, Vector3 position, Vector3 lookAt)
|
|
||||||
{
|
|
||||||
NameValueCollection requestArgs = new NameValueCollection
|
|
||||||
{
|
|
||||||
{ "RequestMethod", "AddUserData" },
|
|
||||||
{ "UserID", userID.ToString() },
|
|
||||||
{ "LastLocation", SerializeLocation(sceneID, position, lookAt) }
|
|
||||||
};
|
|
||||||
|
|
||||||
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
|
|
||||||
bool success = response["Success"].AsBoolean();
|
|
||||||
|
|
||||||
if (!success)
|
if (!success)
|
||||||
m_log.Warn("[SIMIAN PRESENCE CONNECTOR]: Failed to set last location for " + userID + ": " + response["Message"].AsString());
|
m_log.Warn("[SIMIAN PRESENCE CONNECTOR]: Failed to update agent session " + sessionID + ": " + response["Message"].AsString());
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///// <summary>
|
||||||
|
///// Fetch the last known avatar location with GetSession and persist it
|
||||||
|
///// as user data with AddUserData
|
||||||
|
///// </summary>
|
||||||
|
//private bool SetLastLocation(UUID sessionID)
|
||||||
|
//{
|
||||||
|
// NameValueCollection requestArgs = new NameValueCollection
|
||||||
|
// {
|
||||||
|
// { "RequestMethod", "GetSession" },
|
||||||
|
// { "SessionID", sessionID.ToString() }
|
||||||
|
// };
|
||||||
|
|
||||||
|
// OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
|
||||||
|
// bool success = response["Success"].AsBoolean();
|
||||||
|
|
||||||
|
// if (success)
|
||||||
|
// {
|
||||||
|
// UUID userID = response["UserID"].AsUUID();
|
||||||
|
// UUID sceneID = response["SceneID"].AsUUID();
|
||||||
|
// Vector3 position = response["ScenePosition"].AsVector3();
|
||||||
|
// Vector3 lookAt = response["SceneLookAt"].AsVector3();
|
||||||
|
|
||||||
|
// return SetLastLocation(userID, sceneID, position, lookAt);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// m_log.Warn("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve presence information for session " + sessionID +
|
||||||
|
// " while saving last location: " + response["Message"].AsString());
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return success;
|
||||||
|
//}
|
||||||
|
|
||||||
private PresenceInfo ResponseToPresenceInfo(OSDMap sessionResponse, OSDMap userResponse)
|
private PresenceInfo ResponseToPresenceInfo(OSDMap sessionResponse, OSDMap userResponse)
|
||||||
{
|
{
|
||||||
if (sessionResponse == null)
|
if (sessionResponse == null)
|
||||||
|
|
|
@ -108,7 +108,7 @@ namespace OpenSim.Services.Interfaces
|
||||||
bool LoggedOut(string userID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt);
|
bool LoggedOut(string userID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt);
|
||||||
|
|
||||||
bool SetHome(string userID, UUID homeID, Vector3 homePosition, Vector3 homeLookAt);
|
bool SetHome(string userID, UUID homeID, Vector3 homePosition, Vector3 homeLookAt);
|
||||||
bool SetLastPosition(string userID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt);
|
bool SetLastPosition(string userID, UUID sessionID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt);
|
||||||
|
|
||||||
GridUserInfo GetGridUserInfo(string userID);
|
GridUserInfo GetGridUserInfo(string userID);
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,7 +139,7 @@ namespace OpenSim.Services.UserAccountService
|
||||||
return m_Database.Store(d);
|
return m_Database.Store(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool SetLastPosition(string userID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt)
|
public bool SetLastPosition(string userID, UUID sessionID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt)
|
||||||
{
|
{
|
||||||
//m_log.DebugFormat("[Grid User Service]: SetLastPosition for {0}", userID);
|
//m_log.DebugFormat("[Grid User Service]: SetLastPosition for {0}", userID);
|
||||||
GridUserData d = m_Database.Get(userID);
|
GridUserData d = m_Database.Get(userID);
|
||||||
|
|
|
@ -621,14 +621,6 @@ namespace OpenSim.Tests.Common.Mock
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void SendAvatarData(SendAvatarData data)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void SendAvatarTerseUpdate(SendAvatarTerseData data)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
|
public virtual void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -641,15 +633,15 @@ namespace OpenSim.Tests.Common.Mock
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void SendPrimitiveToClient(SendPrimitiveData data)
|
public void SendAvatarDataImmediate(ISceneEntity avatar)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void SendPrimTerseUpdate(SendPrimitiveTerseData data)
|
public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler)
|
public void ReprioritizeUpdates(UpdatePriorityHandler handler)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,5 +85,9 @@ namespace OpenSim.Tests.Common.Mock
|
||||||
public void setParcelObjectMaxOverride(overrideParcelMaxPrimCountDelegate overrideDel) {}
|
public void setParcelObjectMaxOverride(overrideParcelMaxPrimCountDelegate overrideDel) {}
|
||||||
public void setSimulatorObjectMaxOverride(overrideSimulatorMaxPrimCountDelegate overrideDel) {}
|
public void setSimulatorObjectMaxOverride(overrideSimulatorMaxPrimCountDelegate overrideDel) {}
|
||||||
public void SetParcelOtherCleanTime(IClientAPI remoteClient, int localID, int otherCleanTime) {}
|
public void SetParcelOtherCleanTime(IClientAPI remoteClient, int localID, int otherCleanTime) {}
|
||||||
|
|
||||||
|
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) {}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue