OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
Scene.cs
Go to the documentation of this file.
1 /*
2  * Copyright (c) Contributors, http://opensimulator.org/
3  * See CONTRIBUTORS.TXT for a full list of copyright holders.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of the OpenSimulator Project nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 using System;
29 using System.Collections.Generic;
30 using System.Diagnostics;
31 using System.Drawing;
32 using System.Drawing.Imaging;
33 using System.IO;
34 using System.Text;
35 using System.Threading;
36 using System.Timers;
37 using System.Xml;
38 using Nini.Config;
39 using OpenMetaverse;
40 using OpenMetaverse.Packets;
41 using OpenMetaverse.Imaging;
42 using OpenMetaverse.StructuredData;
43 using OpenSim.Framework;
44 using OpenSim.Framework.Monitoring;
45 using OpenSim.Services.Interfaces;
46 using OpenSim.Framework.Console;
47 using OpenSim.Region.Framework.Interfaces;
48 using OpenSim.Region.Framework.Scenes.Scripting;
49 using OpenSim.Region.Framework.Scenes.Serialization;
50 using OpenSim.Region.PhysicsModules.SharedBase;
55 
56 namespace OpenSim.Region.Framework.Scenes
57 {
58  public delegate bool FilterAvatarList(ScenePresence avatar);
59 
60  public partial class Scene : SceneBase
61  {
62  private const long DEFAULT_MIN_TIME_FOR_PERSISTENCE = 60L;
63  private const long DEFAULT_MAX_TIME_FOR_PERSISTENCE = 600L;
64 
65 
66  public delegate void SynchronizeSceneHandler(Scene scene);
67 
68  #region Fields
69 
70  public bool EmergencyMonitoring = false;
71 
75  public bool DebugAnimations { get; set; }
76 
80  public bool DebugTeleporting { get; set; }
81 
85  public bool DebugUpdates { get; set; }
86 
96  public bool PeriodicBackup { get; set; }
97 
102  public bool UseBackup { get; set; }
103 
107 
108  public bool PhysicsEnabled
109  {
110  get
111  {
112  return m_physicsEnabled;
113  }
114 
115  set
116  {
117  m_physicsEnabled = value;
118 
119  if (PhysicsScene != null)
120  {
122 
123  if (physScene != null)
124  physScene.SetPhysicsParameter(
125  "Active", m_physicsEnabled.ToString(), PhysParameterEntry.APPLY_TO_NONE);
126  }
127  }
128  }
129 
130  private bool m_physicsEnabled;
131 
135  public bool ScriptsEnabled
136  {
137  get { return m_scripts_enabled; }
138  set
139  {
140  if (m_scripts_enabled != value)
141  {
142  if (!value)
143  {
144  m_log.Info("Stopping all Scripts in Scene");
145 
146  EntityBase[] entities = Entities.GetEntities();
147  foreach (EntityBase ent in entities)
148  {
149  if (ent is SceneObjectGroup)
150  ((SceneObjectGroup)ent).RemoveScriptInstances(false);
151  }
152  }
153  else
154  {
155  m_log.Info("Starting all Scripts in Scene");
156 
157  EntityBase[] entities = Entities.GetEntities();
158  foreach (EntityBase ent in entities)
159  {
160  if (ent is SceneObjectGroup)
161  {
162  SceneObjectGroup sog = (SceneObjectGroup)ent;
163  sog.CreateScriptInstances(0, false, DefaultScriptEngine, 0);
164  sog.ResumeScripts();
165  }
166  }
167  }
168 
169  m_scripts_enabled = value;
170  }
171  }
172  }
173  private bool m_scripts_enabled;
174 
175  public SynchronizeSceneHandler SynchronizeScene;
176 
177  public bool ClampNegativeZ
178  {
179  get { return m_clampNegativeZ; }
180  }
181 
182  private bool m_clampNegativeZ = false;
183 
187  private object m_removeClientLock = new object();
188 
192  public SimStatsReporter StatsReporter { get; private set; }
193 
198  public bool PhysicalPrims { get; private set; }
199 
206  public bool CollidablePrims { get; private set; }
207 
211  public float m_minNonphys = 0.001f;
212 
216  public float m_maxNonphys = 256;
217 
221  public float m_minPhys = 0.01f;
222 
226  public float m_maxPhys = 10;
227 
231  public int m_linksetCapacity = 0;
232 
233  public bool m_clampPrimSize;
234  public bool m_trustBinaries;
235  public bool m_allowScriptCrossings = true;
236 
241  public bool LegacySitOffsets = true;
242 
246  public bool AllowAvatarCrossing { get; set; }
247 
251  public int m_linksetPhysCapacity = 0;
252 
253  public bool m_useFlySlow;
254  public bool m_useTrashOnDelete = true;
255 
259  public bool SendPeriodicAppearanceUpdates { get; set; }
260 
264  public float RootPositionUpdateTolerance { get; set; }
265 
269  public float RootRotationUpdateTolerance { get; set; }
270 
274  public float RootVelocityUpdateTolerance { get; set; }
275 
279  public int RootTerseUpdatePeriod { get; set; }
280 
284  public int ChildTerseUpdatePeriod { get; set; }
285 
286  protected float m_defaultDrawDistance = 255f;
287  public float DefaultDrawDistance
288  {
289  get { return m_defaultDrawDistance; }
290  }
291 
292  protected float m_maxDrawDistance = 512.0f;
293 // protected float m_maxDrawDistance = 256.0f;
294  public float MaxDrawDistance
295  {
296  get { return m_maxDrawDistance; }
297  }
298 
299  protected float m_maxRegionViewDistance = 255f;
300  public float MaxRegionViewDistance
301  {
302  get { return m_maxRegionViewDistance; }
303  }
304 
305  private List<string> m_AllowedViewers = new List<string>();
306  private List<string> m_BannedViewers = new List<string>();
307 
308  // TODO: need to figure out how allow client agents but deny
309  // root agents when ACL denies access to root agent
310  public bool m_strictAccessControl = true;
311  public bool m_seeIntoBannedRegion = false;
312  public int MaxUndoCount = 5;
313 
314  public bool SeeIntoRegion { get; set; }
315 
316  // Using this for RegionReady module to prevent LoginsDisabled from changing under our feet;
317  public bool LoginLock = false;
318 
319  public bool StartDisabled = false;
320  public bool LoadingPrims;
322 
323  // the minimum time that must elapse before a changed object will be considered for persisted
324  public long m_dontPersistBefore = DEFAULT_MIN_TIME_FOR_PERSISTENCE * 10000000L;
325  // the maximum time that must elapse before a changed object will be considered for persisted
326  public long m_persistAfter = DEFAULT_MAX_TIME_FOR_PERSISTENCE * 10000000L;
327 
328  protected int m_splitRegionID;
329  protected Timer m_restartWaitTimer = new Timer();
330  protected Timer m_timerWatchdog = new Timer();
331  protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>();
332  protected List<RegionInfo> m_neighbours = new List<RegionInfo>();
333  protected string m_simulatorVersion = "OpenSimulator Server";
336  protected ISnmpModule m_snmpService = null;
337 
352 
356  protected IConfigSource m_config;
361 
362  private Dictionary<string, string> m_extraSettings;
363 
367  public uint Frame
368  {
369  get;
370  protected set;
371  }
372 
376  public uint MaintenanceRun { get; private set; }
377 
381  public float FrameTime { get; private set; }
382  public int FrameTimeWarnPercent { get; private set; }
383  public int FrameTimeCritPercent { get; private set; }
384 
385  // Normalize the frame related stats to nominal 55fps for viewer and scripts option
386  // see SimStatsReporter.cs
387  public bool Normalized55FPS { get; private set; }
388 
395  public float MinMaintenanceTime { get; private set; }
396 
397  private int m_update_physics = 1;
398  private int m_update_entitymovement = 1;
399  private int m_update_objects = 1;
400  private int m_update_presences = 1; // Update scene presence movements
401  private int m_update_events = 1;
402  private int m_update_backup = 200;
403 
404  private int m_update_terrain = 1000;
405  private int m_update_land = 10;
406 
407  private int m_update_coarse_locations = 50;
408  private int m_update_temp_cleaning = 180;
409 
410  private float agentMS;
411  private float frameMS;
412  private float physicsMS2;
413  private float physicsMS;
414  private float otherMS;
415  private float tempOnRezMS;
416  private float eventMS;
417  private float backupMS;
418  private float terrainMS;
419  private float landMS;
420 
424  private int m_lastFrameTick;
425 
426  public bool CombineRegions = false;
430  private int m_lastMaintenanceTick;
431 
435  private long m_scriptExecutionTime = 0;
436 
441  private bool m_cleaningTemps = false;
442 
446  private ManualResetEvent m_updateWaitEvent = new ManualResetEvent(false);
447 
451  private ManualResetEvent m_maintenanceWaitEvent = new ManualResetEvent(false);
452 
453  // TODO: Possibly stop other classes being able to manipulate this directly.
454  private SceneGraph m_sceneGraph;
455  private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing
456  private volatile bool m_backingup;
457  private Dictionary<UUID, ReturnInfo> m_returns = new Dictionary<UUID, ReturnInfo>();
458  private Dictionary<UUID, int> m_groupsWithTargets = new Dictionary<UUID, int>();
459 
460  private string m_defaultScriptEngine;
461 
462  private int m_unixStartTime;
463  public int UnixStartTime
464  {
465  get { return m_unixStartTime; }
466  }
467 
471  private int m_LastLogin;
472 
473  private int m_lastIncoming;
474  private int m_lastOutgoing;
475  private int m_hbRestarts = 0;
476 
477 
481  private Thread m_heartbeatThread;
482 
486  public bool ShuttingDown
487  {
488  get { return m_shuttingDown; }
489  }
490  private volatile bool m_shuttingDown;
491 
500  public bool Active
501  {
502  get { return m_active; }
503  set
504  {
505  if (value)
506  {
507  if (!m_active)
508  Start(false);
509  }
510  else
511  {
512  // This appears assymetric with Start() above but is not - setting m_active = false stops the loops
513  // XXX: Possibly this should be in an explicit Stop() method for symmetry.
514  m_active = false;
515  }
516  }
517  }
518  private volatile bool m_active;
519 
523  public bool IsRunning { get { return m_isRunning; } }
524  private volatile bool m_isRunning;
525 
526 // private int m_lastUpdate;
527  private bool m_firstHeartbeat = true;
528 
529 // private UpdatePrioritizationSchemes m_priorityScheme = UpdatePrioritizationSchemes.Time;
530 // private bool m_reprioritizationEnabled = true;
531 // private double m_reprioritizationInterval = 5000.0;
532 // private double m_rootReprioritizationDistance = 10.0;
533 // private double m_childReprioritizationDistance = 20.0;
534 
535 
536  private Timer m_mapGenerationTimer = new Timer();
537  private bool m_generateMaptiles;
538 
539  #endregion Fields
540 
541  #region Properties
542 
543  /* Used by the loadbalancer plugin on GForge */
544  public int SplitRegionID
545  {
546  get { return m_splitRegionID; }
547  set { m_splitRegionID = value; }
548  }
549 
550  public new float TimeDilation
551  {
552  get { return m_sceneGraph.PhysicsScene.TimeDilation; }
553  }
554 
555  public void setThreadCount(int inUseThreads)
556  {
557  // Just pass the thread count information on its way as the Scene
558  // does not require the value for anything at this time
559  StatsReporter.SetThreadCount(inUseThreads);
560  }
561 
562  public SceneCommunicationService SceneGridService
563  {
564  get { return m_sceneGridService; }
565  }
566 
567  public ISnmpModule SnmpService
568  {
569  get
570  {
571  if (m_snmpService == null)
572  {
573  m_snmpService = RequestModuleInterface<ISnmpModule>();
574  }
575 
576  return m_snmpService;
577  }
578  }
579 
580  public ISimulationDataService SimulationDataService
581  {
582  get
583  {
584  if (m_SimulationDataService == null)
585  {
586  m_SimulationDataService = RequestModuleInterface<ISimulationDataService>();
587 
588  if (m_SimulationDataService == null)
589  {
590  throw new Exception("No ISimulationDataService available.");
591  }
592  }
593 
594  return m_SimulationDataService;
595  }
596  }
597 
598  public IEstateDataService EstateDataService
599  {
600  get
601  {
602  if (m_EstateDataService == null)
603  {
604  m_EstateDataService = RequestModuleInterface<IEstateDataService>();
605 
606  if (m_EstateDataService == null)
607  {
608  throw new Exception("No IEstateDataService available.");
609  }
610  }
611 
612  return m_EstateDataService;
613  }
614  }
615 
616  public IAssetService AssetService
617  {
618  get
619  {
620  if (m_AssetService == null)
621  {
622  m_AssetService = RequestModuleInterface<IAssetService>();
623 
624  if (m_AssetService == null)
625  {
626  throw new Exception("No IAssetService available.");
627  }
628  }
629 
630  return m_AssetService;
631  }
632  }
633 
634  public IAuthorizationService AuthorizationService
635  {
636  get
637  {
638  if (m_AuthorizationService == null)
639  {
640  m_AuthorizationService = RequestModuleInterface<IAuthorizationService>();
641 
642  //if (m_AuthorizationService == null)
643  //{
644  // // don't throw an exception if no authorization service is set for the time being
645  // m_log.InfoFormat("[SCENE]: No Authorization service is configured");
646  //}
647  }
648 
649  return m_AuthorizationService;
650  }
651  }
652 
653  public IInventoryService InventoryService
654  {
655  get
656  {
657  if (m_InventoryService == null)
658  {
659  m_InventoryService = RequestModuleInterface<IInventoryService>();
660 
661  if (m_InventoryService == null)
662  {
663  throw new Exception("No IInventoryService available. This could happen if the config_include folder doesn't exist or if the OpenSim.ini [Architecture] section isn't set. Please also check that you have the correct version of your inventory service dll. Sometimes old versions of this dll will still exist. Do a clean checkout and re-create the opensim.ini from the opensim.ini.example.");
664  }
665  }
666 
667  return m_InventoryService;
668  }
669  }
670 
671  public IGridService GridService
672  {
673  get
674  {
675  if (m_GridService == null)
676  {
677  m_GridService = RequestModuleInterface<IGridService>();
678 
679  if (m_GridService == null)
680  {
681  throw new Exception("No IGridService available. This could happen if the config_include folder doesn't exist or if the OpenSim.ini [Architecture] section isn't set. Please also check that you have the correct version of your inventory service dll. Sometimes old versions of this dll will still exist. Do a clean checkout and re-create the opensim.ini from the opensim.ini.example.");
682  }
683  }
684 
685  return m_GridService;
686  }
687  }
688 
689  public ILibraryService LibraryService
690  {
691  get
692  {
693  if (m_LibraryService == null)
694  m_LibraryService = RequestModuleInterface<ILibraryService>();
695 
696  return m_LibraryService;
697  }
698  }
699 
700  public ISimulationService SimulationService
701  {
702  get
703  {
704  if (m_simulationService == null)
705  m_simulationService = RequestModuleInterface<ISimulationService>();
706 
707  return m_simulationService;
708  }
709  }
710 
711  public IAuthenticationService AuthenticationService
712  {
713  get
714  {
715  if (m_AuthenticationService == null)
716  m_AuthenticationService = RequestModuleInterface<IAuthenticationService>();
717  return m_AuthenticationService;
718  }
719  }
720 
721  public IPresenceService PresenceService
722  {
723  get
724  {
725  if (m_PresenceService == null)
726  m_PresenceService = RequestModuleInterface<IPresenceService>();
727  return m_PresenceService;
728  }
729  }
730 
731  public IUserAccountService UserAccountService
732  {
733  get
734  {
735  if (m_UserAccountService == null)
736  m_UserAccountService = RequestModuleInterface<IUserAccountService>();
737  return m_UserAccountService;
738  }
739  }
740 
741  public IAvatarService AvatarService
742  {
743  get
744  {
745  if (m_AvatarService == null)
746  m_AvatarService = RequestModuleInterface<IAvatarService>();
747  return m_AvatarService;
748  }
749  }
750 
751  public IGridUserService GridUserService
752  {
753  get
754  {
755  if (m_GridUserService == null)
756  m_GridUserService = RequestModuleInterface<IGridUserService>();
757  return m_GridUserService;
758  }
759  }
760 
761  public IAgentPreferencesService AgentPreferencesService
762  {
763  get
764  {
765  if (m_AgentPreferencesService == null)
766  m_AgentPreferencesService = RequestModuleInterface<IAgentPreferencesService>();
767  return m_AgentPreferencesService;
768  }
769  }
770 
771  public IAttachmentsModule AttachmentsModule { get; set; }
772  public IEntityTransferModule EntityTransferModule { get; private set; }
773  public IAgentAssetTransactions AgentTransactionsModule { get; private set; }
774  public IUserManagement UserManagementModule { get; private set; }
775 
776  public IAvatarFactoryModule AvatarFactory
777  {
778  get { return m_AvatarFactory; }
779  }
780 
781  public ICapabilitiesModule CapsModule
782  {
783  get { return m_capsModule; }
784  }
785 
786  public int MonitorFrameTime { get { return (int)frameMS; } }
787  public int MonitorPhysicsUpdateTime { get { return (int)physicsMS; } }
788  public int MonitorPhysicsSyncTime { get { return (int)physicsMS2; } }
789  public int MonitorOtherTime { get { return (int)otherMS; } }
790  public int MonitorTempOnRezTime { get { return (int)tempOnRezMS; } }
791  public int MonitorEventTime { get { return (int)eventMS; } } // This may need to be divided into each event?
792  public int MonitorBackupTime { get { return (int)backupMS; } }
793  public int MonitorTerrainTime { get { return (int)terrainMS; } }
794  public int MonitorLandTime { get { return (int)landMS; } }
795  public int MonitorLastFrameTick { get { return m_lastFrameTick; } }
796 
797  public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get; set; }
798  public bool IsReprioritizationEnabled { get; set; }
799  public float ReprioritizationInterval { get; set; }
800  public float RootReprioritizationDistance { get; set; }
801  public float ChildReprioritizationDistance { get; set; }
802  private float m_minReprioritizationDistance = 32f;
803 
804  public AgentCircuitManager AuthenticateHandler
805  {
806  get { return m_authenticateHandler; }
807  }
808 
809  // an instance to the physics plugin's Scene object.
811  {
812  get { return m_sceneGraph.PhysicsScene; }
813  set
814  {
815  // If we're not doing the initial set
816  // Then we've got to remove the previous
817  // event handler
819  {
820  PhysicsScene.OnJointMoved -= jointMoved;
821  PhysicsScene.OnJointDeactivated -= jointDeactivated;
822  PhysicsScene.OnJointErrorMessage -= jointErrorMessage;
823  }
824 
825  m_sceneGraph.PhysicsScene = value;
826 
827  if (PhysicsScene != null && m_sceneGraph.PhysicsScene.SupportsNINJAJoints)
828  {
829  // register event handlers to respond to joint movement/deactivation
830  PhysicsScene.OnJointMoved += jointMoved;
831  PhysicsScene.OnJointDeactivated += jointDeactivated;
832  PhysicsScene.OnJointErrorMessage += jointErrorMessage;
833  }
834  }
835  }
836 
837  public string DefaultScriptEngine
838  {
839  get { return m_defaultScriptEngine; }
840  }
841 
842  public EntityManager Entities
843  {
844  get { return m_sceneGraph.Entities; }
845  }
846 
847 
848  // used in sequence see: SpawnPoint()
849  private int m_SpawnPoint;
850  // can be closest/random/sequence
851  public string SpawnPointRouting
852  {
853  get;
854  private set;
855  }
856  // allow landmarks to pass
857  public bool TelehubAllowLandmarks
858  {
859  get;
860  private set;
861  }
862 
863  #endregion Properties
864 
865  #region Constructors
866 
867  public Scene(RegionInfo regInfo, AgentCircuitManager authen,
868  ISimulationDataService simDataService, IEstateDataService estateDataService,
869  IConfigSource config, string simulatorVersion)
870  : this(regInfo)
871  {
872  m_config = config;
873  FrameTime = 0.0908f;
874  FrameTimeWarnPercent = 60;
875  FrameTimeCritPercent = 40;
876  Normalized55FPS = true;
877  MinMaintenanceTime = 1;
878  SeeIntoRegion = true;
879 
880  Random random = new Random();
881 
882  m_lastAllocatedLocalId = (uint)(random.NextDouble() * (double)(uint.MaxValue / 2)) + (uint)(uint.MaxValue / 4);
883  m_authenticateHandler = authen;
884  m_sceneGridService = new SceneCommunicationService();
885  m_SimulationDataService = simDataService;
886  m_EstateDataService = estateDataService;
887 
888  m_lastIncoming = 0;
889  m_lastOutgoing = 0;
890 
891  m_asyncSceneObjectDeleter = new AsyncSceneObjectGroupDeleter(this);
892  m_asyncSceneObjectDeleter.Enabled = true;
893 
894  m_asyncInventorySender = new AsyncInventorySender(this);
895 
896  #region Region Settings
897 
898  // Load region settings
899  // LoadRegionSettings creates new region settings in persistence if they don't already exist for this region.
900  // However, in this case, the default textures are not set in memory properly, so we need to do it here and
901  // resave.
902  // FIXME: It shouldn't be up to the database plugins to create this data - we should do it when a new
903  // region is set up and avoid these gyrations.
904  RegionSettings rs = simDataService.LoadRegionSettings(RegionInfo.RegionID);
905  m_extraSettings = simDataService.GetExtra(RegionInfo.RegionID);
906 
907  bool updatedTerrainTextures = false;
908  if (rs.TerrainTexture1 == UUID.Zero)
909  {
910  rs.TerrainTexture1 = RegionSettings.DEFAULT_TERRAIN_TEXTURE_1;
911  updatedTerrainTextures = true;
912  }
913 
914  if (rs.TerrainTexture2 == UUID.Zero)
915  {
916  rs.TerrainTexture2 = RegionSettings.DEFAULT_TERRAIN_TEXTURE_2;
917  updatedTerrainTextures = true;
918  }
919 
920  if (rs.TerrainTexture3 == UUID.Zero)
921  {
922  rs.TerrainTexture3 = RegionSettings.DEFAULT_TERRAIN_TEXTURE_3;
923  updatedTerrainTextures = true;
924  }
925 
926  if (rs.TerrainTexture4 == UUID.Zero)
927  {
928  rs.TerrainTexture4 = RegionSettings.DEFAULT_TERRAIN_TEXTURE_4;
929  updatedTerrainTextures = true;
930  }
931 
932  if (updatedTerrainTextures)
933  rs.Save();
934 
935  RegionInfo.RegionSettings = rs;
936 
937  if (estateDataService != null)
938  RegionInfo.EstateSettings = estateDataService.LoadEstateSettings(RegionInfo.RegionID, false);
939 
940  #endregion Region Settings
941 
942  //Bind Storage Manager functions to some land manager functions for this scene
943  EventManager.OnLandObjectAdded +=
944  new EventManager.LandObjectAdded(simDataService.StoreLandObject);
945  EventManager.OnLandObjectRemoved +=
946  new EventManager.LandObjectRemoved(simDataService.RemoveLandObject);
947 
948  RegisterDefaultSceneEvents();
949 
950  // XXX: Don't set the public property since we don't want to activate here. This needs to be handled
951  // better in the future.
952  m_scripts_enabled = !RegionInfo.RegionSettings.DisableScripts;
953 
954  PhysicsEnabled = !RegionInfo.RegionSettings.DisablePhysics;
955 
956  m_simulatorVersion = simulatorVersion + " (" + Util.GetRuntimeInformation() + ")";
957 
958  #region Region Config
959 
960  // Region config overrides global config
961  //
962  if (m_config.Configs["Startup"] != null)
963  {
964  IConfig startupConfig = m_config.Configs["Startup"];
965 
966  StartDisabled = startupConfig.GetBoolean("StartDisabled", false);
967 
968  m_defaultDrawDistance = startupConfig.GetFloat("DefaultDrawDistance", m_defaultDrawDistance);
969  m_maxDrawDistance = startupConfig.GetFloat("MaxDrawDistance", m_maxDrawDistance);
970  m_maxRegionViewDistance = startupConfig.GetFloat("MaxRegionsViewDistance", m_maxRegionViewDistance);
971 
972  LegacySitOffsets = startupConfig.GetBoolean("LegacyOpenSimSitOffsets", LegacySitOffsets);
973 
974  if (m_defaultDrawDistance > m_maxDrawDistance)
975  m_defaultDrawDistance = m_maxDrawDistance;
976 
977  if (m_maxRegionViewDistance > m_maxDrawDistance)
978  m_maxRegionViewDistance = m_maxDrawDistance;
979 
980  UseBackup = startupConfig.GetBoolean("UseSceneBackup", UseBackup);
981  if (!UseBackup)
982  m_log.InfoFormat("[SCENE]: Backup has been disabled for {0}", RegionInfo.RegionName);
983 
984  //Animation states
985  m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false);
986 
987  SeeIntoRegion = startupConfig.GetBoolean("see_into_region", SeeIntoRegion);
988 
989  MaxUndoCount = startupConfig.GetInt("MaxPrimUndos", 20);
990 
991  PhysicalPrims = startupConfig.GetBoolean("physical_prim", true);
992  CollidablePrims = startupConfig.GetBoolean("collidable_prim", true);
993  m_minNonphys = startupConfig.GetFloat("NonPhysicalPrimMin", m_minNonphys);
994  if (RegionInfo.NonphysPrimMin > 0)
995  {
996  m_minNonphys = RegionInfo.NonphysPrimMin;
997  }
998 
999  m_maxNonphys = startupConfig.GetFloat("NonPhysicalPrimMax", m_maxNonphys);
1000  if (RegionInfo.NonphysPrimMax > 0)
1001  {
1002  m_maxNonphys = RegionInfo.NonphysPrimMax;
1003  }
1004 
1005  m_minPhys = startupConfig.GetFloat("PhysicalPrimMin", m_minPhys);
1006  if (RegionInfo.PhysPrimMin > 0)
1007  {
1008  m_minPhys = RegionInfo.PhysPrimMin;
1009  }
1010 
1011  m_maxPhys = startupConfig.GetFloat("PhysicalPrimMax", m_maxPhys);
1012 
1013  if (RegionInfo.PhysPrimMax > 0)
1014  {
1015  m_maxPhys = RegionInfo.PhysPrimMax;
1016  }
1017 
1018  m_linksetCapacity = startupConfig.GetInt("LinksetPrims", m_linksetCapacity);
1019  if (RegionInfo.LinksetCapacity > 0)
1020  {
1021  m_linksetCapacity = RegionInfo.LinksetCapacity;
1022  }
1023 
1024  m_linksetPhysCapacity = startupConfig.GetInt("LinksetPhysPrims", m_linksetPhysCapacity);
1025 
1026 
1027  SpawnPointRouting = startupConfig.GetString("SpawnPointRouting", "closest");
1028  TelehubAllowLandmarks = startupConfig.GetBoolean("TelehubAllowLandmark", false);
1029 
1030  // Here, if clamping is requested in either global or
1031  // local config, it will be used
1032  //
1033  m_clampPrimSize = startupConfig.GetBoolean("ClampPrimSize", m_clampPrimSize);
1035  {
1036  m_clampPrimSize = true;
1037  }
1038 
1039  m_clampNegativeZ = startupConfig.GetBoolean("ClampNegativeZ", m_clampNegativeZ);
1040 
1041  m_useTrashOnDelete = startupConfig.GetBoolean("UseTrashOnDelete",m_useTrashOnDelete);
1042  m_trustBinaries = startupConfig.GetBoolean("TrustBinaries", m_trustBinaries);
1043  m_allowScriptCrossings = startupConfig.GetBoolean("AllowScriptCrossing", m_allowScriptCrossings);
1044  m_dontPersistBefore =
1045  startupConfig.GetLong("MinimumTimeBeforePersistenceConsidered", DEFAULT_MIN_TIME_FOR_PERSISTENCE);
1046  m_dontPersistBefore *= 10000000;
1047  m_persistAfter =
1048  startupConfig.GetLong("MaximumTimeBeforePersistenceConsidered", DEFAULT_MAX_TIME_FOR_PERSISTENCE);
1049  m_persistAfter *= 10000000;
1050 
1051  m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine");
1052  m_log.InfoFormat("[SCENE]: Default script engine {0}", m_defaultScriptEngine);
1053 
1054  m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl);
1055  m_seeIntoBannedRegion = startupConfig.GetBoolean("SeeIntoBannedRegion", m_seeIntoBannedRegion);
1056  CombineRegions = startupConfig.GetBoolean("CombineContiguousRegions", false);
1057 
1058  string[] possibleMapConfigSections = new string[] { "Map", "Startup" };
1059 
1060  m_generateMaptiles
1061  = Util.GetConfigVarFromSections<bool>(config, "GenerateMaptiles", possibleMapConfigSections, true);
1062 
1063  if (m_generateMaptiles)
1064  {
1065  int maptileRefresh = Util.GetConfigVarFromSections<int>(config, "MaptileRefresh", possibleMapConfigSections, 0);
1066  m_log.InfoFormat("[SCENE]: Region {0}, WORLD MAP refresh time set to {1} seconds", RegionInfo.RegionName, maptileRefresh);
1067  if (maptileRefresh != 0)
1068  {
1069  m_mapGenerationTimer.Interval = maptileRefresh * 1000;
1070  m_mapGenerationTimer.Elapsed += RegenerateMaptileAndReregister;
1071  m_mapGenerationTimer.AutoReset = true;
1072  m_mapGenerationTimer.Start();
1073  }
1074  }
1075  else
1076  {
1077  string tile
1078  = Util.GetConfigVarFromSections<string>(
1079  config, "MaptileStaticUUID", possibleMapConfigSections, UUID.Zero.ToString());
1080 
1081  UUID tileID;
1082 
1083  if (tile != UUID.Zero.ToString() && UUID.TryParse(tile, out tileID))
1084  {
1085  RegionInfo.RegionSettings.TerrainImageID = tileID;
1086  }
1087  else
1088  {
1089  RegionInfo.RegionSettings.TerrainImageID = RegionInfo.MaptileStaticUUID;
1090  m_log.InfoFormat("[SCENE]: Region {0}, maptile set to {1}", RegionInfo.RegionName, RegionInfo.MaptileStaticUUID.ToString());
1091  }
1092  }
1093 
1094  string[] possibleAccessControlConfigSections = new string[] { "Startup", "AccessControl"};
1095 
1096  string grant
1097  = Util.GetConfigVarFromSections<string>(
1098  config, "AllowedClients", possibleAccessControlConfigSections, string.Empty);
1099 
1100  if (grant.Length > 0)
1101  {
1102  foreach (string viewer in grant.Split(','))
1103  {
1104  m_AllowedViewers.Add(viewer.Trim().ToLower());
1105  }
1106  }
1107 
1108  grant
1109  = Util.GetConfigVarFromSections<string>(
1110  config, "DeniedClients", possibleAccessControlConfigSections, String.Empty);
1111  // Deal with the mess of someone having used a different word at some point
1112  if (grant == String.Empty)
1113  grant = Util.GetConfigVarFromSections<string>(
1114  config, "BannedClients", possibleAccessControlConfigSections, String.Empty);
1115 
1116  if (grant.Length > 0)
1117  {
1118  foreach (string viewer in grant.Split(','))
1119  {
1120  m_BannedViewers.Add(viewer.Trim().ToLower());
1121  }
1122  }
1123 
1124  FrameTime = startupConfig.GetFloat( "FrameTime", FrameTime);
1125  FrameTimeWarnPercent = startupConfig.GetInt( "FrameTimeWarnPercent", FrameTimeWarnPercent);
1126  FrameTimeCritPercent = startupConfig.GetInt( "FrameTimeCritPercent", FrameTimeCritPercent);
1127  Normalized55FPS = startupConfig.GetBoolean( "Normalized55FPS", Normalized55FPS);
1128 
1129  m_update_backup = startupConfig.GetInt("UpdateStorageEveryNFrames", m_update_backup);
1130  m_update_coarse_locations = startupConfig.GetInt("UpdateCoarseLocationsEveryNFrames", m_update_coarse_locations);
1131  m_update_entitymovement = startupConfig.GetInt("UpdateEntityMovementEveryNFrames", m_update_entitymovement);
1132  m_update_events = startupConfig.GetInt("UpdateEventsEveryNFrames", m_update_events);
1133  m_update_objects = startupConfig.GetInt("UpdateObjectsEveryNFrames", m_update_objects);
1134  m_update_physics = startupConfig.GetInt("UpdatePhysicsEveryNFrames", m_update_physics);
1135  m_update_presences = startupConfig.GetInt("UpdateAgentsEveryNFrames", m_update_presences);
1136  m_update_terrain = startupConfig.GetInt("UpdateTerrainEveryNFrames", m_update_terrain);
1137  m_update_temp_cleaning = startupConfig.GetInt("UpdateTempCleaningEveryNSeconds", m_update_temp_cleaning);
1138 
1139  }
1140 
1141 
1142  // FIXME: Ultimately this should be in a module.
1143  SendPeriodicAppearanceUpdates = false;
1144 
1145  IConfig appearanceConfig = m_config.Configs["Appearance"];
1146  if (appearanceConfig != null)
1147  {
1148  SendPeriodicAppearanceUpdates
1149  = appearanceConfig.GetBoolean("ResendAppearanceUpdates", SendPeriodicAppearanceUpdates);
1150  }
1151 
1152  #endregion Region Config
1153 
1154  IConfig entityTransferConfig = m_config.Configs["EntityTransfer"];
1155  if (entityTransferConfig != null)
1156  {
1157  AllowAvatarCrossing = entityTransferConfig.GetBoolean("AllowAvatarCrossing", AllowAvatarCrossing);
1158  }
1159 
1160  #region Interest Management
1161 
1162  IConfig interestConfig = m_config.Configs["InterestManagement"];
1163  if (interestConfig != null)
1164  {
1165  string update_prioritization_scheme = interestConfig.GetString("UpdatePrioritizationScheme", "Time").Trim().ToLower();
1166 
1167  try
1168  {
1169  UpdatePrioritizationScheme = (UpdatePrioritizationSchemes)Enum.Parse(typeof(UpdatePrioritizationSchemes), update_prioritization_scheme, true);
1170  }
1171  catch (Exception)
1172  {
1173  m_log.Warn("[PRIORITIZER]: UpdatePrioritizationScheme was not recognized, setting to default prioritizer Time");
1174  UpdatePrioritizationScheme = UpdatePrioritizationSchemes.Time;
1175  }
1176 
1177  IsReprioritizationEnabled
1178  = interestConfig.GetBoolean("ReprioritizationEnabled", IsReprioritizationEnabled);
1179  ReprioritizationInterval
1180  = interestConfig.GetFloat("ReprioritizationInterval", ReprioritizationInterval);
1181  RootReprioritizationDistance
1182  = interestConfig.GetFloat("RootReprioritizationDistance", RootReprioritizationDistance);
1183  ChildReprioritizationDistance
1184  = interestConfig.GetFloat("ChildReprioritizationDistance", ChildReprioritizationDistance);
1185 
1186  if(RootReprioritizationDistance < m_minReprioritizationDistance)
1187  RootReprioritizationDistance = m_minReprioritizationDistance;
1188  if(ChildReprioritizationDistance < m_minReprioritizationDistance)
1189  ChildReprioritizationDistance = m_minReprioritizationDistance;
1190 
1191  RootTerseUpdatePeriod = interestConfig.GetInt("RootTerseUpdatePeriod", RootTerseUpdatePeriod);
1192  ChildTerseUpdatePeriod = interestConfig.GetInt("ChildTerseUpdatePeriod", ChildTerseUpdatePeriod);
1193 
1194  RootPositionUpdateTolerance
1195  = interestConfig.GetFloat("RootPositionUpdateTolerance", RootPositionUpdateTolerance);
1196  RootRotationUpdateTolerance
1197  = interestConfig.GetFloat("RootRotationUpdateTolerance", RootRotationUpdateTolerance);
1198  RootVelocityUpdateTolerance
1199  = interestConfig.GetFloat("RootVelocityUpdateTolerance", RootVelocityUpdateTolerance);
1200  }
1201 
1202  m_log.DebugFormat("[SCENE]: Using the {0} prioritization scheme", UpdatePrioritizationScheme);
1203 
1204  #endregion Interest Management
1205 
1206 
1207  StatsReporter = new SimStatsReporter(this);
1208 
1209  StatsReporter.OnSendStatsResult += SendSimStatsPackets;
1210  StatsReporter.OnStatsIncorrect += m_sceneGraph.RecalculateStats;
1211 
1212  }
1213 
1214  public Scene(RegionInfo regInfo)
1215  : base(regInfo)
1216  {
1217  m_sceneGraph = new SceneGraph(this);
1218 
1219  // If the scene graph has an Unrecoverable error, restart this sim.
1220  // Currently the only thing that causes it to happen is two kinds of specific
1221  // Physics based crashes.
1222  //
1223  // Out of memory
1224  // Operating system has killed the plugin
1225  m_sceneGraph.UnRecoverableError
1226  += () =>
1227  {
1228  m_log.ErrorFormat("[SCENE]: Restarting region {0} due to unrecoverable physics crash", Name);
1229  RestartNow();
1230  };
1231 
1232  PhysicalPrims = true;
1233  CollidablePrims = true;
1234  PhysicsEnabled = true;
1235 
1236  AllowAvatarCrossing = true;
1237 
1238  PeriodicBackup = true;
1239  UseBackup = true;
1240 
1241  IsReprioritizationEnabled = true;
1242  UpdatePrioritizationScheme = UpdatePrioritizationSchemes.Time;
1243  ReprioritizationInterval = 5000;
1244 
1245  RootRotationUpdateTolerance = 0.1f;
1246  RootVelocityUpdateTolerance = 0.001f;
1247  RootPositionUpdateTolerance = 0.05f;
1248  RootReprioritizationDistance = m_minReprioritizationDistance;
1249  ChildReprioritizationDistance = m_minReprioritizationDistance;
1250 
1251  m_eventManager = new EventManager();
1252 
1253  m_permissions = new ScenePermissions(this);
1254 
1255  }
1256 
1257  #endregion
1258 
1259  #region Startup / Close Methods
1260 
1265  public SceneGraph SceneGraph
1266  {
1267  get { return m_sceneGraph; }
1268  }
1269 
1275  public void AllModulesLoaded()
1276  {
1277  IDialogModule dm = RequestModuleInterface<IDialogModule>();
1278 
1279  if (dm != null)
1280  m_eventManager.OnPermissionError += dm.SendAlertToUser;
1281 
1282  ISimulatorFeaturesModule fm = RequestModuleInterface<ISimulatorFeaturesModule>();
1283  if (fm != null)
1284  {
1285  OSD openSimExtras;
1286  OSDMap openSimExtrasMap;
1287 
1288  if (!fm.TryGetFeature("OpenSimExtras", out openSimExtras))
1289  openSimExtras = new OSDMap();
1290 
1291  float statisticsFPSfactor = 1.0f;
1292  if(Normalized55FPS)
1293  statisticsFPSfactor = 55.0f * FrameTime;
1294 
1295  openSimExtrasMap = (OSDMap)openSimExtras;
1296  openSimExtrasMap["SimulatorFPS"] = OSD.FromReal(1.0f / FrameTime);
1297  openSimExtrasMap["SimulatorFPSFactor"] = OSD.FromReal(statisticsFPSfactor);
1298  openSimExtrasMap["SimulatorFPSWarnPercent"] = OSD.FromInteger(FrameTimeWarnPercent);
1299  openSimExtrasMap["SimulatorFPSCritPercent"] = OSD.FromInteger(FrameTimeCritPercent);
1300 
1301  fm.AddFeature("OpenSimExtras", openSimExtrasMap);
1302  }
1303  }
1304 
1305  protected virtual void RegisterDefaultSceneEvents()
1306  {
1307 // m_eventManager.OnSignificantClientMovement += HandleOnSignificantClientMovement;
1308  }
1309 
1310  public override string GetSimulatorVersion()
1311  {
1312  return m_simulatorVersion;
1313  }
1314 
1326  public override void OtherRegionUp(GridRegion otherRegion)
1327  {
1328  if (RegionInfo.RegionHandle != otherRegion.RegionHandle)
1329  {
1330 
1331  if (isNeighborRegion(otherRegion))
1332  {
1333  // Let the grid service module know, so this can be cached
1334  m_eventManager.TriggerOnRegionUp(otherRegion);
1335 
1336  try
1337  {
1338  ForEachRootScenePresence(delegate(ScenePresence agent)
1339  {
1340  //agent.ControllingClient.new
1341  //this.CommsManager.InterRegion.InformRegionOfChildAgent(otherRegion.RegionHandle, agent.ControllingClient.RequestClientInfo());
1342 
1343  List<ulong> old = new List<ulong>();
1344  old.Add(otherRegion.RegionHandle);
1345  agent.DropOldNeighbours(old);
1346  if (EntityTransferModule != null && agent.PresenceType != PresenceType.Npc)
1347  EntityTransferModule.EnableChildAgent(agent, otherRegion);
1348  });
1349  }
1350  catch (NullReferenceException)
1351  {
1352  // This means that we're not booted up completely yet.
1353  // This shouldn't happen too often anymore.
1354  m_log.Error("[SCENE]: Couldn't inform client of regionup because we got a null reference exception");
1355  }
1356  }
1357  else
1358  {
1359  m_log.InfoFormat(
1360  "[SCENE]: Got notice about far away Region: {0} at ({1}, {2})",
1361  otherRegion.RegionName, otherRegion.RegionLocX, otherRegion.RegionLocY);
1362  }
1363  }
1364  }
1365 
1366  public bool isNeighborRegion(GridRegion otherRegion)
1367  {
1368  int tmp = otherRegion.RegionLocX - (int)RegionInfo.WorldLocX; ;
1369 
1370  if (tmp < -otherRegion.RegionSizeX && tmp > RegionInfo.RegionSizeX)
1371  return false;
1372 
1373  tmp = otherRegion.RegionLocY - (int)RegionInfo.WorldLocY;
1374 
1375  if (tmp < -otherRegion.RegionSizeY && tmp > RegionInfo.RegionSizeY)
1376  return false;
1377 
1378  return true;
1379  }
1380 
1381  public void AddNeighborRegion(RegionInfo region)
1382  {
1383  lock (m_neighbours)
1384  {
1385  if (!CheckNeighborRegion(region))
1386  {
1387  m_neighbours.Add(region);
1388  }
1389  }
1390  }
1391 
1392  public bool CheckNeighborRegion(RegionInfo region)
1393  {
1394  bool found = false;
1395  lock (m_neighbours)
1396  {
1397  foreach (RegionInfo reg in m_neighbours)
1398  {
1399  if (reg.RegionHandle == region.RegionHandle)
1400  {
1401  found = true;
1402  break;
1403  }
1404  }
1405  }
1406  return found;
1407  }
1408 
1409  // Alias IncomingHelloNeighbour OtherRegionUp, for now
1411  {
1412  OtherRegionUp(new GridRegion(neighbour));
1413  return new GridRegion(RegionInfo);
1414  }
1415 
1416  // This causes the region to restart immediatley.
1417  public void RestartNow()
1418  {
1419  IConfig startupConfig = m_config.Configs["Startup"];
1420  if (startupConfig != null)
1421  {
1422  if (startupConfig.GetBoolean("InworldRestartShutsDown", false))
1423  {
1424  MainConsole.Instance.RunCommand("shutdown");
1425  return;
1426  }
1427  }
1428 
1429  m_log.InfoFormat("[REGION]: Restarting region {0}", Name);
1430 
1431  Close();
1432 
1433  base.Restart();
1434  }
1435 
1436  // This is a helper function that notifies root agents in this region that a new sim near them has come up
1437  // This is in the form of a timer because when an instance of OpenSim.exe is started,
1438  // Even though the sims initialize, they don't listen until 'all of the sims are initialized'
1439  // If we tell an agent about a sim that's not listening yet, the agent will not be able to connect to it.
1440  // subsequently the agent will never see the region come back online.
1441  public void RestartNotifyWaitElapsed(object sender, ElapsedEventArgs e)
1442  {
1443  m_restartWaitTimer.Stop();
1444  lock (m_regionRestartNotifyList)
1445  {
1446  foreach (RegionInfo region in m_regionRestartNotifyList)
1447  {
1448  GridRegion r = new GridRegion(region);
1449  try
1450  {
1451  ForEachRootScenePresence(delegate(ScenePresence agent)
1452  {
1453  if (EntityTransferModule != null && agent.PresenceType != PresenceType.Npc)
1454  EntityTransferModule.EnableChildAgent(agent, r);
1455  });
1456  }
1457  catch (NullReferenceException)
1458  {
1459  // This means that we're not booted up completely yet.
1460  // This shouldn't happen too often anymore.
1461  }
1462  }
1463 
1464  // Reset list to nothing.
1465  m_regionRestartNotifyList.Clear();
1466  }
1467  }
1468 
1470  {
1471  return m_neighbours.Count;
1472  }
1473 
1474  // This is the method that shuts down the scene.
1475  public override void Close()
1476  {
1477  if (m_shuttingDown)
1478  {
1479  m_log.WarnFormat("[SCENE]: Ignoring close request because already closing {0}", Name);
1480  return;
1481  }
1482 
1483  m_log.InfoFormat("[SCENE]: Closing down the single simulator: {0}", RegionInfo.RegionName);
1484 
1485 
1486  StatsReporter.Close();
1487  m_restartTimer.Stop();
1488  m_restartTimer.Close();
1489 
1490  if (!GridService.DeregisterRegion(RegionInfo.RegionID))
1491  m_log.WarnFormat("[SCENE]: Deregister from grid failed for region {0}", Name);
1492 
1493  // Kick all ROOT agents with the message, 'The simulator is going down'
1494  ForEachScenePresence(delegate(ScenePresence avatar)
1495  {
1496  avatar.RemoveNeighbourRegion(RegionInfo.RegionHandle);
1497 
1498  if (!avatar.IsChildAgent)
1499  avatar.ControllingClient.Kick("The simulator is going down.");
1500 
1501  avatar.ControllingClient.SendShutdownConnectionNotice();
1502  });
1503 
1504  // Stop updating the scene objects and agents.
1505  m_shuttingDown = true;
1506 
1507  // Wait here, or the kick messages won't actually get to the agents before the scene terminates.
1508  // We also need to wait to avoid a race condition with the scene update loop which might not yet
1509  // have checked ShuttingDown.
1510  Thread.Sleep(500);
1511 
1512  // Stop all client threads.
1513  ForEachScenePresence(delegate(ScenePresence avatar) { CloseAgent(avatar.UUID, false); });
1514 
1515  m_log.Debug("[SCENE]: TriggerSceneShuttingDown");
1516  EventManager.TriggerSceneShuttingDown(this);
1517 
1518  m_log.Debug("[SCENE]: Persisting changed objects");
1519  Backup(true);
1520 
1521  m_sceneGraph.Close();
1522 
1523  base.Close();
1524 
1525  // XEngine currently listens to the EventManager.OnShutdown event to trigger script stop and persistence.
1526  // Therefore. we must dispose of the PhysicsScene after this to prevent a window where script code can
1527  // attempt to reference a null or disposed physics scene.
1528  if (PhysicsScene != null)
1529  {
1530  m_log.Debug("[SCENE]: Dispose Physics");
1531  PhysicsScene phys = PhysicsScene;
1532  // remove the physics engine from both Scene and SceneGraph
1533  PhysicsScene = null;
1534  phys.Dispose();
1535  phys = null;
1536  }
1537  }
1538 
1539  public override void Start()
1540  {
1541  Start(true);
1542  }
1543 
1550  public void Start(bool startScripts)
1551  {
1552  if (IsRunning)
1553  return;
1554 
1555  m_isRunning = true;
1556  m_active = true;
1557 
1558  m_unixStartTime = Util.UnixTimeSinceEpoch();
1559 // m_log.DebugFormat("[SCENE]: Starting Heartbeat timer for {0}", RegionInfo.RegionName);
1560  if (m_heartbeatThread != null)
1561  {
1562  m_hbRestarts++;
1563  if(m_hbRestarts > 10)
1564  Environment.Exit(1);
1565  m_log.ErrorFormat("[SCENE]: Restarting heartbeat thread because it hasn't reported in in region {0}", RegionInfo.RegionName);
1566 
1567 //int pid = System.Diagnostics.Process.GetCurrentProcess().Id;
1568 //System.Diagnostics.Process proc = new System.Diagnostics.Process();
1569 //proc.EnableRaisingEvents=false;
1570 //proc.StartInfo.FileName = "/bin/kill";
1571 //proc.StartInfo.Arguments = "-QUIT " + pid.ToString();
1572 //proc.Start();
1573 //proc.WaitForExit();
1574 //Thread.Sleep(1000);
1575 //Environment.Exit(1);
1576  m_heartbeatThread.Abort();
1577  Watchdog.AbortThread(m_heartbeatThread.ManagedThreadId);
1578  m_heartbeatThread = null;
1579  }
1580 
1581  GC.Collect();
1582  // tell physics to finish building actor
1583  m_sceneGraph.ProcessPhysicsPreSimulation();
1584 
1585  m_heartbeatThread
1586  = WorkManager.StartThread(
1587  Heartbeat, string.Format("Heartbeat-({0})", RegionInfo.RegionName.Replace(" ", "_")), ThreadPriority.Normal, false, false);
1588 
1589  StartScripts();
1590  }
1591 
1595  public void SetModuleInterfaces()
1596  {
1597  m_xmlrpcModule = RequestModuleInterface<IXMLRPC>();
1598  m_worldCommModule = RequestModuleInterface<IWorldComm>();
1599  XferManager = RequestModuleInterface<IXfer>();
1600  m_AvatarFactory = RequestModuleInterface<IAvatarFactoryModule>();
1601  AttachmentsModule = RequestModuleInterface<IAttachmentsModule>();
1602  m_serialiser = RequestModuleInterface<IRegionSerialiserModule>();
1603  m_dialogModule = RequestModuleInterface<IDialogModule>();
1604  m_capsModule = RequestModuleInterface<ICapabilitiesModule>();
1605  EntityTransferModule = RequestModuleInterface<IEntityTransferModule>();
1606  m_groupsModule = RequestModuleInterface<IGroupsModule>();
1607  AgentTransactionsModule = RequestModuleInterface<IAgentAssetTransactions>();
1608  UserManagementModule = RequestModuleInterface<IUserManagement>();
1609  }
1610 
1611  #endregion
1612 
1613  #region Update Methods
1614 
1618  private void Heartbeat()
1619  {
1620  m_eventManager.TriggerOnRegionStarted(this);
1621 
1622  // The first frame can take a very long time due to physics actors being added on startup. Therefore,
1623  // don't turn on the watchdog alarm for this thread until the second frame, in order to prevent false
1624  // alarms for scenes with many objects.
1625  Update(1);
1626 
1627  WorkManager.StartThread(
1628  Maintenance, string.Format("Maintenance ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false, true);
1629 
1630  Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true;
1631  m_lastFrameTick = Util.EnvironmentTickCount();
1632  Update(-1);
1633 
1634  Watchdog.RemoveThread();
1635  }
1636 
1637  private void Maintenance()
1638  {
1639  DoMaintenance(-1);
1640 
1641  Watchdog.RemoveThread();
1642  }
1643 
1644  public void DoMaintenance(int runs)
1645  {
1646  long? endRun = null;
1647  int runtc, tmpMS;
1648  int previousMaintenanceTick;
1649 
1650  if (runs >= 0)
1651  endRun = MaintenanceRun + runs;
1652 
1653  List<Vector3> coarseLocations;
1654  List<UUID> avatarUUIDs;
1655 
1656  while (!m_shuttingDown && ((endRun == null && Active) || MaintenanceRun < endRun))
1657  {
1658  runtc = Util.EnvironmentTickCount();
1659  ++MaintenanceRun;
1660 
1661  // m_log.DebugFormat("[SCENE]: Maintenance run {0} in {1}", MaintenanceRun, Name);
1662 
1663  // Coarse locations relate to positions of green dots on the mini-map (on a SecondLife client)
1664  if (MaintenanceRun % (m_update_coarse_locations / 10) == 0)
1665  {
1666  SceneGraph.GetCoarseLocations(out coarseLocations, out avatarUUIDs, 60);
1667  // Send coarse locations to clients
1668  ForEachScenePresence(delegate(ScenePresence presence)
1669  {
1670  presence.SendCoarseLocations(coarseLocations, avatarUUIDs);
1671  });
1672  }
1673 
1674  if (SendPeriodicAppearanceUpdates && MaintenanceRun % 60 == 0)
1675  {
1676  // m_log.DebugFormat("[SCENE]: Sending periodic appearance updates");
1677 
1678  if (AvatarFactory != null)
1679  {
1680  ForEachRootScenePresence(sp => AvatarFactory.SendAppearance(sp.UUID));
1681  }
1682  }
1683 
1684  // Delete temp-on-rez stuff
1685  if (MaintenanceRun % m_update_temp_cleaning == 0 && !m_cleaningTemps)
1686  {
1687  // m_log.DebugFormat("[SCENE]: Running temp-on-rez cleaning in {0}", Name);
1688  tmpMS = Util.EnvironmentTickCount();
1689  m_cleaningTemps = true;
1690 
1691  WorkManager.RunInThread(
1692  delegate { CleanTempObjects(); m_cleaningTemps = false; },
1693  null,
1694  string.Format("CleanTempObjects ({0})", Name));
1695 
1696  tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpMS);
1697  }
1698 
1699  Watchdog.UpdateThread();
1700 
1701  previousMaintenanceTick = m_lastMaintenanceTick;
1702  m_lastMaintenanceTick = Util.EnvironmentTickCount();
1703  runtc = Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, runtc);
1704  runtc = (int)(MinMaintenanceTime * 1000) - runtc;
1705 
1706  if (runtc > 0)
1707  m_maintenanceWaitEvent.WaitOne(runtc);
1708 
1709  // Optionally warn if a frame takes double the amount of time that it should.
1710  if (DebugUpdates
1711  && Util.EnvironmentTickCountSubtract(
1712  m_lastMaintenanceTick, previousMaintenanceTick) > (int)(MinMaintenanceTime * 1000 * 2))
1713  m_log.WarnFormat(
1714  "[SCENE]: Maintenance took {0} ms (desired max {1} ms) in {2}",
1715  Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, previousMaintenanceTick),
1716  MinMaintenanceTime * 1000,
1717  RegionInfo.RegionName);
1718  }
1719  }
1720 
1721  public override void Update(int frames)
1722  {
1723  long? endFrame = null;
1724 
1725  if (frames >= 0)
1726  endFrame = Frame + frames;
1727 
1728  float physicsFPS = 0f;
1729  float frameTimeMS = FrameTime * 1000.0f;
1730 
1731  int previousFrameTick;
1732 
1733  double tmpMS;
1734  double tmpMS2;
1735  double framestart;
1736  float sleepMS;
1737  float sleepError = 0;
1738 
1739  while (!m_shuttingDown && ((endFrame == null && Active) || Frame < endFrame))
1740  {
1741  framestart = Util.GetTimeStampMS();
1742  ++Frame;
1743 
1744  // m_log.DebugFormat("[SCENE]: Processing frame {0} in {1}", Frame, RegionInfo.RegionName);
1745 
1746  agentMS = tempOnRezMS = eventMS = backupMS = terrainMS = landMS = 0f;
1747 
1748  try
1749  {
1750  EventManager.TriggerRegionHeartbeatStart(this);
1751 
1752  // Apply taints in terrain module to terrain in physics scene
1753 
1754  tmpMS = Util.GetTimeStampMS();
1755 
1756  if (Frame % 4 == 0)
1757  {
1758  CheckTerrainUpdates();
1759  }
1760 
1761  if (Frame % m_update_terrain == 0)
1762  {
1763  UpdateTerrain();
1764  }
1765 
1766  tmpMS2 = Util.GetTimeStampMS();
1767  terrainMS = (float)(tmpMS2 - tmpMS);
1768  tmpMS = tmpMS2;
1769 
1770  if (PhysicsEnabled && Frame % m_update_physics == 0)
1771  m_sceneGraph.UpdatePreparePhysics();
1772 
1773  tmpMS2 = Util.GetTimeStampMS();
1774  physicsMS2 = (float)(tmpMS2 - tmpMS);
1775  tmpMS = tmpMS2;
1776 
1777  // Apply any pending avatar force input to the avatar's velocity
1778  if (Frame % m_update_entitymovement == 0)
1779  m_sceneGraph.UpdateScenePresenceMovement();
1780 
1781  // Get the simulation frame time that the avatar force input
1782  // took
1783  tmpMS2 = Util.GetTimeStampMS();
1784  agentMS = (float)(tmpMS2 - tmpMS);
1785  tmpMS = tmpMS2;
1786 
1787  // Perform the main physics update. This will do the actual work of moving objects and avatars according to their
1788  // velocity
1789  if (Frame % m_update_physics == 0)
1790  {
1791  if (PhysicsEnabled)
1792  physicsFPS = m_sceneGraph.UpdatePhysics(FrameTime);
1793 
1794  if (SynchronizeScene != null)
1795  SynchronizeScene(this);
1796  }
1797 
1798  tmpMS2 = Util.GetTimeStampMS();
1799  physicsMS = (float)(tmpMS2 - tmpMS);
1800  tmpMS = tmpMS2;
1801 
1802  // Check if any objects have reached their targets
1803  CheckAtTargets();
1804 
1805  // Update SceneObjectGroups that have scheduled themselves for updates
1806  // Objects queue their updates onto all scene presences
1807  if (Frame % m_update_objects == 0)
1808  m_sceneGraph.UpdateObjectGroups();
1809 
1810  // Run through all ScenePresences looking for updates
1811  // Presence updates and queued object updates for each presence are sent to clients
1812  if (Frame % m_update_presences == 0)
1813  m_sceneGraph.UpdatePresences();
1814 
1815  tmpMS2 = Util.GetTimeStampMS();
1816  agentMS += (float)(tmpMS2 - tmpMS);
1817  tmpMS = tmpMS2;
1818 
1819  // Delete temp-on-rez stuff
1820  if (Frame % m_update_temp_cleaning == 0 && !m_cleaningTemps)
1821  {
1822  m_cleaningTemps = true;
1823  Util.FireAndForget(delegate { CleanTempObjects(); m_cleaningTemps = false; });
1824  tmpMS2 = Util.GetTimeStampMS();
1825  tempOnRezMS = (float)(tmpMS2 - tmpMS); // bad.. counts the FireAndForget, not CleanTempObjects
1826  tmpMS = tmpMS2;
1827  }
1828 
1829  if (Frame % m_update_events == 0)
1830  {
1831  UpdateEvents();
1832 
1833  tmpMS2 = Util.GetTimeStampMS();
1834  eventMS = (float)(tmpMS2 - tmpMS);
1835  tmpMS = tmpMS2;
1836  }
1837 
1838  if (PeriodicBackup && Frame % m_update_backup == 0)
1839  {
1840  UpdateStorageBackup();
1841 
1842  tmpMS2 = Util.GetTimeStampMS();
1843  backupMS = (float)(tmpMS2 - tmpMS);
1844  tmpMS = tmpMS2;
1845  }
1846 
1847  //if (Frame % m_update_land == 0)
1848  //{
1849  // int ldMS = Util.EnvironmentTickCount();
1850  // UpdateLand();
1851  // landMS = Util.EnvironmentTickCountSubtract(ldMS);
1852  //}
1853 
1854  if (!LoginsEnabled && Frame == 20)
1855  {
1856  // m_log.DebugFormat("{0} {1} {2}", LoginsDisabled, m_sceneGraph.GetActiveScriptsCount(), LoginLock);
1857 
1858  // In 99.9% of cases it is a bad idea to manually force garbage collection. However,
1859  // this is a rare case where we know we have just went through a long cycle of heap
1860  // allocations, and there is no more work to be done until someone logs in
1861  GC.Collect();
1862 
1863  if (!LoginLock)
1864  {
1865  if (!StartDisabled)
1866  {
1867  m_log.InfoFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName);
1868  LoginsEnabled = true;
1869  }
1870 
1871  m_sceneGridService.InformNeighborsThatRegionisUp(
1872  RequestModuleInterface<INeighbourService>(), RegionInfo);
1873 
1874  // Region ready should always be set
1875  Ready = true;
1876  }
1877  else
1878  {
1879  // This handles a case of a region having no scripts for the RegionReady module
1880  if (m_sceneGraph.GetActiveScriptsCount() == 0)
1881  {
1882  // In this case, we leave it to the IRegionReadyModule to enable logins
1883 
1884  // LoginLock can currently only be set by a region module implementation.
1885  // If somehow this hasn't been done then the quickest way to bugfix is to see the
1886  // NullReferenceException
1887  IRegionReadyModule rrm = RequestModuleInterface<IRegionReadyModule>();
1888  rrm.TriggerRegionReady(this);
1889  }
1890  }
1891  }
1892  }
1893  catch (Exception e)
1894  {
1895  m_log.ErrorFormat(
1896  "[SCENE]: Failed on region {0} with exception {1}{2}",
1897  RegionInfo.RegionName, e.Message, e.StackTrace);
1898  }
1899 
1900  EventManager.TriggerRegionHeartbeatEnd(this);
1901  m_firstHeartbeat = false;
1902  Watchdog.UpdateThread();
1903 
1904  otherMS = tempOnRezMS + eventMS + backupMS + terrainMS + landMS;
1905 
1906  tmpMS = Util.GetTimeStampMS();
1907 
1908  previousFrameTick = m_lastFrameTick;
1909  m_lastFrameTick = (int)(tmpMS + 0.5);
1910 
1911  // estimate sleep time
1912  tmpMS2 = tmpMS - framestart;
1913  tmpMS2 = (double)frameTimeMS - tmpMS2 - sleepError;
1914 
1915  // reuse frameMS as temporary
1916  frameMS = (float)tmpMS2;
1917 
1918  // sleep if we can
1919  if (tmpMS2 > 0)
1920  {
1921  Thread.Sleep((int)(tmpMS2 + 0.5));
1922 
1923  tmpMS2 = Util.GetTimeStampMS();
1924  sleepMS = (float)(tmpMS2 - tmpMS);
1925  sleepError = sleepMS - frameMS;
1926  Util.Clamp(sleepError, 0.0f, 20f);
1927  frameMS = (float)(tmpMS2 - framestart);
1928  }
1929  else
1930  {
1931  tmpMS2 = Util.GetTimeStampMS();
1932  frameMS = (float)(tmpMS2 - framestart);
1933  sleepMS = 0.0f;
1934  sleepError = 0.0f;
1935  }
1936 
1937  // script time is not scene frame time, but is displayed per frame
1938  float scriptTimeMS = GetAndResetScriptExecutionTime();
1939  StatsReporter.AddFrameStats(TimeDilation, physicsFPS, agentMS,
1940  physicsMS + physicsMS2, otherMS , sleepMS, frameMS, scriptTimeMS);
1941 
1942 
1943 
1944  // if (Frame%m_update_avatars == 0)
1945  // UpdateInWorldTime();
1946 
1947  // Optionally warn if a frame takes double the amount of time that it should.
1948  if (DebugUpdates
1949  && Util.EnvironmentTickCountSubtract(
1950  m_lastFrameTick, previousFrameTick) > (int)(FrameTime * 1000 * 2))
1951 
1952  m_log.WarnFormat(
1953  "[SCENE]: Frame took {0} ms (desired max {1} ms) in {2}",
1954  Util.EnvironmentTickCountSubtract(m_lastFrameTick, previousFrameTick),
1955  FrameTime * 1000,
1956 
1957  RegionInfo.RegionName);
1958  }
1959  }
1960 
1965  public void AddScriptExecutionTime(long ticks)
1966  {
1967  StatsReporter.addScriptEvents(1);
1968  Interlocked.Add(ref m_scriptExecutionTime, ticks);
1969  }
1970 
1976 
1977  // Warning: this is now called from StatsReporter, and can't be shared
1978 
1980  {
1981  long ticks = Interlocked.Exchange(ref m_scriptExecutionTime, 0);
1982  return (ticks * 1000L) / Stopwatch.Frequency;
1983  }
1984 
1986  {
1987  lock (m_groupsWithTargets)
1988  m_groupsWithTargets[grp.UUID] = 0;
1989  }
1990 
1992  {
1993  lock (m_groupsWithTargets)
1994  m_groupsWithTargets.Remove(grp.UUID);
1995  }
1996 
1997  private void CheckAtTargets()
1998  {
1999  List<UUID> objs = null;
2000 
2001  lock (m_groupsWithTargets)
2002  {
2003  if (m_groupsWithTargets.Count != 0)
2004  objs = new List<UUID>(m_groupsWithTargets.Keys);
2005  }
2006 
2007  if (objs != null)
2008  {
2009  foreach (UUID entry in objs)
2010  {
2011  SceneObjectGroup grp = GetSceneObjectGroup(entry);
2012  if (grp == null)
2013  m_groupsWithTargets.Remove(entry);
2014  else
2015  grp.checkAtTargets();
2016  }
2017  }
2018  }
2019 
2024  private void SendSimStatsPackets(SimStats stats)
2025  {
2026  ForEachRootClient(delegate(IClientAPI client)
2027  {
2028  client.SendSimStats(stats);
2029  });
2030  }
2031 
2035  private void UpdateTerrain()
2036  {
2037  EventManager.TriggerTerrainTick();
2038  }
2039 
2040  private void CheckTerrainUpdates()
2041  {
2042  EventManager.TriggerTerrainCheckUpdates();
2043  }
2044 
2048  private void UpdateStorageBackup()
2049  {
2050  if (!m_backingup)
2051  {
2052  m_backingup = true;
2053  WorkManager.RunInThread(o => Backup(false), null, string.Format("BackupWaitCallback ({0})", Name));
2054  }
2055  }
2056 
2060  private void UpdateEvents()
2061  {
2062  m_eventManager.TriggerOnFrame();
2063  }
2064 
2077  public void Backup(bool forced)
2078  {
2079  lock (m_returns)
2080  {
2081  EventManager.TriggerOnBackup(SimulationDataService, forced);
2082  m_backingup = false;
2083 
2084  foreach (KeyValuePair<UUID, ReturnInfo> ret in m_returns)
2085  {
2086  UUID transaction = UUID.Random();
2087 
2089  msg.fromAgentID = new Guid(UUID.Zero.ToString()); // From server
2090  msg.toAgentID = new Guid(ret.Key.ToString());
2091  msg.imSessionID = new Guid(transaction.ToString());
2092  msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
2093  msg.fromAgentName = "Server";
2094  msg.dialog = (byte)19; // Object msg
2095  msg.fromGroup = false;
2096  msg.offline = (byte)1;
2097  msg.ParentEstateID = RegionInfo.EstateSettings.ParentEstateID;
2098  msg.Position = Vector3.Zero;
2099  msg.RegionID = RegionInfo.RegionID.Guid;
2100 
2101  // We must fill in a null-terminated 'empty' string here since bytes[0] will crash viewer 3.
2102  msg.binaryBucket = Util.StringToBytes256("\0");
2103  if (ret.Value.count > 1)
2104  msg.message = string.Format("Your {0} objects were returned from {1} in region {2} due to {3}", ret.Value.count, ret.Value.location.ToString(), RegionInfo.RegionName, ret.Value.reason);
2105  else
2106  msg.message = string.Format("Your object {0} was returned from {1} in region {2} due to {3}", ret.Value.objectName, ret.Value.location.ToString(), RegionInfo.RegionName, ret.Value.reason);
2107 
2108  IMessageTransferModule tr = RequestModuleInterface<IMessageTransferModule>();
2109  if (tr != null)
2110  tr.SendInstantMessage(msg, delegate(bool success) { });
2111  }
2112  m_returns.Clear();
2113  }
2114  }
2115 
2121  {
2122  if (group != null)
2123  {
2124  group.HasGroupChanged = true;
2125  group.ProcessBackup(SimulationDataService, true);
2126  }
2127  }
2128 
2139  public void AddReturn(UUID agentID, string objectName, Vector3 location, string reason)
2140  {
2141  lock (m_returns)
2142  {
2143  if (m_returns.ContainsKey(agentID))
2144  {
2145  ReturnInfo info = m_returns[agentID];
2146  info.count++;
2147  m_returns[agentID] = info;
2148  }
2149  else
2150  {
2151  ReturnInfo info = new ReturnInfo();
2152  info.count = 1;
2153  info.objectName = objectName;
2154  info.location = location;
2155  info.reason = reason;
2156  m_returns[agentID] = info;
2157  }
2158  }
2159  }
2160 
2161  #endregion
2162 
2163  #region Load Terrain
2164 
2168  public void SaveTerrain()
2169  {
2170  SimulationDataService.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID);
2171  }
2172 
2174  {
2175  RegionInfo.WindlightSettings = wl;
2176  SimulationDataService.StoreRegionWindlightSettings(wl);
2177  m_eventManager.TriggerOnSaveNewWindlightProfile();
2178  }
2179 
2180  public void LoadWindlightProfile()
2181  {
2182  RegionInfo.WindlightSettings = SimulationDataService.LoadRegionWindlightSettings(RegionInfo.RegionID);
2183  m_eventManager.TriggerOnSaveNewWindlightProfile();
2184  }
2185 
2189  public override void LoadWorldMap()
2190  {
2191  try
2192  {
2193  TerrainData map = SimulationDataService.LoadTerrain(RegionInfo.RegionID, (int)RegionInfo.RegionSizeX, (int)RegionInfo.RegionSizeY, (int)RegionInfo.RegionSizeZ);
2194  if (map == null)
2195  {
2196  // This should be in the Terrain module, but it isn't because
2197  // the heightmap is needed _way_ before the modules are initialized...
2198  IConfig terrainConfig = m_config.Configs["Terrain"];
2199  String m_InitialTerrain = "pinhead-island";
2200  if (terrainConfig != null)
2201  m_InitialTerrain = terrainConfig.GetString("InitialTerrain", m_InitialTerrain);
2202 
2203  m_log.InfoFormat("[TERRAIN]: No default terrain. Generating a new terrain {0}.", m_InitialTerrain);
2204  Heightmap = new TerrainChannel(m_InitialTerrain, (int)RegionInfo.RegionSizeX, (int)RegionInfo.RegionSizeY, (int)RegionInfo.RegionSizeZ);
2205 
2206  SimulationDataService.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID);
2207  }
2208  else
2209  {
2210  Heightmap = new TerrainChannel(map);
2211  }
2212  }
2213  catch (IOException e)
2214  {
2215  m_log.WarnFormat(
2216  "[TERRAIN]: Scene.cs: LoadWorldMap() - Regenerating as failed with exception {0}{1}",
2217  e.Message, e.StackTrace);
2218 
2219  // Non standard region size. If there's an old terrain in the database, it might read past the buffer
2220 #pragma warning disable 0162
2221  if ((int)Constants.RegionSize != 256)
2222  {
2223  Heightmap = new TerrainChannel();
2224 
2225  SimulationDataService.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID);
2226  }
2227  }
2228  catch (Exception e)
2229  {
2230  m_log.WarnFormat(
2231  "[TERRAIN]: Scene.cs: LoadWorldMap() - Failed with exception {0}{1}", e.Message, e.StackTrace);
2232  }
2233  }
2234 
2240  {
2241  m_sceneGridService.SetScene(this);
2242 
2247  if (m_generateMaptiles)
2248  RegenerateMaptile();
2249 
2250  GridRegion region = new GridRegion(RegionInfo);
2251  string error = GridService.RegisterRegion(RegionInfo.ScopeID, region);
2252  // m_log.DebugFormat("[SCENE]: RegisterRegionWithGrid. name={0},id={1},loc=<{2},{3}>,size=<{4},{5}>",
2253  // m_regionName,
2254  // RegionInfo.RegionID,
2255  // RegionInfo.RegionLocX, RegionInfo.RegionLocY,
2256  // RegionInfo.RegionSizeX, RegionInfo.RegionSizeY);
2257 
2258  if (error != String.Empty)
2259  throw new Exception(error);
2260  }
2261 
2262  #endregion
2263 
2264  #region Load Land
2265 
2270  public void loadAllLandObjectsFromStorage(UUID regionID)
2271  {
2272  m_log.Info("[SCENE]: Loading land objects from storage");
2273  List<LandData> landData = SimulationDataService.LoadLandObjects(regionID);
2274 
2275  if (LandChannel != null)
2276  {
2277  if (landData.Count == 0)
2278  {
2279  EventManager.TriggerNoticeNoLandDataFromStorage();
2280  }
2281  else
2282  {
2283  EventManager.TriggerIncomingLandDataFromStorage(landData);
2284  }
2285  }
2286  else
2287  {
2288  m_log.Error("[SCENE]: Land Channel is not defined. Cannot load from storage!");
2289  }
2290  }
2291 
2292  #endregion
2293 
2294  #region Primitives Methods
2295 
2300  public virtual void LoadPrimsFromStorage(UUID regionID)
2301  {
2302  LoadingPrims = true;
2303  m_log.Info("[SCENE]: Loading objects from datastore");
2304 
2305  List<SceneObjectGroup> PrimsFromDB = SimulationDataService.LoadObjects(regionID);
2306 
2307  m_log.InfoFormat("[SCENE]: Loaded {0} objects from the datastore", PrimsFromDB.Count);
2308 
2309  foreach (SceneObjectGroup group in PrimsFromDB)
2310  {
2311  AddRestoredSceneObject(group, true, true);
2312  EventManager.TriggerOnSceneObjectLoaded(group);
2313  SceneObjectPart rootPart = group.GetPart(group.UUID);
2314  rootPart.Flags &= ~PrimFlags.Scripted;
2315  rootPart.TrimPermissions();
2316 
2317  // Don't do this here - it will get done later on when sculpt data is loaded.
2318  // group.CheckSculptAndLoad();
2319  }
2320 
2321  LoadingPrims = false;
2322  EventManager.TriggerPrimsLoaded(this);
2323  }
2324 
2326  {
2327  if (PhysicsScene == null)
2328  return false;
2329  return PhysicsScene.SupportsRaycastWorldFiltered();
2330  }
2331 
2332  public object RayCastFiltered(Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags filter)
2333  {
2334  if (PhysicsScene == null)
2335  return null;
2336  return PhysicsScene.RaycastWorld(position, direction, length, Count, filter);
2337  }
2338 
2352  public Vector3 GetNewRezLocation(Vector3 RayStart, Vector3 RayEnd, UUID RayTargetID, Quaternion rot, byte bypassRayCast, byte RayEndIsIntersection, bool frontFacesOnly, Vector3 scale, bool FaceCenter)
2353  {
2354 
2355  Vector3 dir = RayEnd - RayStart;
2356 
2357  float wheight = (float)RegionInfo.RegionSettings.WaterHeight;
2358  Vector3 wpos = Vector3.Zero;
2359  // Check for water surface intersection from above
2360  if ((RayStart.Z > wheight) && (RayEnd.Z < wheight))
2361  {
2362  float ratio = (wheight - RayStart.Z) / dir.Z;
2363  wpos.X = RayStart.X + (ratio * dir.X);
2364  wpos.Y = RayStart.Y + (ratio * dir.Y);
2365  wpos.Z = wheight;
2366  }
2367 
2368  Vector3 pos = Vector3.Zero;
2369 
2370  if (RayEndIsIntersection != (byte)1)
2371  {
2372  float dist = dir.Length();
2373  if (dist != 0)
2374  {
2375  Vector3 direction = dir * (1 / dist);
2376 
2377  dist += 1.0f;
2378 
2379  if (SupportsRayCastFiltered())
2380  {
2381  RayFilterFlags rayfilter = RayFilterFlags.BackFaceCull;
2382  rayfilter |= RayFilterFlags.land;
2383  rayfilter |= RayFilterFlags.physical;
2384  rayfilter |= RayFilterFlags.nonphysical;
2385  rayfilter |= RayFilterFlags.LSLPhantom; // ubODE will only see volume detectors
2386 
2387  // get some more contacts ???
2388  int physcount = 4;
2389 
2390  List<ContactResult> physresults =
2391  (List<ContactResult>)RayCastFiltered(RayStart, direction, dist, physcount, rayfilter);
2392  if (physresults != null && physresults.Count > 0)
2393  {
2394  // look for terrain ?
2395  if(RayTargetID == UUID.Zero)
2396  {
2397  foreach (ContactResult r in physresults)
2398  {
2399  if (r.ConsumerID == 0)
2400  {
2401  pos = r.Normal * scale;
2402  pos *= 0.5f;
2403  pos = r.Pos + pos;
2404 
2405  if (wpos.Z > pos.Z) pos = wpos;
2406  return pos;
2407  }
2408  }
2409  }
2410  else
2411  {
2412  foreach (ContactResult r in physresults)
2413  {
2414  SceneObjectPart part = GetSceneObjectPart(r.ConsumerID);
2415  if (part == null)
2416  continue;
2417  if (part.UUID == RayTargetID)
2418  {
2419  pos = r.Normal * scale;
2420  pos *= 0.5f;
2421  pos = r.Pos + pos;
2422 
2423  if (wpos.Z > pos.Z) pos = wpos;
2424  return pos;
2425  }
2426  }
2427  }
2428  // else the first we got
2429  pos = physresults[0].Normal * scale;
2430  pos *= 0.5f;
2431  pos = physresults[0].Pos + pos;
2432 
2433  if (wpos.Z > pos.Z)
2434  pos = wpos;
2435  return pos;
2436  }
2437 
2438  }
2439  if (RayTargetID != UUID.Zero)
2440  {
2441  SceneObjectPart target = GetSceneObjectPart(RayTargetID);
2442 
2443  Ray NewRay = new Ray(RayStart, direction);
2444 
2445  if (target != null)
2446  {
2447  pos = target.AbsolutePosition;
2448 
2449  // Ray Trace against target here
2450  EntityIntersection ei = target.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, FaceCenter);
2451 
2452  // Un-comment out the following line to Get Raytrace results printed to the console.
2453  // m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString());
2454  float ScaleOffset = 0.5f;
2455 
2456  // If we hit something
2457  if (ei.HitTF)
2458  {
2459  Vector3 scaleComponent = ei.AAfaceNormal;
2460  if (scaleComponent.X != 0) ScaleOffset = scale.X;
2461  if (scaleComponent.Y != 0) ScaleOffset = scale.Y;
2462  if (scaleComponent.Z != 0) ScaleOffset = scale.Z;
2463  ScaleOffset = Math.Abs(ScaleOffset);
2464  Vector3 intersectionpoint = ei.ipoint;
2465  Vector3 normal = ei.normal;
2466  // Set the position to the intersection point
2467  Vector3 offset = (normal * (ScaleOffset / 2f));
2468  pos = (intersectionpoint + offset);
2469 
2470  //Seems to make no sense to do this as this call is used for rezzing from inventory as well, and with inventory items their size is not always 0.5f
2471  //And in cases when we weren't rezzing from inventory we were re-adding the 0.25 straight after calling this method
2472  // Un-offset the prim (it gets offset later by the consumer method)
2473  //pos.Z -= 0.25F;
2474 
2475  if (wpos.Z > pos.Z) pos = wpos;
2476  return pos;
2477  }
2478  }
2479  else
2480  {
2481  // We don't have a target here, so we're going to raytrace all the objects in the scene.
2482  EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(NewRay, true, false);
2483 
2484  // Un-comment the following line to print the raytrace results to the console.
2485  //m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString());
2486 
2487  if (ei.HitTF)
2488  {
2489  pos = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z);
2490  }
2491  else
2492  {
2493  // fall back to our stupid functionality
2494  pos = RayEnd;
2495  }
2496 
2497  if (wpos.Z > pos.Z) pos = wpos;
2498  return pos;
2499  }
2500  }
2501  }
2502  }
2503 
2504  // fall back to our stupid functionality
2505  pos = RayEnd;
2506 
2507  //increase height so its above the ground.
2508  //should be getting the normal of the ground at the rez point and using that?
2509  pos.Z += scale.Z / 2f;
2510  // return pos;
2511  // check against posible water intercept
2512  if (wpos.Z > pos.Z) pos = wpos;
2513  return pos;
2514  }
2515 
2516 
2529  public virtual void AddNewPrim(UUID ownerID, UUID groupID, Vector3 RayEnd, Quaternion rot, PrimitiveBaseShape shape,
2530  byte bypassRaycast, Vector3 RayStart, UUID RayTargetID,
2531  byte RayEndIsIntersection)
2532  {
2533  Vector3 pos = GetNewRezLocation(RayStart, RayEnd, RayTargetID, rot, bypassRaycast, RayEndIsIntersection, true, new Vector3(0.5f, 0.5f, 0.5f), false);
2534 
2535  if (Permissions.CanRezObject(1, ownerID, pos))
2536  {
2537  // rez ON the ground, not IN the ground
2538  // pos.Z += 0.25F; The rez point should now be correct so that its not in the ground
2539 
2540  AddNewPrim(ownerID, groupID, pos, rot, shape);
2541  }
2542  else
2543  {
2544  IClientAPI client = null;
2545  if (TryGetClient(ownerID, out client))
2546  client.SendAlertMessage("You cannot create objects here.");
2547  }
2548  }
2549 
2551  UUID ownerID, UUID groupID, Vector3 pos, Quaternion rot, PrimitiveBaseShape shape)
2552  {
2553  //m_log.DebugFormat(
2554  // "[SCENE]: Scene.AddNewPrim() pcode {0} called for {1} in {2}", shape.PCode, ownerID, RegionInfo.RegionName);
2555 
2556  SceneObjectGroup sceneObject = null;
2557 
2558  // If an entity creator has been registered for this prim type then use that
2559  if (m_entityCreators.ContainsKey((PCode)shape.PCode))
2560  {
2561  sceneObject = m_entityCreators[(PCode)shape.PCode].CreateEntity(ownerID, groupID, pos, rot, shape);
2562  }
2563  else
2564  {
2565  // Otherwise, use this default creation code;
2566  sceneObject = new SceneObjectGroup(ownerID, pos, rot, shape);
2567  AddNewSceneObject(sceneObject, true);
2568  sceneObject.SetGroup(groupID, null);
2569  }
2570 
2571  if (UserManagementModule != null)
2572  sceneObject.RootPart.CreatorIdentification = UserManagementModule.GetUserUUI(ownerID);
2573 
2574  sceneObject.ScheduleGroupForFullUpdate();
2575 
2576  return sceneObject;
2577  }
2578 
2600  SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates)
2601  {
2602  if (m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates))
2603  {
2604  sceneObject.IsDeleted = false;
2605  EventManager.TriggerObjectAddedToScene(sceneObject);
2606  return true;
2607  }
2608 
2609  return false;
2610  }
2611 
2629  SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted)
2630  {
2631  return AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, true);
2632  }
2633 
2643  public bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup)
2644  {
2645  return AddNewSceneObject(sceneObject, attachToBackup, true);
2646  }
2647 
2661  public bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates)
2662  {
2663  if (m_sceneGraph.AddNewSceneObject(sceneObject, attachToBackup, sendClientUpdates))
2664  {
2665  EventManager.TriggerObjectAddedToScene(sceneObject);
2666  return true;
2667  }
2668 
2669  return false;
2670  }
2671 
2684  public bool AddNewSceneObject(
2685  SceneObjectGroup sceneObject, bool attachToBackup, Vector3? pos, Quaternion? rot, Vector3 vel)
2686  {
2687  if (m_sceneGraph.AddNewSceneObject(sceneObject, attachToBackup, pos, rot, vel))
2688  {
2689  EventManager.TriggerObjectAddedToScene(sceneObject);
2690  return true;
2691  }
2692 
2693  return false;
2694  }
2695 
2700  {
2701  DeleteAllSceneObjects(false);
2702  }
2703 
2707  public void DeleteAllSceneObjects(bool exceptNoCopy)
2708  {
2709  List<SceneObjectGroup> toReturn = new List<SceneObjectGroup>();
2710  lock (Entities)
2711  {
2712  EntityBase[] entities = Entities.GetEntities();
2713  foreach (EntityBase e in entities)
2714  {
2715  if (e is SceneObjectGroup)
2716  {
2717  SceneObjectGroup sog = (SceneObjectGroup)e;
2718  if (sog != null && !sog.IsAttachment)
2719  {
2720  if (!exceptNoCopy || ((sog.GetEffectivePermissions() & (uint)PermissionMask.Copy) != 0))
2721  {
2722  DeleteSceneObject((SceneObjectGroup)e, false);
2723  }
2724  else
2725  {
2726  toReturn.Add((SceneObjectGroup)e);
2727  }
2728  }
2729  }
2730  }
2731  }
2732  if (toReturn.Count > 0)
2733  {
2734  returnObjects(toReturn.ToArray(), UUID.Zero);
2735  }
2736  }
2737 
2746  public void DeleteSceneObject(SceneObjectGroup group, bool silent)
2747  {
2748  DeleteSceneObject(group, silent, true);
2749  }
2750 
2757  public void DeleteSceneObject(SceneObjectGroup group, bool silent, bool removeScripts)
2758  {
2759  // m_log.DebugFormat("[SCENE]: Deleting scene object {0} {1}", group.Name, group.UUID);
2760 
2761  if (removeScripts)
2762  group.RemoveScriptInstances(true);
2763  else
2764  group.StopScriptInstances();
2765 
2766  List<ScenePresence> avatars = group.GetSittingAvatars();
2767  foreach (ScenePresence av in avatars)
2768  {
2769  if(av.ParentUUID == UUID.Zero)
2770  av.StandUp();
2771  }
2772 
2773  SceneObjectPart[] partList = group.Parts;
2774 
2775  foreach (SceneObjectPart part in partList)
2776  {
2777  if (part.KeyframeMotion != null)
2778  {
2779  part.KeyframeMotion.Delete();
2780  part.KeyframeMotion = null;
2781  }
2782 
2783  if (part.IsJoint() && ((part.Flags & PrimFlags.Physics) != 0))
2784  {
2785  PhysicsScene.RequestJointDeletion(part.Name); // FIXME: what if the name changed?
2786  }
2787  else if (part.PhysActor != null)
2788  {
2789  part.RemoveFromPhysics();
2790  }
2791  }
2792 
2793  if (UnlinkSceneObject(group, false))
2794  {
2795  EventManager.TriggerObjectBeingRemovedFromScene(group);
2796  EventManager.TriggerParcelPrimCountTainted();
2797  }
2798 
2799  group.DeleteGroupFromScene(silent);
2800  if (!silent)
2801  SendKillObject(new List<uint>() { group.LocalId });
2802 
2803  // use this to mean also full delete
2804  if (removeScripts)
2805  group.Clear();
2806  partList = null;
2807  // m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID);
2808  }
2809 
2817  public bool UnlinkSceneObject(SceneObjectGroup so, bool softDelete)
2818  {
2819  if (m_sceneGraph.DeleteSceneObject(so.UUID, softDelete))
2820  {
2821  if (!softDelete)
2822  {
2823  // If the group contains prims whose SceneGroupID is incorrect then force a
2824  // database update, because RemoveObject() works by searching on the SceneGroupID.
2825  // This is an expensive thing to do so only do it if absolutely necessary.
2827  ForceSceneObjectBackup(so);
2828 
2829  so.DetachFromBackup();
2830  SimulationDataService.RemoveObject(so.UUID, RegionInfo.RegionID);
2831  }
2832 
2833  // We need to keep track of this state in case this group is still queued for further backup.
2834  so.IsDeleted = true;
2835 
2836  return true;
2837  }
2838 
2839  return false;
2840  }
2841 
2842 
2844  {
2845  m_sceneGraph.updateScenePartGroup(part, grp);
2846  }
2847 
2848 /* not in use, outdate by async method
2856  public void CrossPrimGroupIntoNewRegion(Vector3 attemptedPosition, SceneObjectGroup grp, bool silent)
2857  {
2858  if (grp == null)
2859  return;
2860  if (grp.IsDeleted)
2861  return;
2862 
2863  if (grp.RootPart.DIE_AT_EDGE)
2864  {
2865  // We remove the object here
2866  try
2867  {
2868  DeleteSceneObject(grp, false);
2869  }
2870  catch (Exception)
2871  {
2872  m_log.Warn("[SCENE]: exception when trying to remove the prim that crossed the border.");
2873  }
2874  return;
2875  }
2876 
2877  if (grp.RootPart.RETURN_AT_EDGE)
2878  {
2879  // We remove the object here
2880  try
2881  {
2882  List<SceneObjectGroup> objects = new List<SceneObjectGroup>();
2883  objects.Add(grp);
2884  SceneObjectGroup[] objectsArray = objects.ToArray();
2885  returnObjects(objectsArray, UUID.Zero);
2886  }
2887  catch (Exception)
2888  {
2889  m_log.Warn("[SCENE]: exception when trying to return the prim that crossed the border.");
2890  }
2891  return;
2892  }
2893 
2894  if (EntityTransferModule != null)
2895  EntityTransferModule.Cross(grp, attemptedPosition, silent);
2896  }
2897 */
2898 
2899  // Simple test to see if a position is in the current region.
2900  // This test is mostly used to see if a region crossing is necessary.
2901  // Assuming the position is relative to the region so anything outside its bounds.
2902  // Return 'true' if position inside region.
2903  public bool PositionIsInCurrentRegion(Vector3 pos)
2904  {
2905  bool ret = false;
2906  int xx = (int)Math.Floor(pos.X);
2907  int yy = (int)Math.Floor(pos.Y);
2908  if (xx < 0 || yy < 0)
2909  return false;
2910 
2911  IRegionCombinerModule regionCombinerModule = RequestModuleInterface<IRegionCombinerModule>();
2912  if (regionCombinerModule == null)
2913  {
2914  // Regular region. Just check for region size
2915  if (xx < RegionInfo.RegionSizeX && yy < RegionInfo.RegionSizeY )
2916  ret = true;
2917  }
2918  else
2919  {
2920  // We're in a mega-region so see if we are still in that larger region
2921  ret = regionCombinerModule.PositionIsInMegaregion(this.RegionInfo.RegionID, xx, yy);
2922  }
2923  return ret;
2924  }
2925 
2931  public bool IncomingCreateObject(Vector3 newPosition, ISceneObject sog)
2932  {
2933  //m_log.DebugFormat(" >>> IncomingCreateObject(sog) <<< {0} deleted? {1} isAttach? {2}", ((SceneObjectGroup)sog).AbsolutePosition,
2934  // ((SceneObjectGroup)sog).IsDeleted, ((SceneObjectGroup)sog).RootPart.IsAttachment);
2935 
2936  SceneObjectGroup newObject;
2937  try
2938  {
2939  newObject = (SceneObjectGroup)sog;
2940  }
2941  catch (Exception e)
2942  {
2943  m_log.WarnFormat("[INTERREGION]: Problem casting object, exception {0}{1}", e.Message, e.StackTrace);
2944  return false;
2945  }
2946 
2947  // If the user is banned, we won't let any of their objects
2948  // enter. Period.
2949  //
2950  if (RegionInfo.EstateSettings.IsBanned(newObject.OwnerID, 36))
2951  {
2952  m_log.InfoFormat("[INTERREGION]: Denied prim crossing for banned avatar {0}", newObject.OwnerID);
2953  return false;
2954  }
2955 
2956  if (newPosition != Vector3.Zero)
2957  newObject.RootPart.GroupPosition = newPosition;
2958 
2959  if (!AddSceneObject(newObject))
2960  {
2961  m_log.DebugFormat(
2962  "[INTERREGION]: Problem adding scene object {0} in {1} ", newObject.UUID, RegionInfo.RegionName);
2963  return false;
2964  }
2965 
2966  if (!newObject.IsAttachment)
2967  {
2968  // FIXME: It would be better to never add the scene object at all rather than add it and then delete
2969  // it
2970  if (!Permissions.CanObjectEntry(newObject.UUID, true, newObject.AbsolutePosition))
2971  {
2972  // Deny non attachments based on parcel settings
2973  //
2974  m_log.Info("[INTERREGION]: Denied prim crossing because of parcel settings");
2975 
2976  DeleteSceneObject(newObject, false);
2977 
2978  return false;
2979  }
2980 
2981  // For attachments, we need to wait until the agent is root
2982  // before we restart the scripts, or else some functions won't work.
2983  newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject));
2984  newObject.ResumeScripts();
2985 
2986  // AddSceneObject already does this and doing it again messes
2987  // up region crossings, so don't.
2988  //if (newObject.RootPart.KeyframeMotion != null)
2989  // newObject.RootPart.KeyframeMotion.UpdateSceneObject(newObject);
2990  }
2991 
2992 
2993 
2994  // Do this as late as possible so that listeners have full access to the incoming object
2995  EventManager.TriggerOnIncomingSceneObject(newObject);
2996 
2997  return true;
2998  }
2999 
3007  public bool AddSceneObject(SceneObjectGroup sceneObject)
3008  {
3009  if (sceneObject.OwnerID == UUID.Zero)
3010  {
3011  m_log.ErrorFormat("[SCENE]: Owner ID for {0} was zero", sceneObject.UUID);
3012  return false;
3013  }
3014 
3015  // If the user is banned, we won't let any of their objects
3016  // enter. Period.
3017  //
3018  int flags = GetUserFlags(sceneObject.OwnerID);
3019  if (RegionInfo.EstateSettings.IsBanned(sceneObject.OwnerID, flags))
3020  {
3021  m_log.InfoFormat("[INTERREGION]: Denied prim crossing for banned avatar {0}", sceneObject.OwnerID);
3022 
3023  return false;
3024  }
3025 
3026  // Force allocation of new LocalId
3027  //
3028  SceneObjectPart[] parts = sceneObject.Parts;
3029  for (int i = 0; i < parts.Length; i++)
3030  parts[i].LocalId = 0;
3031 
3032  if (sceneObject.IsAttachmentCheckFull()) // Attachment
3033  {
3034  sceneObject.RootPart.AddFlag(PrimFlags.TemporaryOnRez);
3035 // sceneObject.RootPart.AddFlag(PrimFlags.Phantom);
3036 
3037  // Don't sent a full update here because this will cause full updates to be sent twice for
3038  // attachments on region crossings, resulting in viewer glitches.
3039  AddRestoredSceneObject(sceneObject, false, false, false);
3040 
3041  // Handle attachment special case
3042  SceneObjectPart RootPrim = sceneObject.RootPart;
3043 
3044  // Fix up attachment Parent Local ID
3045  ScenePresence sp = GetScenePresence(sceneObject.OwnerID);
3046 
3047  if (sp != null)
3048  {
3049  SceneObjectGroup grp = sceneObject;
3050 
3051  // m_log.DebugFormat(
3052  // "[ATTACHMENT]: Received attachment {0}, inworld asset id {1}", grp.FromItemID, grp.UUID);
3053  // m_log.DebugFormat(
3054  // "[ATTACHMENT]: Attach to avatar {0} at position {1}", sp.UUID, grp.AbsolutePosition);
3055 
3056  RootPrim.RemFlag(PrimFlags.TemporaryOnRez);
3057 
3058  // We must currently not resume scripts at this stage since AttachmentsModule does not have the
3059  // information that this is due to a teleport/border cross rather than an ordinary attachment.
3060  // We currently do this in Scene.MakeRootAgent() instead.
3061  if (AttachmentsModule != null)
3062  AttachmentsModule.AttachObject(sp, grp, 0, false, false, true);
3063  }
3064  else
3065  {
3066  m_log.DebugFormat("[SCENE]: Attachment {0} arrived and scene presence was not found, setting to temp", sceneObject.UUID);
3067 // RootPrim.RemFlag(PrimFlags.TemporaryOnRez);
3068 // RootPrim.AddFlag(PrimFlags.TemporaryOnRez);
3069  }
3070  if (sceneObject.OwnerID == UUID.Zero)
3071  {
3072  m_log.ErrorFormat("[SCENE]: Owner ID for {0} was zero after attachment processing. BUG!", sceneObject.UUID);
3073  return false;
3074  }
3075  }
3076  else
3077  {
3078  if (sceneObject.OwnerID == UUID.Zero)
3079  {
3080  m_log.ErrorFormat("[SCENE]: Owner ID for non-attachment {0} was zero", sceneObject.UUID);
3081  return false;
3082  }
3083  AddRestoredSceneObject(sceneObject, true, false);
3084  }
3085 
3086  return true;
3087  }
3088 
3089  private int GetStateSource(SceneObjectGroup sog)
3090  {
3091  if(!sog.IsAttachmentCheckFull())
3092  return 2; // StateSource.PrimCrossing
3093 
3094  ScenePresence sp = GetScenePresence(sog.OwnerID);
3095  if (sp != null)
3096  return sp.GetStateSource();
3097 
3098  return 2; // StateSource.PrimCrossing
3099  }
3100 
3101  public int GetUserFlags(UUID user)
3102  {
3103  //Unfortunately the SP approach means that the value is cached until region is restarted
3104  /*
3105  ScenePresence sp;
3106  if (TryGetScenePresence(user, out sp))
3107  {
3108  return sp.UserFlags;
3109  }
3110  else
3111  {
3112  */
3113  UserAccount uac = UserAccountService.GetUserAccount(RegionInfo.ScopeID, user);
3114  if (uac == null)
3115  return 0;
3116  return uac.UserFlags;
3117  //}
3118  }
3119 
3120  #endregion
3121 
3122  #region Add/Remove Avatar Methods
3123 
3124  public override ISceneAgent AddNewAgent(IClientAPI client, PresenceType type)
3125  {
3126  ScenePresence sp;
3127  bool vialogin;
3128  bool reallyNew = true;
3129 
3130  // Update the number of users attempting to login
3131  StatsReporter.UpdateUsersLoggingIn(true);
3132 
3133  // Validation occurs in LLUDPServer
3134  //
3135  // XXX: A race condition exists here where two simultaneous calls to AddNewAgent can interfere with
3136  // each other. In practice, this does not currently occur in the code.
3137  AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode);
3138 
3139  // We lock here on AgentCircuitData to prevent a race condition between the thread adding a new connection
3140  // and a simultaneous one that removes it (as can happen if the client is closed at a particular point
3141  // whilst connecting).
3142  //
3143  // It would be easier to lock across all NewUserConnection(), AddNewAgent() and
3144  // RemoveClient() calls for all agents, but this would allow a slow call (e.g. because of slow service
3145  // response in some module listening to AddNewAgent()) from holding up unrelated agent calls.
3146  //
3147  // In practice, the lock (this) in LLUDPServer.AddNewClient() currently lock across all
3148  // AddNewClient() operations (though not other ops).
3149  // In the future this can be relieved once locking per agent (not necessarily on AgentCircuitData) is improved.
3150  lock (aCircuit)
3151  {
3152  vialogin
3153  = (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0
3154  || (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0;
3155 
3156  CheckHeartbeat();
3157 
3158 
3159  sp = GetScenePresence(client.AgentId);
3160 
3161  // XXX: Not sure how good it is to add a new client if a scene presence already exists. Possibly this
3162  // could occur if a viewer crashes and relogs before the old client is kicked out. But this could cause
3163  // other problems, and possibly the code calling AddNewAgent() should ensure that no client is already
3164  // connected.
3165  if (sp == null)
3166  {
3167  m_log.DebugFormat(
3168  "[SCENE]: Adding new child scene presence {0} {1} to scene {2} at pos {3}, tpflags: {4}",
3169  client.Name, client.AgentId, RegionInfo.RegionName, client.StartPos,
3170  ((TPFlags)aCircuit.teleportFlags).ToString());
3171 
3172  m_clientManager.Add(client);
3173  SubscribeToClientEvents(client);
3174 
3175  sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type);
3176 
3177  sp.TeleportFlags = (TPFlags)aCircuit.teleportFlags;
3178 
3179 /* done in completMovement
3180  InventoryFolderBase cof = InventoryService.GetFolderForType(client.AgentId, (AssetType)46);
3181  if (cof == null)
3182  sp.COF = UUID.Zero;
3183  else
3184  sp.COF = cof.ID;
3185 
3186  m_log.DebugFormat("[SCENE]: COF for {0} is {1}", client.AgentId, sp.COF);
3187  */
3188  m_eventManager.TriggerOnNewPresence(sp);
3189  }
3190  else
3191  {
3192  // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the
3193  // client is for a root or child agent.
3194  // XXX: This may be better set for a new client before that client is added to the client manager.
3195  // But need to know what happens in the case where a ScenePresence is already present (and if this
3196  // actually occurs).
3197 
3198 
3199  m_log.WarnFormat(
3200  "[SCENE]: Already found {0} scene presence for {1} in {2} when asked to add new scene presence",
3201  sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName);
3202 
3203  reallyNew = false;
3204  }
3205  client.SceneAgent = sp;
3206 
3207  // This is currently also being done earlier in NewUserConnection for real users to see if this
3208  // resolves problems where HG agents are occasionally seen by others as "Unknown user" in chat and other
3209  // places. However, we still need to do it here for NPCs.
3210  CacheUserName(sp, aCircuit);
3211 
3212  if (reallyNew)
3213  EventManager.TriggerOnNewClient(client);
3214 
3215  if (vialogin)
3216  EventManager.TriggerOnClientLogin(client);
3217  }
3218 
3219  // User has logged into the scene so update the list of users logging
3220  // in
3221  StatsReporter.UpdateUsersLoggingIn(false);
3222 
3223  m_LastLogin = Util.EnvironmentTickCount();
3224 
3225  return sp;
3226  }
3227 
3231  public string GetAgentHomeURI(UUID agentID)
3232  {
3233  AgentCircuitData circuit = AuthenticateHandler.GetAgentCircuitData(agentID);
3234  if (circuit != null && circuit.ServiceURLs != null && circuit.ServiceURLs.ContainsKey("HomeURI"))
3235  return circuit.ServiceURLs["HomeURI"].ToString();
3236  else
3237  return null;
3238  }
3239 
3245  private void CacheUserName(ScenePresence sp, AgentCircuitData aCircuit)
3246  {
3247  if (UserManagementModule != null)
3248  {
3249  string first = aCircuit.firstname, last = aCircuit.lastname;
3250 
3251  if (sp != null && sp.PresenceType == PresenceType.Npc)
3252  {
3253  UserManagementModule.AddUser(aCircuit.AgentID, first, last);
3254  }
3255  else
3256  {
3257  string homeURL = string.Empty;
3258 
3259  if (aCircuit.ServiceURLs.ContainsKey("HomeURI"))
3260  homeURL = aCircuit.ServiceURLs["HomeURI"].ToString();
3261 
3262  if (aCircuit.lastname.StartsWith("@"))
3263  {
3264  string[] parts = aCircuit.firstname.Split('.');
3265  if (parts.Length >= 2)
3266  {
3267  first = parts[0];
3268  last = parts[1];
3269  }
3270  }
3271 
3272  UserManagementModule.AddUser(aCircuit.AgentID, first, last, homeURL);
3273  }
3274  }
3275  }
3276 
3277  private bool VerifyClient(AgentCircuitData aCircuit, System.Net.IPEndPoint ep, out bool vialogin)
3278  {
3279  vialogin = false;
3280 
3281  // Do the verification here
3282  if ((aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0)
3283  {
3284  m_log.DebugFormat("[SCENE]: Incoming client {0} {1} in region {2} via HG login", aCircuit.firstname, aCircuit.lastname, RegionInfo.RegionName);
3285  vialogin = true;
3286  IUserAgentVerificationModule userVerification = RequestModuleInterface<IUserAgentVerificationModule>();
3287  if (userVerification != null && ep != null)
3288  {
3289  if (!userVerification.VerifyClient(aCircuit, ep.Address.ToString()))
3290  {
3291  // uh-oh, this is fishy
3292  m_log.DebugFormat("[SCENE]: User Client Verification for {0} {1} in {2} returned false", aCircuit.firstname, aCircuit.lastname, RegionInfo.RegionName);
3293  return false;
3294  }
3295  else
3296  m_log.DebugFormat("[SCENE]: User Client Verification for {0} {1} in {2} returned true", aCircuit.firstname, aCircuit.lastname, RegionInfo.RegionName);
3297 
3298  }
3299  }
3300 
3301  else if ((aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0)
3302  {
3303  m_log.DebugFormat("[SCENE]: Incoming client {0} {1} in region {2} via regular login. Client IP verification not performed.",
3304  aCircuit.firstname, aCircuit.lastname, RegionInfo.RegionName);
3305  vialogin = true;
3306  }
3307 
3308  return true;
3309  }
3310 
3311  // Called by Caps, on the first HTTP contact from the client
3312  public override bool CheckClient(UUID agentID, System.Net.IPEndPoint ep)
3313  {
3314  AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(agentID);
3315  if (aCircuit != null)
3316  {
3317  bool vialogin = false;
3318  if (!VerifyClient(aCircuit, ep, out vialogin))
3319  {
3320  // if it doesn't pass, we remove the agentcircuitdata altogether
3321  // and the scene presence and the client, if they exist
3322  try
3323  {
3324  ScenePresence sp = WaitGetScenePresence(agentID);
3325 
3326  if (sp != null)
3327  {
3328  PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
3329 
3330  CloseAgent(sp.UUID, false);
3331  }
3332 
3333  // BANG! SLASH!
3334  m_authenticateHandler.RemoveCircuit(agentID);
3335 
3336  return false;
3337  }
3338  catch (Exception e)
3339  {
3340  m_log.DebugFormat("[SCENE]: Exception while closing aborted client: {0}", e.StackTrace);
3341  }
3342  }
3343  else
3344  return true;
3345  }
3346 
3347  return false;
3348  }
3349 
3354  public virtual void SubscribeToClientEvents(IClientAPI client)
3355  {
3356  SubscribeToClientTerrainEvents(client);
3357  SubscribeToClientPrimEvents(client);
3358  SubscribeToClientPrimRezEvents(client);
3359  SubscribeToClientInventoryEvents(client);
3360  SubscribeToClientTeleportEvents(client);
3361  SubscribeToClientScriptEvents(client);
3362  SubscribeToClientParcelEvents(client);
3363  SubscribeToClientGridEvents(client);
3364  SubscribeToClientNetworkEvents(client);
3365  }
3366 
3367  public virtual void SubscribeToClientTerrainEvents(IClientAPI client)
3368  {
3369 // client.OnRegionHandShakeReply += SendLayerData;
3370  }
3371 
3372  public virtual void SubscribeToClientPrimEvents(IClientAPI client)
3373  {
3374  client.OnUpdatePrimGroupPosition += m_sceneGraph.UpdatePrimGroupPosition;
3375  client.OnUpdatePrimSinglePosition += m_sceneGraph.UpdatePrimSinglePosition;
3376 
3377  client.onClientChangeObject += m_sceneGraph.ClientChangeObject;
3378 
3379  client.OnUpdatePrimGroupRotation += m_sceneGraph.UpdatePrimGroupRotation;
3380  client.OnUpdatePrimGroupMouseRotation += m_sceneGraph.UpdatePrimGroupRotation;
3381  client.OnUpdatePrimSingleRotation += m_sceneGraph.UpdatePrimSingleRotation;
3382  client.OnUpdatePrimSingleRotationPosition += m_sceneGraph.UpdatePrimSingleRotationPosition;
3383 
3384  client.OnUpdatePrimScale += m_sceneGraph.UpdatePrimScale;
3385  client.OnUpdatePrimGroupScale += m_sceneGraph.UpdatePrimGroupScale;
3386  client.OnUpdateExtraParams += m_sceneGraph.UpdateExtraParam;
3387  client.OnUpdatePrimShape += m_sceneGraph.UpdatePrimShape;
3388  client.OnUpdatePrimTexture += m_sceneGraph.UpdatePrimTexture;
3389  client.OnObjectRequest += RequestPrim;
3390  client.OnObjectSelect += SelectPrim;
3391  client.OnObjectDeselect += DeselectPrim;
3392  client.OnGrabUpdate += m_sceneGraph.MoveObject;
3393  client.OnSpinStart += m_sceneGraph.SpinStart;
3394  client.OnSpinUpdate += m_sceneGraph.SpinObject;
3395  client.OnDeRezObject += DeRezObjects;
3396 
3397  client.OnObjectName += m_sceneGraph.PrimName;
3398  client.OnObjectClickAction += m_sceneGraph.PrimClickAction;
3399  client.OnObjectMaterial += m_sceneGraph.PrimMaterial;
3400  client.OnLinkObjects += LinkObjects;
3401  client.OnDelinkObjects += DelinkObjects;
3402  client.OnObjectDuplicate += DuplicateObject;
3403  client.OnObjectDuplicateOnRay += doObjectDuplicateOnRay;
3404  client.OnUpdatePrimFlags += m_sceneGraph.UpdatePrimFlags;
3405  client.OnRequestObjectPropertiesFamily += m_sceneGraph.RequestObjectPropertiesFamily;
3406  client.OnObjectPermissions += HandleObjectPermissionsUpdate;
3407  client.OnGrabObject += ProcessObjectGrab;
3408  client.OnGrabUpdate += ProcessObjectGrabUpdate;
3409  client.OnDeGrabObject += ProcessObjectDeGrab;
3410  client.OnUndo += m_sceneGraph.HandleUndo;
3411  client.OnRedo += m_sceneGraph.HandleRedo;
3412  client.OnObjectDescription += m_sceneGraph.PrimDescription;
3413  client.OnObjectIncludeInSearch += m_sceneGraph.MakeObjectSearchable;
3414  client.OnObjectOwner += ObjectOwner;
3415  client.OnObjectGroupRequest += HandleObjectGroupUpdate;
3416  }
3417 
3418  public virtual void SubscribeToClientPrimRezEvents(IClientAPI client)
3419  {
3420  client.OnAddPrim += AddNewPrim;
3421  client.OnRezObject += RezObject;
3422  }
3423 
3424  public virtual void SubscribeToClientInventoryEvents(IClientAPI client)
3425  {
3426  client.OnLinkInventoryItem += HandleLinkInventoryItem;
3427  client.OnCreateNewInventoryFolder += HandleCreateInventoryFolder;
3428  client.OnUpdateInventoryFolder += HandleUpdateInventoryFolder;
3429  client.OnMoveInventoryFolder += HandleMoveInventoryFolder; // 2; //!!
3430  client.OnFetchInventoryDescendents += HandleFetchInventoryDescendents;
3431  client.OnPurgeInventoryDescendents += HandlePurgeInventoryDescendents; // 2; //!!
3432  client.OnFetchInventory += m_asyncInventorySender.HandleFetchInventory;
3433  client.OnUpdateInventoryItem += UpdateInventoryItemAsset;
3434  client.OnCopyInventoryItem += CopyInventoryItem;
3435  client.OnMoveItemsAndLeaveCopy += MoveInventoryItemsLeaveCopy;
3436  client.OnMoveInventoryItem += MoveInventoryItem;
3437  client.OnRemoveInventoryItem += RemoveInventoryItem;
3438  client.OnRemoveInventoryFolder += RemoveInventoryFolder;
3439  client.OnRezScript += RezScript;
3440  client.OnRequestTaskInventory += RequestTaskInventory;
3441  client.OnRemoveTaskItem += RemoveTaskInventory;
3442  client.OnUpdateTaskInventory += UpdateTaskInventory;
3443  client.OnMoveTaskItem += ClientMoveTaskInventoryItem;
3444  }
3445 
3446  public virtual void SubscribeToClientTeleportEvents(IClientAPI client)
3447  {
3448  client.OnTeleportLocationRequest += RequestTeleportLocation;
3449  }
3450 
3451  public virtual void SubscribeToClientScriptEvents(IClientAPI client)
3452  {
3453  client.OnScriptReset += ProcessScriptReset;
3454  client.OnGetScriptRunning += GetScriptRunning;
3455  client.OnSetScriptRunning += SetScriptRunning;
3456  }
3457 
3458  public virtual void SubscribeToClientParcelEvents(IClientAPI client)
3459  {
3460  client.OnParcelReturnObjectsRequest += LandChannel.ReturnObjectsInParcel;
3461  client.OnParcelSetOtherCleanTime += LandChannel.SetParcelOtherCleanTime;
3462  client.OnParcelBuy += ProcessParcelBuy;
3463  }
3464 
3465  public virtual void SubscribeToClientGridEvents(IClientAPI client)
3466  {
3467  //client.OnNameFromUUIDRequest += HandleUUIDNameRequest;
3468  client.OnMoneyTransferRequest += ProcessMoneyTransferRequest;
3469  }
3470 
3471  public virtual void SubscribeToClientNetworkEvents(IClientAPI client)
3472  {
3473  client.OnNetworkStatsUpdate += StatsReporter.AddPacketsStats;
3474  client.OnViewerEffect += ProcessViewerEffect;
3475  }
3476 
3482  public virtual void UnSubscribeToClientEvents(IClientAPI client)
3483  {
3484  UnSubscribeToClientTerrainEvents(client);
3485  UnSubscribeToClientPrimEvents(client);
3486  UnSubscribeToClientPrimRezEvents(client);
3487  UnSubscribeToClientInventoryEvents(client);
3488  UnSubscribeToClientTeleportEvents(client);
3489  UnSubscribeToClientScriptEvents(client);
3490  UnSubscribeToClientParcelEvents(client);
3491  UnSubscribeToClientGridEvents(client);
3492  UnSubscribeToClientNetworkEvents(client);
3493  }
3494 
3495  public virtual void UnSubscribeToClientTerrainEvents(IClientAPI client)
3496  {
3497 // client.OnRegionHandShakeReply -= SendLayerData;
3498  }
3499 
3500  public virtual void UnSubscribeToClientPrimEvents(IClientAPI client)
3501  {
3502  client.OnUpdatePrimGroupPosition -= m_sceneGraph.UpdatePrimGroupPosition;
3503  client.OnUpdatePrimSinglePosition -= m_sceneGraph.UpdatePrimSinglePosition;
3504 
3505  client.onClientChangeObject -= m_sceneGraph.ClientChangeObject;
3506 
3507  client.OnUpdatePrimGroupRotation -= m_sceneGraph.UpdatePrimGroupRotation;
3508  client.OnUpdatePrimGroupMouseRotation -= m_sceneGraph.UpdatePrimGroupRotation;
3509  client.OnUpdatePrimSingleRotation -= m_sceneGraph.UpdatePrimSingleRotation;
3510  client.OnUpdatePrimSingleRotationPosition -= m_sceneGraph.UpdatePrimSingleRotationPosition;
3511 
3512  client.OnUpdatePrimScale -= m_sceneGraph.UpdatePrimScale;
3513  client.OnUpdatePrimGroupScale -= m_sceneGraph.UpdatePrimGroupScale;
3514  client.OnUpdateExtraParams -= m_sceneGraph.UpdateExtraParam;
3515  client.OnUpdatePrimShape -= m_sceneGraph.UpdatePrimShape;
3516  client.OnUpdatePrimTexture -= m_sceneGraph.UpdatePrimTexture;
3517  client.OnObjectRequest -= RequestPrim;
3518  client.OnObjectSelect -= SelectPrim;
3519  client.OnObjectDeselect -= DeselectPrim;
3520  client.OnGrabUpdate -= m_sceneGraph.MoveObject;
3521  client.OnSpinStart -= m_sceneGraph.SpinStart;
3522  client.OnSpinUpdate -= m_sceneGraph.SpinObject;
3523  client.OnDeRezObject -= DeRezObjects;
3524  client.OnObjectName -= m_sceneGraph.PrimName;
3525  client.OnObjectClickAction -= m_sceneGraph.PrimClickAction;
3526  client.OnObjectMaterial -= m_sceneGraph.PrimMaterial;
3527  client.OnLinkObjects -= LinkObjects;
3528  client.OnDelinkObjects -= DelinkObjects;
3529  client.OnObjectDuplicate -= DuplicateObject;
3530  client.OnObjectDuplicateOnRay -= doObjectDuplicateOnRay;
3531  client.OnUpdatePrimFlags -= m_sceneGraph.UpdatePrimFlags;
3532  client.OnRequestObjectPropertiesFamily -= m_sceneGraph.RequestObjectPropertiesFamily;
3533  client.OnObjectPermissions -= HandleObjectPermissionsUpdate;
3534  client.OnGrabObject -= ProcessObjectGrab;
3535  client.OnDeGrabObject -= ProcessObjectDeGrab;
3536  client.OnUndo -= m_sceneGraph.HandleUndo;
3537  client.OnRedo -= m_sceneGraph.HandleRedo;
3538  client.OnObjectDescription -= m_sceneGraph.PrimDescription;
3539  client.OnObjectIncludeInSearch -= m_sceneGraph.MakeObjectSearchable;
3540  client.OnObjectOwner -= ObjectOwner;
3541  }
3542 
3543  public virtual void UnSubscribeToClientPrimRezEvents(IClientAPI client)
3544  {
3545  client.OnAddPrim -= AddNewPrim;
3546  client.OnRezObject -= RezObject;
3547  }
3548 
3550  {
3551  client.OnCreateNewInventoryFolder -= HandleCreateInventoryFolder;
3552  client.OnUpdateInventoryFolder -= HandleUpdateInventoryFolder;
3553  client.OnMoveInventoryFolder -= HandleMoveInventoryFolder; // 2; //!!
3554  client.OnFetchInventoryDescendents -= HandleFetchInventoryDescendents;
3555  client.OnPurgeInventoryDescendents -= HandlePurgeInventoryDescendents; // 2; //!!
3556  client.OnFetchInventory -= m_asyncInventorySender.HandleFetchInventory;
3557  client.OnUpdateInventoryItem -= UpdateInventoryItemAsset;
3558  client.OnCopyInventoryItem -= CopyInventoryItem;
3559  client.OnMoveInventoryItem -= MoveInventoryItem;
3560  client.OnRemoveInventoryItem -= RemoveInventoryItem;
3561  client.OnRemoveInventoryFolder -= RemoveInventoryFolder;
3562  client.OnRezScript -= RezScript;
3563  client.OnRequestTaskInventory -= RequestTaskInventory;
3564  client.OnRemoveTaskItem -= RemoveTaskInventory;
3565  client.OnUpdateTaskInventory -= UpdateTaskInventory;
3566  client.OnMoveTaskItem -= ClientMoveTaskInventoryItem;
3567  }
3568 
3569  public virtual void UnSubscribeToClientTeleportEvents(IClientAPI client)
3570  {
3571  client.OnTeleportLocationRequest -= RequestTeleportLocation;
3572  //client.OnTeleportLandmarkRequest -= RequestTeleportLandmark;
3573  //client.OnTeleportHomeRequest -= TeleportClientHome;
3574  }
3575 
3576  public virtual void UnSubscribeToClientScriptEvents(IClientAPI client)
3577  {
3578  client.OnScriptReset -= ProcessScriptReset;
3579  client.OnGetScriptRunning -= GetScriptRunning;
3580  client.OnSetScriptRunning -= SetScriptRunning;
3581  }
3582 
3583  public virtual void UnSubscribeToClientParcelEvents(IClientAPI client)
3584  {
3585  client.OnParcelReturnObjectsRequest -= LandChannel.ReturnObjectsInParcel;
3586  client.OnParcelSetOtherCleanTime -= LandChannel.SetParcelOtherCleanTime;
3587  client.OnParcelBuy -= ProcessParcelBuy;
3588  }
3589 
3590  public virtual void UnSubscribeToClientGridEvents(IClientAPI client)
3591  {
3592  //client.OnNameFromUUIDRequest -= HandleUUIDNameRequest;
3593  client.OnMoneyTransferRequest -= ProcessMoneyTransferRequest;
3594  }
3595 
3596  public virtual void UnSubscribeToClientNetworkEvents(IClientAPI client)
3597  {
3598  client.OnNetworkStatsUpdate -= StatsReporter.AddPacketsStats;
3599  client.OnViewerEffect -= ProcessViewerEffect;
3600  }
3601 
3607  public virtual bool TeleportClientHome(UUID agentId, IClientAPI client)
3608  {
3609  if (EntityTransferModule != null)
3610  {
3611  return EntityTransferModule.TeleportHome(agentId, client);
3612  }
3613  else
3614  {
3615  m_log.DebugFormat("[SCENE]: Unable to teleport user home: no AgentTransferModule is active");
3616  client.SendTeleportFailed("Unable to perform teleports on this simulator.");
3617  }
3618  return false;
3619  }
3620 
3629  public void DuplicateObject(uint originalPrim, Vector3 offset, uint flags, UUID AgentID, UUID GroupID)
3630  {
3631  SceneObjectGroup copy = SceneGraph.DuplicateObject(originalPrim, offset, flags, AgentID, GroupID, Quaternion.Identity);
3632  if (copy != null)
3633  EventManager.TriggerObjectAddedToScene(copy);
3634  }
3635 
3651  public void doObjectDuplicateOnRay(uint localID, uint dupeFlags, UUID AgentID, UUID GroupID,
3652  UUID RayTargetObj, Vector3 RayEnd, Vector3 RayStart,
3653  bool BypassRaycast, bool RayEndIsIntersection, bool CopyCenters, bool CopyRotates)
3654  {
3655  Vector3 pos;
3656  const bool frontFacesOnly = true;
3657  //m_log.Info("HITTARGET: " + RayTargetObj.ToString() + ", COPYTARGET: " + localID.ToString());
3658  SceneObjectPart target = GetSceneObjectPart(localID);
3659  SceneObjectPart target2 = GetSceneObjectPart(RayTargetObj);
3660 
3661  if (target != null && target2 != null)
3662  {
3663  Vector3 direction = Vector3.Normalize(RayEnd - RayStart);
3664 
3665  pos = target2.AbsolutePosition;
3666  //m_log.Info("[OBJECT_REZ]: TargetPos: " + pos.ToString() + ", RayStart: " + RayStart.ToString() + ", RayEnd: " + RayEnd.ToString() + ", Volume: " + Util.GetDistanceTo(RayStart,RayEnd).ToString() + ", mag1: " + Util.GetMagnitude(RayStart).ToString() + ", mag2: " + Util.GetMagnitude(RayEnd).ToString());
3667 
3668  // TODO: Raytrace better here
3669 
3670  //EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection));
3671  Ray NewRay = new Ray(RayStart,direction);
3672 
3673  // Ray Trace against target here
3674  EntityIntersection ei = target2.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, CopyCenters);
3675 
3676  // Un-comment out the following line to Get Raytrace results printed to the console.
3677  //m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString());
3678  float ScaleOffset = 0.5f;
3679 
3680  // If we hit something
3681  if (ei.HitTF)
3682  {
3683  Vector3 scale = target.Scale;
3684  Vector3 scaleComponent = ei.AAfaceNormal;
3685  if (scaleComponent.X != 0) ScaleOffset = scale.X;
3686  if (scaleComponent.Y != 0) ScaleOffset = scale.Y;
3687  if (scaleComponent.Z != 0) ScaleOffset = scale.Z;
3688  ScaleOffset = Math.Abs(ScaleOffset);
3689  Vector3 intersectionpoint = ei.ipoint;
3690  Vector3 normal = ei.normal;
3691  Vector3 offset = normal * (ScaleOffset / 2f);
3692  pos = intersectionpoint + offset;
3693 
3694  // stick in offset format from the original prim
3695  pos = pos - target.ParentGroup.AbsolutePosition;
3696  SceneObjectGroup copy;
3697  if (CopyRotates)
3698  {
3699  Quaternion worldRot = target2.GetWorldRotation();
3700 
3701  // SceneObjectGroup obj = m_sceneGraph.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID, worldRot);
3702  copy = m_sceneGraph.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID, worldRot);
3703  //obj.Rotation = worldRot;
3704  //obj.UpdateGroupRotationR(worldRot);
3705  }
3706  else
3707  {
3708  copy = m_sceneGraph.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID, Quaternion.Identity);
3709  }
3710 
3711  if (copy != null)
3712  EventManager.TriggerObjectAddedToScene(copy);
3713  }
3714  }
3715  }
3716 
3722  public void GetAvatarAppearance(IClientAPI client, out AvatarAppearance appearance)
3723  {
3724  AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode);
3725 
3726  if (aCircuit == null)
3727  {
3728  m_log.DebugFormat("[APPEARANCE] Client did not supply a circuit. Non-Linden? Creating default appearance.");
3729  appearance = new AvatarAppearance();
3730  return;
3731  }
3732 
3733  appearance = aCircuit.Appearance;
3734  if (appearance == null)
3735  {
3736  m_log.DebugFormat("[APPEARANCE]: Appearance not found in {0}, returning default", RegionInfo.RegionName);
3737  appearance = new AvatarAppearance();
3738  }
3739  }
3740 
3754 
3755  private object m_removeClientPrivLock = new Object();
3756 
3757  public void RemoveClient(UUID agentID, bool closeChildAgents)
3758  {
3759  AgentCircuitData acd = m_authenticateHandler.GetAgentCircuitData(agentID);
3760 
3761  // Shouldn't be necessary since RemoveClient() is currently only called by IClientAPI.Close() which
3762  // in turn is only called by Scene.IncomingCloseAgent() which checks whether the presence exists or not
3763  // However, will keep for now just in case.
3764  if (acd == null)
3765  {
3766  m_log.ErrorFormat(
3767  "[SCENE]: No agent circuit found for {0} in {1}, aborting Scene.RemoveClient", agentID, Name);
3768 
3769  return;
3770  }
3771 
3772  // TODO: Can we now remove this lock?
3773  lock (m_removeClientPrivLock)
3774  {
3775  bool isChildAgent = false;
3776 
3777  ScenePresence avatar = GetScenePresence(agentID);
3778 
3779  // Shouldn't be necessary since RemoveClient() is currently only called by IClientAPI.Close() which
3780  // in turn is only called by Scene.IncomingCloseAgent() which checks whether the presence exists or not
3781  // However, will keep for now just in case.
3782  if (avatar == null)
3783  {
3784  m_log.ErrorFormat(
3785  "[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in the scene.", agentID);
3786  m_authenticateHandler.RemoveCircuit(agentID);
3787 
3788  return;
3789  }
3790 
3791  try
3792  {
3793  isChildAgent = avatar.IsChildAgent;
3794 
3795  m_log.DebugFormat(
3796  "[SCENE]: Removing {0} agent {1} {2} from {3}",
3797  isChildAgent ? "child" : "root", avatar.Name, agentID, Name);
3798 
3799  // Don't do this to root agents, it's not nice for the viewer
3800  if (closeChildAgents && isChildAgent)
3801  {
3802  // Tell a single agent to disconnect from the region.
3803  // Let's do this via UDP
3804  avatar.ControllingClient.SendShutdownConnectionNotice();
3805  }
3806 
3807  // Only applies to root agents.
3808  if (avatar.ParentID != 0)
3809  {
3810  avatar.StandUp();
3811  }
3812 
3813  m_sceneGraph.removeUserCount(!isChildAgent);
3814 
3815  // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop
3816  // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI
3817  if (closeChildAgents && CapsModule != null)
3818  CapsModule.RemoveCaps(agentID, avatar.ControllingClient.CircuitCode);
3819 
3820  if (closeChildAgents && !isChildAgent)
3821  {
3822  List<ulong> regions = avatar.KnownRegionHandles;
3823  regions.Remove(RegionInfo.RegionHandle);
3824 
3825  // This ends up being done asynchronously so that a logout isn't held up where there are many present but unresponsive neighbours.
3826  m_sceneGridService.SendCloseChildAgentConnections(agentID, acd.SessionID.ToString(), regions);
3827  }
3828 
3829  m_eventManager.TriggerClientClosed(agentID, this);
3830 // m_log.Debug("[Scene]TriggerClientClosed done");
3831  m_eventManager.TriggerOnRemovePresence(agentID);
3832 // m_log.Debug("[Scene]TriggerOnRemovePresence done");
3833 
3834  if (!isChildAgent)
3835  {
3836  if (AttachmentsModule != null)
3837  {
3838 // m_log.Debug("[Scene]DeRezAttachments");
3839  AttachmentsModule.DeRezAttachments(avatar);
3840 // m_log.Debug("[Scene]DeRezAttachments done");
3841  }
3842 
3843  ForEachClient(
3844  delegate(IClientAPI client)
3845  {
3846  //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway
3847  try { client.SendKillObject(new List<uint> { avatar.LocalId }); }
3848  catch (NullReferenceException) { }
3849  });
3850  }
3851 
3852  // It's possible for child agents to have transactions if changes are being made cross-border.
3853  if (AgentTransactionsModule != null)
3854  {
3855 // m_log.Debug("[Scene]RemoveAgentAssetTransactions");
3856  AgentTransactionsModule.RemoveAgentAssetTransactions(agentID);
3857  }
3858  m_log.Debug("[Scene] The avatar has left the building");
3859  }
3860  catch (Exception e)
3861  {
3862  m_log.Error(
3863  string.Format("[SCENE]: Exception removing {0} from {1}. Cleaning up. Exception ", avatar.Name, Name), e);
3864  }
3865  finally
3866  {
3867  try
3868  {
3869  // Always clean these structures up so that any failure above doesn't cause them to remain in the
3870  // scene with possibly bad effects (e.g. continually timing out on unacked packets and triggering
3871  // the same cleanup exception continually.
3872  m_authenticateHandler.RemoveCircuit(agentID);
3873  m_sceneGraph.RemoveScenePresence(agentID);
3874  m_clientManager.Remove(agentID);
3875 
3876  avatar.Close();
3877  }
3878  catch (Exception e)
3879  {
3880  m_log.Error(
3881  string.Format("[SCENE]: Exception in final clean up of {0} in {1}. Exception ", avatar.Name, Name), e);
3882  }
3883  }
3884  }
3885 
3886  //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false));
3887  //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true));
3888  }
3889 
3896  public void HandleRemoveKnownRegionsFromAvatar(UUID avatarID, List<ulong> regionslst)
3897  {
3898  ScenePresence av = GetScenePresence(avatarID);
3899  if (av != null)
3900  {
3901  lock (av)
3902  {
3903  for (int i = 0; i < regionslst.Count; i++)
3904  {
3905  av.RemoveNeighbourRegion(regionslst[i]);
3906  }
3907  }
3908  }
3909  }
3910 
3911  #endregion
3912 
3913  #region Entities
3914 
3915  public void SendKillObject(List<uint> localIDs)
3916  {
3917  List<uint> deleteIDs = new List<uint>();
3918 
3919  foreach (uint localID in localIDs)
3920  {
3921  SceneObjectPart part = GetSceneObjectPart(localID);
3922  if (part != null) // It is a prim
3923  {
3924  if (part.ParentGroup != null && !part.ParentGroup.IsDeleted) // Valid
3925  {
3926  if (part.ParentGroup.RootPart != part) // Child part
3927  continue;
3928  }
3929  }
3930  deleteIDs.Add(localID);
3931  }
3932 
3933  ForEachClient(c => c.SendKillObject(deleteIDs));
3934  }
3935 
3936  #endregion
3937 
3938  #region RegionComms
3939 
3949  public bool NewUserConnection(AgentCircuitData agent, uint teleportFlags, GridRegion source, out string reason)
3950  {
3951  return NewUserConnection(agent, teleportFlags, source, out reason, true);
3952  }
3953 
3978  private object m_newUserConnLock = new object();
3979 
3980  public bool NewUserConnection(AgentCircuitData acd, uint teleportFlags, GridRegion source, out string reason, bool requirePresenceLookup)
3981  {
3982  bool vialogin = ((teleportFlags & (uint)TPFlags.ViaLogin) != 0 ||
3983  (teleportFlags & (uint)TPFlags.ViaHGLogin) != 0);
3984  bool viahome = ((teleportFlags & (uint)TPFlags.ViaHome) != 0);
3985  bool godlike = ((teleportFlags & (uint)TPFlags.Godlike) != 0);
3986 
3987  reason = String.Empty;
3988 
3989  //Teleport flags:
3990  //
3991  // TeleportFlags.ViaGodlikeLure - Border Crossing
3992  // TeleportFlags.ViaLogin - Login
3993  // TeleportFlags.TeleportFlags.ViaLure - Teleport request sent by another user
3994  // TeleportFlags.ViaLandmark | TeleportFlags.ViaLocation | TeleportFlags.ViaLandmark | TeleportFlags.Default - Regular Teleport
3995 
3996  // Don't disable this log message - it's too helpful
3997  string curViewer = Util.GetViewerName(acd);
3998  m_log.DebugFormat(
3999  "[SCENE]: Region {0} told of incoming {1} agent {2} {3} {4} (circuit code {5}, IP {6}, viewer {7}, teleportflags ({8}), position {9}. {10}",
4000  RegionInfo.RegionName,
4001  (acd.child ? "child" : "root"),
4002  acd.firstname,
4003  acd.lastname,
4004  acd.AgentID,
4005  acd.circuitcode,
4006  acd.IPAddress,
4007  curViewer,
4008  ((TPFlags)teleportFlags).ToString(),
4009  acd.startpos,
4010  (source == null) ? "" : string.Format("From region {0} ({1}){2}", source.RegionName, source.RegionID, (source.RawServerURI == null) ? "" : " @ " + source.ServerURI)
4011  );
4012 
4013 // m_log.DebugFormat("NewUserConnection stack {0}", Environment.StackTrace);
4014 
4015  if (!LoginsEnabled)
4016  {
4017  reason = "Logins Disabled";
4018  return false;
4019  }
4020 
4021  //Check if the viewer is banned or in the viewer access list
4022  //We check if the substring is listed for higher flexebility
4023  bool ViewerDenied = true;
4024 
4025  //Check if the specific viewer is listed in the allowed viewer list
4026  if (m_AllowedViewers.Count > 0)
4027  {
4028  foreach (string viewer in m_AllowedViewers)
4029  {
4030  if (viewer == curViewer.Substring(0, Math.Min(viewer.Length, curViewer.Length)).Trim().ToLower())
4031  {
4032  ViewerDenied = false;
4033  break;
4034  }
4035  }
4036  }
4037  else
4038  {
4039  ViewerDenied = false;
4040  }
4041 
4042  //Check if the viewer is in the banned list
4043  if (m_BannedViewers.Count > 0)
4044  {
4045  foreach (string viewer in m_BannedViewers)
4046  {
4047  if (viewer == curViewer.Substring(0, Math.Min(viewer.Length, curViewer.Length)).Trim().ToLower())
4048  {
4049  ViewerDenied = true;
4050  break;
4051  }
4052  }
4053  }
4054 
4055  if (ViewerDenied)
4056  {
4057  m_log.DebugFormat(
4058  "[SCENE]: Access denied for {0} {1} using {2}",
4059  acd.firstname, acd.lastname, curViewer);
4060  reason = "Access denied, your viewer is banned by the region owner";
4061  return false;
4062  }
4063 
4064  ScenePresence sp;
4065 
4066  lock (m_removeClientLock)
4067  {
4068  sp = GetScenePresence(acd.AgentID);
4069 
4070  // We need to ensure that we are not already removing the scene presence before we ask it not to be
4071  // closed.
4072  if (sp != null && sp.IsChildAgent
4073  && (sp.LifecycleState == ScenePresenceState.Running
4074  || sp.LifecycleState == ScenePresenceState.PreRemove))
4075  {
4076  m_log.DebugFormat(
4077  "[SCENE]: Reusing existing child scene presence for {0}, state {1} in {2}",
4078  sp.Name, sp.LifecycleState, Name);
4079 
4080  // In the case where, for example, an A B C D region layout, an avatar may
4081  // teleport from A -> D, but then -> C before A has asked B to close its old child agent. When C
4082  // renews the lease on the child agent at B, we must make sure that the close from A does not succeed.
4083  //
4084  // XXX: In the end, this should not be necessary if child agents are closed without delay on
4085  // teleport, since realistically, the close request should always be processed before any other
4086  // region tried to re-establish a child agent. This is much simpler since the logic below is
4087  // vulnerable to an issue when a viewer quits a region without sending a proper logout but then
4088  // re-establishes the connection on a relogin. This could wrongly set the DoNotCloseAfterTeleport
4089  // flag when no teleport had taken place (and hence no close was going to come).
4090 // if (!acd.ChildrenCapSeeds.ContainsKey(RegionInfo.RegionHandle))
4091 // {
4092 // m_log.DebugFormat(
4093 // "[SCENE]: Setting DoNotCloseAfterTeleport for child scene presence {0} in {1} because source will attempt close.",
4094 // sp.Name, Name);
4095 //
4096 // sp.DoNotCloseAfterTeleport = true;
4097 // }
4098 // else if (EntityTransferModule.IsInTransit(sp.UUID))
4099 
4100  sp.LifecycleState = ScenePresenceState.Running;
4101 
4102  if (EntityTransferModule.IsInTransit(sp.UUID))
4103  {
4104  sp.DoNotCloseAfterTeleport = true;
4105 
4106  m_log.DebugFormat(
4107  "[SCENE]: Set DoNotCloseAfterTeleport for child scene presence {0} in {1} because this region will attempt end-of-teleport close from a previous close.",
4108  sp.Name, Name);
4109  }
4110  }
4111  }
4112 
4113  // Need to poll here in case we are currently deleting an sp. Letting threads run over each other will
4114  // allow unpredictable things to happen.
4115  if (sp != null)
4116  {
4117  const int polls = 10;
4118  const int pollInterval = 1000;
4119  int pollsLeft = polls;
4120 
4121  while (sp.LifecycleState == ScenePresenceState.Removing && pollsLeft-- > 0)
4122  Thread.Sleep(pollInterval);
4123 
4124  if (sp.LifecycleState == ScenePresenceState.Removing)
4125  {
4126  m_log.WarnFormat(
4127  "[SCENE]: Agent {0} in {1} was still being removed after {2}s. Aborting NewUserConnection.",
4128  sp.Name, Name, polls * pollInterval / 1000);
4129 
4130  return false;
4131  }
4132  else if (polls != pollsLeft)
4133  {
4134  m_log.DebugFormat(
4135  "[SCENE]: NewUserConnection for agent {0} in {1} had to wait {2}s for in-progress removal to complete on an old presence.",
4136  sp.Name, Name, polls * pollInterval / 1000);
4137  }
4138  }
4139 
4140  // TODO: can we remove this lock?
4141  lock (m_newUserConnLock)
4142  {
4143  if (sp != null && !sp.IsChildAgent)
4144  {
4145  // We have a root agent. Is it in transit?
4146  if (!EntityTransferModule.IsInTransit(sp.UUID))
4147  {
4148  // We have a zombie from a crashed session.
4149  // Or the same user is trying to be root twice here, won't work.
4150  // Kill it.
4151  m_log.WarnFormat(
4152  "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.",
4153  sp.Name, sp.UUID, RegionInfo.RegionName);
4154 
4155  if (sp.ControllingClient != null)
4156  CloseAgent(sp.UUID, true);
4157 
4158  sp = null;
4159  }
4160  //else
4161  // m_log.WarnFormat("[SCENE]: Existing root scene presence for {0} {1} in {2}, but agent is in trasit", sp.Name, sp.UUID, RegionInfo.RegionName);
4162  }
4163 
4164  // Optimistic: add or update the circuit data with the new agent circuit data and teleport flags.
4165  // We need the circuit data here for some of the subsequent checks. (groups, for example)
4166  // If the checks fail, we remove the circuit.
4167  acd.teleportFlags = teleportFlags;
4168 
4169  if (vialogin)
4170  {
4171  IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>();
4172  if (cache != null)
4173  cache.Remove(acd.firstname + " " + acd.lastname);
4174 
4175  // Remove any preexisting circuit - we don't want duplicates
4176  // This is a stab at preventing avatar "ghosting"
4177  m_authenticateHandler.RemoveCircuit(acd.AgentID);
4178  }
4179 
4180  m_authenticateHandler.AddNewCircuit(acd.circuitcode, acd);
4181 
4182  if (sp == null) // We don't have an [child] agent here already
4183  {
4184  if (requirePresenceLookup)
4185  {
4186  try
4187  {
4188  if (!VerifyUserPresence(acd, out reason))
4189  {
4190  m_authenticateHandler.RemoveCircuit(acd.circuitcode);
4191  return false;
4192  }
4193  }
4194  catch (Exception e)
4195  {
4196  m_log.ErrorFormat(
4197  "[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace);
4198 
4199  m_authenticateHandler.RemoveCircuit(acd.circuitcode);
4200  return false;
4201  }
4202  }
4203 
4204  try
4205  {
4206  if (!AuthorizeUser(acd, (vialogin ? false : SeeIntoRegion), out reason))
4207  {
4208  m_authenticateHandler.RemoveCircuit(acd.circuitcode);
4209  return false;
4210  }
4211  }
4212  catch (Exception e)
4213  {
4214  m_log.ErrorFormat(
4215  "[SCENE]: Exception authorizing user {0}{1}", e.Message, e.StackTrace);
4216 
4217  m_authenticateHandler.RemoveCircuit(acd.circuitcode);
4218  return false;
4219  }
4220 
4221  m_log.InfoFormat(
4222  "[SCENE]: Region {0} authenticated and authorized incoming {1} agent {2} {3} {4} (circuit code {5})",
4223  Name, (acd.child ? "child" : "root"), acd.firstname, acd.lastname,
4224  acd.AgentID, acd.circuitcode);
4225 
4226  if (CapsModule != null)
4227  {
4228  CapsModule.SetAgentCapsSeeds(acd);
4229  CapsModule.CreateCaps(acd.AgentID, acd.circuitcode);
4230  }
4231  }
4232  else
4233  {
4234  // Let the SP know how we got here. This has a lot of interesting
4235  // uses down the line.
4236  sp.TeleportFlags = (TPFlags)teleportFlags;
4237 
4238  if (sp.IsChildAgent)
4239  {
4240  m_log.DebugFormat(
4241  "[SCENE]: Adjusting known seeds for existing agent {0} in {1}",
4242  acd.AgentID, RegionInfo.RegionName);
4243 
4244  if (CapsModule != null)
4245  {
4246  CapsModule.SetAgentCapsSeeds(acd);
4247  CapsModule.CreateCaps(acd.AgentID, acd.circuitcode);
4248  }
4249 
4250  sp.AdjustKnownSeeds();
4251  }
4252  }
4253 
4254  // Try caching an incoming user name much earlier on to see if this helps with an issue
4255  // where HG users are occasionally seen by others as "Unknown User" because their UUIDName
4256  // request for the HG avatar appears to trigger before the user name is cached.
4257  CacheUserName(null, acd);
4258  }
4259 
4260  if (CapsModule != null)
4261  {
4262  CapsModule.ActivateCaps(acd.circuitcode);
4263  }
4264 
4265 // if (vialogin)
4266 // {
4267 // CleanDroppedAttachments();
4268 // }
4269 
4270  // Make sure avatar position is in the region (why it wouldn't be is a mystery but do sanity checking)
4271  if (acd.startpos.X < 0)
4272  acd.startpos.X = 1f;
4273  else if (acd.startpos.X >= RegionInfo.RegionSizeX)
4274  acd.startpos.X = RegionInfo.RegionSizeX - 1f;
4275  if (acd.startpos.Y < 0)
4276  acd.startpos.Y = 1f;
4277  else if (acd.startpos.Y >= RegionInfo.RegionSizeY)
4278  acd.startpos.Y = RegionInfo.RegionSizeY - 1f;
4279 
4280  // only check access, actual relocations will happen later on ScenePresence MakeRoot
4281  // allow child agents creation
4282  if(!godlike && teleportFlags != (uint) TPFlags.Default)
4283  {
4284  bool checkTeleHub;
4285 
4286  // don't check hubs if via home or via lure
4287  if((teleportFlags & (uint) TPFlags.ViaHome) != 0
4288  || (teleportFlags & (uint) TPFlags.ViaLure) != 0)
4289  checkTeleHub = false;
4290  else
4291  checkTeleHub = vialogin
4292  || (TelehubAllowLandmarks == true ? false : ((teleportFlags & (uint)TPFlags.ViaLandmark) != 0 ))
4293  || (teleportFlags & (uint) TPFlags.ViaLocation) != 0;
4294 
4295  if(!CheckLandPositionAccess(acd.AgentID, true, checkTeleHub, acd.startpos, out reason))
4296  {
4297  m_authenticateHandler.RemoveCircuit(acd.circuitcode);
4298  return false;
4299  }
4300  }
4301 
4302  return true;
4303  }
4304 
4305  private bool IsPositionAllowed(UUID agentID, Vector3 pos, ref string reason)
4306  {
4307  ILandObject land = LandChannel.GetLandObject(pos);
4308  if (land == null)
4309  return true;
4310 
4311  if (land.IsBannedFromLand(agentID) || land.IsRestrictedFromLand(agentID))
4312  {
4313  reason = "You are banned from the region.";
4314  return false;
4315  }
4316 
4317  return true;
4318  }
4319 
4320  public bool TestLandRestrictions(UUID agentID, out string reason, ref float posX, ref float posY)
4321  {
4322  if (posX < 0)
4323  posX = 0;
4324 
4325  else if (posX >= RegionInfo.RegionSizeX)
4326  posX = RegionInfo.RegionSizeX - 0.5f;
4327  if (posY < 0)
4328  posY = 0;
4329  else if (posY >= RegionInfo.RegionSizeY)
4330  posY = RegionInfo.RegionSizeY - 0.5f;
4331 
4332  reason = String.Empty;
4333  if (Permissions.IsGod(agentID))
4334  return true;
4335 
4336  ILandObject land = LandChannel.GetLandObject(posX, posY);
4337  if (land == null)
4338  return false;
4339 
4340  bool banned = land.IsBannedFromLand(agentID);
4341  bool restricted = land.IsRestrictedFromLand(agentID);
4342 
4343  if (banned || restricted)
4344  {
4345  ILandObject nearestParcel = GetNearestAllowedParcel(agentID, posX, posY);
4346  if (nearestParcel != null)
4347  {
4348  //Move agent to nearest allowed
4349  Vector2 newPosition = GetParcelSafeCorner(nearestParcel);
4350  posX = newPosition.X;
4351  posY = newPosition.Y;
4352  }
4353  else
4354  {
4355  if (banned)
4356  {
4357  reason = "Cannot regioncross into banned parcel.";
4358  }
4359  else
4360  {
4361  reason = String.Format("Denied access to private region {0}: You are not on the access list for that region.",
4362  RegionInfo.RegionName);
4363  }
4364  return false;
4365  }
4366  }
4367  reason = "";
4368  return true;
4369  }
4370 
4378  public virtual bool VerifyUserPresence(AgentCircuitData agent, out string reason)
4379  {
4380  reason = String.Empty;
4381 
4382  IPresenceService presence = RequestModuleInterface<IPresenceService>();
4383  if (presence == null)
4384  {
4385  reason = String.Format("Failed to verify user presence in the grid for {0} {1} in region {2}. Presence service does not exist.", agent.firstname, agent.lastname, RegionInfo.RegionName);
4386  return false;
4387  }
4388 
4389  OpenSim.Services.Interfaces.PresenceInfo pinfo = presence.GetAgent(agent.SessionID);
4390 
4391  if (pinfo == null)
4392  {
4393  reason = String.Format("Failed to verify user presence in the grid for {0} {1}, access denied to region {2}.", agent.firstname, agent.lastname, RegionInfo.RegionName);
4394  return false;
4395  }
4396 
4397  return true;
4398  }
4399 
4407  protected virtual bool AuthorizeUser(AgentCircuitData agent, bool bypassAccessControl, out string reason)
4408  {
4409  reason = String.Empty;
4410 
4411  if (!m_strictAccessControl)
4412  return true;
4413  if (Permissions.IsGod(agent.AgentID))
4414  return true;
4415 
4416  if (AuthorizationService != null)
4417  {
4418  if (!AuthorizationService.IsAuthorizedForRegion(
4419  agent.AgentID.ToString(), agent.firstname, agent.lastname, RegionInfo.RegionID.ToString(), out reason))
4420  {
4421  m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because: {4}",
4422  agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName, reason);
4423 
4424  return false;
4425  }
4426  }
4427 
4428  // We only test the things below when we want to cut off
4429  // child agents from being present in the scene for which their root
4430  // agent isn't allowed. Otherwise, we allow child agents. The test for
4431  // the root is done elsewhere (QueryAccess)
4432  if (!bypassAccessControl)
4433  {
4434  if(RegionInfo.EstateSettings == null)
4435  {
4436  // something is broken? let it get in
4437  m_log.ErrorFormat("[CONNECTION BEGIN]: Estate Settings is null!");
4438  return true;
4439  }
4440 
4441  // check estate ban
4442  int flags = GetUserFlags(agent.AgentID);
4443  if (RegionInfo.EstateSettings.IsBanned(agent.AgentID, flags))
4444  {
4445  m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist",
4446  agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
4447  reason = String.Format("Denied access to region {0}: You have been banned from that region.",
4448  RegionInfo.RegionName);
4449  return false;
4450  }
4451 
4452  // public access
4454  return true;
4455 
4456  // in access list / owner / manager
4458  return true;
4459 
4460  // finally test groups
4461  bool groupAccess = false;
4462 
4463  // some say GOTO is ugly
4464  if(m_groupsModule == null) // if no groups refuse
4465  goto Label_GroupsDone;
4466 
4467  UUID[] estateGroups = RegionInfo.EstateSettings.EstateGroups;
4468 
4469  if(estateGroups == null)
4470  {
4471  m_log.ErrorFormat("[CONNECTION BEGIN]: Estate GroupMembership is null!");
4472  goto Label_GroupsDone;
4473  }
4474 
4475  if(estateGroups.Length == 0)
4476  goto Label_GroupsDone;
4477 
4478  List<UUID> agentGroups = new List<UUID>();
4479  GroupMembershipData[] GroupMembership = m_groupsModule.GetMembershipData(agent.AgentID);
4480 
4481  if(GroupMembership == null)
4482  {
4483  m_log.ErrorFormat("[CONNECTION BEGIN]: GroupMembership is null!");
4484  goto Label_GroupsDone;
4485  }
4486 
4487  if(GroupMembership.Length == 0)
4488  goto Label_GroupsDone;
4489 
4490  for(int i = 0;i < GroupMembership.Length;i++)
4491  agentGroups.Add(GroupMembership[i].GroupID);
4492 
4493  foreach(UUID group in estateGroups)
4494  {
4495  if(agentGroups.Contains(group))
4496  {
4497  groupAccess = true;
4498  break;
4499  }
4500  }
4501 
4502 Label_GroupsDone:
4503  if (!groupAccess)
4504  {
4505  m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the estate",
4506  agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
4507  reason = String.Format("Denied access to private region {0}: You are do not have access to that region.",
4508  RegionInfo.RegionName);
4509  return false;
4510  }
4511  }
4512 
4513  return true;
4514  }
4515 
4521  {
4522  m_authenticateHandler.UpdateAgentData(data);
4523  }
4524 
4531  public bool ChangeCircuitCode(uint oldcc, uint newcc)
4532  {
4533  return m_authenticateHandler.TryChangeCiruitCode(oldcc, newcc);
4534  }
4535 
4536 // /// <summary>
4537 // /// The Grid has requested that we log-off a user. Log them off.
4538 // /// </summary>
4539 // /// <param name="AvatarID">Unique ID of the avatar to log-off</param>
4540 // /// <param name="RegionSecret">SecureSessionID of the user, or the RegionSecret text when logging on to the grid</param>
4541 // /// <param name="message">message to display to the user. Reason for being logged off</param>
4542 // public void HandleLogOffUserFromGrid(UUID AvatarID, UUID RegionSecret, string message)
4543 // {
4544 // ScenePresence loggingOffUser = GetScenePresence(AvatarID);
4545 // if (loggingOffUser != null)
4546 // {
4547 // UUID localRegionSecret = UUID.Zero;
4548 // bool parsedsecret = UUID.TryParse(RegionInfo.regionSecret, out localRegionSecret);
4549 //
4550 // // Region Secret is used here in case a new sessionid overwrites an old one on the user server.
4551 // // Will update the user server in a few revisions to use it.
4552 //
4553 // if (RegionSecret == loggingOffUser.ControllingClient.SecureSessionId || (parsedsecret && RegionSecret == localRegionSecret))
4554 // {
4555 // m_sceneGridService.SendCloseChildAgentConnections(loggingOffUser.UUID, loggingOffUser.KnownRegionHandles);
4556 // loggingOffUser.ControllingClient.Kick(message);
4557 // // Give them a second to receive the message!
4558 // Thread.Sleep(1000);
4559 // loggingOffUser.ControllingClient.Close();
4560 // }
4561 // else
4562 // {
4563 // m_log.Info("[USERLOGOFF]: System sending the LogOff user message failed to sucessfully authenticate");
4564 // }
4565 // }
4566 // else
4567 // {
4568 // m_log.InfoFormat("[USERLOGOFF]: Got a logoff request for {0} but the user isn't here. The user might already have been logged out", AvatarID.ToString());
4569 // }
4570 // }
4571 
4572 // /// <summary>
4573 // /// Triggered when an agent crosses into this sim. Also happens on initial login.
4574 // /// </summary>
4575 // /// <param name="agentID"></param>
4576 // /// <param name="position"></param>
4577 // /// <param name="isFlying"></param>
4578 // public virtual void AgentCrossing(UUID agentID, Vector3 position, bool isFlying)
4579 // {
4580 // ScenePresence presence = GetScenePresence(agentID);
4581 // if (presence != null)
4582 // {
4583 // try
4584 // {
4585 // presence.MakeRootAgent(position, isFlying);
4586 // }
4587 // catch (Exception e)
4588 // {
4589 // m_log.ErrorFormat("[SCENE]: Unable to do agent crossing, exception {0}{1}", e.Message, e.StackTrace);
4590 // }
4591 // }
4592 // else
4593 // {
4594 // m_log.ErrorFormat(
4595 // "[SCENE]: Could not find presence for agent {0} crossing into scene {1}",
4596 // agentID, RegionInfo.RegionName);
4597 // }
4598 // }
4599 
4607  public virtual bool IncomingUpdateChildAgent(AgentData cAgentData)
4608  {
4609  m_log.DebugFormat(
4610  "[SCENE]: Incoming child agent update for {0} in {1}", cAgentData.AgentID, RegionInfo.RegionName);
4611 
4612  if (!LoginsEnabled)
4613  {
4614 // reason = "Logins Disabled";
4615  m_log.DebugFormat(
4616  "[SCENE]: update for {0} in {1} refused: Logins Disabled", cAgentData.AgentID, RegionInfo.RegionName);
4617  return false;
4618  }
4619  // We have to wait until the viewer contacts this region after receiving EAC.
4620  // That calls AddNewClient, which finally creates the ScenePresence
4621  int flags = GetUserFlags(cAgentData.AgentID);
4622  if (RegionInfo.EstateSettings.IsBanned(cAgentData.AgentID, flags))
4623  {
4624  m_log.DebugFormat("[SCENE]: Denying root agent entry to {0}: banned", cAgentData.AgentID);
4625  return false;
4626  }
4627 
4628  // TODO: This check should probably be in QueryAccess().
4629  ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, RegionInfo.RegionSizeX / 2, RegionInfo.RegionSizeY / 2);
4630  if (nearestParcel == null)
4631  {
4632  m_log.InfoFormat(
4633  "[SCENE]: Denying root agent entry to {0} in {1}: no allowed parcel",
4634  cAgentData.AgentID, RegionInfo.RegionName);
4635 
4636  return false;
4637  }
4638 
4639  // We have to wait until the viewer contacts this region
4640  // after receiving the EnableSimulator HTTP Event Queue message (for the v1 teleport protocol)
4641  // or TeleportFinish (for the v2 teleport protocol). This triggers the viewer to send
4642  // a UseCircuitCode packet which in turn calls AddNewAgent which finally creates the ScenePresence.
4643  ScenePresence sp = WaitGetScenePresence(cAgentData.AgentID);
4644 
4645  if (sp != null)
4646  {
4647  if (!sp.IsChildAgent)
4648  {
4649  m_log.WarnFormat("[SCENE]: Ignoring a child update on a root agent {0} {1} in {2}",
4650  sp.Name, sp.UUID, Name);
4651  return false;
4652  }
4653  if (cAgentData.SessionID != sp.ControllingClient.SessionId)
4654  {
4655  m_log.WarnFormat(
4656  "[SCENE]: Attempt to update agent {0} with invalid session id {1} (possibly from simulator in older version; tell them to update).",
4657  sp.UUID, cAgentData.SessionID);
4658 
4659  Console.WriteLine(String.Format("[SCENE]: Attempt to update agent {0} ({1}) with invalid session id {2}",
4660  sp.UUID, sp.ControllingClient.SessionId, cAgentData.SessionID));
4661  }
4662 
4663  sp.UpdateChildAgent(cAgentData);
4664 
4665  int ntimes = 20;
4666  if (cAgentData.SenderWantsToWaitForRoot)
4667  {
4668  while (sp.IsChildAgent && ntimes-- > 0)
4669  Thread.Sleep(1000);
4670 
4671  if (sp.IsChildAgent)
4672  m_log.WarnFormat(
4673  "[SCENE]: Found presence {0} {1} unexpectedly still child in {2}",
4674  sp.Name, sp.UUID, Name);
4675  else
4676  m_log.InfoFormat(
4677  "[SCENE]: Found presence {0} {1} as root in {2} after {3} waits",
4678  sp.Name, sp.UUID, Name, 20 - ntimes);
4679 
4680  if (sp.IsChildAgent)
4681  return false;
4682  }
4683 
4684  return true;
4685  }
4686 
4687  return false;
4688  }
4689 
4696  public virtual bool IncomingUpdateChildAgent(AgentPosition cAgentData)
4697  {
4698 // m_log.DebugFormat(
4699 // "[SCENE PRESENCE]: IncomingChildAgentDataUpdate POSITION for {0} in {1}, position {2}",
4700 // cAgentData.AgentID, Name, cAgentData.Position);
4701 
4702  ScenePresence childAgentUpdate = GetScenePresence(cAgentData.AgentID);
4703  if (childAgentUpdate != null)
4704  {
4705 // if (childAgentUpdate.ControllingClient.SessionId != cAgentData.SessionID)
4706 // // Only warn for now
4707 // m_log.WarnFormat("[SCENE]: Attempt at updating position of agent {0} with invalid session id {1}. Neighbor running older version?",
4708 // childAgentUpdate.UUID, cAgentData.SessionID);
4709 
4710  // I can't imagine *yet* why we would get an update if the agent is a root agent..
4711  // however to avoid a race condition crossing borders..
4712  if (childAgentUpdate.IsChildAgent)
4713  {
4714  uint rRegionX = (uint)(cAgentData.RegionHandle >> 40);
4715  uint rRegionY = (((uint)(cAgentData.RegionHandle)) >> 8);
4716  uint tRegionX = RegionInfo.RegionLocX;
4717  uint tRegionY = RegionInfo.RegionLocY;
4718  //Send Data to ScenePresence
4719  childAgentUpdate.UpdateChildAgent(cAgentData, tRegionX, tRegionY, rRegionX, rRegionY);
4720  // Not Implemented:
4721  //TODO: Do we need to pass the message on to one of our neighbors?
4722  }
4723 
4724  return true;
4725  }
4726 
4727  return false;
4728  }
4729 
4735  protected virtual ScenePresence WaitGetScenePresence(UUID agentID)
4736  {
4737  int ntimes = 30;
4738  ScenePresence sp = null;
4739  while ((sp = GetScenePresence(agentID)) == null && (ntimes-- > 0))
4740  Thread.Sleep(1000);
4741 
4742  if (sp == null)
4743  m_log.WarnFormat(
4744  "[SCENE PRESENCE]: Did not find presence with id {0} in {1} before timeout",
4745  agentID, RegionInfo.RegionName);
4746 
4747  return sp;
4748  }
4749 
4757  public bool CloseAgent(UUID agentID, bool force, string auth_token)
4758  {
4759  //m_log.DebugFormat("[SCENE]: Processing incoming close agent {0} in region {1} with auth_token {2}", agentID, RegionInfo.RegionName, auth_token);
4760 
4761  // Check that the auth_token is valid
4762  AgentCircuitData acd = AuthenticateHandler.GetAgentCircuitData(agentID);
4763 
4764  if (acd == null)
4765  {
4766  m_log.DebugFormat(
4767  "[SCENE]: Request to close agent {0} but no such agent in scene {1}. May have been closed previously.",
4768  agentID, Name);
4769 
4770  return false;
4771  }
4772 
4773  if (acd.SessionID.ToString() == auth_token)
4774  {
4775  return CloseAgent(agentID, force);
4776  }
4777  else
4778  {
4779  m_log.WarnFormat(
4780  "[SCENE]: Request to close agent {0} with invalid authorization token {1} in {2}",
4781  agentID, auth_token, Name);
4782  }
4783 
4784  return false;
4785  }
4786 
4787 // public bool IncomingCloseAgent(UUID agentID)
4788 // {
4789 // return IncomingCloseAgent(agentID, false);
4790 // }
4791 
4792 // public bool IncomingCloseChildAgent(UUID agentID)
4793 // {
4794 // return IncomingCloseAgent(agentID, true);
4795 // }
4796 
4808  {
4809  lock (m_removeClientLock)
4810  {
4811  // We need to avoid a race condition where in, for example, an A B C D region layout, an avatar may
4812  // teleport from A -> D, but then -> C before A has asked B to close its old child agent. We do not
4813  // want to obey this close since C may have renewed the child agent lease on B.
4814  if (sp.DoNotCloseAfterTeleport)
4815  {
4816  m_log.DebugFormat(
4817  "[SCENE]: Not pre-closing {0} agent {1} in {2} since another simulator has re-established the child connection",
4818  sp.IsChildAgent ? "child" : "root", sp.Name, Name);
4819 
4820  // Need to reset the flag so that a subsequent close after another teleport can succeed.
4821  sp.DoNotCloseAfterTeleport = false;
4822 
4823  return false;
4824  }
4825 
4826  if (sp.LifecycleState != ScenePresenceState.Running)
4827  {
4828  m_log.DebugFormat(
4829  "[SCENE]: Called IncomingPreCloseAgent() for {0} in {1} but presence is already in state {2}",
4830  sp.Name, Name, sp.LifecycleState);
4831 
4832  return false;
4833  }
4834 
4835  sp.LifecycleState = ScenePresenceState.PreRemove;
4836 
4837  return true;
4838  }
4839  }
4840 
4849  public override bool CloseAgent(UUID agentID, bool force)
4850  {
4851  ScenePresence sp;
4852 
4853  lock (m_removeClientLock)
4854  {
4855  sp = GetScenePresence(agentID);
4856 
4857  if (sp == null)
4858  {
4859  // If there is no scene presence, we may be handling a dead
4860  // client. These can keep an avatar from reentering a region
4861  // and since they don't get cleaned up they will stick
4862  // around until region restart. So, if there is no SP,
4863  // remove the client as well.
4864  IClientAPI client = null;
4865  if (m_clientManager.TryGetValue(agentID, out client))
4866  {
4867  m_clientManager.Remove(agentID);
4868  if (CapsModule != null)
4869  CapsModule.RemoveCaps(agentID, 0);
4870  m_log.DebugFormat( "[SCENE]: Dead client for agent ID {0} was cleaned up in {1}", agentID, Name);
4871  return true;
4872  }
4873  m_log.DebugFormat(
4874  "[SCENE]: Called CloseClient() with agent ID {0} but no such presence is in {1}",
4875  agentID, Name);
4876 
4877  return false;
4878  }
4879 
4880  if (sp.LifecycleState != ScenePresenceState.Running && sp.LifecycleState != ScenePresenceState.PreRemove)
4881  {
4882  m_log.DebugFormat(
4883  "[SCENE]: Called CloseClient() for {0} in {1} but presence is already in state {2}",
4884  sp.Name, Name, sp.LifecycleState);
4885 
4886  return false;
4887  }
4888 
4889  // We need to avoid a race condition where in, for example, an A B C D region layout, an avatar may
4890  // teleport from A -> D, but then -> C before A has asked B to close its old child agent. We do not
4891  // want to obey this close since C may have renewed the child agent lease on B.
4892  if (sp.DoNotCloseAfterTeleport)
4893  {
4894  m_log.DebugFormat(
4895  "[SCENE]: Not closing {0} agent {1} in {2} since another simulator has re-established the child connection",
4896  sp.IsChildAgent ? "child" : "root", sp.Name, Name);
4897 
4898  // Need to reset the flag so that a subsequent close after another teleport can succeed.
4899  sp.DoNotCloseAfterTeleport = false;
4900 
4901  return false;
4902  }
4903 
4904  sp.LifecycleState = ScenePresenceState.Removing;
4905  }
4906 
4907  if (sp != null)
4908  {
4909  sp.ControllingClient.Close(force, force);
4910  return true;
4911  }
4912 
4913  return true;
4914  }
4915 
4927  public void RequestTeleportLocation(IClientAPI remoteClient, string regionName, Vector3 position,
4928  Vector3 lookat, uint teleportFlags)
4929  {
4930  GridRegion region = GridService.GetRegionByName(RegionInfo.ScopeID, regionName);
4931 
4932  if (region == null)
4933  {
4934  // can't find the region: Tell viewer and abort
4935  remoteClient.SendTeleportFailed("The region '" + regionName + "' could not be found.");
4936  return;
4937  }
4938 
4939  RequestTeleportLocation(remoteClient, region.RegionHandle, position, lookat, teleportFlags);
4940  }
4941 
4950  public void RequestTeleportLocation(IClientAPI remoteClient, ulong regionHandle, Vector3 position,
4951  Vector3 lookAt, uint teleportFlags)
4952  {
4953  ScenePresence sp = GetScenePresence(remoteClient.AgentId);
4954  if (sp != null)
4955  {
4956  if (EntityTransferModule != null)
4957  {
4958  EntityTransferModule.Teleport(sp, regionHandle, position, lookAt, teleportFlags);
4959  }
4960  else
4961  {
4962  m_log.DebugFormat("[SCENE]: Unable to perform teleports: no AgentTransferModule is active");
4963  sp.ControllingClient.SendTeleportFailed("Unable to perform teleports on this simulator.");
4964  }
4965  }
4966  }
4967 
4968  public bool CrossAgentToNewRegion(ScenePresence agent, bool isFlying)
4969  {
4970  if (EntityTransferModule != null)
4971  {
4972  return EntityTransferModule.Cross(agent, isFlying);
4973  }
4974  else
4975  {
4976  m_log.DebugFormat("[SCENE]: Unable to cross agent to neighbouring region, because there is no AgentTransferModule");
4977  }
4978 
4979  return false;
4980  }
4981 
4983  {
4984  m_sceneGridService.SendChildAgentDataUpdate(cadu, presence);
4985  }
4986 
4987  #endregion
4988 
4989  #region Other Methods
4990 
4991  protected override IConfigSource GetConfig()
4992  {
4993  return m_config;
4994  }
4995 
4996  #endregion
4997 
4998  public void HandleObjectPermissionsUpdate(IClientAPI controller, UUID agentID, UUID sessionID, byte field, uint localId, uint mask, byte set)
4999  {
5000  // Check for spoofing.. since this is permissions we're talking about here!
5001  if ((controller.SessionId == sessionID) && (controller.AgentId == agentID))
5002  {
5003  // Tell the object to do permission update
5004  if (localId != 0)
5005  {
5006  SceneObjectGroup chObjectGroup = GetGroupByPrim(localId);
5007  if (chObjectGroup != null)
5008  {
5009  chObjectGroup.UpdatePermissions(agentID, field, localId, mask, set);
5010  }
5011  }
5012  }
5013  }
5014 
5018  public void ForceClientUpdate()
5019  {
5020  EntityBase[] entityList = GetEntities();
5021  foreach (EntityBase ent in entityList)
5022  {
5023  if (ent is SceneObjectGroup)
5024  {
5025  ((SceneObjectGroup)ent).ScheduleGroupForFullUpdate();
5026  }
5027  }
5028  }
5029 
5035  public void HandleEditCommand(string[] cmdparams)
5036  {
5037  m_log.DebugFormat("Searching for Primitive: '{0}'", cmdparams[2]);
5038 
5039  EntityBase[] entityList = GetEntities();
5040  foreach (EntityBase ent in entityList)
5041  {
5042  if (ent is SceneObjectGroup)
5043  {
5044  SceneObjectPart part = ((SceneObjectGroup)ent).GetPart(((SceneObjectGroup)ent).UUID);
5045  if (part != null)
5046  {
5047  if (part.Name == cmdparams[2])
5048  {
5049  part.Resize(
5050  new Vector3(Convert.ToSingle(cmdparams[3]), Convert.ToSingle(cmdparams[4]),
5051  Convert.ToSingle(cmdparams[5])));
5052 
5053  m_log.DebugFormat("Edited scale of Primitive: {0}", part.Name);
5054  }
5055  }
5056  }
5057  }
5058  }
5059 
5060  #region Script Handling Methods
5061 
5066  public void SendCommandToPlugins(string[] args)
5067  {
5068  m_eventManager.TriggerOnPluginConsole(args);
5069  }
5070 
5071  public LandData GetLandData(float x, float y)
5072  {
5073  ILandObject parcel = LandChannel.GetLandObject(x, y);
5074  if (parcel == null)
5075  return null;
5076  return parcel.LandData;
5077  }
5078 
5084  public LandData GetLandData(Vector3 pos)
5085  {
5086  return GetLandData(pos.X, pos.Y);
5087  }
5088 
5089  public LandData GetLandData(uint x, uint y)
5090  {
5091  m_log.DebugFormat("[SCENE]: returning land for {0},{1}", x, y);
5092  ILandObject parcel = LandChannel.GetLandObject((int)x, (int)y);
5093  if (parcel == null)
5094  return null;
5095  return parcel.LandData;
5096  }
5097 
5098  #endregion
5099 
5100  #region Script Engine
5101 
5102  private bool ScriptDanger(SceneObjectPart part, Vector3 pos)
5103  {
5104  ILandObject parcel = LandChannel.GetLandObject(pos.X, pos.Y);
5105  if (part != null)
5106  {
5107  if (parcel != null)
5108  {
5109  if ((parcel.LandData.Flags & (uint)ParcelFlags.AllowOtherScripts) != 0)
5110  {
5111  return true;
5112  }
5113  else if ((part.OwnerID == parcel.LandData.OwnerID) || Permissions.IsGod(part.OwnerID))
5114  {
5115  return true;
5116  }
5117  else if (((parcel.LandData.Flags & (uint)ParcelFlags.AllowGroupScripts) != 0)
5118  && (parcel.LandData.GroupID != UUID.Zero) && (parcel.LandData.GroupID == part.GroupID))
5119  {
5120  return true;
5121  }
5122  else
5123  {
5124  return false;
5125  }
5126  }
5127  else
5128  {
5129 
5130  if (pos.X > 0f && pos.X < RegionInfo.RegionSizeX && pos.Y > 0f && pos.Y < RegionInfo.RegionSizeY)
5131  {
5132  // The only time parcel != null when an object is inside a region is when
5133  // there is nothing behind the landchannel. IE, no land plugin loaded.
5134  return true;
5135  }
5136  else
5137  {
5138  // The object is outside of this region. Stop piping events to it.
5139  return false;
5140  }
5141  }
5142  }
5143  else
5144  {
5145  return false;
5146  }
5147  }
5148 
5149  public bool ScriptDanger(uint localID, Vector3 pos)
5150  {
5151  SceneObjectPart part = GetSceneObjectPart(localID);
5152  if (part != null)
5153  {
5154  return ScriptDanger(part, pos);
5155  }
5156  else
5157  {
5158  return false;
5159  }
5160  }
5161 
5162  public bool PipeEventsForScript(uint localID)
5163  {
5164  SceneObjectPart part = GetSceneObjectPart(localID);
5165 
5166  if (part != null)
5167  {
5168  SceneObjectPart parent = part.ParentGroup.RootPart;
5169  return ScriptDanger(parent, parent.GetWorldPosition());
5170  }
5171  else
5172  {
5173  return false;
5174  }
5175  }
5176 
5177  #endregion
5178 
5179  #region SceneGraph wrapper methods
5180 
5186  public UUID ConvertLocalIDToFullID(uint localID)
5187  {
5188  return m_sceneGraph.ConvertLocalIDToFullID(localID);
5189  }
5190 
5191  public void SwapRootAgentCount(bool rootChildChildRootTF)
5192  {
5193  m_sceneGraph.SwapRootChildAgent(rootChildChildRootTF);
5194  }
5195 
5196  public void AddPhysicalPrim(int num)
5197  {
5198  m_sceneGraph.AddPhysicalPrim(num);
5199  }
5200 
5201  public void RemovePhysicalPrim(int num)
5202  {
5203  m_sceneGraph.RemovePhysicalPrim(num);
5204  }
5205 
5206  public int GetRootAgentCount()
5207  {
5208  return m_sceneGraph.GetRootAgentCount();
5209  }
5210 
5211  public int GetChildAgentCount()
5212  {
5213  return m_sceneGraph.GetChildAgentCount();
5214  }
5215 
5221  public ScenePresence GetScenePresence(UUID agentID)
5222  {
5223  return m_sceneGraph.GetScenePresence(agentID);
5224  }
5225 
5232  public ScenePresence GetScenePresence(string firstName, string lastName)
5233  {
5234  return m_sceneGraph.GetScenePresence(firstName, lastName);
5235  }
5236 
5242  public ScenePresence GetScenePresence(uint localID)
5243  {
5244  return m_sceneGraph.GetScenePresence(localID);
5245  }
5246 
5259  public List<ScenePresence> GetScenePresences()
5260  {
5261  return new List<ScenePresence>(m_sceneGraph.GetScenePresences());
5262  }
5263 
5269  public void ForEachRootScenePresence(Action<ScenePresence> action)
5270  {
5271  m_sceneGraph.ForEachAvatar(action);
5272  }
5273 
5278  public void ForEachScenePresence(Action<ScenePresence> action)
5279  {
5280  m_sceneGraph.ForEachScenePresence(action);
5281  }
5282 
5289  public List<SceneObjectGroup> GetSceneObjectGroups()
5290  {
5291  return m_sceneGraph.GetSceneObjectGroups();
5292  }
5293 
5300  {
5301  return m_sceneGraph.GetSceneObjectGroup(fullID);
5302  }
5303 
5311  {
5312  return m_sceneGraph.GetSceneObjectGroup(localID);
5313  }
5314 
5322  {
5323  return m_sceneGraph.GetSceneObjectGroup(name);
5324  }
5325 
5332  public bool TryGetSceneObjectGroup(UUID fullID, out SceneObjectGroup sog)
5333  {
5334  sog = GetSceneObjectGroup(fullID);
5335  return sog != null;
5336  }
5337 
5345  {
5346  return m_sceneGraph.GetSceneObjectPart(name);
5347  }
5348 
5355  {
5356  return m_sceneGraph.GetSceneObjectPart(localID);
5357  }
5358 
5365  {
5366  return m_sceneGraph.GetSceneObjectPart(fullID);
5367  }
5368 
5375  public bool TryGetSceneObjectPart(UUID fullID, out SceneObjectPart sop)
5376  {
5377  sop = GetSceneObjectPart(fullID);
5378  return sop != null;
5379  }
5380 
5386  public SceneObjectGroup GetGroupByPrim(uint localID)
5387  {
5388  return m_sceneGraph.GetGroupByPrim(localID);
5389  }
5390 
5396  public SceneObjectGroup GetGroupByPrim(UUID fullID)
5397  {
5398  return m_sceneGraph.GetGroupByPrim(fullID);
5399  }
5400 
5401  public override bool TryGetScenePresence(UUID agentID, out ScenePresence sp)
5402  {
5403  return m_sceneGraph.TryGetScenePresence(agentID, out sp);
5404  }
5405 
5406  public bool TryGetAvatarByName(string avatarName, out ScenePresence avatar)
5407  {
5408  return m_sceneGraph.TryGetAvatarByName(avatarName, out avatar);
5409  }
5410 
5415  public void ForEachRootClient(Action<IClientAPI> action)
5416  {
5417  ForEachRootScenePresence(delegate(ScenePresence presence)
5418  {
5419  action(presence.ControllingClient);
5420  });
5421  }
5422 
5427  public void ForEachClient(Action<IClientAPI> action)
5428  {
5429  m_clientManager.ForEachSync(action);
5430  }
5431 
5432  public bool TryGetClient(UUID avatarID, out IClientAPI client)
5433  {
5434  return m_clientManager.TryGetValue(avatarID, out client);
5435  }
5436 
5437  public bool TryGetClient(System.Net.IPEndPoint remoteEndPoint, out IClientAPI client)
5438  {
5439  return m_clientManager.TryGetValue(remoteEndPoint, out client);
5440  }
5441 
5442  public void ForEachSOG(Action<SceneObjectGroup> action)
5443  {
5444  m_sceneGraph.ForEachSOG(action);
5445  }
5446 
5453  {
5454  return m_sceneGraph.GetEntities();
5455  }
5456 
5457  #endregion
5458 
5459 
5460 // Commented pending deletion since this method no longer appears to do anything at all
5461 // public bool NeedSceneCacheClear(UUID agentID)
5462 // {
5463 // IInventoryTransferModule inv = RequestModuleInterface<IInventoryTransferModule>();
5464 // if (inv == null)
5465 // return true;
5466 //
5467 // return inv.NeedSceneCacheClear(agentID, this);
5468 // }
5469 
5470  public void CleanTempObjects()
5471  {
5472  EntityBase[] entities = GetEntities();
5473  foreach (EntityBase obj in entities)
5474  {
5475  if (obj is SceneObjectGroup)
5476  {
5477  SceneObjectGroup grp = (SceneObjectGroup)obj;
5478 
5479  if (!grp.IsDeleted)
5480  {
5481  if ((grp.RootPart.Flags & PrimFlags.TemporaryOnRez) != 0)
5482  {
5483  if (grp.GetSittingAvatarsCount() == 0 && grp.RootPart.Expires <= DateTime.Now)
5484  DeleteSceneObject(grp, false);
5485  }
5486  }
5487  }
5488  }
5489 
5490  }
5491 
5492  public void DeleteFromStorage(UUID uuid)
5493  {
5494  SimulationDataService.RemoveObject(uuid, RegionInfo.RegionID);
5495  }
5496 
5497  public int GetHealth(out int flags, out string message)
5498  {
5499  // Returns:
5500  // 1 = sim is up and accepting http requests. The heartbeat has
5501  // stopped and the sim is probably locked up, but a remote
5502  // admin restart may succeed
5503  //
5504  // 2 = Sim is up and the heartbeat is running. The sim is likely
5505  // usable for people within
5506  //
5507  // 3 = Sim is up and one packet thread is running. Sim is
5508  // unstable and will not accept new logins
5509  //
5510  // 4 = Sim is up and both packet threads are running. Sim is
5511  // likely usable
5512  //
5513  // 5 = We have seen a new user enter within the past 4 minutes
5514  // which can be seen as positive confirmation of sim health
5515  //
5516  int health = 1; // Start at 1, means we're up
5517 
5518  flags = 0;
5519  message = String.Empty;
5520 
5521  CheckHeartbeat();
5522 
5523  if (m_firstHeartbeat || (m_lastIncoming == 0 && m_lastOutgoing == 0))
5524  {
5525  // We're still starting
5526  // 0 means "in startup", it can't happen another way, since
5527  // to get here, we must be able to accept http connections
5528  return 0;
5529  }
5530 
5531  if ((Util.EnvironmentTickCountSubtract(m_lastFrameTick)) < 1000)
5532  {
5533  health+=1;
5534  flags |= 1;
5535  }
5536 
5537  if (Util.EnvironmentTickCountSubtract(m_lastIncoming) < 1000)
5538  {
5539  health+=1;
5540  flags |= 2;
5541  }
5542 
5543  if (Util.EnvironmentTickCountSubtract(m_lastOutgoing) < 1000)
5544  {
5545  health+=1;
5546  flags |= 4;
5547  }
5548  else
5549  {
5550 int pid = System.Diagnostics.Process.GetCurrentProcess().Id;
5551 System.Diagnostics.Process proc = new System.Diagnostics.Process();
5552 proc.EnableRaisingEvents=false;
5553 proc.StartInfo.FileName = "/bin/kill";
5554 proc.StartInfo.Arguments = "-QUIT " + pid.ToString();
5555 proc.Start();
5556 proc.WaitForExit();
5557 Thread.Sleep(1000);
5558 Environment.Exit(1);
5559  }
5560 
5561  if (flags != 7)
5562  return health;
5563 
5564  // A login in the last 4 mins? We can't be doing too badly
5565  //
5566  if (Util.EnvironmentTickCountSubtract(m_LastLogin) < 240000)
5567  health++;
5568  else
5569  return health;
5570 
5571  return health;
5572  }
5573 
5574  // This callback allows the PhysicsScene to call back to its caller (the SceneGraph) and
5575  // update non-physical objects like the joint proxy objects that represent the position
5576  // of the joints in the scene.
5577 
5578  // This routine is normally called from within a lock (OdeLock) from within the OdePhysicsScene
5579  // WARNING: be careful of deadlocks here if you manipulate the scene. Remember you are being called
5580  // from within the OdePhysicsScene.
5581 
5582  protected internal void jointMoved(PhysicsJoint joint)
5583  {
5584  // m_parentScene.PhysicsScene.DumpJointInfo(); // non-thread-locked version; we should already be in a lock (OdeLock) when this callback is invoked
5585  SceneObjectPart jointProxyObject = GetSceneObjectPart(joint.ObjectNameInScene);
5586  if (jointProxyObject == null)
5587  {
5588  jointErrorMessage(joint, "WARNING, joint proxy not found, name " + joint.ObjectNameInScene);
5589  return;
5590  }
5591 
5592  // now update the joint proxy object in the scene to have the position of the joint as returned by the physics engine
5593  SceneObjectPart trackedBody = GetSceneObjectPart(joint.TrackedBodyName); // FIXME: causes a sequential lookup
5594  if (trackedBody == null) return; // the actor may have been deleted but the joint still lingers around a few frames waiting for deletion. during this time, trackedBody is NULL to prevent further motion of the joint proxy.
5595  jointProxyObject.Velocity = trackedBody.Velocity;
5596  jointProxyObject.AngularVelocity = trackedBody.AngularVelocity;
5597  switch (joint.Type)
5598  {
5599  case PhysicsJointType.Ball:
5600  {
5601  Vector3 jointAnchor = PhysicsScene.GetJointAnchor(joint);
5602  Vector3 proxyPos = jointAnchor;
5603  jointProxyObject.ParentGroup.UpdateGroupPosition(proxyPos); // schedules the entire group for a terse update
5604  }
5605  break;
5606 
5607  case PhysicsJointType.Hinge:
5608  {
5609  Vector3 jointAnchor = PhysicsScene.GetJointAnchor(joint);
5610 
5611  // Normally, we would just ask the physics scene to return the axis for the joint.
5612  // Unfortunately, ODE sometimes returns <0,0,0> for the joint axis, which should
5613  // never occur. Therefore we cannot rely on ODE to always return a correct joint axis.
5614  // Therefore the following call does not always work:
5615  //PhysicsVector phyJointAxis = _PhyScene.GetJointAxis(joint);
5616 
5617  // instead we compute the joint orientation by saving the original joint orientation
5618  // relative to one of the jointed bodies, and applying this transformation
5619  // to the current position of the jointed bodies (the tracked body) to compute the
5620  // current joint orientation.
5621 
5622  if (joint.TrackedBodyName == null)
5623  {
5624  jointErrorMessage(joint, "joint.TrackedBodyName is null, joint " + joint.ObjectNameInScene);
5625  }
5626 
5627  Vector3 proxyPos = jointAnchor;
5628  Quaternion q = trackedBody.RotationOffset * joint.LocalRotation;
5629 
5630  jointProxyObject.ParentGroup.UpdateGroupPosition(proxyPos); // schedules the entire group for a terse update
5631  jointProxyObject.ParentGroup.UpdateGroupRotationR(q); // schedules the entire group for a terse update
5632  }
5633  break;
5634  }
5635  }
5636 
5637  // This callback allows the PhysicsScene to call back to its caller (the SceneGraph) and
5638  // update non-physical objects like the joint proxy objects that represent the position
5639  // of the joints in the scene.
5640 
5641  // This routine is normally called from within a lock (OdeLock) from within the OdePhysicsScene
5642  // WARNING: be careful of deadlocks here if you manipulate the scene. Remember you are being called
5643  // from within the OdePhysicsScene.
5644  protected internal void jointDeactivated(PhysicsJoint joint)
5645  {
5646  //m_log.Debug("[NINJA] SceneGraph.jointDeactivated, joint:" + joint.ObjectNameInScene);
5647  SceneObjectPart jointProxyObject = GetSceneObjectPart(joint.ObjectNameInScene);
5648  if (jointProxyObject == null)
5649  {
5650  jointErrorMessage(joint, "WARNING, trying to deactivate (stop interpolation of) joint proxy, but not found, name " + joint.ObjectNameInScene);
5651  return;
5652  }
5653 
5654  // turn the proxy non-physical, which also stops its client-side interpolation
5655  bool wasUsingPhysics = ((jointProxyObject.Flags & PrimFlags.Physics) != 0);
5656  if (wasUsingPhysics)
5657  {
5658  jointProxyObject.UpdatePrimFlags(false, false, true, false,false); // FIXME: possible deadlock here; check to make sure all the scene alterations set into motion here won't deadlock
5659  }
5660  }
5661 
5662  // This callback allows the PhysicsScene to call back to its caller (the SceneGraph) and
5663  // alert the user of errors by using the debug channel in the same way that scripts alert
5664  // the user of compile errors.
5665 
5666  // This routine is normally called from within a lock (OdeLock) from within the OdePhysicsScene
5667  // WARNING: be careful of deadlocks here if you manipulate the scene. Remember you are being called
5668  // from within the OdePhysicsScene.
5669  public void jointErrorMessage(PhysicsJoint joint, string message)
5670  {
5671  if (joint != null)
5672  {
5674  return;
5675 
5676  SceneObjectPart jointProxyObject = GetSceneObjectPart(joint.ObjectNameInScene);
5677  if (jointProxyObject != null)
5678  {
5679  SimChat(Utils.StringToBytes("[NINJA]: " + message),
5680  ChatTypeEnum.DebugChannel,
5681  2147483647,
5682  jointProxyObject.AbsolutePosition,
5683  jointProxyObject.Name,
5684  jointProxyObject.UUID,
5685  false);
5686 
5687  joint.ErrorMessageCount++;
5688 
5690  {
5691  SimChat(Utils.StringToBytes("[NINJA]: Too many messages for this joint, suppressing further messages."),
5692  ChatTypeEnum.DebugChannel,
5693  2147483647,
5694  jointProxyObject.AbsolutePosition,
5695  jointProxyObject.Name,
5696  jointProxyObject.UUID,
5697  false);
5698  }
5699  }
5700  else
5701  {
5702  // couldn't find the joint proxy object; the error message is silently suppressed
5703  }
5704  }
5705  }
5706 
5708  {
5709  if (MainConsole.Instance == null)
5710  return null;
5712  return (Scene)MainConsole.Instance.ConsoleScene;
5713  return null;
5714  }
5715 
5716  // Get terrain height at the specified <x,y> location.
5717  // Presumes the underlying implementation is a heightmap which is a 1m grid.
5718  // Finds heightmap grid points before and after the point and
5719  // does a linear approximation of the height at this intermediate point.
5720  public float GetGroundHeight(float x, float y)
5721  {
5722  if (x < 0)
5723  x = 0;
5724  if (x >= Heightmap.Width)
5725  x = Heightmap.Width - 1;
5726  if (y < 0)
5727  y = 0;
5728  if (y >= Heightmap.Height)
5729  y = Heightmap.Height - 1;
5730 
5731  Vector3 p0 = new Vector3(x, y, (float)Heightmap[(int)x, (int)y]);
5732  Vector3 p1 = p0;
5733  Vector3 p2 = p0;
5734 
5735  p1.X += 1.0f;
5736  if (p1.X < Heightmap.Width)
5737  p1.Z = (float)Heightmap[(int)p1.X, (int)p1.Y];
5738 
5739  p2.Y += 1.0f;
5740  if (p2.Y < Heightmap.Height)
5741  p2.Z = (float)Heightmap[(int)p2.X, (int)p2.Y];
5742 
5743  Vector3 v0 = new Vector3(p1.X - p0.X, p1.Y - p0.Y, p1.Z - p0.Z);
5744  Vector3 v1 = new Vector3(p2.X - p0.X, p2.Y - p0.Y, p2.Z - p0.Z);
5745 
5746  v0.Normalize();
5747  v1.Normalize();
5748 
5749  Vector3 vsn = new Vector3();
5750  vsn.X = (v0.Y * v1.Z) - (v0.Z * v1.Y);
5751  vsn.Y = (v0.Z * v1.X) - (v0.X * v1.Z);
5752  vsn.Z = (v0.X * v1.Y) - (v0.Y * v1.X);
5753  vsn.Normalize();
5754 
5755  float xdiff = x - (float)((int)x);
5756  float ydiff = y - (float)((int)y);
5757 
5758  return (((vsn.X * xdiff) + (vsn.Y * ydiff)) / (-1 * vsn.Z)) + p0.Z;
5759  }
5760 
5761  private void CheckHeartbeat()
5762  {
5763  if (m_firstHeartbeat)
5764  return;
5765 
5766  if ((Util.EnvironmentTickCountSubtract(m_lastFrameTick)) > 5000)
5767  Start();
5768  }
5769 
5770  public override ISceneObject DeserializeObject(string representation)
5771  {
5772  return SceneObjectSerializer.FromXml2Format(representation);
5773  }
5774 
5775  public override bool AllowScriptCrossings
5776  {
5777  get { return m_allowScriptCrossings; }
5778  }
5779 
5781  {
5782  return GetNearestAllowedPosition(avatar, null);
5783  }
5784 
5785  public Vector3 GetNearestAllowedPosition(ScenePresence avatar, ILandObject excludeParcel)
5786  {
5787  Vector3 pos = avatar.AbsolutePosition;
5788 
5789  ILandObject nearestParcel = GetNearestAllowedParcel(avatar.UUID, pos.X, pos.Y, excludeParcel);
5790 
5791  if (nearestParcel != null)
5792  {
5793  Vector2? nearestPoint = null;
5794  Vector3 dir = -avatar.Velocity;
5795  float dirlen = dir.Length();
5796  if(dirlen > 1.0f)
5797  //Try to get a location that feels like where they came from
5798  nearestPoint = nearestParcel.GetNearestPointAlongDirection(pos, dir);
5799 
5800  if (nearestPoint == null)
5801  nearestPoint = nearestParcel.GetNearestPoint(pos);
5802 
5803  if (nearestPoint != null)
5804  {
5805  return GetPositionAtAvatarHeightOrGroundHeight(avatar,
5806  nearestPoint.Value.X, nearestPoint.Value.Y);
5807  }
5808 
5809  ILandObject dest = LandChannel.GetLandObject(avatar.lastKnownAllowedPosition.X, avatar.lastKnownAllowedPosition.Y);
5810  if (dest != excludeParcel)
5811  {
5812  // Ultimate backup if we have no idea where they are and
5813  // the last allowed position was in another parcel
5814  m_log.Debug("Have no idea where they are, sending them to: " + avatar.lastKnownAllowedPosition.ToString());
5815  return avatar.lastKnownAllowedPosition;
5816  }
5817 
5818  // else fall through to region edge
5819  }
5820 
5821  //Go to the edge, this happens in teleporting to a region with no available parcels
5822  Vector3 nearestRegionEdgePoint = GetNearestRegionEdgePosition(avatar);
5823 
5824  //Debug.WriteLine("They are really in a place they don't belong, sending them to: " + nearestRegionEdgePoint.ToString());
5825  return nearestRegionEdgePoint;
5826  }
5827 
5828  private Vector3 GetParcelCenterAtGround(ILandObject parcel)
5829  {
5830  Vector2 center = parcel.CenterPoint;
5831  return GetPositionAtGround(center.X, center.Y);
5832  }
5833 
5834  public ILandObject GetNearestAllowedParcel(UUID avatarId, float x, float y)
5835  {
5836  return GetNearestAllowedParcel(avatarId, x, y, null);
5837  }
5838 
5839  public ILandObject GetNearestAllowedParcel(UUID avatarId, float x, float y, ILandObject excludeParcel)
5840  {
5841  if(LandChannel == null)
5842  return null;
5843 
5844  List<ILandObject> all = LandChannel.AllParcels();
5845 
5846  if(all == null || all.Count == 0)
5847  return null;
5848 
5849  float minParcelDistanceSQ = float.MaxValue;
5850  ILandObject nearestParcel = null;
5851  Vector2 curCenter;
5852  float parcelDistanceSQ;
5853 
5854  foreach (var parcel in all)
5855  {
5856  if (parcel != excludeParcel && !parcel.IsEitherBannedOrRestricted(avatarId))
5857  {
5858  curCenter = parcel.CenterPoint;
5859  curCenter.X -= x;
5860  curCenter.Y -= y;
5861  parcelDistanceSQ = curCenter.LengthSquared();
5862  if (parcelDistanceSQ < minParcelDistanceSQ)
5863  {
5864  minParcelDistanceSQ = parcelDistanceSQ;
5865  nearestParcel = parcel;
5866  }
5867  }
5868  }
5869 
5870  return nearestParcel;
5871  }
5872 
5873  private Vector2 GetParcelSafeCorner(ILandObject parcel)
5874  {
5875  Vector2 place = parcel.StartPoint;
5876  place.X += 2f;
5877  place.Y += 2f;
5878  return place;
5879  }
5880 
5881  private Vector3 GetNearestRegionEdgePosition(ScenePresence avatar)
5882  {
5883  float posX = avatar.AbsolutePosition.X;
5884  float posY = avatar.AbsolutePosition.Y;
5885  float regionSizeX = RegionInfo.RegionSizeX;
5886  float halfRegionSizeX = regionSizeX * 0.5f;
5887  float regionSizeY = RegionInfo.RegionSizeY;
5888  float halfRegionSizeY = regionSizeY * 0.5f;
5889 
5890  float xdistance = posX < halfRegionSizeX ? posX : regionSizeX - posX;
5891  float ydistance = posY < halfRegionSizeY ? posY : regionSizeY - posY;
5892 
5893  //find out what vertical edge to go to
5894  if (xdistance < ydistance)
5895  {
5896  if (posX < halfRegionSizeX)
5897  return GetPositionAtAvatarHeightOrGroundHeight(avatar, 0.5f, posY);
5898  else
5899  return GetPositionAtAvatarHeightOrGroundHeight(avatar, regionSizeX - 0.5f, posY);
5900  }
5901  //find out what horizontal edge to go to
5902  else
5903  {
5904  if (posY < halfRegionSizeY)
5905  return GetPositionAtAvatarHeightOrGroundHeight(avatar, posX, 0.5f);
5906  else
5907  return GetPositionAtAvatarHeightOrGroundHeight(avatar, posX, regionSizeY - 0.5f);
5908  }
5909  }
5910 
5911  private Vector3 GetPositionAtAvatarHeightOrGroundHeight(ScenePresence avatar, float x, float y)
5912  {
5913  Vector3 ground = GetPositionAtGround(x, y);
5914  if(avatar.Appearance != null)
5915  ground.Z += avatar.Appearance.AvatarHeight * 0.5f;
5916  else
5917  ground.Z += 0.8f;
5918 
5919  if (avatar.AbsolutePosition.Z > ground.Z)
5920  {
5921  ground.Z = avatar.AbsolutePosition.Z;
5922  }
5923  return ground;
5924  }
5925 
5926  private Vector3 GetPositionAtGround(float x, float y)
5927  {
5928  return new Vector3(x, y, GetGroundHeight(x, y));
5929  }
5930 
5931  public List<UUID> GetEstateRegions(int estateID)
5932  {
5933  IEstateDataService estateDataService = EstateDataService;
5934  if (estateDataService == null)
5935  return new List<UUID>(0);
5936 
5937  return estateDataService.GetRegions(estateID);
5938  }
5939 
5940  public void ReloadEstateData()
5941  {
5942  IEstateDataService estateDataService = EstateDataService;
5943  if (estateDataService != null)
5944  {
5945  RegionInfo.EstateSettings = estateDataService.LoadEstateSettings(RegionInfo.RegionID, false);
5946  TriggerEstateSunUpdate();
5947  }
5948  }
5949 
5951  {
5952  EventManager.TriggerEstateToolsSunUpdate(RegionInfo.RegionHandle);
5953  }
5954 
5955  private void HandleReloadEstate(string module, string[] cmd)
5956  {
5957  if (MainConsole.Instance.ConsoleScene == null ||
5960  {
5961  ReloadEstateData();
5962  }
5963  }
5964 
5976  public static Vector3[] GetCombinedBoundingBox(
5977  List<SceneObjectGroup> objects,
5978  out float minX, out float maxX, out float minY, out float maxY, out float minZ, out float maxZ)
5979  {
5980  minX = float.MaxValue;
5981  maxX = float.MinValue;
5982  minY = float.MaxValue;
5983  maxY = float.MinValue;
5984  minZ = float.MaxValue;
5985  maxZ = float.MinValue;
5986 
5987  List<Vector3> offsets = new List<Vector3>();
5988 
5989  foreach (SceneObjectGroup g in objects)
5990  {
5991  float ominX, ominY, ominZ, omaxX, omaxY, omaxZ;
5992 
5993  Vector3 vec = g.AbsolutePosition;
5994 
5995  g.GetAxisAlignedBoundingBoxRaw(out ominX, out omaxX, out ominY, out omaxY, out ominZ, out omaxZ);
5996 
5997 // m_log.DebugFormat(
5998 // "[SCENE]: For {0} found AxisAlignedBoundingBoxRaw {1}, {2}",
5999 // g.Name, new Vector3(ominX, ominY, ominZ), new Vector3(omaxX, omaxY, omaxZ));
6000 
6001  ominX += vec.X;
6002  omaxX += vec.X;
6003  ominY += vec.Y;
6004  omaxY += vec.Y;
6005  ominZ += vec.Z;
6006  omaxZ += vec.Z;
6007 
6008  if (minX > ominX)
6009  minX = ominX;
6010  if (minY > ominY)
6011  minY = ominY;
6012  if (minZ > ominZ)
6013  minZ = ominZ;
6014  if (maxX < omaxX)
6015  maxX = omaxX;
6016  if (maxY < omaxY)
6017  maxY = omaxY;
6018  if (maxZ < omaxZ)
6019  maxZ = omaxZ;
6020  }
6021 
6022  foreach (SceneObjectGroup g in objects)
6023  {
6024  Vector3 vec = g.AbsolutePosition;
6025  vec.X -= minX;
6026  vec.Y -= minY;
6027  vec.Z -= minZ;
6028 
6029  offsets.Add(vec);
6030  }
6031 
6032  return offsets.ToArray();
6033  }
6034 
6040  private void RegenerateMaptile()
6041  {
6042  IWorldMapModule mapModule = RequestModuleInterface<IWorldMapModule>();
6043  if (mapModule != null)
6044  mapModule.GenerateMaptile();
6045  }
6046 
6047 // public void CleanDroppedAttachments()
6048 // {
6049 // List<SceneObjectGroup> objectsToDelete =
6050 // new List<SceneObjectGroup>();
6051 //
6052 // lock (m_cleaningAttachments)
6053 // {
6054 // ForEachSOG(delegate (SceneObjectGroup grp)
6055 // {
6056 // if (grp.RootPart.Shape.PCode == 0 && grp.RootPart.Shape.State != 0 && (!objectsToDelete.Contains(grp)))
6057 // {
6058 // UUID agentID = grp.OwnerID;
6059 // if (agentID == UUID.Zero)
6060 // {
6061 // objectsToDelete.Add(grp);
6062 // return;
6063 // }
6064 //
6065 // ScenePresence sp = GetScenePresence(agentID);
6066 // if (sp == null)
6067 // {
6068 // objectsToDelete.Add(grp);
6069 // return;
6070 // }
6071 // }
6072 // });
6073 // }
6074 //
6075 // foreach (SceneObjectGroup grp in objectsToDelete)
6076 // {
6077 // m_log.InfoFormat("[SCENE]: Deleting dropped attachment {0} of user {1}", grp.UUID, grp.OwnerID);
6078 // DeleteSceneObject(grp, true);
6079 // }
6080 // }
6081 
6082  public void ThreadAlive(int threadCode)
6083  {
6084  switch(threadCode)
6085  {
6086  case 1: // Incoming
6087  m_lastIncoming = Util.EnvironmentTickCount();
6088  break;
6089  case 2: // Incoming
6090  m_lastOutgoing = Util.EnvironmentTickCount();
6091  break;
6092  }
6093  }
6094 
6095  public void RegenerateMaptileAndReregister(object sender, ElapsedEventArgs e)
6096  {
6097  RegenerateMaptile();
6098 
6099  // We need to propagate the new image UUID to the grid service
6100  // so that all simulators can retrieve it
6101  string error = GridService.RegisterRegion(RegionInfo.ScopeID, new GridRegion(RegionInfo));
6102  if (error != string.Empty)
6103  throw new Exception(error);
6104  }
6105 
6122  public bool QueryAccess(UUID agentID, string agentHomeURI, bool viaTeleport, Vector3 position, List<UUID> features, out string reason)
6123  {
6124  reason = string.Empty;
6125 
6126  if (Permissions.IsGod(agentID))
6127  return true;
6128 
6129  if (!AllowAvatarCrossing && !viaTeleport)
6130  {
6131  reason = "Region Crossing not allowed";
6132  return false;
6133  }
6134 
6135  bool isAdmin = Permissions.IsAdministrator(agentID);
6136  bool isManager = Permissions.IsEstateManager(agentID);
6137 
6138  // FIXME: Root agent count is currently known to be inaccurate. This forces a recount before we check.
6139  // However, the long term fix is to make sure root agent count is always accurate.
6140  m_sceneGraph.RecalculateStats();
6141 
6142  int num = m_sceneGraph.GetRootAgentCount();
6143 
6145  {
6146  if (!(isAdmin || isManager))
6147  {
6148  reason = "The region is full";
6149 
6150  m_log.DebugFormat(
6151  "[SCENE]: Denying presence with id {0} entry into {1} since region is at agent limit of {2}",
6152  agentID, RegionInfo.RegionName, RegionInfo.RegionSettings.AgentLimit);
6153 
6154  return false;
6155  }
6156  }
6157 
6158  ScenePresence presence = GetScenePresence(agentID);
6159  IClientAPI client = null;
6160  AgentCircuitData aCircuit = null;
6161 
6162  if (presence != null)
6163  {
6164  client = presence.ControllingClient;
6165  if (client != null)
6166  aCircuit = client.RequestClientInfo();
6167  }
6168 
6169  // We may be called before there is a presence or a client.
6170  // Fake AgentCircuitData to keep IAuthorizationModule smiling
6171  if (client == null)
6172  {
6173  aCircuit = new AgentCircuitData();
6174  aCircuit.AgentID = agentID;
6175  aCircuit.firstname = String.Empty;
6176  aCircuit.lastname = String.Empty;
6177  }
6178 
6179  try
6180  {
6181  if (!AuthorizeUser(aCircuit, false, out reason))
6182  {
6183  //m_log.DebugFormat("[SCENE]: Denying access for {0}", agentID);
6184 // reason = "Region authorization fail";
6185  return false;
6186  }
6187  }
6188  catch (Exception e)
6189  {
6190  m_log.DebugFormat("[SCENE]: Exception authorizing agent: {0} " + e.StackTrace, e.Message);
6191  reason = "Error authorizing agent: " + e.Message;
6192  return false;
6193  }
6194 
6195  // last check aditional land access restrictions and relocations
6196  // if crossing (viaTeleport false) check only the specified parcel
6197  return CheckLandPositionAccess(agentID, viaTeleport, true, position, out reason);
6198  }
6199 
6200  // check access to land.
6201  public bool CheckLandPositionAccess(UUID agentID, bool NotCrossing, bool checkTeleHub, Vector3 position, out string reason)
6202  {
6203  reason = string.Empty;
6204 
6205  if (Permissions.IsGod(agentID))
6206  return true;
6207 
6208  bool isAdmin = Permissions.IsAdministrator(agentID);
6209  if(isAdmin)
6210  return true;
6211 
6212  // also honor estate managers access rights
6213  bool isManager = Permissions.IsEstateManager(agentID);
6214  if(isManager)
6215  return true;
6216 
6217  if (NotCrossing)
6218  {
6220  {
6221  SceneObjectGroup telehub;
6222  if (RegionInfo.RegionSettings.TelehubObject != UUID.Zero && (telehub = GetSceneObjectGroup (RegionInfo.RegionSettings.TelehubObject)) != null && checkTeleHub)
6223  {
6224  bool banned = true;
6225  bool validTelehub = false;
6226  List<SpawnPoint> spawnPoints = RegionInfo.RegionSettings.SpawnPoints();
6227  Vector3 spawnPoint;
6228  ILandObject land = null;
6229  Vector3 telehubPosition = telehub.AbsolutePosition;
6230 
6231  if(spawnPoints.Count == 0)
6232  {
6233  // will this ever happen?
6234  // if so use the telehub object position
6235  spawnPoint = telehubPosition;
6236  land = LandChannel.GetLandObject(spawnPoint.X, spawnPoint.Y);
6237  if(land != null && !land.IsEitherBannedOrRestricted(agentID))
6238  {
6239  banned = false;
6240  validTelehub = true;
6241  }
6242  }
6243  else
6244  {
6245  Quaternion telehubRotation = telehub.GroupRotation;
6246  foreach (SpawnPoint spawn in spawnPoints)
6247  {
6248  spawnPoint = spawn.GetLocation(telehubPosition, telehubRotation);
6249  land = LandChannel.GetLandObject(spawnPoint.X, spawnPoint.Y);
6250  if (land == null)
6251  continue;
6252  validTelehub = true;
6253  if (!land.IsEitherBannedOrRestricted(agentID))
6254  {
6255  banned = false;
6256  break;
6257  }
6258  }
6259  }
6260 
6261  if(validTelehub)
6262  {
6263  if (banned)
6264  {
6265  reason = "No suitable landing point found";
6266  return false;
6267  }
6268  else
6269  return true;
6270  }
6271  // possible broken telehub, fall into normal check
6272  }
6273  }
6274 
6275  float posX = position.X;
6276  float posY = position.Y;
6277 
6278  // allow position relocation
6279  if (!TestLandRestrictions(agentID, out reason, ref posX, ref posY))
6280  {
6281  // m_log.DebugFormat("[SCENE]: Denying {0} because they are banned on all parcels", agentID);
6282  reason = "You dont have access to the region parcels";
6283  return false;
6284  }
6285  }
6286  else // check for query region crossing only
6287  {
6288  // no relocation allowed on crossings
6289  ILandObject land = LandChannel.GetLandObject(position.X, position.Y);
6290  if (land == null)
6291  {
6292  reason = "No parcel found";
6293  return false;
6294  }
6295 
6296  bool banned = land.IsBannedFromLand(agentID);
6297  bool restricted = land.IsRestrictedFromLand(agentID);
6298 
6299  if (banned || restricted)
6300  {
6301  if (banned)
6302  reason = "You are banned from the parcel";
6303  else
6304  reason = "The parcel is restricted";
6305  return false;
6306  }
6307  }
6308 
6309  return true;
6310  }
6311 
6312  public void StartTimerWatchdog()
6313  {
6314  m_timerWatchdog.Interval = 1000;
6315  m_timerWatchdog.Elapsed += TimerWatchdog;
6316  m_timerWatchdog.AutoReset = true;
6317  m_timerWatchdog.Start();
6318  }
6319 
6320  public void TimerWatchdog(object sender, ElapsedEventArgs e)
6321  {
6322  CheckHeartbeat();
6323  }
6324 
6332 /* move to target is now done on presence update
6333  private void HandleOnSignificantClientMovement(ScenePresence presence)
6334  {
6335  if (presence.MovingToTarget)
6336  {
6337  double distanceToTarget = Util.GetDistanceTo(presence.AbsolutePosition, presence.MoveToPositionTarget);
6338 // m_log.DebugFormat(
6339 // "[SCENE]: Abs pos of {0} is {1}, target {2}, distance {3}",
6340 // presence.Name, presence.AbsolutePosition, presence.MoveToPositionTarget, distanceToTarget);
6341 
6342  // Check the error term of the current position in relation to the target position
6343  if (distanceToTarget <= ScenePresence.SIGNIFICANT_MOVEMENT)
6344  {
6345  // We are close enough to the target
6346 // m_log.DebugFormat("[SCENEE]: Stopping autopilot of {0}", presence.Name);
6347 
6348  presence.Velocity = Vector3.Zero;
6349  presence.AbsolutePosition = presence.MoveToPositionTarget;
6350  presence.ResetMoveToTarget();
6351 
6352  if (presence.Flying)
6353  {
6354  // A horrible hack to stop the avatar dead in its tracks rather than having them overshoot
6355  // the target if flying.
6356  // We really need to be more subtle (slow the avatar as it approaches the target) or at
6357  // least be able to set collision status once, rather than 5 times to give it enough
6358  // weighting so that that PhysicsActor thinks it really is colliding.
6359  for (int i = 0; i < 5; i++)
6360  presence.IsColliding = true;
6361 
6362  if (presence.LandAtTarget)
6363  presence.Flying = false;
6364 
6365 // Vector3 targetPos = presence.MoveToPositionTarget;
6366 // float terrainHeight = (float)presence.Scene.Heightmap[(int)targetPos.X, (int)targetPos.Y];
6367 // if (targetPos.Z - terrainHeight < 0.2)
6368 // {
6369 // presence.Flying = false;
6370 // }
6371  }
6372 
6373 // m_log.DebugFormat(
6374 // "[SCENE]: AgentControlFlags {0}, MovementFlag {1} for {2}",
6375 // presence.AgentControlFlags, presence.MovementFlag, presence.Name);
6376  }
6377  else
6378  {
6379 // m_log.DebugFormat(
6380 // "[SCENE]: Updating npc {0} at {1} for next movement to {2}",
6381 // presence.Name, presence.AbsolutePosition, presence.MoveToPositionTarget);
6382 
6383  Vector3 agent_control_v3 = new Vector3();
6384  presence.HandleMoveToTargetUpdate(1, ref agent_control_v3);
6385  presence.AddNewMovement(agent_control_v3);
6386  }
6387  }
6388  }
6389 */
6390  // manage and select spawn points in sequence
6391  public int SpawnPoint()
6392  {
6393  int spawnpoints = RegionInfo.RegionSettings.SpawnPoints().Count;
6394 
6395  if (spawnpoints == 0)
6396  return 0;
6397 
6398  m_SpawnPoint++;
6399  if (m_SpawnPoint > spawnpoints)
6400  m_SpawnPoint = 1;
6401  return m_SpawnPoint - 1;
6402  }
6403 
6404  private void HandleGcCollect(string module, string[] args)
6405  {
6406  GC.Collect();
6407  }
6408 
6420  public void PhysicsRequestAsset(UUID assetID, AssetReceivedDelegate callback)
6421  {
6422  AssetService.Get(assetID.ToString(), callback, PhysicsAssetReceived);
6423  }
6424 
6425  private void PhysicsAssetReceived(string id, Object sender, AssetBase asset)
6426  {
6427  AssetReceivedDelegate callback = (AssetReceivedDelegate)sender;
6428 
6429  callback(asset);
6430  }
6431 
6432  public string GetExtraSetting(string name)
6433  {
6434  if (m_extraSettings == null)
6435  return String.Empty;
6436 
6437  string val;
6438 
6439  if (!m_extraSettings.TryGetValue(name, out val))
6440  return String.Empty;
6441 
6442  return val;
6443  }
6444 
6445  public void StoreExtraSetting(string name, string val)
6446  {
6447  if (m_extraSettings == null)
6448  return;
6449 
6450  string oldVal;
6451 
6452  if (m_extraSettings.TryGetValue(name, out oldVal))
6453  {
6454  if (oldVal == val)
6455  return;
6456  }
6457 
6458  m_extraSettings[name] = val;
6459 
6460  m_SimulationDataService.SaveExtra(RegionInfo.RegionID, name, val);
6461 
6462  m_eventManager.TriggerExtraSettingChanged(this, name, val);
6463  }
6464 
6465  public void RemoveExtraSetting(string name)
6466  {
6467  if (m_extraSettings == null)
6468  return;
6469 
6470  if (!m_extraSettings.ContainsKey(name))
6471  return;
6472 
6473  m_extraSettings.Remove(name);
6474 
6475  m_SimulationDataService.RemoveExtra(RegionInfo.RegionID, name);
6476 
6477  m_eventManager.TriggerExtraSettingChanged(this, name, String.Empty);
6478  }
6479  }
6480 }
delegate void RezScript(IClientAPI remoteClient, InventoryItemBase item, UUID transactionID, uint localID)
virtual void SubscribeToClientEvents(IClientAPI client)
Register for events from the client
Definition: Scene.cs:3354
void Backup(bool forced)
Backup the scene.
Definition: Scene.cs:2077
bool ScriptDanger(uint localID, Vector3 pos)
Definition: Scene.cs:5149
override void OtherRegionUp(GridRegion otherRegion)
Process the fact that a neighbouring region has come up.
Definition: Scene.cs:1326
string lastname
Agent's account last name
LandData GetLandData(uint x, uint y)
Definition: Scene.cs:5089
delegate void UpdatePrimSingleRotationPosition(uint localID, Quaternion rot, Vector3 pos, IClientAPI remoteClient)
EstateSettings EstateSettings
Definition: RegionInfo.cs:275
IAuthenticationService m_AuthenticationService
Definition: Scene.cs:346
bool CrossAgentToNewRegion(ScenePresence agent, bool isFlying)
Definition: Scene.cs:4968
delegate void UpdatePrimGroupRotation(uint localID, Vector3 pos, Quaternion rot, IClientAPI remoteClient)
virtual SceneObjectGroup AddNewPrim(UUID ownerID, UUID groupID, Vector3 pos, Quaternion rot, PrimitiveBaseShape shape)
Definition: Scene.cs:2550
uint circuitcode
Number given to the client when they log-in that they provide as credentials to the UDP server ...
override void Update(int frames)
Called to update the scene loop by a number of frames and until shutdown.
Definition: Scene.cs:1721
delegate void RemoveInventoryItem(IClientAPI remoteClient, List< UUID > itemIDs)
delegate void UpdatePrimSingleRotation(uint localID, Quaternion rot, IClientAPI remoteClient)
bool IncomingCreateObject(Vector3 newPosition, ISceneObject sog)
Called when objects or attachments cross the border, or teleport, between regions.
Definition: Scene.cs:2931
void DeleteAllSceneObjects()
Delete every object from the scene. This does not include attachments worn by avatars.
Definition: Scene.cs:2699
void RequestTeleportLocation(IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags)
Tries to teleport agent to other region.
Definition: Scene.cs:4950
OpenSim.Services.Interfaces.GridRegion GridRegion
Definition: Scene.cs:53
bool NewUserConnection(AgentCircuitData acd, uint teleportFlags, GridRegion source, out string reason, bool requirePresenceLookup)
Definition: Scene.cs:3980
delegate bool FilterAvatarList(ScenePresence avatar)
void DeleteSceneObject(SceneObjectGroup group, bool silent)
Synchronously delete the given object from the scene.
Definition: Scene.cs:2746
OpenSim.Framework.Constants.TeleportFlags TeleportFlags
bool TryGetSceneObjectGroup(UUID fullID, out SceneObjectGroup sog)
Attempt to get the SOG via its UUID
Definition: Scene.cs:5332
delegate void UpdateTaskInventory(IClientAPI remoteClient, UUID transactionID, TaskInventoryItem item, uint localID)
void AddNeighborRegion(RegionInfo region)
Definition: Scene.cs:1381
bool QueryAccess(UUID agentID, string agentHomeURI, bool viaTeleport, Vector3 position, List< UUID > features, out string reason)
This method is called across the simulation connector to determine if a given agent is allowed in thi...
Definition: Scene.cs:6122
SceneObjectPart GetSceneObjectPart(UUID fullID)
Get a prim via its UUID
Definition: Scene.cs:5364
ScenePresence GetScenePresence(string firstName, string lastName)
Request the scene presence by name.
Definition: Scene.cs:5232
override bool CloseAgent(UUID agentID, bool force)
Tell a single agent to disconnect from the region.
Definition: Scene.cs:4849
virtual ScenePresence WaitGetScenePresence(UUID agentID)
Poll until the requested ScenePresence appears or we timeout.
Definition: Scene.cs:4735
bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, Vector3?pos, Quaternion?rot, Vector3 vel)
Add a newly created object to the scene.
Definition: Scene.cs:2684
delegate void RequestTaskInventory(IClientAPI remoteClient, uint localID)
float GetGroundHeight(float x, float y)
Definition: Scene.cs:5720
virtual void RegisterDefaultSceneEvents()
Definition: Scene.cs:1305
void jointErrorMessage(PhysicsJoint joint, string message)
Definition: Scene.cs:5669
void SaveTerrain()
Store the terrain in the persistant data store
Definition: Scene.cs:2168
bool VerifyClient(AgentCircuitData aCircuit, string token)
void loadAllLandObjectsFromStorage(UUID regionID)
Loads all Parcel data from the datastore for region identified by regionID
Definition: Scene.cs:2270
EntityBase[] GetEntities()
Returns a list of the entities in the scene. This is a new list so operations perform on the list its...
Definition: Scene.cs:5452
OpenSim.Server.Handlers.Simulation.Utils Utils
LandData GetLandData(Vector3 pos)
Get LandData by position.
Definition: Scene.cs:5084
SynchronizeSceneHandler SynchronizeScene
Definition: Scene.cs:175
Vector3 GetNearestAllowedPosition(ScenePresence avatar)
Definition: Scene.cs:5780
Send FetchInventoryReply information to clients asynchronously on a single thread rather than asynchr...
bool SenderWantsToWaitForRoot
Signal on a V2 teleport that Scene.IncomingChildAgentDataUpdate(AgentData ad) should wait for the sce...
SceneObjectGroup GetSceneObjectGroup(string name)
Get a group by name from the scene (will return the first found, if there are more than one prim with...
Definition: Scene.cs:5321
delegate void UpdatePrimFlags(uint localID, bool UsePhysics, bool IsTemporary, bool IsPhantom, ExtraPhysicsData PhysData, IClientAPI remoteClient)
delegate void RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart, UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, bool RezSelected, bool RemoveItem, UUID fromTaskID)
virtual bool AuthorizeUser(AgentCircuitData agent, bool bypassAccessControl, out string reason)
Verify if the user can connect to this region. Checks the banlist and ensures that the region is set ...
Definition: Scene.cs:4407
uint RegionSizeX
X dimension of the region.
Definition: RegionInfo.cs:161
Contains the Avatar's Appearance and methods to manipulate the appearance.
void RemoveGroupTarget(SceneObjectGroup grp)
Definition: Scene.cs:1991
void RegenerateMaptileAndReregister(object sender, ElapsedEventArgs e)
Definition: Scene.cs:6095
ScenePresenceState
The possible states that a scene presence can be in. This is currently orthagonal to whether a scene ...
ISimulationService m_simulationService
Definition: Scene.cs:345
delegate void ClientChangeObject(uint localID, object data, IClientAPI remoteClient)
override bool CheckClient(UUID agentID, System.Net.IPEndPoint ep)
Definition: Scene.cs:3312
delegate void DelinkObjects(List< uint > primIds, IClientAPI client)
SceneObjectPart GetSceneObjectPart(uint localID)
Get a prim via its local id
Definition: Scene.cs:5354
uint RegionSizeY
X dimension of the region.
Definition: RegionInfo.cs:169
OpenMetaverse.StructuredData.OSDMap OSDMap
bool TryGetAvatarByName(string avatarName, out ScenePresence avatar)
Definition: Scene.cs:5406
Asynchronously derez objects. This is used to derez large number of objects to inventory without hold...
IGridUserService m_GridUserService
Definition: Scene.cs:350
Vector3 startpos
Position the Agent's Avatar starts in the region
override void LoadWorldMap()
Loads the World heightmap
Definition: Scene.cs:2189
A scene object group is conceptually an object in the scene. The object is constituted of SceneObject...
Add remove or retrieve Simulator Features that will be given to a viewer via the SimulatorFeatures ca...
PrimFlags Flags
Property flags. See OpenMetaverse.PrimFlags
void DeleteAllSceneObjects(bool exceptNoCopy)
Delete every object from the scene. This does not include attachments worn by avatars.
Definition: Scene.cs:2707
Dictionary< string, object > ServiceURLs
void ForEachSOG(Action< SceneObjectGroup > action)
Definition: Scene.cs:5442
SceneObjectGroup GetGroupByPrim(UUID fullID)
Get a scene object group that contains the prim with the given uuid
Definition: Scene.cs:5396
void ForEachRootClient(Action< IClientAPI > action)
Perform an action on all clients with an avatar in this scene (root only)
Definition: Scene.cs:5415
RegionSettings RegionSettings
Definition: RegionInfo.cs:290
delegate void UpdatePrimTexture(uint localID, byte[] texture, IClientAPI remoteClient)
void DeleteSceneObject(SceneObjectGroup group, bool silent, bool removeScripts)
Synchronously delete the given object from the scene.
Definition: Scene.cs:2757
delegate void AddNewPrim(UUID ownerID, UUID groupID, Vector3 RayEnd, Quaternion rot, PrimitiveBaseShape shape, byte bypassRaycast, Vector3 RayStart, UUID RayTargetID, byte RayEndIsIntersection)
Vector3 GetNearestAllowedPosition(ScenePresence avatar, ILandObject excludeParcel)
Definition: Scene.cs:5785
virtual void UnSubscribeToClientTerrainEvents(IClientAPI client)
Definition: Scene.cs:3495
Enapsulate statistics for a simulator/scene.
Definition: SimStats.cs:39
string IPAddress
The client's IP address, as captured by the login service
virtual void SubscribeToClientTeleportEvents(IClientAPI client)
Definition: Scene.cs:3446
delegate void CopyInventoryItem(IClientAPI remoteClient, uint callbackID, UUID oldAgentID, UUID oldItemID, UUID newFolderID, string newName)
bool IsEitherBannedOrRestricted(UUID avatar)
PresenceType
Indicate the type of ScenePresence.
Definition: PresenceType.cs:34
System.Timers.Timer Timer
bool DoNotCloseAfterTeleport
Used by the entity transfer module to signal when the presence should not be closed because a subsequ...
ScenePresence GetScenePresence(UUID agentID)
Request a scene presence by UUID. Fast, indexed lookup.
Definition: Scene.cs:5221
virtual void UnSubscribeToClientPrimRezEvents(IClientAPI client)
Definition: Scene.cs:3543
SceneCommunicationService m_sceneGridService
Definition: Scene.cs:335
UUID SessionID
Non secure Session ID
ILibraryService m_LibraryService
Definition: Scene.cs:344
bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates)
Add a newly created object to the scene
Definition: Scene.cs:2661
void SwapRootAgentCount(bool rootChildChildRootTF)
Definition: Scene.cs:5191
System.Timers.Timer Timer
Definition: Scene.cs:51
bool IsDeleted
Signals whether this entity was in a scene but has since been removed from it.
Definition: EntityBase.cs:73
Asset class. All Assets are reference by this class or a class derived from this class ...
Definition: AssetBase.cs:49
void AddReturn(UUID agentID, string objectName, Vector3 location, string reason)
Tell an agent that their object has been returned.
Definition: Scene.cs:2139
void RequestTeleportLocation(IClientAPI remoteClient, string regionName, Vector3 position, Vector3 lookat, uint teleportFlags)
Tries to teleport agent to another region.
Definition: Scene.cs:4927
IPresenceService m_PresenceService
Definition: Scene.cs:347
virtual void UnSubscribeToClientScriptEvents(IClientAPI client)
Definition: Scene.cs:3576
virtual void UnSubscribeToClientEvents(IClientAPI client)
Unsubscribe the client from events.
Definition: Scene.cs:3482
string firstname
Agent's account first name
bool isNeighborRegion(GridRegion otherRegion)
Definition: Scene.cs:1366
bool IsBannedFromLand(UUID avatar)
void updateScenePartGroup(SceneObjectPart part, SceneObjectGroup grp)
Definition: Scene.cs:2843
OpenSim.Framework.Constants.TeleportFlags TPFlags
Definition: Scene.cs:52
void PhysicsRequestAsset(UUID assetID, AssetReceivedDelegate callback)
Wrappers to get physics modules retrieve assets.
Definition: Scene.cs:6420
delegate void AssetReceivedDelegate(AssetBase asset)
LandData GetLandData(float x, float y)
Definition: Scene.cs:5071
virtual bool IncomingUpdateChildAgent(AgentData cAgentData)
We've got an update about an agent that sees into this region, send it to ScenePresence for processin...
Definition: Scene.cs:4607
delegate void MoveObject(UUID objectID, Vector3 offset, Vector3 grapPos, IClientAPI remoteClient, List< SurfaceTouchEventArgs > surfaceArgs)
override void Close()
Tidy before shutdown
Definition: Scene.cs:1475
bool IsAttachmentCheckFull()
Check both the attachment property and the relevant properties of the underlying root part...
virtual void SubscribeToClientParcelEvents(IClientAPI client)
Definition: Scene.cs:3458
IUserAccountService m_UserAccountService
Definition: Scene.cs:348
SceneObjectGroup GetSceneObjectGroup(UUID fullID)
Get a group via its UUID
Definition: Scene.cs:5299
SceneObjectGroup GetGroupByPrim(uint localID)
Get a scene object group that contains the prim with the given local id
Definition: Scene.cs:5386
UUID GroupID
Unique ID of the Group that owns
Definition: LandData.cs:342
void HandleRemoveKnownRegionsFromAvatar(UUID avatarID, List< ulong > regionslst)
Removes region from an avatar's known region list. This coincides with child agents. For each child agent, there will be a known region entry.
Definition: Scene.cs:3896
void AllModulesLoaded()
Called by the module loader when all modules are loaded, after each module's RegionLoaded hook is cal...
Definition: Scene.cs:1275
void StoreWindlightProfile(RegionLightShareData wl)
Definition: Scene.cs:2173
virtual void SubscribeToClientGridEvents(IClientAPI client)
Definition: Scene.cs:3465
An agent in the scene.
Definition: ISceneAgent.cs:39
GridRegion IncomingHelloNeighbour(RegionInfo neighbour)
Definition: Scene.cs:1410
override string GetSimulatorVersion()
Definition: Scene.cs:1310
Circuit data for an agent. Connection information shared between regions that accept UDP connections ...
IRegionSerialiserModule m_serialiser
Definition: Scene.cs:357
List< UUID > GetEstateRegions(int estateID)
Definition: Scene.cs:5931
static ICommandConsole Instance
Definition: MainConsole.cs:35
bool TryGetSceneObjectPart(UUID fullID, out SceneObjectPart sop)
Attempt to get a prim via its UUID
Definition: Scene.cs:5375
virtual void LoadPrimsFromStorage(UUID regionID)
Loads the World's objects
Definition: Scene.cs:2300
Details of a Parcel of land
Definition: LandData.cs:47
delegate void RemoveTaskInventory(IClientAPI remoteClient, UUID itemID, uint localID)
void RegisterRegionWithGrid()
Register this region with a grid service
Definition: Scene.cs:2239
delegate void ObjectOwner(IClientAPI remoteClient, UUID ownerID, UUID groupID, List< uint > localIDs)
ILandObject GetNearestAllowedParcel(UUID avatarId, float x, float y, ILandObject excludeParcel)
Definition: Scene.cs:5839
bool NewUserConnection(AgentCircuitData agent, uint teleportFlags, GridRegion source, out string reason)
Do the work necessary to initiate a new user connection for a particular scene.
Definition: Scene.cs:3949
void ForceSceneObjectBackup(SceneObjectGroup group)
Synchronous force backup. For deletes and links/unlinks
Definition: Scene.cs:2120
Vector3 GetNewRezLocation(Vector3 RayStart, Vector3 RayEnd, UUID RayTargetID, Quaternion rot, byte bypassRayCast, byte RayEndIsIntersection, bool frontFacesOnly, Vector3 scale, bool FaceCenter)
Gets a new rez location based on the raycast and the size of the object that is being rezzed...
Definition: Scene.cs:2352
ILandObject GetNearestAllowedParcel(UUID avatarId, float x, float y)
Definition: Scene.cs:5834
PhysicsActor PhysActor
The representation of this part in the physics scene.
OpenMetaverse.StructuredData.OSD OSD
virtual bool IncomingUpdateChildAgent(AgentPosition cAgentData)
We've got an update about an agent that sees into this region, send it to ScenePresence for processin...
Definition: Scene.cs:4696
void TimerWatchdog(object sender, ElapsedEventArgs e)
Definition: Scene.cs:6320
virtual void SubscribeToClientPrimEvents(IClientAPI client)
Definition: Scene.cs:3372
SceneObjectPart GetSceneObjectPart(string name)
Get a prim by name from the scene (will return the first found, if there are more than one prim with ...
Definition: Scene.cs:5344
virtual void UnSubscribeToClientInventoryEvents(IClientAPI client)
Definition: Scene.cs:3549
override ISceneObject DeserializeObject(string representation)
Definition: Scene.cs:5770
void StoreExtraSetting(string name, string val)
Definition: Scene.cs:6445
delegate void MoveInventoryItem(IClientAPI remoteClient, List< InventoryItemBase > items)
Replacement for ChildAgentDataUpdate. Used over RESTComms and LocalComms.
static Vector3[] GetCombinedBoundingBox(List< SceneObjectGroup > objects, out float minX, out float maxX, out float minY, out float maxY, out float minZ, out float maxZ)
Get the volume of space that will encompass all the given objects.
Definition: Scene.cs:5976
AgentCircuitManager m_authenticateHandler
Definition: Scene.cs:334
void AddScriptExecutionTime(long ticks)
Adds the execution time of one script to the total scripts execution time for this region...
Definition: Scene.cs:1965
delegate void LinkObjects(IClientAPI remoteClient, uint parent, List< uint > children)
void setThreadCount(int inUseThreads)
Definition: Scene.cs:555
bool PipeEventsForScript(uint localID)
Definition: Scene.cs:5162
SceneObjectGroup GetSceneObjectGroup(uint localID)
Get a group via its local ID
Definition: Scene.cs:5310
void HandleObjectPermissionsUpdate(IClientAPI controller, UUID agentID, UUID sessionID, byte field, uint localId, uint mask, byte set)
Definition: Scene.cs:4998
override bool TryGetScenePresence(UUID agentID, out ScenePresence sp)
Try to get a scene presence from the scene
Definition: Scene.cs:5401
A class for triggering remote scene events.
Definition: EventManager.cs:44
Collect statistics from the scene to send to the client and for access by other monitoring tools...
virtual void UnSubscribeToClientPrimEvents(IClientAPI client)
Definition: Scene.cs:3500
void SendOutChildAgentUpdates(AgentPosition cadu, ScenePresence presence)
Definition: Scene.cs:4982
bool IncomingPreCloseClient(ScenePresence sp)
Tell a single client to prepare to close.
Definition: Scene.cs:4807
void ThreadAlive(int threadCode)
Definition: Scene.cs:6082
delegate void SpinStart(UUID objectID, IClientAPI remoteClient)
void RestartNotifyWaitElapsed(object sender, ElapsedEventArgs e)
Definition: Scene.cs:1441
delegate void SpinObject(UUID objectID, Quaternion rotation, IClientAPI remoteClient)
virtual void SubscribeToClientTerrainEvents(IClientAPI client)
Definition: Scene.cs:3367
bool UnlinkSceneObject(SceneObjectGroup so, bool softDelete)
Unlink the given object from the scene. Unlike delete, this just removes the record of the object - t...
Definition: Scene.cs:2817
ISimulationDataService m_SimulationDataService
Definition: Scene.cs:338
UUID ConvertLocalIDToFullID(uint localID)
Definition: Scene.cs:5186
OpenSim.Framework.PermissionMask PermissionMask
Definition: Scene.cs:54
virtual void AddNewPrim(UUID ownerID, UUID groupID, Vector3 RayEnd, Quaternion rot, PrimitiveBaseShape shape, byte bypassRaycast, Vector3 RayStart, UUID RayTargetID, byte RayEndIsIntersection)
Create a New SceneObjectGroup/Part by raycasting
Definition: Scene.cs:2529
virtual void SubscribeToClientNetworkEvents(IClientAPI client)
Definition: Scene.cs:3471
void SendCommandToPlugins(string[] args)
Console command handler to send script command to script engine.
Definition: Scene.cs:5066
IAvatarFactoryModule m_AvatarFactory
Definition: Scene.cs:355
virtual void UnSubscribeToClientGridEvents(IClientAPI client)
Definition: Scene.cs:3590
bool TestLandRestrictions(UUID agentID, out string reason, ref float posX, ref float posY)
Definition: Scene.cs:4320
const uint APPLY_TO_NONE
string GetExtraSetting(string name)
Definition: Scene.cs:6432
void Start(bool startScripts)
Start the scene
Definition: Scene.cs:1550
string GetAgentHomeURI(UUID agentID)
Returns the Home URI of the agent, or null if unknown.
Definition: Scene.cs:3231
List< SceneObjectGroup > GetSceneObjectGroups()
Get all the scene object groups.
Definition: Scene.cs:5289
UUID TelehubObject
Connected Telehub object
bool PositionIsInCurrentRegion(Vector3 pos)
Definition: Scene.cs:2903
bool CheckLandPositionAccess(UUID agentID, bool NotCrossing, bool checkTeleHub, Vector3 position, out string reason)
Definition: Scene.cs:6201
IEstateDataService m_EstateDataService
Definition: Scene.cs:339
override Vector3 AbsolutePosition
The absolute position of this scene object in the scene
int GetSittingAvatarsCount()
Gets the number of sitting avatars.
bool AddRestoredSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted)
Add an object into the scene that has come from storage
Definition: Scene.cs:2628
void RemoveClient(UUID agentID, bool closeChildAgents)
Definition: Scene.cs:3757
List< ScenePresence > GetScenePresences()
Gets all the scene presences in this scene.
Definition: Scene.cs:5259
uint Flags
Parcel settings. Access flags, Fly, NoPush, Voice, Scripts allowed, etc. ParcelFlags ...
Definition: LandData.cs:402
delegate void SetScriptRunning(IClientAPI remoteClient, UUID objectID, UUID itemID, bool running)
UUID AgentID
Avatar Unique Agent Identifier
bool ChangeCircuitCode(uint oldcc, uint newcc)
Change the Circuit Code for the user's Circuit Data
Definition: Scene.cs:4531
void ForEachRootScenePresence(Action< ScenePresence > action)
Performs action on all avatars in the scene (root scene presences) Avatars may be an NPC or a 'real' ...
Definition: Scene.cs:5269
A new version of the old Channel class, simplified
override void Start()
Start the scene and associated scripts within it.
Definition: Scene.cs:1539
IAgentPreferencesService m_AgentPreferencesService
Definition: Scene.cs:351
delegate void RemoveInventoryFolder(IClientAPI remoteClient, List< UUID > folderIDs)
void RemoveExtraSetting(string name)
Definition: Scene.cs:6465
int GetHealth(out int flags, out string message)
Definition: Scene.cs:5497
bool TryGetClient(System.Net.IPEndPoint remoteEndPoint, out IClientAPI client)
Definition: Scene.cs:5437
void ForceClientUpdate()
Causes all clients to get a full object update on all of the objects in the scene.
Definition: Scene.cs:5018
void HandleEditCommand(string[] cmdparams)
This is currently only used for scale (to scale to MegaPrim size) There is a console command that cal...
Definition: Scene.cs:5035
virtual void UnSubscribeToClientParcelEvents(IClientAPI client)
Definition: Scene.cs:3583
void SendKillObject(List< uint > localIDs)
Definition: Scene.cs:3915
uint RegionSizeZ
Z dimension of the region.
Definition: RegionInfo.cs:177
override IConfigSource GetConfig()
Definition: Scene.cs:4991
void doObjectDuplicateOnRay(uint localID, uint dupeFlags, UUID AgentID, UUID GroupID, UUID RayTargetObj, Vector3 RayEnd, Vector3 RayStart, bool BypassRaycast, bool RayEndIsIntersection, bool CopyCenters, bool CopyRotates)
Duplicates object specified by localID at position raycasted against RayTargetObject using RayEnd and...
Definition: Scene.cs:3651
uint teleportFlags
How this agent got here
object RayCastFiltered(Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags filter)
Definition: Scene.cs:2332
This maintains the relationship between a UUID and a user name.
delegate void RequestObjectPropertiesFamily(IClientAPI remoteClient, UUID AgentID, uint RequestFlags, UUID TaskID)
virtual bool VerifyUserPresence(AgentCircuitData agent, out string reason)
Verifies that the user has a presence on the Grid
Definition: Scene.cs:4378
virtual void SubscribeToClientScriptEvents(IClientAPI client)
Definition: Scene.cs:3451
IAuthorizationService m_AuthorizationService
Definition: Scene.cs:341
bool TryGetClient(UUID avatarID, out IClientAPI client)
Definition: Scene.cs:5432
override ISceneAgent AddNewAgent(IClientAPI client, PresenceType type)
Add a new agent with an attached client. All agents except initial login clients will starts off as a...
Definition: Scene.cs:3124
ScenePresence GetScenePresence(uint localID)
Request the scene presence by localID.
Definition: Scene.cs:5242
virtual void UnSubscribeToClientTeleportEvents(IClientAPI client)
Definition: Scene.cs:3569
bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup)
Add a newly created object to the scene. Updates are also sent to viewers.
Definition: Scene.cs:2643
virtual bool TeleportClientHome(UUID agentId, IClientAPI client)
Teleport an avatar to their home region
Definition: Scene.cs:3607
IInventoryService m_InventoryService
Definition: Scene.cs:342
ICapabilitiesModule m_capsModule
Definition: Scene.cs:359
ScenePresenceState LifecycleState
The current state of this presence. Governs only the existence lifecycle. See ScenePresenceStateMachi...
void GetAvatarAppearance(IClientAPI client, out AvatarAppearance appearance)
Get the avatar appearance for the given client.
Definition: Scene.cs:3722
bool CloseAgent(UUID agentID, bool force, string auth_token)
Authenticated close (via network)
Definition: Scene.cs:4757
bool AddRestoredSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates)
Add an object into the scene that has come from storage
Definition: Scene.cs:2599
virtual void SubscribeToClientPrimRezEvents(IClientAPI client)
Definition: Scene.cs:3418
void UpdateCircuitData(AgentCircuitData data)
Update an AgentCircuitData object with new information
Definition: Scene.cs:4520
void ForEachClient(Action< IClientAPI > action)
Perform an action on all clients connected to the region (root and child)
Definition: Scene.cs:5427
This class used to be called InnerScene and may not yet truly be a SceneGraph. The non scene graph co...
Definition: SceneGraph.cs:54
Vector3 GetWorldPosition()
Method for a prim to get it's world position from the group.
bool GroupContainsForeignPrims
Whether the group contains prims that came from a different group. This happens when linking or delin...
void DuplicateObject(uint originalPrim, Vector3 offset, uint flags, UUID AgentID, UUID GroupID)
Duplicates object specified by localID. This is the event handler for IClientAPI. ...
Definition: Scene.cs:3629
long GetAndResetScriptExecutionTime()
Returns the total execution time of all the scripts in the region since the last call (in millisecond...
Definition: Scene.cs:1979
bool IsAttachment
Is this scene object acting as an attachment?
bool CheckNeighborRegion(RegionInfo region)
Definition: Scene.cs:1392
bool AddSceneObject(SceneObjectGroup sceneObject)
Adds a Scene Object group to the Scene. Verifies that the creator of the object is not banned from th...
Definition: Scene.cs:3007
delegate void GetScriptRunning(IClientAPI remoteClient, UUID objectID, UUID itemID)
void AddGroupTarget(SceneObjectGroup grp)
Definition: Scene.cs:1985
Scene(RegionInfo regInfo, AgentCircuitManager authen, ISimulationDataService simDataService, IEstateDataService estateDataService, IConfigSource config, string simulatorVersion)
Definition: Scene.cs:867
virtual void SubscribeToClientInventoryEvents(IClientAPI client)
Definition: Scene.cs:3424
void SetModuleInterfaces()
Sets up references to modules required by the scene
Definition: Scene.cs:1595
virtual void UnSubscribeToClientNetworkEvents(IClientAPI client)
Definition: Scene.cs:3596
uint ParentID
If the avatar is sitting, the local ID of the prim that it's sitting on. If not sitting then zero...
UUID OwnerID
Owner Avatar or Group of the parcel. Naturally, all land masses must be owned by someone ...
Definition: LandData.cs:551
void ForEachScenePresence(Action< ScenePresence > action)
Performs action on all scene presences (root and child)
Definition: Scene.cs:5278