Some work on sceneapi

dsg
Dan Lake 2010-03-23 16:30:56 -07:00
parent 28e4302eb6
commit 4216eacd6c
25 changed files with 3127 additions and 418 deletions

6
.gitignore vendored
View File

@ -9,6 +9,12 @@
*.pdb
*.pidb
*.dll.build
*/*/obj
*/*/*/obj
*/*/*/*/obj
*/*/*/*/*/obj
*/*/*/*/*/*/obj
*/*/*/*/*/*/*/obj
*/*/bin
*/*/*/bin
*/*/*/*/bin

View File

@ -1,312 +0,0 @@
<!-- -*- xml -*- -->
<!-- please leave the top comment for us emacs folks -->
<property name="projectdir" value="opensim-0.5.5" />
<property name="nunitcmd" value="nunit-console" />
<target name="distdir">
<delete dir="${projectdir}" />
<copy todir="${projectdir}">
<fileset basedir=".">
<include name="ThirdPartyLicenses/**" />
<include name="CONTRIBUTORS.txt" />
<include name="README" />
<include name="OpenSim/**/*.cs" />
<include name="**/*.build" />
<include name="**/*.csproj" />
<include name="**/*.csproj.user" />
<include name="**/*.sln" />
<include name="bin/*.dll" />
<include name="bin/*.so" />
<include name="bin/*.config" />
<include name="bin/assets/**" />
<include name="bin/data/**" />
<include name="bin/OpenSim*xml" />
<!-- the next is to exclude built libs -->
<exclude name="bin/OpenSim.*dll" />
<include name="bin/OpenSim.ini" />
<include name="bin/defaultstripe.png" />
</fileset>
</copy>
<touch file="${projectdir}/bin/startup_commands.txt" />
</target>
<target name="test" depends="build, find-nunit">
<setenv name="MONO_THREADS_PER_CPU" value="100" />
<!-- Unit Test Assembly -->
<!-- if you want to add more unit tests it's important that you add
the assembly here as an exec, and you add the fail clause later.
This lets all the unit tests run and tells you if they fail at the
end, instead of stopping short -->
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.framework.tests">
<arg value="./bin/OpenSim.Framework.Tests.dll" />
</exec>
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.framework.tests)==0}" />
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.framework.servers.tests">
<arg value="./bin/OpenSim.Framework.Servers.Tests.dll" />
</exec>
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.framework.servers.tests)==0}" />
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.framework.serialization.tests">
<arg value="./bin/OpenSim.Framework.Serialization.Tests.dll" />
</exec>
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.framework.serialization.tests)==0}" />
<!--
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.region.clientstack.lindenudp.tests">
<arg value="./bin/OpenSim.Region.ClientStack.LindenUDP.Tests.dll" />
</exec>
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.clientstack.lindenudp.tests)==0}" />
-->
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.region.scriptengine.tests">
<arg value="./bin/OpenSim.Region.ScriptEngine.Tests.dll" />
</exec>
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.scriptengine.tests)==0}" />
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.region.coremodules.tests">
<arg value="./bin/OpenSim.Region.CoreModules.Tests.dll" />
</exec>
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.coremodules.tests)==0}" />
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.region.framework.tests">
<arg value="./bin/OpenSim.Region.Framework.Tests.dll" />
</exec>
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.framework.tests)==0}" />
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.data.sqlite.tests">
<arg value="./bin/OpenSim.Data.SQLite.Tests.dll" />
</exec>
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.data.sqlite.tests)==0}" />
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.data.mysql.tests">
<arg value="./bin/OpenSim.Data.MySQL.Tests.dll" />
</exec>
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.data.mysql.tests)==0}" />
<delete dir="%temp%"/>
</target>
<target name="test-cov" depends="build">
<!-- Code Coverage Test. Prototype, only works with mono 1.2. Instructions in http://opensimulator.org/wiki/Automated_Testing -->
<mkdir dir="cov" failonerror="false" />
<exec program="mono">
<arg value="--debug" />
<arg value="--profile=monocov:outfile=./cov/OpenSim.Framework.Servers.cov,+[OpenSim.Framework.Servers]" />
<arg value="/usr/lib/nunit/nunit-console.exe" />
<arg value="./bin/OpenSim.Framework.Servers.Tests.dll" />
</exec>
<delete dir="./cov/OpenSim.Framework.Servers" />
<exec program="monocov">
<arg value="--export-html=./cov/OpenSim.Framework.Servers ./cov/OpenSim.Framework.Servers.cov" />
</exec>
<!--
<exec program="mono">
<arg value="&#45;&#45;debug" />
<arg value="&#45;&#45;profile=monocov:outfile=./cov/OpenSim.Region.ClientStack.LindenUDP.cov,+[OpenSim.Region.ClientStack.LindenUDP]" />
<arg value="/usr/lib/nunit/nunit-console.exe" />
<arg value="./bin/OpenSim.Region.ClientStack.LindenUDP.Tests.dll" />
</exec>
<delete dir="./cov/OpenSim.Region.ClientStack.LindenUDP" />
<exec program="monocov">
<arg value="&#45;&#45;export-html=./cov/OpenSim.Region.ClientStack.LindenUDP ./cov/OpenSim.Region.ClientStack.LindenUDP.cov" />
</exec>
-->
<exec program="mono">
<arg value="--debug" />
<arg value="--profile=monocov:outfile=./cov/OpenSim.Region.ScriptEngine.Shared.cov,+[OpenSim.Region.ScriptEngine.Shared]" />
<arg value="/usr/lib/nunit/nunit-console.exe" />
<arg value="./bin/OpenSim.Region.ScriptEngine.Shared.Tests.dll" />
</exec>
<delete dir="./cov/OpenSim.Region.ScriptEngine.Shared" />
<exec program="monocov">
<arg value="--export-html=./cov/OpenSim.Region.ScriptEngine.Shared ./cov/OpenSim.Region.ScriptEngine.Shared.cov" />
</exec>
<exec program="mono">
<arg value="--debug" />
<arg value="--profile=monocov:outfile=./cov/OpenSim.Region.ScriptEngine.Shared.CodeTools.cov,+[OpenSim.Region.ScriptEngine.Shared.CodeTools]" />
<arg value="/usr/lib/nunit/nunit-console.exe" />
<arg value="./bin/OpenSim.Region.ScriptEngine.Shared.CodeTools.Tests.dll" />
</exec>
<delete dir="./cov/OpenSim.Region.ScriptEngine.Shared.CodeTools" />
<exec program="monocov">
<arg value="--export-html=./cov/OpenSim.Region.ScriptEngine.Shared.CodeTools ./cov/OpenSim.Region.ScriptEngine.Shared.CodeTools.cov" />
</exec>
<exec program="mono">
<arg value="--debug" />
<arg value="--profile=monocov:outfile=./cov/OpenSim.Region.CoreModules.cov,+[OpenSim.Region.CoreModules]" />
<arg value="/usr/lib/nunit/nunit-console.exe" />
<arg value="./bin/OpenSim.Region.CoreModules.Tests.dll" />
</exec>
<delete dir="./cov/OpenSim.Region.CoreModules" />
<exec program="monocov">
<arg value="--export-html=./cov/OpenSim.Region.CoreModules ./cov/OpenSim.Region.CoreModules.cov" />
</exec>
<exec program="mono">
<arg value="--debug" />
<arg value="--profile=monocov:outfile=./cov/OpenSim.Region.Framework.cov,+[OpenSim.Region.Framework]" />
<arg value="/usr/lib/nunit/nunit-console.exe" />
<arg value="./bin/OpenSim.Region.Framework.Tests.dll" />
</exec>
<delete dir="./cov/OpenSim.Region.Framework" />
<exec program="monocov">
<arg value="--export-html=./cov/OpenSim.Region.Framework ./cov/OpenSim.Region.Framework.cov" />
</exec>
<exec program="mono">
<arg value="--debug" />
<arg value="--profile=monocov:outfile=./cov/OpenSim.Data.SQLite.cov,+[OpenSim.Data.SQLite]" />
<arg value="/usr/lib/nunit/nunit-console.exe" />
<arg value="./bin/OpenSim.Data.SQLite.Tests.dll" />
</exec>
<delete dir="./cov/OpenSim.Data.SQLite" />
<exec program="monocov">
<arg value="--export-html=./cov/OpenSim.Data.SQLite ./cov/OpenSim.Data.SQLite.cov" />
</exec>
<exec program="mono">
<arg value="--debug" />
<arg value="--profile=monocov:outfile=./cov/OpenSim.Data.MySQL.cov,+[OpenSim.Data.MySQL.Tests]" />
<arg value="/usr/lib/nunit/nunit-console.exe" />
<arg value="./bin/OpenSim.Data.MySQL.Tests.dll" />
</exec>
<delete dir="./cov/OpenSim.Data.MySQL" />
<exec program="monocov">
<arg value="--export-html=./cov/OpenSim.Data.MySQL ./cov/OpenSim.Data.MySQL.cov" />
</exec>
<delete file="C:\NUnitPrimaryTrace.txt" failonerror="false" />
<delete file="TestResult.xml" failonerror="false" />
</target>
<target name="find-nunit">
<exec program="which" failonerror="false"
resultproperty="hasnunit2">
<arg value="nunit-console2" />
</exec>
<property name="nunitcmd" value="nunit-console2"
if="${int::parse(hasnunit2)==0}" />
<property name="nunitcmd" value="nunit-console"
if="${int::parse(hasnunit2)==1}" />
</target>
<!-- this is used for panda test execution -->
<!-- work in progress -->
<target name="test-xml" depends="build, find-nunit">
<mkdir dir="test-results" failonerror="false" />
<!-- Unit Test Assembly -->
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.framework.tests">
<arg value="./bin/OpenSim.Framework.Tests.dll" />
<arg value="-xml=test-results/OpenSim.Framework.Tests.dll-Results.xml" />
</exec>
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.framework.serialization.tests">
<arg value="./bin/OpenSim.Framework.Serialization.Tests.dll" />
<arg value="-xml=test-results/OpenSim.Framework.Serialization.Tests.dll-Results.xml" />
</exec>
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.framework.servers.tests">
<arg value="./bin/OpenSim.Framework.Servers.Tests.dll" />
<arg value="-xml=test-results/OpenSim.Framework.Servers.Tests.dll-Results.xml" />
</exec>
<!--
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.region.clientstack.lindenudp.tests">
<arg value="./bin/OpenSim.Region.ClientStack.LindenUDP.Tests.dll" />
<arg value="-xml=test-results/OpenSim.Region.ClientStack.LindenUDP.Tests.dll-Results.xml" />
</exec>
-->
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.region.scriptengine.tests">
<arg value="./bin/OpenSim.Region.ScriptEngine.Tests.dll" />
<arg value="-xml=test-results/OpenSim.Region.ScriptEngine.Tests.dll-Results.xml" />
</exec>
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.region.coremodules.tests">
<arg value="./bin/OpenSim.Region.CoreModules.Tests.dll" />
<arg value="-xml=test-results/OpenSim.Region.CoreModules.Tests.dll-Results.xml" />
</exec>
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.region.framework.tests">
<arg value="./bin/OpenSim.Region.Framework.Tests.dll" />
<arg value="-xml=test-results/OpenSim.Region.Framework.Tests.dll-Results.xml" />
</exec>
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.data.sqlite.tests">
<arg value="./bin/OpenSim.Data.SQLite.Tests.dll" />
<arg value="-xml=test-results/OpenSim.Data.SQLite.Tests.dll-Results.xml" />
</exec>
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.data.mysql.tests">
<arg value="./bin/OpenSim.Data.MySQL.Tests.dll" />
<arg value="-xml=test-results/OpenSim.Data.MySQL.Tests.dll-Results.xml" />
</exec>
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.framework.tests)==0}" />
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.framework.servers.tests)==0}" />
<!-- <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.clientstack.lindenudp.tests)==0}" /> -->
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.scriptengine.tests)==0}" />
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.coremodules.tests)==0}" />
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.framework.tests)==0}" />
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.data.sqlite.tests)==0}" />
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.data.mysql.tests)==0}" />
</target>
<!-- <exec program="nunit-console.exe" failonerror="false" resultproperty="testresult.acceptancetestassembly"> -->
<!-- <arg value="AcceptanceTestAssembly.dll" /> -->
<!-- <arg value="/xml=AcceptanceTestAssembly-Results.xml" /> -->
<!-- </exec> -->
<!-- <fail message="Failures reported in unit tests." unless="${int::parse(testresult.unittestassembly)==0}" /> -->
<!-- <fail message="Failures reported in acceptance tests." unless="${int::parse(testresult.acceptancetestassembly)==0}" /> -->
<!-- </target> -->
<!-- <nunit2 failonerror="true" verbose="true"> -->
<!-- <formatter type="Xml" usefile="true" extension=".xml" outputdir="./test-results" /> -->
<!-- <test> -->
<!-- <assemblies> -->
<!-- <include name="./bin/OpenSim.Framework.Tests.dll" /> -->
<!-- <include name="./bin/OpenSim.Framework.Servers.Tests.dll" /> -->
<!-- <include name="./bin/OpenSim.Region.ClientStack.LindenUDP.Tests.dll" /> -->
<!-- <include name="./bin/OpenSim.Region.ScriptEngine.Tests.dll" /> -->
<!-- <include name="./bin/OpenSim.Region.CoreModules.Tests.dll" /> -->
<!-- <include name="./bin/OpenSim.Region.Framework.Tests.dll" /> -->
<!-- <include name="./bin/OpenSim.Data.SQLite.Tests.dll" /> -->
<!-- <include name="./bin/OpenSim.Data.MySQL.Tests.dll" /> -->
<!-- </assemblies> -->
<!-- </test> -->
<!-- </nunit2> -->
<!-- </target> -->
<target name="doxygen">
<exec program="doxygen" workingdir="doc" commandline="doxygen.conf" />
</target>
<target name="dist" depends="distdir">
<zip zipfile="${projectdir}.zip">
<fileset basedir=".">
<include name="${projectdir}/**" />
</fileset>
</zip>
<tar destfile="${projectdir}.tar.gz" compression="GZip">
<fileset basedir=".">
<include name="${projectdir}/**" />
</fileset>
</tar>
</target>

