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.
parent
cd6f4a57e7
commit
279e0061c5
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -69,5 +69,10 @@ namespace OpenSim.Framework
|
|||
{
|
||||
return m_queue.Count;
|
||||
}
|
||||
|
||||
public T[] GetQueueArray()
|
||||
{
|
||||
return m_queue.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
ALTER TABLE `regions`
|
||||
ADD COLUMN `originUUID` varchar(36),
|
||||
COMMENT='Rev. 2';
|
|
@ -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"];
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,8 @@ namespace OpenSim.Framework
|
|||
Down = 0,
|
||||
Up = 1,
|
||||
Crashed = 2,
|
||||
Starting = 3
|
||||
Starting = 3,
|
||||
SlaveScene = 4
|
||||
} ;
|
||||
|
||||
public interface IScene
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
*
|
||||
*/
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Collections;
|
||||
using libsecondlife.Packets;
|
||||
|
||||
|
@ -33,29 +34,68 @@ 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)
|
||||
lock(pool)
|
||||
{
|
||||
if (pool[type] == null || ((Stack) pool[type]).Count == 0)
|
||||
if(pool[type] == null || ((Stack) pool[type]).Count == 0)
|
||||
{
|
||||
// Creating a new packet if we cannot reuse an old package
|
||||
packet = Packet.BuildPacket(type);
|
||||
|
@ -63,39 +103,16 @@ namespace OpenSim.Framework
|
|||
else
|
||||
{
|
||||
// Recycle old packages
|
||||
packet = (Packet) ((Stack) pool[type]).Pop();
|
||||
packet=(Packet) ((Stack) pool[type]).Pop();
|
||||
}
|
||||
}
|
||||
|
||||
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,21 +155,22 @@ namespace OpenSim.Framework
|
|||
return packet;
|
||||
}
|
||||
|
||||
public void ReturnPacket(Packet packet)
|
||||
{
|
||||
/* Skip until PacketPool performance problems have been resolved (mantis 281)
|
||||
lock (pool)
|
||||
{
|
||||
PacketType type = packet.Type;
|
||||
public void ReturnPacket(Packet packet) {
|
||||
return; // packet pool disabled
|
||||
|
||||
if (pool[type] == null)
|
||||
lock(pool)
|
||||
{
|
||||
PacketType type=packet.Type;
|
||||
|
||||
if(pool[type] == null)
|
||||
{
|
||||
pool[type] = new Stack();
|
||||
}
|
||||
|
||||
((Stack) pool[type]).Push(packet);
|
||||
if (((Stack)pool[type]).Count < 50)
|
||||
{
|
||||
((Stack)pool[type]).Push(packet);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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.
|
||||
|
|
@ -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>
|
||||
|
|
||||
</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>
|
||||
|
|
||||
</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;
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
64
prebuild.xml
64
prebuild.xml
|
@ -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 -->
|
||||
|
|
Loading…
Reference in New Issue