Merged 3Di code that provides scene and avatar serialization, and plugin support for region move/split/merge. See ThirdParty/3Di/README.txt. Unless the new modules are used there should be no noticeable changes when running OpenSim.

0.6.0-stable
Johan Berntsson 2008-03-04 05:31:54 +00:00
parent cd6f4a57e7
commit 279e0061c5
44 changed files with 4503 additions and 126 deletions

View File

@ -66,7 +66,7 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
for (int i = 0; i < regionsToLoad.Length; i++)
{
m_log.Debug("[LOADREGIONS]: Creating Region: " + regionsToLoad[i].RegionName + " (ThreadID: " + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString() + ")");
openSim.CreateRegion(regionsToLoad[i]);
openSim.CreateRegion(regionsToLoad[i], true);
}
openSim.ModuleLoader.PostInitialise();
@ -96,7 +96,7 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
if (regionhandle == regionsToLoad[i].RegionHandle)
{
m_log.Debug("[LOADREGIONS]: Creating Region: " + regionsToLoad[i].RegionName + " (ThreadID: " + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString() + ")");
openSim.CreateRegion(regionsToLoad[i]);
openSim.CreateRegion(regionsToLoad[i], true);
}
}
}

View File

@ -269,7 +269,7 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
newRegionData.MasterAvatarFirstName = (string) requestData["region_master_first"];
newRegionData.MasterAvatarLastName = (string) requestData["region_master_last"];
m_app.CreateRegion(newRegionData);
m_app.CreateRegion(newRegionData, true);
responseData["created"] = "true";
response.Value = responseData;

View File

@ -26,10 +26,14 @@
*
*/
using libsecondlife;
using System;
using System.Runtime.Serialization;
using System.Security.Permissions;
namespace OpenSim.Framework
{
public class AvatarWearable
[Serializable]
public class AvatarWearable : ISerializable
{
public LLUUID AssetID = new LLUUID("00000000-0000-0000-0000-000000000000");
public LLUUID ItemID = new LLUUID("00000000-0000-0000-0000-000000000000");
@ -67,5 +71,32 @@ namespace OpenSim.Framework
return defaultWearables;
}
}
protected AvatarWearable(SerializationInfo info, StreamingContext context)
{
//System.Console.WriteLine("AvatarWearable Deserialize BGN");
if (info == null)
{
throw new System.ArgumentNullException("info");
}
AssetID = new LLUUID((Guid)info.GetValue("AssetID", typeof(Guid)));
ItemID = new LLUUID((Guid)info.GetValue("ItemID", typeof(Guid)));
//System.Console.WriteLine("AvatarWearable Deserialize END");
}
[SecurityPermission(SecurityAction.LinkDemand,
Flags = SecurityPermissionFlag.SerializationFormatter)]
public virtual void GetObjectData(
SerializationInfo info, StreamingContext context)
{
if (info == null)
{
throw new System.ArgumentNullException("info");
}
info.AddValue("AssetID", AssetID.UUID);
info.AddValue("ItemID", ItemID.UUID);
}
}
}

View File

@ -69,5 +69,10 @@ namespace OpenSim.Framework
{
return m_queue.Count;
}
public T[] GetQueueArray()
{
return m_queue.ToArray();
}
}
}

View File

@ -137,7 +137,7 @@ namespace OpenSim.Framework
}
}
private uint[] GetAllCircuits(LLUUID agentId)
public uint[] GetAllCircuits(LLUUID agentId)
{
List<uint> circuits = new List<uint>();
// Wasteful, I know

View File

@ -97,6 +97,11 @@ namespace OpenSim.Framework.Data.MySQL
database.ExecuteResourceSql("CreateRegionsTable.sql");
return;
}
else if (oldVersion.Contains("Rev. 1"))
{
database.ExecuteResourceSql("UpgradeRegionsTableToVersion2.sql");
return;
}
}
#endregion
@ -259,6 +264,27 @@ namespace OpenSim.Framework.Data.MySQL
}
}
/// <summary>
/// Deletes a profile from the database
/// </summary>
/// <param name="profile">The profile to delete</param>
/// <returns>Successful?</returns>
//public DataResponse DeleteProfile(RegionProfileData profile)
public DataResponse DeleteProfile(string uuid)
{
lock (database)
{
if (database.deleteRegion(uuid))
{
return DataResponse.RESPONSE_OK;
}
else
{
return DataResponse.RESPONSE_ERROR;
}
}
}
/// <summary>
/// DEPRECIATED. Attempts to authenticate a region by comparing a shared secret.
/// </summary>

View File

@ -301,6 +301,7 @@ namespace OpenSim.Framework.Data.MySQL
// non-critical parts
retval.regionName = (string)reader["regionName"];
retval.originUUID = new LLUUID((string) reader["originUUID"]);
// Secrets
retval.regionRecvKey = (string) reader["regionRecvKey"];
@ -752,13 +753,13 @@ namespace OpenSim.Framework.Data.MySQL
// server for the UUID of the region's owner (master avatar). It consists of the addition of the column and value to the relevant sql,
// as well as the related parameterization
sql +=
"regionAssetSendKey, regionUserURI, regionUserRecvKey, regionUserSendKey, regionMapTexture, serverHttpPort, serverRemotingPort, owner_uuid) VALUES ";
"regionAssetSendKey, regionUserURI, regionUserRecvKey, regionUserSendKey, regionMapTexture, serverHttpPort, serverRemotingPort, owner_uuid, originUUID) VALUES ";
sql += "(?regionHandle, ?regionName, ?uuid, ?regionRecvKey, ?regionSecret, ?regionSendKey, ?regionDataURI, ";
sql +=
"?serverIP, ?serverPort, ?serverURI, ?locX, ?locY, ?locZ, ?eastOverrideHandle, ?westOverrideHandle, ?southOverrideHandle, ?northOverrideHandle, ?regionAssetURI, ?regionAssetRecvKey, ";
sql +=
"?regionAssetSendKey, ?regionUserURI, ?regionUserRecvKey, ?regionUserSendKey, ?regionMapTexture, ?serverHttpPort, ?serverRemotingPort, ?owner_uuid)";
"?regionAssetSendKey, ?regionUserURI, ?regionUserRecvKey, ?regionUserSendKey, ?regionMapTexture, ?serverHttpPort, ?serverRemotingPort, ?owner_uuid, ?originUUID)";
if (GRID_ONLY_UPDATE_NECESSARY_DATA)
{
@ -798,6 +799,7 @@ namespace OpenSim.Framework.Data.MySQL
parameters["?serverHttpPort"] = regiondata.httpPort.ToString();
parameters["?serverRemotingPort"] = regiondata.remotingPort.ToString();
parameters["?owner_uuid"] = regiondata.owner_uuid.ToString();
parameters["?originUUID"] = regiondata.originUUID.ToString();
bool returnval = false;
@ -819,6 +821,42 @@ namespace OpenSim.Framework.Data.MySQL
return false;
}
return returnval;
}
/// <summary>
/// Delete a region from the database
/// </summary>
/// <param name="profile">The region to insert</param>
/// <returns>Success?</returns>
//public bool deleteRegion(RegionProfileData regiondata)
public bool deleteRegion(string uuid)
{
bool returnval = false;
string sql =
"DELETE FROM regions WHERE uuid = ?uuid;";
Dictionary<string, string> parameters = new Dictionary<string, string>();
try
{
parameters["?uuid"] = uuid;
IDbCommand result = Query(sql, parameters);
int x;
if ((x = result.ExecuteNonQuery()) > 0)
{
returnval = true;
}
result.Dispose();
}
catch (Exception e)
{
m_log.Error(e.ToString());
return false;
}
return returnval;
}
}

View File

@ -23,8 +23,9 @@ CREATE TABLE `regions` (
`regionUserRecvKey` varchar(128) default NULL,
`regionUserSendKey` varchar(128) default NULL, `regionMapTexture` varchar(36) default NULL,
`serverHttpPort` int(10) default NULL, `serverRemotingPort` int(10) default NULL,
`originUUID` varchar(36),
PRIMARY KEY (`uuid`),
KEY `regionName` (`regionName`),
KEY `regionHandle` (`regionHandle`),
KEY `overrideHandles` (`eastOverrideHandle`,`westOverrideHandle`,`southOverrideHandle`,`northOverrideHandle`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Rev. 1';
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Rev. 2';

View File

@ -0,0 +1,3 @@
ALTER TABLE `regions`
ADD COLUMN `originUUID` varchar(36),
COMMENT='Rev. 2';

View File

@ -129,6 +129,12 @@ namespace OpenSim.Framework.Data
/// </summary>
public LLUUID owner_uuid = LLUUID.Zero;
/// <summary>
/// OGS/OpenSim Specific original ID for a region after move/split
/// </summary>
public LLUUID originUUID;
/// <summary>
/// Get Sim profile data from grid server when in grid mode
/// </summary>
@ -162,7 +168,7 @@ namespace OpenSim.Framework.Data
simData.serverPort = Convert.ToUInt32((string) responseData["sim_port"]);
simData.httpPort = Convert.ToUInt32((string) responseData["http_port"]);
simData.remotingPort = Convert.ToUInt32((string) responseData["remoting_port"]);
simData.serverURI = "http://" + simData.serverIP + ":" + simData.serverPort.ToString() + "/";
simData.serverURI = (string)responseData["server_uri"];
simData.httpServerURI = "http://" + simData.serverIP + ":" + simData.httpPort.ToString() + "/";
simData.UUID = new LLUUID((string) responseData["region_UUID"]);
simData.regionName = (string) responseData["region_name"];
@ -205,7 +211,7 @@ namespace OpenSim.Framework.Data
simData.httpPort = Convert.ToUInt32((string) responseData["http_port"]);
simData.remotingPort = Convert.ToUInt32((string) responseData["remoting_port"]);
simData.httpServerURI = "http://" + simData.serverIP + ":" + simData.httpPort.ToString() + "/";
simData.serverURI = "http://" + simData.serverIP + ":" + simData.serverPort.ToString() + "/";
simData.serverURI = (string)responseData["server_uri"];
simData.UUID = new LLUUID((string) responseData["region_UUID"]);
simData.regionName = (string) responseData["region_name"];

View File

@ -665,5 +665,24 @@ namespace OpenSim.Framework
void SendBlueBoxMessage(LLUUID FromAvatarID, LLUUID fromSessionID, String FromAvatarName, String Message);
void SendLogoutPacket();
ClientInfo GetClientInfo();
void SetClientInfo(ClientInfo info);
void Terminate();
}
[Serializable]
public class ClientInfo
{
public byte[] usecircuit;
public EndPoint userEP;
public EndPoint proxyEP;
public sAgentCircuitData agentcircuit;
public Dictionary<uint, uint> pendingAcks;
public Dictionary<uint, byte[]> needAck;
public List<byte[]> out_packets;
public uint sequence;
}
}

View File

@ -38,7 +38,8 @@ namespace OpenSim.Framework
Down = 0,
Up = 1,
Crashed = 2,
Starting = 3
Starting = 3,
SlaveScene = 4
} ;
public interface IScene

View File

@ -26,6 +26,7 @@
*
*/
using System;
using System.Net;
using System.Collections;
using libsecondlife.Packets;
@ -33,24 +34,63 @@ namespace OpenSim.Framework
{
public sealed class PacketPool
{
static public void EncodeProxyMessage(byte[] bytes, ref int numBytes, EndPoint trueEP)
{
if( numBytes > 4090 ) // max UPD size = 4096
{
throw new Exception("ERROR: No space to encode the proxy EP");
}
ushort port = (ushort) ((IPEndPoint) trueEP).Port;
bytes[numBytes++] = (byte)(port % 256);
bytes[numBytes++] = (byte)(port / 256);
foreach (byte b in ((IPEndPoint)trueEP).Address.GetAddressBytes())
{
bytes[numBytes++] = b;
}
int x = numBytes;
DecodeProxyMessage(bytes, ref numBytes);
numBytes = x;
}
static public EndPoint DecodeProxyMessage(byte[] bytes, ref int numBytes)
{
// IPv4 Only
byte[] addr = new byte[4];
addr[3] = bytes[--numBytes];
addr[2] = bytes[--numBytes];
addr[1] = bytes[--numBytes];
addr[0] = bytes[--numBytes];
ushort port = (ushort)(bytes[--numBytes] * 256);
port += (ushort)bytes[--numBytes];
return (EndPoint) new IPEndPoint(new IPAddress(addr), (int)port);
}
// Set up a thread-safe singleton pattern
static PacketPool()
{
}
private static readonly PacketPool instance = new PacketPool();
static readonly PacketPool instance = new PacketPool();
public static PacketPool Instance
{
get { return instance; }
get
{
return instance;
}
}
private Hashtable pool = new Hashtable();
public Packet GetPacket(PacketType type)
{
return Packet.BuildPacket(type);
/* Skip until PacketPool performance problems have been resolved (mantis 281)
public Packet GetPacket(PacketType type) {
Packet packet = null;
lock(pool)
@ -68,34 +108,11 @@ namespace OpenSim.Framework
}
return packet;
*/
}
// Copied from LibSL, and added a check to avoid overwriting the
// buffer
private void ZeroDecodeCommand(byte[] src, byte[] dest)
{
for (int srcPos = 6, destPos = 6; destPos < 10; ++srcPos)
{
if (src[srcPos] == 0x00)
{
for (byte j = 0; j < src[srcPos + 1] && destPos < 10; ++j)
{
dest[destPos++] = 0x00;
}
++srcPos;
}
else
{
dest[destPos++] = src[srcPos];
}
}
}
private byte[] decoded_header = new byte[10];
private PacketType GetType(byte[] bytes)
{
byte[] decoded_header = new byte[10];
ushort id;
libsecondlife.PacketFrequency freq;
@ -103,7 +120,7 @@ namespace OpenSim.Framework
if((bytes[0] & libsecondlife.Helpers.MSG_ZEROCODED)!=0)
{
ZeroDecodeCommand(bytes, decoded_header);
libsecondlife.Helpers.ZeroDecodeCommand(bytes, decoded_header);
}
if (decoded_header[6] == 0xFF)
@ -138,9 +155,9 @@ namespace OpenSim.Framework
return packet;
}
public void ReturnPacket(Packet packet)
{
/* Skip until PacketPool performance problems have been resolved (mantis 281)
public void ReturnPacket(Packet packet) {
return; // packet pool disabled
lock(pool)
{
PacketType type=packet.Type;
@ -149,10 +166,11 @@ namespace OpenSim.Framework
{
pool[type] = new Stack();
}
if (((Stack)pool[type]).Count < 50)
{
((Stack)pool[type]).Push(packet);
}
*/
}
}
}
}

View File

@ -71,6 +71,7 @@ namespace OpenSim.Framework
m_allow_alternate_ports = ConvertFrom.m_allow_alternate_ports;
RemotingAddress = ConvertFrom.RemotingAddress;
RegionID = LLUUID.Zero;
ServerURI = ConvertFrom.ServerURI;
}
public LLUUID RegionID = LLUUID.Zero;
@ -84,6 +85,19 @@ namespace OpenSim.Framework
}
public bool m_allow_alternate_ports;
public string m_serverURI;
public string ServerURI
{
get
{
return m_serverURI;
}
set
{
m_serverURI = value;
}
}
public string RemotingAddress;
public IPEndPoint ExternalEndPoint
@ -175,6 +189,8 @@ namespace OpenSim.Framework
public string MasterAvatarFirstName = String.Empty;
public string MasterAvatarLastName = String.Empty;
public string MasterAvatarSandboxPassword = String.Empty;
public string proxyUrl = "";
public LLUUID originRegionID = LLUUID.Zero;
// Apparently, we're applying the same estatesettings regardless of whether it's local or remote.
private EstateSettings m_estateSettings;
@ -227,6 +243,10 @@ namespace OpenSim.Framework
m_allow_alternate_ports = ConvertFrom.m_allow_alternate_ports;
RemotingAddress = ConvertFrom.RemotingAddress;
RegionID = LLUUID.Zero;
proxyUrl = ConvertFrom.ProxyUrl;
originRegionID = ConvertFrom.OriginRegionID;
RegionName = ConvertFrom.RegionName;
ServerURI = ConvertFrom.ServerURI;
}
public RegionInfo(SimpleRegionInfo ConvertFrom)
@ -239,6 +259,7 @@ namespace OpenSim.Framework
m_allow_alternate_ports = ConvertFrom.m_allow_alternate_ports;
RemotingAddress = ConvertFrom.RemotingAddress;
RegionID = LLUUID.Zero;
ServerURI = ConvertFrom.ServerURI;
}
//not in use, should swap to nini though.

View File

@ -51,6 +51,10 @@ namespace OpenSim.Framework
m_remotingPort = ConvertFrom.RemotingPort;
m_allow_alternate_ports = ConvertFrom.m_allow_alternate_ports;
RemotingAddress = ConvertFrom.RemotingAddress;
m_proxyUrl = ConvertFrom.proxyUrl;
OriginRegionID = ConvertFrom.originRegionID;
RegionName = ConvertFrom.RegionName;
ServerURI = ConvertFrom.ServerURI;
}
public SearializableRegionInfo(uint regionLocX, uint regionLocY, IPEndPoint internalEndPoint, string externalUri)
@ -157,5 +161,57 @@ namespace OpenSim.Framework
{
get { return Util.UIntsToLong((RegionLocX * (uint)Constants.RegionSize), (RegionLocY * (uint)Constants.RegionSize)); }
}
protected string m_proxyUrl;
public string ProxyUrl
{
get
{
return m_proxyUrl;
}
set
{
m_proxyUrl = value;
}
}
protected Guid m_originRegionID = LLUUID.Zero.UUID;
public LLUUID OriginRegionID
{
get
{
return new LLUUID(m_originRegionID);
}
set
{
m_originRegionID = value.UUID;
}
}
protected string m_regionName;
public string RegionName
{
get
{
return m_regionName;
}
set
{
m_regionName = value;
}
}
protected string m_serverURI;
public string ServerURI
{
get
{
return m_serverURI;
}
set
{
m_serverURI = value;
}
}
}
}

