diff options
Diffstat (limited to 'OpenSim/Framework/Util.cs')
-rw-r--r-- | OpenSim/Framework/Util.cs | 234 |
1 files changed, 193 insertions, 41 deletions
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index a5f798d..3e6d8ef 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs | |||
@@ -61,6 +61,15 @@ namespace OpenSim.Framework | |||
61 | public enum PermissionMask : uint | 61 | public enum PermissionMask : uint |
62 | { | 62 | { |
63 | None = 0, | 63 | None = 0, |
64 | |||
65 | // folded perms | ||
66 | foldedTransfer = 1, | ||
67 | foldedModify = 1 << 1, | ||
68 | foldedCopy = 1 << 2, | ||
69 | |||
70 | foldedMask = 0x07, | ||
71 | |||
72 | // | ||
64 | Transfer = 1 << 13, | 73 | Transfer = 1 << 13, |
65 | Modify = 1 << 14, | 74 | Modify = 1 << 14, |
66 | Copy = 1 << 15, | 75 | Copy = 1 << 15, |
@@ -131,10 +140,14 @@ namespace OpenSim.Framework | |||
131 | 140 | ||
132 | public static readonly int MAX_THREADPOOL_LEVEL = 3; | 141 | public static readonly int MAX_THREADPOOL_LEVEL = 3; |
133 | 142 | ||
143 | public static double TimeStampClockPeriodMS; | ||
144 | |||
134 | static Util() | 145 | static Util() |
135 | { | 146 | { |
136 | LogThreadPool = 0; | 147 | LogThreadPool = 0; |
137 | LogOverloads = true; | 148 | LogOverloads = true; |
149 | TimeStampClockPeriodMS = 1000.0D / (double)Stopwatch.Frequency; | ||
150 | m_log.InfoFormat("[UTIL] TimeStamp clock with period of {0}ms", Math.Round(TimeStampClockPeriodMS,6,MidpointRounding.AwayFromZero)); | ||
138 | } | 151 | } |
139 | 152 | ||
140 | private static uint nextXferID = 5000; | 153 | private static uint nextXferID = 5000; |
@@ -267,14 +280,12 @@ namespace OpenSim.Framework | |||
267 | /// </summary> | 280 | /// </summary> |
268 | /// <param name="a">A 3d vector</param> | 281 | /// <param name="a">A 3d vector</param> |
269 | /// <returns>A new vector which is normalized form of the vector</returns> | 282 | /// <returns>A new vector which is normalized form of the vector</returns> |
270 | /// <remarks>The vector paramater cannot be <0,0,0></remarks> | 283 | |
271 | public static Vector3 GetNormalizedVector(Vector3 a) | 284 | public static Vector3 GetNormalizedVector(Vector3 a) |
272 | { | 285 | { |
273 | if (IsZeroVector(a)) | 286 | Vector3 v = new Vector3(a.X, a.Y, a.Z); |
274 | throw new ArgumentException("Vector paramater cannot be a zero vector."); | 287 | v.Normalize(); |
275 | 288 | return v; | |
276 | float Mag = (float) GetMagnitude(a); | ||
277 | return new Vector3(a.X / Mag, a.Y / Mag, a.Z / Mag); | ||
278 | } | 289 | } |
279 | 290 | ||
280 | /// <summary> | 291 | /// <summary> |
@@ -641,19 +652,25 @@ namespace OpenSim.Framework | |||
641 | /// </summary> | 652 | /// </summary> |
642 | /// <param name="data"></param> | 653 | /// <param name="data"></param> |
643 | /// <returns></returns> | 654 | /// <returns></returns> |
655 | |||
644 | public static string Md5Hash(string data) | 656 | public static string Md5Hash(string data) |
645 | { | 657 | { |
646 | byte[] dataMd5 = ComputeMD5Hash(data); | 658 | return Md5Hash(data, Encoding.Default); |
659 | } | ||
660 | |||
661 | public static string Md5Hash(string data, Encoding encoding) | ||
662 | { | ||
663 | byte[] dataMd5 = ComputeMD5Hash(data, encoding); | ||
647 | StringBuilder sb = new StringBuilder(); | 664 | StringBuilder sb = new StringBuilder(); |
648 | for (int i = 0; i < dataMd5.Length; i++) | 665 | for (int i = 0; i < dataMd5.Length; i++) |
649 | sb.AppendFormat("{0:x2}", dataMd5[i]); | 666 | sb.AppendFormat("{0:x2}", dataMd5[i]); |
650 | return sb.ToString(); | 667 | return sb.ToString(); |
651 | } | 668 | } |
652 | 669 | ||
653 | private static byte[] ComputeMD5Hash(string data) | 670 | private static byte[] ComputeMD5Hash(string data, Encoding encoding) |
654 | { | 671 | { |
655 | MD5 md5 = MD5.Create(); | 672 | MD5 md5 = MD5.Create(); |
656 | return md5.ComputeHash(Encoding.Default.GetBytes(data)); | 673 | return md5.ComputeHash(encoding.GetBytes(data)); |
657 | } | 674 | } |
658 | 675 | ||
659 | /// <summary> | 676 | /// <summary> |
@@ -661,6 +678,12 @@ namespace OpenSim.Framework | |||
661 | /// </summary> | 678 | /// </summary> |
662 | /// <param name="data"></param> | 679 | /// <param name="data"></param> |
663 | /// <returns></returns> | 680 | /// <returns></returns> |
681 | |||
682 | public static string SHA1Hash(string data, Encoding enc) | ||
683 | { | ||
684 | return SHA1Hash(enc.GetBytes(data)); | ||
685 | } | ||
686 | |||
664 | public static string SHA1Hash(string data) | 687 | public static string SHA1Hash(string data) |
665 | { | 688 | { |
666 | return SHA1Hash(Encoding.Default.GetBytes(data)); | 689 | return SHA1Hash(Encoding.Default.GetBytes(data)); |
@@ -714,17 +737,26 @@ namespace OpenSim.Framework | |||
714 | /// <param name="oldy">Old region y-coord</param> | 737 | /// <param name="oldy">Old region y-coord</param> |
715 | /// <param name="newy">New region y-coord</param> | 738 | /// <param name="newy">New region y-coord</param> |
716 | /// <returns></returns> | 739 | /// <returns></returns> |
717 | public static bool IsOutsideView(float drawdist, uint oldx, uint newx, uint oldy, uint newy) | 740 | public static bool IsOutsideView(float drawdist, uint oldx, uint newx, uint oldy, uint newy, |
741 | int oldsizex, int oldsizey, int newsizex, int newsizey) | ||
718 | { | 742 | { |
719 | int dd = (int)((drawdist + Constants.RegionSize - 1) / Constants.RegionSize); | 743 | // we still need to make sure we see new region 1stNeighbors |
720 | 744 | ||
721 | int startX = (int)oldx - dd; | 745 | oldx *= Constants.RegionSize; |
722 | int startY = (int)oldy - dd; | 746 | newx *= Constants.RegionSize; |
747 | if (oldx + oldsizex + drawdist < newx) | ||
748 | return true; | ||
749 | if (newx + newsizex + drawdist < oldx) | ||
750 | return true; | ||
723 | 751 | ||
724 | int endX = (int)oldx + dd; | 752 | oldy *= Constants.RegionSize; |
725 | int endY = (int)oldy + dd; | 753 | newy *= Constants.RegionSize; |
754 | if (oldy + oldsizey + drawdist < newy) | ||
755 | return true; | ||
756 | if (newy + newsizey + drawdist< oldy) | ||
757 | return true; | ||
726 | 758 | ||
727 | return (newx < startX || endX < newx || newy < startY || endY < newy); | 759 | return false; |
728 | } | 760 | } |
729 | 761 | ||
730 | public static string FieldToString(byte[] bytes) | 762 | public static string FieldToString(byte[] bytes) |
@@ -805,6 +837,16 @@ namespace OpenSim.Framework | |||
805 | } | 837 | } |
806 | 838 | ||
807 | /// <summary> | 839 | /// <summary> |
840 | /// Converts a URL to a IPAddress | ||
841 | /// </summary> | ||
842 | /// <param name="url">URL Standard Format</param> | ||
843 | /// <returns>A resolved IP Address</returns> | ||
844 | public static IPAddress GetHostFromURL(string url) | ||
845 | { | ||
846 | return GetHostFromDNS(url.Split(new char[] {'/', ':'})[3]); | ||
847 | } | ||
848 | |||
849 | /// <summary> | ||
808 | /// Returns a IP address from a specified DNS, favouring IPv4 addresses. | 850 | /// Returns a IP address from a specified DNS, favouring IPv4 addresses. |
809 | /// </summary> | 851 | /// </summary> |
810 | /// <param name="dnsAddress">DNS Hostname</param> | 852 | /// <param name="dnsAddress">DNS Hostname</param> |
@@ -1065,6 +1107,25 @@ namespace OpenSim.Framework | |||
1065 | } | 1107 | } |
1066 | } | 1108 | } |
1067 | 1109 | ||
1110 | public static string GetConfigVarWithDefaultSection(IConfigSource config, string varname, string section) | ||
1111 | { | ||
1112 | // First, check the Startup section, the default section | ||
1113 | IConfig cnf = config.Configs["Startup"]; | ||
1114 | if (cnf == null) | ||
1115 | return string.Empty; | ||
1116 | string val = cnf.GetString(varname, string.Empty); | ||
1117 | |||
1118 | // Then check for an overwrite of the default in the given section | ||
1119 | if (!string.IsNullOrEmpty(section)) | ||
1120 | { | ||
1121 | cnf = config.Configs[section]; | ||
1122 | if (cnf != null) | ||
1123 | val = cnf.GetString(varname, val); | ||
1124 | } | ||
1125 | |||
1126 | return val; | ||
1127 | } | ||
1128 | |||
1068 | /// <summary> | 1129 | /// <summary> |
1069 | /// Gets the value of a configuration variable by looking into | 1130 | /// Gets the value of a configuration variable by looking into |
1070 | /// multiple sections in order. The latter sections overwrite | 1131 | /// multiple sections in order. The latter sections overwrite |
@@ -1388,6 +1449,46 @@ namespace OpenSim.Framework | |||
1388 | return ret; | 1449 | return ret; |
1389 | } | 1450 | } |
1390 | 1451 | ||
1452 | public static string Compress(string text) | ||
1453 | { | ||
1454 | byte[] buffer = Util.UTF8.GetBytes(text); | ||
1455 | MemoryStream memory = new MemoryStream(); | ||
1456 | using (GZipStream compressor = new GZipStream(memory, CompressionMode.Compress, true)) | ||
1457 | { | ||
1458 | compressor.Write(buffer, 0, buffer.Length); | ||
1459 | } | ||
1460 | |||
1461 | memory.Position = 0; | ||
1462 | |||
1463 | byte[] compressed = new byte[memory.Length]; | ||
1464 | memory.Read(compressed, 0, compressed.Length); | ||
1465 | |||
1466 | byte[] compressedBuffer = new byte[compressed.Length + 4]; | ||
1467 | Buffer.BlockCopy(compressed, 0, compressedBuffer, 4, compressed.Length); | ||
1468 | Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, compressedBuffer, 0, 4); | ||
1469 | return Convert.ToBase64String(compressedBuffer); | ||
1470 | } | ||
1471 | |||
1472 | public static string Decompress(string compressedText) | ||
1473 | { | ||
1474 | byte[] compressedBuffer = Convert.FromBase64String(compressedText); | ||
1475 | using (MemoryStream memory = new MemoryStream()) | ||
1476 | { | ||
1477 | int msgLength = BitConverter.ToInt32(compressedBuffer, 0); | ||
1478 | memory.Write(compressedBuffer, 4, compressedBuffer.Length - 4); | ||
1479 | |||
1480 | byte[] buffer = new byte[msgLength]; | ||
1481 | |||
1482 | memory.Position = 0; | ||
1483 | using (GZipStream decompressor = new GZipStream(memory, CompressionMode.Decompress)) | ||
1484 | { | ||
1485 | decompressor.Read(buffer, 0, buffer.Length); | ||
1486 | } | ||
1487 | |||
1488 | return Util.UTF8.GetString(buffer); | ||
1489 | } | ||
1490 | } | ||
1491 | |||
1391 | /// <summary> | 1492 | /// <summary> |
1392 | /// Copy data from one stream to another, leaving the read position of both streams at the beginning. | 1493 | /// Copy data from one stream to another, leaving the read position of both streams at the beginning. |
1393 | /// </summary> | 1494 | /// </summary> |
@@ -1524,19 +1625,19 @@ namespace OpenSim.Framework | |||
1524 | { | 1625 | { |
1525 | string os = String.Empty; | 1626 | string os = String.Empty; |
1526 | 1627 | ||
1527 | if (Environment.OSVersion.Platform != PlatformID.Unix) | 1628 | // if (Environment.OSVersion.Platform != PlatformID.Unix) |
1528 | { | 1629 | // { |
1529 | os = Environment.OSVersion.ToString(); | 1630 | // os = Environment.OSVersion.ToString(); |
1530 | } | 1631 | // } |
1531 | else | 1632 | // else |
1532 | { | 1633 | // { |
1533 | os = ReadEtcIssue(); | 1634 | // os = ReadEtcIssue(); |
1534 | } | 1635 | // } |
1535 | 1636 | // | |
1536 | if (os.Length > 45) | 1637 | // if (os.Length > 45) |
1537 | { | 1638 | // { |
1538 | os = os.Substring(0, 45); | 1639 | // os = os.Substring(0, 45); |
1539 | } | 1640 | // } |
1540 | 1641 | ||
1541 | return os; | 1642 | return os; |
1542 | } | 1643 | } |
@@ -1645,7 +1746,7 @@ namespace OpenSim.Framework | |||
1645 | 1746 | ||
1646 | public static Guid GetHashGuid(string data, string salt) | 1747 | public static Guid GetHashGuid(string data, string salt) |
1647 | { | 1748 | { |
1648 | byte[] hash = ComputeMD5Hash(data + salt); | 1749 | byte[] hash = ComputeMD5Hash(data + salt, Encoding.Default); |
1649 | 1750 | ||
1650 | //string s = BitConverter.ToString(hash); | 1751 | //string s = BitConverter.ToString(hash); |
1651 | 1752 | ||
@@ -1792,6 +1893,32 @@ namespace OpenSim.Framework | |||
1792 | return found.ToArray(); | 1893 | return found.ToArray(); |
1793 | } | 1894 | } |
1794 | 1895 | ||
1896 | public static string ServerURI(string uri) | ||
1897 | { | ||
1898 | if (uri == string.Empty) | ||
1899 | return string.Empty; | ||
1900 | |||
1901 | // Get rid of eventual slashes at the end | ||
1902 | uri = uri.TrimEnd('/'); | ||
1903 | |||
1904 | IPAddress ipaddr1 = null; | ||
1905 | string port1 = ""; | ||
1906 | try | ||
1907 | { | ||
1908 | ipaddr1 = Util.GetHostFromURL(uri); | ||
1909 | } | ||
1910 | catch { } | ||
1911 | |||
1912 | try | ||
1913 | { | ||
1914 | port1 = uri.Split(new char[] { ':' })[2]; | ||
1915 | } | ||
1916 | catch { } | ||
1917 | |||
1918 | // We tried our best to convert the domain names to IP addresses | ||
1919 | return (ipaddr1 != null) ? "http://" + ipaddr1.ToString() + ":" + port1 : uri; | ||
1920 | } | ||
1921 | |||
1795 | /// <summary> | 1922 | /// <summary> |
1796 | /// Convert a string to a byte format suitable for transport in an LLUDP packet. The output is truncated to 256 bytes if necessary. | 1923 | /// Convert a string to a byte format suitable for transport in an LLUDP packet. The output is truncated to 256 bytes if necessary. |
1797 | /// </summary> | 1924 | /// </summary> |
@@ -1818,17 +1945,26 @@ namespace OpenSim.Framework | |||
1818 | /// <returns></returns> | 1945 | /// <returns></returns> |
1819 | public static byte[] StringToBytes256(string str) | 1946 | public static byte[] StringToBytes256(string str) |
1820 | { | 1947 | { |
1821 | if (String.IsNullOrEmpty(str)) { return Utils.EmptyBytes; } | 1948 | if (String.IsNullOrEmpty(str)) |
1822 | if (str.Length > 254) str = str.Remove(254); | 1949 | return Utils.EmptyBytes; |
1823 | if (!str.EndsWith("\0")) { str += "\0"; } | 1950 | |
1951 | if (!str.EndsWith("\0")) | ||
1952 | str += "\0"; | ||
1824 | 1953 | ||
1825 | // Because this is UTF-8 encoding and not ASCII, it's possible we | 1954 | // Because this is UTF-8 encoding and not ASCII, it's possible we |
1826 | // might have gotten an oversized array even after the string trim | 1955 | // might have gotten an oversized array even after the string trim |
1827 | byte[] data = UTF8.GetBytes(str); | 1956 | byte[] data = UTF8.GetBytes(str); |
1957 | |||
1828 | if (data.Length > 256) | 1958 | if (data.Length > 256) |
1829 | { | 1959 | { |
1830 | Array.Resize<byte>(ref data, 256); | 1960 | int cut = 255; |
1831 | data[255] = 0; | 1961 | if((data[cut] & 0x80 ) != 0 ) |
1962 | { | ||
1963 | while(cut > 0 && (data[cut] & 0xc0) != 0xc0) | ||
1964 | cut--; | ||
1965 | } | ||
1966 | Array.Resize<byte>(ref data, cut + 1); | ||
1967 | data[cut] = 0; | ||
1832 | } | 1968 | } |
1833 | 1969 | ||
1834 | return data; | 1970 | return data; |
@@ -1860,17 +1996,26 @@ namespace OpenSim.Framework | |||
1860 | /// <returns></returns> | 1996 | /// <returns></returns> |
1861 | public static byte[] StringToBytes1024(string str) | 1997 | public static byte[] StringToBytes1024(string str) |
1862 | { | 1998 | { |
1863 | if (String.IsNullOrEmpty(str)) { return Utils.EmptyBytes; } | 1999 | if (String.IsNullOrEmpty(str)) |
1864 | if (str.Length > 1023) str = str.Remove(1023); | 2000 | return Utils.EmptyBytes; |
1865 | if (!str.EndsWith("\0")) { str += "\0"; } | 2001 | |
2002 | if (!str.EndsWith("\0")) | ||
2003 | str += "\0"; | ||
1866 | 2004 | ||
1867 | // Because this is UTF-8 encoding and not ASCII, it's possible we | 2005 | // Because this is UTF-8 encoding and not ASCII, it's possible we |
1868 | // might have gotten an oversized array even after the string trim | 2006 | // might have gotten an oversized array even after the string trim |
1869 | byte[] data = UTF8.GetBytes(str); | 2007 | byte[] data = UTF8.GetBytes(str); |
2008 | |||
1870 | if (data.Length > 1024) | 2009 | if (data.Length > 1024) |
1871 | { | 2010 | { |
1872 | Array.Resize<byte>(ref data, 1024); | 2011 | int cut = 1023; |
1873 | data[1023] = 0; | 2012 | if((data[cut] & 0x80 ) != 0 ) |
2013 | { | ||
2014 | while(cut > 0 && (data[cut] & 0xc0) != 0xc0) | ||
2015 | cut--; | ||
2016 | } | ||
2017 | Array.Resize<byte>(ref data, cut + 1); | ||
2018 | data[cut] = 0; | ||
1874 | } | 2019 | } |
1875 | 2020 | ||
1876 | return data; | 2021 | return data; |
@@ -1986,7 +2131,7 @@ namespace OpenSim.Framework | |||
1986 | 2131 | ||
1987 | STPStartInfo startInfo = new STPStartInfo(); | 2132 | STPStartInfo startInfo = new STPStartInfo(); |
1988 | startInfo.ThreadPoolName = "Util"; | 2133 | startInfo.ThreadPoolName = "Util"; |
1989 | startInfo.IdleTimeout = 2000; | 2134 | startInfo.IdleTimeout = 20000; |
1990 | startInfo.MaxWorkerThreads = maxThreads; | 2135 | startInfo.MaxWorkerThreads = maxThreads; |
1991 | startInfo.MinWorkerThreads = minThreads; | 2136 | startInfo.MinWorkerThreads = minThreads; |
1992 | 2137 | ||
@@ -2539,6 +2684,13 @@ namespace OpenSim.Framework | |||
2539 | return tcA - tcB; | 2684 | return tcA - tcB; |
2540 | } | 2685 | } |
2541 | 2686 | ||
2687 | // returns a timestamp in ms as double | ||
2688 | // using the time resolution avaiable to StopWatch | ||
2689 | public static double GetTimeStampMS() | ||
2690 | { | ||
2691 | return (double)Stopwatch.GetTimestamp() * TimeStampClockPeriodMS; | ||
2692 | } | ||
2693 | |||
2542 | /// <summary> | 2694 | /// <summary> |
2543 | /// Formats a duration (given in milliseconds). | 2695 | /// Formats a duration (given in milliseconds). |
2544 | /// </summary> | 2696 | /// </summary> |