View File

@ -570,6 +570,7 @@ namespace OpenSim.Client.MXP.ClientStack
public event GenericMessage OnGenericMessage;
public event ImprovedInstantMessage OnInstantMessage;
public event ChatMessage OnChatFromClient;
public event ChatMessageRaw OnChatFromClientRaw;
public event TextureRequest OnRequestTexture;
public event RezObject OnRezObject;
public event ModifyTerrain OnModifyTerrain;
@ -600,6 +601,7 @@ namespace OpenSim.Client.MXP.ClientStack
public event GenericCall1 OnCompleteMovementToRegion;
public event UpdateAgent OnPreAgentUpdate;
public event UpdateAgent OnAgentUpdate;
public event UpdateAgentRaw OnAgentUpdateRaw;
public event AgentRequestSit OnAgentRequestSit;
public event AgentSit OnAgentSit;
public event AvatarPickerRequest OnAvatarPickerRequest;

View File

@ -216,6 +216,7 @@ namespace OpenSim.Client.Sirikata.ClientStack
public event GenericMessage OnGenericMessage;
public event ImprovedInstantMessage OnInstantMessage;
public event ChatMessage OnChatFromClient;
public event ChatMessageRaw OnChatFromClientRaw;
public event TextureRequest OnRequestTexture;
public event RezObject OnRezObject;
public event ModifyTerrain OnModifyTerrain;
@ -246,6 +247,7 @@ namespace OpenSim.Client.Sirikata.ClientStack
public event GenericCall1 OnCompleteMovementToRegion;
public event UpdateAgent OnPreAgentUpdate;
public event UpdateAgent OnAgentUpdate;
public event UpdateAgentRaw OnAgentUpdateRaw;
public event AgentRequestSit OnAgentRequestSit;
public event AgentSit OnAgentSit;
public event AvatarPickerRequest OnAvatarPickerRequest;

View File

@ -219,6 +219,7 @@ namespace OpenSim.Client.VWoHTTP.ClientStack
public event GenericMessage OnGenericMessage = delegate { };
public event ImprovedInstantMessage OnInstantMessage = delegate { };
public event ChatMessage OnChatFromClient = delegate { };
public event ChatMessageRaw OnChatFromClientRaw = delegate { };
public event TextureRequest OnRequestTexture = delegate { };
public event RezObject OnRezObject = delegate { };
public event ModifyTerrain OnModifyTerrain = delegate { };
@ -249,6 +250,7 @@ namespace OpenSim.Client.VWoHTTP.ClientStack
public event GenericCall1 OnCompleteMovementToRegion = delegate { };
public event UpdateAgent OnPreAgentUpdate;
public event UpdateAgent OnAgentUpdate = delegate { };
public event UpdateAgentRaw OnAgentUpdateRaw = delegate { };
public event AgentRequestSit OnAgentRequestSit = delegate { };
public event AgentSit OnAgentSit = delegate { };
public event AvatarPickerRequest OnAvatarPickerRequest = delegate { };

View File

@ -38,6 +38,7 @@ namespace OpenSim.Framework
public delegate void ViewerEffectEventHandler(IClientAPI sender, List<ViewerEffectEventHandlerArg> args);
public delegate void ChatMessage(Object sender, OSChatMessage e);
public delegate void ChatMessageRaw(Object sender, byte[] chatData);
public delegate void GenericMessage(Object sender, string method, List<String> args);
@ -149,6 +150,7 @@ namespace OpenSim.Framework
public delegate void NewAvatar(IClientAPI remoteClient, UUID agentID, bool status);
public delegate void UpdateAgent(IClientAPI remoteClient, AgentUpdateArgs agentData);
public delegate void UpdateAgentRaw(IClientAPI remoteClient, byte[] agentData);
public delegate void AgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset);
@ -848,6 +850,7 @@ namespace OpenSim.Framework
event ImprovedInstantMessage OnInstantMessage;
// [Obsolete("LLClientView Specific - Replace with more bare-bones arguments. Rename OnChat.")]
event ChatMessage OnChatFromClient;
event ChatMessageRaw OnChatFromClientRaw;
// [Obsolete("LLClientView Specific - Replace with more bare-bones arguments.")]
event TextureRequest OnRequestTexture;
// [Obsolete("LLClientView Specific - Remove bitbuckets. Adam, can you be more specific here.. as I don't see any bit buckets.")]
@ -883,6 +886,7 @@ namespace OpenSim.Framework
event GenericCall1 OnCompleteMovementToRegion;
event UpdateAgent OnPreAgentUpdate;
event UpdateAgent OnAgentUpdate;
event UpdateAgentRaw OnAgentUpdateRaw;
event AgentRequestSit OnAgentRequestSit;
event AgentSit OnAgentSit;
event AvatarPickerRequest OnAvatarPickerRequest;

View File

@ -48,6 +48,7 @@ using OpenSim.Services.Interfaces;
using Timer = System.Timers.Timer;
using AssetLandmark = OpenSim.Framework.AssetLandmark;
using Nini.Config;
using System.Linq;
namespace OpenSim.Region.ClientStack.LindenUDP
{
@ -112,6 +113,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public event ViewerEffectEventHandler OnViewerEffect;
public event ImprovedInstantMessage OnInstantMessage;
public event ChatMessage OnChatFromClient;
public event ChatMessageRaw OnChatFromClientRaw;
public event TextureRequest OnRequestTexture;
public event RezObject OnRezObject;
public event DeRezObject OnDeRezObject;
@ -129,6 +131,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public event GenericCall1 OnCompleteMovementToRegion;
public event UpdateAgent OnPreAgentUpdate;
public event UpdateAgent OnAgentUpdate;
public event UpdateAgentRaw OnAgentUpdateRaw;
public event AgentRequestSit OnAgentRequestSit;
public event AgentSit OnAgentSit;
public event AvatarPickerRequest OnAvatarPickerRequest;
@ -356,7 +359,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private int m_moneyBalance;
private int m_animationSequenceNumber = 1;
private bool m_SendLogoutPacketWhenClosing = true;
private AgentUpdateArgs lastarg;
private byte[] m_lastAgentUpdate;
private bool m_IsActive = true;
private bool m_IsLoggingOut = false;
@ -4836,9 +4839,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private bool HandleAgentUpdate(IClientAPI sener, Packet Pack)
{
if (OnAgentUpdate != null)
if (OnAgentUpdate != null || OnAgentUpdateRaw != null)
{
bool update = false;
AgentUpdatePacket agenUpdate = (AgentUpdatePacket)Pack;
#region Packet Session and User Check
@ -4847,37 +4849,49 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#endregion
AgentUpdatePacket.AgentDataBlock x = agenUpdate.AgentData;
byte[] xb = new byte[x.Length];
int i = 0;
x.ToBytes(xb, ref i);
// We can only check when we have something to check
// against.
// If there was a previous update and this update is exactly the same, skip it
if (m_lastAgentUpdate != null && Enumerable.SequenceEqual(xb, m_lastAgentUpdate))
return true;
if (lastarg != null)
/*
// What is different?? (only interesting for client managers)
if(m_scene.IsSyncedClient() && m_lastAgentUpdate != null)
{
update =
(
(x.BodyRotation != lastarg.BodyRotation) ||
(x.CameraAtAxis != lastarg.CameraAtAxis) ||
(x.CameraCenter != lastarg.CameraCenter) ||
(x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
(x.CameraUpAxis != lastarg.CameraUpAxis) ||
(x.ControlFlags != lastarg.ControlFlags) ||
(x.Far != lastarg.Far) ||
(x.Flags != lastarg.Flags) ||
(x.State != lastarg.State) ||
(x.HeadRotation != lastarg.HeadRotation) ||
(x.SessionID != lastarg.SessionID) ||
(x.AgentID != lastarg.AgentID)
);
AgentUpdatePacket.AgentDataBlock lastarg = new AgentUpdatePacket.AgentDataBlock();
i = 0;
lastarg.FromBytes(m_lastAgentUpdate, ref i);
if(x.BodyRotation != lastarg.BodyRotation) m_log.Warn("BodyRotation");
if(x.CameraAtAxis != lastarg.CameraAtAxis) m_log.Warn("CameraAtAxis");
if(x.CameraCenter != lastarg.CameraCenter) m_log.Warn("CameraCenter");
if(x.CameraLeftAxis != lastarg.CameraLeftAxis) m_log.Warn("CameraLeftAxis");
if(x.CameraUpAxis != lastarg.CameraUpAxis) m_log.Warn("CameraUpAxis");
if(x.ControlFlags != lastarg.ControlFlags) m_log.Warn("ControlFlags");
if(x.Far != lastarg.Far) m_log.Warn("Far");
if(x.Flags != lastarg.Flags) m_log.Warn("Flags");
if(x.State != lastarg.State) m_log.Warn("State");
if(x.HeadRotation != lastarg.HeadRotation) m_log.Warn("HeadRotation");
if(x.SessionID != lastarg.SessionID) m_log.Warn("SessionID");
if(x.AgentID != lastarg.AgentID) m_log.Warn("AgentID");
}
else
update = true;
* */
// These should be ordered from most-likely to
// least likely to change. I've made an initial
// guess at that.
// save this set of arguments for next time
m_lastAgentUpdate = xb;
if (update)
// If we have a raw handler, call it
UpdateAgentRaw handlerAgentUpdateRaw = OnAgentUpdateRaw;
if (handlerAgentUpdateRaw != null)
{
handlerAgentUpdateRaw(this, xb);
handlerAgentUpdateRaw = null;
return true;
}
AgentUpdateArgs arg = new AgentUpdateArgs();
arg.AgentID = x.AgentID;
arg.BodyRotation = x.BodyRotation;
@ -4891,17 +4905,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
arg.HeadRotation = x.HeadRotation;
arg.SessionID = x.SessionID;
arg.State = x.State;
UpdateAgent handlerAgentUpdate = OnAgentUpdate;
lastarg = arg; // save this set of arguments for nexttime
if (handlerAgentUpdate != null)
{
OnPreAgentUpdate(this, arg);
OnAgentUpdate(this, arg);
}
handlerAgentUpdate = null;
}
}
return true;
}
@ -5155,6 +5165,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
int channel = inchatpack.ChatData.Channel;
// If we have a raw handler, call it
ChatMessageRaw handlerChatFromClientRaw = OnChatFromClientRaw;
if (handlerChatFromClientRaw != null)
{
ChatFromViewerPacket.ChatDataBlock x = inchatpack.ChatData;
byte[] xb = new byte[x.Length];
int i = 0;
x.ToBytes(xb, ref i);
handlerChatFromClientRaw(this, xb);
handlerChatFromClientRaw = null;
return true;
}
if (OnChatFromClient != null)
{
OSChatMessage args = new OSChatMessage();

View File

@ -0,0 +1,62 @@
/*
* 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.Reflection;
using System.Runtime.InteropServices;
// General information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("OpenSim.Region.Examples.RegionSyncModule")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("http://opensimulator.org")]
[assembly: AssemblyProduct("OpenSim.Region.Examples.RegionSyncModule")]
[assembly: AssemblyCopyright("Copyright (c) 2008")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("f0caca77-7818-4a43-9200-0a8548009a05")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("0.6.4.*")]
[assembly: AssemblyVersion("0.6.4.*")]
[assembly: AssemblyFileVersion("1.0.0.0")]

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,374 @@
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Collections.Generic;
using System.Threading;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
using OpenSim.Framework;
using OpenSim.Framework.Client;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Scenes.Serialization;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes.Types;
using log4net;
namespace OpenSim.Region.Examples.RegionSyncModule
{
// The RegionSyncClient has a receive thread to process messages from the RegionSyncServer.
public class RegionSyncClient
{
#region RegionSyncClient members
// Set the addr and port of RegionSyncServer
private IPAddress m_addr;
private Int32 m_port;
// A reference to the local scene
private Scene m_scene;
// The logfile
private ILog m_log;
// The listener and the thread which listens for connections from client managers
private Thread m_rcvLoop;
// The client connection to the RegionSyncServer
private TcpClient m_client = new TcpClient();
// The queue of incoming messages which need handling
//private Queue<string> m_inQ = new Queue<string>();
#endregion
// Constructor
public RegionSyncClient(Scene scene, string addr, int port)
{
m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
m_log.Warn("[REGION SYNC CLIENT] Constructed");
m_scene = scene;
m_addr = IPAddress.Parse(addr);
m_port = port;
}
// Start the RegionSyncClient
public void Start()
{
try
{
m_client.Connect(m_addr, m_port);
}
catch (Exception e)
{
m_log.WarnFormat("[REGION SYNC CLIENT] [Start] Could not connect to RegionSyncServer at {0}:{1}", m_addr, m_port);
m_log.Warn(e.Message);
}
m_log.WarnFormat("[REGION SYNC CLIENT] Connected to RegionSyncServer at {0}:{1}", m_addr, m_port);
m_rcvLoop = new Thread(new ThreadStart(ReceiveLoop));
m_rcvLoop.Name = "RegionSyncClient ReceiveLoop";
m_log.WarnFormat("[REGION SYNC CLIENT] Starting {0} thread", m_rcvLoop.Name);
m_rcvLoop.Start();
m_log.Warn("[REGION SYNC CLIENT] Started");
DoInitialSync();
}
// Disconnect from the RegionSyncServer and close the RegionSyncClient
public void Stop()
{
m_rcvLoop.Abort();
ShutdownClient();
}
private void ShutdownClient()
{
m_log.WarnFormat("[REGION SYNC CLIENT] Disconnected from RegionSyncServer. Shutting down.");
m_scene.ForEachClient(delegate(IClientAPI client) { client.OnAgentUpdateRaw -= HandleAgentUpdateRaw; });
m_client.Client.Close();
m_client.Close();
}
// Listen for messages from a RegionSyncClient
// *** This is the main thread loop for each connected client
private void ReceiveLoop()
{
m_log.WarnFormat("[REGION SYNC CLIENT] Thread running: {0}", m_rcvLoop.Name);
while (true && m_client.Connected)
{
RegionSyncMessage msg;
// Try to get the message from the network stream
try
{
msg = new RegionSyncMessage(m_client.GetStream());
//m_log.WarnFormat("[REGION SYNC CLIENT] Received: {0}", msg.ToString());
}
// If there is a problem reading from the client, shut 'er down.
catch
{
ShutdownClient();
return;
}
// Try handling the message
try
{
HandleMessage(msg);
}
catch (Exception e)
{
m_log.WarnFormat("[REGION SYNC CLIENT] Encountered an exception: {0}", e.Message);
}
}
}
#region Send
// Send a message to a single connected RegionSyncClient
private void Send(string msg)
{
byte[] bmsg = System.Text.Encoding.ASCII.GetBytes(msg + System.Environment.NewLine);
Send(bmsg);
}
private void Send(RegionSyncMessage msg)
{
Send(msg.ToBytes());
//m_log.WarnFormat("[REGION SYNC CLIENT] Sent {0}", msg.ToString());
}
private void Send(byte[] data)
{
if (m_client.Connected)
{
try
{
m_client.GetStream().Write(data, 0, data.Length);
}
// If there is a problem reading from the client, shut 'er down.
// *** Still need to alert the module that it's no longer connected!
catch
{
ShutdownClient();
}
}
}
#endregion
// Handle an incoming message
// TODO: This should not be synchronous with the receive!
// Instead, handle messages from the incoming Queue
private bool HandleMessage(RegionSyncMessage msg)
{
switch (msg.Type)
{
case RegionSyncMessage.MsgType.Terrain:
{
m_scene.Heightmap.LoadFromXmlString(Encoding.ASCII.GetString(msg.Data));
return HandlerSuccess(msg, "Syncrhonized terrain");
}
case RegionSyncMessage.MsgType.RegionArchive:
{
IRegionArchiverModule archiver = m_scene.RequestModuleInterface<IRegionArchiverModule>();
if (archiver == null)
{
return HandlerFailure(msg, "Could not retrieve archiver module.");
}
MemoryStream ms = new MemoryStream(msg.Data);
archiver.DearchiveRegion(ms);
return HandlerSuccess(msg,"Synchronized region");
}
case RegionSyncMessage.MsgType.AddObject:
case RegionSyncMessage.MsgType.UpdateObject:
{
SceneObjectGroup sog = SceneObjectSerializer.FromXml2Format(Encoding.ASCII.GetString(msg.Data));
if(sog.IsDeleted)
return HandlerFailure(msg, String.Format("Ignoring update on deleted LocalId {0}.", sog.LocalId.ToString()));
if (m_scene.AddNewSceneObject(sog, true))
{
sog.ScheduleGroupForFullUpdate();
return HandlerSuccess(msg, String.Format("LocalId {0} added or updated.", sog.LocalId.ToString()));
}
return HandlerFailure(msg, String.Format("Could not add or update LocalId {0}.", sog.LocalId.ToString()));
}
case RegionSyncMessage.MsgType.UpdateAvatarTerse:
{
OSDMap data = OSDParser.DeserializeJson(Encoding.ASCII.GetString(msg.Data)) as OSDMap;
if( data != null )
{
UUID agentID = data["id"].AsUUID();
Vector3 pos = data["pos"].AsVector3();
Vector3 vel = data["vel"].AsVector3();
Quaternion rot = data["rot"].AsQuaternion();
// We get the UUID of the object to be deleted, find it in the scene
if (agentID != UUID.Zero)
{
ScenePresence presence = m_scene.GetScenePresence(agentID);
if (presence != null)
{
presence.AbsolutePosition = pos;
presence.Velocity = vel;
presence.Rotation = rot;
presence.SendTerseUpdateToAllClients();
return HandlerSuccess(msg, String.Format("agentID {0} updated", agentID.ToString()));
}
}
return HandlerFailure(msg, String.Format("agentID {0} not found.", agentID.ToString()));
}
return HandlerFailure(msg, "Could not parse AgentUpdate parameters");
}
// return HandlerSuccess(msg, "Updated avatar");
/*
case RegionSyncMessage.MsgType.SetObjectPosition: Attributes!
{
if (part.ParentGroup == null)
{
part.UpdateOffSet(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z));
}
else if (part.ParentGroup.RootPart == part)
{
part.parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z));
}
else
{
part.OffsetPosition = new Vector3((float)targetPos.x, (float)targetPos.y, (float)targetPos.z);
SceneObjectGroup parent = part.ParentGroup;
parent.HasGroupChanged = true;
parent.ScheduleGroupForTerseUpdate();
}
}
* */
case RegionSyncMessage.MsgType.RemoveObject:
{
OSDMap data = OSDParser.DeserializeJson(Encoding.ASCII.GetString(msg.Data)) as OSDMap;
if( data != null )
{
ulong regionHandle = data["regionHandle"].AsULong();
uint localID = data["localID"].AsUInteger();
// We get the UUID of the object to be deleted, find it in the scene
if (regionHandle != 0 && localID != 0 )
{
if (regionHandle == m_scene.RegionInfo.RegionHandle)
{
SceneObjectGroup sog = m_scene.SceneGraph.GetGroupByPrim(localID);
if (sog != null)
{
m_scene.DeleteSceneObject(sog, false);
return HandlerSuccess(msg, String.Format("localID {0} deleted.", localID.ToString()));
}
}
return HandlerFailure(msg, String.Format("ignoring delete request for non-local regionHandle {0}.", regionHandle.ToString()));
}
return HandlerFailure(msg, String.Format("localID {0} not found.", localID.ToString()));
}
return HandlerFailure(msg, "Could not parse DeleteObject parameters");
}
/*
case RegionSyncMessage.MsgType.UpdateObject:
{
UUID uuid;
if (UUID.TryParse(Encoding.ASCII.GetString(msg.Data), out uuid))
{
// We get the UUID of the object to be updated, find it in the scene
SceneObjectGroup sog = m_scene.SceneGraph.GetGroupByPrim(uuid);
Vector3 v = new Vector3();
v.ToString();
if (sog != null)
{
//m_scene.DeleteSceneObject(sog, false);
return HandlerSuccess(msg, String.Format("UUID {0} updated.", uuid.ToString()));
}
else
{
return HandlerFailure(msg, String.Format("UUID {0} not found.", uuid.ToString()));
}
}
return HandlerFailure(msg, "Could not parse UUID");
}
* */
default:
{
m_log.WarnFormat("[REGION SYNC CLIENT] Unsupported message type");
return false;
}
}
}
private bool HandlerSuccess(RegionSyncMessage msg, string handlerMessage)
{
//m_log.WarnFormat("[REGION SYNC CLIENT] Handled {0}: {1}", msg.ToString(), handlerMessage);
return true;
}
private bool HandlerFailure(RegionSyncMessage msg, string handlerMessage)
{
//m_log.WarnFormat("[REGION SYNC SERVER] Unable to handle {0}: {1}", msg.ToString(), handlerMessage);
return false;
}
private void DoInitialSync()
{
m_scene.DeleteAllSceneObjects();
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.GetTerrain));
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.GetObjects));
//Send(new RegionSyncMessage(RegionSyncMessage.MsgType.GetRegionArchive));
// Register for events which will be forwarded to authoritative scene
m_scene.EventManager.OnNewClient += EventManager_OnNewClient;
}
public string GetServerAddressAndPort()
{
return m_addr.ToString() + ":" + m_port.ToString();
}
#region Event Handlers
public void EventManager_OnNewClient(IClientAPI client)
{
// Let the auth sim know that a new agent has connected
OSDMap data = new OSDMap(1);
data["agentID"] = OSD.FromUUID(client.AgentId);
data["first"] = OSD.FromString(client.FirstName);
data["last"] = OSD.FromString(client.LastName);
data["startPos"] = OSD.FromVector3(client.StartPos);
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.AgentAdd, OSDParser.SerializeJsonString(data)));
// Register for interesting client events which will be forwarded to auth sim
// These are the raw packet data blocks from the client, intercepted and sent up to the sim
client.OnAgentUpdateRaw += HandleAgentUpdateRaw;
client.OnChatFromClientRaw += HandleChatFromClientRaw;
}
/// <summary>
/// This is the event handler for client movement. If a client is moving, this event is triggering.
/// </summary>
public void HandleAgentUpdateRaw(object sender, byte[] agentData)
{
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.AgentUpdate, agentData));
}
public void HandleChatFromClientRaw(object sender, byte[] chatData)
{
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.ChatFromClient, chatData));
}
#endregion
/*
// Should be part of the RegionSyncClient
public string ReceiveMsg()
{
lock (m_outQ)
{
if (m_outQ.Count > 0)
{
return m_outQ.Dequeue();
}
}
return null;
}
* */
}
}

View File

@ -0,0 +1,222 @@
/*
* 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.Collections.Generic;
using System.Reflection;
using Nini.Config;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Client;
using OpenSim.Region.CoreModules.Framework.InterfaceCommander;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using log4net;
using System.Net;
using System.Net.Sockets;
namespace OpenSim.Region.Examples.RegionSyncModule
{
public class RegionSyncClientModule : IRegionModule, IRegionSyncClientModule, ICommandableModule
{
#region IRegionModule Members
public void Initialise(Scene scene, IConfigSource config)
{
m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
IConfig syncConfig = config.Configs["RegionSyncModule"];
if (syncConfig == null || syncConfig.GetString("Mode", "client").ToLower() != "client")
{
m_active = false;
m_log.Warn("[REGION SYNC CLIENT MODULE] Not in client mode. Shutting down.");
return;
}
m_serveraddr = syncConfig.GetString("ServerIPAddress", "127.0.0.1");
m_serverport = syncConfig.GetInt("ServerPort", 13000);
m_scene = scene;
m_scene.RegisterModuleInterface<IRegionSyncClientModule>(this);
// Setup the command line interface
m_scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole;
InstallInterfaces();
m_log.Warn("[REGION SYNC CLIENT MODULE] Initialised");
}
public void PostInitialise()
{
if (!m_active)
return;
m_log.Warn("[REGION SYNC CLIENT MODULE] Post-Initialised");
}
public void Close()
{
m_scene = null;
}
public string Name
{
get { return "RegionSyncModule"; }
}
public bool IsSharedModule
{
get { return false; }
}
#endregion
#region ICommandableModule Members
private readonly Commander m_commander = new Commander("sync");
public ICommander CommandInterface
{
get { return m_commander; }
}
#endregion
#region IRegionSyncClientModule members
public bool Active
{
get { return m_active; }
}
public bool Synced
{
get
{
lock(m_client_lock)
{
return (m_client != null);
}
}
}
#endregion
#region RegionSyncClientModule members
private bool m_active = true;
private string m_serveraddr;
private int m_serverport;
private Scene m_scene;
private ILog m_log;
private Object m_client_lock = new Object();
private RegionSyncClient m_client = null;
#endregion
#region Event Handlers
#endregion
private void DebugSceneStats()
{
return;
/*
List<ScenePresence> avatars = m_scene.GetAvatars();
List<EntityBase> entities = m_scene.GetEntities();
m_log.WarnFormat("There are {0} avatars and {1} entities in the scene", avatars.Count, entities.Count);
*/
}
#region Console Command Interface
private void InstallInterfaces()
{
Command cmdSyncStart = new Command("start", CommandIntentions.COMMAND_HAZARDOUS, SyncStart, "Begins synchronization with RegionSyncServer.");
//cmdSyncStart.AddArgument("server_address", "The IP address of the server to synchronize with", "String");
//cmdSyncStart.AddArgument("server_port", "The port of the server to synchronize with", "Integer");
Command cmdSyncStop = new Command("stop", CommandIntentions.COMMAND_HAZARDOUS, SyncStop, "Stops synchronization with RegionSyncServer.");
//cmdSyncStop.AddArgument("server_address", "The IP address of the server to synchronize with", "String");
//cmdSyncStop.AddArgument("server_port", "The port of the server to synchronize with", "Integer");
m_commander.RegisterCommand("start", cmdSyncStart);
m_commander.RegisterCommand("stop", cmdSyncStop);
lock (m_scene)
{
// Add this to our scene so scripts can call these functions
m_scene.RegisterModuleCommander(m_commander);
}
}
/// <summary>
/// Processes commandline input. Do not call directly.
/// </summary>
/// <param name="args">Commandline arguments</param>
private void EventManager_OnPluginConsole(string[] args)
{
if (args[0] == "sync")
{
if (args.Length == 1)
{
m_commander.ProcessConsoleCommand("help", new string[0]);
return;
}
string[] tmpArgs = new string[args.Length - 2];
int i;
for (i = 2; i < args.Length; i++)
tmpArgs[i - 2] = args[i];
m_commander.ProcessConsoleCommand(args[1], tmpArgs);
}
}
private void SyncStart(Object[] args)
{
lock (m_client_lock)
{
if (m_client != null)
{
m_log.WarnFormat("[REGION SYNC CLIENT MODULE] Already synchronizing to {0}", m_client.GetServerAddressAndPort());
return;
}
m_log.Warn("[REGION SYNC CLIENT MODULE] Starting synchronization");
m_log.Warn("[REGION SYNC CLIENT MODULE] Starting RegionSyncClient");
m_client = new RegionSyncClient(m_scene, m_serveraddr, m_serverport);
m_client.Start();
}
}
private void SyncStop(Object[] args)
{
lock(m_client_lock)
{
if (m_client == null)
{
m_log.WarnFormat("[REGION SYNC CLIENT MODULE] Already stopped");
return;
}
m_client.Stop();
m_client = null;
m_log.Warn("[REGION SYNC CLIENT MODULE] Stopping synchronization");
}
}
#endregion
}
}

View File