View File

@ -37,6 +37,8 @@ using System.Text;
using libsecondlife;
using Nini.Config;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
namespace OpenSim.Framework
{
public class Util
@ -509,7 +511,63 @@ namespace OpenSim.Framework
{
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;
}
}
}

View File

@ -37,6 +37,7 @@ using OpenSim.Framework;
using OpenSim.Framework.Console;
using OpenSim.Framework.Data;
using OpenSim.Framework.Servers;
using OpenSim.Framework.Data.MySQL;
namespace OpenSim.Grid.GridServer
{
@ -301,16 +302,20 @@ namespace OpenSim.Grid.GridServer
catch (KeyNotFoundException) { }
TheSim.regionHandle = Helpers.UIntsToLong((TheSim.regionLocX * Constants.RegionSize), (TheSim.regionLocY * Constants.RegionSize));
TheSim.serverURI = "http://" + TheSim.serverIP + ":" + TheSim.serverPort + "/";
TheSim.serverURI = (string)requestData["server_uri"];
Console.WriteLine("adding region " + TheSim.regionLocX + " , " + TheSim.regionLocY + " , " +
TheSim.serverURI);
TheSim.httpServerURI = "http://" + TheSim.serverIP + ":" + TheSim.httpPort + "/";
TheSim.regionName = (string)requestData["sim_name"];
TheSim.UUID = new LLUUID((string)requestData["UUID"]);
TheSim.originUUID = new LLUUID((string) requestData["originUUID"]);
//make sure there is not an existing region at this location
OldSim = getRegion(TheSim.regionHandle);
if (OldSim == null || OldSim.UUID == TheSim.UUID)
//if (OldSim == null || OldSim.UUID == TheSim.UUID)
if (OldSim == null || OldSim.UUID == TheSim.UUID || TheSim.UUID != TheSim.originUUID)
{
bool brandNew = ( OldSim == null && TheSim.regionRecvKey == config.SimSendKey &&
TheSim.regionSendKey == config.SimRecvKey);
@ -500,6 +505,69 @@ namespace OpenSim.Grid.GridServer
}
/// <summary>
/// Returns an XML RPC response to a simulator profile request
/// Performed after moving a region.
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
/// <param name="request">The XMLRPC Request</param>
/// <returns>Processing parameters</returns>
public XmlRpcResponse XmlRpcDeleteRegionMethod(XmlRpcRequest request)
{
XmlRpcResponse response = new XmlRpcResponse();
Hashtable responseData = new Hashtable();
response.Value = responseData;
//RegionProfileData TheSim = null;
string uuid = String.Empty;;
Hashtable requestData = (Hashtable) request.Params[0];
string myword;
if (requestData.ContainsKey("UUID")) {
//TheSim = getRegion(new LLUUID((string) requestData["UUID"]));
uuid = requestData["UUID"].ToString();
Console.WriteLine("deleting region " + uuid);
// logToDB((new LLUUID((string)requestData["UUID"])).ToString(),"XmlRpcDeleteRegionMethod","", 5,"Attempting delete with UUID.");
}
else {
responseData["error"] = "No UUID or region_handle passed to grid server - unable to delete";
return response;
}
foreach (KeyValuePair<string, IGridData> kvp in _plugins) {
//OpenSim.Framework.Data.MySQL.MySQLGridData dbengine = new OpenSim.Framework.Data.MySQL.MySQLGridData();
try {
OpenSim.Framework.Data.MySQL.MySQLGridData mysqldata = (OpenSim.Framework.Data.MySQL.MySQLGridData)(kvp.Value);
//DataResponse insertResponse = mysqldata.DeleteProfile(TheSim);
DataResponse insertResponse = mysqldata.DeleteProfile(uuid);
switch (insertResponse) {
case DataResponse.RESPONSE_OK:
//MainLog.Instance.Verbose("grid", "Deleting region successful: " + uuid);
responseData["status"] = "Deleting region successful: " + uuid;
break;
case DataResponse.RESPONSE_ERROR:
//MainLog.Instance.Warn("storage", "Deleting region failed (Error): " + uuid);
responseData["status"] = "Deleting region failed (Error): " + uuid;
break;
case DataResponse.RESPONSE_INVALIDCREDENTIALS:
//MainLog.Instance.Warn("storage", "Deleting region failed (Invalid Credentials): " + uuid);
responseData["status"] = "Deleting region (Invalid Credentials): " + uuid;
break;
case DataResponse.RESPONSE_AUTHREQUIRED:
//MainLog.Instance.Warn("storage", "Deleting region failed (Authentication Required): " + uuid);
responseData["status"] = "Deleting region (Authentication Required): " + uuid;
break;
}
}
catch (Exception e) {
m_log.Error("storage Unable to delete region " + uuid + " via MySQL");
//MainLog.Instance.Warn("storage", e.ToString());
}
}
return response;
}
/// <summary>
/// Returns an XML RPC response to a simulator profile request
/// </summary>
@ -533,6 +601,7 @@ namespace OpenSim.Grid.GridServer
(string) requestData["region_handle"]);
responseData["sim_ip"] = Util.GetHostFromDNS(simData.serverIP).ToString();
responseData["sim_port"] = simData.serverPort.ToString();
responseData["server_uri"] = simData.serverURI;
responseData["http_port"] = simData.httpPort.ToString();
responseData["remoting_port"] = simData.remotingPort.ToString();
responseData["region_locx"] = simData.regionLocX.ToString();
@ -799,7 +868,6 @@ namespace OpenSim.Grid.GridServer
}
TheSim.serverURI = "http://" + TheSim.serverIP + ":" + TheSim.serverPort + "/";
bool requirePublic = false;
bool requireValid = true;

View File

@ -113,6 +113,7 @@ namespace OpenSim.Grid.GridServer
httpServer.AddXmlRPCHandler("simulator_login", m_gridManager.XmlRpcSimulatorLoginMethod);
httpServer.AddXmlRPCHandler("simulator_data_request", m_gridManager.XmlRpcSimulatorDataRequestMethod);
httpServer.AddXmlRPCHandler("simulator_after_region_moved", m_gridManager.XmlRpcDeleteRegionMethod);
httpServer.AddXmlRPCHandler("map_block", m_gridManager.XmlRpcMapBlockMethod);
// Message Server ---> Grid Server

View File

@ -99,8 +99,8 @@ namespace OpenSim.Grid.UserServer
//CFK: the next one for X & Y and comment this one.
//CFK: m_log.Info("[LOGIN]: CUSTOMISERESPONSE: Region X: " + SimInfo.regionLocX +
//CFK: "; Region Y: " + SimInfo.regionLocY);
response.SimAddress = Util.GetHostFromDNS(SimInfo.serverIP).ToString();
response.SimPort = (uint) SimInfo.serverPort;
response.SimAddress = Util.GetHostFromDNS(SimInfo.serverURI.Split(new char[] { '/', ':' })[3]).ToString();
response.SimPort = uint.Parse(SimInfo.serverURI.Split(new char[] { '/', ':' })[4]);
response.RegionX = SimInfo.regionLocX;
response.RegionY = SimInfo.regionLocY;
@ -190,8 +190,8 @@ namespace OpenSim.Grid.UserServer
m_log.Info("[LOGIN]: " +
"CUSTOMISERESPONSE: Region X: " + SimInfo.regionLocX + "; Region Y: " +
SimInfo.regionLocY);
response.SimAddress = Util.GetHostFromDNS(SimInfo.serverIP).ToString();
response.SimPort = (uint) SimInfo.serverPort;
response.SimAddress = Util.GetHostFromDNS(SimInfo.serverURI.Split(new char[] { '/', ':' })[3]).ToString();
response.SimPort = uint.Parse(SimInfo.serverURI.Split(new char[] { '/', ':' })[4]);
response.RegionX = SimInfo.regionLocX;
response.RegionY = SimInfo.regionLocY;

View File

@ -33,8 +33,6 @@ using System.IO;
using System.Text;
using System.Threading;
using System.Timers;
using libsecondlife;
using Mono.Addins;
using Nini.Config;
using OpenSim.Framework;
using OpenSim.Framework.Communications.Cache;
@ -49,6 +47,13 @@ using OpenSim.Region.Environment.Interfaces;
using OpenSim.Region.Environment.Scenes;
using OpenSim.Region.Physics.Manager;
using Timer=System.Timers.Timer;
using System.Net;
using Nwc.XmlRpc;
using System.Collections;
using System.Reflection;
using libsecondlife;
using Mono.Addins;
using Mono.Addins.Description;
namespace OpenSim
{
@ -57,6 +62,8 @@ namespace OpenSim
public class OpenSimMain : RegionApplicationBase, conscmd_callback
{
private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private string proxyUrl;
private int proxyOffset = 0;
private const string DEFAULT_PRIM_BACKUP_FILENAME = "prim-backup.xml";
@ -110,6 +117,16 @@ namespace OpenSim
get { return m_httpServer; }
}
public List<UDPServer> UdpServers
{
get { return m_udpServers; }
}
public List<RegionInfo> RegionData
{
get { return m_regionData; }
}
private ModuleLoader m_moduleLoader;
public ModuleLoader ModuleLoader
@ -350,20 +367,34 @@ namespace OpenSim
m_httpServer.AddStreamHandler(new SimStatusHandler());
}
proxyUrl = ConfigSource.Configs["Network"].GetString("proxy_url", "");
proxyOffset = Int32.Parse(ConfigSource.Configs["Network"].GetString("proxy_offset", "0"));
// Create a ModuleLoader instance
m_moduleLoader = new ModuleLoader(m_config);
ExtensionNodeList nodes = AddinManager.GetExtensionNodes("/OpenSim/Startup");
m_log.InfoFormat("[PLUGINS]: Loading {0} OpenSim application plugins", nodes.Count);
foreach (TypeExtensionNode node in nodes)
{
// First load the proxy server (if present)
if(node.Path.Contains("Proxy"))
{
IApplicationPlugin plugin = (IApplicationPlugin)node.CreateInstance();
plugin.Initialise(this);
m_plugins.Add(plugin);
}
}
// then load the other modules
foreach (TypeExtensionNode node in nodes)
{
if(!node.Path.Contains("Proxy"))
{
IApplicationPlugin plugin = (IApplicationPlugin)node.CreateInstance();
plugin.Initialise(this);
m_plugins.Add(plugin);
}
}
// Start UDP servers
//for (int i = 0; i < m_udpServers.Count; i++)
//{
@ -436,10 +467,25 @@ namespace OpenSim
return m_commsManager.AddUser(tempfirstname,templastname,tempPasswd,regX,regY);
}
public UDPServer CreateRegion(RegionInfo regionInfo)
public UDPServer CreateRegion(RegionInfo regionInfo, bool portadd_flag)
{
int port = regionInfo.InternalEndPoint.Port;
if ((proxyOffset != 0) && (portadd_flag))
{
// set proxy url to RegionInfo
regionInfo.proxyUrl = proxyUrl;
// set initial RegionID to originRegionID in RegionInfo. (it needs for loding prims)
regionInfo.originRegionID = regionInfo.RegionID;
// set initial ServerURI
regionInfo.ServerURI = "http://" + regionInfo.ExternalHostName
+ ":" + regionInfo.InternalEndPoint.Port.ToString();
ProxyCommand(proxyUrl, "AddPort", port, port + proxyOffset, regionInfo.ExternalHostName);
}
UDPServer udpServer;
Scene scene = SetupScene(regionInfo, out udpServer, m_permissions);
Scene scene = SetupScene(regionInfo, proxyOffset, out udpServer, m_permissions);
m_log.Info("[MODULES]: Loading Region's modules");
@ -546,7 +592,7 @@ namespace OpenSim
m_regionData.RemoveAt(RegionHandleElement);
}
CreateRegion(whichRegion);
CreateRegion(whichRegion, true);
//UDPServer restartingRegion = CreateRegion(whichRegion);
//restartingRegion.ServerListener();
//m_sceneManager.SendSimOnlineNotification(restartingRegion.RegionHandle);
@ -594,6 +640,8 @@ namespace OpenSim
/// </summary>
public virtual void Shutdown()
{
ProxyCommand(proxyUrl, "Stop");
if (m_startupCommandsFile != String.Empty)
{
RunCommandScript(m_shutdownCommandsFile);
@ -882,9 +930,8 @@ namespace OpenSim
break;
case "create-region":
CreateRegion(new RegionInfo(cmdparams[0], "Regions/" + cmdparams[1],false));
CreateRegion(new RegionInfo(cmdparams[0], "Regions/" + cmdparams[1],false), true);
break;
case "remove-region":
string regName = CombineParams(cmdparams, 0);
@ -1120,6 +1167,8 @@ namespace OpenSim
presence.ControllingClient.CircuitCode,
ep,
regionName));
m_console.Notice(" {0}", (((ClientView)presence.ControllingClient).PacketProcessingEnabled)?"Active client":"Standby client");
}
break;
@ -1167,5 +1216,80 @@ namespace OpenSim
}
#endregion
// TODO: remove me!! (almost same as XmlRpcCommand)
public object ProxyCommand(string url, string methodName, params object[] args)
{
if(proxyUrl.Length==0) return null;
return SendXmlRpcCommand(url, methodName, args);
}
public object XmlRpcCommand(uint port, string methodName, params object[] args)
{
return SendXmlRpcCommand("http://localhost:"+port, methodName, args);
}
public object XmlRpcCommand(string url, string methodName, params object[] args)
{
return SendXmlRpcCommand(url, methodName, args);
}
private object SendXmlRpcCommand(string url, string methodName, object[] args)
{
try {
//MainLog.Instance.Verbose("XMLRPC", "Sending command {0} to {1}", methodName, url);
XmlRpcRequest client = new XmlRpcRequest(methodName, args);
//MainLog.Instance.Verbose("XMLRPC", client.ToString());
XmlRpcResponse response = client.Send(url, 6000);
if(!response.IsFault) return response.Value;
}
catch(Exception e)
{
m_log.ErrorFormat("XMLRPC Failed to send command {0} to {1}: {2}", methodName, url, e.Message);
}
return null;
}
/// <summary>
/// Get the start time and up time of Region server
/// </summary>
/// <param name="starttime">The first out parameter describing when the Region server started</param>
/// <param name="uptime">The second out parameter describing how long the Region server has run</param>
public void GetRunTime(out string starttime, out string uptime)
{
starttime = m_startuptime.ToString();
uptime = (DateTime.Now - m_startuptime).ToString();
}
/// <summary>
/// Get the number of the avatars in the Region server
/// </summary>
/// <param name="usernum">The first out parameter describing the number of all the avatars in the Region server</param>
public void GetAvatarNumber(out int usernum)
{
int accounter = 0;
foreach (ScenePresence presence in m_sceneManager.GetCurrentSceneAvatars()) {
//presence.RegionHandle;
accounter++;
}
usernum = accounter;
}
/// <summary>
/// Get the number of the avatars in the Region server
/// </summary>
/// <param name="usernum">The first out parameter describing the number of all the avatars in the Region server</param>
public void GetRegionNumber(out int regionnum)
{
int accounter = 0;
//List<string> regionNameList = new List<string>();
m_sceneManager.ForEachScene(delegate(Scene scene) {
accounter++;
});
regionnum = accounter;
}
}
}

View File

@ -61,6 +61,8 @@ namespace OpenSim.Region.ClientStack
/* static variables */
public static TerrainManager TerrainManager;
public delegate bool SynchronizeClientHandler(IScene scene, Packet packet, LLUUID agentID, ThrottleOutPacketType throttlePacketType);
public static SynchronizeClientHandler SynchronizeClient = null;
/* private variables */
private readonly LLUUID m_sessionId;
private LLUUID m_secureSessionId = LLUUID.Zero;
@ -118,6 +120,7 @@ namespace OpenSim.Region.ClientStack
protected Thread m_clientThread;
protected LLVector3 m_startpos;
protected EndPoint m_userEndPoint;
protected EndPoint m_proxyEndPoint;
/* Instantiated Designated Event Delegates */
//- used so we don't create new objects for each incoming packet and then toss it out later */
@ -291,7 +294,7 @@ namespace OpenSim.Region.ClientStack
/* METHODS */
public ClientView(EndPoint remoteEP, IScene scene, AssetCache assetCache, PacketServer packServer,
AgentCircuitManager authenSessions, LLUUID agentId, LLUUID sessionId, uint circuitCode)
AgentCircuitManager authenSessions, LLUUID agentId, LLUUID sessionId, uint circuitCode, EndPoint proxyEP)
{
m_moneyBalance = 1000;
@ -311,6 +314,7 @@ namespace OpenSim.Region.ClientStack
m_circuitCode = circuitCode;
m_userEndPoint = remoteEP;
m_proxyEndPoint = proxyEP;
m_startpos = m_authenticateSessionsHandler.GetPosition(circuitCode);
@ -411,7 +415,37 @@ namespace OpenSim.Region.ClientStack
public void Stop()
{
m_log.Info("[BUG]: Stop called, please find out where and remove it");
// Shut down timers
m_ackTimer.Stop();
m_clientPingTimer.Stop();
}
public void Restart()
{
// re-construct
m_pendingAcks = new Dictionary<uint, uint>();
m_needAck = new Dictionary<uint, Packet>();
m_sequence += 1000000;
m_ackTimer = new Timer(750);
m_ackTimer.Elapsed += new ElapsedEventHandler(AckTimer_Elapsed);
m_ackTimer.Start();
m_clientPingTimer = new Timer(5000);
m_clientPingTimer.Elapsed += new ElapsedEventHandler(CheckClientConnectivity);
m_clientPingTimer.Enabled = true;
}
public void Terminate()
{
// disable blocking queue
m_packetQueue.Enqueue(null);
// wait for thread stoped
m_clientThread.Join();
// delete circuit code
m_networkServer.CloseClient(this);
}
#endregion
@ -507,6 +541,10 @@ namespace OpenSim.Region.ClientStack
while (true)
{
QueItem nextPacket = m_packetQueue.Dequeue();
if (nextPacket == null)
{
break;
}
if (nextPacket.Incoming)
{
if (nextPacket.Packet.Type != PacketType.AgentUpdate)
@ -2651,8 +2689,11 @@ namespace OpenSim.Region.ClientStack
}
else
{
m_networkServer.SendPacketTo(sendbuffer, sendbuffer.Length, SocketFlags.None, m_circuitCode);
//Need some extra space in case we need to add proxy information to the message later
Buffer.BlockCopy(sendbuffer, 0, ZeroOutBuffer, 0, sendbuffer.Length);
m_networkServer.SendPacketTo(ZeroOutBuffer, sendbuffer.Length, SocketFlags.None, m_circuitCode);
}
}
catch (Exception e)
{
@ -2666,6 +2707,12 @@ namespace OpenSim.Region.ClientStack
public virtual void InPacket(Packet NewPack)
{
if(!m_packetProcessingEnabled && NewPack.Type != PacketType.LogoutRequest)
{
PacketPool.Instance.ReturnPacket(NewPack);
return;
}
// Handle appended ACKs
if (NewPack != null)
{
@ -2726,6 +2773,15 @@ namespace OpenSim.Region.ClientStack
public virtual void OutPacket(Packet NewPack, ThrottleOutPacketType throttlePacketType)
{
if ((SynchronizeClient != null) && (!PacketProcessingEnabled))
{
// Sending packet to active client's server.
if (SynchronizeClient(m_scene, NewPack, m_agentId, throttlePacketType))
{
return;
}
}
QueItem item = new QueItem();
item.Packet = NewPack;
item.Incoming = false;
@ -2853,6 +2909,13 @@ namespace OpenSim.Region.ClientStack
}
}
private bool m_packetProcessingEnabled = true;
public bool PacketProcessingEnabled {
get { return m_packetProcessingEnabled; }
set { m_packetProcessingEnabled = value; }
}
protected void ProcessInPacket(Packet Pack)
{
ack_pack(Pack);
@ -4373,5 +4436,79 @@ namespace OpenSim.Region.ClientStack
OutPacket(logReply, ThrottleOutPacketType.Task);
}
public ClientInfo GetClientInfo()
{
//MainLog.Instance.Verbose("CLIENT", "GetClientInfo BGN");
ClientInfo info = new ClientInfo();
info.userEP = this.m_userEndPoint;
info.proxyEP = this.m_proxyEndPoint;
info.agentcircuit = new sAgentCircuitData(RequestClientInfo());
info.pendingAcks = m_pendingAcks;
info.needAck = new Dictionary<uint,byte[]>();
lock (m_needAck)
{
foreach (uint key in m_needAck.Keys)
{
info.needAck.Add(key, m_needAck[key].ToBytes());
}
}
/* pending
QueItem[] queitems = m_packetQueue.GetQueueArray();
MainLog.Instance.Verbose("CLIENT", "Queue Count : [{0}]", queitems.Length);
for (int i = 0; i < queitems.Length; i++)
{
if (queitems[i].Incoming == false)
{
info.out_packets.Add(queitems[i].Packet.ToBytes());
MainLog.Instance.Verbose("CLIENT", "Add OutPacket [{0}]", queitems[i].Packet.Type.ToString());
}
}
*/
info.sequence = m_sequence;
//MainLog.Instance.Verbose("CLIENT", "GetClientInfo END");
return info;
}
public void SetClientInfo(ClientInfo info)
{
m_pendingAcks = info.pendingAcks;
m_needAck = new Dictionary<uint,Packet>();
Packet packet = null;
int packetEnd = 0;
byte[] zero = new byte[3000];
foreach (uint key in info.needAck.Keys)
{
byte[] buff = info.needAck[key];
packetEnd = buff.Length - 1;
try
{
packet = PacketPool.Instance.GetPacket(buff, ref packetEnd, zero);
}
catch (Exception)
{
//MainLog.Instance.Debug("UDPSERVER", e.ToString());
}
m_needAck.Add(key, packet);
}
m_sequence = info.sequence;
}
}
}

View File

@ -142,8 +142,13 @@ namespace OpenSim.Region.ClientStack
// We could micro lock, but that will tend to actually
// probably be worse than just synchronizing on SendQueue
lock (this)
if (item == null)
{
SendQueue.Enqueue(item);
return;
}
lock (this) {
switch (item.throttleType)
{
case ThrottleOutPacketType.Resend:
@ -518,5 +523,10 @@ namespace OpenSim.Region.ClientStack
TextureOutgoingPacketQueue.Count,
AssetOutgoingPacketQueue.Count);
}
public QueItem[] GetQueueArray()
{
return SendQueue.GetQueueArray();
}
}
}

View File

@ -74,14 +74,14 @@ namespace OpenSim.Region.ClientStack
protected virtual IClientAPI CreateNewClient(EndPoint remoteEP, UseCircuitCodePacket initialcirpack,
ClientManager clientManager, IScene scene, AssetCache assetCache,
PacketServer packServer, AgentCircuitManager authenSessions,
LLUUID agentId, LLUUID sessionId, uint circuitCode)
LLUUID agentId, LLUUID sessionId, uint circuitCode, EndPoint proxyEP)
{
return
new ClientView(remoteEP, scene, assetCache, packServer, authenSessions, agentId, sessionId, circuitCode);
new ClientView(remoteEP, scene, assetCache, packServer, authenSessions, agentId, sessionId, circuitCode, proxyEP);
}
public virtual bool AddNewClient(EndPoint epSender, UseCircuitCodePacket useCircuit, AssetCache assetCache,
AgentCircuitManager authenticateSessionsClass)
AgentCircuitManager authenticateSessionsClass, EndPoint proxyEP)
{
IClientAPI newuser;
@ -93,7 +93,7 @@ namespace OpenSim.Region.ClientStack
{
newuser = CreateNewClient(epSender, useCircuit, m_scene.ClientManager, m_scene, assetCache, this,
authenticateSessionsClass, useCircuit.CircuitCode.ID,
useCircuit.CircuitCode.SessionID, useCircuit.CircuitCode.Code);
useCircuit.CircuitCode.SessionID, useCircuit.CircuitCode.Code, proxyEP);
m_scene.ClientManager.Add(useCircuit.CircuitCode.Code, newuser);

View File

@ -103,6 +103,11 @@ namespace OpenSim.Region.ClientStack
}
protected Scene SetupScene(RegionInfo regionInfo, out UDPServer udpServer, bool m_permissions)
{
return SetupScene(regionInfo, 0, out udpServer, m_permissions);
}
protected Scene SetupScene(RegionInfo regionInfo, int proxyOffset, out UDPServer udpServer, bool m_permissions)
{
AgentCircuitManager circuitManager = new AgentCircuitManager();
IPAddress listenIP = regionInfo.InternalEndPoint.Address;
@ -110,7 +115,7 @@ namespace OpenSim.Region.ClientStack
// listenIP = IPAddress.Parse("0.0.0.0");
uint port = (uint) regionInfo.InternalEndPoint.Port;
udpServer = new UDPServer(listenIP, ref port, regionInfo.m_allow_alternate_ports, m_assetCache, circuitManager);
udpServer = new UDPServer(listenIP, ref port, proxyOffset, regionInfo.m_allow_alternate_ports, m_assetCache, circuitManager);
regionInfo.InternalEndPoint.Port = (int)port;
Scene scene = CreateScene(regionInfo, m_storageManager, circuitManager);
@ -148,8 +153,8 @@ namespace OpenSim.Region.ClientStack
scene.RegionInfo.MasterAvatarAssignedUUID = LLUUID.Zero;
}
scene.LoadPrimsFromStorage(m_permissions);
scene.loadAllLandObjectsFromStorage();
scene.LoadPrimsFromStorage(m_permissions, regionInfo.originRegionID);
scene.loadAllLandObjectsFromStorage(regionInfo.originRegionID);
scene.performParcelPrimCountUpdate();
scene.StartTimer();
return scene;

View File

@ -43,12 +43,15 @@ namespace OpenSim.Region.ClientStack
protected Dictionary<EndPoint, uint> clientCircuits = new Dictionary<EndPoint, uint>();
public Dictionary<uint, EndPoint> clientCircuits_reverse = new Dictionary<uint, EndPoint>();
protected Dictionary<uint, EndPoint> proxyCircuits = new Dictionary<uint, EndPoint>();
public Socket Server;
protected IPEndPoint ServerIncoming;
protected byte[] RecvBuffer = new byte[4096];
protected byte[] ZeroBuffer = new byte[8192];
protected IPEndPoint ipeSender;
protected EndPoint epSender;
protected EndPoint epProxy;
protected int proxyPortOffset;
protected AsyncCallback ReceivedData;
protected PacketServer m_packetServer;
protected ulong m_regionHandle;
@ -85,10 +88,11 @@ namespace OpenSim.Region.ClientStack
{
}
public UDPServer(IPAddress _listenIP, ref uint port, bool allow_alternate_port, AssetCache assetCache, AgentCircuitManager authenticateClass)
public UDPServer(IPAddress _listenIP, ref uint port, int proxyPortOffset, bool allow_alternate_port, AssetCache assetCache, AgentCircuitManager authenticateClass)
{
this.proxyPortOffset = proxyPortOffset;
listenPort = (uint) (port + proxyPortOffset);
listenIP = _listenIP;
listenPort = port;
Allow_Alternate_Port = allow_alternate_port;
m_assetCache = assetCache;
m_authenticateSessionsClass = authenticateClass;
@ -97,7 +101,7 @@ namespace OpenSim.Region.ClientStack
// Return new port
// This because in Grid mode it is not really important what port the region listens to as long as it is correctly registered.
// So the option allow_alternate_ports="true" was added to default.xml
port = listenPort;
port = (uint)(listenPort - proxyPortOffset);
}
protected virtual void CreatePacketServer()
@ -211,6 +215,13 @@ namespace OpenSim.Region.ClientStack
//return;
}
//System.Console.WriteLine("UDPServer : recieved message from {0}", epSender.ToString());
epProxy = epSender;
if (proxyPortOffset != 0)
{
epSender = PacketPool.DecodeProxyMessage(RecvBuffer, ref numBytes);
}
int packetEnd = numBytes - 1;
try
@ -317,6 +328,9 @@ namespace OpenSim.Region.ClientStack
}
protected virtual void AddNewClient(Packet packet)
{
//Slave regions don't accept new clients
if(m_localScene.Region_Status != RegionStatus.SlaveScene)
{
UseCircuitCodePacket useCircuit = (UseCircuitCodePacket) packet;
lock (clientCircuits)
@ -334,7 +348,17 @@ namespace OpenSim.Region.ClientStack
m_log.Error("[UDPSERVER]: clientCurcuits_reverse already contains entry for user " + useCircuit.CircuitCode.Code.ToString() + ". NOT adding.");
}
PacketServer.AddNewClient(epSender, useCircuit, m_assetCache, m_authenticateSessionsClass);
lock (proxyCircuits)
{
if (!proxyCircuits.ContainsKey(useCircuit.CircuitCode.Code))
proxyCircuits.Add(useCircuit.CircuitCode.Code, epProxy);
else
m_log.Error("[UDPSERVER]: proxyCircuits already contains entry for user " + useCircuit.CircuitCode.Code.ToString() + ". NOT adding.");
}
PacketServer.AddNewClient(epSender, useCircuit, m_assetCache, m_authenticateSessionsClass, epProxy);
}
PacketPool.Instance.ReturnPacket(packet);
}
public void ServerListener()
@ -389,10 +413,20 @@ namespace OpenSim.Region.ClientStack
if (clientCircuits_reverse.TryGetValue(circuitcode, out sendto))
{
//we found the endpoint so send the packet to it
if (proxyPortOffset != 0)
{
//MainLog.Instance.Verbose("UDPSERVER", "SendPacketTo proxy " + proxyCircuits[circuitcode].ToString() + ": client " + sendto.ToString());
PacketPool.EncodeProxyMessage(buffer, ref size, sendto);
Server.SendTo(buffer, size, flags, proxyCircuits[circuitcode]);
}
else
{
//MainLog.Instance.Verbose("UDPSERVER", "SendPacketTo : client " + sendto.ToString());
Server.SendTo(buffer, size, flags, sendto);
}
}
}
}
public virtual void RemoveClientCircuit(uint circuitcode)
{
@ -404,8 +438,50 @@ namespace OpenSim.Region.ClientStack
clientCircuits.Remove(sendto);
clientCircuits_reverse.Remove(circuitcode);
proxyCircuits.Remove(circuitcode);
}
}
}
public void RestoreClient(AgentCircuitData circuit, EndPoint userEP, EndPoint proxyEP)
{
//MainLog.Instance.Verbose("UDPSERVER", "RestoreClient");
UseCircuitCodePacket useCircuit = new UseCircuitCodePacket();
useCircuit.CircuitCode.Code = circuit.circuitcode;
useCircuit.CircuitCode.ID = circuit.AgentID;
useCircuit.CircuitCode.SessionID = circuit.SessionID;
lock (clientCircuits)
{
if (!clientCircuits.ContainsKey(userEP))
clientCircuits.Add(userEP, useCircuit.CircuitCode.Code);
else
m_log.Error("[UDPSERVER]: clientCircuits already contans entry for user " + useCircuit.CircuitCode.Code.ToString() + ". NOT adding.");
}
lock (clientCircuits_reverse)
{
if (!clientCircuits_reverse.ContainsKey(useCircuit.CircuitCode.Code))
clientCircuits_reverse.Add(useCircuit.CircuitCode.Code, userEP);
else
m_log.Error("[UDPSERVER]: clientCurcuits_reverse already contains entry for user " + useCircuit.CircuitCode.Code.ToString() + ". NOT adding.");
}
lock (proxyCircuits)
{
if (!proxyCircuits.ContainsKey(useCircuit.CircuitCode.Code))
{
proxyCircuits.Add(useCircuit.CircuitCode.Code, proxyEP);
}
else
{
// re-set proxy endpoint
proxyCircuits.Remove(useCircuit.CircuitCode.Code);
proxyCircuits.Add(useCircuit.CircuitCode.Code, proxyEP);
}
}
PacketServer.AddNewClient(userEP, useCircuit, m_assetCache, m_authenticateSessionsClass, proxyEP);
}
}
}

View File

@ -111,6 +111,8 @@ namespace OpenSim.Region.Communications.OGS1
GridParams["http_port"] = serversInfo.HttpListenerPort.ToString();
GridParams["remoting_port"] = NetworkServersInfo.RemotingListenerPort.ToString();
GridParams["map-image-id"] = regionInfo.EstateSettings.terrainImageID.ToString();
GridParams["originUUID"] = regionInfo.originRegionID.ToString();
GridParams["server_uri"] = regionInfo.ServerURI;
// part of an initial brutish effort to provide accurate information (as per the xml region spec)
// wrt the ownership of a given region
@ -165,9 +167,32 @@ namespace OpenSim.Region.Communications.OGS1
public bool DeregisterRegion(RegionInfo regionInfo)
{
Hashtable GridParams = new Hashtable();
GridParams["UUID"] = regionInfo.RegionID.ToString();
// Package into an XMLRPC Request
ArrayList SendParams = new ArrayList();
SendParams.Add(GridParams);
// Send Request
XmlRpcRequest GridReq = new XmlRpcRequest("simulator_after_region_moved", SendParams);
XmlRpcResponse GridResp = GridReq.Send(serversInfo.GridURL, 10000);
Hashtable GridRespData = (Hashtable) GridResp.Value;
Hashtable griddatahash = GridRespData;
// Process Response
if (GridRespData.ContainsKey("error")) {
string errorstring = (string)GridRespData["error"];
m_log.Error("Unable to connect to grid: " + errorstring);
return false;
}
// What does DeregisterRegion() do?
return m_localBackend.DeregisterRegion(regionInfo);
}
public virtual Dictionary<string, string> GetGridSettings()
{
Dictionary<string, string> returnGridSettings = new Dictionary<string, string>();
@ -1209,7 +1234,6 @@ namespace OpenSim.Region.Communications.OGS1
}
return m_localBackend.TriggerRegionUp(new RegionInfo(regionData), regionhandle);
}
catch (RemotingException e)

View File

