29 using System.Collections;
30 using System.Collections.Generic;
32 using System.Diagnostics;
33 using System.Globalization;
35 using System.IO.Compression;
37 using System.Net.Sockets;
38 using System.Reflection;
39 using System.Runtime.InteropServices;
40 using System.Runtime.Serialization;
41 using System.Runtime.Serialization.Formatters.Binary;
42 using System.Security.Cryptography;
44 using System.Text.RegularExpressions;
46 using System.Threading;
48 using log4net.Appender;
52 using OpenMetaverse.StructuredData;
54 using System.Collections.Concurrent;
55 using System.Collections.Specialized;
58 namespace OpenSim.Framework
81 All = (1 << 13) | (1 << 14) | (1 << 15) | (1 << 19)
111 public string Name {
get; set; }
112 public STPStartInfo STPStartInfo {
get; set; }
113 public WIGStartInfo WIGStartInfo {
get; set; }
114 public bool IsIdle {
get; set; }
115 public bool IsShuttingDown {
get; set; }
116 public int MaxThreads {
get; set; }
117 public int MinThreads {
get; set; }
118 public int InUseThreads {
get; set; }
119 public int ActiveThreads {
get; set; }
120 public int WaitingCallbacks {
get; set; }
121 public int MaxConcurrentWorkItems {
get; set; }
127 public static class Util
129 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
138 public static int LogThreadPool {
get; set; }
139 public static bool LogOverloads {
get; set; }
141 public static readonly
int MAX_THREADPOOL_LEVEL = 3;
143 public static double TimeStampClockPeriodMS;
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));
153 private static uint nextXferID = 5000;
154 private static Random randomClass =
new ThreadSafeRandom();
157 private static string regexInvalidFileChars =
"[" +
new String(Path.GetInvalidFileNameChars()) +
"]";
158 private static string regexInvalidPathChars =
"[" +
new String(Path.GetInvalidPathChars()) +
"]";
159 private static object XferLock =
new object();
167 private static Timer m_threadPoolWatchdog;
170 public static readonly DateTime UnixEpoch =
171 DateTime.ParseExact(
"1970-01-01 00:00:00 +0",
"yyyy-MM-dd hh:mm:ss z", DateTimeFormatInfo.InvariantInfo).ToUniversalTime();
173 private static readonly
string rawUUIDPattern
174 =
"[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}";
175 public static readonly Regex PermissiveUUIDPattern =
new Regex(rawUUIDPattern);
176 public static readonly Regex UUIDPattern =
new Regex(
string.Format(
"^{0}$", rawUUIDPattern));
178 public static FireAndForgetMethod DefaultFireAndForgetMethod = FireAndForgetMethod.SmartThreadPool;
181 public static bool IsPlatformMono
183 get {
return Type.GetType(
"Mono.Runtime") != null; }
192 public static string ExecutingDirectory()
194 return Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
204 public static double lerp(
double a,
double b,
double c)
206 return (b*a) + (c*(1 - a));
224 public static double lerp2D(
double x,
double y,
double a,
double b,
double c,
double d)
226 return lerp(y, lerp(x, a, b), lerp(x, c, d));
229 public static Encoding UTF8 = Encoding.UTF8;
230 public static Encoding UTF8NoBomEncoding =
new UTF8Encoding(
false);
235 public static UUID BLANK_TEXTURE_UUID =
new UUID(
"5748decc-f629-461c-9a36-a35a221fe21f");
237 #region Vector Equations
245 public static double GetDistanceTo(Vector3 a, Vector3 b)
247 float dx = a.X - b.X;
248 float dy = a.Y - b.Y;
249 float dz = a.Z - b.Z;
250 return Math.Sqrt(dx * dx + dy * dy + dz * dz);
260 public static bool DistanceLessThan(Vector3 a, Vector3 b,
double amount)
262 float dx = a.X - b.X;
263 float dy = a.Y - b.Y;
264 float dz = a.Z - b.Z;
265 return (dx*dx + dy*dy + dz*dz) < (amount*amount);
273 public static double GetMagnitude(Vector3 a)
275 return Math.Sqrt((a.X * a.X) + (a.Y * a.Y) + (a.Z * a.Z));
284 public static Vector3 GetNormalizedVector(Vector3 a)
286 Vector3 v =
new Vector3(a.X, a.Y, a.Z);
295 public static bool IsZeroVector(Vector3 v)
297 if (v.X == 0 && v.Y == 0 && v.Z == 0)
307 public static Quaternion Axes2Rot(Vector3 fwd, Vector3 left, Vector3 up)
310 float tr = (float) (fwd.X + left.Y + up.Z + 1.0);
314 s = (float) (0.5 / Math.Sqrt(tr));
315 return new Quaternion(
318 (fwd.Y - left.X) * s,
323 float max = (left.Y > up.Z) ? left.Y : up.Z;
327 s = (float) (Math.Sqrt(fwd.X - (left.Y + up.Z) + 1.0));
328 float x = (float) (s * 0.5);
329 s = (float) (0.5 / s);
330 return new Quaternion(
332 (fwd.Y + left.X) * s,
334 (left.Z - up.Y) * s);
336 else if (max == left.Y)
338 s = (float) (Math.Sqrt(left.Y - (up.Z + fwd.X) + 1.0));
339 float y = (float) (s * 0.5);
340 s = (float) (0.5 / s);
341 return new Quaternion(
342 (fwd.Y + left.X) * s,
349 s = (float) (Math.Sqrt(up.Z - (fwd.X + left.Y) + 1.0));
350 float z = (float) (s * 0.5);
351 s = (float) (0.5 / s);
352 return new Quaternion(
356 (fwd.Y - left.X) * s);
361 public static Random RandomClass
363 get {
return randomClass; }
366 public static ulong UIntsToLong(uint X, uint Y)
368 return Utils.UIntsToLong(X, Y);
375 public static ulong RegionWorldLocToHandle(uint X, uint Y)
377 return Utils.UIntsToLong(X, Y);
380 public static ulong RegionLocToHandle(uint X, uint Y)
382 return Utils.UIntsToLong(Util.RegionToWorldLoc(X), Util.RegionToWorldLoc(Y));
385 public static void RegionHandleToWorldLoc(ulong handle, out uint X, out uint Y)
387 X = (uint)(handle >> 32);
388 Y = (uint)(handle & (ulong)uint.MaxValue);
391 public static void RegionHandleToRegionLoc(ulong handle, out uint X, out uint Y)
394 RegionHandleToWorldLoc(handle, out worldX, out worldY);
395 X = WorldToRegionLoc(worldX);
396 Y = WorldToRegionLoc(worldY);
403 public static uint WorldToRegionLoc(uint worldCoord)
405 return worldCoord / Constants.RegionSize;
409 public static uint RegionToWorldLoc(uint regionCoord)
411 return regionCoord * Constants.RegionSize;
414 public static T Clamp<T>(T x, T min, T max)
415 where T : IComparable<T>
417 return x.CompareTo(max) > 0 ? max :
418 x.CompareTo(min) < 0 ? min :
423 public static Vector3 ClampV(Vector3 x,
float max)
425 float lenSq = x.LengthSquared();
426 if (lenSq > (max * max))
428 x = x / x.Length() * max;
439 public static bool IsNanOrInfinity(Vector3 v)
441 if (
float.IsNaN(v.X) ||
float.IsNaN(v.Y) || float.IsNaN(v.Z))
444 if (
float.IsInfinity(v.X) || float.IsInfinity(v.Y) ||
float.IsNaN(v.Z))
451 public static bool InRange<T>(T x, T min, T max)
452 where T : IComparable<T>
454 return x.CompareTo(max) <= 0 && x.CompareTo(min) >= 0;
457 public static uint GetNextXferID()
468 public static string GetFileName(
string file)
472 if (Environment.OSVersion.Platform == PlatformID.Unix)
479 if (Environment.OSVersion.Platform == PlatformID.Win32NT)
481 if (!Directory.Exists(
"%APPDATA%\\OpenSim\\"))
483 Directory.CreateDirectory(
"%APPDATA%\\OpenSim");
486 return "%APPDATA%\\OpenSim\\" + file;
503 public static string GetFormattedXml(
OSD osd)
505 return GetFormattedXml(OSDParser.SerializeLLSDXmlString(osd));
516 public static string GetFormattedXml(
string rawXml)
518 XmlDocument xd =
new XmlDocument();
521 StringBuilder sb =
new StringBuilder();
522 StringWriter sw =
new StringWriter(sb);
524 XmlTextWriter xtw =
new XmlTextWriter(sw);
525 xtw.Formatting = Formatting.Indented;
536 return sb.ToString();
539 public static byte[] DocToBytes(XmlDocument doc)
541 using (MemoryStream ms =
new MemoryStream())
542 using (XmlTextWriter xw =
new XmlTextWriter(ms, null))
544 xw.Formatting = Formatting.Indented;
556 public static bool IsWindows()
558 PlatformID platformId = Environment.OSVersion.Platform;
560 return (platformId == PlatformID.Win32NT
561 || platformId == PlatformID.Win32S
562 || platformId == PlatformID.Win32Windows
563 || platformId == PlatformID.WinCE);
566 public static bool LoadArchSpecificWindowsDll(
string libraryName)
568 return LoadArchSpecificWindowsDll(libraryName,
string.Empty);
571 public static bool LoadArchSpecificWindowsDll(
string libraryName,
string path)
579 string nativeLibraryPath;
581 if (Util.Is64BitProcess())
582 nativeLibraryPath = Path.Combine(Path.Combine(path,
"lib64"), libraryName);
584 nativeLibraryPath = Path.Combine(Path.Combine(path,
"lib32"), libraryName);
586 m_log.DebugFormat(
"[UTIL]: Loading native Windows library at {0}", nativeLibraryPath);
588 if (Util.LoadLibrary(nativeLibraryPath) == IntPtr.Zero)
591 "[UTIL]: Couldn't find native Windows library at {0}", nativeLibraryPath);
601 public static bool IsEnvironmentSupported(ref
string reason)
604 if (Environment.Version.Major < 2)
606 reason =
".NET 1.0/1.1 lacks components that is used by OpenSim";
611 if (Environment.OSVersion.Platform == PlatformID.Win32Windows &&
612 Environment.OSVersion.Platform != PlatformID.Win32NT)
614 reason =
"Windows 95/98/ME will not run OpenSim";
619 if (Environment.OSVersion.Version.Major == 5 &&
620 Environment.OSVersion.Version.Minor == 0)
622 reason =
"Please update to Windows XP Service Pack 2 or Server2003";
629 public static int UnixTimeSinceEpoch()
631 return ToUnixTime(DateTime.UtcNow);
634 public static int ToUnixTime(DateTime stamp)
636 TimeSpan t = stamp.ToUniversalTime() - UnixEpoch;
637 return (
int)t.TotalSeconds;
640 public static DateTime ToDateTime(ulong seconds)
642 return UnixEpoch.AddSeconds(seconds);
645 public static DateTime ToDateTime(
int seconds)
647 return UnixEpoch.AddSeconds(seconds);
656 public static string Md5Hash(
string data)
658 return Md5Hash(data, Encoding.Default);
661 public static string Md5Hash(
string data, Encoding encoding)
663 byte[] dataMd5 = ComputeMD5Hash(data, encoding);
664 StringBuilder sb =
new StringBuilder();
665 for (
int i = 0; i < dataMd5.Length; i++)
666 sb.AppendFormat(
"{0:x2}", dataMd5[i]);
667 return sb.ToString();
670 private static byte[] ComputeMD5Hash(
string data, Encoding encoding)
672 MD5 md5 = MD5.Create();
673 return md5.ComputeHash(encoding.GetBytes(data));
682 public static string SHA1Hash(
string data, Encoding enc)
684 return SHA1Hash(enc.GetBytes(data));
687 public static string SHA1Hash(
string data)
689 return SHA1Hash(Encoding.Default.GetBytes(data));
697 public static string SHA1Hash(byte[] data)
699 byte[] hash = ComputeSHA1Hash(data);
700 return BitConverter.ToString(hash).Replace(
"-",
String.Empty);
703 private static byte[] ComputeSHA1Hash(byte[] src)
705 SHA1CryptoServiceProvider SHA1 =
new SHA1CryptoServiceProvider();
706 return SHA1.ComputeHash(src);
709 public static int fast_distance2d(
int x,
int y)
714 int min = Math.Min(x, y);
716 return (x + y - (min >> 1) - (min >> 2) + (min >> 4));
726 public static bool IsInsideBox(Vector3 v, Vector3 min, Vector3 max)
728 return v.X >= min.X & v.Y >= min.Y && v.Z >= min.Z
729 && v.X <= max.X && v.Y <= max.Y && v.Z <= max.Z;
740 public static bool IsOutsideView(
float drawdist, uint oldx, uint newx, uint oldy, uint newy,
741 int oldsizex,
int oldsizey,
int newsizex,
int newsizey)
745 oldx *= Constants.RegionSize;
746 newx *= Constants.RegionSize;
747 if (oldx + oldsizex + drawdist < newx)
749 if (newx + newsizex + drawdist < oldx)
752 oldy *= Constants.RegionSize;
753 newy *= Constants.RegionSize;
754 if (oldy + oldsizey + drawdist < newy)
756 if (newy + newsizey + drawdist < oldy)
762 public static string FieldToString(byte[] bytes)
764 return FieldToString(bytes,
String.Empty);
777 public static string FieldToString(byte[] bytes,
string fieldName)
780 if (bytes.Length == 0)
return String.Empty;
782 StringBuilder output =
new StringBuilder();
783 bool printable =
true;
785 for (
int i = 0; i < bytes.Length; ++i)
788 if ((bytes[i] < 0x20 || bytes[i] > 0x7E) && bytes[i] != 0x09
789 && bytes[i] != 0x0D && bytes[i] != 0x0A && bytes[i] != 0x00)
798 if (fieldName.Length > 0)
800 output.Append(fieldName);
804 output.Append(CleanString(Util.UTF8.GetString(bytes, 0, bytes.Length - 1)));
808 for (
int i = 0; i < bytes.Length; i += 16)
811 output.Append(Environment.NewLine);
812 if (fieldName.Length > 0)
814 output.Append(fieldName);
818 for (
int j = 0; j < 16; j++)
820 if ((i + j) < bytes.Length)
821 output.Append(
String.Format(
"{0:X2} ", bytes[i + j]));
826 for (
int j = 0; j < 16 && (i + j) < bytes.Length; j++)
828 if (bytes[i + j] >= 0x20 && bytes[i + j] < 0x7E)
829 output.Append((char) bytes[i + j]);
836 return output.ToString();
844 public static IPAddress GetHostFromURL(
string url)
846 return GetHostFromDNS(url.Split(
new char[] {
'/',
':'})[3]);
854 public static IPAddress GetHostFromDNS(
string dnsAddress)
858 if (IPAddress.TryParse(dnsAddress, out ipa))
861 IPAddress[] hosts = null;
866 hosts = Dns.GetHostEntry(dnsAddress).AddressList;
870 m_log.WarnFormat(
"[UTIL]: An error occurred while resolving host name {0}, {1}", dnsAddress, e);
876 foreach (IPAddress host
in hosts)
878 if (host.AddressFamily == AddressFamily.InterNetwork)
884 if (hosts.Length > 0)
890 public static Uri GetURI(
string protocol,
string hostname,
int port,
string path)
892 return new UriBuilder(protocol, hostname, port, path).Uri;
899 public static IPAddress[] GetLocalHosts()
901 return Dns.GetHostAddresses(Dns.GetHostName());
904 public static IPAddress GetLocalHost()
906 IPAddress[] iplist = GetLocalHosts();
908 if (iplist.Length == 0)
910 IPAddress[] loopback = Dns.GetHostAddresses(
"localhost");
911 IPAddress localhost = loopback[0];
916 foreach (IPAddress host
in iplist)
918 if (!IPAddress.IsLoopback(host) && host.AddressFamily == AddressFamily.InterNetwork)
924 if (iplist.Length > 0)
926 foreach (IPAddress host
in iplist)
928 if (host.AddressFamily == AddressFamily.InterNetwork)
945 public static bool ParseForeignAssetID(
string id, out
string url, out
string assetID)
948 assetID = String.Empty;
951 if (
UUID.TryParse(
id, out uuid))
953 assetID = uuid.ToString();
957 if ((
id.Length == 0) || (
id[0] !=
'h' &&
id[0] !=
'H'))
961 if (!Uri.TryCreate(
id, UriKind.Absolute, out assetUri) || assetUri.Scheme != Uri.UriSchemeHttp)
965 if (assetUri.Query !=
string.Empty)
967 NameValueCollection qscoll = HttpUtility.ParseQueryString(assetUri.Query);
968 assetID = qscoll[
"id"];
970 url = id.Replace(assetID,
"");
976 url =
"http://" + assetUri.Authority;
977 assetID = assetUri.LocalPath.Trim(
new char[] {
'/' });
980 if (!
UUID.TryParse(assetID, out uuid))
991 public static string safePath(
string path)
993 return Regex.Replace(path, regexInvalidPathChars, String.Empty);
1001 public static string safeFileName(
string filename)
1003 return Regex.Replace(filename, regexInvalidFileChars, String.Empty);
1011 public static string homeDir()
1020 public static string assetsDir()
1022 return Path.Combine(configDir(),
"assets");
1025 public static string inventoryDir()
1027 return Path.Combine(configDir(),
"inventory");
1030 public static string configDir()
1035 public static string dataDir()
1040 public static string logFile()
1042 foreach (IAppender appender
in LogManager.GetRepository().GetAppenders())
1044 if (appender is FileAppender)
1046 return ((FileAppender)appender).File;
1050 return "./OpenSim.log";
1053 public static string logDir()
1055 return Path.GetDirectoryName(logFile());
1059 public static string GetUniqueFilename(
string FileName)
1064 if (
File.Exists(FileName))
1066 FileInfo f =
new FileInfo(FileName);
1068 if (!
String.IsNullOrEmpty(f.Extension))
1070 Name = f.FullName.Substring(0, f.FullName.LastIndexOf(
'.'));
1077 while (
File.Exists(FileName))
1080 FileName = Name + count + f.Extension;
1086 #region Nini (config) related Methods
1088 public static IConfigSource ConvertDataRowToXMLConfig(DataRow row,
string fileName)
1090 if (!
File.Exists(fileName))
1094 XmlConfigSource config =
new XmlConfigSource(fileName);
1095 AddDataRowToConfig(config, row);
1101 public static void AddDataRowToConfig(IConfigSource config, DataRow row)
1103 config.Configs.Add((string) row[0]);
1104 for (
int i = 0; i < row.Table.Columns.Count; i++)
1106 config.Configs[(string) row[0]].Set(row.Table.Columns[i].ColumnName, row[i]);
1110 public static string GetConfigVarWithDefaultSection(IConfigSource config,
string varname,
string section)
1113 IConfig cnf = config.Configs[
"Startup"];
1115 return string.Empty;
1116 string val = cnf.GetString(varname, string.Empty);
1119 if (!
string.IsNullOrEmpty(section))
1121 cnf = config.Configs[section];
1123 val = cnf.GetString(varname, val);
1139 public static T GetConfigVarFromSections<T>(IConfigSource config,
string varname,
string[] sections)
1141 return GetConfigVarFromSections<T>(config, varname, sections,
default(T));
1158 public static T GetConfigVarFromSections<T>(IConfigSource config,
string varname,
string[] sections,
object val)
1160 foreach (
string section
in sections)
1162 IConfig cnf = config.Configs[section];
1166 if (typeof(T) == typeof(String))
1167 val = cnf.GetString(varname, (
string)val);
1168 else if (typeof(T) == typeof(Boolean))
1169 val = cnf.GetBoolean(varname, (bool)val);
1170 else if (typeof(T) == typeof(Int32))
1171 val = cnf.GetInt(varname, (int)val);
1172 else if (typeof(T) == typeof(
float))
1173 val = cnf.GetFloat(varname, (float)val);
1175 m_log.ErrorFormat(
"[UTIL]: Unhandled type {0}", typeof(T));
1181 public static void MergeEnvironmentToConfig(IConfigSource ConfigSource)
1183 IConfig enVars = ConfigSource.Configs[
"Environment"];
1185 if( enVars != null )
1188 EnvConfigSource envConfigSource =
new EnvConfigSource();
1190 string[] env_keys = enVars.GetKeys();
1191 foreach (
string key in env_keys )
1193 envConfigSource.AddEnv(
key, string.Empty);
1196 envConfigSource.LoadEnv();
1198 ConfigSource.Merge(envConfigSource);
1199 ConfigSource.ExpandKeyValues();
1203 public static T ReadSettingsFromIniFile<T>(IConfig config, T settingsClass)
1205 Type settingsType = settingsClass.GetType();
1207 FieldInfo[] fieldInfos = settingsType.GetFields();
1208 foreach (FieldInfo fieldInfo
in fieldInfos)
1210 if (!fieldInfo.IsStatic)
1212 if (fieldInfo.FieldType == typeof(System.String))
1214 fieldInfo.SetValue(settingsClass, config.Get(fieldInfo.Name, (string)fieldInfo.GetValue(settingsClass)));
1216 else if (fieldInfo.FieldType == typeof(System.Boolean))
1218 fieldInfo.SetValue(settingsClass, config.GetBoolean(fieldInfo.Name, (bool)fieldInfo.GetValue(settingsClass)));
1220 else if (fieldInfo.FieldType == typeof(System.Int32))
1222 fieldInfo.SetValue(settingsClass, config.GetInt(fieldInfo.Name, (int)fieldInfo.GetValue(settingsClass)));
1224 else if (fieldInfo.FieldType == typeof(System.Single))
1226 fieldInfo.SetValue(settingsClass, config.GetFloat(fieldInfo.Name, (float)fieldInfo.GetValue(settingsClass)));
1228 else if (fieldInfo.FieldType == typeof(System.UInt32))
1230 fieldInfo.SetValue(settingsClass, Convert.ToUInt32(config.Get(fieldInfo.Name, ((uint)fieldInfo.GetValue(settingsClass)).ToString())));
1235 PropertyInfo[] propertyInfos = settingsType.GetProperties();
1236 foreach (PropertyInfo propInfo
in propertyInfos)
1238 if ((propInfo.CanRead) && (propInfo.CanWrite))
1240 if (propInfo.PropertyType == typeof(System.String))
1242 propInfo.SetValue(settingsClass, config.Get(propInfo.Name, (string)propInfo.GetValue(settingsClass, null)), null);
1244 else if (propInfo.PropertyType == typeof(System.Boolean))
1246 propInfo.SetValue(settingsClass, config.GetBoolean(propInfo.Name, (bool)propInfo.GetValue(settingsClass, null)), null);
1248 else if (propInfo.PropertyType == typeof(System.Int32))
1250 propInfo.SetValue(settingsClass, config.GetInt(propInfo.Name, (int)propInfo.GetValue(settingsClass, null)), null);
1252 else if (propInfo.PropertyType == typeof(System.Single))
1254 propInfo.SetValue(settingsClass, config.GetFloat(propInfo.Name, (float)propInfo.GetValue(settingsClass, null)), null);
1256 if (propInfo.PropertyType == typeof(System.UInt32))
1258 propInfo.SetValue(settingsClass, Convert.ToUInt32(config.Get(propInfo.Name, ((uint)propInfo.GetValue(settingsClass, null)).ToString())), null);
1263 return settingsClass;
1277 public static bool MergeConfigurationFile(IConfigSource config,
string configFileName,
string exampleConfigFile, out
string configFilePath, out
bool created)
1280 configFilePath = string.Empty;
1282 IConfig cnf = config.Configs[
"Startup"];
1285 m_log.WarnFormat(
"[UTILS]: Startup section doesn't exist");
1289 string configDirectory = cnf.GetString(
"ConfigDirectory",
".");
1290 string configFile = Path.Combine(configDirectory, configFileName);
1292 if (!
File.Exists(configFile) && !string.IsNullOrEmpty(exampleConfigFile))
1296 if (!Directory.Exists(configDirectory))
1297 Directory.CreateDirectory(configDirectory);
1301 File.Copy(exampleConfigFile, configFile);
1306 m_log.WarnFormat(
"[UTILS]: Exception copying configuration file {0} to {1}: {2}", configFile, exampleConfigFile, e.Message);
1311 if (
File.Exists(configFile))
1314 config.Merge(
new IniConfigSource(configFile));
1315 config.ExpandKeyValues();
1316 configFilePath = configFile;
1325 public static float Clip(
float x,
float min,
float max)
1327 return Math.Min(Math.Max(x, min), max);
1330 public static int Clip(
int x,
int min,
int max)
1332 return Math.Min(Math.Max(x, min), max);
1335 public static Vector3 Clip(Vector3 vec,
float min,
float max)
1337 return new Vector3(Clip(vec.X, min, max), Clip(vec.Y, min, max),
1338 Clip(vec.Z, min, max));
1346 public static String ToRawUuidString(UUID UUID)
1348 return UUID.Guid.ToString(
"n");
1351 public static string CleanString(
string input)
1353 if (input.Length == 0)
1356 int clip = input.Length;
1359 int pos = input.IndexOf(
"\0");
1360 if (pos != -1 && pos < clip)
1364 pos = input.IndexOf(
"\r");
1365 if (pos != -1 && pos < clip)
1369 pos = input.IndexOf(
"\n");
1370 if (pos != -1 && pos < clip)
1374 return input.Substring(0, clip);
1382 public static string ReadEtcIssue()
1386 StreamReader sr =
new StreamReader(
"/etc/issue.net");
1387 string issue = sr.ReadToEnd();
1397 public static void SerializeToFile(
string filename, Object obj)
1399 IFormatter formatter =
new BinaryFormatter();
1400 Stream stream = null;
1404 stream =
new FileStream(
1405 filename, FileMode.Create,
1406 FileAccess.Write, FileShare.None);
1408 formatter.Serialize(stream, obj);
1412 m_log.Error(e.ToString());
1423 public static Object DeserializeFromFile(
string filename)
1425 IFormatter formatter =
new BinaryFormatter();
1426 Stream stream = null;
1431 stream =
new FileStream(
1432 filename, FileMode.Open,
1433 FileAccess.Read, FileShare.None);
1435 ret = formatter.Deserialize(stream);
1439 m_log.Error(e.ToString());
1452 public static string Compress(
string text)
1454 byte[] buffer = Util.UTF8.GetBytes(text);
1455 MemoryStream memory =
new MemoryStream();
1458 compressor.Write(buffer, 0, buffer.Length);
1461 memory.Position = 0;
1463 byte[] compressed =
new byte[memory.Length];
1464 memory.Read(compressed, 0, compressed.Length);
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);
1472 public static string Decompress(
string compressedText)
1474 byte[] compressedBuffer = Convert.FromBase64String(compressedText);
1475 using (MemoryStream memory =
new MemoryStream())
1477 int msgLength = BitConverter.ToInt32(compressedBuffer, 0);
1478 memory.Write(compressedBuffer, 4, compressedBuffer.Length - 4);
1480 byte[] buffer =
new byte[msgLength];
1482 memory.Position = 0;
1485 decompressor.Read(buffer, 0, buffer.Length);
1488 return Util.UTF8.GetString(buffer);
1501 public static Stream
Copy(Stream inputStream)
1503 if (!inputStream.CanSeek)
1504 throw new ArgumentException(
"Util.Copy(Stream inputStream) must receive an inputStream that can seek");
1506 const int readSize = 256;
1507 byte[] buffer =
new byte[readSize];
1508 MemoryStream ms =
new MemoryStream();
1510 int count = inputStream.Read(buffer, 0, readSize);
1514 ms.Write(buffer, 0, count);
1515 count = inputStream.Read(buffer, 0, readSize);
1519 inputStream.Position = 0;
1524 public static XmlRpcResponse XmlRpcCommand(
string url,
string methodName, params
object[] args)
1526 return SendXmlRpcCommand(url, methodName, args);
1529 public static XmlRpcResponse SendXmlRpcCommand(
string url,
string methodName,
object[] args)
1531 XmlRpcRequest client =
new XmlRpcRequest(methodName, args);
1532 return client.Send(url, 6000);
1539 public static XmlRpcResponse CreateUnknownUserErrorResponse()
1541 XmlRpcResponse response =
new XmlRpcResponse();
1542 Hashtable responseData =
new Hashtable();
1543 responseData[
"error_type"] =
"unknown_user";
1544 responseData[
"error_desc"] =
"The user requested is not in the database";
1546 response.Value = responseData;
1559 public static ulong BytesToUInt64Big(byte[] bytes)
1561 if (bytes.Length < 8)
return 0;
1562 return ((ulong)bytes[0] << 56) | ((ulong)bytes[1] << 48) | ((ulong)bytes[2] << 40) | ((ulong)bytes[3] << 32) |
1563 ((ulong)bytes[4] << 24) | ((ulong)bytes[5] << 16) | ((ulong)bytes[6] << 8) | (ulong)bytes[7];
1567 public static UUID BuildFakeParcelID(ulong regionHandle, uint x, uint y)
1571 (byte)regionHandle, (byte)(regionHandle >> 8), (byte)(regionHandle >> 16), (byte)(regionHandle >> 24),
1572 (byte)(regionHandle >> 32), (byte)(regionHandle >> 40), (byte)(regionHandle >> 48), (byte)(regionHandle >> 56),
1573 (byte)x, (byte)(x >> 8), 0, 0,
1574 (byte)y, (byte)(y >> 8), 0, 0 };
1575 return new UUID(bytes, 0);
1578 public static UUID BuildFakeParcelID(ulong regionHandle, uint x, uint y, uint z)
1582 (byte)regionHandle, (byte)(regionHandle >> 8), (byte)(regionHandle >> 16), (byte)(regionHandle >> 24),
1583 (byte)(regionHandle >> 32), (byte)(regionHandle >> 40), (byte)(regionHandle >> 48), (byte)(regionHandle >> 56),
1584 (byte)x, (byte)(x >> 8), (byte)z, (byte)(z >> 8),
1585 (byte)y, (byte)(y >> 8), 0, 0 };
1586 return new UUID(bytes, 0);
1589 public static void ParseFakeParcelID(UUID parcelID, out ulong regionHandle, out uint x, out uint y)
1591 byte[] bytes = parcelID.GetBytes();
1592 regionHandle = Utils.BytesToUInt64(bytes);
1593 x = Utils.BytesToUInt(bytes, 8) & 0xffff;
1594 y = Utils.BytesToUInt(bytes, 12) & 0xffff;
1597 public static void ParseFakeParcelID(UUID parcelID, out ulong regionHandle, out uint x, out uint y, out uint z)
1599 byte[] bytes = parcelID.GetBytes();
1600 regionHandle = Utils.BytesToUInt64(bytes);
1601 x = Utils.BytesToUInt(bytes, 8) & 0xffff;
1602 z = (Utils.BytesToUInt(bytes, 8) & 0xffff0000) >> 16;
1603 y = Utils.BytesToUInt(bytes, 12) & 0xffff;
1606 public static void FakeParcelIDToGlobalPosition(UUID parcelID, out uint x, out uint y)
1611 ParseFakeParcelID(parcelID, out regionHandle, out x, out y);
1612 Utils.LongToUInts(regionHandle, out rx, out ry);
1624 public static string GetOperatingSystemInformation()
1626 string os = String.Empty;
1645 public static string GetRuntimeInformation()
1647 string ru = String.Empty;
1649 if (Environment.OSVersion.Platform == PlatformID.Unix)
1652 if (Environment.OSVersion.Platform == PlatformID.MacOSX)
1670 public static bool isUUID(
string s)
1672 return UUIDPattern.IsMatch(s);
1675 public static string GetDisplayConnectionString(
string connectionString)
1677 int passPosition = 0;
1678 int passEndPosition = 0;
1679 string displayConnectionString = null;
1682 passPosition = connectionString.IndexOf(
"password", StringComparison.OrdinalIgnoreCase);
1683 passPosition = connectionString.IndexOf(
"=", passPosition);
1684 if (passPosition < connectionString.Length)
1686 passEndPosition = connectionString.IndexOf(
";", passPosition);
1688 displayConnectionString = connectionString.Substring(0, passPosition);
1689 displayConnectionString +=
"***";
1690 displayConnectionString += connectionString.Substring(passEndPosition, connectionString.Length - passEndPosition);
1692 return displayConnectionString;
1695 public static string Base64ToString(
string str)
1697 Decoder utf8Decode = Encoding.UTF8.GetDecoder();
1699 byte[] todecode_byte = Convert.FromBase64String(str);
1700 int charCount = utf8Decode.GetCharCount(todecode_byte, 0, todecode_byte.Length);
1701 char[] decoded_char =
new char[charCount];
1702 utf8Decode.GetChars(todecode_byte, 0, todecode_byte.Length, decoded_char, 0);
1703 string result =
new String(decoded_char);
1707 public static void BinaryToASCII(
char[] chars)
1709 for (
int i = 0; i < chars.Length; i++)
1712 if (ch < 32 || ch > 127)
1717 public static string BinaryToASCII(
string src)
1719 char[] chars = src.ToCharArray();
1720 BinaryToASCII(chars);
1721 return new String(chars);
1732 public static void ReadStream(Stream stream, byte[] data)
1735 int remaining = data.Length;
1737 while (remaining > 0)
1739 int read = stream.Read(data, offset, remaining);
1741 throw new EndOfStreamException(
String.Format(
"End of stream reached with {0} bytes left to read", remaining));
1747 public static Guid GetHashGuid(
string data,
string salt)
1749 byte[] hash = ComputeMD5Hash(data + salt, Encoding.Default);
1753 Guid guid =
new Guid(hash);
1758 public static byte ConvertMaturityToAccessLevel(uint maturity)
1778 public static uint ConvertAccessLevelToMaturity(byte maturity)
1782 else if (maturity <= 21)
1794 public static OSDMap GetOSDMap(Stream stream,
int length)
1796 byte[] data =
new byte[length];
1797 stream.Read(data, 0, length);
1798 string strdata = Util.UTF8.GetString(data);
1801 buffer = OSDParser.DeserializeJson(strdata);
1802 if (buffer.Type == OSDType.Map)
1810 public static OSDMap GetOSDMap(
string data)
1817 buffer = OSDParser.DeserializeJson(data);
1818 if (buffer.Type == OSDType.Map)
1826 m_log.Debug((
"[UTILS]: Got OSD of unexpected type " + buffer.Type.ToString()));
1830 catch (Exception ex)
1832 m_log.Debug(
"[UTILS]: exception on GetOSDMap " + ex.Message);
1837 public static string[] Glob(
string path)
1839 string vol=String.Empty;
1841 if (Path.VolumeSeparatorChar != Path.DirectorySeparatorChar)
1843 string[] vcomps = path.Split(
new char[] {Path.VolumeSeparatorChar}, 2, StringSplitOptions.RemoveEmptyEntries);
1845 if (vcomps.Length > 1)
1852 string[] comps = path.Split(
new char[] {Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar}, StringSplitOptions.RemoveEmptyEntries);
1858 path +=
new String(
new char[] {Path.VolumeSeparatorChar, Path.DirectorySeparatorChar});
1860 path =
new String(
new char[] {Path.DirectorySeparatorChar});
1862 List<string> paths =
new List<string>();
1863 List<string> found =
new List<string>();
1867 foreach (
string c
in comps)
1871 List<string> addpaths =
new List<string>();
1872 foreach (
string p
in paths)
1874 string[] dirs = Directory.GetDirectories(p, c);
1876 if (dirs.Length != 0)
1878 foreach (
string dir
in dirs)
1879 addpaths.Add(Path.Combine(path, dir));
1883 if (compIndex == comps.Length - 1)
1885 string[] files = Directory.GetFiles(p, c);
1886 foreach (
string f
in files)
1893 return found.ToArray();
1896 public static string ServerURI(
string uri)
1898 if (uri ==
string.Empty)
1899 return string.Empty;
1902 uri = uri.TrimEnd(
'/');
1904 IPAddress ipaddr1 = null;
1908 ipaddr1 = Util.GetHostFromURL(uri);
1914 port1 = uri.Split(
new char[] {
':' })[2];
1919 return (ipaddr1 != null) ?
"http://" + ipaddr1.ToString() +
":" + port1 : uri;
1933 public static byte[] StringToBytes256(
string str, params
object[] args)
1935 return StringToBytes256(
string.Format(str, args));
1946 public static byte[] StringToBytes256(
string str)
1948 if (
String.IsNullOrEmpty(str))
1949 return Utils.EmptyBytes;
1951 if (!str.EndsWith(
"\0"))
1956 byte[] data = UTF8.GetBytes(str);
1958 if (data.Length > 256)
1961 if((data[cut] & 0x80 ) != 0 )
1963 while(cut > 0 && (data[cut] & 0xc0) != 0xc0)
1966 Array.Resize<byte>(ref data, cut + 1);
1984 public static byte[] StringToBytes1024(
string str, params
object[] args)
1986 return StringToBytes1024(
string.Format(str, args));
1997 public static byte[] StringToBytes1024(
string str)
1999 if (
String.IsNullOrEmpty(str))
2000 return Utils.EmptyBytes;
2002 if (!str.EndsWith(
"\0"))
2007 byte[] data = UTF8.GetBytes(str);
2009 if (data.Length > 1024)
2012 if((data[cut] & 0x80 ) != 0 )
2014 while(cut > 0 && (data[cut] & 0xc0) != 0xc0)
2017 Array.Resize<byte>(ref data, cut + 1);
2035 public static byte[] StringToBytes(
string str,
int MaxLength, params
object[] args)
2037 return StringToBytes1024(
string.Format(str, args), MaxLength);
2048 public static byte[] StringToBytes(
string str,
int MaxLength)
2050 if (
String.IsNullOrEmpty(str))
2051 return Utils.EmptyBytes;
2053 if (!str.EndsWith(
"\0"))
2058 byte[] data = UTF8.GetBytes(str);
2060 if (data.Length > MaxLength)
2062 int cut = MaxLength -1 ;
2063 if((data[cut] & 0x80 ) != 0 )
2065 while(cut > 0 && (data[cut] & 0xc0) != 0xc0)
2068 Array.Resize<byte>(ref data, cut + 1);
2081 public static string PrettyFormatToSingleLine(Hashtable ht)
2083 StringBuilder sb =
new StringBuilder();
2087 foreach (
string key in ht.Keys)
2089 sb.AppendFormat(
"{0}:{1}",
key, ht[
key]);
2092 sb.AppendFormat(
", ");
2095 return sb.ToString();
2107 [DllImport(
"kernel32.dll")]
2108 public static extern IntPtr LoadLibrary(
string dllToLoad);
2114 public static bool Is64BitProcess()
2116 return IntPtr.Size == 8;
2119 #region FireAndForget Threading Pattern
2124 private sealed
class FireAndForgetWrapper
2126 private static volatile FireAndForgetWrapper instance;
2127 private static object syncRoot =
new Object();
2129 public static FireAndForgetWrapper Instance {
2132 if (instance == null)
2136 if (instance == null)
2138 instance =
new FireAndForgetWrapper();
2147 public void FireAndForget(System.Threading.WaitCallback callback)
2149 callback.BeginInvoke(null, EndFireAndForget, callback);
2152 public void FireAndForget(System.Threading.WaitCallback callback,
object obj)
2154 callback.BeginInvoke(obj, EndFireAndForget, callback);
2157 private static void EndFireAndForget(IAsyncResult ar)
2159 System.Threading.WaitCallback callback = (System.Threading.WaitCallback)ar.AsyncState;
2161 try { callback.EndInvoke(ar); }
2162 catch (Exception ex) { m_log.Error(
"[UTIL]: Asynchronous method threw an exception: " + ex.Message, ex); }
2164 ar.AsyncWaitHandle.Close();
2168 public static void InitThreadPool(
int minThreads,
int maxThreads)
2171 throw new ArgumentOutOfRangeException(
"maxThreads",
"maxThreads must be greater than 2");
2173 if (minThreads > maxThreads || minThreads < 2)
2174 throw new ArgumentOutOfRangeException(
"minThreads",
"minThreads must be greater than 2 and less than or equal to maxThreads");
2176 if (m_ThreadPool != null)
2178 m_log.Warn(
"SmartThreadPool is already initialized. Ignoring request.");
2182 STPStartInfo startInfo =
new STPStartInfo();
2183 startInfo.ThreadPoolName =
"Util";
2184 startInfo.IdleTimeout = 20000;
2185 startInfo.MaxWorkerThreads = maxThreads;
2186 startInfo.MinWorkerThreads = minThreads;
2189 m_threadPoolWatchdog =
new Timer(ThreadPoolWatchdog, null, 0, 1000);
2192 public static int FireAndForgetCount()
2194 const int MAX_SYSTEM_THREADS = 200;
2198 case FireAndForgetMethod.UnsafeQueueUserWorkItem:
2199 case FireAndForgetMethod.QueueUserWorkItem:
2200 case FireAndForgetMethod.BeginInvoke:
2201 int workerThreads, iocpThreads;
2202 ThreadPool.GetAvailableThreads(out workerThreads, out iocpThreads);
2203 return workerThreads;
2204 case FireAndForgetMethod.SmartThreadPool:
2205 return m_ThreadPool.MaxThreads - m_ThreadPool.InUseThreads;
2206 case FireAndForgetMethod.Thread:
2207 return MAX_SYSTEM_THREADS - System.Diagnostics.Process.GetCurrentProcess().Threads.Count;
2209 throw new NotImplementedException();
2217 private class ThreadInfo
2219 public long ThreadFuncNum {
get; set; }
2220 public string StackTrace {
get; set; }
2221 private string context;
2222 public bool LogThread {
get; set; }
2224 public IWorkItemResult WorkItem {
get; set; }
2226 public bool Running {
get; set; }
2227 public bool Aborted {
get; set; }
2228 private int started;
2230 public ThreadInfo(
long threadFuncNum,
string context)
2232 ThreadFuncNum = threadFuncNum;
2233 this.context = context;
2240 public void Started()
2242 Thread = Thread.CurrentThread;
2243 started = EnvironmentTickCount();
2252 public int Elapsed()
2254 return EnvironmentTickCountSubtract(started);
2260 WorkItem.Cancel(
true);
2271 public string GetStackTrace()
2273 string ret = (context == null) ?
"" : (
"(" + context +
") ");
2275 StackTrace activeStackTrace = Util.GetStackTrace(
Thread);
2276 if (activeStackTrace != null)
2277 ret += activeStackTrace.ToString();
2278 else if (StackTrace != null)
2279 ret +=
"(Stack trace when queued) " + StackTrace;
2286 private static long nextThreadFuncNum = 0;
2287 private static long numQueuedThreadFuncs = 0;
2288 private static long numRunningThreadFuncs = 0;
2289 private static long numTotalThreadFuncsCalled = 0;
2290 private static Int32 threadFuncOverloadMode = 0;
2292 public static long TotalQueuedFireAndForgetCalls {
get {
return numQueuedThreadFuncs; } }
2293 public static long TotalRunningFireAndForgetCalls {
get {
return numRunningThreadFuncs; } }
2296 private static ConcurrentDictionary<long, ThreadInfo> activeThreads =
new ConcurrentDictionary<long, ThreadInfo>();
2298 private static readonly
int THREAD_TIMEOUT = 10 * 60 * 1000;
2303 private static void ThreadPoolWatchdog(
object state)
2305 foreach (KeyValuePair<long, ThreadInfo> entry
in activeThreads)
2307 ThreadInfo t = entry.Value;
2308 if (t.Running && !t.Aborted && (t.Elapsed() >= THREAD_TIMEOUT))
2310 m_log.WarnFormat(
"Timeout in threadfunc {0} ({1}) {2}", t.ThreadFuncNum, t.Thread.Name, t.GetStackTrace());
2314 activeThreads.TryRemove(entry.Key, out dummy);
2323 public static long TotalFireAndForgetCallsMade {
get {
return numTotalThreadFuncsCalled; } }
2325 public static Dictionary<string, int> GetFireAndForgetCallsMade()
2327 return new Dictionary<string, int>(m_fireAndForgetCallsMade);
2330 private static Dictionary<string, int> m_fireAndForgetCallsMade =
new Dictionary<string, int>();
2332 public static Dictionary<string, int> GetFireAndForgetCallsInProgress()
2334 return new Dictionary<string, int>(m_fireAndForgetCallsInProgress);
2337 private static Dictionary<string, int> m_fireAndForgetCallsInProgress =
new Dictionary<string, int>();
2339 public static void FireAndForget(System.Threading.WaitCallback callback)
2341 FireAndForget(callback, null, null);
2344 public static void FireAndForget(System.Threading.WaitCallback callback,
object obj)
2346 FireAndForget(callback, obj, null);
2349 public static void FireAndForget(System.Threading.WaitCallback callback,
object obj,
string context)
2351 Interlocked.Increment(ref numTotalThreadFuncsCalled);
2353 if (context != null)
2355 if (!m_fireAndForgetCallsMade.ContainsKey(context))
2356 m_fireAndForgetCallsMade[context] = 1;
2358 m_fireAndForgetCallsMade[context]++;
2360 if (!m_fireAndForgetCallsInProgress.ContainsKey(context))
2361 m_fireAndForgetCallsInProgress[context] = 1;
2363 m_fireAndForgetCallsInProgress[context]++;
2366 WaitCallback realCallback;
2368 bool loggingEnabled = LogThreadPool > 0;
2370 long threadFuncNum = Interlocked.Increment(ref nextThreadFuncNum);
2371 ThreadInfo threadInfo =
new ThreadInfo(threadFuncNum, context);
2379 Culture.SetCurrentCulture();
2382 if (context != null)
2383 m_fireAndForgetCallsInProgress[context]--;
2393 long numQueued1 = Interlocked.Decrement(ref numQueuedThreadFuncs);
2394 long numRunning1 = Interlocked.Increment(ref numRunningThreadFuncs);
2395 threadInfo.Started();
2396 activeThreads[threadFuncNum] = threadInfo;
2400 if ((loggingEnabled || (threadFuncOverloadMode == 1)) && threadInfo.LogThread)
2401 m_log.DebugFormat(
"Run threadfunc {0} (Queued {1}, Running {2})", threadFuncNum, numQueued1, numRunning1);
2403 Culture.SetCurrentCulture();
2407 catch (ThreadAbortException e)
2409 m_log.Error(string.Format(
"Aborted threadfunc {0} ", threadFuncNum), e);
2413 m_log.Error(string.Format(
"[UTIL]: Util STP threadfunc {0} terminated with error ", threadFuncNum), e);
2417 Interlocked.Decrement(ref numRunningThreadFuncs);
2420 activeThreads.TryRemove(threadFuncNum, out dummy);
2421 if ((loggingEnabled || (threadFuncOverloadMode == 1)) && threadInfo.LogThread)
2422 m_log.DebugFormat(
"Exit threadfunc {0} ({1})", threadFuncNum, FormatDuration(threadInfo.Elapsed()));
2424 if (context != null)
2425 m_fireAndForgetCallsInProgress[context]--;
2430 long numQueued = Interlocked.Increment(ref numQueuedThreadFuncs);
2470 threadInfo.LogThread =
false;
2475 case FireAndForgetMethod.RegressionTest:
2476 case FireAndForgetMethod.None:
2477 realCallback.Invoke(obj);
2479 case FireAndForgetMethod.UnsafeQueueUserWorkItem:
2480 ThreadPool.UnsafeQueueUserWorkItem(realCallback, obj);
2482 case FireAndForgetMethod.QueueUserWorkItem:
2483 ThreadPool.QueueUserWorkItem(realCallback, obj);
2485 case FireAndForgetMethod.BeginInvoke:
2486 FireAndForgetWrapper wrapper = FireAndForgetWrapper.Instance;
2487 wrapper.FireAndForget(realCallback, obj);
2489 case FireAndForgetMethod.SmartThreadPool:
2490 if (m_ThreadPool == null)
2491 InitThreadPool(2, 15);
2492 threadInfo.WorkItem = m_ThreadPool.QueueWorkItem((cb, o) => cb(o), realCallback, obj);
2494 case FireAndForgetMethod.Thread:
2495 Thread thread =
new Thread(delegate(
object o) { realCallback(o); });
2499 throw new NotImplementedException();
2504 Interlocked.Decrement(ref numQueuedThreadFuncs);
2506 activeThreads.TryRemove(threadFuncNum, out dummy);
2517 private static bool ShouldLogThread(
string stackTrace)
2519 if (LogThreadPool < 3)
2521 if (stackTrace.Contains(
"BeginFireQueueEmpty"))
2533 private static void GetFireAndForgetStackTrace(out
string full, out
string partial)
2535 string src = Environment.StackTrace;
2536 string[] lines = src.Split(
new string[] { Environment.NewLine }, StringSplitOptions.None);
2538 StringBuilder dest =
new StringBuilder(src.Length);
2540 bool started =
false;
2544 for (
int i = 0; i < lines.Length; i++)
2546 string line = lines[i];
2551 if (line.Contains(
"StackTrace") || line.Contains(
"FireAndForget"))
2558 line = line.TrimStart();
2563 bool last = (i == lines.Length - 1);
2567 dest.AppendLine(line);
2570 full = dest.ToString();
2573 #pragma warning disable 0618
2574 private static StackTrace GetStackTrace(Thread targetThread)
2597 ManualResetEventSlim fallbackThreadReady =
new ManualResetEventSlim();
2598 ManualResetEventSlim exitedSafely =
new ManualResetEventSlim();
2604 fallbackThreadReady.Set();
2605 while (!exitedSafely.Wait(200))
2609 targetThread.Resume();
2618 fallbackThreadReady.Wait();
2621 targetThread.Suspend();
2623 StackTrace trace = null;
2626 trace =
new StackTrace(targetThread,
true);
2628 catch (ThreadStateException)
2639 targetThread.Resume();
2641 catch (ThreadStateException)
2654 #pragma warning restore 0618
2662 public static STPInfo GetSmartThreadPoolInfo()
2664 if (m_ThreadPool == null)
2667 STPInfo stpi =
new STPInfo();
2668 stpi.Name = m_ThreadPool.Name;
2669 stpi.STPStartInfo = m_ThreadPool.STPStartInfo;
2670 stpi.IsIdle = m_ThreadPool.IsIdle;
2671 stpi.IsShuttingDown = m_ThreadPool.IsShuttingdown;
2672 stpi.MaxThreads = m_ThreadPool.MaxThreads;
2673 stpi.MinThreads = m_ThreadPool.MinThreads;
2674 stpi.InUseThreads = m_ThreadPool.InUseThreads;
2675 stpi.ActiveThreads = m_ThreadPool.ActiveThreads;
2676 stpi.WaitingCallbacks = m_ThreadPool.WaitingCallbacks;
2677 stpi.MaxConcurrentWorkItems = m_ThreadPool.Concurrency;
2682 #endregion FireAndForget Threading Pattern
2691 public static Int32 EnvironmentTickCount()
2693 return Environment.TickCount & EnvironmentTickCountMask;
2695 const Int32 EnvironmentTickCountMask = 0x3fffffff;
2705 public static Int32 EnvironmentTickCountSubtract(Int32 newValue, Int32 prevValue)
2707 Int32 diff = newValue - prevValue;
2708 return (diff >= 0) ? diff : (diff + EnvironmentTickCountMask + 1);
2717 public static Int32 EnvironmentTickCountSubtract(Int32 prevValue)
2719 return EnvironmentTickCountSubtract(EnvironmentTickCount(), prevValue);
2725 public static Int32 EnvironmentTickCountCompare(Int32 tcA, Int32 tcB)
2728 int tc = EnvironmentTickCount();
2731 tcA += EnvironmentTickCountMask + 1;
2734 tcB += EnvironmentTickCountMask + 1;
2741 public static double GetTimeStampMS()
2743 return (
double)Stopwatch.GetTimestamp() * TimeStampClockPeriodMS;
2749 public static string FormatDuration(
int ms)
2751 TimeSpan span =
new TimeSpan(ms * TimeSpan.TicksPerMillisecond);
2754 string suffix = null;
2756 int hours = (int)span.TotalHours;
2759 str += hours.ToString(str.Length == 0 ?
"0" :
"00");
2763 if ((hours > 0) || (span.Minutes > 0))
2767 str += span.Minutes.ToString(str.Length == 0 ?
"0" :
"00");
2772 if ((hours > 0) || (span.Minutes > 0) || (span.Seconds > 0))
2776 str += span.Seconds.ToString(str.Length == 0 ?
"0" :
"00");
2784 if (span.TotalMinutes < 1)
2786 int ms1 = span.Milliseconds;
2792 str += ms1.ToString(
"0");
2795 str +=
" " + suffix;
2803 public static void PrintCallStack()
2805 PrintCallStack(m_log.DebugFormat);
2808 public delegate
void DebugPrinter(
string msg, params Object[] parm);
2809 public static void PrintCallStack(DebugPrinter printer)
2811 StackTrace stackTrace =
new StackTrace(
true);
2812 StackFrame[] stackFrames = stackTrace.GetFrames();
2815 foreach (StackFrame stackFrame
in stackFrames)
2817 MethodBase mb = stackFrame.GetMethod();
2818 printer(
"{0}.{1}:{2}", mb.DeclaringType, mb.Name, stackFrame.GetFileLineNumber());
2827 public static IPEndPoint GetClientIPFromXFF(
string xff)
2829 if (xff ==
string.Empty)
2832 string[] parts = xff.Split(
new char[] {
',' });
2833 if (parts.Length > 0)
2837 return new IPEndPoint(IPAddress.Parse(parts[0]), 0);
2841 m_log.WarnFormat(
"[UTIL]: Exception parsing XFF header {0}: {1}", xff, e.Message);
2848 public static string GetCallerIP(Hashtable req)
2850 if (req.ContainsKey(
"headers"))
2854 Hashtable headers = (Hashtable)req[
"headers"];
2855 if (headers.ContainsKey(
"remote_addr") && headers[
"remote_addr"] != null)
2856 return headers[
"remote_addr"].ToString();
2860 m_log.WarnFormat(
"[UTIL]: exception in GetCallerIP: {0}", e.Message);
2863 return string.Empty;
2866 #region Xml Serialization Utilities
2867 public static bool ReadBoolean(XmlReader reader)
2870 reader.ReadStartElement();
2871 string val = reader.ReadContentAsString().ToLower();
2872 bool result = val.Equals(
"true") || val.Equals(
"1");
2873 reader.ReadEndElement();
2878 public static UUID ReadUUID(XmlReader reader,
string name)
2883 reader.ReadStartElement(name);
2885 if (reader.Name ==
"Guid")
2886 idStr = reader.ReadElementString(
"Guid");
2887 else if (reader.Name ==
"UUID")
2888 idStr = reader.ReadElementString(
"UUID");
2890 idStr = reader.ReadContentAsString();
2891 UUID.TryParse(idStr, out id);
2892 reader.ReadEndElement();
2897 public static Vector3 ReadVector(XmlReader reader,
string name)
2901 reader.ReadStartElement(name);
2902 vec.X = reader.ReadElementContentAsFloat(reader.Name, String.Empty);
2903 vec.Y = reader.ReadElementContentAsFloat(reader.Name, String.Empty);
2904 vec.Z = reader.ReadElementContentAsFloat(reader.Name, String.Empty);
2905 reader.ReadEndElement();
2910 public static Quaternion ReadQuaternion(XmlReader reader,
string name)
2912 Quaternion quat =
new Quaternion();
2914 reader.ReadStartElement(name);
2915 while (reader.NodeType != XmlNodeType.EndElement)
2917 switch (reader.Name.ToLower())
2920 quat.X = reader.ReadElementContentAsFloat(reader.Name, String.Empty);
2923 quat.Y = reader.ReadElementContentAsFloat(reader.Name, String.Empty);
2926 quat.Z = reader.ReadElementContentAsFloat(reader.Name, String.Empty);
2929 quat.W = reader.ReadElementContentAsFloat(reader.Name, String.Empty);
2934 reader.ReadEndElement();
2939 public static T ReadEnum<T>(XmlReader reader,
string name)
2941 string value = reader.ReadElementContentAsString(name, String.Empty);
2943 if (value.Contains(
" ") && !value.Contains(
","))
2944 value = value.Replace(
" ",
", ");
2946 return (T)Enum.Parse(typeof(T), value); ;
2950 #region Universal User Identifiers
2961 public static bool ParseUniversalUserIdentifier(
string value, out UUID uuid, out
string url, out
string firstname, out
string lastname, out
string secret)
2963 uuid = UUID.Zero; url = string.Empty; firstname =
"Unknown"; lastname =
"UserUPUUI"; secret = string.Empty;
2965 string[] parts = value.Split(
';');
2966 if (parts.Length >= 1)
2967 if (!
UUID.TryParse(parts[0], out uuid))
2970 if (parts.Length >= 2)
2973 if (parts.Length >= 3)
2975 string[] name = parts[2].Split();
2976 if (name.Length == 2)
2978 firstname = name[0];
2982 if (parts.Length >= 4)
2991 public static bool ParseForeignAvatarName(
string firstname,
string lastname,
2992 out
string realFirstName, out
string realLastName, out
string serverURI)
2994 realFirstName = realLastName = serverURI = string.Empty;
2996 if (!lastname.Contains(
"@"))
2999 if (!firstname.Contains(
"."))
3002 realFirstName = firstname.Split(
'.')[0];
3003 realLastName = firstname.Split(
'.')[1];
3004 serverURI =
new Uri(
"http://" + lastname.Replace(
"@",
"")).ToString();
3014 public static string ProduceUserUniversalIdentifier(AgentCircuitData acircuit)
3016 if (acircuit.ServiceURLs.ContainsKey(
"HomeURI"))
3017 return UniversalIdentifier(acircuit.AgentID, acircuit.firstname, acircuit.lastname, acircuit.ServiceURLs[
"HomeURI"].ToString());
3019 return acircuit.AgentID.ToString();
3030 public static string UniversalIdentifier(UUID
id, String firstName, String lastName, String homeURI)
3032 string agentsURI = homeURI;
3033 if (!agentsURI.EndsWith(
"/"))
3038 if (lastName.Contains(
"@"))
3040 string[] parts = firstName.Split(
new char[] {
'.' });
3041 if (parts.Length == 2)
3042 return CalcUniversalIdentifier(
id, agentsURI, parts[0] +
" " + parts[1]);
3045 return CalcUniversalIdentifier(
id, agentsURI, firstName +
" " + lastName);
3048 private static string CalcUniversalIdentifier(UUID
id,
string agentsURI,
string name)
3050 return id.ToString() +
";" + agentsURI +
";" + name;
3060 public static string UniversalName(String firstName, String lastName, String homeURI)
3065 uri =
new Uri(homeURI);
3067 catch (UriFormatException)
3069 return firstName +
" " + lastName;
3071 return firstName +
"." + lastName +
" " +
"@" + uri.Authority;
3081 public static string EscapeForLike(
string str)
3083 return str.Replace(
"_",
"\\_").Replace(
"%",
"\\%");
3094 public static string GetViewerName(AgentCircuitData agent)
3096 string name = agent.Viewer;
3104 foreach (
char c
in name)
3106 if (Char.IsLetter(c))
3112 if ((agent.Channel != null) && (agent.Channel.Length > 0))
3113 name = agent.Channel.Trim() +
" " + name;
3118 public static void LogFailedXML(
string message,
string xml)
3120 int length = xml.Length;
3122 xml = xml.Substring(0, 2000) +
"...";
3124 m_log.ErrorFormat(
"{0} Failed XML ({1} bytes) = {2}", message, length, xml);
3244 private const int BufferSize = 1024;
3245 private byte[] RandomBuffer;
3246 private int BufferOffset;
3247 private RNGCryptoServiceProvider rng;
3250 RandomBuffer =
new byte[BufferSize];
3251 rng =
new RNGCryptoServiceProvider();
3252 BufferOffset = RandomBuffer.Length;
3254 private void FillBuffer()
3256 rng.GetBytes(RandomBuffer);
3261 if (BufferOffset >= RandomBuffer.Length)
3265 int val = BitConverter.ToInt32(RandomBuffer, BufferOffset) & 0x7fffffff;
3266 BufferOffset +=
sizeof(int);
3271 return Next() % maxValue;
3273 public int Next(
int minValue,
int maxValue)
3275 if (maxValue < minValue)
3277 throw new ArgumentOutOfRangeException(
"maxValue must be greater than or equal to minValue");
3279 int range = maxValue - minValue;
3280 return minValue + Next(range);
3285 return (
double)val / int.MaxValue;
FireAndForgetMethod
The method used by Util.FireAndForget for asynchronously firing events
OpenSim.Server.Handlers.Simulation.Utils Utils
void GetBytes(byte[] buff)
Class for delivering SmartThreadPool statistical information
OpenMetaverse.StructuredData.OSDMap OSDMap
Ionic.Zlib.GZipStream GZipStream
System.Timers.Timer Timer
OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString key
int Next(int minValue, int maxValue)
OpenMetaverse.StructuredData.OSD OSD
Ionic.Zlib.CompressionMode CompressionMode