aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs4
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs58
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs5
-rw-r--r--OpenSim/Region/Framework/Interfaces/IScenePresence.cs22
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs15
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneBase.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs39
-rw-r--r--OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs8
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs5
9 files changed, 85 insertions, 73 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 7d39ddc..f246637 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -379,6 +379,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
379 set { m_startpos = value; } 379 set { m_startpos = value; }
380 } 380 }
381 public UUID AgentId { get { return m_agentId; } } 381 public UUID AgentId { get { return m_agentId; } }
382 public ISceneAgent SceneAgent { get; private set; }
382 public UUID ActiveGroupId { get { return m_activeGroupID; } } 383 public UUID ActiveGroupId { get { return m_activeGroupID; } }
383 public string ActiveGroupName { get { return m_activeGroupName; } } 384 public string ActiveGroupName { get { return m_activeGroupName; } }
384 public ulong ActiveGroupPowers { get { return m_activeGroupPowers; } } 385 public ulong ActiveGroupPowers { get { return m_activeGroupPowers; } }
@@ -508,6 +509,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
508 509
509 // Remove ourselves from the scene 510 // Remove ourselves from the scene
510 m_scene.RemoveClient(AgentId, true); 511 m_scene.RemoveClient(AgentId, true);
512 SceneAgent = null;
511 513
512 // We can't reach into other scenes and close the connection 514 // We can't reach into other scenes and close the connection
513 // We need to do this over grid communications 515 // We need to do this over grid communications
@@ -687,7 +689,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
687 689
688 public virtual void Start() 690 public virtual void Start()
689 { 691 {
690 m_scene.AddNewClient(this, PresenceType.User); 692 SceneAgent = m_scene.AddNewClient(this, PresenceType.User);
691 693
692 RefreshGroupMembership(); 694 RefreshGroupMembership();
693 } 695 }
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index ccad241..7db5f6b 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -894,11 +894,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
894 IPEndPoint remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint; 894 IPEndPoint remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint;
895 895
896 // Begin the process of adding the client to the simulator 896 // Begin the process of adding the client to the simulator
897 AddNewClient((UseCircuitCodePacket)packet, remoteEndPoint); 897 IClientAPI client = AddNewClient((UseCircuitCodePacket)packet, remoteEndPoint);
898 898
899 // Send ack 899 // Send ack straight away to let the viewer know that the connection is active.
900 SendAckImmediate(remoteEndPoint, packet.Header.Sequence); 900 SendAckImmediate(remoteEndPoint, packet.Header.Sequence);
901 901
902 // FIXME: Nasty - this is the only way we currently know if Scene.AddNewClient() failed to find a
903 // circuit and bombed out early. That check might be pointless since authorization is established
904 // up here.
905 if (client != null && client.SceneAgent != null)
906 client.SceneAgent.SendInitialDataToMe();
907
902 // m_log.DebugFormat( 908 // m_log.DebugFormat(
903// "[LLUDPSERVER]: Handling UseCircuitCode request from {0} took {1}ms", 909// "[LLUDPSERVER]: Handling UseCircuitCode request from {0} took {1}ms",
904// buffer.RemoteEndPoint, (DateTime.Now - startTime).Milliseconds); 910// buffer.RemoteEndPoint, (DateTime.Now - startTime).Milliseconds);
@@ -933,7 +939,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
933 return sessionInfo.Authorised; 939 return sessionInfo.Authorised;
934 } 940 }
935 941
936 private void AddNewClient(UseCircuitCodePacket useCircuitCode, IPEndPoint remoteEndPoint) 942 /// <summary>
943 /// Add a new client.
944 /// </summary>
945 /// <param name="useCircuitCode"></param>
946 /// <param name="remoteEndPoint"></param>
947 /// <returns>
948 /// The client that was added or null if the client failed authorization or already existed.
949 /// </returns>
950 private IClientAPI AddNewClient(UseCircuitCodePacket useCircuitCode, IPEndPoint remoteEndPoint)
937 { 951 {
938 UUID agentID = useCircuitCode.CircuitCode.ID; 952 UUID agentID = useCircuitCode.CircuitCode.ID;
939 UUID sessionID = useCircuitCode.CircuitCode.SessionID; 953 UUID sessionID = useCircuitCode.CircuitCode.SessionID;
@@ -942,7 +956,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
942 AuthenticateResponse sessionInfo; 956 AuthenticateResponse sessionInfo;
943 if (IsClientAuthorized(useCircuitCode, out sessionInfo)) 957 if (IsClientAuthorized(useCircuitCode, out sessionInfo))
944 { 958 {
945 AddClient(circuitCode, agentID, sessionID, remoteEndPoint, sessionInfo); 959 return AddClient(circuitCode, agentID, sessionID, remoteEndPoint, sessionInfo);
946 } 960 }
947 else 961 else
948 { 962 {
@@ -950,38 +964,44 @@ namespace OpenSim.Region.ClientStack.LindenUDP
950 m_log.WarnFormat( 964 m_log.WarnFormat(
951 "[LLUDPSERVER]: Connection request for client {0} connecting with unnotified circuit code {1} from {2}", 965 "[LLUDPSERVER]: Connection request for client {0} connecting with unnotified circuit code {1} from {2}",
952 useCircuitCode.CircuitCode.ID, useCircuitCode.CircuitCode.Code, remoteEndPoint); 966 useCircuitCode.CircuitCode.ID, useCircuitCode.CircuitCode.Code, remoteEndPoint);
967
968 return null;
953 } 969 }
954 } 970 }
955 971
956 protected virtual void AddClient(uint circuitCode, UUID agentID, UUID sessionID, IPEndPoint remoteEndPoint, AuthenticateResponse sessionInfo) 972 /// <summary>
973 /// Add a client.
974 /// </summary>
975 /// <param name="circuitCode"></param>
976 /// <param name="agentID"></param>
977 /// <param name="sessionID"></param>
978 /// <param name="remoteEndPoint"></param>
979 /// <param name="sessionInfo"></param>
980 /// <returns>The client if it was added. Null if the client already existed.</returns>
981 protected virtual IClientAPI AddClient(
982 uint circuitCode, UUID agentID, UUID sessionID, IPEndPoint remoteEndPoint, AuthenticateResponse sessionInfo)
957 { 983 {
984 IClientAPI client = null;
985
958 // In priciple there shouldn't be more than one thread here, ever. 986 // In priciple there shouldn't be more than one thread here, ever.
959 // But in case that happens, we need to synchronize this piece of code 987 // But in case that happens, we need to synchronize this piece of code
960 // because it's too important 988 // because it's too important
961 lock (this) 989 lock (this)
962 { 990 {
963 IClientAPI existingClient; 991 if (!m_scene.TryGetClient(agentID, out client))
964
965 if (!m_scene.TryGetClient(agentID, out existingClient))
966 { 992 {
967 // Create the LLUDPClient
968 LLUDPClient udpClient = new LLUDPClient(this, ThrottleRates, m_throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO); 993 LLUDPClient udpClient = new LLUDPClient(this, ThrottleRates, m_throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO);
969 // Create the LLClientView 994
970 LLClientView client = new LLClientView(remoteEndPoint, m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode); 995 client = new LLClientView(remoteEndPoint, m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
971 client.OnLogout += LogoutHandler; 996 client.OnLogout += LogoutHandler;
972 997
973 client.DisableFacelights = m_disableFacelights; 998 ((LLClientView)client).DisableFacelights = m_disableFacelights;
974 999
975 // Start the IClientAPI
976 client.Start(); 1000 client.Start();
977
978 }
979 else
980 {
981 m_log.WarnFormat("[LLUDPSERVER]: Ignoring a repeated UseCircuitCode from {0} at {1} for circuit {2}",
982 existingClient.AgentId, remoteEndPoint, circuitCode);
983 } 1001 }
984 } 1002 }
1003
1004 return client;
985 } 1005 }
986 1006
987 private void RemoveClient(LLUDPClient udpClient) 1007 private void RemoveClient(LLUDPClient udpClient)
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs
index 737c654..fb94355 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs
@@ -53,9 +53,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
53 public override void Update() {} 53 public override void Update() {}
54 public override void LoadWorldMap() {} 54 public override void LoadWorldMap() {}
55 55
56 public override void AddNewClient(IClientAPI client, PresenceType type) 56 public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type)
57 { 57 {
58 client.OnObjectName += RecordObjectNameCall; 58 client.OnObjectName += RecordObjectNameCall;
59
60 // FIXME
61 return null;
59 } 62 }
60 63
61 public override void RemoveClient(UUID agentID, bool someReason) {} 64 public override void RemoveClient(UUID agentID, bool someReason) {}
diff --git a/OpenSim/Region/Framework/Interfaces/IScenePresence.cs b/OpenSim/Region/Framework/Interfaces/IScenePresence.cs
index ff39283..5e43843 100644
--- a/OpenSim/Region/Framework/Interfaces/IScenePresence.cs
+++ b/OpenSim/Region/Framework/Interfaces/IScenePresence.cs
@@ -38,28 +38,8 @@ namespace OpenSim.Region.Framework.Interfaces
38 /// <remarks> 38 /// <remarks>
39 /// Interface is a work in progress. Please feel free to add other required properties and methods. 39 /// Interface is a work in progress. Please feel free to add other required properties and methods.
40 /// </remarks> 40 /// </remarks>
41 public interface IScenePresence : ISceneEntity 41 public interface IScenePresence : ISceneAgent
42 { 42 {
43 /// <value>
44 /// The client controlling this presence
45 /// </value>
46 IClientAPI ControllingClient { get; }
47
48 /// <summary>
49 /// What type of presence is this? User, NPC, etc.
50 /// </summary>
51 PresenceType PresenceType { get; }
52
53 /// <summary>
54 /// Avatar appearance data.
55 /// </summary>
56 /// <remarks>
57 // Because appearance setting is in a module, we actually need
58 // to give it access to our appearance directly, otherwise we
59 // get a synchronization issue.
60 /// </remarks>
61 AvatarAppearance Appearance { get; set; }
62
63 /// <summary> 43 /// <summary>
64 /// The AttachmentsModule synchronizes on this to avoid race conditions between commands to add and remove attachments. 44 /// The AttachmentsModule synchronizes on this to avoid race conditions between commands to add and remove attachments.
65 /// </summary> 45 /// </summary>
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 21c4a87..d47536a 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -2491,13 +2491,13 @@ namespace OpenSim.Region.Framework.Scenes
2491 /// </summary> 2491 /// </summary>
2492 /// <param name="client"></param> 2492 /// <param name="client"></param>
2493 /// <param name="type">The type of agent to add.</param> 2493 /// <param name="type">The type of agent to add.</param>
2494 public override void AddNewClient(IClientAPI client, PresenceType type) 2494 public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type)
2495 { 2495 {
2496 AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode); 2496 AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode);
2497 bool vialogin = false; 2497 bool vialogin = false;
2498 2498
2499 if (aCircuit == null) // no good, didn't pass NewUserConnection successfully 2499 if (aCircuit == null) // no good, didn't pass NewUserConnection successfully
2500 return; 2500 return null;
2501 2501
2502 vialogin = (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0 || 2502 vialogin = (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0 ||
2503 (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0; 2503 (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0;
@@ -2552,16 +2552,7 @@ namespace OpenSim.Region.Framework.Scenes
2552 if (vialogin) 2552 if (vialogin)
2553 EventManager.TriggerOnClientLogin(client); 2553 EventManager.TriggerOnClientLogin(client);
2554 2554
2555 // Send all scene object to the new client 2555 return sp;
2556 Util.FireAndForget(delegate
2557 {
2558 EntityBase[] entities = Entities.GetEntities();
2559 foreach(EntityBase e in entities)
2560 {
2561 if (e != null && e is SceneObjectGroup)
2562 ((SceneObjectGroup)e).SendFullUpdateToClient(client);
2563 }
2564 });
2565 } 2556 }
2566 2557
2567 /// <summary> 2558 /// <summary>
diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs
index a633c72..da15491 100644
--- a/OpenSim/Region/Framework/Scenes/SceneBase.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs
@@ -175,7 +175,7 @@ namespace OpenSim.Region.Framework.Scenes
175 175
176 #region Add/Remove Agent/Avatar 176 #region Add/Remove Agent/Avatar
177 177
178 public abstract void AddNewClient(IClientAPI client, PresenceType type); 178 public abstract ISceneAgent AddNewClient(IClientAPI client, PresenceType type);
179 public abstract void RemoveClient(UUID agentID, bool closeChildAgents); 179 public abstract void RemoveClient(UUID agentID, bool closeChildAgents);
180 180
181 public bool TryGetScenePresence(UUID agentID, out object scenePresence) 181 public bool TryGetScenePresence(UUID agentID, out object scenePresence)
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 5b9438b..8e55996 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -782,15 +782,6 @@ namespace OpenSim.Region.Framework.Scenes
782 782
783 AdjustKnownSeeds(); 783 AdjustKnownSeeds();
784 784
785 // we created a new ScenePresence (a new child agent) in a fresh region.
786 // Request info about all the (root) agents in this region
787 // Note: This won't send data *to* other clients in that region (children don't send)
788
789// MIC: This gets called again in CompleteMovement
790 // SendInitialFullUpdateToAllClients();
791 SendOtherAgentsAvatarDataToMe();
792 SendOtherAgentsAppearanceToMe();
793
794 RegisterToEvents(); 785 RegisterToEvents();
795 SetDirectionVectors(); 786 SetDirectionVectors();
796 787
@@ -1191,9 +1182,9 @@ namespace OpenSim.Region.Framework.Scenes
1191 { 1182 {
1192// DateTime startTime = DateTime.Now; 1183// DateTime startTime = DateTime.Now;
1193 1184
1194 m_log.DebugFormat( 1185// m_log.DebugFormat(
1195 "[SCENE PRESENCE]: Completing movement of {0} into region {1}", 1186// "[SCENE PRESENCE]: Completing movement of {0} into region {1}",
1196 client.Name, Scene.RegionInfo.RegionName); 1187// client.Name, Scene.RegionInfo.RegionName);
1197 1188
1198 Vector3 look = Velocity; 1189 Vector3 look = Velocity;
1199 if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) 1190 if ((look.X == 0) && (look.Y == 0) && (look.Z == 0))
@@ -1225,7 +1216,7 @@ namespace OpenSim.Region.Framework.Scenes
1225 //m_log.DebugFormat("[SCENE PRESENCE] Completed movement"); 1216 //m_log.DebugFormat("[SCENE PRESENCE] Completed movement");
1226 1217
1227 ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look); 1218 ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look);
1228 SendInitialData(); 1219 ValidateAndSendAppearanceAndAgentData();
1229 1220
1230 // Create child agents in neighbouring regions 1221 // Create child agents in neighbouring regions
1231 if (openChildAgents && !IsChildAgent) 1222 if (openChildAgents && !IsChildAgent)
@@ -2512,11 +2503,31 @@ namespace OpenSim.Region.Framework.Scenes
2512 ControllingClient.SendCoarseLocationUpdate(avatarUUIDs, coarseLocations); 2503 ControllingClient.SendCoarseLocationUpdate(avatarUUIDs, coarseLocations);
2513 } 2504 }
2514 2505
2506 public void SendInitialDataToMe()
2507 {
2508 // we created a new ScenePresence (a new child agent) in a fresh region.
2509 // Request info about all the (root) agents in this region
2510 // Note: This won't send data *to* other clients in that region (children don't send)
2511 SendOtherAgentsAvatarDataToMe();
2512 SendOtherAgentsAppearanceToMe();
2513
2514 // Send all scene object to the new client
2515 Util.FireAndForget(delegate
2516 {
2517 EntityBase[] entities = Scene.Entities.GetEntities();
2518 foreach(EntityBase e in entities)
2519 {
2520 if (e != null && e is SceneObjectGroup)
2521 ((SceneObjectGroup)e).SendFullUpdateToClient(ControllingClient);
2522 }
2523 });
2524 }
2525
2515 /// <summary> 2526 /// <summary>
2516 /// Do everything required once a client completes its movement into a region and becomes 2527 /// Do everything required once a client completes its movement into a region and becomes
2517 /// a root agent. 2528 /// a root agent.
2518 /// </summary> 2529 /// </summary>
2519 private void SendInitialData() 2530 private void ValidateAndSendAppearanceAndAgentData()
2520 { 2531 {
2521 //m_log.DebugFormat("[SCENE PRESENCE] SendInitialData: {0} ({1})", Name, UUID); 2532 //m_log.DebugFormat("[SCENE PRESENCE] SendInitialData: {0} ({1})", Name, UUID);
2522 // Moved this into CompleteMovement to ensure that Appearance is initialized before 2533 // Moved this into CompleteMovement to ensure that Appearance is initialized before
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
index 380570b..70326b7 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
@@ -55,6 +55,8 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
55 55
56 private UUID m_agentID = UUID.Random(); 56 private UUID m_agentID = UUID.Random();
57 57
58 public ISceneAgent SceneAgent { get; private set; }
59
58 private string m_username; 60 private string m_username;
59 private string m_nick; 61 private string m_nick;
60 62
@@ -547,6 +549,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
547 549
548 m_connected = false; 550 m_connected = false;
549 m_client.Close(); 551 m_client.Close();
552 SceneAgent = null;
550 } 553 }
551 554
552 public UUID SessionId 555 public UUID SessionId
@@ -890,12 +893,11 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
890 893
891 public void Start() 894 public void Start()
892 { 895 {
893 Scene.AddNewClient(this, PresenceType.User); 896 SceneAgent = m_scene.AddNewClient(this, PresenceType.User);
894 897
895 // Mimicking LLClientView which gets always set appearance from client. 898 // Mimicking LLClientView which gets always set appearance from client.
896 Scene scene = (Scene)Scene;
897 AvatarAppearance appearance; 899 AvatarAppearance appearance;
898 scene.GetAvatarAppearance(this, out appearance); 900 m_scene.GetAvatarAppearance(this, out appearance);
899 OnSetAppearance(this, appearance.Texture, (byte[])appearance.VisualParams.Clone()); 901 OnSetAppearance(this, appearance.Texture, (byte[])appearance.VisualParams.Clone());
900 } 902 }
901 903
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
index 152377a..ed60976 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
@@ -43,7 +43,6 @@ namespace OpenSim.Region.OptionalModules.World.NPC
43 private readonly UUID m_uuid = UUID.Random(); 43 private readonly UUID m_uuid = UUID.Random();
44 private readonly Scene m_scene; 44 private readonly Scene m_scene;
45 45
46
47 public NPCAvatar(string firstname, string lastname, Vector3 position, Scene scene) 46 public NPCAvatar(string firstname, string lastname, Vector3 position, Scene scene)
48 { 47 {
49 m_firstname = firstname; 48 m_firstname = firstname;
@@ -57,6 +56,8 @@ namespace OpenSim.Region.OptionalModules.World.NPC
57 get { return m_scene; } 56 get { return m_scene; }
58 } 57 }
59 58
59 public ISceneAgent SceneAgent { get { throw new NotImplementedException(); } }
60
60 public void Say(string message) 61 public void Say(string message)
61 { 62 {
62 SendOnChatFromClient(message, ChatTypeEnum.Say); 63 SendOnChatFromClient(message, ChatTypeEnum.Say);
@@ -841,6 +842,8 @@ namespace OpenSim.Region.OptionalModules.World.NPC
841 842
842 public void Start() 843 public void Start()
843 { 844 {
845 // We never start the client, so always fail.
846 throw new NotImplementedException();
844 } 847 }
845 848
846 public void Stop() 849 public void Stop()