@ -26,13 +26,16 @@
*
*/
using System;
using libsecondlife;
using libsecondlife.Packets;
using OpenSim.Framework;
using System.Runtime.Serialization;
using System.Security.Permissions;
namespace OpenSim.Region.Environment.Scenes
{
public class AvatarAppearance
[Serializable]
public class AvatarAppearance : ISerializable
{
protected LLUUID m_scenePresenceID;
@ -149,5 +152,45 @@ namespace OpenSim.Region.Environment.Scenes
textu.CreateFace(6).TextureID = new LLUUID("00000000-0000-1111-9999-000000000011");
return textu;
}
protected AvatarAppearance(SerializationInfo info, StreamingContext context)
{
//System.Console.WriteLine("AvatarAppearance Deserialize BGN");
if (info == null)
{
throw new System.ArgumentNullException("info");
}
m_scenePresenceID = new LLUUID((Guid)info.GetValue("m_scenePresenceID", typeof(Guid)));
m_wearablesSerial = (int)info.GetValue("m_wearablesSerial", typeof(int));
m_visualParams = (byte[])info.GetValue("m_visualParams", typeof(byte[]));
m_wearables = (AvatarWearable[])info.GetValue("m_wearables", typeof(AvatarWearable[]));
byte[] m_textureEntry_work = (byte[])info.GetValue("m_textureEntry", typeof(byte[]));
m_textureEntry = new LLObject.TextureEntry(m_textureEntry_work, 0, m_textureEntry_work.Length);
m_avatarHeight = (float)info.GetValue("m_avatarHeight", typeof(float));
//System.Console.WriteLine("AvatarAppearance Deserialize END");
}
[SecurityPermission(SecurityAction.LinkDemand,
Flags = SecurityPermissionFlag.SerializationFormatter)]
public virtual void GetObjectData(
SerializationInfo info, StreamingContext context)
{
if (info == null)
{
throw new System.ArgumentNullException("info");
}
info.AddValue("m_scenePresenceID", m_scenePresenceID.UUID);
info.AddValue("m_wearablesSerial", m_wearablesSerial);
info.AddValue("m_visualParams", m_visualParams);
info.AddValue("m_wearables", m_wearables);
info.AddValue("m_textureEntry", m_textureEntry.ToBytes());
info.AddValue("m_avatarHeight", m_avatarHeight);
}
}
}

View File