@ -0,0 +1,288 @@
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Collections.Generic;
using System.Threading;
using OpenMetaverse;
using OpenMetaverse.Packets;
using OpenMetaverse.StructuredData;
using OpenSim.Framework;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Scenes.Serialization;
using OpenSim.Region.Framework.Interfaces;
using log4net;
namespace OpenSim.Region.Examples.RegionSyncModule
{
// The RegionSyncClientView acts as a thread on the RegionSyncServer to handle incoming
// messages from RegionSyncClients.
public class RegionSyncClientView
{
#region RegionSyncClientView members
// The TcpClient this view uses to communicate with its RegionSyncClient
private TcpClient m_tcpclient;
// Set the addr and port for TcpListener
private IPAddress m_addr;
private Int32 m_port;
private int m_connection_number;
private Scene m_scene;
Dictionary<UUID, RegionSyncAvatar> m_syncedAvatars = new Dictionary<UUID, RegionSyncAvatar>();
// A queue for incoming and outgoing traffic
private Queue<string> m_inQ = new Queue<string>();
private Queue<string> m_outQ = new Queue<string>();
private ILog m_log;
private Thread m_receive_loop;
// The last time the entire region was sent to this RegionSyncClient
private long m_archive_time;
// A string of the format [REGION SYNC CLIENT VIEW #X] for use in log headers
private string LogHeader
{
get { return String.Format("[REGION SYNC CLIENT VIEW #{0}]", m_connection_number); }
}
// A string of the format "RegionSyncClientView #X" for use in describing the object itself
public string Description
{
get { return String.Format("RegionSyncClientView #{0}", m_connection_number); }
}
// Check if the client is connected
public bool Connected
{ get { return m_tcpclient.Connected; } }
#endregion
// Constructor
public RegionSyncClientView(int num, Scene scene, TcpClient client)
{
m_connection_number = num;
m_scene = scene;
m_tcpclient = client;
m_addr = ((IPEndPoint)client.Client.RemoteEndPoint).Address;
m_port = ((IPEndPoint)client.Client.RemoteEndPoint).Port;
m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
m_log.WarnFormat("{0} Constructed", LogHeader);
// Create a thread for the receive loop
m_receive_loop = new Thread(new ThreadStart(delegate() { ReceiveLoop(); }));
m_receive_loop.Name = Description;
m_log.WarnFormat("{0} Started thread: {1}", LogHeader, m_receive_loop.Name);
m_receive_loop.Start();
}
// Stop the RegionSyncClientView, disconnecting the RegionSyncClient
public void Shutdown()
{
// Abort ReceiveLoop Thread, close Socket and TcpClient
m_receive_loop.Abort();
m_tcpclient.Client.Close();
m_tcpclient.Close();
}
// Listen for messages from a RegionSyncClient
// *** This is the main thread loop for each connected client
private void ReceiveLoop()
{
try
{
while (true)
{
RegionSyncMessage msg = GetMessage();
HandleMessage(msg);
}
}
catch (Exception e)
{
m_log.WarnFormat("{0} RegionSyncClient has disconnected.", LogHeader);
}
}
// Get a message from the RegionSyncClient
private RegionSyncMessage GetMessage()
{
// Get a RegionSyncMessager from the incoming stream
RegionSyncMessage msg = new RegionSyncMessage(m_tcpclient.GetStream());
m_log.WarnFormat("{0} Received {1}", LogHeader, msg.ToString());
return msg;
}
// Handle an incoming message
// *** Perhaps this should not be synchronous with the receive
// We could handle messages from an incoming Queue
private bool HandleMessage(RegionSyncMessage msg)
{
//string handlerMessage = "";
switch (msg.Type)
{
case RegionSyncMessage.MsgType.GetObjects:
{
List<EntityBase> entities = m_scene.GetEntities();
foreach(EntityBase e in entities)
{
if (e is SceneObjectGroup)
{
string sogxml = SceneObjectSerializer.ToXml2Format((SceneObjectGroup)e);
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.AddObject, sogxml));
}
}
return HandlerSuccess(msg, "Sent all scene objects");
}
case RegionSyncMessage.MsgType.GetTerrain:
{
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.Terrain, m_scene.Heightmap.SaveToXmlString()));
return HandlerSuccess(msg, "Terrain sent");
}
case RegionSyncMessage.MsgType.GetRegionArchive:
{
IRegionArchiverModule archiver = m_scene.RequestModuleInterface<IRegionArchiverModule>();
if (archiver == null)
{
return HandlerFailure(msg, "Could not retrieve archiver module from scene");
}
MemoryStream ms = new MemoryStream();
// Remember the last time we archived this region to the ClientSyncServer
// Any updates after this time cannot be assumed to be in the archive stream
m_archive_time = DateTime.Now.Ticks;
archiver.ArchiveRegion(ms, Guid.Empty);
// ***
// The call to ArchiveRegion is asynchronous. We need a better way to know when it's done.
// For now, just sleep for 1 second. That will support a vary large region to be archived.
// Since this command is typically only executed when a new RegionSyncClient connects and
// is done on a RegionSyncServer thread, it should not impact other RegionSyncClients the
// RegionSyncServer, or the sim.
Thread.Sleep(1000);
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.RegionArchive, ms.ToArray()));
return HandlerSuccess(msg, "Region archive sent");
}
case RegionSyncMessage.MsgType.AgentAdd:
{
OSDMap data = OSDParser.DeserializeJson(Encoding.ASCII.GetString(msg.Data)) as OSDMap;
if (data != null)
{
UUID agentID = data["agentID"].AsUUID();
string first = data["first"].AsString();
string last = data["last"].AsString();
Vector3 startPos = data["startPos"].AsVector3();
if (agentID != null && first != null && last != null && startPos != null)
{
RegionSyncAvatar av = new RegionSyncAvatar(m_scene, agentID, first, last, startPos);
lock (m_syncedAvatars)
{
if (m_syncedAvatars.ContainsKey(agentID))
{
return HandlerFailure(msg, String.Format( "Attempted to add duplicate avatar with agentID {0}", agentID));
}
m_syncedAvatars.Add(agentID, av);
}
m_scene.AddNewClient(av);
return HandlerSuccess(msg, String.Format("Handled AddAgent for UUID {0}", agentID));
}
}
return HandlerFailure(msg, "Could not parse AddAgent parameters");
}
case RegionSyncMessage.MsgType.AgentUpdate:
{
int len = 0;
AgentUpdatePacket.AgentDataBlock agentData = new AgentUpdatePacket.AgentDataBlock();
agentData.FromBytes(msg.Data, ref len);
UUID agentID = agentData.AgentID;
RegionSyncAvatar av;
bool found;
lock (m_syncedAvatars)
{
found = m_syncedAvatars.TryGetValue(agentData.AgentID, out av);
}
if(!found)
return HandlerFailure(msg, String.Format("Received agent update for non-existent avatar with UUID {0}", agentData.AgentID));
AgentUpdateArgs arg = new AgentUpdateArgs();
arg.AgentID = agentData.AgentID;
arg.BodyRotation = agentData.BodyRotation;
arg.CameraAtAxis = agentData.CameraAtAxis;
arg.CameraCenter = agentData.CameraCenter;
arg.CameraLeftAxis = agentData.CameraLeftAxis;
arg.CameraUpAxis = agentData.CameraUpAxis;
arg.ControlFlags = agentData.ControlFlags;
arg.Far = agentData.Far;
arg.Flags = agentData.Flags;
arg.HeadRotation = agentData.HeadRotation;
arg.SessionID = agentData.SessionID;
arg.State = agentData.State;
if( av.AgentUpdate(arg) )
return HandlerSuccess(msg, String.Format("Handled AgentUpdate for UUID {0}", agentID));
else
return HandlerFailure(msg, String.Format("Could not handle AgentUpdate UUID {0}", agentID));
}
default:
{
m_log.WarnFormat("{0} Unable to handle unsupported message type", LogHeader);
return false;
}
}
}
private bool HandlerSuccess(RegionSyncMessage msg, string handlerMessage)
{
m_log.WarnFormat("{0} Handled {1}: {2}", LogHeader, msg.ToString(), handlerMessage);
return true;
}
private bool HandlerFailure(RegionSyncMessage msg, string handlerMessage)
{
m_log.WarnFormat("{0} Unable to handle {1}: {2}", LogHeader, msg.ToString(), handlerMessage);
return false;
}
public void Send(RegionSyncMessage msg)
{
Send(msg.ToBytes());
//m_log.WarnFormat("{0} Sent {1}", LogHeader, msg.ToString());
}
private void Send(byte[] data)
{
if (m_tcpclient.Connected)
{
try
{
m_tcpclient.GetStream().Write(data, 0, data.Length);
}
catch (IOException e)
{
m_log.WarnFormat("{0} RegionSyncClient has disconnected.", LogHeader);
}
}
}
#region crud
// Should be part of the RegionSyncClient
/*
public string ReceiveMsg()
{
lock (m_outQ)
{
if (m_outQ.Count > 0)
{
return m_outQ.Dequeue();
}
}
return null;
}
* */
#endregion
}
}

View File

@ -0,0 +1,132 @@
using System;
using System.IO;
using OpenMetaverse;
using log4net;
namespace OpenSim.Region.Examples.RegionSyncModule
{
/// <summary>
/// A message for synchonization message between scenes
/// </summary>
public class RegionSyncMessage
{
#region MsgType Enum
public enum MsgType
{
Null,
//ConnectSyncClient,
//DisconnectSyncClient,
// CM -> SIM
AgentAdd,
AgentUpdate,
GetTerrain,
GetRegionArchive,
GetObjects,
GetObject,
ChatFromClient,
// SIM -> CM
Terrain,
RegionArchive,
AddObject,
UpdateObject,
RemoveObject,
AddAvatar,
UpdateAvatarTerse,
RemoveAvatar,
ChatFromSim,
// BIDIR
EchoRequest,
EchoResponse
}
#endregion
#region Member Data
private MsgType m_type;
private byte[] m_data;
#endregion
#region Constructors
public RegionSyncMessage(MsgType type, byte[] data)
{
m_type = type;
m_data = data;
}
public RegionSyncMessage(MsgType type, string msg)
{
m_type = type;
m_data = System.Text.Encoding.ASCII.GetBytes(msg + System.Environment.NewLine);
}
public RegionSyncMessage(MsgType type)
{
m_type = type;
m_data = new byte[0];
}
public RegionSyncMessage(Stream stream)
{
//ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
//try
{
m_type = (MsgType)Utils.BytesToInt(GetBytesFromStream(stream, 4));
int length = Utils.BytesToInt(GetBytesFromStream(stream, 4));
m_data = GetBytesFromStream(stream, length);
//log.WarnFormat("RegionSyncMessage Constructed {0} ({1} bytes)", m_type.ToString(), length);
}
/*
catch (Exception e)
{
log.WarnFormat("[REGION SYNC MESSAGE] RegionSyncMessage Constructor encountered an exception {0}", e.Message);
}
* */
}
private byte[] GetBytesFromStream(Stream stream, int count)
{
// Loop to receive the message length
byte[] ret = new byte[count];
int i = 0;
while (i < count)
{
i += stream.Read(ret, i, count - i);
}
return ret;
}
#endregion
#region Accessors
public MsgType Type
{
get { return m_type; }
}
public int Length
{
get { return m_data.Length; }
}
public byte[] Data
{
get { return m_data; }
}
#endregion
#region Conversions
public byte[] ToBytes()
{
byte[] buf = new byte[m_data.Length + 8];
Utils.IntToBytes((int)m_type, buf, 0);
Utils.IntToBytes(m_data.Length, buf, 4);
Array.Copy(m_data, 0, buf, 8, m_data.Length);
return buf;
}
public override string ToString()
{
return String.Format("{0} ({1} bytes)", m_type.ToString(), m_data.Length.ToString());
}
#endregion
}
}

View File

@ -0,0 +1,161 @@
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Collections.Generic;
using System.Threading;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Interfaces;
using log4net;
namespace OpenSim.Region.Examples.RegionSyncModule
{
// The RegionSyncServer has a listener thread which accepts connections from RegionSyncClients
// and an additional thread to process updates to/from each RegionSyncClient.
public class RegionSyncServer
{
#region RegionSyncServer members
// Set the addr and port for TcpListener
private IPAddress m_addr;
private Int32 m_port;
// The local scene.
private Scene m_scene;
// A queue for incoming and outgoing traffic
// Incoming stuff can be from any client
// Outgoing stuff will be multicast to all clients
private Queue<string> m_inQ = new Queue<string>();
private Queue<string> m_outQ = new Queue<string>();
private ILog m_log;
// The listener and the thread which listens for connections from client managers
private TcpListener m_listener;
private Thread m_listenerThread;
// The list of clients and the threads handling IO for each client
// Lock should be used when client managers connect or disconnect
// while modifying the client list.
private Object clientLock = new Object();
private List<RegionSyncClientView> m_client_views = new List<RegionSyncClientView>();
// Check if any of the client views are in a connected state
public bool Synced
{
get
{
lock (clientLock)
{
foreach (RegionSyncClientView cv in m_client_views)
{
if (cv.Connected)
return true;
}
return false;
}
}
}
#endregion
// Constructor
public RegionSyncServer(Scene scene, string addr, int port)
{
m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
m_log.Warn("[REGION SYNC SERVER] Constructed");
m_scene = scene;
m_addr = IPAddress.Parse(addr);
m_port = port;
}
// Start the server
public void Start()
{
m_listenerThread = new Thread(new ThreadStart(Listen));
m_listenerThread.Name = "RegionSyncServer Listener";
m_log.WarnFormat("[REGION SYNC SERVER] Starting {0} thread", m_listenerThread.Name);
m_listenerThread.Start();
m_log.Warn("[REGION SYNC SERVER] Started");
}
// Stop the server and disconnect all RegionSyncClients
public void Shutdown()
{
lock (clientLock)
{
// Stop the listener and listening thread so no new clients are accepted
m_listener.Stop();
m_listenerThread.Abort();
m_listenerThread = null;
// Stop all existing client views and clear client list
foreach (RegionSyncClientView cv in m_client_views)
{
// Each client view will clean up after itself
cv.Shutdown();
}
m_client_views.Clear();
}
}
// Listen for connections from a new RegionSyncClient
// When connected, start the ReceiveLoop for the new client
private void Listen()
{
m_listener = new TcpListener(m_addr, m_port);
try
{
// Start listening for clients
m_listener.Start();
m_log.WarnFormat("[REGION SYNC SERVER] Listening on port {0}", m_port.ToString());
while (true)
{
// *** Move/Add TRY/CATCH to here, but we don't want to spin loop on the same error
m_log.Warn("[REGION SYNC SERVER] Waiting for a connection...");
TcpClient tcpclient = m_listener.AcceptTcpClient();
IPAddress addr = ((IPEndPoint)tcpclient.Client.RemoteEndPoint).Address;
int port = ((IPEndPoint)tcpclient.Client.RemoteEndPoint).Port;
lock (clientLock)
{
// Add the RegionSyncClientView to the list of clients
// *** Need to work on the timing order of starting the client view and adding to the server list
// so that messages coming from the scene do not get lost before the client view is added but
// not sent before it is ready to process them.
RegionSyncClientView rscv = new RegionSyncClientView(m_client_views.Count, m_scene, tcpclient);
m_log.WarnFormat("[REGION SYNC SERVER] New connection from {0}", rscv.Description);
m_client_views.Add(rscv);
}
}
}
catch (SocketException e)
{
m_log.WarnFormat("[REGION SYNC SERVER] [Listen] SocketException: {0}", e);
}
}
// Broadcast a message to all connected RegionSyncClients
public void Broadcast(RegionSyncMessage msg)
{
List<RegionSyncClientView> clients = new List<RegionSyncClientView>();
lock (clientLock)
{
foreach (RegionSyncClientView client in m_client_views)
{
if (client.Connected)
clients.Add(client);
}
}
if(clients.Count > 0 )
{
//m_log.WarnFormat("[REGION SYNC SERVER] Broadcasting {0} to all connected RegionSyncClients", msg.ToString());
foreach( RegionSyncClientView client in clients)
{
client.Send(msg);
}
}
}
}
}

