PageRenderTime 72ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/Aurora/Framework/Utilities/Util.cs

https://bitbucket.org/VirtualReality/async-sim-testing
C# | 3042 lines | 2328 code | 354 blank | 360 comment | 395 complexity | d4de62d4428e5e099577b3a9324ffbd4 MD5 | raw file
  1. /*
  2. * Copyright (c) Contributors, http://aurora-sim.org/, http://opensimulator.org/
  3. * See CONTRIBUTORS.TXT for a full list of copyright holders.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of the Aurora-Sim Project nor the
  13. * names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
  17. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
  20. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. using Amib.Threading;
  28. using Aurora.Framework.ConsoleFramework;
  29. using Aurora.Framework.Modules;
  30. using Nini.Config;
  31. using OpenMetaverse;
  32. using OpenMetaverse.StructuredData;
  33. using ProtoBuf;
  34. using ProtoBuf.Meta;
  35. using System;
  36. using System.Collections;
  37. using System.Collections.Generic;
  38. using System.Data;
  39. using System.Diagnostics;
  40. using System.Globalization;
  41. using System.IO;
  42. using System.IO.Compression;
  43. using System.Linq;
  44. using System.Net;
  45. using System.Net.NetworkInformation;
  46. using System.Net.Sockets;
  47. using System.Reflection;
  48. using System.Reflection.Emit;
  49. using System.Runtime.Serialization;
  50. using System.Runtime.Serialization.Formatters.Binary;
  51. using System.Security.Cryptography;
  52. using System.Text;
  53. using System.Text.RegularExpressions;
  54. using System.Threading;
  55. using System.Windows.Forms;
  56. using System.Xml;
  57. using ReaderWriterLockSlim = System.Threading.ReaderWriterLockSlim;
  58. namespace Aurora.Framework.Utilities
  59. {
  60. /// <summary>
  61. /// The method used by Util.FireAndForget for asynchronously firing events
  62. /// </summary>
  63. public enum FireAndForgetMethod
  64. {
  65. UnsafeQueueUserWorkItem,
  66. QueueUserWorkItem,
  67. BeginInvoke,
  68. SmartThreadPool,
  69. Thread
  70. }
  71. public enum RuntimeEnvironment
  72. {
  73. NET,
  74. WinMono,
  75. Mono
  76. }
  77. /// <summary>
  78. /// Miscellaneous utility functions
  79. /// </summary>
  80. public class Util
  81. {
  82. private static uint nextXferID = 5000;
  83. private static readonly Random randomClass = new Random();
  84. // Get a list of invalid file characters (OS dependent)
  85. private static readonly string regexInvalidFileChars = "[" + new String(Path.GetInvalidFileNameChars()) + "]";
  86. private static readonly string regexInvalidPathChars = "[" + new String(Path.GetInvalidPathChars()) + "]";
  87. private static readonly object XferLock = new object();
  88. /// <summary>
  89. /// Thread pool used for Util.FireAndForget if
  90. /// FireAndForgetMethod.SmartThreadPool is used
  91. /// </summary>
  92. private static SmartThreadPool m_ThreadPool;
  93. private static volatile bool m_threadPoolRunning;
  94. // Unix-epoch starts at January 1st 1970, 00:00:00 UTC. And all our times in the server are (or at least should be) in UTC.
  95. public static readonly DateTime UnixEpoch =
  96. DateTime.ParseExact("1970-01-01 00:00:00 +0", "yyyy-MM-dd hh:mm:ss z", DateTimeFormatInfo.InvariantInfo).
  97. ToUniversalTime();
  98. public static readonly Regex UUIDPattern
  99. = new Regex("^[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}$");
  100. public static FireAndForgetMethod FireAndForgetMethod = FireAndForgetMethod.SmartThreadPool;
  101. static Util()
  102. {
  103. RuntimeTypeModel.Default.Add(typeof (UUID), false)
  104. .SetSurrogate(typeof (UUIDSurrogate));
  105. RuntimeTypeModel.Default.Add(typeof (IPEndPoint), false)
  106. .SetSurrogate(typeof (IPEndPointSurrogate));
  107. RuntimeTypeModel.Default.Add(typeof (OSD), false)
  108. .SetSurrogate(typeof (OSDSurrogate));
  109. RuntimeTypeModel.Default.Add(typeof (OSDMap), false)
  110. .SetSurrogate(typeof (OSDMapSurrogate));
  111. RuntimeTypeModel.Default.Add(typeof (Vector3), false)
  112. .SetSurrogate(typeof (Vector3Surrogate));
  113. RuntimeTypeModel.Default.Add(typeof (Quaternion), false)
  114. .SetSurrogate(typeof (QuaternionSurrogate));
  115. RuntimeTypeModel.Default.Add(typeof (ParcelManager.ParcelAccessEntry), false)
  116. .SetSurrogate(typeof (ParcelAccessEntrySurrogate));
  117. RuntimeTypeModel.Default.Add(typeof (MediaEntry), false)
  118. .SetSurrogate(typeof (MediaEntrySurrogate));
  119. RuntimeTypeModel.Default.Add(typeof (System.Drawing.Color), false)
  120. .SetSurrogate(typeof (ColorSurrogate));
  121. }
  122. #region Protobuf helpers
  123. [ProtoContract]
  124. private class UUIDSurrogate
  125. {
  126. [ProtoMember(1)] public string ID;
  127. // protobuf-net wants an implicit or explicit operator between the types
  128. public static implicit operator UUID(UUIDSurrogate value)
  129. {
  130. return UUID.Parse(value.ID);
  131. }
  132. public static implicit operator UUIDSurrogate(UUID value)
  133. {
  134. return new UUIDSurrogate
  135. {
  136. ID = value.ToString()
  137. };
  138. }
  139. }
  140. [ProtoContract]
  141. private class Vector3Surrogate
  142. {
  143. [ProtoMember(1)] public float X;
  144. [ProtoMember(2)] public float Y;
  145. [ProtoMember(3)] public float Z;
  146. // protobuf-net wants an implicit or explicit operator between the types
  147. public static implicit operator Vector3(Vector3Surrogate value)
  148. {
  149. return new Vector3(value.X, value.Y, value.Z);
  150. }
  151. public static implicit operator Vector3Surrogate(Vector3 value)
  152. {
  153. return new Vector3Surrogate()
  154. {
  155. X = value.X,
  156. Y = value.Y,
  157. Z = value.Z
  158. };
  159. }
  160. }
  161. [ProtoContract]
  162. private class QuaternionSurrogate
  163. {
  164. [ProtoMember(1)] public float X;
  165. [ProtoMember(2)] public float Y;
  166. [ProtoMember(3)] public float Z;
  167. [ProtoMember(4)] public float W;
  168. // protobuf-net wants an implicit or explicit operator between the types
  169. public static implicit operator Quaternion(QuaternionSurrogate value)
  170. {
  171. return new Quaternion(value.X, value.Y, value.Z, value.W);
  172. }
  173. public static implicit operator QuaternionSurrogate(Quaternion value)
  174. {
  175. return new QuaternionSurrogate()
  176. {
  177. X = value.X,
  178. Y = value.Y,
  179. Z = value.Z,
  180. W = value.W
  181. };
  182. }
  183. }
  184. [ProtoContract]
  185. private class IPEndPointSurrogate
  186. {
  187. [ProtoMember(1)] public string IPAddr;
  188. [ProtoMember(2)] public int Port;
  189. // protobuf-net wants an implicit or explicit operator between the types
  190. public static implicit operator IPEndPoint(IPEndPointSurrogate value)
  191. {
  192. return value == null ? null : new IPEndPoint(IPAddress.Parse(value.IPAddr), value.Port);
  193. }
  194. public static implicit operator IPEndPointSurrogate(IPEndPoint value)
  195. {
  196. return value == null
  197. ? null
  198. : new IPEndPointSurrogate
  199. {
  200. IPAddr = value.Address.ToString(),
  201. Port = value.Port
  202. };
  203. }
  204. }
  205. [ProtoContract]
  206. private class OSDSurrogate
  207. {
  208. [ProtoMember(1)] public string str;
  209. // protobuf-net wants an implicit or explicit operator between the types
  210. public static implicit operator OSD(OSDSurrogate value)
  211. {
  212. return value.str == "" ? null : OSDParser.DeserializeJson(value.str);
  213. }
  214. public static implicit operator OSDSurrogate(OSD value)
  215. {
  216. return new OSDSurrogate
  217. {
  218. str = value == null ? "" : OSDParser.SerializeJsonString(value)
  219. };
  220. }
  221. }
  222. [ProtoContract]
  223. private class OSDMapSurrogate
  224. {
  225. [ProtoMember(1)] public string str;
  226. // protobuf-net wants an implicit or explicit operator between the types
  227. public static implicit operator OSDMap(OSDMapSurrogate value)
  228. {
  229. return value.str == "" ? null : (OSDMap) OSDParser.DeserializeJson(value.str);
  230. }
  231. public static implicit operator OSDMapSurrogate(OSDMap value)
  232. {
  233. return new OSDMapSurrogate
  234. {
  235. str = value == null ? "" : OSDParser.SerializeJsonString(value)
  236. };
  237. }
  238. }
  239. [ProtoContract]
  240. private class ParcelAccessEntrySurrogate
  241. {
  242. [ProtoMember(1)] public UUID AgentID;
  243. [ProtoMember(2)] public AccessList Flags;
  244. [ProtoMember(3)] public DateTime Time;
  245. // protobuf-net wants an implicit or explicit operator between the types
  246. public static implicit operator ParcelManager.ParcelAccessEntry(ParcelAccessEntrySurrogate value)
  247. {
  248. return new ParcelManager.ParcelAccessEntry()
  249. {
  250. AgentID = value.AgentID,
  251. Flags = value.Flags,
  252. Time = value.Time
  253. };
  254. }
  255. public static implicit operator ParcelAccessEntrySurrogate(ParcelManager.ParcelAccessEntry value)
  256. {
  257. return new ParcelAccessEntrySurrogate
  258. {
  259. AgentID = value.AgentID,
  260. Flags = value.Flags,
  261. Time = value.Time
  262. };
  263. }
  264. }
  265. [ProtoContract]
  266. private class MediaEntrySurrogate
  267. {
  268. [ProtoMember(1)] public OSD info;
  269. // protobuf-net wants an implicit or explicit operator between the types
  270. public static implicit operator MediaEntry(MediaEntrySurrogate value)
  271. {
  272. return value.info == null ? null : MediaEntry.FromOSD(value.info);
  273. }
  274. public static implicit operator MediaEntrySurrogate(MediaEntry value)
  275. {
  276. return new MediaEntrySurrogate
  277. {
  278. info = value == null ? null : value.GetOSD()
  279. };
  280. }
  281. }
  282. [ProtoContract]
  283. private class ColorSurrogate
  284. {
  285. [ProtoMember(1)] public int A;
  286. [ProtoMember(2)] public int R;
  287. [ProtoMember(3)] public int G;
  288. [ProtoMember(4)] public int B;
  289. // protobuf-net wants an implicit or explicit operator between the types
  290. public static implicit operator System.Drawing.Color(ColorSurrogate value)
  291. {
  292. return System.Drawing.Color.FromArgb(value.A, value.R, value.G, value.B);
  293. }
  294. public static implicit operator ColorSurrogate(System.Drawing.Color value)
  295. {
  296. return new ColorSurrogate
  297. {
  298. A = value.A,
  299. R = value.R,
  300. G = value.G,
  301. B = value.B
  302. };
  303. }
  304. }
  305. #endregion
  306. public static string ConvertToString(List<string> list)
  307. {
  308. StringBuilder builder = new StringBuilder();
  309. foreach (string val in list)
  310. {
  311. builder.Append(val + ",");
  312. }
  313. return builder.ToString();
  314. }
  315. public static string ConvertToString(Dictionary<string, object> list)
  316. {
  317. StringBuilder builder = new StringBuilder();
  318. foreach (var val in list)
  319. {
  320. builder.Append(val.Key + "=" + val.Value.ToString() + ",");
  321. }
  322. return builder.ToString();
  323. }
  324. //wab - Added for debugging ease
  325. public static string ConvertToString(OSDMap values, string lineStart)
  326. {
  327. if (string.IsNullOrEmpty(lineStart)) lineStart = "\t";
  328. StringBuilder builder = new StringBuilder();
  329. String[] keys = new String[values.Count];
  330. values.Keys.CopyTo(keys, 0);
  331. foreach (String key in keys)
  332. {
  333. Object val = values[key];
  334. if (val == null)
  335. builder.AppendFormat("{0}{1}=null\n", lineStart, key);
  336. else if (val is OSDMap)
  337. builder.AppendFormat("{0}{1}=...\n{2}", lineStart, key, ConvertToString((OSDMap) val, "\t\t"));
  338. else
  339. builder.AppendFormat("{0}{1}={2}\n", lineStart, key, val.ToString());
  340. }
  341. return builder.ToString();
  342. }
  343. public static List<string> ConvertToList(string listAsString)
  344. {
  345. //Do both , and " " so that it removes any annoying spaces in the string added by users
  346. List<string> value =
  347. new List<string>(listAsString.Split(new[] {","}, StringSplitOptions.RemoveEmptyEntries));
  348. return value;
  349. }
  350. public static Dictionary<string, string> ConvertToDictionary(string listAsString)
  351. {
  352. //Do both , and " " so that it removes any annoying spaces in the string added by users
  353. List<string> value =
  354. new List<string>(listAsString.Split(new[] {","}, StringSplitOptions.RemoveEmptyEntries));
  355. Dictionary<string, string> dict = new Dictionary<string, string>();
  356. foreach (var v in value)
  357. {
  358. var split = v.Split('=');
  359. dict.Add(split[0], split[1]);
  360. }
  361. return dict;
  362. }
  363. public static string BuildYMDDateString(DateTime time)
  364. {
  365. return time.Year + "-" + time.Month + "-" + time.Day;
  366. }
  367. /// <summary>
  368. /// Gets the name of the directory where the current running executable
  369. /// is located
  370. /// </summary>
  371. /// <returns>
  372. /// Filesystem path to the directory containing the current
  373. /// executable
  374. /// </returns>
  375. public static string ExecutingDirectory()
  376. {
  377. return Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
  378. }
  379. /// <summary>
  380. /// Copy data from one stream to another, leaving the read position of both streams at the beginning.
  381. /// </summary>
  382. /// <param name='inputStream'>
  383. /// Input stream. Must be seekable.
  384. /// </param>
  385. /// <exception cref='ArgumentException'>
  386. /// Thrown if the input stream is not seekable.
  387. /// </exception>
  388. public static Stream Copy(Stream inputStream)
  389. {
  390. if (!inputStream.CanSeek)
  391. throw new ArgumentException("Util.Copy(Stream inputStream) must receive an inputStream that can seek");
  392. const int readSize = 256;
  393. byte[] buffer = new byte[readSize];
  394. MemoryStream ms = new MemoryStream();
  395. int count = inputStream.Read(buffer, 0, readSize);
  396. while (count > 0)
  397. {
  398. ms.Write(buffer, 0, count);
  399. count = inputStream.Read(buffer, 0, readSize);
  400. }
  401. ms.Position = 0;
  402. inputStream.Position = 0;
  403. return ms;
  404. }
  405. /// <summary>
  406. /// Linear interpolates B&lt;-&gt;C using percent A
  407. /// </summary>
  408. /// <param name="a"></param>
  409. /// <param name="b"></param>
  410. /// <param name="c"></param>
  411. /// <returns></returns>
  412. public static double lerp(double a, double b, double c)
  413. {
  414. return (b*a) + (c*(1 - a));
  415. }
  416. /// <summary>
  417. /// Bilinear Interpolate, see Lerp but for 2D using 'percents' X & Y.
  418. /// Layout:
  419. /// A B
  420. /// C D
  421. /// A&lt;-&gt;C = Y
  422. /// C&lt;-&gt;D = X
  423. /// </summary>
  424. /// <param name="x"></param>
  425. /// <param name="y"></param>
  426. /// <param name="a"></param>
  427. /// <param name="b"></param>
  428. /// <param name="c"></param>
  429. /// <param name="d"></param>
  430. /// <returns></returns>
  431. public static double lerp2D(double x, double y, double a, double b, double c, double d)
  432. {
  433. return lerp(y, lerp(x, a, b), lerp(x, c, d));
  434. }
  435. public static Encoding UTF8 = Encoding.UTF8;
  436. /// <value>
  437. /// Well known UUID for the blank texture used in the Linden SL viewer version 1.20 (and hopefully onwards)
  438. /// </value>
  439. public static UUID BLANK_TEXTURE_UUID = new UUID("5748decc-f629-461c-9a36-a35a221fe21f");
  440. #region Vector Equations
  441. /// <summary>
  442. /// Get the distance between two 3d vectors
  443. /// </summary>
  444. /// <param name="a">A 3d vector</param>
  445. /// <param name="b">A 3d vector</param>
  446. /// <returns>The distance between the two vectors</returns>
  447. public static double GetDistanceTo(Vector3 a, Vector3 b)
  448. {
  449. float dx = a.X - b.X;
  450. float dy = a.Y - b.Y;
  451. float dz = a.Z - b.Z;
  452. return Math.Sqrt(dx*dx + dy*dy + dz*dz);
  453. }
  454. /// <summary>
  455. /// Get the distance between two 3d vectors (excluding Z)
  456. /// </summary>
  457. /// <param name="a">A 3d vector</param>
  458. /// <param name="b">A 3d vector</param>
  459. /// <returns>The distance between the two vectors</returns>
  460. public static double GetFlatDistanceTo(Vector3 a, Vector3 b)
  461. {
  462. float dx = a.X - b.X;
  463. float dy = a.Y - b.Y;
  464. return Math.Sqrt(dx*dx + dy*dy);
  465. }
  466. /// <summary>
  467. /// Returns true if the distance beween A and B is less than amount. Significantly faster than GetDistanceTo since it eliminates the Sqrt.
  468. /// </summary>
  469. /// <param name="a"></param>
  470. /// <param name="b"></param>
  471. /// <param name="amount"></param>
  472. /// <returns></returns>
  473. public static bool DistanceLessThan(Vector3 a, Vector3 b, double amount)
  474. {
  475. float dx = a.X - b.X;
  476. float dy = a.Y - b.Y;
  477. float dz = a.Z - b.Z;
  478. return (dx*dx + dy*dy + dz*dz) < (amount*amount);
  479. }
  480. /// <summary>
  481. /// Get the magnitude of a 3d vector
  482. /// </summary>
  483. /// <param name="a">A 3d vector</param>
  484. /// <returns>The magnitude of the vector</returns>
  485. public static double GetMagnitude(Vector3 a)
  486. {
  487. return Math.Sqrt((a.X*a.X) + (a.Y*a.Y) + (a.Z*a.Z));
  488. }
  489. /// <summary>
  490. /// Get a normalized form of a 3d vector
  491. /// The vector paramater cannot be &lt;0,0,0&gt;
  492. /// </summary>
  493. /// <param name="a">A 3d vector</param>
  494. /// <returns>A new vector which is normalized form of the vector</returns>
  495. public static Vector3 GetNormalizedVector(Vector3 a)
  496. {
  497. if (IsZeroVector(a))
  498. throw new ArgumentException("Vector paramater cannot be a zero vector.");
  499. float Mag = (float) GetMagnitude(a);
  500. return new Vector3(a.X/Mag, a.Y/Mag, a.Z/Mag);
  501. }
  502. /// <summary>
  503. /// Returns if a vector is a zero vector (has all zero components)
  504. /// </summary>
  505. /// <returns></returns>
  506. public static bool IsZeroVector(Vector3 v)
  507. {
  508. if (v.X == 0 && v.Y == 0 && v.Z == 0)
  509. {
  510. return true;
  511. }
  512. return false;
  513. }
  514. # endregion
  515. public static Quaternion Axes2Rot(Vector3 fwd, Vector3 left, Vector3 up)
  516. {
  517. float s;
  518. float tr = (float) (fwd.X + left.Y + up.Z + 1.0);
  519. if (tr >= 1.0)
  520. {
  521. s = (float) (0.5/Math.Sqrt(tr));
  522. return new Quaternion(
  523. (left.Z - up.Y)*s,
  524. (up.X - fwd.Z)*s,
  525. (fwd.Y - left.X)*s,
  526. (float) 0.25/s);
  527. }
  528. else
  529. {
  530. float max = (left.Y > up.Z) ? left.Y : up.Z;
  531. if (max < fwd.X)
  532. {
  533. s = (float) (Math.Sqrt(fwd.X - (left.Y + up.Z) + 1.0));
  534. float x = (float) (s*0.5);
  535. s = (float) (0.5/s);
  536. return new Quaternion(
  537. x,
  538. (fwd.Y + left.X)*s,
  539. (up.X + fwd.Z)*s,
  540. (left.Z - up.Y)*s);
  541. }
  542. else if (max == left.Y)
  543. {
  544. s = (float) (Math.Sqrt(left.Y - (up.Z + fwd.X) + 1.0));
  545. float y = (float) (s*0.5);
  546. s = (float) (0.5/s);
  547. return new Quaternion(
  548. (fwd.Y + left.X)*s,
  549. y,
  550. (left.Z + up.Y)*s,
  551. (up.X - fwd.Z)*s);
  552. }
  553. else
  554. {
  555. s = (float) (Math.Sqrt(up.Z - (fwd.X + left.Y) + 1.0));
  556. float z = (float) (s*0.5);
  557. s = (float) (0.5/s);
  558. return new Quaternion(
  559. (up.X + fwd.Z)*s,
  560. (left.Z + up.Y)*s,
  561. z,
  562. (fwd.Y - left.X)*s);
  563. }
  564. }
  565. }
  566. public static Random RandomClass
  567. {
  568. get { return randomClass; }
  569. }
  570. public static T Clamp<T>(T x, T min, T max)
  571. where T : IComparable<T>
  572. {
  573. return x.CompareTo(max) > 0
  574. ? max
  575. : x.CompareTo(min) < 0
  576. ? min
  577. : x;
  578. }
  579. public static uint GetNextXferID()
  580. {
  581. uint id = 0;
  582. lock (XferLock)
  583. {
  584. id = nextXferID;
  585. nextXferID++;
  586. }
  587. return id;
  588. }
  589. /// <summary>
  590. /// Debug utility function to convert unbroken strings of XML into something human readable for occasional debugging purposes.
  591. /// Please don't delete me even if I appear currently unused!
  592. /// </summary>
  593. /// <param name="rawXml"></param>
  594. /// <returns></returns>
  595. public static string GetFormattedXml(string rawXml)
  596. {
  597. XmlDocument xd = new XmlDocument();
  598. xd.LoadXml(rawXml);
  599. StringBuilder sb = new StringBuilder();
  600. StringWriter sw = new StringWriter(sb);
  601. XmlTextWriter xtw = new XmlTextWriter(sw) {Formatting = Formatting.Indented};
  602. try
  603. {
  604. xd.WriteTo(xtw);
  605. }
  606. finally
  607. {
  608. xtw.Close();
  609. }
  610. return sb.ToString();
  611. }
  612. public static bool IsEnvironmentSupported(ref string reason)
  613. {
  614. // Must have .NET 2.0 (Generics / libsl)
  615. if (Environment.Version.Major < 2)
  616. {
  617. reason = ".NET 1.0/1.1 lacks components that are used by Aurora";
  618. return false;
  619. }
  620. // Windows 95/98/ME are unsupported
  621. if (Environment.OSVersion.Platform == PlatformID.Win32Windows ||
  622. Environment.OSVersion.Platform == PlatformID.Win32S ||
  623. Environment.OSVersion.Platform == PlatformID.WinCE)
  624. {
  625. reason = "Windows 95/98/ME will not run Aurora";
  626. return false;
  627. }
  628. // Windows 2000 / Pre-SP2 XP
  629. if (Environment.OSVersion.Platform == PlatformID.Win32NT &&
  630. Environment.OSVersion.Version.Major == 5 &&
  631. Environment.OSVersion.Version.Minor == 0)
  632. {
  633. reason = "Please update to Windows XP Service Pack 2 or Server 2003 with .NET 3.5 installed";
  634. return false;
  635. }
  636. if (Environment.OSVersion.Platform == PlatformID.Win32NT &&
  637. Environment.Version.Major < 4 &&
  638. Environment.Version.Build < 50727) //.net 3.5
  639. {
  640. reason = ".NET versions before 3.5 lack components that are used by Aurora";
  641. return false;
  642. }
  643. return true;
  644. }
  645. public static bool IsLinux
  646. {
  647. get
  648. {
  649. int p = (int) Environment.OSVersion.Platform;
  650. return (p == 4) || (p == 6) || (p == 128);
  651. }
  652. }
  653. public static int UnixTimeSinceEpoch()
  654. {
  655. return ToUnixTime(DateTime.UtcNow);
  656. }
  657. public static int ToUnixTime(DateTime stamp)
  658. {
  659. TimeSpan t = stamp.ToUniversalTime() - UnixEpoch;
  660. return (int) t.TotalSeconds;
  661. }
  662. public static DateTime ToDateTime(ulong seconds)
  663. {
  664. DateTime epoch = UnixEpoch;
  665. return epoch.AddSeconds(seconds);
  666. }
  667. public static DateTime ToDateTime(int seconds)
  668. {
  669. DateTime epoch = UnixEpoch;
  670. return epoch.AddSeconds(seconds);
  671. }
  672. /// <summary>
  673. /// Return an md5 hash of the given string
  674. /// </summary>
  675. /// <param name="data"></param>
  676. /// <returns></returns>
  677. public static string Md5Hash(string data)
  678. {
  679. byte[] dataMd5 = ComputeMD5Hash(data);
  680. StringBuilder sb = new StringBuilder();
  681. foreach (byte t in dataMd5)
  682. sb.AppendFormat("{0:x2}", t);
  683. return sb.ToString();
  684. }
  685. private static byte[] ComputeMD5Hash(string data)
  686. {
  687. MD5 md5 = MD5.Create();
  688. return md5.ComputeHash(Encoding.Default.GetBytes(data));
  689. }
  690. /// <summary>
  691. /// Return an SHA1 hash of the given string
  692. /// </summary>
  693. /// <param name="data"></param>
  694. /// <returns></returns>
  695. public static string SHA1Hash(string data)
  696. {
  697. byte[] hash = ComputeSHA1Hash(data);
  698. return BitConverter.ToString(hash).Replace("-", String.Empty);
  699. }
  700. private static byte[] ComputeSHA1Hash(string src)
  701. {
  702. SHA1CryptoServiceProvider SHA1 = new SHA1CryptoServiceProvider();
  703. return SHA1.ComputeHash(Encoding.Default.GetBytes(src));
  704. }
  705. public static int fast_distance2d(int x, int y)
  706. {
  707. x = Math.Abs(x);
  708. y = Math.Abs(y);
  709. int min = Math.Min(x, y);
  710. return (x + y - (min >> 1) - (min >> 2) + (min >> 4));
  711. }
  712. // Inclusive, within range test (true if equal to the endpoints)
  713. public static bool InRange<T>(T x, T min, T max)
  714. where T : IComparable<T>
  715. {
  716. return x.CompareTo(max) <= 0 && x.CompareTo(min) >= 0;
  717. }
  718. // Clamp the maximum magnitude of a vector
  719. public static Vector3 ClampV(Vector3 x, float max)
  720. {
  721. Vector3 ret = x;
  722. float lenSq = x.LengthSquared();
  723. if (lenSq > (max*max))
  724. {
  725. x = x/x.Length()*max;
  726. }
  727. return x;
  728. }
  729. public static string FieldToString(byte[] bytes)
  730. {
  731. return FieldToString(bytes, String.Empty);
  732. }
  733. /// <summary>
  734. /// Convert a variable length field (byte array) to a string, with a
  735. /// field name prepended to each line of the output
  736. /// </summary>
  737. /// <remarks>
  738. /// If the byte array has unprintable characters in it, a
  739. /// hex dump will be put in the string instead
  740. /// </remarks>
  741. /// <param name="bytes">The byte array to convert to a string</param>
  742. /// <param name="fieldName">A field name to prepend to each line of output</param>
  743. /// <returns>
  744. /// An ASCII string or a string containing a hex dump, minus
  745. /// the null terminator
  746. /// </returns>
  747. public static string FieldToString(byte[] bytes, string fieldName)
  748. {
  749. // Check for a common case
  750. if (bytes.Length == 0) return String.Empty;
  751. StringBuilder output = new StringBuilder();
  752. bool printable = bytes.All(t => (t >= 0x20 && t <= 0x7E) || t == 0x09 || t == 0x0D || t == 0x0A || t == 0x00);
  753. if (printable)
  754. {
  755. if (fieldName.Length > 0)
  756. {
  757. output.Append(fieldName);
  758. output.Append(": ");
  759. }
  760. output.Append(CleanString(UTF8.GetString(bytes, 0, bytes.Length - 1)));
  761. }
  762. else
  763. {
  764. for (int i = 0; i < bytes.Length; i += 16)
  765. {
  766. if (i != 0)
  767. output.Append(Environment.NewLine);
  768. if (fieldName.Length > 0)
  769. {
  770. output.Append(fieldName);
  771. output.Append(": ");
  772. }
  773. for (int j = 0; j < 16; j++)
  774. {
  775. output.Append((i + j) < bytes.Length ? String.Format("{0:X2} ", bytes[i + j]) : " ");
  776. }
  777. for (int j = 0; j < 16 && (i + j) < bytes.Length; j++)
  778. {
  779. if (bytes[i + j] >= 0x20 && bytes[i + j] < 0x7E)
  780. output.Append((char) bytes[i + j]);
  781. else
  782. output.Append(".");
  783. }
  784. }
  785. }
  786. return output.ToString();
  787. }
  788. /// <summary>
  789. /// Removes all invalid path chars (OS dependent)
  790. /// </summary>
  791. /// <param name="path">path</param>
  792. /// <returns>safe path</returns>
  793. public static string safePath(string path)
  794. {
  795. return Regex.Replace(path, regexInvalidPathChars, String.Empty);
  796. }
  797. /// <summary>
  798. /// Removes all invalid filename chars (OS dependent)
  799. /// </summary>
  800. /// <param name="filename">filename</param>
  801. /// <returns>safe filename</returns>
  802. public static string safeFileName(string filename)
  803. {
  804. return Regex.Replace(filename, regexInvalidFileChars, String.Empty);
  805. }
  806. //
  807. // directory locations
  808. //
  809. public static string homeDir()
  810. {
  811. string temp;
  812. // string personal=(Environment.GetFolderPath(Environment.SpecialFolder.Personal));
  813. // temp = Path.Combine(personal,".OpenSim");
  814. temp = ".";
  815. return temp;
  816. }
  817. public static string configDir()
  818. {
  819. return ".";
  820. }
  821. public static string dataDir()
  822. {
  823. return ".";
  824. }
  825. public static string logDir()
  826. {
  827. return ".";
  828. }
  829. // From: http://coercedcode.blogspot.com/2008/03/c-generate-unique-filenames-within.html
  830. public static string GetUniqueFilename(string FileName)
  831. {
  832. int count = 0;
  833. string Name;
  834. if (File.Exists(FileName))
  835. {
  836. FileInfo f = new FileInfo(FileName);
  837. Name = !String.IsNullOrEmpty(f.Extension)
  838. ? f.FullName.Substring(0, f.FullName.LastIndexOf('.'))
  839. : f.FullName;
  840. while (File.Exists(FileName))
  841. {
  842. count++;
  843. FileName = Name + count + f.Extension;
  844. }
  845. }
  846. return FileName;
  847. }
  848. // Nini (config) related Methods
  849. public static IConfigSource ConvertDataRowToXMLConfig(DataRow row, string fileName)
  850. {
  851. if (!File.Exists(fileName))
  852. {
  853. //create new file
  854. }
  855. XmlConfigSource config = new XmlConfigSource(fileName);
  856. AddDataRowToConfig(config, row);
  857. config.Save();
  858. return config;
  859. }
  860. public static void AddDataRowToConfig(IConfigSource config, DataRow row)
  861. {
  862. config.Configs.Add((string) row[0]);
  863. for (int i = 0; i < row.Table.Columns.Count; i++)
  864. {
  865. config.Configs[(string) row[0]].Set(row.Table.Columns[i].ColumnName, row[i]);
  866. }
  867. }
  868. public static float Clip(float x, float min, float max)
  869. {
  870. return Math.Min(Math.Max(x, min), max);
  871. }
  872. public static int Clip(int x, int min, int max)
  873. {
  874. return Math.Min(Math.Max(x, min), max);
  875. }
  876. /// <summary>
  877. /// Convert an UUID to a raw uuid string. Right now this is a string without hyphens.
  878. /// </summary>
  879. /// <param name="UUID"></param>
  880. /// <returns></returns>
  881. public static String ToRawUuidString(UUID UUID)
  882. {
  883. return UUID.Guid.ToString("n");
  884. }
  885. public static string CleanString(string input)
  886. {
  887. if (input.Length == 0)
  888. return input;
  889. int clip = input.Length;
  890. // Test for ++ string terminator
  891. int pos = input.IndexOf("\0");
  892. if (pos != -1 && pos < clip)
  893. clip = pos;
  894. // Test for CR
  895. pos = input.IndexOf("\r");
  896. if (pos != -1 && pos < clip)
  897. clip = pos;
  898. // Test for LF
  899. pos = input.IndexOf("\n");
  900. if (pos != -1 && pos < clip)
  901. clip = pos;
  902. // Truncate string before first end-of-line character found
  903. return input.Substring(0, clip);
  904. }
  905. /// <summary>
  906. /// returns the contents of /etc/issue on Unix Systems
  907. /// Use this for where it's absolutely necessary to implement platform specific stuff
  908. /// </summary>
  909. /// <returns></returns>
  910. public static string ReadEtcIssue()
  911. {
  912. try
  913. {
  914. StreamReader sr = new StreamReader("/etc/issue.net");
  915. string issue = sr.ReadToEnd();
  916. sr.Close();
  917. return issue;
  918. }
  919. catch (Exception)
  920. {
  921. return "";
  922. }
  923. }
  924. public static void SerializeToFile(string filename, Object obj)
  925. {
  926. IFormatter formatter = new BinaryFormatter();
  927. Stream stream = null;
  928. try
  929. {
  930. stream = new FileStream(
  931. filename, FileMode.Create,
  932. FileAccess.Write, FileShare.None);
  933. formatter.Serialize(stream, obj);
  934. }
  935. catch (Exception e)
  936. {
  937. MainConsole.Instance.Error(e.ToString());
  938. }
  939. finally
  940. {
  941. if (stream != null)
  942. {
  943. stream.Close();
  944. }
  945. }
  946. }
  947. public static Object DeserializeFromFile(string filename)
  948. {
  949. IFormatter formatter = new BinaryFormatter();
  950. Stream stream = null;
  951. Object ret = null;
  952. try
  953. {
  954. stream = new FileStream(
  955. filename, FileMode.Open,
  956. FileAccess.Read, FileShare.None);
  957. ret = formatter.Deserialize(stream);
  958. }
  959. catch (Exception e)
  960. {
  961. MainConsole.Instance.Error(e.ToString());
  962. }
  963. finally
  964. {
  965. if (stream != null)
  966. {
  967. stream.Close();
  968. }
  969. }
  970. return ret;
  971. }
  972. public static void Compress7ZipFile(string path, string destination)
  973. {
  974. ProcessStartInfo p = new ProcessStartInfo();
  975. string pa = Path.GetDirectoryName(Assembly.GetAssembly(typeof (Util)).CodeBase);
  976. if (pa != null)
  977. {
  978. p.FileName = Path.Combine(pa, "7za.exe");
  979. p.Arguments = "a -y -tgzip \"" + destination + "\" \"" + path + "\" -mx=9";
  980. p.WindowStyle = ProcessWindowStyle.Hidden;
  981. Process x = Process.Start(p);
  982. x.WaitForExit();
  983. }
  984. }
  985. public static void UnCompress7ZipFile(string path, string destination)
  986. {
  987. ProcessStartInfo p = new ProcessStartInfo();
  988. string pa = Path.GetDirectoryName(Assembly.GetAssembly(typeof (Util)).CodeBase);
  989. if (pa != null)
  990. {
  991. p.FileName = Path.Combine(pa, "7za.exe");
  992. p.Arguments = "e -y \"" + path + "\" -o\"" + destination + "\" -mx=9";
  993. p.WindowStyle = ProcessWindowStyle.Hidden;
  994. Process x = Process.Start(p);
  995. x.WaitForExit();
  996. }
  997. }
  998. public static string Compress(string text)
  999. {
  1000. byte[] buffer = UTF8.GetBytes(text);
  1001. MemoryStream memory = new MemoryStream();
  1002. using (GZipStream compressor = new GZipStream(memory, CompressionMode.Compress, true))
  1003. {
  1004. compressor.Write(buffer, 0, buffer.Length);
  1005. }
  1006. memory.Position = 0;
  1007. byte[] compressed = new byte[memory.Length];
  1008. memory.Read(compressed, 0, compressed.Length);
  1009. byte[] compressedBuffer = new byte[compressed.Length + 4];
  1010. Buffer.BlockCopy(compressed, 0, compressedBuffer, 4, compressed.Length);
  1011. Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, compressedBuffer, 0, 4);
  1012. return Convert.ToBase64String(compressedBuffer);
  1013. }
  1014. public static byte[] CompressBytes(byte[] buffer)
  1015. {
  1016. MemoryStream memory = new MemoryStream();
  1017. using (GZipStream compressor = new GZipStream(memory, CompressionMode.Compress, true))
  1018. {
  1019. compressor.Write(buffer, 0, buffer.Length);
  1020. }
  1021. memory.Position = 0;
  1022. byte[] compressed = new byte[memory.Length];
  1023. memory.Read(compressed, 0, compressed.Length);
  1024. byte[] compressedBuffer = new byte[compressed.Length + 4];
  1025. Buffer.BlockCopy(compressed, 0, compressedBuffer, 4, compressed.Length);
  1026. Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, compressedBuffer, 0, 4);
  1027. return compressedBuffer;
  1028. }
  1029. public static string Decompress(string compressedText)
  1030. {
  1031. byte[] compressedBuffer = Convert.FromBase64String(compressedText);
  1032. using (MemoryStream memory = new MemoryStream())
  1033. {
  1034. int msgLength = BitConverter.ToInt32(compressedBuffer, 0);
  1035. memory.Write(compressedBuffer, 4, compressedBuffer.Length - 4);
  1036. byte[] buffer = new byte[msgLength];
  1037. memory.Position = 0;
  1038. using (GZipStream decompressor = new GZipStream(memory, CompressionMode.Decompress))
  1039. {
  1040. decompressor.Read(buffer, 0, buffer.Length);
  1041. }
  1042. return UTF8.GetString(buffer);
  1043. }
  1044. }
  1045. public static Stream DecompressStream(Stream compressedStream)
  1046. {
  1047. byte[] compressedBuffer = ReadToEnd(compressedStream);
  1048. using (MemoryStream memory = new MemoryStream())
  1049. {
  1050. int msgLength = BitConverter.ToInt32(compressedBuffer, 0);
  1051. memory.Write(compressedBuffer, 4, compressedBuffer.Length - 4);
  1052. byte[] buffer = new byte[msgLength];
  1053. memory.Position = 0;
  1054. using (GZipStream decompressor = new GZipStream(memory, CompressionMode.Decompress))
  1055. {
  1056. decompressor.Read(buffer, 0, buffer.Length);
  1057. }
  1058. return new MemoryStream(buffer);
  1059. }
  1060. }
  1061. public static byte[] ReadToEnd(System.IO.Stream stream)
  1062. {
  1063. byte[] readBuffer = new byte[4096];
  1064. int totalBytesRead = 0;
  1065. int bytesRead;
  1066. while ((bytesRead = stream.Read(readBuffer, totalBytesRead, readBuffer.Length - totalBytesRead)) > 0)
  1067. {
  1068. totalBytesRead += bytesRead;
  1069. if (totalBytesRead == readBuffer.Length)
  1070. {
  1071. int nextByte = stream.ReadByte();
  1072. if (nextByte != -1)
  1073. {
  1074. byte[] temp = new byte[readBuffer.Length*2];
  1075. Buffer.BlockCopy(readBuffer, 0, temp, 0, readBuffer.Length);
  1076. Buffer.SetByte(temp, totalBytesRead, (byte) nextByte);
  1077. readBuffer = temp;
  1078. totalBytesRead++;
  1079. }
  1080. }
  1081. }
  1082. byte[] buffer = readBuffer;
  1083. if (readBuffer.Length != totalBytesRead)
  1084. {
  1085. buffer = new byte[totalBytesRead];
  1086. Buffer.BlockCopy(readBuffer, 0, buffer, 0, totalBytesRead);
  1087. }
  1088. return buffer;
  1089. }
  1090. /// <summary>
  1091. /// Converts a byte array in big endian order into an ulong.
  1092. /// </summary>
  1093. /// <param name="bytes">
  1094. /// The array of bytes
  1095. /// </param>
  1096. /// <returns>
  1097. /// The extracted ulong
  1098. /// </returns>
  1099. public static ulong BytesToUInt64Big(byte[] bytes)
  1100. {
  1101. if (bytes.Length < 8) return 0;
  1102. return ((ulong) bytes[0] << 56) | ((ulong) bytes[1] << 48) | ((ulong) bytes[2] << 40) |
  1103. ((ulong) bytes[3] << 32) |
  1104. ((ulong) bytes[4] << 24) | ((ulong) bytes[5] << 16) | ((ulong) bytes[6] << 8) | bytes[7];
  1105. }
  1106. // used for RemoteParcelRequest (for "About Landmark")
  1107. public static UUID BuildFakeParcelID(ulong regionHandle, uint x, uint y)
  1108. {
  1109. byte[] bytes =
  1110. {
  1111. (byte) regionHandle, (byte) (regionHandle >> 8), (byte) (regionHandle >> 16),
  1112. (byte) (regionHandle >> 24),
  1113. (byte) (regionHandle >> 32), (byte) (regionHandle >> 40), (byte) (regionHandle >> 48),
  1114. (byte) (regionHandle << 56),
  1115. (byte) x, (byte) (x >> 8), 0, 0,
  1116. (byte) y, (byte) (y >> 8), 0, 0
  1117. };
  1118. return new UUID(bytes, 0);
  1119. }
  1120. public static UUID BuildFakeParcelID(ulong regionHandle, uint x, uint y, uint z)
  1121. {
  1122. byte[] bytes =
  1123. {
  1124. (byte) regionHandle, (byte) (regionHandle >> 8), (byte) (regionHandle >> 16),
  1125. (byte) (regionHandle >> 24),
  1126. (byte) (regionHandle >> 32), (byte) (regionHandle >> 40), (byte) (regionHandle >> 48),
  1127. (byte) (regionHandle << 56),
  1128. (byte) x, (byte) (x >> 8), (byte) z, (byte) (z >> 8),
  1129. (byte) y, (byte) (y >> 8), 0, 0
  1130. };
  1131. return new UUID(bytes, 0);
  1132. }
  1133. public static void ParseFakeParcelID(UUID parcelID, out ulong regionHandle, out uint x, out uint y)
  1134. {
  1135. byte[] bytes = parcelID.GetBytes();
  1136. regionHandle = Utils.BytesToUInt64(bytes);
  1137. x = Utils.BytesToUInt(bytes, 8) & 0xffff;
  1138. y = Utils.BytesToUInt(bytes, 12) & 0xffff;
  1139. }
  1140. public static void ParseFakeParcelID(UUID parcelID, out ulong regionHandle, out uint x, out uint y, out uint z)
  1141. {
  1142. byte[] bytes = parcelID.GetBytes();
  1143. regionHandle = Utils.BytesToUInt64(bytes);
  1144. x = Utils.BytesToUInt(bytes, 8) & 0xffff;
  1145. z = (Utils.BytesToUInt(bytes, 8) & 0xffff0000) >> 16;
  1146. y = Utils.BytesToUInt(bytes, 12) & 0xffff;
  1147. }
  1148. public static void FakeParcelIDToGlobalPosition(UUID parcelID, out uint x, out uint y)
  1149. {
  1150. ulong regionHandle;
  1151. uint rx, ry;
  1152. ParseFakeParcelID(parcelID, out regionHandle, out x, out y);
  1153. Utils.LongToUInts(regionHandle, out rx, out ry);
  1154. x += rx;
  1155. y += ry;
  1156. }
  1157. /// <summary>
  1158. /// Get operating system information if available. Returns only the first 45 characters of information
  1159. /// </summary>
  1160. /// <returns>
  1161. /// Operating system information. Returns an empty string if none was available.
  1162. /// </returns>
  1163. public static string GetOperatingSystemInformation()
  1164. {
  1165. string os = String.Empty;
  1166. os = Environment.OSVersion.Platform != PlatformID.Unix ? Environment.OSVersion.ToString() : ReadEtcIssue();
  1167. if (os.Length > 45)
  1168. {
  1169. os = os.Substring(0, 45);
  1170. }
  1171. return os;
  1172. }
  1173. public static string GetRuntimeInformation()
  1174. {
  1175. string ru = String.Empty;
  1176. switch (Environment.OSVersion.Platform)
  1177. {
  1178. case PlatformID.Unix:
  1179. ru = "Unix/Mono";
  1180. break;
  1181. case PlatformID.MacOSX:
  1182. ru = "OSX/Mono";
  1183. break;
  1184. default:
  1185. ru = Type.GetType("Mono.Runtime") != null ? "Win/Mono" : "Win/.NET";
  1186. break;
  1187. }
  1188. return ru;
  1189. }
  1190. public static RuntimeEnvironment GetRuntimeEnvironment()
  1191. {
  1192. switch (Environment.OSVersion.Platform)
  1193. {
  1194. case PlatformID.Unix:
  1195. return RuntimeEnvironment.Mono;
  1196. case PlatformID.MacOSX:
  1197. return RuntimeEnvironment.Mono;
  1198. default:
  1199. return Type.GetType("Mono.Runtime") != null
  1200. ? RuntimeEnvironment.WinMono
  1201. : RuntimeEnvironment.NET;
  1202. }
  1203. }
  1204. /// <summary>
  1205. /// Is the given string a UUID?
  1206. /// </summary>
  1207. /// <param name="s"></param>
  1208. /// <returns></returns>
  1209. public static bool isUUID(string s)
  1210. {
  1211. return UUIDPattern.IsMatch(s);
  1212. }
  1213. public static string GetDisplayConnectionString(string connectionString)
  1214. {
  1215. int passPosition = 0;
  1216. int passEndPosition = 0;
  1217. string displayConnectionString = null;
  1218. // hide the password in the connection string
  1219. passPosition = connectionString.IndexOf("password", StringComparison.OrdinalIgnoreCase);
  1220. passPosition = connectionString.IndexOf("=", passPosition);
  1221. if (passPosition < connectionString.Length)
  1222. passPosition += 1;
  1223. passEndPosition = connectionString.IndexOf(";", passPosition);
  1224. displayConnectionString = connectionString.Substring(0, passPosition);
  1225. displayConnectionString += "***";
  1226. displayConnectionString += connectionString.Substring(passEndPosition,
  1227. connectionString.Length - passEndPosition);
  1228. return displayConnectionString;
  1229. }
  1230. public static T ReadSettingsFromIniFile<T>(IConfig config, T settingsClass)
  1231. {
  1232. Type settingsType = settingsClass.GetType();
  1233. FieldInfo[] fieldInfos = settingsType.GetFields();
  1234. foreach (FieldInfo fieldInfo in fieldInfos)
  1235. {
  1236. if (!fieldInfo.IsStatic)
  1237. {
  1238. if (fieldInfo.FieldType == typeof (String))
  1239. {
  1240. fieldInfo.SetValue(settingsClass,
  1241. config.Get(fieldInfo.Name, (string) fieldInfo.GetValue(settingsClass)));
  1242. }
  1243. else if (fieldInfo.FieldType == typeof (Boolean))
  1244. {
  1245. fieldInfo.SetValue(settingsClass,
  1246. config.GetBoolean(fieldInfo.Name, (bool) fieldInfo.GetValue(settingsClass)));
  1247. }
  1248. else if (fieldInfo.FieldType == typeof (Int32))
  1249. {
  1250. fieldInfo.SetValue(settingsClass,
  1251. config.GetInt(fieldInfo.Name, (int) fieldInfo.GetValue(settingsClass)));
  1252. }
  1253. else if (fieldInfo.FieldType == typeof (Single))
  1254. {
  1255. fieldInfo.SetValue(settingsClass,
  1256. config.GetFloat(fieldInfo.Name, (float) fieldInfo.GetValue(settingsClass)));
  1257. }
  1258. else if (fieldInfo.FieldType == typeof (UInt32))
  1259. {
  1260. fieldInfo.SetValue(settingsClass,
  1261. Convert.ToUInt32(config.Get(fieldInfo.Name,
  1262. ((uint) fieldInfo.GetValue(settingsClass))
  1263. .ToString())));
  1264. }
  1265. }
  1266. }
  1267. PropertyInfo[] propertyInfos = settingsType.GetProperties();
  1268. foreach (PropertyInfo propInfo in propertyInfos)
  1269. {
  1270. if ((propInfo.CanRead) && (propInfo.CanWrite))
  1271. {
  1272. if (propInfo.PropertyType == typeof (String))
  1273. {
  1274. propInfo.SetValue(settingsClass,
  1275. config.Get(propInfo.Name, (string) propInfo.GetValue(settingsClass, null)),
  1276. null);
  1277. }
  1278. else if (propInfo.PropertyType == typeof (Boolean))
  1279. {
  1280. propInfo.SetValue(settingsClass,
  1281. config.GetBoolean(propInfo.Name, (bool) propInfo.GetValue(settingsClass, null)),
  1282. null);
  1283. }
  1284. else if (propInfo.PropertyType == typeof (Int32))
  1285. {
  1286. propInfo.SetValue(settingsClass,
  1287. config.GetInt(propInfo.Name, (int) propInfo.GetValue(settingsClass, null)),
  1288. null);
  1289. }
  1290. else if (propInfo.PropertyType == typeof (Single))
  1291. {
  1292. propInfo.SetValue(settingsClass,
  1293. config.GetFloat(propInfo.Name, (float) propInfo.GetValue(settingsClass, null)),
  1294. null);
  1295. }
  1296. if (propInfo.PropertyType == typeof (UInt32))
  1297. {
  1298. propInfo.SetValue(settingsClass,
  1299. Convert.ToUInt32(config.Get(propInfo.Name,
  1300. ((uint) propInfo.GetValue(settingsClass, null))
  1301. .ToString())), null);
  1302. }
  1303. }
  1304. }
  1305. return settingsClass;
  1306. }
  1307. public static string Base64ToString(string str)
  1308. {
  1309. UTF8Encoding encoder = new UTF8Encoding();
  1310. Decoder utf8Decode = encoder.GetDecoder();
  1311. byte[] todecode_byte = Convert.FromBase64String(str);
  1312. int charCount = utf8Decode.GetCharCount(todecode_byte, 0, todecode_byte.Length);
  1313. char[] decoded_char = new char[charCount];
  1314. utf8Decode.GetChars(todecode_byte, 0, todecode_byte.Length, decoded_char, 0);
  1315. string result = new String(decoded_char);
  1316. return result;
  1317. }
  1318. public static Guid GetHashGuid(string data, string salt)
  1319. {
  1320. byte[] hash = ComputeMD5Hash(data + salt);
  1321. //string s = BitConverter.ToString(hash);
  1322. Guid guid = new Guid(hash);
  1323. return guid;
  1324. }
  1325. public static byte ConvertMaturityToAccessLevel(uint maturity)
  1326. {
  1327. byte retVal = 0;
  1328. switch (maturity)
  1329. {
  1330. case 0: //PG
  1331. retVal = 13;
  1332. break;
  1333. case 1: //Mature
  1334. retVal = 21;
  1335. break;
  1336. case 2: // Adult
  1337. retVal = 42;
  1338. break;
  1339. }
  1340. return retVal;
  1341. }
  1342. public static uint ConvertAccessLevelToMaturity(byte maturity)
  1343. {
  1344. uint retVal = 0;
  1345. switch (maturity)
  1346. {
  1347. case 13: //PG
  1348. retVal = 0;
  1349. break;
  1350. case 21: //Mature
  1351. retVal = 1;
  1352. break;
  1353. case 42: // Adult
  1354. retVal = 2;
  1355. break;
  1356. }
  1357. return retVal;
  1358. }
  1359. /// <summary>
  1360. /// Produces an OSDMap from its string representation on a stream
  1361. /// </summary>
  1362. /// <param name="stream">The stream</param>
  1363. /// <param name="length">The size of the data on the stream</param>
  1364. /// <returns>The OSDMap or an exception</returns>
  1365. public static OSDMap GetOSDMap(Stream stream, int length)
  1366. {
  1367. byte[] data = new byte[length];
  1368. stream.Read(data, 0, length);
  1369. string strdata = UTF8.GetString(data);
  1370. OSDMap args = null;
  1371. OSD buffer;
  1372. buffer = OSDParser.DeserializeJson(strdata);
  1373. if (buffer.Type == OSDType.Map)
  1374. {
  1375. args = (OSDMap) buffer;
  1376. return args;
  1377. }
  1378. return null;
  1379. }
  1380. public static OSDMap GetOSDMap(string data)
  1381. {
  1382. OSDMap args = null;
  1383. try
  1384. {
  1385. OSD buffer;
  1386. // We should pay attention to the content-type, but let's assume we know it's Json
  1387. buffer = OSDParser.DeserializeJson(data);
  1388. if (buffer.Type == OSDType.Map)
  1389. {
  1390. args = (OSDMap) buffer;
  1391. return args;
  1392. }
  1393. else
  1394. {
  1395. // uh?
  1396. MainConsole.Instance.Debug(("[UTILS]: Got OSD of unexpected type " + buffer.Type.ToString()));
  1397. return null;
  1398. }
  1399. }
  1400. catch (Exception ex)
  1401. {
  1402. MainConsole.Instance.Debug("[UTILS]: exception on GetOSDMap " + ex);
  1403. return null;
  1404. }
  1405. }
  1406. public static string[] Glob(string path)
  1407. {
  1408. string vol = String.Empty;
  1409. if (Path.VolumeSeparatorChar != Path.DirectorySeparatorChar)
  1410. {
  1411. string[] vcomps = path.Split(new[] {Path.VolumeSeparatorChar}, 2, StringSplitOptions.RemoveEmptyEntries);
  1412. if (vcomps.Length > 1)
  1413. {
  1414. path = vcomps[1];
  1415. vol = vcomps[0];
  1416. }
  1417. }
  1418. string[] comps = path.Split(new[] {Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar},
  1419. StringSplitOptions.RemoveEmptyEntries);
  1420. // Glob
  1421. path = vol;
  1422. if (vol != String.Empty)
  1423. path += new String(new[] {Path.VolumeSeparatorChar, Path.DirectorySeparatorChar});
  1424. else
  1425. path = new String(new[] {Path.DirectorySeparatorChar});
  1426. List<string> paths = new List<string>();
  1427. List<string> found = new List<string>();
  1428. paths.Add(path);
  1429. int compIndex = -1;
  1430. foreach (string c in comps)
  1431. {
  1432. compIndex++;
  1433. List<string> addpaths = new List<string>();
  1434. foreach (string p in paths)
  1435. {
  1436. string[] dirs = Directory.GetDirectories(p, c);
  1437. if (dirs.Length != 0)
  1438. {
  1439. addpaths.AddRange(dirs.Select(dir => Path.Combine(path, dir)));
  1440. }
  1441. // Only add files if that is the last path component
  1442. if (compIndex == comps.Length - 1)
  1443. {
  1444. string[] files = Directory.GetFiles(p, c);
  1445. found.AddRange(files);
  1446. }
  1447. }
  1448. paths = addpaths;
  1449. }
  1450. return found.ToArray();
  1451. }
  1452. public static string[] GetSubFiles(string path)
  1453. {
  1454. string[] comps = path.Split(new[] {Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar},
  1455. StringSplitOptions.None);
  1456. List<string> paths = new List<string>();
  1457. string endFind = comps[comps.Length - 1];
  1458. string baseDir = "";
  1459. for (int i = 0; i < comps.Length - 1; i++)
  1460. {
  1461. if (i == comps.Length - 2)
  1462. baseDir += comps[i];
  1463. else
  1464. baseDir += comps[i] + Path.DirectorySeparatorChar;
  1465. }
  1466. paths.Add(baseDir);
  1467. return paths.SelectMany(p => Directory.GetFiles(p, endFind)).ToArray();
  1468. }
  1469. public static byte[] StringToBytes256(string str, params object[] args)
  1470. {
  1471. return StringToBytes256(string.Format(str, args));
  1472. }
  1473. public static byte[] StringToBytes1024(string str, params object[] args)
  1474. {
  1475. return StringToBytes1024(string.Format(str, args));
  1476. }
  1477. public static byte[] StringToBytes256(string str)
  1478. {
  1479. if (String.IsNullOrEmpty(str))
  1480. {
  1481. return Utils.EmptyBytes;
  1482. }
  1483. if (str.Length > 254) str = str.Remove(254);
  1484. if (!str.EndsWith("\0"))
  1485. {
  1486. str += "\0";
  1487. }
  1488. // Because this is UTF-8 encoding and not ASCII, it's possible we
  1489. // might have gotten an oversized array even after the string trim
  1490. byte[] data = UTF8.GetBytes(str);
  1491. if (data.Length > 256)
  1492. {
  1493. Array.Resize(ref data, 256);
  1494. data[255] = 0;
  1495. }
  1496. return data;
  1497. }
  1498. public static byte[] StringToBytes1024(string str)
  1499. {
  1500. if (String.IsNullOrEmpty(str))
  1501. {
  1502. return Utils.EmptyBytes;
  1503. }
  1504. if (str.Length > 1023) str = str.Remove(1023);
  1505. if (!str.EndsWith("\0"))
  1506. {
  1507. str += "\0";
  1508. }
  1509. // Because this is UTF-8 encoding and not ASCII, it's possible we
  1510. // might have gotten an oversized array even after the string trim
  1511. byte[] data = UTF8.GetBytes(str);
  1512. if (data.Length > 1024)
  1513. {
  1514. Array.Resize(ref data, 1024);
  1515. data[1023] = 0;
  1516. }
  1517. return data;
  1518. }
  1519. #region FireAndForget Threading Pattern
  1520. /// <summary>
  1521. /// Created to work around a limitation in Mono with nested delegates
  1522. /// </summary>
  1523. private sealed class FireAndForgetWrapper
  1524. {
  1525. private static volatile FireAndForgetWrapper instance;
  1526. private static readonly object syncRoot = new Object();
  1527. public static FireAndForgetWrapper Instance
  1528. {
  1529. get
  1530. {
  1531. if (instance == null)
  1532. {
  1533. lock (syncRoot)
  1534. {
  1535. if (instance == null)
  1536. {
  1537. instance = new FireAndForgetWrapper();
  1538. }
  1539. }
  1540. }
  1541. return instance;
  1542. }
  1543. }
  1544. public void FireAndForget(WaitCallback callback)
  1545. {
  1546. callback.BeginInvoke(null, EndFireAndForget, callback);
  1547. }
  1548. public void FireAndForget(WaitCallback callback, object obj)
  1549. {
  1550. callback.BeginInvoke(obj, EndFireAndForget, callback);
  1551. }
  1552. private static void EndFireAndForget(IAsyncResult ar)
  1553. {
  1554. WaitCallback callback = (WaitCallback) ar.AsyncState;
  1555. try
  1556. {
  1557. callback.EndInvoke(ar);
  1558. }
  1559. catch (Exception ex)
  1560. {
  1561. MainConsole.Instance.ErrorFormat("[UTIL]: Asynchronous method threw an exception: {0}", ex.ToString());
  1562. }
  1563. ar.AsyncWaitHandle.Close();
  1564. }
  1565. }
  1566. public static void FireAndForget(WaitCallback callback)
  1567. {
  1568. FireAndForget(callback, null);
  1569. }
  1570. public static void InitThreadPool(int maxThreads)
  1571. {
  1572. if (maxThreads < 2)
  1573. throw new ArgumentOutOfRangeException("maxThreads", "maxThreads must be greater than 2");
  1574. if (m_ThreadPool != null)
  1575. throw new InvalidOperationException("SmartThreadPool is already initialized");
  1576. m_threadPoolRunning = true;
  1577. m_ThreadPool = new SmartThreadPool(2000, maxThreads, 2);
  1578. }
  1579. public static void CloseThreadPool()
  1580. {
  1581. if (FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool &&
  1582. m_ThreadPool != null)
  1583. {
  1584. //This stops more tasks and threads from being started
  1585. m_threadPoolRunning = false;
  1586. m_ThreadPool.WaitForIdle(60*1000);
  1587. //Wait for the threads to be idle, but don't wait for more than a minute
  1588. //Destroy the threadpool now
  1589. m_ThreadPool.Dispose();
  1590. m_ThreadPool = null;
  1591. }
  1592. }
  1593. public static int FireAndForgetCount()
  1594. {
  1595. const int MAX_SYSTEM_THREADS = 200;
  1596. switch (FireAndForgetMethod)
  1597. {
  1598. case FireAndForgetMethod.UnsafeQueueUserWorkItem:
  1599. case FireAndForgetMethod.QueueUserWorkItem:
  1600. case FireAndForgetMethod.BeginInvoke:
  1601. int workerThreads, iocpThreads;
  1602. ThreadPool.GetAvailableThreads(out workerThreads, out iocpThreads);
  1603. return workerThreads;
  1604. case FireAndForgetMethod.SmartThreadPool:
  1605. if (m_ThreadPool == null || !m_threadPoolRunning)
  1606. return 0;
  1607. return m_ThreadPool.MaxThreads - m_ThreadPool.InUseThreads;
  1608. case FireAndForgetMethod.Thread:
  1609. return MAX_SYSTEM_THREADS - Process.GetCurrentProcess().Threads.Count;
  1610. default:
  1611. throw new NotImplementedException();
  1612. }
  1613. }
  1614. public static void FireAndForget(WaitCallback callback, object obj)
  1615. {
  1616. switch (FireAndForgetMethod)
  1617. {
  1618. case FireAndForgetMethod.UnsafeQueueUserWorkItem:
  1619. ThreadPool.UnsafeQueueUserWorkItem(callback, obj);
  1620. break;
  1621. case FireAndForgetMethod.QueueUserWorkItem:
  1622. ThreadPool.QueueUserWorkItem(callback, obj);
  1623. break;
  1624. case FireAndForgetMethod.BeginInvoke:
  1625. FireAndForgetWrapper wrapper = FireAndForgetWrapper.Instance;
  1626. wrapper.FireAndForget(callback, obj);
  1627. break;
  1628. case FireAndForgetMethod.SmartThreadPool:
  1629. if (m_ThreadPool == null)
  1630. InitThreadPool(15);
  1631. if (m_threadPoolRunning) //Check if the thread pool should be running
  1632. m_ThreadPool.QueueWorkItem((WorkItemCallback) SmartThreadPoolCallback, new[] {callback, obj});
  1633. break;
  1634. case FireAndForgetMethod.Thread:
  1635. Thread thread = new Thread(delegate(object o)
  1636. {
  1637. Culture.SetCurrentCulture();
  1638. callback(o);
  1639. });
  1640. thread.Start(obj);
  1641. break;
  1642. default:
  1643. throw new NotImplementedException();
  1644. }
  1645. }
  1646. private static object SmartThreadPoolCallback(object o)
  1647. {
  1648. object[] array = (object[]) o;
  1649. WaitCallback callback = (WaitCallback) array[0];
  1650. object obj = array[1];
  1651. callback(obj);
  1652. return null;
  1653. }
  1654. #endregion FireAndForget Threading Pattern
  1655. /// <summary>
  1656. /// Environment.TickCount is an int but it counts all 32 bits so it goes positive
  1657. /// and negative every 24.9 days. This trims down TickCount so it doesn't wrap
  1658. /// for the callers.
  1659. /// This trims it to a 12 day interval so don't let your frame time get too long.
  1660. /// </summary>
  1661. /// <returns></returns>
  1662. public static Int32 EnvironmentTickCount()
  1663. {
  1664. return Environment.TickCount & EnvironmentTickCountMask;
  1665. }
  1666. public const Int32 EnvironmentTickCountMask = 0x3fffffff;
  1667. /// <summary>
  1668. /// Environment.TickCount is an int but it counts all 32 bits so it goes positive
  1669. /// and negative every 24.9 days. Subtracts the passed value (previously fetched by
  1670. /// 'EnvironmentTickCount()') and accounts for any wrapping.
  1671. /// </summary>
  1672. /// <returns>subtraction of passed prevValue from current Environment.TickCount</returns>
  1673. public static Int32 EnvironmentTickCountSubtract(Int32 prevValue)
  1674. {
  1675. Int32 diff = EnvironmentTickCount() - prevValue;
  1676. return (diff >= 0) ? diff : (diff + EnvironmentTickCountMask + 1);
  1677. }
  1678. /// <summary>
  1679. /// Environment.TickCount is an int but it counts all 32 bits so it goes positive
  1680. /// and negative every 24.9 days. Adds the passed value (previously fetched by
  1681. /// 'EnvironmentTickCount()') and accounts for any wrapping.
  1682. /// </summary>
  1683. /// <returns>addition of passed prevValue from current Environment.TickCount</returns>
  1684. public static Int32 EnvironmentTickCountAdd(Int32 ms)
  1685. {
  1686. Int32 add = EnvironmentTickCount() + ms;
  1687. return (add >= EnvironmentTickCountMask) ? add - EnvironmentTickCountMask : add;
  1688. }
  1689. /// <summary>
  1690. /// Prints the call stack at any given point. Useful for debugging.
  1691. /// </summary>
  1692. public static void PrintCallStack()
  1693. {
  1694. StackTrace stackTrace = new StackTrace(); // get call stack
  1695. StackFrame[] stackFrames = stackTrace.GetFrames(); // get method calls (frames)
  1696. // write call stack method names
  1697. foreach (StackFrame stackFrame in stackFrames)
  1698. {
  1699. MainConsole.Instance.Debug(stackFrame.GetMethod().DeclaringType + "." + stackFrame.GetMethod().Name);
  1700. // write method name
  1701. }
  1702. }
  1703. public static OSDMap DictionaryToOSD(Dictionary<string, object> sendData)
  1704. {
  1705. OSDMap map = new OSDMap();
  1706. foreach (KeyValuePair<string, object> kvp in sendData)
  1707. {
  1708. if (kvp.Value is Dictionary<string, object>)
  1709. {
  1710. map[kvp.Key] = DictionaryToOSD(kvp.Value as Dictionary<string, object>);
  1711. }
  1712. else
  1713. {
  1714. OSD v = OSD.FromObject(kvp.Value);
  1715. OSD val = kvp.Value as OSD;
  1716. map[kvp.Key] = v.Type == OSDType.Unknown ? val : v;
  1717. }
  1718. }
  1719. return map;
  1720. }
  1721. public static Dictionary<string, object> OSDToDictionary(OSDMap map)
  1722. {
  1723. Dictionary<string, object> retVal = new Dictionary<string, object>();
  1724. foreach (string key in map.Keys)
  1725. {
  1726. retVal.Add(key, OSDToObject(map[key]));
  1727. }
  1728. return retVal;
  1729. }
  1730. public static OSD MakeOSD(object o, Type t)
  1731. {
  1732. if (o is OSD)
  1733. return (OSD) o;
  1734. if (o is System.Drawing.Image)
  1735. return OSDBinary.FromBinary(ImageToByteArray(o as System.Drawing.Image));
  1736. OSD oo;
  1737. if ((oo = OSD.FromObject(o)).Type != OSDType.Unknown)
  1738. return (OSD) oo;
  1739. if (o is IDataTransferable)
  1740. return ((IDataTransferable) o).ToOSD();
  1741. Type[] genericArgs = t.GetGenericArguments();
  1742. if (Util.IsInstanceOfGenericType(typeof (List<>), t))
  1743. {
  1744. OSDArray array = new OSDArray();
  1745. System.Collections.IList collection = (System.Collections.IList) o;
  1746. foreach (object item in collection)
  1747. {
  1748. array.Add(MakeOSD(item, genericArgs[0]));
  1749. }
  1750. return array;
  1751. }
  1752. else if (Util.IsInstanceOfGenericType(typeof (Dictionary<,>), t))
  1753. {
  1754. OSDMap array = new OSDMap();
  1755. System.Collections.IDictionary collection = (System.Collections.IDictionary) o;
  1756. foreach (System.Collections.DictionaryEntry item in collection)
  1757. {
  1758. array.Add(MakeOSD(item.Key, genericArgs[0]), MakeOSD(item.Value, genericArgs[1]));
  1759. }
  1760. return array;
  1761. }
  1762. if (t.BaseType == typeof (Enum))
  1763. return OSD.FromString(o.ToString());
  1764. return null;
  1765. }
  1766. public static byte[] ImageToByteArray(System.Drawing.Image imageIn)
  1767. {
  1768. MemoryStream ms = new MemoryStream();
  1769. imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
  1770. return ms.ToArray();
  1771. }
  1772. public static System.Drawing.Image ByteArrayToImage(byte[] byteArrayIn)
  1773. {
  1774. MemoryStream ms = new MemoryStream(byteArrayIn);
  1775. System.Drawing.Image returnImage = System.Drawing.Image.FromStream(ms);
  1776. return returnImage;
  1777. }
  1778. private static object CreateInstance(Type type)
  1779. {
  1780. if (type == typeof (string))
  1781. return string.Empty;
  1782. else
  1783. return Activator.CreateInstance(type);
  1784. }
  1785. public static object OSDToObject(OSD o)
  1786. {
  1787. return OSDToObject(o, o.GetType());
  1788. }
  1789. public static object OSDToObject(OSD o, Type PossibleArrayType)
  1790. {
  1791. if (o.Type == OSDType.UUID || PossibleArrayType == typeof (UUID))
  1792. return o.AsUUID();
  1793. if (PossibleArrayType == typeof (string) || PossibleArrayType == typeof (OSDString) ||
  1794. PossibleArrayType.BaseType == typeof (Enum))
  1795. {
  1796. if (PossibleArrayType.BaseType == typeof (Enum))
  1797. return Enum.Parse(PossibleArrayType, o.AsString());
  1798. return o.AsString();
  1799. }
  1800. if (o.Type == OSDType.Array && PossibleArrayType == typeof (System.Drawing.Image))
  1801. return ByteArrayToImage(o.AsBinary());
  1802. if (o.Type == OSDType.Integer && PossibleArrayType == typeof (byte))
  1803. return (byte) o.AsInteger();
  1804. if (o.Type == OSDType.Integer || PossibleArrayType == typeof (int))
  1805. return o.AsInteger();
  1806. if (o.Type == OSDType.Binary || PossibleArrayType == typeof (byte[]))
  1807. return o.AsBinary();
  1808. if (o.Type == OSDType.Boolean || PossibleArrayType == typeof (bool))
  1809. return o.AsBoolean();
  1810. if (PossibleArrayType == typeof (Color4))
  1811. return o.AsColor4();
  1812. if (o.Type == OSDType.Date || PossibleArrayType == typeof (DateTime))
  1813. return o.AsDate();
  1814. if (PossibleArrayType == typeof (long))
  1815. return o.AsLong();
  1816. if (PossibleArrayType == typeof (Quaternion))
  1817. return o.AsQuaternion();
  1818. if (PossibleArrayType == typeof (float))
  1819. return (float) o.AsReal();
  1820. if (o.Type == OSDType.Real || PossibleArrayType == typeof (double))
  1821. return o.AsReal();
  1822. if (PossibleArrayType == typeof (uint))
  1823. return o.AsUInteger();
  1824. if (PossibleArrayType == typeof (ulong))
  1825. return o.AsULong();
  1826. if (o.Type == OSDType.URI || PossibleArrayType == typeof (Uri))
  1827. return o.AsUri();
  1828. if (PossibleArrayType == typeof (Vector2))
  1829. return o.AsVector2();
  1830. if (PossibleArrayType == typeof (Vector3))
  1831. return o.AsVector3();
  1832. if (PossibleArrayType == typeof (Vector3d))
  1833. return o.AsVector3d();
  1834. if (PossibleArrayType == typeof (Vector4))
  1835. return o.AsVector4();
  1836. if (PossibleArrayType == typeof (OSDMap))
  1837. return (OSDMap) o;
  1838. if (PossibleArrayType == typeof (OSDArray))
  1839. return (OSDArray) o;
  1840. if (o.Type == OSDType.Array)
  1841. {
  1842. OSDArray array = (OSDArray) o;
  1843. var possArrayType = Activator.CreateInstance(PossibleArrayType);
  1844. IList list = (IList) possArrayType;
  1845. Type t = PossibleArrayType.GetGenericArguments()[0];
  1846. if (t == typeof (UInt32))
  1847. return o.AsUInteger();
  1848. foreach (OSD oo in array)
  1849. {
  1850. list.Add(OSDToObject(oo, t));
  1851. }
  1852. return list;
  1853. }
  1854. var possType = Activator.CreateInstance(PossibleArrayType);
  1855. if (possType is IDataTransferable)
  1856. {
  1857. IDataTransferable data = (IDataTransferable) possType;
  1858. data.FromOSD((OSDMap) o);
  1859. return data;
  1860. }
  1861. else if (o.Type == OSDType.Map)
  1862. {
  1863. OSDMap array = (OSDMap) o;
  1864. var possArrayTypeB = Activator.CreateInstance(PossibleArrayType);
  1865. var list = (IDictionary) possArrayTypeB;
  1866. Type t = PossibleArrayType.GetGenericArguments()[1];
  1867. Type tt = PossibleArrayType.GetGenericArguments()[0];
  1868. foreach (KeyValuePair<string, OSD> oo in array)
  1869. {
  1870. list.Add(OSDToObject(oo.Key, tt), OSDToObject(oo.Value, t));
  1871. }
  1872. return list;
  1873. }
  1874. return null;
  1875. }
  1876. public static List<T> MakeList<T>(T itemOftype)
  1877. {
  1878. List<T> newList = new List<T>();
  1879. return newList;
  1880. }
  1881. public static Dictionary<A, B> MakeDictionary<A, B>(A itemOftypeA, B itemOfTypeB)
  1882. {
  1883. Dictionary<A, B> newList = new Dictionary<A, B>();
  1884. return newList;
  1885. }
  1886. public static void UlongToInts(ulong regionHandle, out int x, out int y)
  1887. {
  1888. uint xx, yy;
  1889. Utils.LongToUInts(regionHandle, out xx, out yy);
  1890. x = (int) xx;
  1891. y = (int) yy;
  1892. }
  1893. public static ulong IntsToUlong(int x, int y)
  1894. {
  1895. return Utils.UIntsToLong((uint) x, (uint) y);
  1896. }
  1897. public static string CombineParams(string[] commandParams, int pos)
  1898. {
  1899. string result = string.Empty;
  1900. for (int i = pos; i < commandParams.Length; i++)
  1901. {
  1902. result += commandParams[i] + " ";
  1903. }
  1904. result = result.Remove(result.Length - 1, 1); //Remove the trailing space
  1905. return result;
  1906. }
  1907. public static string CombineParams(string[] commandParams, int pos, int endPos)
  1908. {
  1909. string result = string.Empty;
  1910. for (int i = pos; i < endPos; i++)
  1911. {
  1912. result += commandParams[i] + " ";
  1913. }
  1914. return result.Substring(0, result.Length - 1);
  1915. }
  1916. public static string BasePathCombine(string p)
  1917. {
  1918. if (p == "")
  1919. return Application.StartupPath;
  1920. return Path.Combine(Application.StartupPath, p);
  1921. }
  1922. public static void GetReaderLock(ReaderWriterLockSlim l)
  1923. {
  1924. int i = 0;
  1925. while (i < 10) //Only try 10 times... 10s is way too much
  1926. {
  1927. try
  1928. {
  1929. l.TryEnterReadLock(100);
  1930. //Got it
  1931. return;
  1932. }
  1933. catch (ApplicationException)
  1934. {
  1935. // The reader lock request timed out. Try again
  1936. }
  1937. }
  1938. throw new ApplicationException("Could not retrieve read lock");
  1939. }
  1940. public static void ReleaseReaderLock(ReaderWriterLockSlim l)
  1941. {
  1942. l.ExitReadLock();
  1943. }
  1944. public static void GetWriterLock(ReaderWriterLockSlim l)
  1945. {
  1946. int i = 0;
  1947. while (i < 10) //Only try 10 times... 10s is way too much
  1948. {
  1949. try
  1950. {
  1951. l.TryEnterWriteLock(100);
  1952. //Got it
  1953. return;
  1954. }
  1955. catch (ApplicationException)
  1956. {
  1957. // The reader lock request timed out. Try again
  1958. }
  1959. }
  1960. throw new ApplicationException("Could not retrieve write lock");
  1961. }
  1962. public static void ReleaseWriterLock(ReaderWriterLockSlim l)
  1963. {
  1964. l.ExitWriteLock();
  1965. }
  1966. public static sbyte CheckMeshType(sbyte p)
  1967. {
  1968. if (p == (sbyte) AssetType.Mesh)
  1969. return (sbyte) AssetType.Texture;
  1970. return p;
  1971. }
  1972. public static bool IsInstanceOfGenericType(Type genericType, object instance)
  1973. {
  1974. Type type = instance.GetType();
  1975. return IsInstanceOfGenericType(genericType, type);
  1976. }
  1977. public static bool IsInstanceOfGenericType(Type genericType, Type type)
  1978. {
  1979. while (type != null)
  1980. {
  1981. if (type.IsGenericType &&
  1982. type.GetGenericTypeDefinition() == genericType)
  1983. {
  1984. return true;
  1985. }
  1986. type = type.BaseType;
  1987. }
  1988. return false;
  1989. }
  1990. // http://social.msdn.microsoft.com/forums/en-US/csharpgeneral/thread/68f7ca38-5cd1-411f-b8d4-e4f7a688bc03
  1991. // By: A Million Lemmings
  1992. public static string ConvertDecString(int dvalue)
  1993. {
  1994. string CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  1995. string retVal = string.Empty;
  1996. double value = Convert.ToDouble(dvalue);
  1997. do
  1998. {
  1999. double remainder = value - (26*Math.Truncate(value/26));
  2000. retVal = retVal + CHARS.Substring((int) remainder, 1);
  2001. value = Math.Truncate(value/26);
  2002. } while (value > 0);
  2003. return retVal;
  2004. }
  2005. }
  2006. public static class StringUtils
  2007. {
  2008. public static string MySqlEscape(this string usString)
  2009. {
  2010. return MySqlEscape(usString, 0);
  2011. }
  2012. /// <summary>
  2013. /// Because Escaping the sql might cause it to go over the max length
  2014. /// DO NOT USE THIS ON JSON STRINGS!!! IT WILL BREAK THE DESERIALIZATION!!!
  2015. /// </summary>
  2016. /// <param name="usString"></param>
  2017. /// <param name="maxLength"></param>
  2018. /// <returns></returns>
  2019. public static string MySqlEscape(this string usString, int maxLength)
  2020. {
  2021. if (usString == null)
  2022. {
  2023. return null;
  2024. }
  2025. // SQL Encoding for MySQL Recommended here:
  2026. // http://au.php.net/manual/en/function.mysql-real-escape-string.php
  2027. // it escapes \r, \n, \x00, \x1a, baskslash, single quotes, and double quotes
  2028. string returnvalue = Regex.Replace(usString, @"[\r\n\x00\x1a\\'""]", @"\$0");
  2029. if ((maxLength != 0) && (returnvalue.Length > maxLength))
  2030. returnvalue = returnvalue.Substring(0, maxLength);
  2031. return returnvalue;
  2032. }
  2033. /// From http://www.c-sharpcorner.com/UploadFile/mahesh/RandomNumber11232005010428AM/RandomNumber.aspx
  2034. /// <summary>
  2035. /// Generates a random string with the given length
  2036. /// </summary>
  2037. /// <param name="size">Size of the string</param>
  2038. /// <param name="lowerCase">If true, generate lowercase string</param>
  2039. /// <returns>Random string</returns>
  2040. public static string RandomString(int size, bool lowerCase)
  2041. {
  2042. string builder = "t";
  2043. int off = lowerCase ? 'a' : 'A';
  2044. int j;
  2045. for (int i = 0; i < size; i++)
  2046. {
  2047. j = Util.RandomClass.Next(25);
  2048. builder += (char) (j + off);
  2049. }
  2050. return builder;
  2051. }
  2052. public static string[] AlphanumericSort(List<string> list)
  2053. {
  2054. string[] nList = list.ToArray();
  2055. Array.Sort(nList, new AlphanumComparatorFast());
  2056. return nList;
  2057. }
  2058. public class AlphanumComparatorFast : IComparer
  2059. {
  2060. public int Compare(object x, object y)
  2061. {
  2062. string s1 = x as string;
  2063. if (s1 == null)
  2064. {
  2065. return 0;
  2066. }
  2067. string s2 = y as string;
  2068. if (s2 == null)
  2069. {
  2070. return 0;
  2071. }
  2072. int len1 = s1.Length;
  2073. int len2 = s2.Length;
  2074. int marker1 = 0;
  2075. int marker2 = 0;
  2076. // Walk through two the strings with two markers.
  2077. while (marker1 < len1 && marker2 < len2)
  2078. {
  2079. char ch1 = s1[marker1];
  2080. char ch2 = s2[marker2];
  2081. // Some buffers we can build up characters in for each chunk.
  2082. char[] space1 = new char[len1];
  2083. int loc1 = 0;
  2084. char[] space2 = new char[len2];
  2085. int loc2 = 0;
  2086. // Walk through all following characters that are digits or
  2087. // characters in BOTH strings starting at the appropriate marker.
  2088. // Collect char arrays.
  2089. do
  2090. {
  2091. space1[loc1++] = ch1;
  2092. marker1++;
  2093. if (marker1 < len1)
  2094. {
  2095. ch1 = s1[marker1];
  2096. }
  2097. else
  2098. {
  2099. break;
  2100. }
  2101. } while (char.IsDigit(ch1) == char.IsDigit(space1[0]));
  2102. do
  2103. {
  2104. space2[loc2++] = ch2;
  2105. marker2++;
  2106. if (marker2 < len2)
  2107. {
  2108. ch2 = s2[marker2];
  2109. }
  2110. else
  2111. {
  2112. break;
  2113. }
  2114. } while (char.IsDigit(ch2) == char.IsDigit(space2[0]));
  2115. // If we have collected numbers, compare them numerically.
  2116. // Otherwise, if we have strings, compare them alphabetically.
  2117. string str1 = new string(space1);
  2118. string str2 = new string(space2);
  2119. int result;
  2120. if (char.IsDigit(space1[0]) && char.IsDigit(space2[0]))
  2121. {
  2122. int thisNumericChunk = int.Parse(str1);
  2123. int thatNumericChunk = int.Parse(str2);
  2124. result = thisNumericChunk.CompareTo(thatNumericChunk);
  2125. }
  2126. else
  2127. {
  2128. result = str1.CompareTo(str2);
  2129. }
  2130. if (result != 0)
  2131. {
  2132. return result;
  2133. }
  2134. }
  2135. return len1 - len2;
  2136. }
  2137. }
  2138. public static List<string> SizeSort(List<string> functionKeys, bool smallestToLargest)
  2139. {
  2140. functionKeys.Sort((a, b) => { return a.Length.CompareTo(b.Length); });
  2141. if (!smallestToLargest)
  2142. functionKeys.Reverse(); //Flip the order then
  2143. return functionKeys;
  2144. }
  2145. }
  2146. public class NetworkUtils
  2147. {
  2148. private static bool m_noInternetConnection;
  2149. private static int m_nextInternetConnectionCheck;
  2150. //private static bool useLocalhostLoopback=false;
  2151. private static readonly ExpiringCache<string, IPAddress> m_dnsCache = new ExpiringCache<string, IPAddress>();
  2152. public static IPEndPoint ResolveEndPoint(string hostName, int port)
  2153. {
  2154. IPEndPoint endpoint = null;
  2155. // Old one defaults to IPv6
  2156. //return new IPEndPoint(Dns.GetHostAddresses(m_externalHostName)[0], m_internalEndPoint.Port);
  2157. IPAddress ia = null;
  2158. // If it is already an IP, don't resolve it - just return directly
  2159. if (IPAddress.TryParse(hostName, out ia))
  2160. {
  2161. endpoint = new IPEndPoint(ia, port);
  2162. return endpoint;
  2163. }
  2164. try
  2165. {
  2166. if (IPAddress.TryParse(hostName.Split(':')[0], out ia))
  2167. {
  2168. endpoint = new IPEndPoint(ia, port);
  2169. return endpoint;
  2170. }
  2171. }
  2172. catch
  2173. {
  2174. }
  2175. // Reset for next check
  2176. ia = null;
  2177. try
  2178. {
  2179. if (CheckInternetConnection())
  2180. {
  2181. foreach (IPAddress Adr in Dns.GetHostAddresses(hostName))
  2182. {
  2183. if (ia == null)
  2184. ia = Adr;
  2185. if (Adr.AddressFamily == AddressFamily.InterNetwork)
  2186. {
  2187. ia = Adr;
  2188. InternetSuccess();
  2189. break;
  2190. }
  2191. }
  2192. }
  2193. }
  2194. catch (SocketException e)
  2195. {
  2196. InternetFailure();
  2197. throw new Exception(
  2198. "Unable to resolve local hostname " + hostName + " innerException of type '" +
  2199. e + "' attached to this exception", e);
  2200. }
  2201. if (ia != null)
  2202. endpoint = new IPEndPoint(ia, port);
  2203. return endpoint;
  2204. }
  2205. public static bool CheckInternetConnection()
  2206. {
  2207. if (m_noInternetConnection)
  2208. {
  2209. if (Util.EnvironmentTickCount() > m_nextInternetConnectionCheck)
  2210. return true; //Try again
  2211. return false;
  2212. }
  2213. return true; //No issues
  2214. }
  2215. public static void InternetSuccess()
  2216. {
  2217. m_noInternetConnection = false;
  2218. }
  2219. public static void InternetFailure()
  2220. {
  2221. m_nextInternetConnectionCheck = Util.EnvironmentTickCountAdd(5*60*1000); /*5 mins*/
  2222. m_noInternetConnection = true;
  2223. }
  2224. /// <summary>
  2225. /// Gets the client IP address
  2226. /// </summary>
  2227. /// <param name="xff"></param>
  2228. /// <returns></returns>
  2229. public static IPEndPoint GetClientIPFromXFF(string xff)
  2230. {
  2231. if (xff == string.Empty)
  2232. return null;
  2233. string[] parts = xff.Split(new[] {','});
  2234. if (parts.Length > 0)
  2235. {
  2236. try
  2237. {
  2238. return new IPEndPoint(IPAddress.Parse(parts[0]), 0);
  2239. }
  2240. catch (Exception e)
  2241. {
  2242. MainConsole.Instance.WarnFormat("[UTIL]: Exception parsing XFF header {0}: {1}", xff, e.Message);
  2243. }
  2244. }
  2245. return null;
  2246. }
  2247. public static string GetCallerIP(Hashtable req)
  2248. {
  2249. if (req.ContainsKey("headers"))
  2250. {
  2251. try
  2252. {
  2253. Hashtable headers = (Hashtable) req["headers"];
  2254. if (headers.ContainsKey("remote_addr") && headers["remote_addr"] != null)
  2255. return headers["remote_addr"].ToString();
  2256. if (headers.ContainsKey("Host") && headers["Host"] != null)
  2257. return headers["Host"].ToString().Split(':')[0];
  2258. }
  2259. catch (Exception e)
  2260. {
  2261. MainConsole.Instance.WarnFormat("[UTIL]: exception in GetCallerIP: {0}", e.Message);
  2262. }
  2263. }
  2264. return string.Empty;
  2265. }
  2266. /// <summary>
  2267. /// Attempts to resolve the loopback issue, but only works if this is run on the same network as the iPAddress
  2268. /// </summary>
  2269. /// <param name="iPAddress"></param>
  2270. /// <param name="clientIP"></param>
  2271. /// <returns></returns>
  2272. public static IPAddress ResolveAddressForClient(IPAddress iPAddress, IPEndPoint clientIP)
  2273. {
  2274. /*if (iPAddress == null)
  2275. return clientIP.Address;
  2276. if (iPAddress.Equals(clientIP.Address))
  2277. {
  2278. if (useLocalhostLoopback)
  2279. return IPAddress.Loopback;
  2280. if (iPAddress == IPAddress.Loopback)
  2281. return iPAddress; //Don't send something else if it is already on loopback
  2282. if (CheckInternetConnection())
  2283. {
  2284. #pragma warning disable 618
  2285. //The 'bad' way, only works for things on the same machine...
  2286. try
  2287. {
  2288. string hostName = Dns.GetHostName();
  2289. IPHostEntry ipEntry = Dns.GetHostByName(hostName);
  2290. #pragma warning restore 618
  2291. IPAddress[] addr = ipEntry.AddressList;
  2292. return addr[0]; //Loopback around! They are on the same connection
  2293. }
  2294. catch
  2295. {
  2296. InternetFailure(); //Something went wrong
  2297. }
  2298. }
  2299. }
  2300. return iPAddress;*/
  2301. return iPAddress;
  2302. }
  2303. public static bool IsLanIP(IPAddress address)
  2304. {
  2305. var interfaces = NetworkInterface.GetAllNetworkInterfaces();
  2306. foreach (var iface in interfaces)
  2307. {
  2308. var properties = iface.GetIPProperties();
  2309. foreach (var ifAddr in properties.UnicastAddresses)
  2310. {
  2311. if (ifAddr.IPv4Mask != null &&
  2312. ifAddr.Address.AddressFamily == AddressFamily.InterNetwork &&
  2313. CheckMask(ifAddr.Address, ifAddr.IPv4Mask, address))
  2314. return true;
  2315. }
  2316. }
  2317. return false;
  2318. }
  2319. private static bool CheckMask(IPAddress address, IPAddress mask, IPAddress target)
  2320. {
  2321. if (mask == null)
  2322. return false;
  2323. var ba = address.GetAddressBytes();
  2324. var bm = mask.GetAddressBytes();
  2325. var bb = target.GetAddressBytes();
  2326. if (ba.Length != bm.Length || bm.Length != bb.Length)
  2327. return false;
  2328. for (var i = 0; i < ba.Length; i++)
  2329. {
  2330. int m = bm[i];
  2331. int a = ba[i] & m;
  2332. int b = bb[i] & m;
  2333. if (a != b)
  2334. return false;
  2335. }
  2336. return true;
  2337. }
  2338. public static IPEndPoint ResolveAddressForClient(IPEndPoint iPAddress, IPEndPoint clientIP)
  2339. {
  2340. iPAddress.Address = ResolveAddressForClient(iPAddress.Address, clientIP);
  2341. return iPAddress;
  2342. }
  2343. /// <summary>
  2344. /// Returns a IP address from a specified DNS, favouring IPv4 addresses.
  2345. /// </summary>
  2346. /// <param name="dnsAddress">DNS Hostname</param>
  2347. /// <returns>An IP address, or null</returns>
  2348. public static IPAddress GetHostFromDNS(string dnsAddress)
  2349. {
  2350. dnsAddress = dnsAddress.Replace("http://", "").Replace("https://", "");
  2351. if (dnsAddress.EndsWith("/"))
  2352. dnsAddress = dnsAddress.Remove(dnsAddress.Length - 1);
  2353. if (dnsAddress.Contains(":"))
  2354. dnsAddress = dnsAddress.Split(':')[0];
  2355. IPAddress ipa;
  2356. if (m_dnsCache.TryGetValue(dnsAddress, out ipa))
  2357. return ipa;
  2358. // Is it already a valid IP? No need to look it up.
  2359. if (IPAddress.TryParse(dnsAddress, out ipa))
  2360. {
  2361. m_dnsCache.Add(dnsAddress, ipa, 30*60 /*30mins*/);
  2362. return ipa;
  2363. }
  2364. try
  2365. {
  2366. if (IPAddress.TryParse(dnsAddress.Split(':')[0], out ipa))
  2367. {
  2368. m_dnsCache.Add(dnsAddress, ipa, 30*60 /*30mins*/);
  2369. return ipa;
  2370. }
  2371. }
  2372. catch
  2373. {
  2374. }
  2375. IPAddress[] hosts = null;
  2376. // Not an IP, lookup required
  2377. try
  2378. {
  2379. if (CheckInternetConnection())
  2380. {
  2381. hosts = Dns.GetHostEntry(dnsAddress).AddressList;
  2382. if (hosts != null)
  2383. InternetSuccess();
  2384. else
  2385. InternetFailure();
  2386. }
  2387. }
  2388. catch (Exception e)
  2389. {
  2390. MainConsole.Instance.WarnFormat("[UTIL]: An error occurred while resolving host name {0}, {1}",
  2391. dnsAddress, e);
  2392. InternetFailure();
  2393. // Still going to throw the exception on for now, since this was what was happening in the first place
  2394. throw e;
  2395. }
  2396. if (hosts != null)
  2397. {
  2398. foreach (IPAddress host in hosts.Where(host => host.AddressFamily == AddressFamily.InterNetwork))
  2399. {
  2400. m_dnsCache.Add(dnsAddress, host, 30*60 /*30mins*/);
  2401. return host;
  2402. }
  2403. if (hosts.Length > 0)
  2404. {
  2405. m_dnsCache.Add(dnsAddress, hosts[0], 30*60 /*30mins*/);
  2406. return hosts[0];
  2407. }
  2408. }
  2409. return null;
  2410. }
  2411. public static Uri GetURI(string protocol, string hostname, int port, string path)
  2412. {
  2413. return new UriBuilder(protocol, hostname, port, path).Uri;
  2414. }
  2415. /// <summary>
  2416. /// Gets a list of all local system IP addresses
  2417. /// </summary>
  2418. /// <returns></returns>
  2419. public static IPAddress[] GetLocalHosts()
  2420. {
  2421. return Dns.GetHostAddresses(Dns.GetHostName());
  2422. }
  2423. public static IPAddress GetLocalHost()
  2424. {
  2425. IPAddress[] iplist = GetLocalHosts();
  2426. if (iplist.Length == 0) // No accessible external interfaces
  2427. {
  2428. if (CheckInternetConnection())
  2429. {
  2430. try
  2431. {
  2432. IPAddress[] loopback = Dns.GetHostAddresses("localhost");
  2433. IPAddress localhost = loopback[0];
  2434. InternetSuccess();
  2435. return localhost;
  2436. }
  2437. catch
  2438. {
  2439. InternetFailure();
  2440. }
  2441. }
  2442. }
  2443. foreach (
  2444. IPAddress host in
  2445. iplist.Where(host => !IPAddress.IsLoopback(host) && host.AddressFamily == AddressFamily.InterNetwork)
  2446. )
  2447. {
  2448. return host;
  2449. }
  2450. if (iplist.Length > 0)
  2451. {
  2452. foreach (IPAddress host in iplist.Where(host => host.AddressFamily == AddressFamily.InterNetwork))
  2453. {
  2454. return host;
  2455. }
  2456. // Well all else failed...
  2457. return iplist[0];
  2458. }
  2459. return null;
  2460. }
  2461. #region Nested type: IPAddressRange
  2462. public class IPAddressRange
  2463. {
  2464. private readonly AddressFamily addressFamily;
  2465. private readonly byte[] lowerBytes;
  2466. private readonly byte[] upperBytes;
  2467. public IPAddressRange(IPAddress lower, IPAddress upper)
  2468. {
  2469. // Assert that lower.AddressFamily == upper.AddressFamily
  2470. this.addressFamily = lower.AddressFamily;
  2471. this.lowerBytes = lower.GetAddressBytes();
  2472. this.upperBytes = upper.GetAddressBytes();
  2473. }
  2474. public bool IsInRange(IPAddress address)
  2475. {
  2476. if (address.AddressFamily != addressFamily)
  2477. {
  2478. return false;
  2479. }
  2480. byte[] addressBytes = address.GetAddressBytes();
  2481. bool lowerBoundary = true, upperBoundary = true;
  2482. for (int i = 0;
  2483. i < this.lowerBytes.Length &&
  2484. (lowerBoundary || upperBoundary);
  2485. i++)
  2486. {
  2487. if ((lowerBoundary && addressBytes[i] < lowerBytes[i]) ||
  2488. (upperBoundary && addressBytes[i] > upperBytes[i]))
  2489. {
  2490. return false;
  2491. }
  2492. lowerBoundary &= (addressBytes[i] == lowerBytes[i]);
  2493. upperBoundary &= (addressBytes[i] == upperBytes[i]);
  2494. }
  2495. return true;
  2496. }
  2497. }
  2498. #endregion
  2499. }
  2500. public static class Extensions
  2501. {
  2502. public static List<T> ConvertAll<T>(this OSDArray array, Converter<OSD, T> converter)
  2503. {
  2504. List<OSD> list = new List<OSD>();
  2505. foreach (OSD o in array)
  2506. {
  2507. list.Add(o);
  2508. }
  2509. return list.ConvertAll<T>(converter);
  2510. }
  2511. public static Dictionary<string, T> ConvertMap<T>(this OSDMap array, Converter<OSD, T> converter)
  2512. {
  2513. Dictionary<string, T> map = new Dictionary<string, T>();
  2514. foreach (KeyValuePair<string, OSD> o in array)
  2515. {
  2516. map.Add(o.Key, converter(o.Value));
  2517. }
  2518. return map;
  2519. }
  2520. public static OSDArray ToOSDArray<T>(this List<T> array)
  2521. {
  2522. OSDArray list = new OSDArray();
  2523. foreach (object o in array)
  2524. {
  2525. OSD osd = Util.MakeOSD(o, o.GetType());
  2526. if (osd != null)
  2527. list.Add(osd);
  2528. }
  2529. return list;
  2530. }
  2531. public static OSDMap ToOSDMap<A, B>(this Dictionary<A, B> array)
  2532. {
  2533. OSDMap list = new OSDMap();
  2534. foreach (KeyValuePair<A, B> o in array)
  2535. {
  2536. OSD osd = Util.MakeOSD(o.Value, o.Value.GetType());
  2537. if (osd != null)
  2538. list.Add(o.Key.ToString(), osd);
  2539. }
  2540. return list;
  2541. }
  2542. /// <summary>
  2543. /// Comes from http://www.codeproject.com/script/Articles/ViewDownloads.aspx?aid=14593
  2544. /// </summary>
  2545. /// <param name="method"></param>
  2546. /// <param name="parameters"></param>
  2547. /// <param name="invokeClass"></param>
  2548. /// <param name="invokeParameters"></param>
  2549. /// <returns></returns>
  2550. public static object FastInvoke(this MethodInfo method, ParameterInfo[] parameters, object invokeClass,
  2551. object[] invokeParameters)
  2552. {
  2553. DynamicMethod dynamicMethod = new DynamicMethod(string.Empty,
  2554. typeof (object), new Type[]
  2555. {
  2556. typeof (object),
  2557. typeof (object[])
  2558. },
  2559. method.DeclaringType.Module);
  2560. ILGenerator il = dynamicMethod.GetILGenerator();
  2561. Type[] paramTypes = new Type[parameters.Length];
  2562. for (int i = 0; i < paramTypes.Length; i++)
  2563. {
  2564. paramTypes[i] = parameters[i].ParameterType;
  2565. }
  2566. LocalBuilder[] locals = new LocalBuilder[paramTypes.Length];
  2567. for (int i = 0; i < paramTypes.Length; i++)
  2568. {
  2569. locals[i] = il.DeclareLocal(paramTypes[i]);
  2570. }
  2571. for (int i = 0; i < paramTypes.Length; i++)
  2572. {
  2573. il.Emit(OpCodes.Ldarg_1);
  2574. EmitFastInt(il, i);
  2575. il.Emit(OpCodes.Ldelem_Ref);
  2576. EmitCastToReference(il, paramTypes[i]);
  2577. il.Emit(OpCodes.Stloc, locals[i]);
  2578. }
  2579. il.Emit(OpCodes.Ldarg_0);
  2580. for (int i = 0; i < paramTypes.Length; i++)
  2581. {
  2582. il.Emit(OpCodes.Ldloc, locals[i]);
  2583. }
  2584. il.EmitCall(OpCodes.Call, method, null);
  2585. if (method.ReturnType == typeof (void))
  2586. il.Emit(OpCodes.Ldnull);
  2587. else
  2588. EmitBoxIfNeeded(il, method.ReturnType);
  2589. il.Emit(OpCodes.Ret);
  2590. return dynamicMethod.Invoke(null, new object[2] {invokeClass, invokeParameters});
  2591. /*FastInvokeHandler invoder =
  2592. (FastInvokeHandler)dynamicMethod.CreateDelegate(
  2593. typeof(FastInvokeHandler));
  2594. return invoder;*/
  2595. }
  2596. private static void EmitCastToReference(ILGenerator il, System.Type type)
  2597. {
  2598. if (type.IsValueType)
  2599. {
  2600. il.Emit(OpCodes.Unbox_Any, type);
  2601. }
  2602. else
  2603. {
  2604. il.Emit(OpCodes.Castclass, type);
  2605. }
  2606. }
  2607. private static void EmitBoxIfNeeded(ILGenerator il, System.Type type)
  2608. {
  2609. if (type.IsValueType)
  2610. {
  2611. il.Emit(OpCodes.Box, type);
  2612. }
  2613. }
  2614. private static void EmitFastInt(ILGenerator il, int value)
  2615. {
  2616. switch (value)
  2617. {
  2618. case -1:
  2619. il.Emit(OpCodes.Ldc_I4_M1);
  2620. return;
  2621. case 0:
  2622. il.Emit(OpCodes.Ldc_I4_0);
  2623. return;
  2624. case 1:
  2625. il.Emit(OpCodes.Ldc_I4_1);
  2626. return;
  2627. case 2:
  2628. il.Emit(OpCodes.Ldc_I4_2);
  2629. return;
  2630. case 3:
  2631. il.Emit(OpCodes.Ldc_I4_3);
  2632. return;
  2633. case 4:
  2634. il.Emit(OpCodes.Ldc_I4_4);
  2635. return;
  2636. case 5:
  2637. il.Emit(OpCodes.Ldc_I4_5);
  2638. return;
  2639. case 6:
  2640. il.Emit(OpCodes.Ldc_I4_6);
  2641. return;
  2642. case 7:
  2643. il.Emit(OpCodes.Ldc_I4_7);
  2644. return;
  2645. case 8:
  2646. il.Emit(OpCodes.Ldc_I4_8);
  2647. return;
  2648. }
  2649. if (value > -129 && value < 128)
  2650. {
  2651. il.Emit(OpCodes.Ldc_I4_S, (SByte) value);
  2652. }
  2653. else
  2654. {
  2655. il.Emit(OpCodes.Ldc_I4, value);
  2656. }
  2657. }
  2658. }
  2659. public class AllScopeIDImpl : IDataTransferable
  2660. {
  2661. public UUID ScopeID = UUID.Zero;
  2662. public List<UUID> AllScopeIDs
  2663. {
  2664. get
  2665. {
  2666. List<UUID> ids = new List<UUID>();
  2667. if (!ids.Contains(ScopeID))
  2668. ids.Add(ScopeID);
  2669. return ids;
  2670. }
  2671. set { }
  2672. }
  2673. public static List<T> CheckScopeIDs<T>(List<UUID> scopeIDs, List<T> list) where T : AllScopeIDImpl
  2674. {
  2675. if (scopeIDs == null || scopeIDs.Count == 0 || scopeIDs.Contains(UUID.Zero))
  2676. return list;
  2677. return
  2678. new List<T>(
  2679. list.Where(r => scopeIDs.Any(s => r.AllScopeIDs.Contains(s)) || r.AllScopeIDs.Contains(UUID.Zero)));
  2680. }
  2681. public static T CheckScopeIDs<T>(List<UUID> scopeIDs, T l) where T : AllScopeIDImpl
  2682. {
  2683. if (l == null || scopeIDs == null || scopeIDs.Count == 0 || scopeIDs.Contains(UUID.Zero))
  2684. return l;
  2685. return (scopeIDs.Any(s => l.AllScopeIDs.Contains(s)) || l.AllScopeIDs.Contains(UUID.Zero)) ? l : null;
  2686. }
  2687. }
  2688. }