@ -30,9 +30,14 @@ using System.Collections.Generic;
using Axiom.Math;
using libsecondlife;
using System;
using System.Runtime.Serialization;
using System.Security.Permissions;
namespace OpenSim.Region.Environment.Scenes
{
public abstract class EntityBase
[Serializable]
public abstract class EntityBase : ISerializable
{
protected Scene m_scene;
@ -134,6 +139,90 @@ namespace OpenSim.Region.Environment.Scenes
public abstract void SetText(string text, Vector3 color, double alpha);
protected EntityBase(SerializationInfo info, StreamingContext context)
{
//System.Console.WriteLine("EntityBase Deserialize BGN");
if (info == null)
{
throw new System.ArgumentNullException("info");
}
//JB m_children = (List<EntityBase>)info.GetValue("m_children", typeof(List<EntityBase>));
// m_scene = (Scene)info.GetValue("m_scene", typeof(Scene));
m_uuid = new LLUUID((Guid)info.GetValue("m_uuid", typeof(Guid)));
m_name = (string)info.GetValue("m_name", typeof(string));
m_pos
= new LLVector3(
(float)info.GetValue("m_pos.X", typeof(float)),
(float)info.GetValue("m_pos.Y", typeof(float)),
(float)info.GetValue("m_pos.Z", typeof(float)));
m_velocity
= new LLVector3(
(float)info.GetValue("m_velocity.X", typeof(float)),
(float)info.GetValue("m_velocity.Y", typeof(float)),
(float)info.GetValue("m_velocity.Z", typeof(float)));
m_rotationalvelocity
= new LLVector3(
(float)info.GetValue("m_rotationalvelocity.X", typeof(float)),
(float)info.GetValue("m_rotationalvelocity.Y", typeof(float)),
(float)info.GetValue("m_rotationalvelocity.Z", typeof(float)));
m_rotation
= new Quaternion(
(float)info.GetValue("m_rotation.w", typeof(float)),
(float)info.GetValue("m_rotation.x", typeof(float)),
(float)info.GetValue("m_rotation.y", typeof(float)),
(float)info.GetValue("m_rotation.z", typeof(float)));
m_localId = (uint)info.GetValue("m_localId", typeof(uint));
//System.Console.WriteLine("EntityBase Deserialize END");
}
[SecurityPermission(SecurityAction.LinkDemand,
Flags = SecurityPermissionFlag.SerializationFormatter)]
public virtual void GetObjectData(
SerializationInfo info, StreamingContext context)
{
if (info == null)
{
throw new System.ArgumentNullException("info");
}
//JB info.AddValue("m_children", m_children);
// info.AddValue("m_scene", m_scene);
info.AddValue("m_uuid", m_uuid.UUID);
info.AddValue("m_name", m_name);
// LLVector3
info.AddValue("m_pos.X", m_pos.X);
info.AddValue("m_pos.Y", m_pos.Y);
info.AddValue("m_pos.Z", m_pos.Z);
// LLVector3
info.AddValue("m_velocity.X", m_velocity.X);
info.AddValue("m_velocity.Y", m_velocity.Y);
info.AddValue("m_velocity.Z", m_velocity.Z);
// LLVector3
info.AddValue("m_rotationalvelocity.X", m_rotationalvelocity.X);
info.AddValue("m_rotationalvelocity.Y", m_rotationalvelocity.Y);
info.AddValue("m_rotationalvelocity.Z", m_rotationalvelocity.Z);
// Quaternion
info.AddValue("m_rotation.w", m_rotation.w);
info.AddValue("m_rotation.x", m_rotation.x);
info.AddValue("m_rotation.y", m_rotation.y);
info.AddValue("m_rotation.z", m_rotation.z);
info.AddValue("m_localId", m_localId);
}
}
//Nested Classes

View File

@ -57,6 +57,7 @@ namespace OpenSim.Region.Environment.Scenes
// SceneObjects is not currently populated or used.
//public Dictionary<LLUUID, SceneObjectGroup> SceneObjects;
public Dictionary<LLUUID, EntityBase> Entities;
public Dictionary<LLUUID, ScenePresence> RestorePresences;
public BasicQuadTreeNode QuadTree;
@ -455,6 +456,48 @@ namespace OpenSim.Region.Environment.Scenes
return newAvatar;
}
public void AddScenePresence(ScenePresence presence)
{
bool child = presence.IsChildAgent;
if (child)
{
m_numChildAgents++;
m_log.Info("[SCENE]"+ m_regInfo.RegionName + ": Creating new child agent.");
}
else
{
m_numRootAgents++;
m_log.Info("[SCENE] "+ m_regInfo.RegionName + ": Creating new root agent.");
m_log.Info("[SCENE] "+ m_regInfo.RegionName + ": Adding Physical agent.");
presence.AddToPhysicalScene();
}
lock (Entities)
{
if (!Entities.ContainsKey(presence.m_uuid))
{
Entities.Add(presence.m_uuid, presence);
}
else
{
Entities[presence.m_uuid] = presence;
}
}
lock (ScenePresences)
{
if (ScenePresences.ContainsKey(presence.m_uuid))
{
ScenePresences[presence.m_uuid] = presence;
}
else
{
ScenePresences.Add(presence.m_uuid, presence);
}
}
}
public void SwapRootChildAgent(bool direction_RC_CR_T_F)
{
if (direction_RC_CR_T_F)

View File

@ -54,6 +54,10 @@ namespace OpenSim.Region.Environment.Scenes
public partial class Scene : SceneBase
{
public delegate void SynchronizeSceneHandler(Scene scene);
public SynchronizeSceneHandler SynchronizeScene = null;
public int splitID = 0;
#region Fields
protected Timer m_heartbeatTimer = new Timer();
@ -216,7 +220,11 @@ namespace OpenSim.Region.Environment.Scenes
get { return m_innerScene.Entities; }
set { m_innerScene.Entities = value; }
}
public Dictionary<LLUUID, ScenePresence> m_restorePresences
{
get { return m_innerScene.RestorePresences; }
set { m_innerScene.RestorePresences = value; }
}
#endregion
#region Constructors
@ -276,6 +284,7 @@ namespace OpenSim.Region.Environment.Scenes
Entities = new Dictionary<LLUUID, EntityBase>();
m_scenePresences = new Dictionary<LLUUID, ScenePresence>();
//m_sceneObjects = new Dictionary<LLUUID, SceneObjectGroup>();
m_restorePresences = new Dictionary<LLUUID, ScenePresence>();
m_log.Info("[SCENE]: Creating LandMap");
Terrain = new TerrainEngine((int)RegionInfo.RegionLocX, (int)RegionInfo.RegionLocY);
@ -701,6 +710,8 @@ namespace OpenSim.Region.Environment.Scenes
physicsFPS = m_innerScene.UpdatePhysics(
Math.Max(SinceLastFrame.TotalSeconds, m_timespan)
);
if (m_frame % m_update_physics == 0 && SynchronizeScene != null)
SynchronizeScene(this);
physicsMS = System.Environment.TickCount - physicsMS;
physicsMS += physicsMS2;
@ -719,6 +730,8 @@ namespace OpenSim.Region.Environment.Scenes
if (m_frame % m_update_presences == 0)
m_innerScene.UpdatePresences();
if (Region_Status != RegionStatus.SlaveScene)
{
if (m_frame % m_update_events == 0)
UpdateEvents();
@ -747,7 +760,7 @@ namespace OpenSim.Region.Environment.Scenes
m_statsReporter.addOtherMS(otherMS);
m_statsReporter.SetActiveScripts(m_innerScene.GetActiveScripts());
m_statsReporter.addScriptLines(m_innerScene.GetScriptLPS());
}
}
catch (NotImplementedException)
{
@ -1058,10 +1071,10 @@ namespace OpenSim.Region.Environment.Scenes
#region Load Land
public void loadAllLandObjectsFromStorage()
public void loadAllLandObjectsFromStorage(LLUUID regionID)
{
m_log.Info("[SCENE]: Loading land objects from storage");
List<LandData> landData = m_storageManager.DataStore.LoadLandObjects(RegionInfo.RegionID);
List<LandData> landData = m_storageManager.DataStore.LoadLandObjects(regionID);
if (landData.Count == 0)
{
@ -1080,11 +1093,11 @@ namespace OpenSim.Region.Environment.Scenes
/// <summary>
/// Loads the World's objects
/// </summary>
public virtual void LoadPrimsFromStorage(bool m_permissions)
public virtual void LoadPrimsFromStorage(bool m_permissions, LLUUID regionID)
{
m_log.Info("[SCENE]: Loading objects from datastore");
List<SceneObjectGroup> PrimsFromDB = m_storageManager.DataStore.LoadObjects(m_regInfo.RegionID);
List<SceneObjectGroup> PrimsFromDB = m_storageManager.DataStore.LoadObjects(regionID);
foreach (SceneObjectGroup group in PrimsFromDB)
{
AddEntityFromStorage(group);
@ -1339,6 +1352,27 @@ namespace OpenSim.Region.Environment.Scenes
{
m_log.Warn("[CONNECTION DEBUGGING]: Creating new client for " + client.AgentId.ToString());
SubscribeToClientEvents(client);
ScenePresence presence = null;
if (m_restorePresences.ContainsKey(client.AgentId))
{
m_log.Info("REGION Restore Scene Presence");
presence = m_restorePresences[client.AgentId];
m_restorePresences.Remove(client.AgentId);
presence.initializeScenePresence(client, RegionInfo, this);
m_innerScene.AddScenePresence(presence);
lock (m_restorePresences)
{
Monitor.PulseAll(m_restorePresences);
}
}
else
{
m_log.Info("REGION Add New Scene Presence");
m_estateManager.sendRegionHandshake(client);
@ -1347,6 +1381,7 @@ namespace OpenSim.Region.Environment.Scenes
m_LandManager.sendParcelOverlay(client);
CommsManager.UserProfileCacheService.AddNewUser(client.AgentId);
}
}
protected virtual void SubscribeToClientEvents(IClientAPI client)
{

View File

@ -39,6 +39,8 @@ using OpenSim.Framework.Console;
using OpenSim.Region.Environment.Interfaces;
using OpenSim.Region.Environment.Scenes.Scripting;
using OpenSim.Region.Physics.Manager;
using System.Runtime.Serialization;
using System.Security.Permissions;
namespace OpenSim.Region.Environment.Scenes
{
@ -82,7 +84,8 @@ namespace OpenSim.Region.Environment.Scenes
SCALE = 0x40
}
public partial class SceneObjectPart : IScriptHost
[Serializable]
public partial class SceneObjectPart : IScriptHost, ISerializable
{
[XmlIgnore] public PhysicsActor PhysActor = null;
@ -1859,5 +1862,119 @@ namespace OpenSim.Region.Environment.Scenes
(int) (color.z*0xff));
Text = text;
}
protected SceneObjectPart(SerializationInfo info, StreamingContext context)
{
//System.Console.WriteLine("SceneObjectPart Deserialize BGN");
if (info == null)
{
throw new System.ArgumentNullException("info");
}
/*
m_queue = (Queue<SceneObjectPart>)info.GetValue("m_queue", typeof(Queue<SceneObjectPart>));
m_ids = (List<LLUUID>)info.GetValue("m_ids", typeof(List<LLUUID>));
*/
//System.Console.WriteLine("SceneObjectPart Deserialize END");
}
[SecurityPermission(SecurityAction.LinkDemand,
Flags = SecurityPermissionFlag.SerializationFormatter)]
public virtual void GetObjectData(
SerializationInfo info, StreamingContext context)
{
if (info == null)
{
throw new System.ArgumentNullException("info");
}
info.AddValue("m_inventoryFileName", m_inventoryFileName);
info.AddValue("m_folderID", m_folderID.UUID);
info.AddValue("PhysActor", PhysActor);
Dictionary<Guid, TaskInventoryItem> TaskInventory_work = new Dictionary<Guid, TaskInventoryItem>();
foreach (LLUUID id in TaskInventory.Keys)
{
TaskInventory_work.Add(id.UUID, TaskInventory[id]);
}
info.AddValue("TaskInventory", TaskInventory_work);
info.AddValue("LastOwnerID", LastOwnerID.UUID);
info.AddValue("OwnerID", OwnerID.UUID);
info.AddValue("GroupID", GroupID.UUID);
info.AddValue("OwnershipCost", OwnershipCost);
info.AddValue("ObjectSaleType", ObjectSaleType);
info.AddValue("SalePrice", SalePrice);
info.AddValue("Category", Category);
info.AddValue("CreationDate", CreationDate);
info.AddValue("ParentID", ParentID);
info.AddValue("OwnerMask", OwnerMask);
info.AddValue("NextOwnerMask", NextOwnerMask);
info.AddValue("GroupMask", GroupMask);
info.AddValue("EveryoneMask", EveryoneMask);
info.AddValue("BaseMask", BaseMask);
info.AddValue("m_particleSystem", m_particleSystem);
info.AddValue("TimeStampFull", TimeStampFull);
info.AddValue("TimeStampTerse", TimeStampTerse);
info.AddValue("TimeStampLastActivity", TimeStampLastActivity);
info.AddValue("m_updateFlag", m_updateFlag);
info.AddValue("CreatorID", CreatorID.UUID);
info.AddValue("m_inventorySerial", m_inventorySerial);
info.AddValue("m_uuid", m_uuid.UUID);
info.AddValue("m_localID", m_localID);
info.AddValue("m_name", m_name);
info.AddValue("m_flags", Flags);
info.AddValue("m_material", m_material);
info.AddValue("m_regionHandle", m_regionHandle);
info.AddValue("m_groupPosition.X", m_groupPosition.X);
info.AddValue("m_groupPosition.Y", m_groupPosition.Y);
info.AddValue("m_groupPosition.Z", m_groupPosition.Z);
info.AddValue("m_offsetPosition.X", m_offsetPosition.X);
info.AddValue("m_offsetPosition.Y", m_offsetPosition.Y);
info.AddValue("m_offsetPosition.Z", m_offsetPosition.Z);
info.AddValue("m_rotationOffset.W", m_rotationOffset.W);
info.AddValue("m_rotationOffset.X", m_rotationOffset.X);
info.AddValue("m_rotationOffset.Y", m_rotationOffset.Y);
info.AddValue("m_rotationOffset.Z", m_rotationOffset.Z);
info.AddValue("m_velocity.X", m_velocity.X);
info.AddValue("m_velocity.Y", m_velocity.Y);
info.AddValue("m_velocity.Z", m_velocity.Z);
info.AddValue("m_rotationalvelocity.X", m_rotationalvelocity.X);
info.AddValue("m_rotationalvelocity.Y", m_rotationalvelocity.Y);
info.AddValue("m_rotationalvelocity.Z", m_rotationalvelocity.Z);
info.AddValue("m_angularVelocity.X", m_angularVelocity.X);
info.AddValue("m_angularVelocity.Y", m_angularVelocity.Y);
info.AddValue("m_angularVelocity.Z", m_angularVelocity.Z);
info.AddValue("m_acceleration.X", m_acceleration.X);
info.AddValue("m_acceleration.Y", m_acceleration.Y);
info.AddValue("m_acceleration.Z", m_acceleration.Z);
info.AddValue("m_description", m_description);
info.AddValue("m_color", m_color);
info.AddValue("m_text", m_text);
info.AddValue("m_sitName", m_sitName);
info.AddValue("m_touchName", m_touchName);
info.AddValue("m_clickAction", m_clickAction);
info.AddValue("m_shape", m_shape);
info.AddValue("m_parentGroup", m_parentGroup);
}
}
}

View File

@ -34,10 +34,14 @@ using OpenSim.Framework;
using OpenSim.Framework.Console;
using OpenSim.Region.Environment.Types;
using OpenSim.Region.Physics.Manager;
using OpenSim.Region.Environment.Interfaces;
using System.Runtime.Serialization;
using System.Security.Permissions;
namespace OpenSim.Region.Environment.Scenes
{
public class ScenePresence : EntityBase
[Serializable]
public class ScenePresence : EntityBase, ISerializable
{
// ~ScenePresence()
// {
@ -156,6 +160,12 @@ namespace OpenSim.Region.Environment.Scenes
get { return m_physicsActor; }
}
public byte MovementFlag
{
set { m_movementflag = value; }
get { return m_movementflag; }
}
public bool KnownPrim(LLUUID primID)
{
if (m_knownPrimUUID.Contains(primID))
@ -215,13 +225,14 @@ namespace OpenSim.Region.Environment.Scenes
/// <summary>
/// This works out to be the ClientView object associated with this avatar, or it's UDP connection manager
/// </summary>
private readonly IClientAPI m_controllingClient;
private IClientAPI m_controllingClient;
protected PhysicsActor m_physicsActor;
public IClientAPI ControllingClient
{
get { return m_controllingClient; }
set { m_controllingClient = value; }
}
protected LLVector3 m_parentPosition = new LLVector3();
@ -379,7 +390,7 @@ namespace OpenSim.Region.Environment.Scenes
m_appearance = appearance;
}
private void RegisterToEvents()
public void RegisterToEvents()
{
m_controllingClient.OnRequestWearables += SendOwnAppearance;
m_controllingClient.OnSetAppearance += SetAppearance;
@ -1706,6 +1717,7 @@ namespace OpenSim.Region.Environment.Scenes
DefaultTexture = textu.ToBytes();
}
[Serializable]
public class NewForce
{
public float X;
@ -1717,7 +1729,8 @@ namespace OpenSim.Region.Environment.Scenes
}
}
public class ScenePartUpdate
[Serializable]
public class ScenePartUpdate : ISerializable
{
public LLUUID FullID;
public uint LastFullUpdateTime;
@ -1729,6 +1742,38 @@ namespace OpenSim.Region.Environment.Scenes
LastFullUpdateTime = 0;
LastTerseUpdateTime = 0;
}
protected ScenePartUpdate(SerializationInfo info, StreamingContext context)
{
//System.Console.WriteLine("ScenePartUpdate Deserialize BGN");
if (info == null)
{
throw new System.ArgumentNullException("info");
}
FullID = new LLUUID((Guid)info.GetValue("FullID", typeof(Guid)));
LastFullUpdateTime = (uint)info.GetValue("LastFullUpdateTime", typeof(uint));
LastTerseUpdateTime = (uint)info.GetValue("LastTerseUpdateTime", typeof(uint));
//System.Console.WriteLine("ScenePartUpdate Deserialize END");
}
[SecurityPermission(SecurityAction.LinkDemand,
Flags = SecurityPermissionFlag.SerializationFormatter)]
public virtual void GetObjectData(
SerializationInfo info, StreamingContext context)
{
if (info == null)
{
throw new System.ArgumentNullException("info");
}
info.AddValue("FullID", FullID.UUID);
info.AddValue("LastFullUpdateTime", LastFullUpdateTime);
info.AddValue("LastTerseUpdateTime", LastTerseUpdateTime);
}
}
public override void SetText(string text, Vector3 color, double alpha)
@ -1787,5 +1832,368 @@ namespace OpenSim.Region.Environment.Scenes
RemoveFromPhysicalScene();
GC.Collect();
}
public ScenePresence()
{
/* JB
if (Animations == null)
{
Animations = new AvatarAnimations();
Animations.LoadAnims();
}
*/
if (DefaultTexture == null)
{
LLObject.TextureEntry textu = AvatarAppearance.GetDefaultTextureEntry();
DefaultTexture = textu.ToBytes();
}
}
public void initializeScenePresence(IClientAPI client, RegionInfo region, Scene scene)
{
m_controllingClient = client;
m_regionInfo = region;
m_scene = scene;
RegisterToEvents();
/*
AbsolutePosition = client.StartPos;
Animations = new AvatarAnimations();
Animations.LoadAnims();
m_animations = new List<LLUUID>();
m_animations.Add(Animations.AnimsLLUUID["STAND"]);
m_animationSeqs.Add(1);
SetDirectionVectors();
*/
}
protected ScenePresence(SerializationInfo info, StreamingContext context)
: base (info, context)
{
//System.Console.WriteLine("ScenePresence Deserialize BGN");
if (info == null)
{
throw new System.ArgumentNullException("info");
}
/* JB
if (Animations == null)
{
Animations = new AvatarAnimations();
Animations.LoadAnims();
}
*/
if (DefaultTexture == null)
{
LLObject.TextureEntry textu = AvatarAppearance.GetDefaultTextureEntry();
DefaultTexture = textu.ToBytes();
}
List<Guid> animations_work = (List<Guid>)info.GetValue("m_animations", typeof(List<Guid>));
foreach (Guid guid in animations_work)
{
m_animations.Add(new LLUUID(guid));
}
m_animationSeqs = (List<int>)info.GetValue("m_animationSeqs", typeof(List<int>));
m_updateflag = (bool)info.GetValue("m_updateflag", typeof(bool));
m_movementflag = (byte)info.GetValue("m_movementflag", typeof(byte));
m_forcesList = (List<NewForce>)info.GetValue("m_forcesList", typeof(List<NewForce>));
m_updateCount = (short)info.GetValue("m_updateCount", typeof(short));
m_requestedSitTargetID = (uint)info.GetValue("m_requestedSitTargetID", typeof(uint));
m_requestedSitOffset
= new LLVector3(
(float)info.GetValue("m_requestedSitOffset.X", typeof(float)),
(float)info.GetValue("m_requestedSitOffset.Y", typeof(float)),
(float)info.GetValue("m_requestedSitOffset.Z", typeof(float)));
m_sitAvatarHeight = (float)info.GetValue("m_sitAvatarHeight", typeof(float));
m_godlevel = (float)info.GetValue("m_godlevel", typeof(float));
m_setAlwaysRun = (bool)info.GetValue("m_setAlwaysRun", typeof(bool));
m_bodyRot
= new Quaternion(
(float)info.GetValue("m_bodyRot.w", typeof(float)),
(float)info.GetValue("m_bodyRot.x", typeof(float)),
(float)info.GetValue("m_bodyRot.y", typeof(float)),
(float)info.GetValue("m_bodyRot.z", typeof(float)));
IsRestrictedToRegion = (bool)info.GetValue("IsRestrictedToRegion", typeof(bool));
m_newForce = (bool)info.GetValue("m_newForce", typeof(bool));
//m_newAvatar = (bool)info.GetValue("m_newAvatar", typeof(bool));
m_newCoarseLocations = (bool)info.GetValue("m_newCoarseLocations", typeof(bool));
m_gotAllObjectsInScene = (bool)info.GetValue("m_gotAllObjectsInScene", typeof(bool));
m_avHeight = (float)info.GetValue("m_avHeight", typeof(float));
crossingFromRegion = (ulong)info.GetValue("crossingFromRegion", typeof(ulong));
List<float[]> Dir_Vectors_work = (List<float[]>)info.GetValue("Dir_Vectors", typeof(List<float[]>));
List<Vector3> Dir_Vectors_work2 = new List<Vector3>();
foreach (float[] f3 in Dir_Vectors_work)
{
Dir_Vectors_work2.Add(new Vector3(f3[0], f3[1], f3[2]));
}
Dir_Vectors = Dir_Vectors_work2.ToArray();
lastPhysPos
= new LLVector3(
(float)info.GetValue("lastPhysPos.X", typeof(float)),
(float)info.GetValue("lastPhysPos.Y", typeof(float)),
(float)info.GetValue("lastPhysPos.Z", typeof(float)));
m_CameraCenter
= new Vector3(
(float)info.GetValue("m_CameraCenter.X", typeof(float)),
(float)info.GetValue("m_CameraCenter.Y", typeof(float)),
(float)info.GetValue("m_CameraCenter.Z", typeof(float)));
m_CameraAtAxis
= new Vector3(
(float)info.GetValue("m_CameraAtAxis.X", typeof(float)),
(float)info.GetValue("m_CameraAtAxis.Y", typeof(float)),
(float)info.GetValue("m_CameraAtAxis.Z", typeof(float)));
m_CameraLeftAxis
= new Vector3(
(float)info.GetValue("m_CameraLeftAxis.X", typeof(float)),
(float)info.GetValue("m_CameraLeftAxis.Y", typeof(float)),
(float)info.GetValue("m_CameraLeftAxis.Z", typeof(float)));
m_CameraUpAxis
= new Vector3(
(float)info.GetValue("m_CameraUpAxis.X", typeof(float)),
(float)info.GetValue("m_CameraUpAxis.Y", typeof(float)),
(float)info.GetValue("m_CameraUpAxis.Z", typeof(float)));
m_DrawDistance = (float)info.GetValue("m_DrawDistance", typeof(float));
m_appearance = (AvatarAppearance)info.GetValue("m_appearance", typeof(AvatarAppearance));
m_knownChildRegions = (List<ulong>)info.GetValue("m_knownChildRegions", typeof(List<ulong>));
posLastSignificantMove
= new LLVector3(
(float)info.GetValue("posLastSignificantMove.X", typeof(float)),
(float)info.GetValue("posLastSignificantMove.Y", typeof(float)),
(float)info.GetValue("posLastSignificantMove.Z", typeof(float)));
// m_partsUpdateQueue = (UpdateQueue)info.GetValue("m_partsUpdateQueue", typeof(UpdateQueue));
/*
Dictionary<Guid, ScenePartUpdate> updateTimes_work
= (Dictionary<Guid, ScenePartUpdate>)info.GetValue("m_updateTimes", typeof(Dictionary<Guid, ScenePartUpdate>));
foreach (Guid id in updateTimes_work.Keys)
{
m_updateTimes.Add(new LLUUID(id), updateTimes_work[id]);
}
*/
m_regionHandle = (ulong)info.GetValue("m_regionHandle", typeof(ulong));
m_firstname = (string)info.GetValue("m_firstname", typeof(string));
m_lastname = (string)info.GetValue("m_lastname", typeof(string));
m_allowMovement = (bool)info.GetValue("m_allowMovement", typeof(bool));
m_parentPosition = new LLVector3((float)info.GetValue("m_parentPosition.X", typeof(float)),
(float)info.GetValue("m_parentPosition.Y", typeof(float)),
(float)info.GetValue("m_parentPosition.Z", typeof(float)));
m_isChildAgent = (bool)info.GetValue("m_isChildAgent", typeof(bool));
m_parentID = (uint)info.GetValue("m_parentID", typeof(uint));
// for OpenSim_v0.5
currentParcelUUID = new LLUUID((Guid)info.GetValue("currentParcelUUID", typeof(Guid)));
lastKnownAllowedPosition
= new Vector3(
(float)info.GetValue("lastKnownAllowedPosition.X", typeof(float)),
(float)info.GetValue("lastKnownAllowedPosition.Y", typeof(float)),
(float)info.GetValue("lastKnownAllowedPosition.Z", typeof(float)));
sentMessageAboutRestrictedParcelFlyingDown = (bool)info.GetValue("sentMessageAboutRestrictedParcelFlyingDown", typeof(bool));
m_LastChildAgentUpdatePosition
= new LLVector3(
(float)info.GetValue("m_LastChildAgentUpdatePosition.X", typeof(float)),
(float)info.GetValue("m_LastChildAgentUpdatePosition.Y", typeof(float)),
(float)info.GetValue("m_LastChildAgentUpdatePosition.Z", typeof(float)));
m_perfMonMS = (int)info.GetValue("m_perfMonMS", typeof(int));
m_AgentControlFlags = (uint)info.GetValue("m_AgentControlFlags", typeof(uint));
m_headrotation
= new LLQuaternion(
(float)info.GetValue("m_headrotation.W", typeof(float)),
(float)info.GetValue("m_headrotation.X", typeof(float)),
(float)info.GetValue("m_headrotation.Y", typeof(float)),
(float)info.GetValue("m_headrotation.Z", typeof(float)));
m_state = (byte)info.GetValue("m_state", typeof(byte));
List<Guid> knownPrimUUID_work = (List<Guid>)info.GetValue("m_knownPrimUUID", typeof(List<Guid>));
foreach (Guid id in knownPrimUUID_work)
{
m_knownPrimUUID.Add(new LLUUID(id));
}
//System.Console.WriteLine("ScenePresence Deserialize END");
}
[SecurityPermission(SecurityAction.LinkDemand,
Flags = SecurityPermissionFlag.SerializationFormatter)]
public override void GetObjectData(
SerializationInfo info, StreamingContext context)
{
if (info == null)
{
throw new System.ArgumentNullException("info");
}
base.GetObjectData(info, context);
List<Guid> animations_work = new List<Guid>();
foreach (LLUUID uuid in m_animations)
{
animations_work.Add(uuid.UUID);
}
info.AddValue("m_animations", animations_work);
info.AddValue("m_animationSeqs", m_animationSeqs);
info.AddValue("m_updateflag", m_updateflag);
info.AddValue("m_movementflag", m_movementflag);
info.AddValue("m_forcesList", m_forcesList);
info.AddValue("m_updateCount", m_updateCount);
info.AddValue("m_requestedSitTargetID", m_requestedSitTargetID);
// LLVector3
info.AddValue("m_requestedSitOffset.X", m_requestedSitOffset.X);
info.AddValue("m_requestedSitOffset.Y", m_requestedSitOffset.Y);
info.AddValue("m_requestedSitOffset.Z", m_requestedSitOffset.Z);
info.AddValue("m_sitAvatarHeight", m_sitAvatarHeight);
info.AddValue("m_godlevel", m_godlevel);
info.AddValue("m_setAlwaysRun", m_setAlwaysRun);
// Quaternion
info.AddValue("m_bodyRot.w", m_bodyRot.w);
info.AddValue("m_bodyRot.x", m_bodyRot.x);
info.AddValue("m_bodyRot.y", m_bodyRot.y);
info.AddValue("m_bodyRot.z", m_bodyRot.z);
info.AddValue("IsRestrictedToRegion", IsRestrictedToRegion);
info.AddValue("m_newForce", m_newForce);
//info.AddValue("m_newAvatar", m_newAvatar);
info.AddValue("m_newCoarseLocations", m_newCoarseLocations);
info.AddValue("m_gotAllObjectsInScene", m_gotAllObjectsInScene);
info.AddValue("m_avHeight", m_avHeight);
// info.AddValue("m_regionInfo", m_regionInfo);
info.AddValue("crossingFromRegion", crossingFromRegion);
List<float[]> Dir_Vectors_work = new List<float[]>();
foreach (Vector3 v3 in Dir_Vectors)
{
Dir_Vectors_work.Add(new float[] { v3.x, v3.y, v3.z });
}
info.AddValue("Dir_Vectors", Dir_Vectors_work);
// LLVector3
info.AddValue("lastPhysPos.X", lastPhysPos.X);
info.AddValue("lastPhysPos.Y", lastPhysPos.Y);
info.AddValue("lastPhysPos.Z", lastPhysPos.Z);
// Vector3
info.AddValue("m_CameraCenter.X", m_CameraCenter.x);
info.AddValue("m_CameraCenter.Y", m_CameraCenter.y);
info.AddValue("m_CameraCenter.Z", m_CameraCenter.z);
// Vector3
info.AddValue("m_CameraAtAxis.X", m_CameraAtAxis.x);
info.AddValue("m_CameraAtAxis.Y", m_CameraAtAxis.y);
info.AddValue("m_CameraAtAxis.Z", m_CameraAtAxis.z);
// Vector3
info.AddValue("m_CameraLeftAxis.X", m_CameraLeftAxis.x);
info.AddValue("m_CameraLeftAxis.Y", m_CameraLeftAxis.y);
info.AddValue("m_CameraLeftAxis.Z", m_CameraLeftAxis.z);
// Vector3
info.AddValue("m_CameraUpAxis.X", m_CameraUpAxis.x);
info.AddValue("m_CameraUpAxis.Y", m_CameraUpAxis.y);
info.AddValue("m_CameraUpAxis.Z", m_CameraUpAxis.z);
info.AddValue("m_DrawDistance", m_DrawDistance);
info.AddValue("m_appearance", m_appearance);
info.AddValue("m_knownChildRegions", m_knownChildRegions);
// LLVector3
info.AddValue("posLastSignificantMove.X", posLastSignificantMove.X);
info.AddValue("posLastSignificantMove.Y", posLastSignificantMove.Y);
info.AddValue("posLastSignificantMove.Z", posLastSignificantMove.Z);
//info.AddValue("m_partsUpdateQueue", m_partsUpdateQueue);
/*
Dictionary<Guid, ScenePartUpdate> updateTimes_work = new Dictionary<Guid, ScenePartUpdate>();
foreach ( LLUUID id in m_updateTimes.Keys)
{
updateTimes_work.Add(id.UUID, m_updateTimes[id]);
}
info.AddValue("m_updateTimes", updateTimes_work);
*/
info.AddValue("m_regionHandle", m_regionHandle);
info.AddValue("m_firstname", m_firstname);
info.AddValue("m_lastname", m_lastname);
info.AddValue("m_allowMovement", m_allowMovement);
//info.AddValue("m_physicsActor", m_physicsActor);
info.AddValue("m_parentPosition.X", m_parentPosition.X);
info.AddValue("m_parentPosition.Y", m_parentPosition.Y);
info.AddValue("m_parentPosition.Z", m_parentPosition.Z);
info.AddValue("m_isChildAgent", m_isChildAgent);
info.AddValue("m_parentID", m_parentID);
// for OpenSim_v0.5
info.AddValue("currentParcelUUID", currentParcelUUID.UUID);
info.AddValue("lastKnownAllowedPosition.X", lastKnownAllowedPosition.x);
info.AddValue("lastKnownAllowedPosition.Y", lastKnownAllowedPosition.y);
info.AddValue("lastKnownAllowedPosition.Z", lastKnownAllowedPosition.z);
info.AddValue("sentMessageAboutRestrictedParcelFlyingDown", sentMessageAboutRestrictedParcelFlyingDown);
info.AddValue("m_LastChildAgentUpdatePosition.X", m_LastChildAgentUpdatePosition.X);
info.AddValue("m_LastChildAgentUpdatePosition.Y", m_LastChildAgentUpdatePosition.Y);
info.AddValue("m_LastChildAgentUpdatePosition.Z", m_LastChildAgentUpdatePosition.Z);
info.AddValue("m_perfMonMS", m_perfMonMS);
info.AddValue("m_AgentControlFlags", m_AgentControlFlags);
info.AddValue("m_headrotation.W", m_headrotation.W);
info.AddValue("m_headrotation.X", m_headrotation.X);
info.AddValue("m_headrotation.Y", m_headrotation.Y);
info.AddValue("m_headrotation.Z", m_headrotation.Z);
info.AddValue("m_state", m_state);
List<Guid> knownPrimUUID_work = new List<Guid>();
foreach (LLUUID id in m_knownPrimUUID)
{
knownPrimUUID_work.Add(id.UUID);
}
info.AddValue("m_knownPrimUUID", knownPrimUUID_work);
}
}
}