View File

@ -0,0 +1,473 @@
/*
* 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.Collections.Generic;
using System.Reflection;
using Nini.Config;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
using OpenSim.Framework;
using OpenSim.Framework.Client;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Scenes.Serialization;
using log4net;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace OpenSim.Region.Examples.RegionSyncModule
{
public class RegionSyncServerModule : IRegionModule, IRegionSyncServerModule
{
#region IRegionModule Members
public void Initialise(Scene scene, IConfigSource config)
{
m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
IConfig syncConfig = config.Configs["RegionSyncModule"];
if (syncConfig == null || syncConfig.GetString("Mode", "server").ToLower() != "server")
{
m_active = false;
m_log.Warn("[REGION SYNC SERVER MODULE] Not in server mode. Shutting down.");
return;
}
m_serveraddr = syncConfig.GetString("ServerIPAddress", "127.0.0.1");
m_serverport = syncConfig.GetInt("ServerPort", 13000);
m_scene = scene;
m_scene.RegisterModuleInterface<IRegionSyncServerModule>(this);
m_log.Warn("[REGION SYNC SERVER MODULE] Initialised");
}
public void PostInitialise()
{
if (!m_active)
return;
//m_scene.EventManager.OnObjectBeingRemovedFromScene += new EventManager.ObjectBeingRemovedFromScene(EventManager_OnObjectBeingRemovedFromScene);
//m_scene.EventManager.OnNewClient +=new EventManager.OnNewClientDelegate(EventManager_OnNewClient);
//m_scene.EventManager.OnNewPresence +=new EventManager.OnNewPresenceDelegate(EventManager_OnNewPresence);
//m_scene.EventManager.OnAvatarEnteringNewParcel += new EventManager.AvatarEnteringNewParcel(EventManager_OnAvatarEnteringNewParcel);
//m_scene.EventManager.OnClientMovement += new EventManager.ClientMovement(EventManager_OnClientMovement);
//m_scene.EventManager.OnLandObjectAdded += new EventManager.LandObjectAdded(EventManager_OnLandObjectAdded);
//m_scene.EventManager.OnLandObjectRemoved += new EventManager.LandObjectRemoved(EventManager_OnLandObjectRemoved);
m_scene.EventManager.OnRemovePresence += new EventManager.OnRemovePresenceDelegate(EventManager_OnRemovePresence);
m_scene.SceneGraph.OnObjectCreate += new ObjectCreateDelegate(SceneGraph_OnObjectCreate);
m_scene.SceneGraph.OnObjectDuplicate += new ObjectDuplicateDelegate(SceneGraph_OnObjectDuplicate);
//m_scene.SceneGraph.OnObjectRemove += new ObjectDeleteDelegate(SceneGraph_OnObjectRemove);
//m_scene.StatsReporter.OnSendStatsResult += new SimStatsReporter.SendStatResult(StatsReporter_OnSendStatsResult);
m_log.Warn("[REGION SYNC SERVER MODULE] Starting RegionSyncServer");
// Start the server and listen for RegionSyncClients
m_server = new RegionSyncServer(m_scene, m_serveraddr, m_serverport);
m_server.Start();
m_log.Warn("[REGION SYNC SERVER MODULE] Post-Initialised");
}
void IRegionModule.Close()
{
m_scene = null;
}
public string Name
{
get { return "RegionSyncModule"; }
}
public bool IsSharedModule
{
get { return false; }
}
#endregion
#region IRegionSyncServerModule members
// Lock is used to synchronize access to the update status and both update queues
private object m_updateLock = new object();
private int m_sendingUpdates;
private Dictionary<UUID, SceneObjectGroup> m_primUpdates = new Dictionary<UUID, SceneObjectGroup>();
private Dictionary<UUID, ScenePresence> m_presenceUpdates = new Dictionary<UUID, ScenePresence>();
public void QueuePartForUpdate(SceneObjectPart part)
{
if (!Active || !Synced)
return;
lock (m_primUpdates)
{
m_primUpdates[part.ParentGroup.UUID] = part.ParentGroup;
}
//m_log.WarnFormat("[REGION SYNC SERVER MODULE] QueuePartForUpdate: {0}", part.UUID.ToString());
}
public void QueuePresenceForTerseUpdate(ScenePresence presence)
{
if (!Active || !Synced)
return;
lock (m_presenceUpdates)
{
m_presenceUpdates[presence.UUID] = presence;
}
//m_log.WarnFormat("[REGION SYNC SERVER MODULE] QueuePresenceForUpdate: {0}", presence.UUID.ToString());
}
public void SendUpdates()
{
if (!Active || !Synced)
return;
// Existing value of 1 indicates that updates are currently being sent so skip updates this pass
if (Interlocked.Exchange(ref m_sendingUpdates, 1) == 1)
{
m_log.WarnFormat("[REGION SYNC SERVER MODULE] SendUpdates(): An update thread is already running.");
return;
}
List<SceneObjectGroup> primUpdates;
List<ScenePresence> presenceUpdates;
primUpdates = new List<SceneObjectGroup>(m_primUpdates.Values);
presenceUpdates = new List<ScenePresence>(m_presenceUpdates.Values);
m_primUpdates.Clear();
m_presenceUpdates.Clear();
// This could be another thread for sending outgoing messages or just have the Queue functions
// create and queue the messages directly into the outgoing server thread.
System.Threading.ThreadPool.QueueUserWorkItem(delegate
{
// Sending the message when it's first queued would yield lower latency but much higher load on the simulator
// as parts may be updated many many times very quickly. Need to implement a higher resolution send in heartbeat
foreach (SceneObjectGroup sog in primUpdates)
{
if (!sog.IsDeleted)
{
string sogxml = SceneObjectSerializer.ToXml2Format(sog);
m_server.Broadcast(new RegionSyncMessage(RegionSyncMessage.MsgType.UpdateObject, sogxml));
}
}
foreach (ScenePresence presence in presenceUpdates)
{
if (!presence.IsDeleted)
{
OSDMap data = new OSDMap(4);
data["id"] = OSD.FromUUID(presence.UUID);
// Do not include offset for appearance height. That will be handled by RegionSyncClient before sending to viewers
data["pos"] = OSD.FromVector3(presence.AbsolutePosition);
data["vel"] = OSD.FromVector3(presence.Velocity);
data["rot"] = OSD.FromQuaternion(presence.Rotation);
RegionSyncMessage rsm = new RegionSyncMessage(RegionSyncMessage.MsgType.UpdateAvatarTerse, OSDParser.SerializeJsonString(data));
m_server.Broadcast(rsm);
}
}
// Indicate that the current batch of updates has been completed
Interlocked.Exchange(ref m_sendingUpdates, 0);
});
}
public void DeleteObject(ulong regionHandle, uint localID)
{
if (!Active || !Synced)
return;
OSDMap data = new OSDMap(2);
data["regionHandle"] = OSD.FromULong(regionHandle);
data["localID"] = OSD.FromUInteger(localID);
RegionSyncMessage rsm = new RegionSyncMessage(RegionSyncMessage.MsgType.RemoveObject, OSDParser.SerializeJsonString(data));
m_server.Broadcast(rsm);
}
public bool Active
{
get { return m_active; }
}
// Check if the sync server module is connected to any clients
public bool Synced
{
get
{
if (m_server == null || !m_server.Synced)
return false;
return true;
}
}
#region cruft
#if false
public void QueuePartForUpdate(SceneObjectPart part)
{
m_server.Broadcast(string.Format("QueuePartForUpdate - Name:{0}, LocalID:{1}, UUID:{2}", part.Name, part.LocalId.ToString(), part.UUID.ToString()));
m_log.Warn(string.Format("QueuePartForUpdate - Name:{0}, LocalID:{1}, UUID:{2}", part.Name, part.LocalId.ToString(), part.UUID.ToString()));
//m_log.Warn(System.Environment.StackTrace);
}
public void SendPartFullUpdate(SceneObjectPart part)
{
/*
m_server.Broadcast(string.Format("SendPartFullUpdate - Name:{0}, LocalID:{1}, UUID:{2}", part.Name, part.LocalId.ToString(), part.UUID.ToString()));
m_log.Warn(string.Format("SendPartFullUpdate - Name:{0}, LocalID:{1}, UUID:{2}", part.Name, part.LocalId.ToString(), part.UUID.ToString()));
* */
}
public void SendPartTerseUpdate(SceneObjectPart part)
{
/*
m_server.Broadcast(string.Format("SendPartTerseUpdate - Name:{0}, LocalID:{1}, UUID:{2}", part.Name, part.LocalId.ToString(), part.UUID.ToString()));
m_log.Warn(string.Format("SendPartTerseUpdate - Name:{0}, LocalID:{1}, UUID:{2}", part.Name, part.LocalId.ToString(), part.UUID.ToString()));
* */
}
public void SendShutdownConnectionNotice(Scene scene)
{
/*
m_server.Broadcast("SendShutdownConnectionNotice");
m_log.Warn("SendShutdownConnectionNotice");
* */
}
public void SendKillObject(ulong regionHandle, uint localID)
{
/*
m_server.Broadcast(string.Format("SendKillObject - regionHandle:{0}, localID:{1}", regionHandle.ToString(), localID.ToString()));
m_log.Warn(string.Format("SendKillObject - regionHandle:{0}, localID:{1}", regionHandle.ToString(), localID.ToString()));
m_log.Warn(System.Environment.StackTrace);
* */
}
#endif
#endregion
#endregion
#region RegionSyncServerModule members
private bool m_active = true;
private string m_serveraddr;
private int m_serverport;
private Scene m_scene;
//private IClientAPI m_clientAggregator;
private ILog m_log;
//private int m_moveCounter = 0;
private RegionSyncServer m_server = null;
#endregion
#region Event Handlers
private void SceneGraph_OnObjectCreate(EntityBase entity)
{
if (entity is SceneObjectGroup)
{
string sogxml = SceneObjectSerializer.ToXml2Format((SceneObjectGroup)entity);
RegionSyncMessage rsm = new RegionSyncMessage(RegionSyncMessage.MsgType.AddObject, sogxml);
m_server.Broadcast(rsm);
}
else
{
m_log.Warn("SceneGraph_OnObjectCreate called with non-SceneObjectGroup");
}
}
private void SceneGraph_OnObjectDuplicate(EntityBase original, EntityBase copy)
{
if (original is SceneObjectGroup && copy is SceneObjectGroup)
{
string sogxml = SceneObjectSerializer.ToXml2Format((SceneObjectGroup)copy);
RegionSyncMessage rsm = new RegionSyncMessage(RegionSyncMessage.MsgType.AddObject, sogxml);
m_server.Broadcast(rsm);
}
else
{
m_log.Warn("SceneGraph_OnObjectDuplicate called with non-SceneObjectGroup");
}
}
private void SceneGraph_OnObjectRemove(EntityBase entity)
{
if (entity is SceneObjectGroup)
{
// No reason to send the entire object, just send the UUID to be deleted
RegionSyncMessage rsm = new RegionSyncMessage(RegionSyncMessage.MsgType.RemoveObject, entity.UUID.ToString());
m_server.Broadcast(rsm);
}
else
{
m_log.Warn("SceneGraph_OnObjectDelete called with non-SceneObjectGroup");
}
}
// A ficticious event
public void Scene_AddNewPrim(SceneObjectGroup sog)
{
}
/*
public void StatsReporter_OnSendStatsResult(SimStats stats)
{
//m_log.Warn("SendSimStats");
}
void EventManager_OnObjectBeingRemovedFromScene(SceneObjectGroup sog)
{
string msg = (string.Format("EventManager_OnObjectBeingRemovedFromScene" + System.Environment.NewLine +
"REMOVE: ownerID {0}, groupID {1}, pos {2}, rot {3}, shape {4}, id {5}, localID {6}", sog.OwnerID.ToString(), sog.GroupID.ToString(), sog.RootPart.GroupPosition.ToString(), sog.Rotation.ToString(), sog.RootPart.Shape.ToString(), sog.UUID.ToString(), sog.LocalId.ToString()));
m_server.Broadcast(msg);
m_log.Warn("[REGION SYNC SERVER MODULE] " + msg);
DebugSceneStats();
}
void SceneGraph_OnObjectRemove(EntityBase obj)
{
SceneObjectGroup sog = (SceneObjectGroup)obj;
string msg = (string.Format("SceneGraph_OnObjectRemove" + System.Environment.NewLine +
"REMOVE: ownerID {0}, groupID {1}, pos {2}, rot {3}, shape {4}, id {5}, localID {6}", sog.OwnerID.ToString(), sog.GroupID.ToString(), sog.RootPart.GroupPosition.ToString(), sog.Rotation.ToString(), sog.RootPart.Shape.ToString(), sog.UUID.ToString(), sog.LocalId.ToString()));
m_server.Broadcast(msg);
m_log.Warn("[REGION SYNC SERVER MODULE] " + msg);
DebugSceneStats();
}
void SceneGraph_OnObjectDuplicate(EntityBase original, EntityBase clone)
{
SceneObjectGroup sog1 = (SceneObjectGroup)original;
SceneObjectGroup sog2 = (SceneObjectGroup)clone;
string msg = (string.Format("SceneGraph_OnObjectDuplicate" +
System.Environment.NewLine +
"ORIGINAL: ownerID {0}, groupID {1}, pos {2}, rot {3}, shape {4}, id {5}, localID {6}" +
System.Environment.NewLine +
"CLONE: ownerID {7}, groupID {8}, pos {9}, rot {10}, shape {11}, id {12}, localID {13}",
sog1.OwnerID.ToString(), sog1.GroupID.ToString(), sog1.RootPart.GroupPosition.ToString(), sog1.Rotation.ToString(), sog1.RootPart.Shape.ToString(), sog1.UUID.ToString(), sog1.LocalId.ToString(),
sog2.OwnerID.ToString(), sog2.GroupID.ToString(), sog2.RootPart.GroupPosition.ToString(), sog2.Rotation.ToString(), sog2.RootPart.Shape.ToString(), sog2.UUID.ToString(), sog2.LocalId.ToString()));
m_server.Broadcast(msg);
m_log.Warn("[REGION SYNC SERVER MODULE] " + msg);
m_log.WarnFormat("[REGION SYNC SERVER MODULE] SceneGraph_OnObjectDuplicate");
DebugSceneStats();
}
void SceneGraph_OnObjectCreate(EntityBase obj)
{
SceneObjectGroup sog = (SceneObjectGroup)obj;
string msg = (string.Format("SceneGraph_OnObjectCreate" + System.Environment.NewLine +
"CREATE: ownerID {0}, groupID {1}, pos {2}, rot {3}, shape {4}, id {5}, localID {6}", sog.OwnerID.ToString(), sog.GroupID.ToString(), sog.RootPart.GroupPosition.ToString(), sog.Rotation.ToString(), sog.RootPart.Shape.ToString(), sog.UUID.ToString(), sog.LocalId.ToString()));
m_server.Broadcast(msg);
m_log.Warn("[REGION SYNC SERVER MODULE] " + msg);
//DebugSceneStats();
}
void EventManager_OnLandObjectRemoved(UUID globalID)
{
m_log.WarnFormat("[REGION SYNC SERVER MODULE] EventManager_OnLandObjectRemoved");
DebugSceneStats();
}
void EventManager_OnLandObjectAdded(ILandObject newParcel)
{
m_log.WarnFormat("[REGION SYNC SERVER MODULE] EventManager_OnLandObjectAdded");
DebugSceneStats();
}
void EventManager_OnClientMovement(ScenePresence client)
{
m_moveCounter++;
if (m_moveCounter % 100 == 0)
{
string msg = (string.Format("EventManager_OnClientMovement - Event has been triggered 100 times"));
m_server.Broadcast(msg);
m_log.Warn("REGION SYNC SERVER MODULE] " + msg);
}
}
void EventManager_OnAvatarEnteringNewParcel(ScenePresence avatar, int localLandID, UUID regionID)
{
m_log.WarnFormat("[REGION SYNC SERVER MODULE] (OnAvatarEnteringNewParcel) Avatar \"{0}\" has joined the scene (1) {2} {3} {4}", avatar.Name, avatar.ControllingClient.AgentId.ToString(), avatar.UUID.ToString(), localLandID, regionID.ToString());
DebugSceneStats();
}
private void EventManager_OnNewClient(IClientAPI client)
{
ScenePresence presence = m_scene.GetScenePresence(client.AgentId);
if (presence != null)
{
m_log.WarnFormat("[REGION SYNC SERVER MODULE] (OnNewClient) \"{0}\"", presence.Name);
DebugSceneStats();
}
else
{
m_log.WarnFormat("[REGION SYNC SERVER MODULE] (OnNewClient) A new client connected but module could not get ScenePresence");
}
}
private void EventManager_OnNewPresence(ScenePresence presence)
{
m_log.WarnFormat("[REGION SYNC SERVER MODULE] Avatar \"{0}\" (1) {2} has joined the scene", presence.Firstname + " " + presence.Lastname, presence.ControllingClient.AgentId.ToString(), presence.UUID.ToString());
DebugSceneStats();
}
* */
private void EventManager_OnRemovePresence(UUID agentID)
{
ScenePresence avatar;
if (m_scene.TryGetAvatar(agentID, out avatar))
{
m_log.WarnFormat("[REGION SYNC SERVER MODULE] Avatar \"{0}\" (1) {2} has left the scene", avatar.Firstname + " " + avatar.Lastname, agentID.ToString(), avatar.UUID.ToString());
}
else
{
m_log.WarnFormat("[REGION SYNC SERVER MODULE] Avatar \"unknown\" has left the scene");
}
OSDArray data = new OSDArray();
data.Add(OSD.FromULong(avatar.RegionHandle));
data.Add(OSD.FromUInteger(avatar.LocalId));
RegionSyncMessage rsm = new RegionSyncMessage(RegionSyncMessage.MsgType.RemoveAvatar, data.ToString());
m_server.Broadcast(rsm);
}
#endregion
/*
private void DebugSceneStats()
{
List<ScenePresence> avatars = m_scene.GetAvatars();
List<EntityBase> entities = m_scene.GetEntities();
m_log.WarnFormat("There are {0} avatars and {1} entities in the scene", avatars.Count, entities.Count);
}
public IClientAPI ClientAggregator
{
get {return m_clientAggregator;}
}
private void AddAvatars()
{
for (int i = 0; i < 1; i++)
{
MyNpcCharacter m_character = new MyNpcCharacter(m_scene, this);
m_scene.AddNewClient(m_character);
m_scene.AgentCrossing(m_character.AgentId, m_character.StartPos, false);
}
}
*/
}
}

