mirror of
https://github.com/opensim/opensim.git
synced 2026-05-21 07:45:41 +08:00
* This patch aims to introduce look at direction persistence between logins. It won't be active until the second part of the patch is committed in about two weeks time. At this point, region servers that haven't upgraded past this revision may run into problems * This checkin upgrades the user database. As always, we recommend you have backups in case something goes wrong. * Many thanks to tyre for this patch.
765 lines
25 KiB
C#
765 lines
25 KiB
C#
/*
|
|
* Copyright (c) Contributors, http://opensimulator.org/
|
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* * Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* * Neither the name of the OpenSim Project nor the
|
|
* names of its contributors may be used to endorse or promote products
|
|
* derived from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
using System;
|
|
using System.Data;
|
|
using System.IO;
|
|
using System.IO.Compression;
|
|
using System.Net;
|
|
using System.Net.Sockets;
|
|
using System.Reflection;
|
|
using System.Runtime.Serialization;
|
|
using System.Runtime.Serialization.Formatters.Binary;
|
|
using System.Security.Cryptography;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
using System.Xml;
|
|
using OpenMetaverse;
|
|
using log4net;
|
|
using Nini.Config;
|
|
using Nwc.XmlRpc;
|
|
|
|
namespace OpenSim.Framework
|
|
{
|
|
/// <summary>
|
|
/// Miscellaneous utility functions
|
|
/// </summary>
|
|
public class Util
|
|
{
|
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
|
|
|
private static uint nextXferID = 5000;
|
|
private static Random randomClass = new Random();
|
|
// Get a list of invalid file characters (OS dependent)
|
|
private static string regexInvalidFileChars = "[" + new String(Path.GetInvalidFileNameChars()) + "]";
|
|
private static string regexInvalidPathChars = "[" + new String(Path.GetInvalidPathChars()) + "]";
|
|
private static object XferLock = new object();
|
|
|
|
#region Vector Equations
|
|
|
|
/// <summary>
|
|
/// Get the distance between two 3d vectors
|
|
/// </summary>
|
|
/// <param name="a">A 3d vector</param>
|
|
/// <param name="b">A 3d vector</param>
|
|
/// <returns>The distance between the two vectors</returns>
|
|
public static double GetDistanceTo(Vector3 a, Vector3 b)
|
|
{
|
|
float dx = a.X - b.X;
|
|
float dy = a.Y - b.Y;
|
|
float dz = a.Z - b.Z;
|
|
return Math.Sqrt(dx * dx + dy * dy + dz * dz);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get the magnitude of a 3d vector
|
|
/// </summary>
|
|
/// <param name="a">A 3d vector</param>
|
|
/// <returns>The magnitude of the vector</returns>
|
|
public static double GetMagnitude(Vector3 a)
|
|
{
|
|
return Math.Sqrt((a.X * a.X) + (a.Y * a.Y) + (a.Z * a.Z));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get a normalized form of a 3d vector
|
|
/// </summary>
|
|
/// <param name="a">A 3d vector</param>
|
|
/// <returns>A new vector which is normalized form of the vector</returns>
|
|
/// <remarks>The vector paramater cannot be <0,0,0></remarks>
|
|
public static Vector3 GetNormalizedVector(Vector3 a)
|
|
{
|
|
if (IsZeroVector(a))
|
|
throw new ArgumentException("Vector paramater cannot be a zero vector.");
|
|
|
|
float Mag = (float) GetMagnitude(a);
|
|
return new Vector3(a.X / Mag, a.Y / Mag, a.Z / Mag);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns if a vector is a zero vector (has all zero components)
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public static bool IsZeroVector(Vector3 v)
|
|
{
|
|
if (v.X == 0 && v.Y == 0 && v.Z == 0)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
# endregion
|
|
|
|
public Util()
|
|
{
|
|
}
|
|
|
|
public static Random RandomClass
|
|
{
|
|
get { return randomClass; }
|
|
}
|
|
|
|
public static ulong UIntsToLong(uint X, uint Y)
|
|
{
|
|
return Helpers.UIntsToLong(X, Y);
|
|
}
|
|
|
|
public static T Clamp<T>(T x, T min, T max)
|
|
where T : System.IComparable<T>
|
|
{
|
|
return x.CompareTo(max) > 0 ? max :
|
|
x.CompareTo(min) < 0 ? min :
|
|
x;
|
|
}
|
|
|
|
public static uint GetNextXferID()
|
|
{
|
|
uint id = 0;
|
|
lock (XferLock)
|
|
{
|
|
id = nextXferID;
|
|
nextXferID++;
|
|
}
|
|
return id;
|
|
}
|
|
|
|
public static string GetFileName(string file)
|
|
{
|
|
// Return just the filename on UNIX platforms
|
|
// TODO: this should be customisable with a prefix, but that's something to do later.
|
|
if (Environment.OSVersion.Platform == PlatformID.Unix)
|
|
{
|
|
return file;
|
|
}
|
|
|
|
// Return %APPDATA%/OpenSim/file for 2K/XP/NT/2K3/VISTA
|
|
// TODO: Switch this to System.Enviroment.SpecialFolders.ApplicationData
|
|
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
|
|
{
|
|
if (!Directory.Exists("%APPDATA%\\OpenSim\\"))
|
|
{
|
|
Directory.CreateDirectory("%APPDATA%\\OpenSim");
|
|
}
|
|
|
|
return "%APPDATA%\\OpenSim\\" + file;
|
|
}
|
|
|
|
// Catch all - covers older windows versions
|
|
// (but those probably wont work anyway)
|
|
return file;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Debug utility function to convert unbroken strings of XML into something human readable for occasional debugging purposes.
|
|
///
|
|
/// Please don't delete me even if I appear currently unused!
|
|
/// </summary>
|
|
/// <param name="rawXml"></param>
|
|
/// <returns></returns>
|
|
public static string GetFormattedXml(string rawXml)
|
|
{
|
|
XmlDocument xd = new XmlDocument();
|
|
xd.LoadXml(rawXml);
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
StringWriter sw = new StringWriter(sb);
|
|
|
|
XmlTextWriter xtw = new XmlTextWriter(sw);
|
|
xtw.Formatting = Formatting.Indented;
|
|
|
|
try
|
|
{
|
|
xd.WriteTo(xtw);
|
|
}
|
|
finally
|
|
{
|
|
xtw.Close();
|
|
}
|
|
|
|
return sb.ToString();
|
|
}
|
|
|
|
public static bool IsEnvironmentSupported(ref string reason)
|
|
{
|
|
// Must have .NET 2.0 (Generics / libsl)
|
|
if (Environment.Version.Major < 2)
|
|
{
|
|
reason = ".NET 1.0/1.1 lacks components that is used by OpenSim";
|
|
return false;
|
|
}
|
|
|
|
// Windows 95/98/ME are unsupported
|
|
if (Environment.OSVersion.Platform == PlatformID.Win32Windows &&
|
|
Environment.OSVersion.Platform != PlatformID.Win32NT)
|
|
{
|
|
reason = "Windows 95/98/ME will not run OpenSim";
|
|
return false;
|
|
}
|
|
|
|
// Windows 2000 / Pre-SP2 XP
|
|
if (Environment.OSVersion.Version.Major == 5 &&
|
|
Environment.OSVersion.Version.Minor == 0)
|
|
{
|
|
reason = "Please update to Windows XP Service Pack 2 or Server2003";
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public static int UnixTimeSinceEpoch()
|
|
{
|
|
return ToUnixTime(DateTime.UtcNow);
|
|
}
|
|
|
|
public static int ToUnixTime(DateTime stamp)
|
|
{
|
|
TimeSpan t = (stamp.ToUniversalTime() - Convert.ToDateTime("1/1/1970 8:00:00 AM"));
|
|
return (int) t.TotalSeconds;
|
|
}
|
|
|
|
public static DateTime ToDateTime(ulong seconds)
|
|
{
|
|
DateTime epoch = Convert.ToDateTime("1/1/1970 8:00:00 AM");
|
|
return epoch.AddSeconds(seconds);
|
|
}
|
|
|
|
public static DateTime ToDateTime(int seconds)
|
|
{
|
|
DateTime epoch = Convert.ToDateTime("1/1/1970 8:00:00 AM");
|
|
return epoch.AddSeconds(seconds);
|
|
}
|
|
|
|
public static string Md5Hash(string pass)
|
|
{
|
|
MD5 md5 = MD5CryptoServiceProvider.Create();
|
|
byte[] dataMd5 = md5.ComputeHash(Encoding.Default.GetBytes(pass));
|
|
StringBuilder sb = new StringBuilder();
|
|
for (int i = 0; i < dataMd5.Length; i++)
|
|
sb.AppendFormat("{0:x2}", dataMd5[i]);
|
|
return sb.ToString();
|
|
}
|
|
|
|
public static string GetRandomCapsPath()
|
|
{
|
|
UUID caps = UUID.Random();
|
|
string capsPath = caps.ToString();
|
|
capsPath = capsPath.Remove(capsPath.Length - 4, 4);
|
|
return capsPath;
|
|
}
|
|
|
|
public static int fast_distance2d(int x, int y)
|
|
{
|
|
x = Math.Abs(x);
|
|
y = Math.Abs(y);
|
|
|
|
int min = Math.Min(x, y);
|
|
|
|
return (x + y - (min >> 1) - (min >> 2) + (min >> 4));
|
|
}
|
|
|
|
public static string FieldToString(byte[] bytes)
|
|
{
|
|
return FieldToString(bytes, String.Empty);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert a variable length field (byte array) to a string, with a
|
|
/// field name prepended to each line of the output
|
|
/// </summary>
|
|
/// <remarks>If the byte array has unprintable characters in it, a
|
|
/// hex dump will be put in the string instead</remarks>
|
|
/// <param name="bytes">The byte array to convert to a string</param>
|
|
/// <param name="fieldName">A field name to prepend to each line of output</param>
|
|
/// <returns>An ASCII string or a string containing a hex dump, minus
|
|
/// the null terminator</returns>
|
|
public static string FieldToString(byte[] bytes, string fieldName)
|
|
{
|
|
// Check for a common case
|
|
if (bytes.Length == 0) return String.Empty;
|
|
|
|
StringBuilder output = new StringBuilder();
|
|
bool printable = true;
|
|
|
|
for (int i = 0; i < bytes.Length; ++i)
|
|
{
|
|
// Check if there are any unprintable characters in the array
|
|
if ((bytes[i] < 0x20 || bytes[i] > 0x7E) && bytes[i] != 0x09
|
|
&& bytes[i] != 0x0D && bytes[i] != 0x0A && bytes[i] != 0x00)
|
|
{
|
|
printable = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (printable)
|
|
{
|
|
if (fieldName.Length > 0)
|
|
{
|
|
output.Append(fieldName);
|
|
output.Append(": ");
|
|
}
|
|
|
|
output.Append(CleanString(UTF8Encoding.UTF8.GetString(bytes, 0, bytes.Length - 1)));
|
|
}
|
|
else
|
|
{
|
|
for (int i = 0; i < bytes.Length; i += 16)
|
|
{
|
|
if (i != 0)
|
|
output.Append(Environment.NewLine);
|
|
if (fieldName.Length > 0)
|
|
{
|
|
output.Append(fieldName);
|
|
output.Append(": ");
|
|
}
|
|
|
|
for (int j = 0; j < 16; j++)
|
|
{
|
|
if ((i + j) < bytes.Length)
|
|
output.Append(String.Format("{0:X2} ", bytes[i + j]));
|
|
else
|
|
output.Append(" ");
|
|
}
|
|
|
|
for (int j = 0; j < 16 && (i + j) < bytes.Length; j++)
|
|
{
|
|
if (bytes[i + j] >= 0x20 && bytes[i + j] < 0x7E)
|
|
output.Append((char) bytes[i + j]);
|
|
else
|
|
output.Append(".");
|
|
}
|
|
}
|
|
}
|
|
|
|
return output.ToString();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts a URL to a IPAddress
|
|
/// </summary>
|
|
/// <param name="url">URL Standard Format</param>
|
|
/// <returns>A resolved IP Address</returns>
|
|
public static IPAddress GetHostFromURL(string url)
|
|
{
|
|
return GetHostFromDNS(url.Split(new char[] {'/', ':'})[3]);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns a IP address from a specified DNS, favouring IPv4 addresses.
|
|
/// </summary>
|
|
/// <param name="dnsAddress">DNS Hostname</param>
|
|
/// <returns>An IP address, or null</returns>
|
|
public static IPAddress GetHostFromDNS(string dnsAddress)
|
|
{
|
|
// Is it already a valid IP? No need to look it up.
|
|
IPAddress ipa;
|
|
if (IPAddress.TryParse(dnsAddress, out ipa))
|
|
return ipa;
|
|
|
|
IPAddress[] hosts = null;
|
|
|
|
// Not an IP, lookup required
|
|
try
|
|
{
|
|
hosts = Dns.GetHostEntry(dnsAddress).AddressList;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
m_log.ErrorFormat("[UTIL]: An error occurred while resolving {0}, {1}", dnsAddress, e);
|
|
|
|
// Still going to throw the exception on for now, since this was what was happening in the first place
|
|
throw e;
|
|
}
|
|
|
|
foreach (IPAddress host in hosts)
|
|
{
|
|
if (host.AddressFamily == AddressFamily.InterNetwork)
|
|
{
|
|
return host;
|
|
}
|
|
}
|
|
|
|
if (hosts.Length > 0)
|
|
return hosts[0];
|
|
|
|
return null;
|
|
}
|
|
|
|
public static IPAddress GetLocalHost()
|
|
{
|
|
string dnsAddress = "localhost";
|
|
|
|
IPAddress[] hosts = Dns.GetHostEntry(dnsAddress).AddressList;
|
|
|
|
foreach (IPAddress host in hosts)
|
|
{
|
|
if (!IPAddress.IsLoopback(host) && host.AddressFamily == AddressFamily.InterNetwork)
|
|
{
|
|
return host;
|
|
}
|
|
}
|
|
|
|
if (hosts.Length > 0)
|
|
return hosts[0];
|
|
|
|
return null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Removes all invalid path chars (OS dependent)
|
|
/// </summary>
|
|
/// <param name="path">path</param>
|
|
/// <returns>safe path</returns>
|
|
public static string safePath(string path)
|
|
{
|
|
return Regex.Replace(path, @regexInvalidPathChars, string.Empty);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Removes all invalid filename chars (OS dependent)
|
|
/// </summary>
|
|
/// <param name="path">filename</param>
|
|
/// <returns>safe filename</returns>
|
|
public static string safeFileName(string filename)
|
|
{
|
|
return Regex.Replace(filename, @regexInvalidFileChars, string.Empty);
|
|
;
|
|
}
|
|
|
|
//
|
|
// directory locations
|
|
//
|
|
|
|
public static string homeDir()
|
|
{
|
|
string temp;
|
|
// string personal=(Environment.GetFolderPath(Environment.SpecialFolder.Personal));
|
|
// temp = Path.Combine(personal,".OpenSim");
|
|
temp = ".";
|
|
return temp;
|
|
}
|
|
|
|
public static string assetsDir()
|
|
{
|
|
return Path.Combine(configDir(), "assets");
|
|
}
|
|
|
|
public static string inventoryDir()
|
|
{
|
|
return Path.Combine(configDir(), "inventory");
|
|
}
|
|
|
|
public static string configDir()
|
|
{
|
|
return ".";
|
|
}
|
|
|
|
public static string dataDir()
|
|
{
|
|
return ".";
|
|
}
|
|
|
|
public static string logDir()
|
|
{
|
|
return ".";
|
|
}
|
|
|
|
// Nini (config) related Methods
|
|
public static IConfigSource ConvertDataRowToXMLConfig(DataRow row, string fileName)
|
|
{
|
|
if (!File.Exists(fileName))
|
|
{
|
|
//create new file
|
|
}
|
|
XmlConfigSource config = new XmlConfigSource(fileName);
|
|
AddDataRowToConfig(config, row);
|
|
config.Save();
|
|
|
|
return config;
|
|
}
|
|
|
|
public static void AddDataRowToConfig(IConfigSource config, DataRow row)
|
|
{
|
|
config.Configs.Add((string) row[0]);
|
|
for (int i = 0; i < row.Table.Columns.Count; i++)
|
|
{
|
|
config.Configs[(string) row[0]].Set(row.Table.Columns[i].ColumnName, row[i]);
|
|
}
|
|
}
|
|
|
|
public static float Clip(float x, float min, float max)
|
|
{
|
|
return Math.Min(Math.Max(x, min), max);
|
|
}
|
|
|
|
public static int Clip(int x, int min, int max)
|
|
{
|
|
return Math.Min(Math.Max(x, min), max);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert an UUID to a raw uuid string. Right now this is a string without hyphens.
|
|
/// </summary>
|
|
/// <param name="UUID"></param>
|
|
/// <returns></returns>
|
|
public static String ToRawUuidString(UUID UUID)
|
|
{
|
|
return UUID.Guid.ToString("n");
|
|
}
|
|
|
|
public static string CleanString(string input)
|
|
{
|
|
if (input.Length == 0)
|
|
return input;
|
|
|
|
int clip = input.Length;
|
|
|
|
// Test for ++ string terminator
|
|
int pos = input.IndexOf("\0");
|
|
if (pos != -1 && pos < clip)
|
|
clip = pos;
|
|
|
|
// Test for CR
|
|
pos = input.IndexOf("\r");
|
|
if (pos != -1 && pos < clip)
|
|
clip = pos;
|
|
|
|
// Test for LF
|
|
pos = input.IndexOf("\n");
|
|
if (pos != -1 && pos < clip)
|
|
clip = pos;
|
|
|
|
// Truncate string before first end-of-line character found
|
|
return input.Substring(0, clip);
|
|
}
|
|
|
|
/// <summary>
|
|
/// returns the contents of /etc/issue on Unix Systems
|
|
/// Use this for where it's absolutely necessary to implement platform specific stuff
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public static string ReadEtcIssue()
|
|
{
|
|
try
|
|
{
|
|
StreamReader sr = new StreamReader("/etc/issue.net");
|
|
string issue = sr.ReadToEnd();
|
|
sr.Close();
|
|
return issue;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
return "";
|
|
}
|
|
}
|
|
|
|
public static void SerializeToFile(string filename, Object obj)
|
|
{
|
|
IFormatter formatter = new BinaryFormatter();
|
|
Stream stream = null;
|
|
|
|
try
|
|
{
|
|
stream = new FileStream(
|
|
filename, FileMode.Create,
|
|
FileAccess.Write, FileShare.None);
|
|
|
|
formatter.Serialize(stream, obj);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
System.Console.WriteLine(e.Message);
|
|
System.Console.WriteLine(e.StackTrace);
|
|
}
|
|
finally
|
|
{
|
|
if (stream != null)
|
|
{
|
|
stream.Close();
|
|
}
|
|
}
|
|
}
|
|
|
|
public static Object DeserializeFromFile(string filename)
|
|
{
|
|
IFormatter formatter = new BinaryFormatter();
|
|
Stream stream = null;
|
|
Object ret = null;
|
|
|
|
try
|
|
{
|
|
stream = new FileStream(
|
|
filename, FileMode.Open,
|
|
FileAccess.Read, FileShare.None);
|
|
|
|
ret = formatter.Deserialize(stream);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
System.Console.WriteLine(e.Message);
|
|
System.Console.WriteLine(e.StackTrace);
|
|
}
|
|
finally
|
|
{
|
|
if (stream != null)
|
|
{
|
|
stream.Close();
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
public static string Compress(string text)
|
|
{
|
|
byte[] buffer = Encoding.UTF8.GetBytes(text);
|
|
MemoryStream memory = new MemoryStream();
|
|
using (GZipStream compressor = new GZipStream(memory, CompressionMode.Compress, true))
|
|
{
|
|
compressor.Write(buffer, 0, buffer.Length);
|
|
}
|
|
|
|
memory.Position = 0;
|
|
// MemoryStream outStream = new MemoryStream();
|
|
|
|
byte[] compressed = new byte[memory.Length];
|
|
memory.Read(compressed, 0, compressed.Length);
|
|
|
|
byte[] compressedBuffer = new byte[compressed.Length + 4];
|
|
System.Buffer.BlockCopy(compressed, 0, compressedBuffer, 4, compressed.Length);
|
|
System.Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, compressedBuffer, 0, 4);
|
|
return Convert.ToBase64String(compressedBuffer);
|
|
}
|
|
|
|
public static string Decompress(string compressedText)
|
|
{
|
|
byte[] compressedBuffer = Convert.FromBase64String(compressedText);
|
|
using (MemoryStream memory = new MemoryStream())
|
|
{
|
|
int msgLength = BitConverter.ToInt32(compressedBuffer, 0);
|
|
memory.Write(compressedBuffer, 4, compressedBuffer.Length - 4);
|
|
|
|
byte[] buffer = new byte[msgLength];
|
|
|
|
memory.Position = 0;
|
|
using (GZipStream decompressor = new GZipStream(memory, CompressionMode.Decompress))
|
|
{
|
|
decompressor.Read(buffer, 0, buffer.Length);
|
|
}
|
|
|
|
return Encoding.UTF8.GetString(buffer);
|
|
}
|
|
}
|
|
|
|
/* 2008-08-28-tyre: Obsolete (see LocalLoginService UserLoginService)
|
|
public static string[] ParseStartLocationRequest(string startLocationRequest)
|
|
{
|
|
string[] returnstring = new string[4];
|
|
// format uri:RegionName&X&Y&Z
|
|
returnstring[0] = "last";
|
|
returnstring[1] = "127";
|
|
returnstring[2] = "127";
|
|
returnstring[3] = "0";
|
|
// This is the crappy way of doing it.
|
|
|
|
if (startLocationRequest.Contains(":") && startLocationRequest.Contains("&"))
|
|
{
|
|
//System.Console.WriteLine("StartLocationRequest Contains proper elements");
|
|
|
|
string[] splitstr = startLocationRequest.Split(':'); //,2,StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
//System.Console.WriteLine("Found " + splitstr.GetLength(0) + " elements in 1st split result");
|
|
|
|
if (splitstr.GetLength(0) == 2)
|
|
{
|
|
string[] splitstr2 = splitstr[1].Split('&'); //, 4, StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
//System.Console.WriteLine("Found " + splitstr2.GetLength(0) + " elements in 2nd split result");
|
|
|
|
int len = Math.Min(splitstr2.GetLength(0), 4);
|
|
|
|
for (int i = 0; i < 4; ++i)
|
|
{
|
|
if (len > i)
|
|
{
|
|
returnstring[i] = splitstr2[i];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return returnstring;
|
|
}
|
|
*/
|
|
|
|
public static XmlRpcResponse XmlRpcCommand(string url, string methodName, params object[] args)
|
|
{
|
|
return SendXmlRpcCommand(url, methodName, args);
|
|
}
|
|
|
|
public static XmlRpcResponse SendXmlRpcCommand(string url, string methodName, object[] args)
|
|
{
|
|
XmlRpcRequest client = new XmlRpcRequest(methodName, args);
|
|
return client.Send(url, 6000);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts a byte array in big endian order into an ulong.
|
|
/// </summary>
|
|
/// <param name="bytes">
|
|
/// The array of bytes
|
|
/// </param>
|
|
/// <returns>
|
|
/// The extracted ulong
|
|
/// </returns>
|
|
public static ulong BytesToUInt64Big(byte[] bytes) {
|
|
if (bytes.Length < 8) return 0;
|
|
return ((ulong)bytes[0] << 56) | ((ulong)bytes[1] << 48) | ((ulong)bytes[2] << 40) | ((ulong)bytes[3] << 32) |
|
|
((ulong)bytes[4] << 24) | ((ulong)bytes[5] << 16) | ((ulong)bytes[6] << 8) | (ulong)bytes[7];
|
|
}
|
|
|
|
// used for RemoteParcelRequest (for "About Landmark")
|
|
public static UUID BuildFakeParcelID(ulong regionHandle, uint x, uint y) {
|
|
byte[] bytes = {
|
|
(byte)regionHandle, (byte)(regionHandle >> 8), (byte)(regionHandle >> 16), (byte)(regionHandle >> 24),
|
|
(byte)(regionHandle >> 32), (byte)(regionHandle >> 40), (byte)(regionHandle >> 48), (byte)(regionHandle << 56),
|
|
(byte)x, (byte)(x >> 8), (byte)(x >> 16), (byte)(x >> 24),
|
|
(byte)y, (byte)(y >> 8), (byte)(y >> 16), (byte)(y >> 24) };
|
|
return new UUID(bytes, 0);
|
|
}
|
|
|
|
public static void ParseFakeParcelID(UUID parcelID, out ulong regionHandle, out uint x, out uint y) {
|
|
byte[] bytes = parcelID.GetBytes();
|
|
regionHandle = Helpers.BytesToUInt64(bytes);
|
|
x = Helpers.BytesToUInt(bytes, 8);
|
|
y = Helpers.BytesToUInt(bytes, 12);
|
|
}
|
|
}
|
|
}
|