View File

@ -30,9 +30,14 @@ using System.Collections.Generic;
using libsecondlife;
using OpenSim.Region.Environment.Scenes;
using System;
using System.Runtime.Serialization;
using System.Security.Permissions;
namespace OpenSim.Region.Environment.Types
{
public class UpdateQueue
[Serializable]
public class UpdateQueue : ISerializable
{
private Queue<SceneObjectPart> m_queue;
@ -86,5 +91,46 @@ namespace OpenSim.Region.Environment.Types
return part;
}
protected UpdateQueue(SerializationInfo info, StreamingContext context)
{
//System.Console.WriteLine("UpdateQueue Deserialize BGN");
if (info == null)
{
throw new System.ArgumentNullException("info");
}
m_queue = (Queue<SceneObjectPart>)info.GetValue("m_queue", typeof(Queue<SceneObjectPart>));
List<Guid> ids_work = (List<Guid>)info.GetValue("m_ids", typeof(List<Guid>));
foreach (Guid guid in ids_work)
{
m_ids.Add(new LLUUID(guid));
}
//System.Console.WriteLine("UpdateQueue Deserialize END");
}
[SecurityPermission(SecurityAction.LinkDemand,
Flags = SecurityPermissionFlag.SerializationFormatter)]
public virtual void GetObjectData(
SerializationInfo info, StreamingContext context)
{
if (info == null)
{
throw new System.ArgumentNullException("info");
}
List<Guid> ids_work = new List<Guid>();
foreach (LLUUID uuid in m_ids)
{
ids_work.Add(uuid.UUID);
}
info.AddValue("m_queue", m_queue);
info.AddValue("m_ids", ids_work);
}
}
}

View File

@ -538,5 +538,18 @@ namespace SimpleApp
public void SendLogoutPacket()
{
}
public void Terminate()
{
}
public ClientInfo GetClientInfo()
{
return null;
}
public void SetClientInfo(ClientInfo info)
{
}
}
}

File diff suppressed because it is too large Load Diff

240
ThirdParty/3Di/LoadBalancer/TcpClient.cs vendored Normal file
View File

@ -0,0 +1,240 @@
/*
* 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.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Text;
using System.Runtime.Serialization.Formatters.Binary;
namespace OpenSim.ApplicationPlugins.LoadBalancer {
public class AsynchronousClient {
private static ManualResetEvent connectDone = new ManualResetEvent(false);
private static ManualResetEvent sendDone = new ManualResetEvent(false);
private static ManualResetEvent receiveDone = new ManualResetEvent(false);
private static String response = String.Empty;
public static Socket StartClient(string hostname, int port) {
try {
IPHostEntry ipHostInfo = Dns.GetHostEntry(hostname);
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
client.BeginConnect( remoteEP, new AsyncCallback(ConnectCallback), client);
connectDone.WaitOne();
/*
Send(client,"This is a test<EOF>");
sendDone.WaitOne();
Receive(client);
receiveDone.WaitOne();
client.Shutdown(SocketShutdown.Both);
client.Close();
*/
return client;
} catch (Exception e) {
Console.WriteLine(e.ToString());
throw new Exception("socket error !!");
}
}
private static void ConnectCallback(IAsyncResult ar) {
try {
Socket client = (Socket) ar.AsyncState;
client.EndConnect(ar);
Console.WriteLine("Socket connected to {0}", client.RemoteEndPoint.ToString());
connectDone.Set();
} catch (Exception e) {
Console.WriteLine(e.ToString());
}
}
/*
public static void Receive(Socket client) {
try {
StateObject state = new StateObject();
state.workSocket = client;
client.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
} catch (Exception e) {
Console.WriteLine(e.ToString());
}
}
private static void ReceiveCallback( IAsyncResult ar ) {
try {
StateObject state = (StateObject) ar.AsyncState;
Socket client = state.workSocket;
int bytesRead = client.EndReceive(ar);
if (bytesRead > 0) {
state.sb.Append(Encoding.ASCII.GetString(state.buffer,0,bytesRead));
client.BeginReceive(state.buffer,0,StateObject.BufferSize,0, new AsyncCallback(ReceiveCallback), state);
} else {
if (state.sb.Length > 1) {
response = state.sb.ToString();
}
receiveDone.Set();
}
} catch (Exception e) {
Console.WriteLine(e.ToString());
}
}
*/
public static void Send(Socket client, byte[] byteData) {
client.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), client);
}
private static void SendCallback(IAsyncResult ar) {
try {
Socket client = (Socket) ar.AsyncState;
int bytesSent = client.EndSend(ar);
//Console.WriteLine("Sent {0} bytes to server.", bytesSent);
sendDone.Set();
} catch (Exception e) {
Console.WriteLine(e.ToString());
}
}
}
public class InternalPacketHeader
{
private byte[] buffer = new byte[32];
public int type;
public int throttlePacketType;
public int numbytes;
public Guid agent_id;
public int region_port;
public void FromBytes(byte[] bytes)
{
int i = 0; // offset
try
{
this.type = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
this.throttlePacketType = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
this.numbytes = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
this.agent_id = new Guid(
bytes[i++] | (bytes[i++] << 8) | (bytes[i++] << 16) | bytes[i++] << 24,
(short)(bytes[i++] | (bytes[i++] << 8)),
(short)(bytes[i++] | (bytes[i++] << 8)),
bytes[i++], bytes[i++], bytes[i++], bytes[i++],
bytes[i++], bytes[i++], bytes[i++], bytes[i++]);
this.region_port = (int)(bytes[i++] + (bytes[i++] << 8) + (bytes[i++] << 16) + (bytes[i++] << 24));
}
catch (Exception)
{
throw new Exception("bad format!!!");
}
}
public byte[] ToBytes()
{
int i = 0;
this.buffer[i++] = (byte)(this.type % 256);
this.buffer[i++] = (byte)((this.type >> 8) % 256);
this.buffer[i++] = (byte)((this.type >> 16) % 256);
this.buffer[i++] = (byte)((this.type >> 24) % 256);
this.buffer[i++] = (byte)(this.throttlePacketType % 256);
this.buffer[i++] = (byte)((this.throttlePacketType >> 8) % 256);
this.buffer[i++] = (byte)((this.throttlePacketType >> 16) % 256);
this.buffer[i++] = (byte)((this.throttlePacketType >> 24) % 256);
this.buffer[i++] = (byte)(this.numbytes % 256);
this.buffer[i++] = (byte)((this.numbytes >> 8) % 256);
this.buffer[i++] = (byte)((this.numbytes >> 16) % 256);
this.buffer[i++] = (byte)((this.numbytes >> 24) % 256);
// no endian care
Buffer.BlockCopy(agent_id.ToByteArray(), 0, this.buffer, i, 16); i += 16;
this.buffer[i++] = (byte)(this.region_port % 256);
this.buffer[i++] = (byte)((this.region_port >> 8) % 256);
this.buffer[i++] = (byte)((this.region_port >> 16) % 256);
this.buffer[i++] = (byte)((this.region_port >> 24) % 256);
return this.buffer;
}
}
public class TcpClient {
public static int internalPacketHeaderSize = 4*4 + 16*1;
private string mHostname;
private int mPort;
private Socket mConnection;
public TcpClient(string hostname, int port) {
this.mHostname = hostname;
this.mPort = port;
this.mConnection = null;
}
public void connect() {
this.mConnection = AsynchronousClient.StartClient(mHostname, mPort);
}
/*
public void recevie() {
if (mConnection == null) {
throw new Exception("client not initialized");
}
try
{
AsynchronousClient.Receive(this.mConnection);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
mConnection = null;
}
}
*/
public void send(InternalPacketHeader header, byte[] packet) {
lock (this)
{
if (mConnection == null) {
// throw new Exception("client not initialized");
connect();
}
AsynchronousClient.Send(this.mConnection, header.ToBytes());
/*
for (int i = 0; i < 10; i++)
{
Console.Write(packet[i] + " ");
}
Console.WriteLine("");
*/
AsynchronousClient.Send(this.mConnection, packet);
}
}
}
}

219
ThirdParty/3Di/LoadBalancer/TcpServer.cs vendored Normal file
View File

@ -0,0 +1,219 @@
/*
* 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.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Runtime.Serialization.Formatters.Binary;
using OpenSim.Framework.Console;
namespace OpenSim.ApplicationPlugins.LoadBalancer {
public class StateObject {
public Socket workSocket = null;
public const int BufferSize = 2048;
public byte[] buffer = new byte[BufferSize];
public MemoryStream ms_ptr = new MemoryStream();
public InternalPacketHeader header = null;
}
public class AsynchronousSocketListener {
public static string data = null;
public static ManualResetEvent allDone = new ManualResetEvent(false);
#region KIRYU
public delegate void PacketRecieveHandler(InternalPacketHeader header, byte[] buff);
public static PacketRecieveHandler PacketHandler = null;
#endregion
public AsynchronousSocketListener() { }
public static void StartListening(int port) {
IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, port);
Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp );
try {
listener.Bind(localEndPoint);
listener.Listen(100);
while (true) {
allDone.Reset();
listener.BeginAccept( new AsyncCallback(AcceptCallback), listener );
allDone.WaitOne();
}
} catch (Exception e) {
Console.WriteLine(e.ToString());
}
/*
Console.WriteLine("\nPress ENTER to continue...");
Console.Read();
*/
}
public static void AcceptCallback(IAsyncResult ar) {
allDone.Set();
Socket listener = (Socket) ar.AsyncState;
Socket handler = listener.EndAccept(ar);
StateObject state = new StateObject();
state.workSocket = handler;
handler.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
}
public static void ReadCallback(IAsyncResult ar) {
String content = String.Empty;
StateObject state = (StateObject) ar.AsyncState;
Socket handler = state.workSocket;
try
{
int bytesRead = handler.EndReceive(ar);
//MainLog.Instance.Verbose("TCPSERVER", "Received packet [{0}]", bytesRead);
if (bytesRead > 0) {
state.ms_ptr.Write(state.buffer, 0, bytesRead);
}
else
{
//MainLog.Instance.Verbose("TCPSERVER", "Connection terminated");
return;
}
long rest_size = state.ms_ptr.Length;
long current_pos = 0;
while (rest_size > TcpClient.internalPacketHeaderSize) {
if ((state.header == null) && (rest_size >= TcpClient.internalPacketHeaderSize))
{
//MainLog.Instance.Verbose("TCPSERVER", "Processing header");
// reading header
state.header = new InternalPacketHeader();
byte[] headerbytes = new byte[TcpClient.internalPacketHeaderSize];
state.ms_ptr.Position = current_pos;
state.ms_ptr.Read(headerbytes, 0, TcpClient.internalPacketHeaderSize);
state.ms_ptr.Seek(0, SeekOrigin.End);
state.header.FromBytes(headerbytes);
}
if ((state.header != null) && (rest_size >= state.header.numbytes + TcpClient.internalPacketHeaderSize))
{
//MainLog.Instance.Verbose("TCPSERVER", "Processing body");
// reading body
byte[] packet = new byte[state.header.numbytes];
state.ms_ptr.Position = current_pos + TcpClient.internalPacketHeaderSize;
state.ms_ptr.Read(packet, 0, state.header.numbytes);
/*
for(int i=0; i<state.header.numbytes; i++) {
System.Console.Write(packet[i] + " ");
}
System.Console.WriteLine();
*/
state.ms_ptr.Seek(0, SeekOrigin.End);
// call loadbarancer function
if (PacketHandler != null)
{
//MainLog.Instance.Verbose("TCPSERVER", "calling PacketHandler");
PacketHandler(state.header, packet);
}
else
{
//MainLog.Instance.Verbose("TCPSERVER", "PacketHandler not found");
}
int read_size = state.header.numbytes + TcpClient.internalPacketHeaderSize;
state.header = null;
rest_size -= read_size;
current_pos += read_size;
if (rest_size < TcpClient.internalPacketHeaderSize) {
byte[] rest_bytes = new byte[rest_size];
state.ms_ptr.Position = read_size;
state.ms_ptr.Read(rest_bytes, 0, (int)rest_size);
state.ms_ptr.Close();
state.ms_ptr = new MemoryStream();
state.ms_ptr.Write(rest_bytes, 0, (int)rest_size);
break;
}
}
} // while (true)
}
catch (Exception e)
{
//MainLog.Instance.Verbose("TCPSERVER", e.ToString());
//MainLog.Instance.Verbose("TCPSERVER", e.StackTrace);
}
handler.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
}
private static void Send(Socket handler, String data) {
byte[] byteData = Encoding.ASCII.GetBytes(data);
handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler);
}
private static void SendCallback(IAsyncResult ar) {
try {
Socket handler = (Socket) ar.AsyncState;
int bytesSent = handler.EndSend(ar);
//Console.WriteLine("Sent {0} bytes to client.", bytesSent);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
} catch (Exception e) {
Console.WriteLine(e.ToString());
}
}
}
public class TcpServer {
private int mPort = 11000;
public TcpServer() {
}
public TcpServer(int port) {
mPort = port;
}
public void start() {
AsynchronousSocketListener.StartListening(mPort);
}
}
}

82
ThirdParty/3Di/README.txt vendored Normal file
View File

@ -0,0 +1,82 @@
INTRODUCTION
This folder contains code that implement:
1. Dynamic load balancing
OpenSim is allowing many regions to share a region server, but the optimal
number of regions on each server depends on the load of each region, something
which may change as time goes on. 3Di is working on a load balancer that
allows the current load to be monitored and regions to be reassigned without
requiring the servers to be restarted. To move a region, its state is
serialized, and a new clone is created on the target server using this
stream. The old region is then destroyed and the client viewer updated to use
the new region address.
2. Region splitting
Currently each region can hold only a small number of avatars. To allow more
avatars in each region, 3Di has implemented region splitting, in which several
copies of a given region can be distributed across the region servers. Each
sub-region updates a fraction of the avatars, and sends state updates to the
other sub-regions.
IMPLEMENTATION
The code is organised as follows:
* LoadBalancer: communicates with other region servers and creates/destroys
regions on command
* RegionMonitor/MonitorGUI: provides a browser GUI, showing the state of the
grid, and provides buttons for controlling region movement, splitting, and
merging.
* RegionMonitor/ServerPlugin: this is a region server plugin which
communicates with the load balancer GUI to provide information
on the identity and status of the regions on the grid
* RegionProxy: maps messages from a clients to the true location of a region.
USAGE
In order to use these additions the following lines have to be added to
OpenSim.ini:
proxy_offset = -1000
proxy_url = http://10.8.1.50:9001
serialize_dir = /mnt/temp/
If defined, proxy_offset defines how to calculate the true region port, e.g.
if the XML defines the port as 9000 the actual port is 8000 if proxy_offset
is -1000. The RegionProxy module will open a port at 9000 which the clients
can connect to, and route all traffic from there to port 8000. This allows
the region proxy to run on region server together with regions without
blocking them by using the same port number.
The proxy location is defined in proxy_url. When splitting, the region state
is stored on a file in the folder specified in serialize_dir. This has to be
a shared folder which both region servers involved in the split have access to.
3. Monitor GUI
RegionMonitor/MonitorGUI is used to view status of all the managed Region
servers, and send "Move", "Split", "Merge" commands to a specified Regions
server.
MonitorGUI is a web-based application. You can access it through a web browser.
Its back-end is written in perl. (CGI script)
Pre-requierments (CentOS, Fedora)
RPM package "perl-XML-RPC" and relevant packages.
Installation
1. Install Apache
2. copy all the files undef "ThirdParty/3Di/RegionMonitor/MonitorGUI/htdocs" to
"$APACHE_ROOT/htdocs"
3. Configuration in "monitor.cgi"
* 10th line, set the value to your "monitor.cgi"'s location.
* 11th line, set the value to your Grid server.
* 12th line, set your region proxy port number here.
(ref. OpenSim.ini::NetWork::http_listener_port)
* The code also works fine with mod_perl.

View File