View File

@ -56,6 +56,7 @@ namespace OpenSim.Region.Examples.SimpleModule
public event ImprovedInstantMessage OnInstantMessage;
public event ChatMessage OnChatFromClient;
public event ChatMessageRaw OnChatFromClientRaw;
public event TextureRequest OnRequestTexture;
public event RezObject OnRezObject;
public event ModifyTerrain OnModifyTerrain;
@ -86,6 +87,7 @@ namespace OpenSim.Region.Examples.SimpleModule
public event GenericCall1 OnCompleteMovementToRegion;
public event UpdateAgent OnPreAgentUpdate;
public event UpdateAgent OnAgentUpdate;
public event UpdateAgentRaw OnAgentUpdateRaw;
public event AgentRequestSit OnAgentRequestSit;
public event AgentSit OnAgentSit;
public event AvatarPickerRequest OnAvatarPickerRequest;

View File

@ -319,6 +319,33 @@ namespace OpenSim.Region.Framework.Scenes
protected IDialogModule m_dialogModule;
protected IEntityTransferModule m_teleportModule;
protected IRegionSyncServerModule m_regionSyncServerModule;
protected IRegionSyncClientModule m_regionSyncClientModule;
public Object regionSyncLock = new Object();
public IRegionSyncServerModule RegionSyncServerModule
{
get { return m_regionSyncServerModule; }
set { m_regionSyncServerModule = value; }
}
public IRegionSyncClientModule RegionSyncClientModule
{
get { return m_regionSyncClientModule; }
set { m_regionSyncClientModule = value; }
}
public bool IsSyncedClient()
{
return (m_regionSyncClientModule != null && m_regionSyncClientModule.Active && m_regionSyncClientModule.Synced);
}
public bool IsSyncedServer()
{
return (m_regionSyncServerModule != null && m_regionSyncServerModule.Active && m_regionSyncServerModule.Synced);
}
protected ICapabilitiesModule m_capsModule;
public ICapabilitiesModule CapsModule
{
@ -1219,6 +1246,8 @@ namespace OpenSim.Region.Framework.Scenes
m_dialogModule = RequestModuleInterface<IDialogModule>();
m_capsModule = RequestModuleInterface<ICapabilitiesModule>();
m_teleportModule = RequestModuleInterface<IEntityTransferModule>();
RegionSyncServerModule = RequestModuleInterface<IRegionSyncServerModule>();
RegionSyncClientModule = RequestModuleInterface<IRegionSyncClientModule>();
}
#endregion
@ -1290,6 +1319,9 @@ namespace OpenSim.Region.Framework.Scenes
if (m_frame % m_update_presences == 0)
m_sceneGraph.UpdatePresences();
if (IsSyncedServer())
m_regionSyncServerModule.SendUpdates();
int tmpPhysicsMS2 = Util.EnvironmentTickCount();
if ((m_frame % m_update_physics == 0) && m_physics_enabled)
m_sceneGraph.UpdatePreparePhysics();
@ -2449,8 +2481,14 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="client"></param>
public override void AddNewClient(IClientAPI client)
{
AddNewClient2(client, true);
}
public void AddNewClient2(IClientAPI client, bool managed)
{
bool vialogin = false;
if(managed)
m_clientManager.Add(client);
CheckHeartbeat();
@ -3069,6 +3107,11 @@ namespace OpenSim.Region.Framework.Scenes
}
m_eventManager.TriggerOnRemovePresence(agentID);
if(IsSyncedServer())
RegionSyncServerModule.DeleteObject(avatar.RegionHandle, avatar.LocalId);
else
{
ForEachClient(
delegate(IClientAPI client)
{
@ -3077,6 +3120,7 @@ namespace OpenSim.Region.Framework.Scenes
catch (NullReferenceException) { }
});
ForEachScenePresence(
delegate(ScenePresence presence) { presence.CoarseLocationChange(); });
@ -3085,6 +3129,7 @@ namespace OpenSim.Region.Framework.Scenes
{
agentTransactions.RemoveAgentAssetTransactions(agentID);
}
}
// Remove the avatar from the scene
m_sceneGraph.RemoveScenePresence(agentID);
@ -3154,6 +3199,11 @@ namespace OpenSim.Region.Framework.Scenes
return;
}
}
// REGION SYNC
if( IsSyncedServer() )
RegionSyncServerModule.DeleteObject(m_regionHandle, localID);
else
ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, localID); });
}
@ -4198,8 +4248,11 @@ namespace OpenSim.Region.Framework.Scenes
///
/// </summary>
/// <param name="action"></param>
static int s_ForEachPresenceCounter = 0;
public void ForEachScenePresence(Action<ScenePresence> action)
{
if (IsSyncedServer())
return;
// We don't want to try to send messages if there are no avatars.
if (m_sceneGraph != null)
{
@ -4289,11 +4342,18 @@ namespace OpenSim.Region.Framework.Scenes
public void ForEachClient(Action<IClientAPI> action)
{
// REGION SYNC
if (IsSyncedServer())
return;
ForEachClient(action, m_useAsyncWhenPossible);
}
public void ForEachClient(Action<IClientAPI> action, bool doAsynchronous)
{
// REGION SYNC
if (IsSyncedServer())
return;
// FIXME: Asynchronous iteration is disabled until we have a threading model that
// can support calling this function from an async packet handler without
// potentially deadlocking

View File

@ -801,7 +801,7 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary>
/// <param name="fullID"></param>
/// <returns>null if no scene object group containing that prim is found</returns>
private SceneObjectGroup GetGroupByPrim(UUID fullID)
public SceneObjectGroup GetGroupByPrim(UUID fullID)
{
SceneObjectGroup sog;
lock (SceneObjectGroupsByFullID)

View File

@ -1268,22 +1268,27 @@ namespace OpenSim.Region.Framework.Scenes
foreach (SceneObjectPart part in m_parts.Values)
{
// part.Inventory.RemoveScriptInstances();
// REGION SYNC
if (Scene.IsSyncedServer())
{
Scene.RegionSyncServerModule.DeleteObject(part.RegionHandle, part.LocalId);
return;
}
ScenePresence[] avatars = Scene.GetScenePresences();
for (int i = 0; i < avatars.Length; i++)
Scene.ForEachScenePresence(delegate(ScenePresence avatar)
{
if (avatars[i].ParentID == LocalId)
if (avatar.ParentID == LocalId)
{
avatars[i].StandUp();
avatar.StandUp();
}
if (!silent)
{
part.UpdateFlag = 0;
if (part == m_rootPart)
avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId);
}
avatar.ControllingClient.SendKillObject(m_regionHandle, part.LocalId);
}
});
}
}
}

