diff --git a/libsecondlife/LLSD.cs b/libsecondlife/LLSD.cs
index bc8a2977..6f74c95d 100644
--- a/libsecondlife/LLSD.cs
+++ b/libsecondlife/LLSD.cs
@@ -218,7 +218,8 @@ namespace libsecondlife
{
if (reader.IsEmptyElement)
{
- reader.Read(); return false;
+ reader.Read();
+ return false;
}
reader.Read();
diff --git a/libsecondlife/Simulator.cs b/libsecondlife/Simulator.cs
index 9f817f3b..546a2b0e 100644
--- a/libsecondlife/Simulator.cs
+++ b/libsecondlife/Simulator.cs
@@ -668,10 +668,11 @@ namespace libsecondlife
{
try
{
- Client.DebugLog("Resending " + packet.Type.ToString() + " packet (" + packet.Header.Sequence +
- "), " + (now - packet.TickCount) + "ms have passed");
+ Client.DebugLog(String.Format("Resending packet #{0}, {1}ms have passed",
+ packet.Header.Sequence, now - packet.TickCount));
+
packet.Header.Resent = true;
- ResentPackets++;
+ ++ResentPackets;
SendPacket(packet, false);
}
catch (Exception ex)
diff --git a/libsecondlife/TerrainManager.cs b/libsecondlife/TerrainManager.cs
index c47ad8bc..221e238f 100644
--- a/libsecondlife/TerrainManager.cs
+++ b/libsecondlife/TerrainManager.cs
@@ -838,17 +838,17 @@ namespace libsecondlife
{
try { OnLandPatch(simulator, x, y, group.PatchSize, heightmap); }
catch (Exception e) { Client.Log(e.ToString(), Helpers.LogLevel.Error); }
+ }
- if (Client.Settings.STORE_LAND_PATCHES)
+ if (Client.Settings.STORE_LAND_PATCHES)
+ {
+ lock (SimPatches)
{
- lock (SimPatches)
- {
- if (!SimPatches.ContainsKey(simulator.Handle))
- SimPatches.Add(simulator.Handle, new Patch[16 * 16]);
+ if (!SimPatches.ContainsKey(simulator.Handle))
+ SimPatches.Add(simulator.Handle, new Patch[16 * 16]);
- SimPatches[simulator.Handle][y * 16 + x] = new Patch();
- SimPatches[simulator.Handle][y * 16 + x].Heightmap = heightmap;
- }
+ SimPatches[simulator.Handle][y * 16 + x] = new Patch();
+ SimPatches[simulator.Handle][y * 16 + x].Heightmap = heightmap;
}
}
}
@@ -878,17 +878,14 @@ namespace libsecondlife
// Layer type
header.Type = (LayerType)bitpack.UnpackBits(8);
- if (type != header.Type)
- Client.DebugLog("LayerData: LayerID.Type " + type.ToString() + " does not match decoded type " +
- header.Type.ToString());
-
switch (type)
{
case LayerType.Land:
- if (OnLandPatch != null) DecompressLand(simulator, bitpack, header);
+ if (OnLandPatch != null || Client.Settings.STORE_LAND_PATCHES)
+ DecompressLand(simulator, bitpack, header);
break;
case LayerType.Water:
- Client.Log("Got a Water LayerData packet, implement me!", Helpers.LogLevel.Info);
+ Client.Log("Got a Water LayerData packet, implement me!", Helpers.LogLevel.Error);
break;
case LayerType.Wind:
DecompressWind(simulator, bitpack, header);
diff --git a/libsecondlife/Textures.cs b/libsecondlife/Textures.cs
index fabfa705..a1e63552 100644
--- a/libsecondlife/Textures.cs
+++ b/libsecondlife/Textures.cs
@@ -154,9 +154,9 @@ namespace libsecondlife
///
Rotation = 1 << 6,
///
- Flags1 = 1 << 7,
+ Material = 1 << 7,
///
- Flags2 = 1 << 8,
+ Media = 1 << 8,
///
All = 0xFFFFFFFF
}
@@ -353,20 +353,20 @@ namespace libsecondlife
Rotations[value] = (uint)(1 << (int)face.Key);
}
- if (face.Value.Flags1 != DefaultTexture.Flags1)
+ if (face.Value.material != DefaultTexture.material)
{
- if (Flag1s.ContainsKey(face.Value.Flags1))
- Flag1s[face.Value.Flags1] |= (uint)(1 << (int)face.Key);
+ if (Flag1s.ContainsKey(face.Value.material))
+ Flag1s[face.Value.material] |= (uint)(1 << (int)face.Key);
else
- Flag1s[face.Value.Flags1] = (uint)(1 << (int)face.Key);
+ Flag1s[face.Value.material] = (uint)(1 << (int)face.Key);
}
- if (face.Value.Flags2 != DefaultTexture.Flags2)
+ if (face.Value.media != DefaultTexture.media)
{
- if (Flag2s.ContainsKey(face.Value.Flags2))
- Flag2s[face.Value.Flags2] |= (uint)(1 << (int)face.Key);
+ if (Flag2s.ContainsKey(face.Value.media))
+ Flag2s[face.Value.media] |= (uint)(1 << (int)face.Key);
else
- Flag2s[face.Value.Flags2] = (uint)(1 << (int)face.Key);
+ Flag2s[face.Value.media] = (uint)(1 << (int)face.Key);
}
}
@@ -429,7 +429,7 @@ namespace libsecondlife
}
binWriter.Write((byte)0);
- binWriter.Write(DefaultTexture.Flags1);
+ binWriter.Write(DefaultTexture.material);
foreach (KeyValuePair kv in Flag1s)
{
binWriter.Write(GetFaceBitfieldBytes(kv.Value));
@@ -437,7 +437,7 @@ namespace libsecondlife
}
binWriter.Write((byte)0);
- binWriter.Write(DefaultTexture.Flags2);
+ binWriter.Write(DefaultTexture.media);
foreach (KeyValuePair kv in Flag2s)
{
binWriter.Write(GetFaceBitfieldBytes(kv.Value));
@@ -493,10 +493,9 @@ namespace libsecondlife
private float DequantizeSigned(byte[] byteArray, int pos, float upper)
{
- short value = (short)(byteArray[pos] | (byteArray[pos + 1] << 8));
- float QV = (float)value;
+ float QV = (float)(byteArray[pos] | (byteArray[pos + 1] << 8));
float QF = upper / 32767.0f;
- return (float)(QV * QF);
+ return QV * QF;
}
private short QuantizeSigned(float f, float upper)
@@ -638,8 +637,8 @@ namespace libsecondlife
if ((faceBits & bit) != 0)
CreateFace(face).Rotation = tmpFloat;
}
- //Read Flags1 ------------------------------------------
- DefaultTexture.Flags1 = data[i];
+ //Read Material Flags ------------------------------------------
+ DefaultTexture.material = data[i];
i++;
while (ReadFaceBitfield(data, ref i, ref faceBits, ref BitfieldSize))
@@ -649,10 +648,10 @@ namespace libsecondlife
for (uint face = 0, bit = 1; face < BitfieldSize; face++, bit <<= 1)
if ((faceBits & bit) != 0)
- CreateFace(face).Flags1 = tmpByte;
+ CreateFace(face).material = tmpByte;
}
- //Read Flags2 ------------------------------------------
- DefaultTexture.Flags2 = data[i];
+ //Read Media Flags ------------------------------------------
+ DefaultTexture.media = data[i];
i++;
while (i - pos < length && ReadFaceBitfield(data, ref i, ref faceBits, ref BitfieldSize))
@@ -662,7 +661,7 @@ namespace libsecondlife
for (uint face = 0, bit = 1; face < BitfieldSize; face++, bit <<= 1)
if ((faceBits & bit) != 0)
- CreateFace(face).Flags2 = tmpByte;
+ CreateFace(face).media = tmpByte;
}
}
}
@@ -674,35 +673,112 @@ namespace libsecondlife
[Serializable]
public class TextureEntryFace
{
- [XmlAttribute("rgba")]
+ ///
+ ///
+ ///
+ public enum Bumpmap : byte
+ {
+ ///
+ None = 0,
+ ///
+ Brightness,
+ ///
+ Darkness,
+ ///
+ Woodgrain,
+ ///
+ Bark,
+ ///
+ Bricks,
+ ///
+ Checher,
+ ///
+ Concrete,
+ ///
+ Crustytile,
+ ///
+ Cutstone,
+ ///
+ Discs,
+ ///
+ Gravel,
+ ///
+ Petridish,
+ ///
+ Siding,
+ ///
+ Stonetile,
+ ///
+ Stucco,
+ ///
+ Suction,
+ ///
+ Weave
+ }
+
+ ///
+ ///
+ ///
+ public enum TextureMapping : byte
+ {
+ ///
+ Default = 0,
+ ///
+ Planar = 2,
+ ///
+ Spherical = 4,
+ ///
+ Cylindrical = 6
+ }
+
+ ///
+ ///
+ ///
+ public enum ShinyLevel : byte
+ {
+ ///
+ None = 0,
+ ///
+ Quarter = 0x40,
+ ///
+ Half = 0x80,
+ ///
+ ThreeQuarters = 0xC0
+ }
+
private uint rgba;
- [XmlAttribute("repeatu")]
private float repeatU = 1.0f;
- [XmlAttribute("repeatv")]
private float repeatV = 1.0f;
- [XmlAttribute("offsetu")]
private float offsetU;
- [XmlAttribute("offsetv")]
private float offsetV;
- [XmlAttribute("rotation")]
private float rotation;
- [XmlAttribute("flags1")]
- private byte flags1;
- [XmlAttribute("flags2")]
- private byte flags2;
- [XmlAttribute("textureattributes")]
private TextureAttributes hasAttribute;
- [XmlText]
private LLUUID textureID;
- [XmlElement("defaulttexture")]
private TextureEntryFace DefaultTexture = null;
+ // +----------+ S = Shiny
+ // | SSFBBBBB | F = Fullbright
+ // | 76543210 | B = Bumpmap
+ // +----------+
+ private const byte BUMP_MASK = 0x1F;
+ private const byte FULLBRIGHT_MASK = 0x20;
+ private const byte SHINY_MASK = 0xC0;
+
+ // +----------+ M = Media Flags (web page)
+ // | .....TTM | T = Texture Mapping
+ // | 76543210 | . = Unused
+ // +----------+
+ private const byte MEDIA_MASK = 0x01;
+ private const byte TEX_MAP_MASK = 0x06;
+
+ internal byte material;
+ internal byte media;
+
//////////////////////
///// Properties /////
//////////////////////
///
- [XmlAttribute("rgba")]
public uint RGBA
{
get
@@ -720,7 +796,6 @@ namespace libsecondlife
}
///
- [XmlAttribute("repeatu")]
public float RepeatU
{
get
@@ -738,7 +813,6 @@ namespace libsecondlife
}
///
- [XmlAttribute("repeatv")]
public float RepeatV
{
get
@@ -756,7 +830,6 @@ namespace libsecondlife
}
///
- [XmlAttribute("offsetu")]
public float OffsetU
{
get
@@ -774,7 +847,6 @@ namespace libsecondlife
}
///
- [XmlAttribute("offsetv")]
public float OffsetV
{
get
@@ -792,7 +864,6 @@ namespace libsecondlife
}
///
- [XmlAttribute("rotation")]
public float Rotation
{
get
@@ -810,43 +881,108 @@ namespace libsecondlife
}
///
- [XmlAttribute("flags1")]
- public byte Flags1
+ public Bumpmap Bump
{
get
{
- if ((hasAttribute & TextureAttributes.Flags1) != 0)
- return flags1;
+ if ((hasAttribute & TextureAttributes.Material) != 0)
+ return (Bumpmap)(material & BUMP_MASK);
else
- return DefaultTexture.flags1;
+ return DefaultTexture.Bump;
}
set
{
- flags1 = value;
- hasAttribute |= TextureAttributes.Flags1;
+ // Clear out the old material value
+ material &= 0xE0;
+ // Put the new bump value in the material byte
+ material |= (byte)value;
+ hasAttribute |= TextureAttributes.Material;
+ }
+ }
+
+ public ShinyLevel Shiny
+ {
+ get
+ {
+ if ((hasAttribute & TextureAttributes.Material) != 0)
+ return (ShinyLevel)(material & SHINY_MASK);
+ else
+ return DefaultTexture.Shiny;
+ }
+ set
+ {
+ // Clear out the old shiny value
+ material &= 0x3F;
+ // Put the new shiny value in the material byte
+ material |= (byte)value;
+ hasAttribute |= TextureAttributes.Material;
+ }
+ }
+
+ public bool Fullbright
+ {
+ get
+ {
+ if ((hasAttribute & TextureAttributes.Material) != 0)
+ return (material & FULLBRIGHT_MASK) != 0;
+ else
+ return DefaultTexture.Fullbright;
+ }
+ set
+ {
+ // Clear out the old fullbright value
+ material &= 0xDF;
+ if (value)
+ {
+ material |= 0x20;
+ hasAttribute |= TextureAttributes.Material;
+ }
+ }
+ }
+
+ /// In the future this will specify whether a webpage is
+ /// attached to this face
+ public bool MediaFlags
+ {
+ get
+ {
+ if ((hasAttribute & TextureAttributes.Media) != 0)
+ return (media & MEDIA_MASK) != 0;
+ else
+ return DefaultTexture.MediaFlags;
+ }
+ set
+ {
+ // Clear out the old mediaflags value
+ media &= 0xFE;
+ if (value)
+ {
+ media |= 0x01;
+ hasAttribute |= TextureAttributes.Media;
+ }
+ }
+ }
+
+ public TextureMapping TexMapType
+ {
+ get
+ {
+ if ((hasAttribute & TextureAttributes.Media) != 0)
+ return (TextureMapping)(media & TEX_MAP_MASK);
+ else
+ return DefaultTexture.TexMapType;
+ }
+ set
+ {
+ // Clear out the old texmap value
+ media &= 0xF9;
+ // Put the new texmap value in the media byte
+ media |= (byte)value;
+ hasAttribute |= TextureAttributes.Media;
}
}
///
- [XmlAttribute("flags2")]
- public byte Flags2
- {
- get
- {
- if ((hasAttribute & TextureAttributes.Flags2) != 0)
- return flags2;
- else
- return DefaultTexture.flags2;
- }
- set
- {
- flags2 = value;
- hasAttribute |= TextureAttributes.Flags2;
- }
- }
-
- ///
- [XmlElement("id")]
public LLUUID TextureID
{
get
diff --git a/libsecondlife/examples/TestClient/ClientManager.cs b/libsecondlife/examples/TestClient/ClientManager.cs
index 430386e5..504e1c46 100644
--- a/libsecondlife/examples/TestClient/ClientManager.cs
+++ b/libsecondlife/examples/TestClient/ClientManager.cs
@@ -87,11 +87,6 @@ namespace libsecondlife.TestClient
client.SimPrims = SimPrims;
client.Master = account.Master;
- // Throttle the connection to not receive LayerData packets
- client.Throttle.Land = 0.0f;
- client.Throttle.Cloud = 0.0f;
- client.Throttle.Wind = 0.0f;
-
if (this.startpos.sim != null)
{
if (this.startpos.x == 0 || this.startpos.y == 0 || this.startpos.z == 0)
diff --git a/libsecondlife/examples/TestClient/TestClient.cs b/libsecondlife/examples/TestClient/TestClient.cs
index 6afe1647..8e867aec 100644
--- a/libsecondlife/examples/TestClient/TestClient.cs
+++ b/libsecondlife/examples/TestClient/TestClient.cs
@@ -48,6 +48,7 @@ namespace libsecondlife.TestClient
RegisterAllCommands(Assembly.GetExecutingAssembly());
Settings.DEBUG = false;
+ Settings.STORE_LAND_PATCHES = true;
Network.RegisterCallback(PacketType.AgentDataUpdate, new NetworkManager.PacketCallback(AgentDataUpdateHandler));