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));