mirror of
https://github.com/opensim/opensim.git
synced 2026-08-05 08:55:56 +08:00
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:
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user