View File

@ -1260,11 +1260,11 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary>
public void AddFullUpdateToAllAvatars()
{
ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences();
for (int i = 0; i < avatars.Length; i++)
{
avatars[i].SceneViewer.QueuePartForUpdate(this);
}
// REGION SYNC
if (m_parentGroup.Scene.IsSyncedServer())
m_parentGroup.Scene.RegionSyncServerModule.QueuePartForUpdate(this);
m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) { avatar.SceneViewer.QueuePartForUpdate(this); });
}
public void AddFullUpdateToAvatar(ScenePresence presence)
@ -1285,11 +1285,10 @@ namespace OpenSim.Region.Framework.Scenes
/// Terse updates
public void AddTerseUpdateToAllAvatars()
{
ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences();
for (int i = 0; i < avatars.Length; i++)
{
avatars[i].SceneViewer.QueuePartForUpdate(this);
}
if (m_parentGroup.Scene.IsSyncedServer())
m_parentGroup.Scene.RegionSyncServerModule.QueuePartForUpdate(this);
m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) { avatar.SceneViewer.QueuePartForUpdate(this); });
}
public void AddTerseUpdateToAvatar(ScenePresence presence)
@ -2877,11 +2876,10 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary>
public void SendFullUpdateToAllClients()
{
ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences();
for (int i = 0; i < avatars.Length; i++)
m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
{
SendFullUpdate(avatars[i].ControllingClient, avatars[i].GenerateClientFlags(UUID));
}
SendFullUpdate(avatar.ControllingClient, avatar.GenerateClientFlags(UUID));
});
}
/// <summary>
@ -2890,13 +2888,12 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="agentID"></param>
public void SendFullUpdateToAllClientsExcept(UUID agentID)
{
ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences();
for (int i = 0; i < avatars.Length; i++)
m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
{
// Ugly reference :(
if (avatars[i].UUID != agentID)
SendFullUpdate(avatars[i].ControllingClient, avatars[i].GenerateClientFlags(UUID));
}
if (avatar.UUID != agentID)
SendFullUpdate(avatar.ControllingClient, avatar.GenerateClientFlags(UUID));
});
}
/// <summary>
@ -3096,11 +3093,7 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary>
public void SendTerseUpdateToAllClients()
{
ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences();
for (int i = 0; i < avatars.Length; i++)
{
SendTerseUpdateToClient(avatars[i].ControllingClient);
}
m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) { SendTerseUpdateToClient(avatar.ControllingClient); });
}
public void SetAttachmentPoint(uint AttachmentPoint)

View File

@ -688,9 +688,12 @@ namespace OpenSim.Region.Framework.Scenes
AbsolutePosition = posLastSignificantMove = m_CameraCenter =
m_lastCameraCenter = m_controllingClient.StartPos;
if (!m_scene.IsSyncedServer())
{
m_reprioritization_timer = new Timer(world.ReprioritizationInterval);
m_reprioritization_timer.Elapsed += new ElapsedEventHandler(Reprioritize);
m_reprioritization_timer.AutoReset = false;
}
AdjustKnownSeeds();
@ -730,6 +733,9 @@ namespace OpenSim.Region.Framework.Scenes
m_controllingClient.OnSetAppearance += SetAppearance;
m_controllingClient.OnCompleteMovementToRegion += CompleteMovement;
//m_controllingClient.OnCompleteMovementToRegion += SendInitialData;
// REGION SYNC
if(!m_scene.IsSyncedClient())
m_controllingClient.OnAgentUpdate += HandleAgentUpdate;
m_controllingClient.OnAgentRequestSit += HandleAgentRequestSit;
m_controllingClient.OnAgentSit += HandleAgentSit;
@ -912,14 +918,11 @@ namespace OpenSim.Region.Framework.Scenes
m_isChildAgent = false;
ScenePresence[] animAgents = m_scene.GetScenePresences();
for (int i = 0; i < animAgents.Length; i++)
m_scene.ForEachScenePresence(delegate(ScenePresence presence)
{
ScenePresence presence = animAgents[i];
if (presence != this)
presence.Animator.SendAnimPackToClient(ControllingClient);
}
});
m_scene.EventManager.TriggerOnMakeRootAgent(this);
}

View File

@ -652,6 +652,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
public event GenericMessage OnGenericMessage;
public event ImprovedInstantMessage OnInstantMessage;
public event ChatMessage OnChatFromClient;
public event ChatMessageRaw OnChatFromClientRaw;
public event TextureRequest OnRequestTexture;
public event RezObject OnRezObject;
public event ModifyTerrain OnModifyTerrain;
@ -682,6 +683,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
public event GenericCall1 OnCompleteMovementToRegion;
public event UpdateAgent OnPreAgentUpdate;
public event UpdateAgent OnAgentUpdate;
public event UpdateAgentRaw OnAgentUpdateRaw;
public event AgentRequestSit OnAgentRequestSit;
public event AgentSit OnAgentSit;
public event AvatarPickerRequest OnAvatarPickerRequest;

View File

@ -163,6 +163,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
public event GenericMessage OnGenericMessage;
public event ImprovedInstantMessage OnInstantMessage;
public event ChatMessage OnChatFromClient;
public event ChatMessageRaw OnChatFromClientRaw;
public event TextureRequest OnRequestTexture;
public event RezObject OnRezObject;
public event ModifyTerrain OnModifyTerrain;
@ -192,6 +193,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
public event GenericCall1 OnCompleteMovementToRegion;
public event UpdateAgent OnPreAgentUpdate;
public event UpdateAgent OnAgentUpdate;
public event UpdateAgentRaw OnAgentUpdateRaw;
public event AgentRequestSit OnAgentRequestSit;
public event AgentSit OnAgentSit;
public event AvatarPickerRequest OnAvatarPickerRequest;

View File

@ -68,6 +68,7 @@ namespace OpenSim.Tests.Common.Mock
public event ImprovedInstantMessage OnInstantMessage;
public event ChatMessage OnChatFromClient;
public event ChatMessageRaw OnChatFromClientRaw;
public event TextureRequest OnRequestTexture;
public event RezObject OnRezObject;
public event ModifyTerrain OnModifyTerrain;
@ -97,6 +98,7 @@ namespace OpenSim.Tests.Common.Mock
public event GenericCall2 OnRequestWearables;
public event GenericCall1 OnCompleteMovementToRegion;
public event UpdateAgent OnPreAgentUpdate;
public event UpdateAgentRaw OnAgentUpdateRaw;
public event UpdateAgent OnAgentUpdate;
public event AgentRequestSit OnAgentRequestSit;
public event AgentSit OnAgentSit;

View File

@ -24,7 +24,7 @@
</appender>
<root>
<level value="DEBUG" />
<level value="WARN" />
<appender-ref ref="Console" />
<appender-ref ref="LogFileAppender" />
</root>