@ -0,0 +1,214 @@
package MonitorGUI::View;
use strict;
my @server_list;
my $max_port;
my $regions;
sub screen_header {
return << "HEADER";
<HTML>
<HEAD>
<STYLE TYPE="text/css">
<!--
a:link {font-size: 12pt; text-decoration:none; color:#0000ff ;}
a:visited {font-size: 12pt; text-decoration:none; color:#ff0000 ;}
a:active {font-size: 12pt; text-decoration:none; color:#00ff00 ;}
a:hover {font-size: 12pt; text-decoration:underline; color:#ff00ff ;}
td {font-size: 12pt;border:0;}
th {background-color:#000000; font-size: 12pt;border:0; color:#FFFFFF; }
tr {background-color:#FFFFFF; }
b {font-size: 12pt;}
//table {background-color:#000000; }
-->
</STYLE>
<META http-equiv="content-type" content="text/html;charset=UTF-8" />
<META name="refresh" content="300" />
<TITLE>Region Monitor GUI, 3Di</TITLE>
</HEAD>
<BODY>
HEADER
}
sub screen_footer {
return << "FOOTER";
</BODY>
</HTML>
FOOTER
}
sub html {
my $grid_info = shift;
my $regions_list = $grid_info->{"sim-profiles"};
$regions = undef;
foreach(@$regions_list) {
my $ip = $_->{sim_ip} || "UNKNOWN";
my $port = $_->{sim_port} || "UNKNOWN";
$regions->{$ip}->{$port} = $_;
if (!$regions->{max_port} || $regions->{max_port} < $port) {
$regions->{max_port} = $port;
}
}
@server_list = keys %$regions;
$max_port = $regions->{max_port};
my $html = "";
foreach my $machine (@server_list) {
next if ($machine eq "max_port");
$html .= &_machine_view($machine, $regions->{$machine});
}
return $html;
}
sub _machine_view {
my ($ip, $info) = @_;
my $region_html = "";
foreach my $region (keys %$info) {
$region_html .= &_region_html($info->{$region});
}
my $html =<< "MACHINE_HTML";
<h3>$ip</h3>
$region_html
<hr size=0 noshade />
MACHINE_HTML
}
sub _region_html {
my $region_info = shift;
my $name = $region_info->{name} || "UNKNOWN";
my $x = $region_info->{x} || -1;
my $y = $region_info->{y} || -1;
my $ip = $region_info->{sim_ip} || "UNKNOWN";
my $port = $region_info->{sim_port} || "UNKNOWN";
my $get_scene_presence_filter = $region_info->{get_scene_presence_filter};
my $get_scene_presence = $region_info->{get_scene_presence};
my $get_avatar_filter = $region_info->{get_avatar_filter};
my $get_avatar = $region_info->{get_avatar};
my $avatar_names = $region_info->{avatar_names};
my $action_forms = &_action_forms($region_info);
my $html = <<"REGION_HTML";
<strong>$name</strong><br/>
$ip:$port | X: $x Y: $y<br/>
<table border="0">
<tr>
<td>get_avatar</td>
<td>$get_avatar</td>
<td></td>
</tr>
<tr>
<td>get_avatar_filter</td>
<td>$get_avatar_filter</td>
<td>$avatar_names</td>
</tr>
<tr>
<td>get_scene_presence</td>
<td>$get_scene_presence</td>
<td></td>
</tr>
<tr>
<td>get_scene_presence_filter</td>
<td>$get_scene_presence_filter</td>
<td></td>
</tr>
</table>
$action_forms
REGION_HTML
return $html;
}
sub _action_forms {
my $region_info = shift;
my $ip = $region_info->{sim_ip};
my $port = $region_info->{sim_port};
my $default_input_port = $max_port + 1;
my $move_to_options = "";
my $split_to_options = "";
my $merge_ip_options = "";
foreach(@server_list) {
next if ($_ eq "max_port");
$merge_ip_options .= "<option value=\"$_\">$_\n";
$split_to_options .= "<option value=\"$_\">$_\n";
#next if ($_ eq $ip);
$move_to_options .= "<option value=\"$_\">$_\n";
}
my $merge_port_options = "";
my $merge_disabled = "disabled";
foreach(keys %{$regions->{$ip}}) {
next if ($_ eq $port);
$merge_disabled = "";
}
# for(9000..$max_port) { # TODO :
# next if ($_ eq $port);
# $merge_port_options .= "<option value=\"$_\">$_\n";
# }
my %port = ();
foreach my $ip (keys %$regions) {
next if ($ip eq "max_port");
print STDERR "--" . $ip . "\n";
foreach my $region_port (keys %{$regions->{$ip}}) {
print STDERR "---" . $region_port . "\n";
$port{$region_port} = 1;
}
}
foreach (keys %port) {
$merge_port_options .= "<option value=\"$_\">$_\n";
$merge_disabled = "";
}
return << "ACTION_FORMS";
<table>
<tr>
<form method="POST">
<td>
<input type="hidden" name="A" value="move" />
<input type="hidden" name="from_ip" value="$ip" />
<input type="hidden" name="from_port" value="$port" />
<input type="submit" value="Move to" />
<select name="to_ip">
$move_to_options
</select>:
<input type="text" name="to_port" size="5" value="$default_input_port"/>
</td>
</form>
<td>
&nbsp;&nbsp;|&nbsp;&nbsp;
</td>
<form method="POST">
<td>
<input type="hidden" name="A" value="split" />
<input type="hidden" name="from_ip" value="$ip" />
<input type="hidden" name="from_port" value="$port" />
<input type="submit" value="Split to" />
<select name="to_ip">
$split_to_options
</select>:
<input type="text" name="to_port" size="5" value="$default_input_port"/>
</td>
</form>
<td>
&nbsp;&nbsp;|&nbsp;&nbsp;
</td>
<form method="POST">
<td>
<input type="hidden" name="A" value="merge" />
<input type="hidden" name="from_ip" value="$ip" />
<input type="hidden" name="master_port" value="$port" />
<input type="submit" value="Merge" $merge_disabled />
<select name="slave_ip" $merge_disabled>
$merge_ip_options
</select>
<select name="slave_port" $merge_disabled>
$merge_port_options
</select>
</td>
</form>
</tr>
</table>
ACTION_FORMS
}
1;

View File

@ -0,0 +1,91 @@
package MyCGI;
use strict;
use CGI;
sub getParam {
my $cgi;
if ($ARGV[0]) {
$cgi = new CGI($ARGV[0]);
} else {
$cgi = new CGI;
}
my @param_names = $cgi->param();
my %param = ();
foreach (@param_names) {
$param{$_} = $cgi->param($_);
}
return \%param;
}
sub getCookie {
my $name = shift;
my $cookie_value = &CGI::cookie($name);
return &_parse($cookie_value);
}
sub outputHtml {
my ($charset, $html) = @_;
print &CGI::header(-charset => $charset);
print $html;
}
sub outputXml {
my ($charset, $xml) = @_;
print &CGI::header( -type => 'text/xml', -charset => $charset );
print $xml;
}
sub makeCookieValue {
my $param = shift;
my @data = ();
foreach(keys %$param) {
push(@data, $_ . "=" . $param->{$_});
}
return join("&", @data);
}
sub setCookie {
my $param = shift;
my $cookie = &CGI::cookie(
-name => $param->{name} || return,
-value => $param->{value},
-domain => $param->{domain},
-path => $param->{path},
-expires => $param->{expires},
);
return &CGI::header(-cookie => $cookie);
}
sub redirect {
my $dest = shift;
&CGI::redirect($dest);
}
sub urlEncode {
my $str = shift;
$str =~ s/([^\w ])/'%'.unpack('H2', $1)/eg;
$str =~ tr/ /+/;
return $str;
}
sub urlDecode {
my $str = shift;
$str =~ tr/+/ /;
$str =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack('H2', $1)/eg;
return $str;
}
sub _parse {
my $value = shift;
my @pair = split(/&/, $value);
my %data = ();
foreach(@pair) {
my ($name, $value) = split(/=/, $_);
$data{$name} = $value;
}
return \%data;
}
1;

View File

@ -0,0 +1,202 @@
#!/usr/bin/perl -w
use strict;
use Carp;
use MyCGI;
use XML::RPC;
use MonitorGUI::View;
use vars qw ($THIS_URL $GRID_SERVER_URL $DEFAULT_PROXY_PORT);
$THIS_URL = "http://10.8.1.165/monitorgui/monitor.cgi";
$GRID_SERVER_URL = "http://10.8.1.165/opensim/grid.cgi";
$DEFAULT_PROXY_PORT = 9000;
my %ACTIONS = (
# Region commands
move => \&move_command,
split => \&split_command,
merge => \&merge_command,
# display commands
default => \&main_screen,
refresh => \&refresh,
);
# ##################
# main
my $param = &MyCGI::getParam;
my $act = $param->{A} || "default";
my $contents = "";
if (!$ACTIONS{$act}) {
&gui_error("404 NOT FOUND");
} else {
eval {
$ACTIONS{$act}->($param);
};
if ($@) {
&gui_error($@);
}
}
# #################
# Region Commands
sub move_command {
my $param = shift;
# from
my $from_ip = $param->{from_ip} || Carp::croak("not enough params (from_ip)");
my $from_port = $param->{from_port} || Carp::croak("not enough params (from_port)");
my $from_url = "http://" . $param->{from_ip} . ":" . $DEFAULT_PROXY_PORT;
# to
my $to_ip = $param->{to_ip} || Carp::croak("not enough params (to_ip)");
my $to_port = $param->{to_port} || Carp::croak("not enough params (to_port)");
my $to_url = "http://" . $param->{to_ip} . ":" . $DEFAULT_PROXY_PORT;
# commands
eval {
&OpenSim::Utility::XMLRPCCall_array($from_url, "SerializeRegion", [$from_ip, $from_port]);
&OpenSim::Utility::XMLRPCCall_array($to_url, "DeserializeRegion_Move", [$from_ip, $from_port, $to_ip, $to_port]);
&OpenSim::Utility::XMLRPCCall_array($from_url, "TerminateRegion", [$from_port]);
};
if ($@) {
print STDERR "Get Status Error: $@\n";
}
# client refresh
&redirect_refresh({wait=>5, force=>"$from_url|$to_url", msg=>"Move region $from_ip:$from_port from $from_url to $to_url"});
}
sub split_command {
my $param = shift;
# from
my $from_ip = $param->{from_ip} || Carp::croak("not enough params (from_ip)");
my $from_port = $param->{from_port} || Carp::croak("not enough params (from_port)");
my $from_url = "http://" . $param->{from_ip} . ":" . $DEFAULT_PROXY_PORT;
# to
my $to_ip = $param->{to_ip} || Carp::croak("not enough params (to_ip)");
my $to_port = $param->{to_port} || Carp::croak("not enough params (to_port)");
my $to_url = "http://" . $param->{to_ip} . ":" . $DEFAULT_PROXY_PORT;
# commands
eval {
&OpenSim::Utility::XMLRPCCall_array($from_url, "SerializeRegion", [$from_ip, $from_port]);
&OpenSim::Utility::XMLRPCCall_array($to_url, "DeserializeRegion_Clone", [$from_ip, $from_port, $to_ip, $to_port]);
};
if ($@) {
print STDERR "Get Status Error: $@\n";
}
&redirect_refresh({wait=>5, force=>"$from_url", msg=>"Split region $from_ip:$from_port"});
}
sub merge_command {
my $param = shift;
# from
my $from_ip = $param->{from_ip} || Carp::croak("not enough params (from_ip)");
my $url = "http://" . $param->{from_ip} . ":" . $DEFAULT_PROXY_PORT;
# ports
my $master_port = $param->{master_port} || Carp::croak("not enough params (master_port)");
my $slave_ip = $param->{slave_ip} || Carp::croak("not enough params (slave_ip)");
my $slave_port = $param->{slave_port} || Carp::croak("not enough params (slave_port)");
my $slave_url = "http://" . $param->{slave_ip} . ":" . $DEFAULT_PROXY_PORT;
# commands
eval {
&XMLRPCCall_array($url, "MergeRegions", [$from_ip, $master_port]);
&XMLRPCCall_array($slave_url, "TerminateRegion", [$slave_port]);
};
if ($@) {
print STDERR "Get Status Error: $@\n";
}
&redirect_refresh({wait=>5, force=>"$url", msg=>"Merge region $from_ip:$master_port, $slave_port"});
}
# #################
# Display
sub main_screen {
my %xml_rpc_param = (
# TODO: should be 0 - 65535 ?
xmin => 999, ymin => 999, xmax => 1010, ymax => 1010,
);
my $res_obj = undef;
eval {
$res_obj = &XMLRPCCall($GRID_SERVER_URL, "map_block", \%xml_rpc_param);
};
if ($@) {
&gui_error("map_block Error: " . $@);
}
my %copy_obj = %$res_obj;
my $getstatus_failed = "<font color=\"red\">GetStatus Failed</font>";
my $regions_list = $res_obj->{"sim-profiles"};
foreach(@$regions_list) {
if ($_->{sim_ip} && $_->{sim_port}) {
my $url = "http://" . $_->{sim_ip} . ":" . $DEFAULT_PROXY_PORT;
my $port = $_->{sim_port};
my $res = undef;
eval {
$res = &XMLRPCCall_array($url, "GetStatus", [$port]);
};
if ($@) {
print STDERR "Get Status Error: $@\n";
}
$_->{get_scene_presence_filter} = $res ? $res->{get_scene_presence_filter} : $getstatus_failed;
$_->{get_scene_presence} = $res ? $res->{get_scene_presence} : $getstatus_failed;
$_->{get_avatar_filter} = $res ? $res->{get_avatar_filter} : $getstatus_failed;
$_->{get_avatar} = $res ? $res->{get_avatar} : $getstatus_failed;
$_->{avatar_names} = $res ? $res->{avatar_names} : "NO USER";
}
}
my $html = &MonitorGUI::View::html(\%copy_obj);
&MyCGI::outputHtml("UTF-8", &MonitorGUI::View::screen_header . $html . &MonitorGUI::View::screen_footer);
}
sub gui_error {
my $msg = shift;
&MyCGI::outputHtml("UTF-8", "<h1>ERROR</h1><hr />$msg");
}
sub redirect_refresh {
my $args = shift;
my $wait = $args->{wait};
my $force = $args->{force} || "";
my $msg = $args->{msg} || "";
my $param = "A=refresh&wait=$wait&ip=$force&msg=$msg";
my $dist_url = $THIS_URL . "?" . $param;
&MyCGI::redirect($dist_url);
}
sub refresh {
my $param = shift;
my $msg = $param->{msg} || "";
my $wait = $param->{wait} || 0;
my $force = $param->{ip} || "";
#my $jump_url = $force ? "$THIS_URL?A=force&ip=$force" : $THIS_URL;
my $jump_url = $THIS_URL;
my $html =<< "HTML";
<html>
<head>
<meta http-equiv="Refresh" content="$wait;URL=$jump_url" />
<title>Region Monitor GUI REFRESH</title>
</head>
<body>
<h3>$msg</h3>
<br>
wait <font color="red"><b>$wait</b></font> sec for server to take effect ... <br>
(* The page will jump to "Monitor Screen" automatically)
</body>
</html>
HTML
&MyCGI::outputHtml("UTF-8", $html);
}
# ##################
# Utility
sub XMLRPCCall {
my ($url, $methodname, $param) = @_;
my $xmlrpc = new XML::RPC($url);
my $result = $xmlrpc->call($methodname, $param);
return $result;
}
sub XMLRPCCall_array {
my ($url, $methodname, $param) = @_;
my $xmlrpc = new XML::RPC($url);
my $result = $xmlrpc->call($methodname, @$param);
return $result;
}

View File

@ -0,0 +1,129 @@
/*
* 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.Runtime.Remoting;
using System.Threading;
using Mono.Addins;
using OpenSim;
using OpenSim.Framework.Console;
using MonitorLib;
[assembly:Addin]
[assembly:AddinDependency ("OpenSim", "0.5")]
namespace OpenSim.ApplicationPlugins.RegionMonitor
{
[Extension("/OpenSim/Startup")]
public class RegionMonitorPlugin : MonitorLibBase, IApplicationPlugin
{
protected Thread m_mointorThread;
protected static OpenSimMain m_openSimMain;
public void Initialise(OpenSimMain opensim)
{
m_openSimMain = opensim;
Start();
MainLog.Instance.Verbose("Monitor", "Region monitor is runing ...");
}
public void Close()
{
}
public void Start()
{
// start monitor thread (remoting module)
m_mointorThread = new Thread(new ThreadStart(StartMonitor));
m_mointorThread.IsBackground = true;
m_mointorThread.Start();
}
private void StartMonitor()
{
try
{
Object lockObj = new Object();
RemotingConfiguration.Configure("monitorS.config", false);
lock (lockObj)
{
System.Threading.Monitor.Wait(lockObj);
}
}
catch (Exception e)
{
MainLog.Instance.Warn("MONITOR", "Error - " + e.Message);
}
}
public override bool FetchInfo(out string outstr)
{
MainLog.Instance.Verbose("MONITOR", "Fetch Information from Region server");
bool status = true;
string startTime = "";
string upTime = "";
int userNumber = 0;
int regionNumber = 0;
m_openSimMain.GetRunTime(out startTime, out upTime);
m_openSimMain.GetAvatarNumber(out userNumber);
m_openSimMain.GetRegionNumber(out regionNumber);
outstr = startTime
+ "," + upTime
+ "," + regionNumber
+ "," + userNumber;
return status;
}
public override bool MoveRegion()
{
MainLog.Instance.Verbose("MONITOR", "Move Region");
bool status = true;
return status;
}
public override bool SplitRegion()
{
MainLog.Instance.Verbose("MONITOR", "Split Region");
bool status = true;
return status;
}
public override bool MergeScenes()
{
MainLog.Instance.Verbose("MONITOR", "Merge Scenes");
bool status = true;
return status;
}
}
}

View File

@ -0,0 +1,513 @@
/*
* 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.IO;
using System.Net;
using System.Xml;
using System.Text;
using System.Xml.Serialization;
using System.Net.Sockets;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using OpenSim.Framework;
using OpenSim.Framework.Servers;
using OpenSim.Framework.Console;
using Nwc.XmlRpc;
using Mono.Addins;
[assembly:Addin]
[assembly:AddinDependency ("OpenSim", "0.5")]
namespace OpenSim.ApplicationPlugins.RegionProxy
{
/* This module has an interface to OpenSim clients that is constant, and is responsible for relaying
* messages to and from clients to the region objects. Since the region objects can be duplicated and
* moved dynamically, the proxy provides methods for changing and adding regions. If more than one region
* is associated with a client port, then the message will be broadcasted to all those regions.
*
* The client interface port may be blocked. While being blocked, all messages from the clients will be
* stored in the proxy. Once the interface port is unblocked again, all stored messages will be resent
* to the regions. This functionality is used when moving or cloning an region to make sure that no messages
* are sent to the region while it is being reconfigured.
*
* The proxy opens a XmlRpc interface with these public methods:
* - AddPort
* - AddRegion
* - ChangeRegion
* - BlockClientMessages
* - UnblockClientMessages
*/
[Extension("/OpenSim/Startup")]
public class RegionProxyPlugin : IApplicationPlugin
{
private ProxyServer proxy;
private BaseHttpServer command_server;
private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public void Initialise(OpenSimMain openSim)
{
Console.WriteLine("Starting proxy");
string proxyURL = openSim.ConfigSource.Configs["Network"].GetString("proxy_url", "");
if(proxyURL.Length==0) return;
uint port = (uint) Int32.Parse(proxyURL.Split(new char[] { ':' })[2]);
command_server = new BaseHttpServer(port);
command_server.Start();
command_server.AddXmlRPCHandler("AddPort", AddPort);
command_server.AddXmlRPCHandler("AddRegion", AddRegion);
command_server.AddXmlRPCHandler("DeleteRegion", DeleteRegion);
command_server.AddXmlRPCHandler("ChangeRegion", ChangeRegion);
command_server.AddXmlRPCHandler("BlockClientMessages", BlockClientMessages);
command_server.AddXmlRPCHandler("UnblockClientMessages", UnblockClientMessages);
command_server.AddXmlRPCHandler("Stop", Stop);
proxy=new ProxyServer(m_log);
}
public void Close()
{
}
private XmlRpcResponse Stop(XmlRpcRequest request)
{
try
{
proxy.Stop();
}
catch (Exception e)
{
m_log.Error("[PROXY]" + e.Message);
m_log.Error("[PROXY]" + e.StackTrace);
}
return new XmlRpcResponse();
}
private XmlRpcResponse AddPort(XmlRpcRequest request)
{
try {
int clientPort = (int) request.Params[0];
int regionPort = (int) request.Params[1];
string regionUrl = (string) request.Params[2];
proxy.AddPort(clientPort, regionPort, regionUrl);
} catch(Exception e) {
m_log.Error("[PROXY]"+e.Message);
m_log.Error("[PROXY]"+e.StackTrace);
}
return new XmlRpcResponse();
}
private XmlRpcResponse AddRegion(XmlRpcRequest request)
{
try {
int currentRegionPort = (int) request.Params[0];
string currentRegionUrl = (string) request.Params[1];
int newRegionPort = (int) request.Params[2];
string newRegionUrl = (string) request.Params[3];
proxy.AddRegion(currentRegionPort, currentRegionUrl, newRegionPort, newRegionUrl);
} catch(Exception e) {
m_log.Error("[PROXY]"+e.Message);
m_log.Error("[PROXY]"+e.StackTrace);
}
return new XmlRpcResponse();
}
private XmlRpcResponse ChangeRegion(XmlRpcRequest request)
{
try {
int currentRegionPort = (int) request.Params[0];
string currentRegionUrl = (string) request.Params[1];
int newRegionPort = (int) request.Params[2];
string newRegionUrl = (string) request.Params[3];
proxy.ChangeRegion(currentRegionPort, currentRegionUrl, newRegionPort, newRegionUrl);
} catch(Exception e) {
m_log.Error("[PROXY]"+e.Message);
m_log.Error("[PROXY]"+e.StackTrace);
}
return new XmlRpcResponse();
}
private XmlRpcResponse DeleteRegion(XmlRpcRequest request)
{
try {
int currentRegionPort = (int) request.Params[0];
string currentRegionUrl = (string) request.Params[1];
proxy.DeleteRegion(currentRegionPort, currentRegionUrl);
} catch(Exception e) {
m_log.Error("[PROXY]"+e.Message);
m_log.Error("[PROXY]"+e.StackTrace);
}
return new XmlRpcResponse();
}
private XmlRpcResponse BlockClientMessages(XmlRpcRequest request)
{
try {
string regionUrl = (string) request.Params[0];
int regionPort = (int) request.Params[1];
proxy.BlockClientMessages(regionUrl, regionPort);
} catch(Exception e) {
m_log.Error("[PROXY]"+e.Message);
m_log.Error("[PROXY]"+e.StackTrace);
}
return new XmlRpcResponse();
}
private XmlRpcResponse UnblockClientMessages(XmlRpcRequest request)
{
try {
string regionUrl = (string) request.Params[0];
int regionPort = (int) request.Params[1];
proxy.UnblockClientMessages(regionUrl, regionPort);
} catch(Exception e) {
m_log.Error("[PROXY]"+e.Message);
m_log.Error("[PROXY]"+e.StackTrace);
}
return new XmlRpcResponse();
}
}
public class ProxyServer {
protected AsyncCallback receivedData;
protected ProxyMap proxy_map = new ProxyMap();
protected readonly log4net.ILog m_log;
protected bool running;
protected class ProxyMap
{
public class RegionData
{
public bool isBlocked = false;
public Queue storedMessages = new Queue();
public List<EndPoint> regions = new List<EndPoint>();
}
private Dictionary<EndPoint, RegionData> map;
public ProxyMap() {
map = new Dictionary<EndPoint, RegionData>();
}
public void Add(EndPoint client, EndPoint region)
{
if(map.ContainsKey(client))
{
map[client].regions.Add(region);
}
else
{
RegionData regions = new RegionData();
map.Add(client, regions);
regions.regions.Add(region);
}
}
public RegionData GetRegionData(EndPoint client)
{
return map[client];
}
public EndPoint GetClient(EndPoint region)
{
foreach (KeyValuePair<EndPoint, RegionData> pair in map)
{
if(pair.Value.regions.Contains(region))
{
return pair.Key;
}
}
return null;
}
}
protected class ServerData {
public Socket server;
public EndPoint clientEP;
public EndPoint senderEP;
public IPEndPoint serverIP;
public byte[] recvBuffer = new byte[4096];
public ServerData()
{
server = null;
}
}
protected class StoredMessage
{
public byte[] buffer;
public int length;
public EndPoint senderEP;
public ServerData sd;
public StoredMessage(byte[] buffer, int length, int maxLength, EndPoint senderEP, ServerData sd)
{
this.buffer = new byte[maxLength];
this.length = length;
for(int i=0; i<length; i++) this.buffer[i]=buffer[i];
this.senderEP = senderEP;
this.sd = sd;
}
}
public ProxyServer(log4net.ILog log)
{
m_log = log;
running=false;
receivedData = new AsyncCallback(OnReceivedData);
}
public void BlockClientMessages(string regionUrl, int regionPort)
{
EndPoint client = proxy_map.GetClient(new IPEndPoint(IPAddress.Parse(regionUrl), regionPort));
ProxyMap.RegionData rd = proxy_map.GetRegionData(client);
rd.isBlocked = true;
}
public void UnblockClientMessages(string regionUrl, int regionPort)
{
EndPoint client = proxy_map.GetClient(new IPEndPoint(IPAddress.Parse(regionUrl), regionPort));
ProxyMap.RegionData rd = proxy_map.GetRegionData(client);
rd.isBlocked = false;
while(rd.storedMessages.Count > 0) {
StoredMessage msg = (StoredMessage) rd.storedMessages.Dequeue();
//m_log.Verbose("[PROXY]"+"Resending blocked message from {0}", msg.senderEP);
SendMessage(msg.buffer, msg.length, msg.senderEP, msg.sd);
}
}
public void AddRegion(int oldRegionPort, string oldRegionUrl, int newRegionPort, string newRegionUrl)
{
//m_log.Verbose("[PROXY]"+"AddRegion {0} {1}", oldRegionPort, newRegionPort);
EndPoint client = proxy_map.GetClient(new IPEndPoint(IPAddress.Parse(oldRegionUrl), oldRegionPort));
ProxyMap.RegionData data = proxy_map.GetRegionData(client);
data.regions.Add(new IPEndPoint(IPAddress.Parse(newRegionUrl), newRegionPort));
}
public void ChangeRegion(int oldRegionPort, string oldRegionUrl, int newRegionPort, string newRegionUrl)
{
//m_log.Verbose("[PROXY]"+"ChangeRegion {0} {1}", oldRegionPort, newRegionPort);
EndPoint client = proxy_map.GetClient(new IPEndPoint(IPAddress.Parse(oldRegionUrl), oldRegionPort));
ProxyMap.RegionData data = proxy_map.GetRegionData(client);
data.regions.Clear();
data.regions.Add(new IPEndPoint(IPAddress.Parse(newRegionUrl), newRegionPort));
}
public void DeleteRegion(int oldRegionPort, string oldRegionUrl)
{
m_log.InfoFormat("[PROXY]"+"DeleteRegion {0} {1}", oldRegionPort, oldRegionUrl);
EndPoint regionEP = new IPEndPoint(IPAddress.Parse(oldRegionUrl), oldRegionPort);
EndPoint client = proxy_map.GetClient(regionEP);
ProxyMap.RegionData data = proxy_map.GetRegionData(client);
data.regions.Remove(regionEP);
}
public void AddPort(int clientPort, int regionPort, string regionUrl)
{
running = true;
//m_log.Verbose("[PROXY]"+"AddPort {0} {1}", clientPort, regionPort);
IPEndPoint clientEP = new IPEndPoint(IPAddress.Parse("127.0.0.1"), clientPort);
proxy_map.Add(clientEP, new IPEndPoint(IPAddress.Parse(regionUrl), regionPort));
ServerData sd = new ServerData();
sd.clientEP = new IPEndPoint(clientEP.Address, clientEP.Port);
OpenPort(sd);
}
protected void OpenPort(ServerData sd)
{
// sd.clientEP must be set before calling this function
ClosePort(sd);
try
{
m_log.InfoFormat("[PROXY] Opening UDP socket on {0}", sd.clientEP);
sd.serverIP = new IPEndPoint(IPAddress.Parse("0.0.0.0"), ((IPEndPoint)sd.clientEP).Port);
sd.server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
sd.server.Bind(sd.serverIP);
sd.senderEP = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 0);
//receivedData = new AsyncCallback(OnReceivedData);
sd.server.BeginReceiveFrom(sd.recvBuffer, 0, sd.recvBuffer.Length, SocketFlags.None, ref sd.senderEP, receivedData, sd);
}
catch (Exception e)
{
m_log.ErrorFormat("[PROXY] Failed to (re)open socket {0}", sd.clientEP);
m_log.Error("[PROXY]" + e.Message);
m_log.Error("[PROXY]" + e.StackTrace);
}
}
protected void ClosePort(ServerData sd)
{
// Close the port if it exists and is open
if (sd.server == null) return;
try
{
sd.server.Shutdown(SocketShutdown.Both);
sd.server.Close();
}
catch (Exception)
{
}
}
public void Stop()
{
running = false;
m_log.InfoFormat("[PROXY] Stopping the proxy server");
}
protected virtual void OnReceivedData(IAsyncResult result)
{
if(!running) return;
ServerData sd = (ServerData)result.AsyncState;
sd.senderEP = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 0);
try
{
int numBytes = sd.server.EndReceiveFrom(result, ref sd.senderEP);
if (numBytes > 0)
{
SendMessage(sd.recvBuffer, numBytes, sd.senderEP, sd);
}
}
catch (Exception e)
{
// OpenPort(sd); // reopen the port just in case
m_log.ErrorFormat("[PROXY] EndReceiveFrom failed in {0}", sd.clientEP);
m_log.Error("[PROXY]" + e.Message);
m_log.Error("[PROXY]" + e.StackTrace);
}
WaitForNextMessage(sd);
}
protected void WaitForNextMessage(ServerData sd)
{
bool error = true;
while (error)
{
error = false;
try
{
sd.server.BeginReceiveFrom(sd.recvBuffer, 0, sd.recvBuffer.Length, SocketFlags.None, ref sd.senderEP, receivedData, sd);
}
catch (Exception e)
{
error = true;
m_log.ErrorFormat("[PROXY] BeginReceiveFrom failed, retrying... {0}", sd.clientEP);
m_log.Error("[PROXY]" + e.Message);
m_log.Error("[PROXY]" + e.StackTrace);
OpenPort(sd);
}
}
}
protected void SendMessage(byte[] buffer, int length, EndPoint senderEP, ServerData sd)
{
int numBytes = length;
//m_log.ErrorFormat("[PROXY] Got message from {0} in thread {1}, size {2}", senderEP, sd.clientEP, numBytes);
EndPoint client = proxy_map.GetClient(senderEP);
if (client != null)
{
try
{
client = PacketPool.DecodeProxyMessage(buffer, ref numBytes);
try
{
// This message comes from a region object, forward it to the its client
sd.server.SendTo(buffer, numBytes, SocketFlags.None, client);
//m_log.InfoFormat("[PROXY] Sending region message from {0} to {1}, size {2}", senderEP, client, numBytes);
}
catch (Exception e)
{
OpenPort(sd); // reopen the port just in case
m_log.ErrorFormat("[PROXY] Failed sending region message from {0} to {1}", senderEP, client);
m_log.Error("[PROXY]" + e.Message);
m_log.Error("[PROXY]" + e.StackTrace);
return;
}
}
catch (Exception e)
{
OpenPort(sd); // reopen the port just in case
m_log.ErrorFormat("[PROXY] Failed decoding region message from {0}", senderEP);
m_log.Error("[PROXY]" + e.Message);
m_log.Error("[PROXY]" + e.StackTrace);
return;
}
}
else
{
// This message comes from a client object, forward it to the the region(s)
PacketPool.EncodeProxyMessage(buffer, ref numBytes, senderEP);
ProxyMap.RegionData rd = proxy_map.GetRegionData(sd.clientEP);
foreach (EndPoint region in rd.regions)
{
if(rd.isBlocked) {
rd.storedMessages.Enqueue(new StoredMessage(buffer, length, numBytes, senderEP, sd));
}
else
{
try
{
sd.server.SendTo(buffer, numBytes, SocketFlags.None, region);
//m_log.InfoFormat("[PROXY] Sending client message from {0} to {1}", senderEP, region);
}
catch (Exception e)
{
OpenPort(sd); // reopen the port just in case
m_log.ErrorFormat("[PROXY] Failed sending client message from {0} to {1}", senderEP, region);
m_log.Error("[PROXY]" + e.Message);
m_log.Error("[PROXY]" + e.StackTrace);
return;
}
}
}
}
}
}
}

View File

@ -1111,6 +1111,7 @@
<Reference name="OpenSim.Framework.Console"/>
<Reference name="OpenSim.Framework.Servers"/>
<Reference name="OpenSim.Framework.Data"/>
<Reference name="OpenSim.Framework.Data.MySQL"/>
<Reference name="libsecondlife.dll"/>
<Reference name="Db4objects.Db4o.dll"/>
<Reference name="XMLRPC.dll"/>
@ -1509,6 +1510,69 @@
</Files>
</Project>
<Project name="OpenSim.ApplicationPlugins.RegionProxy" path="ThirdParty/3Di/RegionProxy" type="Library">
<Configuration name="Debug">
<Options>
<OutputPath>../../../bin/</OutputPath>
</Options>
</Configuration>
<Configuration name="Release">
<Options>
<OutputPath>../../../bin/</OutputPath>
</Options>
</Configuration>
<ReferencePath>../../../bin/</ReferencePath>
<Reference name="log4net" />
<Reference name="Mono.Addins.dll" />
<Reference name="System"/>
<Reference name="System.Xml"/>
<Reference name="XMLRPC.dll"/>
<Reference name="Nini.dll" />
<Reference name="OpenSim"/>
<Reference name="OpenSim.Framework"/>
<Reference name="OpenSim.Framework.Data"/>
<Reference name="OpenSim.Framework.Servers"/>
<Reference name="OpenSim.Framework.Console"/>
<Reference name="OpenSim.Region.ClientStack"/>
<Files>
<Match pattern="*.cs" recurse="true"/>
</Files>
</Project>
<Project name="OpenSim.ApplicationPlugins.LoadBalancer" path="ThirdParty/3Di/LoadBalancer" type="Library">
<Configuration name="Debug">
<Options>
<OutputPath>../../../bin/</OutputPath>
</Options>
</Configuration>
<Configuration name="Release">
<Options>
<OutputPath>../../../bin/</OutputPath>
</Options>
</Configuration>
<ReferencePath>../../../bin/</ReferencePath>
<Reference name="log4net" />
<Reference name="Mono.Addins.dll" />
<Reference name="System"/>
<Reference name="System.Xml"/>
<Reference name="XMLRPC.dll"/>
<Reference name="Nini.dll" />
<Reference name="OpenSim"/>
<Reference name="OpenSim.Framework"/>
<Reference name="OpenSim.Framework.Data"/>
<Reference name="OpenSim.Framework.Servers"/>
<Reference name="OpenSim.Framework.Console"/>
<Reference name="OpenSim.Region.Environment"/>
<Reference name="OpenSim.Region.ClientStack"/>
<Reference name="OpenSim.Region.Physics.Manager"/>
<Reference name="libsecondlife.dll"/>
<Files>
<Match pattern="*.cs" recurse="true"/>
</Files>
</Project>
</Solution>
<!-- Prebuild tool -->