Some work on sceneapi
parent
28e4302eb6
commit
4216eacd6c
|
@ -9,6 +9,12 @@
|
|||
*.pdb
|
||||
*.pidb
|
||||
*.dll.build
|
||||
*/*/obj
|
||||
*/*/*/obj
|
||||
*/*/*/*/obj
|
||||
*/*/*/*/*/obj
|
||||
*/*/*/*/*/*/obj
|
||||
*/*/*/*/*/*/*/obj
|
||||
*/*/bin
|
||||
*/*/*/bin
|
||||
*/*/*/*/bin
|
||||
|
|
|
@ -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="--debug" />
|
||||
<arg value="--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="--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>
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 { };
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,60 +4849,68 @@ 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)
|
||||
{
|
||||
AgentUpdateArgs arg = new AgentUpdateArgs();
|
||||
arg.AgentID = x.AgentID;
|
||||
arg.BodyRotation = x.BodyRotation;
|
||||
arg.CameraAtAxis = x.CameraAtAxis;
|
||||
arg.CameraCenter = x.CameraCenter;
|
||||
arg.CameraLeftAxis = x.CameraLeftAxis;
|
||||
arg.CameraUpAxis = x.CameraUpAxis;
|
||||
arg.ControlFlags = x.ControlFlags;
|
||||
arg.Far = x.Far;
|
||||
arg.Flags = x.Flags;
|
||||
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;
|
||||
handlerAgentUpdateRaw(this, xb);
|
||||
handlerAgentUpdateRaw = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
AgentUpdateArgs arg = new AgentUpdateArgs();
|
||||
arg.AgentID = x.AgentID;
|
||||
arg.BodyRotation = x.BodyRotation;
|
||||
arg.CameraAtAxis = x.CameraAtAxis;
|
||||
arg.CameraCenter = x.CameraCenter;
|
||||
arg.CameraLeftAxis = x.CameraLeftAxis;
|
||||
arg.CameraUpAxis = x.CameraUpAxis;
|
||||
arg.ControlFlags = x.ControlFlags;
|
||||
arg.Far = x.Far;
|
||||
arg.Flags = x.Flags;
|
||||
arg.HeadRotation = x.HeadRotation;
|
||||
arg.SessionID = x.SessionID;
|
||||
arg.State = x.State;
|
||||
|
||||
UpdateAgent handlerAgentUpdate = OnAgentUpdate;
|
||||
if (handlerAgentUpdate != null)
|
||||
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();
|
||||
|
|
|
@ -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
|
@ -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;
|
||||
}
|
||||
* */
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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,9 +2481,15 @@ 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;
|
||||
|
||||
m_clientManager.Add(client);
|
||||
if(managed)
|
||||
m_clientManager.Add(client);
|
||||
|
||||
CheckHeartbeat();
|
||||
SubscribeToClientEvents(client);
|
||||
|
@ -3069,21 +3107,28 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
|
||||
m_eventManager.TriggerOnRemovePresence(agentID);
|
||||
ForEachClient(
|
||||
delegate(IClientAPI client)
|
||||
{
|
||||
//We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway
|
||||
try { client.SendKillObject(avatar.RegionHandle, avatar.LocalId); }
|
||||
catch (NullReferenceException) { }
|
||||
});
|
||||
|
||||
ForEachScenePresence(
|
||||
delegate(ScenePresence presence) { presence.CoarseLocationChange(); });
|
||||
|
||||
IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>();
|
||||
if (agentTransactions != null)
|
||||
if(IsSyncedServer())
|
||||
RegionSyncServerModule.DeleteObject(avatar.RegionHandle, avatar.LocalId);
|
||||
else
|
||||
{
|
||||
agentTransactions.RemoveAgentAssetTransactions(agentID);
|
||||
ForEachClient(
|
||||
delegate(IClientAPI client)
|
||||
{
|
||||
//We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway
|
||||
try { client.SendKillObject(avatar.RegionHandle, avatar.LocalId); }
|
||||
catch (NullReferenceException) { }
|
||||
});
|
||||
|
||||
|
||||
ForEachScenePresence(
|
||||
delegate(ScenePresence presence) { presence.CoarseLocationChange(); });
|
||||
|
||||
IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>();
|
||||
if (agentTransactions != null)
|
||||
{
|
||||
agentTransactions.RemoveAgentAssetTransactions(agentID);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the avatar from the scene
|
||||
|
@ -3154,7 +3199,12 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
return;
|
||||
}
|
||||
}
|
||||
ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, localID); });
|
||||
|
||||
// REGION SYNC
|
||||
if( IsSyncedServer() )
|
||||
RegionSyncServerModule.DeleteObject(m_regionHandle, localID);
|
||||
else
|
||||
ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, localID); });
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -1268,22 +1268,27 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
foreach (SceneObjectPart part in m_parts.Values)
|
||||
{
|
||||
// part.Inventory.RemoveScriptInstances();
|
||||
|
||||
ScenePresence[] avatars = Scene.GetScenePresences();
|
||||
for (int i = 0; i < avatars.Length; i++)
|
||||
// REGION SYNC
|
||||
if (Scene.IsSyncedServer())
|
||||
{
|
||||
if (avatars[i].ParentID == LocalId)
|
||||
Scene.RegionSyncServerModule.DeleteObject(part.RegionHandle, part.LocalId);
|
||||
return;
|
||||
}
|
||||
|
||||
Scene.ForEachScenePresence(delegate(ScenePresence avatar)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -688,9 +688,12 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
AbsolutePosition = posLastSignificantMove = m_CameraCenter =
|
||||
m_lastCameraCenter = m_controllingClient.StartPos;
|
||||
|
||||
m_reprioritization_timer = new Timer(world.ReprioritizationInterval);
|
||||
m_reprioritization_timer.Elapsed += new ElapsedEventHandler(Reprioritize);
|
||||
m_reprioritization_timer.AutoReset = false;
|
||||
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,7 +733,10 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
m_controllingClient.OnSetAppearance += SetAppearance;
|
||||
m_controllingClient.OnCompleteMovementToRegion += CompleteMovement;
|
||||
//m_controllingClient.OnCompleteMovementToRegion += SendInitialData;
|
||||
m_controllingClient.OnAgentUpdate += HandleAgentUpdate;
|
||||
|
||||
// REGION SYNC
|
||||
if(!m_scene.IsSyncedClient())
|
||||
m_controllingClient.OnAgentUpdate += HandleAgentUpdate;
|
||||
m_controllingClient.OnAgentRequestSit += HandleAgentRequestSit;
|
||||
m_controllingClient.OnAgentSit += HandleAgentSit;
|
||||
m_controllingClient.OnSetAlwaysRun += HandleSetAlwaysRun;
|
||||
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
</appender>
|
||||
|
||||
<root>
|
||||
<level value="DEBUG" />
|
||||
<level value="WARN" />
|
||||
<appender-ref ref="Console" />
|
||||
<appender-ref ref="LogFileAppender" />
|
||||
</root>
|
||||
|
|
Loading…
Reference in New Issue