Merge branch 'master' of /home/opensim/var/repo/opensim
commit
95dc97c0c4
|
@ -34,14 +34,12 @@ namespace OpenSim.Framework.Statistics
|
|||
{
|
||||
private static AssetStatsCollector assetStats;
|
||||
private static UserStatsCollector userStats;
|
||||
private static SimExtraStatsCollector simExtraStats;
|
||||
private static SimExtraStatsCollector simExtraStats = new SimExtraStatsCollector();
|
||||
|
||||
public static AssetStatsCollector AssetStats { get { return assetStats; } }
|
||||
public static UserStatsCollector UserStats { get { return userStats; } }
|
||||
public static SimExtraStatsCollector SimExtraStats { get { return simExtraStats; } }
|
||||
|
||||
private StatsManager() {}
|
||||
|
||||
/// <summary>
|
||||
/// Start collecting statistics related to assets.
|
||||
/// Should only be called once.
|
||||
|
@ -63,16 +61,5 @@ namespace OpenSim.Framework.Statistics
|
|||
|
||||
return userStats;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start collecting extra sim statistics apart from those collected for the client.
|
||||
/// Should only be called once.
|
||||
/// </summary>
|
||||
public static SimExtraStatsCollector StartCollectingSimExtraStats()
|
||||
{
|
||||
simExtraStats = new SimExtraStatsCollector();
|
||||
|
||||
return simExtraStats;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -486,10 +486,10 @@ namespace OpenSim
|
|||
else
|
||||
presence.ControllingClient.Kick("\nThe OpenSim manager kicked you out.\n");
|
||||
|
||||
// ...and close on our side
|
||||
presence.Scene.IncomingCloseAgent(presence.UUID);
|
||||
}
|
||||
}
|
||||
|
||||
MainConsole.Instance.Output("");
|
||||
}
|
||||
|
||||
|
|
|
@ -223,8 +223,6 @@ namespace OpenSim
|
|||
|
||||
base.StartupSpecific();
|
||||
|
||||
m_stats = StatsManager.StartCollectingSimExtraStats();
|
||||
|
||||
// Create a ModuleLoader instance
|
||||
m_moduleLoader = new ModuleLoader(m_config.Source);
|
||||
|
||||
|
|
|
@ -39,7 +39,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
public sealed class IncomingPacket
|
||||
{
|
||||
/// <summary>Client this packet came from</summary>
|
||||
public LLUDPClient Client;
|
||||
public LLClientView Client;
|
||||
|
||||
/// <summary>Packet data that has been received</summary>
|
||||
public Packet Packet;
|
||||
|
||||
|
@ -48,7 +49,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
/// </summary>
|
||||
/// <param name="client">Reference to the client this packet came from</param>
|
||||
/// <param name="packet">Packet data</param>
|
||||
public IncomingPacket(LLUDPClient client, Packet packet)
|
||||
public IncomingPacket(LLClientView client, Packet packet)
|
||||
{
|
||||
Client = client;
|
||||
Packet = packet;
|
||||
|
|
|
@ -494,10 +494,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
"[CLIENT]: Close has been called for {0} attached to scene {1}",
|
||||
Name, m_scene.RegionInfo.RegionName);
|
||||
|
||||
// Send the STOP packet
|
||||
DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
|
||||
OutPacket(disable, ThrottleOutPacketType.Unknown);
|
||||
|
||||
IsActive = false;
|
||||
|
||||
// Shutdown the image manager
|
||||
|
|
|
@ -147,11 +147,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
private int m_elapsed500MSOutgoingPacketHandler;
|
||||
|
||||
/// <summary>Flag to signal when clients should check for resends</summary>
|
||||
private bool m_resendUnacked;
|
||||
protected bool m_resendUnacked;
|
||||
|
||||
/// <summary>Flag to signal when clients should send ACKs</summary>
|
||||
private bool m_sendAcks;
|
||||
protected bool m_sendAcks;
|
||||
|
||||
/// <summary>Flag to signal when clients should send pings</summary>
|
||||
private bool m_sendPing;
|
||||
protected bool m_sendPing;
|
||||
|
||||
private int m_defaultRTO = 0;
|
||||
private int m_maxRTO = 0;
|
||||
|
@ -537,8 +539,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
SendPacket(udpClient, completePing, ThrottleOutPacketType.Unknown, false, null);
|
||||
}
|
||||
|
||||
public void HandleUnacked(LLUDPClient udpClient)
|
||||
public void HandleUnacked(LLClientView client)
|
||||
{
|
||||
LLUDPClient udpClient = client.UDPClient;
|
||||
|
||||
if (!udpClient.IsConnected)
|
||||
return;
|
||||
|
||||
|
@ -551,12 +555,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
if (udpClient.IsPaused)
|
||||
timeoutTicks = m_pausedAckTimeout;
|
||||
|
||||
if ((Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > timeoutTicks)
|
||||
if (!client.IsLoggingOut &&
|
||||
(Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > timeoutTicks)
|
||||
{
|
||||
m_log.Warn("[LLUDPSERVER]: Ack timeout, disconnecting " + udpClient.AgentID);
|
||||
StatsManager.SimExtraStats.AddAbnormalClientThreadTermination();
|
||||
RemoveClient(client);
|
||||
|
||||
RemoveClient(udpClient);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -879,7 +884,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
#endregion Ping Check Handling
|
||||
|
||||
// Inbox insertion
|
||||
packetInbox.Enqueue(new IncomingPacket(udpClient, packet));
|
||||
packetInbox.Enqueue(new IncomingPacket((LLClientView)client, packet));
|
||||
}
|
||||
|
||||
#region BinaryStats
|
||||
|
@ -1105,21 +1110,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
return client;
|
||||
}
|
||||
|
||||
private void RemoveClient(LLUDPClient udpClient)
|
||||
{
|
||||
// Remove this client from the scene
|
||||
IClientAPI client;
|
||||
if (m_scene.TryGetClient(udpClient.AgentID, out client))
|
||||
private void RemoveClient(IClientAPI client)
|
||||
{
|
||||
// We must set IsLoggingOut synchronously so that we can stop the packet loop reinvoking this method.
|
||||
client.IsLoggingOut = true;
|
||||
client.Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[LLUDPSERVER]: Tried to remove client with id {0} but not such client in {1}",
|
||||
udpClient.AgentID, m_scene.RegionInfo.RegionName);
|
||||
}
|
||||
|
||||
// Fire this out on a different thread so that we don't hold up outgoing packet processing for
|
||||
// everybody else if this is being called due to an ack timeout.
|
||||
// This is the same as processing as the async process of a logout request.
|
||||
Util.FireAndForget(o => client.Close());
|
||||
}
|
||||
|
||||
private void IncomingPacketHandler()
|
||||
|
@ -1244,7 +1243,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
Watchdog.RemoveThread();
|
||||
}
|
||||
|
||||
private void ClientOutgoingPacketHandler(IClientAPI client)
|
||||
protected void ClientOutgoingPacketHandler(IClientAPI client)
|
||||
{
|
||||
m_currentOutgoingClient = client;
|
||||
|
||||
|
@ -1252,12 +1251,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
{
|
||||
if (client is LLClientView)
|
||||
{
|
||||
LLUDPClient udpClient = ((LLClientView)client).UDPClient;
|
||||
LLClientView llClient = (LLClientView)client;
|
||||
LLUDPClient udpClient = llClient.UDPClient;
|
||||
|
||||
if (udpClient.IsConnected)
|
||||
{
|
||||
if (m_resendUnacked)
|
||||
HandleUnacked(udpClient);
|
||||
HandleUnacked(llClient);
|
||||
|
||||
if (m_sendAcks)
|
||||
SendAcks(udpClient);
|
||||
|
@ -1306,7 +1306,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
{
|
||||
if (client is LLClientView)
|
||||
{
|
||||
LLUDPClient udpClient = ((LLClientView)client).UDPClient;
|
||||
LLClientView llClient = (LLClientView)client;
|
||||
LLUDPClient udpClient = llClient.UDPClient;
|
||||
|
||||
if (udpClient.IsConnected)
|
||||
{
|
||||
|
@ -1315,7 +1316,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
nticksUnack++;
|
||||
watch2.Start();
|
||||
|
||||
HandleUnacked(udpClient);
|
||||
HandleUnacked(llClient);
|
||||
|
||||
watch2.Stop();
|
||||
avgResendUnackedTicks = (nticksUnack - 1)/(float)nticksUnack * avgResendUnackedTicks + (watch2.ElapsedTicks / (float)nticksUnack);
|
||||
|
@ -1386,22 +1387,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
|
||||
#endregion
|
||||
|
||||
private void ProcessInPacket(object state)
|
||||
private void ProcessInPacket(IncomingPacket incomingPacket)
|
||||
{
|
||||
IncomingPacket incomingPacket = (IncomingPacket)state;
|
||||
Packet packet = incomingPacket.Packet;
|
||||
LLUDPClient udpClient = incomingPacket.Client;
|
||||
IClientAPI client;
|
||||
LLClientView client = incomingPacket.Client;
|
||||
|
||||
// Sanity check
|
||||
if (packet == null || udpClient == null)
|
||||
{
|
||||
m_log.WarnFormat("[LLUDPSERVER]: Processing a packet with incomplete state. Packet=\"{0}\", UDPClient=\"{1}\"",
|
||||
packet, udpClient);
|
||||
}
|
||||
|
||||
// Make sure this client is still alive
|
||||
if (m_scene.TryGetClient(udpClient.AgentID, out client))
|
||||
if (client.IsActive)
|
||||
{
|
||||
m_currentIncomingClient = client;
|
||||
|
||||
|
@ -1419,8 +1410,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
catch (Exception e)
|
||||
{
|
||||
// Don't let a failure in an individual client thread crash the whole sim.
|
||||
m_log.ErrorFormat("[LLUDPSERVER]: Client packet handler for {0} for packet {1} threw an exception", udpClient.AgentID, packet.Type);
|
||||
m_log.Error(e.Message, e);
|
||||
m_log.Error(
|
||||
string.Format(
|
||||
"[LLUDPSERVER]: Client packet handler for {0} for packet {1} threw ",
|
||||
client.Name, packet.Type),
|
||||
e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -1431,15 +1425,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
{
|
||||
m_log.DebugFormat(
|
||||
"[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}",
|
||||
packet.Type, udpClient.AgentID, m_scene.RegionInfo.RegionName);
|
||||
packet.Type, client.Name, m_scene.RegionInfo.RegionName);
|
||||
}
|
||||
}
|
||||
|
||||
protected void LogoutHandler(IClientAPI client)
|
||||
{
|
||||
client.SendLogoutPacket();
|
||||
if (client.IsActive)
|
||||
RemoveClient(((LLClientView)client).UDPClient);
|
||||
if (!client.IsLoggingOut)
|
||||
RemoveClient(client);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -45,6 +45,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
|||
[TestFixture]
|
||||
public class BasicCircuitTests
|
||||
{
|
||||
private Scene m_scene;
|
||||
private TestLLUDPServer m_udpServer;
|
||||
|
||||
[TestFixtureSetUp]
|
||||
public void FixtureInit()
|
||||
{
|
||||
|
@ -61,83 +64,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
|||
Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
|
||||
}
|
||||
|
||||
// /// <summary>
|
||||
// /// Add a client for testing
|
||||
// /// </summary>
|
||||
// /// <param name="scene"></param>
|
||||
// /// <param name="testLLUDPServer"></param>
|
||||
// /// <param name="testPacketServer"></param>
|
||||
// /// <param name="acm">Agent circuit manager used in setting up the stack</param>
|
||||
// protected void SetupStack(
|
||||
// IScene scene, out TestLLUDPServer testLLUDPServer, out TestLLPacketServer testPacketServer,
|
||||
// out AgentCircuitManager acm)
|
||||
// {
|
||||
// IConfigSource configSource = new IniConfigSource();
|
||||
// ClientStackUserSettings userSettings = new ClientStackUserSettings();
|
||||
// testLLUDPServer = new TestLLUDPServer();
|
||||
// acm = new AgentCircuitManager();
|
||||
//
|
||||
// uint port = 666;
|
||||
// testLLUDPServer.Initialise(null, ref port, 0, false, configSource, acm);
|
||||
// testPacketServer = new TestLLPacketServer(testLLUDPServer, userSettings);
|
||||
// testLLUDPServer.LocalScene = scene;
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// Set up a client for tests which aren't concerned with this process itself and where only one client is being
|
||||
// /// tested
|
||||
// /// </summary>
|
||||
// /// <param name="circuitCode"></param>
|
||||
// /// <param name="epSender"></param>
|
||||
// /// <param name="testLLUDPServer"></param>
|
||||
// /// <param name="acm"></param>
|
||||
// protected void AddClient(
|
||||
// uint circuitCode, EndPoint epSender, TestLLUDPServer testLLUDPServer, AgentCircuitManager acm)
|
||||
// {
|
||||
// UUID myAgentUuid = UUID.Parse("00000000-0000-0000-0000-000000000001");
|
||||
// UUID mySessionUuid = UUID.Parse("00000000-0000-0000-0000-000000000002");
|
||||
//
|
||||
// AddClient(circuitCode, epSender, myAgentUuid, mySessionUuid, testLLUDPServer, acm);
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// Set up a client for tests which aren't concerned with this process itself
|
||||
// /// </summary>
|
||||
// /// <param name="circuitCode"></param>
|
||||
// /// <param name="epSender"></param>
|
||||
// /// <param name="agentId"></param>
|
||||
// /// <param name="sessionId"></param>
|
||||
// /// <param name="testLLUDPServer"></param>
|
||||
// /// <param name="acm"></param>
|
||||
// protected void AddClient(
|
||||
// uint circuitCode, EndPoint epSender, UUID agentId, UUID sessionId,
|
||||
// TestLLUDPServer testLLUDPServer, AgentCircuitManager acm)
|
||||
// {
|
||||
// AgentCircuitData acd = new AgentCircuitData();
|
||||
// acd.AgentID = agentId;
|
||||
// acd.SessionID = sessionId;
|
||||
//
|
||||
// UseCircuitCodePacket uccp = new UseCircuitCodePacket();
|
||||
//
|
||||
// UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock
|
||||
// = new UseCircuitCodePacket.CircuitCodeBlock();
|
||||
// uccpCcBlock.Code = circuitCode;
|
||||
// uccpCcBlock.ID = agentId;
|
||||
// uccpCcBlock.SessionID = sessionId;
|
||||
// uccp.CircuitCode = uccpCcBlock;
|
||||
//
|
||||
// acm.AddNewCircuit(circuitCode, acd);
|
||||
//
|
||||
// testLLUDPServer.LoadReceive(uccp, epSender);
|
||||
// testLLUDPServer.ReceiveData(null);
|
||||
// }
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
m_scene = new SceneHelpers().SetupScene();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Build an object name packet for test purposes
|
||||
/// </summary>
|
||||
/// <param name="objectLocalId"></param>
|
||||
/// <param name="objectName"></param>
|
||||
protected ObjectNamePacket BuildTestObjectNamePacket(uint objectLocalId, string objectName)
|
||||
private ObjectNamePacket BuildTestObjectNamePacket(uint objectLocalId, string objectName)
|
||||
{
|
||||
ObjectNamePacket onp = new ObjectNamePacket();
|
||||
ObjectNamePacket.ObjectDataBlock odb = new ObjectNamePacket.ObjectDataBlock();
|
||||
|
@ -149,28 +87,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
|||
return onp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test adding a client to the stack
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestAddClient()
|
||||
private void AddUdpServer()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// XmlConfigurator.Configure();
|
||||
AddUdpServer(new IniConfigSource());
|
||||
}
|
||||
|
||||
TestScene scene = new SceneHelpers().SetupScene();
|
||||
uint myCircuitCode = 123456;
|
||||
private void AddUdpServer(IniConfigSource configSource)
|
||||
{
|
||||
uint port = 0;
|
||||
AgentCircuitManager acm = m_scene.AuthenticateHandler;
|
||||
|
||||
m_udpServer = new TestLLUDPServer(IPAddress.Any, ref port, 0, false, configSource, acm);
|
||||
m_udpServer.AddScene(m_scene);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used by tests that aren't testing this stage.
|
||||
/// </summary>
|
||||
private ScenePresence AddClient()
|
||||
{
|
||||
UUID myAgentUuid = TestHelpers.ParseTail(0x1);
|
||||
UUID mySessionUuid = TestHelpers.ParseTail(0x2);
|
||||
uint myCircuitCode = 123456;
|
||||
IPEndPoint testEp = new IPEndPoint(IPAddress.Loopback, 999);
|
||||
|
||||
uint port = 0;
|
||||
AgentCircuitManager acm = scene.AuthenticateHandler;
|
||||
|
||||
TestLLUDPServer llUdpServer
|
||||
= new TestLLUDPServer(IPAddress.Any, ref port, 0, false, new IniConfigSource(), acm);
|
||||
llUdpServer.AddScene(scene);
|
||||
|
||||
UseCircuitCodePacket uccp = new UseCircuitCodePacket();
|
||||
|
||||
UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock
|
||||
|
@ -185,26 +125,67 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
|||
upb.DataLength = uccpBytes.Length; // God knows why this isn't set by the constructor.
|
||||
Buffer.BlockCopy(uccpBytes, 0, upb.Data, 0, uccpBytes.Length);
|
||||
|
||||
llUdpServer.PacketReceived(upb);
|
||||
AgentCircuitData acd = new AgentCircuitData();
|
||||
acd.AgentID = myAgentUuid;
|
||||
acd.SessionID = mySessionUuid;
|
||||
|
||||
m_scene.AuthenticateHandler.AddNewCircuit(myCircuitCode, acd);
|
||||
|
||||
m_udpServer.PacketReceived(upb);
|
||||
|
||||
return m_scene.GetScenePresence(myAgentUuid);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test adding a client to the stack
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestAddClient()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// XmlConfigurator.Configure();
|
||||
|
||||
AddUdpServer();
|
||||
|
||||
UUID myAgentUuid = TestHelpers.ParseTail(0x1);
|
||||
UUID mySessionUuid = TestHelpers.ParseTail(0x2);
|
||||
uint myCircuitCode = 123456;
|
||||
IPEndPoint testEp = new IPEndPoint(IPAddress.Loopback, 999);
|
||||
|
||||
UseCircuitCodePacket uccp = new UseCircuitCodePacket();
|
||||
|
||||
UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock
|
||||
= new UseCircuitCodePacket.CircuitCodeBlock();
|
||||
uccpCcBlock.Code = myCircuitCode;
|
||||
uccpCcBlock.ID = myAgentUuid;
|
||||
uccpCcBlock.SessionID = mySessionUuid;
|
||||
uccp.CircuitCode = uccpCcBlock;
|
||||
|
||||
byte[] uccpBytes = uccp.ToBytes();
|
||||
UDPPacketBuffer upb = new UDPPacketBuffer(testEp, uccpBytes.Length);
|
||||
upb.DataLength = uccpBytes.Length; // God knows why this isn't set by the constructor.
|
||||
Buffer.BlockCopy(uccpBytes, 0, upb.Data, 0, uccpBytes.Length);
|
||||
|
||||
m_udpServer.PacketReceived(upb);
|
||||
|
||||
// Presence shouldn't exist since the circuit manager doesn't know about this circuit for authentication yet
|
||||
Assert.That(scene.GetScenePresence(myAgentUuid), Is.Null);
|
||||
Assert.That(m_scene.GetScenePresence(myAgentUuid), Is.Null);
|
||||
|
||||
AgentCircuitData acd = new AgentCircuitData();
|
||||
acd.AgentID = myAgentUuid;
|
||||
acd.SessionID = mySessionUuid;
|
||||
|
||||
acm.AddNewCircuit(myCircuitCode, acd);
|
||||
m_scene.AuthenticateHandler.AddNewCircuit(myCircuitCode, acd);
|
||||
|
||||
llUdpServer.PacketReceived(upb);
|
||||
m_udpServer.PacketReceived(upb);
|
||||
|
||||
// Should succeed now
|
||||
ScenePresence sp = scene.GetScenePresence(myAgentUuid);
|
||||
ScenePresence sp = m_scene.GetScenePresence(myAgentUuid);
|
||||
Assert.That(sp.UUID, Is.EqualTo(myAgentUuid));
|
||||
|
||||
Assert.That(llUdpServer.PacketsSent.Count, Is.EqualTo(1));
|
||||
Assert.That(m_udpServer.PacketsSent.Count, Is.EqualTo(1));
|
||||
|
||||
Packet packet = llUdpServer.PacketsSent[0];
|
||||
Packet packet = m_udpServer.PacketsSent[0];
|
||||
Assert.That(packet, Is.InstanceOf(typeof(PacketAckPacket)));
|
||||
|
||||
PacketAckPacket ackPacket = packet as PacketAckPacket;
|
||||
|
@ -212,6 +193,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
|||
Assert.That(ackPacket.Packets[0].ID, Is.EqualTo(0));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestLogoutClientDueToAck()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// TestHelpers.EnableLogging();
|
||||
|
||||
IniConfigSource ics = new IniConfigSource();
|
||||
IConfig config = ics.AddConfig("ClientStack.LindenUDP");
|
||||
config.Set("AckTimeout", -1);
|
||||
AddUdpServer(ics);
|
||||
|
||||
ScenePresence sp = AddClient();
|
||||
m_udpServer.ClientOutgoingPacketHandler(sp.ControllingClient, true, false, false);
|
||||
|
||||
ScenePresence spAfterAckTimeout = m_scene.GetScenePresence(sp.UUID);
|
||||
Assert.That(spAfterAckTimeout, Is.Null);
|
||||
|
||||
// TestHelpers.DisableLogging();
|
||||
}
|
||||
|
||||
// /// <summary>
|
||||
// /// Test removing a client from the stack
|
||||
// /// </summary>
|
||||
|
|
|
@ -59,6 +59,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
|||
PacketsSent.Add(packet);
|
||||
}
|
||||
|
||||
public void ClientOutgoingPacketHandler(IClientAPI client, bool resendUnacked, bool sendAcks, bool sendPing)
|
||||
{
|
||||
m_resendUnacked = resendUnacked;
|
||||
m_sendAcks = sendAcks;
|
||||
m_sendPing = sendPing;
|
||||
|
||||
ClientOutgoingPacketHandler(client);
|
||||
}
|
||||
|
||||
//// /// <summary>
|
||||
//// /// The chunks of data to pass to the LLUDPServer when it calls EndReceive
|
||||
//// /// </summary>
|
||||
|
|
|
@ -42,8 +42,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
|||
public class AssetTransactionModule : INonSharedRegionModule,
|
||||
IAgentAssetTransactions
|
||||
{
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(
|
||||
// MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
protected Scene m_Scene;
|
||||
private bool m_dumpAssetsToFile = false;
|
||||
|
@ -209,15 +208,15 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
|||
/// and comes through this method.
|
||||
/// </summary>
|
||||
/// <param name="remoteClient"></param>
|
||||
/// <param name="part"></param>
|
||||
/// <param name="transactionID"></param>
|
||||
/// <param name="item"></param>
|
||||
public void HandleTaskItemUpdateFromTransaction(IClientAPI remoteClient,
|
||||
SceneObjectPart part, UUID transactionID,
|
||||
TaskInventoryItem item)
|
||||
public void HandleTaskItemUpdateFromTransaction(
|
||||
IClientAPI remoteClient, SceneObjectPart part, UUID transactionID, TaskInventoryItem item)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[TRANSACTIONS MANAGER] Called HandleTaskItemUpdateFromTransaction with item {0}",
|
||||
// item.Name);
|
||||
m_log.DebugFormat(
|
||||
"[TRANSACTIONS MANAGER] Called HandleTaskItemUpdateFromTransaction with item {0} in {1} for {2} in {3}",
|
||||
item.Name, part.Name, remoteClient.Name, m_Scene.RegionInfo.RegionName);
|
||||
|
||||
AgentAssetTransactions transactions =
|
||||
GetUserTransactions(remoteClient.AgentId);
|
||||
|
|
|
@ -644,7 +644,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
// an agent cannot teleport back to this region if it has teleported away.
|
||||
Thread.Sleep(2000);
|
||||
|
||||
sp.Close();
|
||||
sp.Scene.IncomingCloseAgent(sp.UUID);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -216,7 +216,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
|||
}
|
||||
else
|
||||
{
|
||||
IAgentAssetTransactions agentTransactions = m_Scene.RequestModuleInterface<IAgentAssetTransactions>();
|
||||
IAgentAssetTransactions agentTransactions = m_Scene.AgentTransactionsModule;
|
||||
if (agentTransactions != null)
|
||||
{
|
||||
agentTransactions.HandleItemCreationFromTransaction(
|
||||
|
|
|
@ -440,10 +440,9 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
else
|
||||
{
|
||||
IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>();
|
||||
if (agentTransactions != null)
|
||||
if (AgentTransactionsModule != null)
|
||||
{
|
||||
agentTransactions.HandleItemUpdateFromTransaction(remoteClient, transactionID, item);
|
||||
AgentTransactionsModule.HandleItemUpdateFromTransaction(remoteClient, transactionID, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1532,12 +1531,9 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
// Only look for an uploaded updated asset if we are passed a transaction ID. This is only the
|
||||
// case for updates uploded through UDP. Updates uploaded via a capability (e.g. a script update)
|
||||
// will not pass in a transaction ID in the update message.
|
||||
if (transactionID != UUID.Zero)
|
||||
if (transactionID != UUID.Zero && AgentTransactionsModule != null)
|
||||
{
|
||||
IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>();
|
||||
if (agentTransactions != null)
|
||||
{
|
||||
agentTransactions.HandleTaskItemUpdateFromTransaction(
|
||||
AgentTransactionsModule.HandleTaskItemUpdateFromTransaction(
|
||||
remoteClient, part, transactionID, currentItem);
|
||||
|
||||
if ((InventoryType)itemInfo.InvType == InventoryType.Notecard)
|
||||
|
@ -1547,7 +1543,6 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
else
|
||||
remoteClient.SendAgentAlertMessage("Item saved", false);
|
||||
}
|
||||
}
|
||||
|
||||
// Base ALWAYS has move
|
||||
currentItem.BasePermissions |= (uint)PermissionMask.Move;
|
||||
|
|
|
@ -499,6 +499,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
public IAttachmentsModule AttachmentsModule { get; set; }
|
||||
public IEntityTransferModule EntityTransferModule { get; private set; }
|
||||
public IAgentAssetTransactions AgentTransactionsModule { get; private set; }
|
||||
|
||||
public IAvatarFactoryModule AvatarFactory
|
||||
{
|
||||
|
@ -939,7 +940,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
else
|
||||
{
|
||||
m_log.InfoFormat(
|
||||
"[INTERGRID]: Got notice about far away Region: {0} at ({1}, {2})",
|
||||
"[SCENE]: Got notice about far away Region: {0} at ({1}, {2})",
|
||||
otherRegion.RegionName, otherRegion.RegionLocX, otherRegion.RegionLocY);
|
||||
}
|
||||
}
|
||||
|
@ -1241,6 +1242,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
m_capsModule = RequestModuleInterface<ICapabilitiesModule>();
|
||||
EntityTransferModule = RequestModuleInterface<IEntityTransferModule>();
|
||||
m_groupsModule = RequestModuleInterface<IGroupsModule>();
|
||||
AgentTransactionsModule = RequestModuleInterface<IAgentAssetTransactions>();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -3229,21 +3231,44 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
// CheckHeartbeat();
|
||||
bool isChildAgent = false;
|
||||
ScenePresence avatar = GetScenePresence(agentID);
|
||||
if (avatar != null)
|
||||
{
|
||||
isChildAgent = avatar.IsChildAgent;
|
||||
|
||||
if (avatar.ParentID != 0)
|
||||
if (avatar == null)
|
||||
{
|
||||
avatar.StandUp();
|
||||
m_log.WarnFormat(
|
||||
"[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in the scene.", agentID);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
isChildAgent = avatar.IsChildAgent;
|
||||
|
||||
m_log.DebugFormat(
|
||||
"[SCENE]: Removing {0} agent {1} {2} from region {3}",
|
||||
"[SCENE]: Removing {0} agent {1} {2} from {3}",
|
||||
(isChildAgent ? "child" : "root"), avatar.Name, agentID, RegionInfo.RegionName);
|
||||
|
||||
// Don't do this to root agents, it's not nice for the viewer
|
||||
if (closeChildAgents && isChildAgent)
|
||||
{
|
||||
// Tell a single agent to disconnect from the region.
|
||||
IEventQueue eq = RequestModuleInterface<IEventQueue>();
|
||||
if (eq != null)
|
||||
{
|
||||
eq.DisableSimulator(RegionInfo.RegionHandle, avatar.UUID);
|
||||
}
|
||||
else
|
||||
{
|
||||
avatar.ControllingClient.SendShutdownConnectionNotice();
|
||||
}
|
||||
}
|
||||
|
||||
// Only applies to root agents.
|
||||
if (avatar.ParentID != 0)
|
||||
{
|
||||
avatar.StandUp();
|
||||
}
|
||||
|
||||
m_sceneGraph.removeUserCount(!isChildAgent);
|
||||
|
||||
// TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop
|
||||
|
@ -3255,7 +3280,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
// this method is doing is HORRIBLE!!!
|
||||
avatar.Scene.NeedSceneCacheClear(avatar.UUID);
|
||||
|
||||
if (closeChildAgents && !avatar.IsChildAgent)
|
||||
if (closeChildAgents && !isChildAgent)
|
||||
{
|
||||
List<ulong> regions = avatar.KnownRegionHandles;
|
||||
regions.Remove(RegionInfo.RegionHandle);
|
||||
|
@ -3263,18 +3288,11 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
|
||||
m_eventManager.TriggerClientClosed(agentID, this);
|
||||
}
|
||||
catch (NullReferenceException)
|
||||
{
|
||||
// We don't know which count to remove it from
|
||||
// Avatar is already disposed :/
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
m_eventManager.TriggerOnRemovePresence(agentID);
|
||||
|
||||
if (AttachmentsModule != null && !isChildAgent && avatar.PresenceType != PresenceType.Npc)
|
||||
if (!isChildAgent)
|
||||
{
|
||||
if (AttachmentsModule != null && avatar.PresenceType != PresenceType.Npc)
|
||||
{
|
||||
IUserManagement uMan = RequestModuleInterface<IUserManagement>();
|
||||
// Don't save attachments for HG visitors, it
|
||||
|
@ -3294,12 +3312,20 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
try { client.SendKillObject(avatar.RegionHandle, new List<uint> { avatar.LocalId }); }
|
||||
catch (NullReferenceException) { }
|
||||
});
|
||||
|
||||
IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>();
|
||||
if (agentTransactions != null)
|
||||
{
|
||||
agentTransactions.RemoveAgentAssetTransactions(agentID);
|
||||
}
|
||||
|
||||
// It's possible for child agents to have transactions if changes are being made cross-border.
|
||||
if (AgentTransactionsModule != null)
|
||||
AgentTransactionsModule.RemoveAgentAssetTransactions(agentID);
|
||||
|
||||
avatar.Close();
|
||||
|
||||
m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error(
|
||||
string.Format("[SCENE]: Exception removing {0} from {1}, ", avatar.Name, RegionInfo.RegionName), e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -3312,25 +3338,9 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
m_clientManager.Remove(agentID);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
avatar.Close();
|
||||
}
|
||||
catch (NullReferenceException)
|
||||
{
|
||||
//We can safely ignore null reference exceptions. It means the avatar are dead and cleaned up anyway.
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[SCENE] Scene.cs:RemoveClient exception {0}{1}", e.Message, e.StackTrace);
|
||||
}
|
||||
|
||||
m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode);
|
||||
// CleanDroppedAttachments();
|
||||
//m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false));
|
||||
//m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes region from an avatar's known region list. This coincides with child agents. For each child agent, there will be a known region entry.
|
||||
|
@ -4020,29 +4030,6 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
ScenePresence presence = m_sceneGraph.GetScenePresence(agentID);
|
||||
if (presence != null)
|
||||
{
|
||||
// Nothing is removed here, so down count it as such
|
||||
if (presence.IsChildAgent)
|
||||
{
|
||||
m_sceneGraph.removeUserCount(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_sceneGraph.removeUserCount(true);
|
||||
}
|
||||
|
||||
// Don't do this to root agents on logout, it's not nice for the viewer
|
||||
if (presence.IsChildAgent)
|
||||
{
|
||||
// Tell a single agent to disconnect from the region.
|
||||
IEventQueue eq = RequestModuleInterface<IEventQueue>();
|
||||
if (eq != null)
|
||||
{
|
||||
eq.DisableSimulator(RegionInfo.RegionHandle, agentID);
|
||||
}
|
||||
else
|
||||
presence.ControllingClient.SendShutdownConnectionNotice();
|
||||
}
|
||||
|
||||
presence.ControllingClient.Close();
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -84,16 +84,16 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
if (neighbourService != null)
|
||||
neighbour = neighbourService.HelloNeighbour(regionhandle, region);
|
||||
else
|
||||
m_log.DebugFormat("[SCS]: No neighbour service provided for informing neigbhours of this region");
|
||||
m_log.DebugFormat("[SCENE COMMUNICATION SERVICE]: No neighbour service provided for informing neigbhours of this region");
|
||||
|
||||
if (neighbour != null)
|
||||
{
|
||||
m_log.DebugFormat("[INTERGRID]: Successfully informed neighbour {0}-{1} that I'm here", x / Constants.RegionSize, y / Constants.RegionSize);
|
||||
m_log.DebugFormat("[SCENE COMMUNICATION SERVICE]: Successfully informed neighbour {0}-{1} that I'm here", x / Constants.RegionSize, y / Constants.RegionSize);
|
||||
m_scene.EventManager.TriggerOnRegionUp(neighbour);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.InfoFormat("[INTERGRID]: Failed to inform neighbour {0}-{1} that I'm here.", x / Constants.RegionSize, y / Constants.RegionSize);
|
||||
m_log.InfoFormat("[SCENE COMMUNICATION SERVICE]: Failed to inform neighbour {0}-{1} that I'm here.", x / Constants.RegionSize, y / Constants.RegionSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,7 +102,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
//m_log.Info("[INTER]: " + debugRegionName + ": SceneCommunicationService: Sending InterRegion Notification that region is up " + region.RegionName);
|
||||
|
||||
List<GridRegion> neighbours = m_scene.GridService.GetNeighbours(m_scene.RegionInfo.ScopeID, m_scene.RegionInfo.RegionID);
|
||||
m_log.DebugFormat("[INTERGRID]: Informing {0} neighbours that this region is up", neighbours.Count);
|
||||
m_log.DebugFormat("[SCENE COMMUNICATION SERVICE]: Informing {0} neighbours that this region is up", neighbours.Count);
|
||||
foreach (GridRegion n in neighbours)
|
||||
{
|
||||
InformNeighbourThatRegionUpDelegate d = InformNeighboursThatRegionIsUpAsync;
|
||||
|
@ -196,8 +196,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
GridRegion destination = m_scene.GridService.GetRegionByPosition(m_regionInfo.ScopeID, (int)x, (int)y);
|
||||
|
||||
m_log.DebugFormat(
|
||||
"[INTERGRID]: Sending close agent {0} to region at {1}-{2}",
|
||||
agentID, destination.RegionCoordX, destination.RegionCoordY);
|
||||
"[SCENE COMMUNICATION SERVICE]: Sending close agent ID {0} to {1}", agentID, destination.RegionName);
|
||||
|
||||
m_scene.SimulationService.CloseAgent(destination, agentID);
|
||||
}
|
||||
|
|
|
@ -702,12 +702,6 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
public int GetChildAgentCount()
|
||||
{
|
||||
// some network situations come in where child agents get closed twice.
|
||||
if (m_numChildAgents < 0)
|
||||
{
|
||||
m_numChildAgents = 0;
|
||||
}
|
||||
|
||||
return m_numChildAgents;
|
||||
}
|
||||
|
||||
|
|
|
@ -3416,7 +3416,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
public void Close()
|
||||
{
|
||||
if (!IsChildAgent)
|
||||
if (!IsChildAgent && m_scene.AttachmentsModule != null)
|
||||
m_scene.AttachmentsModule.DeleteAttachmentsFromScene(this, false);
|
||||
|
||||
// Clear known regions
|
||||
|
|
|
@ -101,7 +101,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
|
|||
public void TestCloseAgent()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
// TestHelpers.EnableLogging();
|
||||
|
||||
TestScene scene = new SceneHelpers().SetupScene();
|
||||
ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1));
|
||||
|
@ -114,6 +114,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests
|
|||
Assert.That(scene.GetScenePresence(sp.UUID), Is.Null);
|
||||
Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(sp.UUID), Is.Null);
|
||||
Assert.That(scene.AuthenticateHandler.GetAgentCircuits().Count, Is.EqualTo(0));
|
||||
|
||||
// TestHelpers.DisableLogging();
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
|
|
@ -97,6 +97,9 @@ namespace OpenSim.Region.Framework.Scenes.Tests
|
|||
|
||||
Assert.That(sp.AbsolutePosition, Is.EqualTo(teleportPosition));
|
||||
|
||||
Assert.That(scene.GetRootAgentCount(), Is.EqualTo(1));
|
||||
Assert.That(scene.GetChildAgentCount(), Is.EqualTo(0));
|
||||
|
||||
// Lookat is sent to the client only - sp.Lookat does not yield the same thing (calculation from camera
|
||||
// position instead).
|
||||
// Assert.That(sp.Lookat, Is.EqualTo(teleportLookAt));
|
||||
|
@ -158,6 +161,11 @@ namespace OpenSim.Region.Framework.Scenes.Tests
|
|||
Assert.That(sceneBSp.Scene.RegionInfo.RegionName, Is.EqualTo(sceneB.RegionInfo.RegionName));
|
||||
Assert.That(sceneBSp.AbsolutePosition, Is.EqualTo(teleportPosition));
|
||||
|
||||
Assert.That(sceneA.GetRootAgentCount(), Is.EqualTo(0));
|
||||
Assert.That(sceneA.GetChildAgentCount(), Is.EqualTo(0));
|
||||
Assert.That(sceneB.GetRootAgentCount(), Is.EqualTo(1));
|
||||
Assert.That(sceneB.GetChildAgentCount(), Is.EqualTo(0));
|
||||
|
||||
// TODO: Add assertions to check correct circuit details in both scenes.
|
||||
|
||||
// Lookat is sent to the client only - sp.Lookat does not yield the same thing (calculation from camera
|
||||
|
@ -235,6 +243,11 @@ namespace OpenSim.Region.Framework.Scenes.Tests
|
|||
Assert.That(sceneASp.Scene.RegionInfo.RegionName, Is.EqualTo(sceneA.RegionInfo.RegionName));
|
||||
Assert.That(sceneASp.AbsolutePosition, Is.EqualTo(preTeleportPosition));
|
||||
|
||||
Assert.That(sceneA.GetRootAgentCount(), Is.EqualTo(1));
|
||||
Assert.That(sceneA.GetChildAgentCount(), Is.EqualTo(0));
|
||||
Assert.That(sceneB.GetRootAgentCount(), Is.EqualTo(0));
|
||||
Assert.That(sceneB.GetChildAgentCount(), Is.EqualTo(0));
|
||||
|
||||
// TODO: Add assertions to check correct circuit details in both scenes.
|
||||
|
||||
// Lookat is sent to the client only - sp.Lookat does not yield the same thing (calculation from camera
|
||||
|
@ -306,6 +319,11 @@ namespace OpenSim.Region.Framework.Scenes.Tests
|
|||
Assert.That(sceneASp.Scene.RegionInfo.RegionName, Is.EqualTo(sceneA.RegionInfo.RegionName));
|
||||
Assert.That(sceneASp.AbsolutePosition, Is.EqualTo(preTeleportPosition));
|
||||
|
||||
Assert.That(sceneA.GetRootAgentCount(), Is.EqualTo(1));
|
||||
Assert.That(sceneA.GetChildAgentCount(), Is.EqualTo(0));
|
||||
Assert.That(sceneB.GetRootAgentCount(), Is.EqualTo(0));
|
||||
Assert.That(sceneB.GetChildAgentCount(), Is.EqualTo(0));
|
||||
|
||||
// TODO: Add assertions to check correct circuit details in both scenes.
|
||||
|
||||
// Lookat is sent to the client only - sp.Lookat does not yield the same thing (calculation from camera
|
||||
|
@ -382,6 +400,11 @@ namespace OpenSim.Region.Framework.Scenes.Tests
|
|||
Assert.That(afterSceneBSp.Scene.RegionInfo.RegionName, Is.EqualTo(sceneB.RegionInfo.RegionName));
|
||||
Assert.That(afterSceneBSp.AbsolutePosition, Is.EqualTo(teleportPosition));
|
||||
|
||||
Assert.That(sceneA.GetRootAgentCount(), Is.EqualTo(0));
|
||||
Assert.That(sceneA.GetChildAgentCount(), Is.EqualTo(1));
|
||||
Assert.That(sceneB.GetRootAgentCount(), Is.EqualTo(1));
|
||||
Assert.That(sceneB.GetChildAgentCount(), Is.EqualTo(0));
|
||||
|
||||
// TODO: Add assertions to check correct circuit details in both scenes.
|
||||
|
||||
// Lookat is sent to the client only - sp.Lookat does not yield the same thing (calculation from camera
|
||||
|
|
|
@ -480,6 +480,9 @@ namespace pCampBot
|
|||
|
||||
public void Objects_NewPrim(object sender, PrimEventArgs args)
|
||||
{
|
||||
// if (Name.EndsWith("4"))
|
||||
// throw new Exception("Aaargh");
|
||||
|
||||
Primitive prim = args.Prim;
|
||||
|
||||
if (prim != null)
|
||||
|
|
|
@ -67,6 +67,12 @@
|
|||
</Section>
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
<Section Name="Collision Sounds AssetSet">
|
||||
<Key Name="file" Value="CollisionSoundsAssetSet/CollisionSoundsAssetSet.xml"/>
|
||||
</Section>
|
||||
<!---->
|
||||
|
||||
<!---->
|
||||
<Section Name="Textures AssetSet">
|
||||
<Key Name="file" Value="TexturesAssetSet/TexturesAssetSet.xml"/>
|
||||
|
|
|
@ -0,0 +1,341 @@
|
|||
<Nini>
|
||||
<!-- Ubit 2012
|
||||
using Nebadon collision sounds collection-->
|
||||
|
||||
<Section Name="snd_StoneStone">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0800200c9a66" />
|
||||
<Key Name="name" Value="snd_StoneStone" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_StoneStone.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_StoneMetal">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0800201c9a66" />
|
||||
<Key Name="name" Value="snd_StoneMetal" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_StoneMetal.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_StoneGlass">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0800202c9a66" />
|
||||
<Key Name="name" Value="snd_StoneGlass" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_StoneGlass.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_StoneWood">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0800203c9a66" />
|
||||
<Key Name="name" Value="snd_StoneWood" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_StoneWood.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_StoneFlesh">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0800204c9a66" />
|
||||
<Key Name="name" Value="snd_StoneFlesh" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_StoneFlesh.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_StonePlastic">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0800205c9a66" />
|
||||
<Key Name="name" Value="snd_StonePlastic" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_StonePlastic.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_StoneRubber">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0800206c9a66" />
|
||||
<Key Name="name" Value="snd_StoneRubber" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_StoneRubber.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_MetalStone">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0801200c9a66" />
|
||||
<Key Name="name" Value="snd_MetalStone" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_MetalStone.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_MetalMetal">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0801201c9a66" />
|
||||
<Key Name="name" Value="snd_MetalMetal" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_MetalMetal.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_MetalGlass">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0801202c9a66" />
|
||||
<Key Name="name" Value="snd_MetalGlass" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_MetalGlass.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_MetalWood">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0801203c9a66" />
|
||||
<Key Name="name" Value="snd_MetalWood" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_MetalWood.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_MetalFlesh">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0801204c9a66" />
|
||||
<Key Name="name" Value="snd_MetalFlesh" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_MetalFlesh.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_MetalPlastic">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0801205c9a66" />
|
||||
<Key Name="name" Value="snd_MetalPlastic" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_MetalPlastic.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_MetalRubber">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0801206c9a66" />
|
||||
<Key Name="name" Value="snd_MetalRubber" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_MetalRubber.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_GlassStone">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0802200c9a66" />
|
||||
<Key Name="name" Value="snd_GlassStone" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_GlassStone.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_GlassMetal">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0802201c9a66" />
|
||||
<Key Name="name" Value="snd_GlassMetal" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_GlassMetal.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_GlassGlass">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0802202c9a66" />
|
||||
<Key Name="name" Value="snd_GlassGlass" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_GlassGlass.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_GlassWood">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0802203c9a66" />
|
||||
<Key Name="name" Value="snd_GlassWood" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_GlassWood.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_GlassFlesh">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0802204c9a66" />
|
||||
<Key Name="name" Value="snd_GlassFlesh" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_GlassFlesh.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_GlassPlastic">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0802205c9a66" />
|
||||
<Key Name="name" Value="snd_GlassPlastic" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_GlassPlastic.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_GlassRubber">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0802206c9a66" />
|
||||
<Key Name="name" Value="snd_GlassRubber" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_GlassRubber.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_WoodStone">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0803200c9a66" />
|
||||
<Key Name="name" Value="snd_WoodStone" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_WoodStone.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_WoodMetal">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0803201c9a66" />
|
||||
<Key Name="name" Value="snd_WoodMetal" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_WoodMetal.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_WoodGlass">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0803202c9a66" />
|
||||
<Key Name="name" Value="snd_WoodGlass" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_WoodGlass.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_WoodWood">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0803203c9a66" />
|
||||
<Key Name="name" Value="snd_WoodWood" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_WoodWood.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_WoodFlesh">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0803204c9a66" />
|
||||
<Key Name="name" Value="snd_WoodFlesh" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_WoodFlesh.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_WoodPlastic">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0803205c9a66" />
|
||||
<Key Name="name" Value="snd_WoodPlastic" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_WoodPlastic.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_WoodRubber">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0803206c9a66" />
|
||||
<Key Name="name" Value="snd_WoodRubber" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_WoodRubber.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_FleshStone">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0804200c9a66" />
|
||||
<Key Name="name" Value="snd_FleshStone" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_FleshStone.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_FleshMetal">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0804201c9a66" />
|
||||
<Key Name="name" Value="snd_FleshMetal" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_FleshMetal.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_FleshGlass">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0804202c9a66" />
|
||||
<Key Name="name" Value="snd_FleshGlass" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_FleshGlass.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_FleshWood">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0804203c9a66" />
|
||||
<Key Name="name" Value="snd_FleshWood" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_FleshWood.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_FleshFlesh">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0804204c9a66" />
|
||||
<Key Name="name" Value="snd_FleshFlesh" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_FleshFlesh.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_FleshPlastic">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0804205c9a66" />
|
||||
<Key Name="name" Value="snd_FleshPlastic" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_FleshPlastic.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_FleshRubber">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0804206c9a66" />
|
||||
<Key Name="name" Value="snd_FleshRubber" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_FleshRubber.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_PlasticStone">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0805200c9a66" />
|
||||
<Key Name="name" Value="snd_PlasticStone" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_PlasticStone.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_PlasticMetal">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0805201c9a66" />
|
||||
<Key Name="name" Value="snd_PlasticMetal" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_PlasticMetal.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_PlasticGlass">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0805202c9a66" />
|
||||
<Key Name="name" Value="snd_PlasticGlass" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_PlasticGlass.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_PlasticWood">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0805203c9a66" />
|
||||
<Key Name="name" Value="snd_PlasticWood" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_PlasticWood.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_PlasticFlesh">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0805204c9a66" />
|
||||
<Key Name="name" Value="snd_PlasticFlesh" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_PlasticFlesh.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_PlasticPlastic">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0805205c9a66" />
|
||||
<Key Name="name" Value="snd_PlasticPlastic" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_PlasticPlastic.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_PlasticRubber">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0805206c9a66" />
|
||||
<Key Name="name" Value="snd_PlasticRubber" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_PlasticRubber.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_RubberStone">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0806200c9a66" />
|
||||
<Key Name="name" Value="snd_RubberStone" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_RubberStone.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_RubberMetal">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0806201c9a66" />
|
||||
<Key Name="name" Value="snd_RubberMetal" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_RubberMetal.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_RubberGlass">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0806202c9a66" />
|
||||
<Key Name="name" Value="snd_RubberGlass" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_RubberGlass.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_RubberWood">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0806203c9a66" />
|
||||
<Key Name="name" Value="snd_RubberWood" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_RubberWood.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_RubberFlesh">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0806204c9a66" />
|
||||
<Key Name="name" Value="snd_RubberFlesh" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_RubberFlesh.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_RubberPlastic">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0806205c9a66" />
|
||||
<Key Name="name" Value="snd_RubberPlastic" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_RubberPlastic.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_RubberRubber">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0806206c9a66" />
|
||||
<Key Name="name" Value="snd_RubberRubber" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_RubberRubber.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_TerrainStone">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0807200c9a66" />
|
||||
<Key Name="name" Value="snd_TerrainStone" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_TerrainStone.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_TerrainMetal">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0807200c9a66" />
|
||||
<Key Name="name" Value="snd_TerrainMetal" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_TerrainMetal.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_TerrainGlass">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0807200c9a66" />
|
||||
<Key Name="name" Value="snd_TerrainGlass" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_TerrainGlass.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_TerrainWood">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0807200c9a66" />
|
||||
<Key Name="name" Value="snd_TerrainWood" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_TerrainWood.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_TerrainFlesh">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0807200c9a66" />
|
||||
<Key Name="name" Value="snd_TerrainFlesh" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_TerrainFlesh.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_TerrainPlastic">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0807200c9a66" />
|
||||
<Key Name="name" Value="snd_TerrainPlastic" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_TerrainPlastic.ogg" />
|
||||
</Section>
|
||||
<Section Name="snd_TerrainRubber">
|
||||
<Key Name="assetID" Value="be7295c0-a158-11e1-b3dd-0807200c9a66" />
|
||||
<Key Name="name" Value="snd_TerrainRubber" />
|
||||
<Key Name="assetType" Value="1" />
|
||||
<Key Name="fileName" Value="snd_TerrainRubber.ogg" />
|
||||
</Section>
|
||||
</Nini>
|
|
@ -0,0 +1,8 @@
|
|||
thanvannispen - http://www.freesound.org/people/thanvannispen/sounds/30012/
|
||||
hoobtastic - http://www.freesound.org/people/hoobtastic/sounds/132627/
|
||||
kbnevel - http://www.freesound.org/people/kbnevel/sounds/119859/
|
||||
adcbicycle - http://www.freesound.org/people/adcbicycle/sounds/13856/
|
||||
adcbicycle - http://www.freesound.org/people/adcbicycle/sounds/13855/
|
||||
110110010 - http://www.freesound.org/people/110110010/sounds/66397/
|
||||
qubodup - http://www.freesound.org/people/qubodup/sounds/50941/
|
||||
vibe_crc - http://www.freesound.org/people/vibe_crc/sounds/59317/
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue