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.

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

View File

@@ -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)
@@ -2642,7 +2680,7 @@ namespace OpenSim.Region.ClientStack
try
{
byte[] sendbuffer = Pack.ToBytes();
PacketPool.Instance.ReturnPacket(Pack);
PacketPool.Instance.ReturnPacket(Pack);
if (Pack.Header.Zerocoded)
{
@@ -2651,8 +2689,11 @@ namespace OpenSim.Region.ClientStack
}
else
{
m_networkServer.SendPacketTo(sendbuffer, sendbuffer.Length, SocketFlags.None, m_circuitCode);
//Need some extra space in case we need to add proxy information to the message later
Buffer.BlockCopy(sendbuffer, 0, ZeroOutBuffer, 0, sendbuffer.Length);
m_networkServer.SendPacketTo(ZeroOutBuffer, sendbuffer.Length, SocketFlags.None, m_circuitCode);
}
}
catch (Exception e)
{
@@ -2666,6 +2707,12 @@ namespace OpenSim.Region.ClientStack
public virtual void InPacket(Packet NewPack)
{
if(!m_packetProcessingEnabled && NewPack.Type != PacketType.LogoutRequest)
{
PacketPool.Instance.ReturnPacket(NewPack);
return;
}
// Handle appended ACKs
if (NewPack != null)
{
@@ -2726,6 +2773,15 @@ namespace OpenSim.Region.ClientStack
public virtual void OutPacket(Packet NewPack, ThrottleOutPacketType throttlePacketType)
{
if ((SynchronizeClient != null) && (!PacketProcessingEnabled))
{
// Sending packet to active client's server.
if (SynchronizeClient(m_scene, NewPack, m_agentId, throttlePacketType))
{
return;
}
}
QueItem item = new QueItem();
item.Packet = NewPack;
item.Incoming = false;
@@ -2853,6 +2909,13 @@ namespace OpenSim.Region.ClientStack
}
}
private bool m_packetProcessingEnabled = true;
public bool PacketProcessingEnabled {
get { return m_packetProcessingEnabled; }
set { m_packetProcessingEnabled = value; }
}
protected void ProcessInPacket(Packet Pack)
{
ack_pack(Pack);
@@ -4373,5 +4436,79 @@ namespace OpenSim.Region.ClientStack
OutPacket(logReply, ThrottleOutPacketType.Task);
}
public ClientInfo GetClientInfo()
{
//MainLog.Instance.Verbose("CLIENT", "GetClientInfo BGN");
ClientInfo info = new ClientInfo();
info.userEP = this.m_userEndPoint;
info.proxyEP = this.m_proxyEndPoint;
info.agentcircuit = new sAgentCircuitData(RequestClientInfo());
info.pendingAcks = m_pendingAcks;
info.needAck = new Dictionary<uint,byte[]>();
lock (m_needAck)
{
foreach (uint key in m_needAck.Keys)
{
info.needAck.Add(key, m_needAck[key].ToBytes());
}
}
/* pending
QueItem[] queitems = m_packetQueue.GetQueueArray();
MainLog.Instance.Verbose("CLIENT", "Queue Count : [{0}]", queitems.Length);
for (int i = 0; i < queitems.Length; i++)
{
if (queitems[i].Incoming == false)
{
info.out_packets.Add(queitems[i].Packet.ToBytes());
MainLog.Instance.Verbose("CLIENT", "Add OutPacket [{0}]", queitems[i].Packet.Type.ToString());
}
}
*/
info.sequence = m_sequence;
//MainLog.Instance.Verbose("CLIENT", "GetClientInfo END");
return info;
}
public void SetClientInfo(ClientInfo info)
{
m_pendingAcks = info.pendingAcks;
m_needAck = new Dictionary<uint,Packet>();
Packet packet = null;
int packetEnd = 0;
byte[] zero = new byte[3000];
foreach (uint key in info.needAck.Keys)
{
byte[] buff = info.needAck[key];
packetEnd = buff.Length - 1;
try
{
packet = PacketPool.Instance.GetPacket(buff, ref packetEnd, zero);
}
catch (Exception)
{
//MainLog.Instance.Debug("UDPSERVER", e.ToString());
}
m_needAck.Add(key, packet);
}
m_sequence = info.sequence;
}
}
}

View File

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

View File

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

View File

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

View File

@@ -43,12 +43,15 @@ namespace OpenSim.Region.ClientStack
protected Dictionary<EndPoint, uint> clientCircuits = new Dictionary<EndPoint, uint>();
public Dictionary<uint, EndPoint> clientCircuits_reverse = new Dictionary<uint, EndPoint>();
protected Dictionary<uint, EndPoint> proxyCircuits = new Dictionary<uint, EndPoint>();
public Socket Server;
protected IPEndPoint ServerIncoming;
protected byte[] RecvBuffer = new byte[4096];
protected byte[] ZeroBuffer = new byte[8192];
protected IPEndPoint ipeSender;
protected EndPoint epSender;
protected EndPoint epProxy;
protected int proxyPortOffset;
protected AsyncCallback ReceivedData;
protected PacketServer m_packetServer;
protected ulong m_regionHandle;
@@ -85,10 +88,11 @@ namespace OpenSim.Region.ClientStack
{
}
public UDPServer(IPAddress _listenIP, ref uint port, bool allow_alternate_port, AssetCache assetCache, AgentCircuitManager authenticateClass)
public UDPServer(IPAddress _listenIP, ref uint port, int proxyPortOffset, bool allow_alternate_port, AssetCache assetCache, AgentCircuitManager authenticateClass)
{
this.proxyPortOffset = proxyPortOffset;
listenPort = (uint) (port + proxyPortOffset);
listenIP = _listenIP;
listenPort = port;
Allow_Alternate_Port = allow_alternate_port;
m_assetCache = assetCache;
m_authenticateSessionsClass = authenticateClass;
@@ -97,7 +101,7 @@ namespace OpenSim.Region.ClientStack
// Return new port
// This because in Grid mode it is not really important what port the region listens to as long as it is correctly registered.
// So the option allow_alternate_ports="true" was added to default.xml
port = listenPort;
port = (uint)(listenPort - proxyPortOffset);
}
protected virtual void CreatePacketServer()
@@ -211,6 +215,13 @@ namespace OpenSim.Region.ClientStack
//return;
}
//System.Console.WriteLine("UDPServer : recieved message from {0}", epSender.ToString());
epProxy = epSender;
if (proxyPortOffset != 0)
{
epSender = PacketPool.DecodeProxyMessage(RecvBuffer, ref numBytes);
}
int packetEnd = numBytes - 1;
try
@@ -318,6 +329,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()
@@ -387,10 +411,20 @@ namespace OpenSim.Region.ClientStack
lock (clientCircuits_reverse)
{
if (clientCircuits_reverse.TryGetValue(circuitcode, out sendto))
{
//we found the endpoint so send the packet to it
Server.SendTo(buffer, size, flags, 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);
}
}
}
}
@@ -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);
}
}
}