Scene.cs 148 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696
  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 OpenSim 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. using System;
  28. using System.Collections.Generic;
  29. using System.Drawing;
  30. using System.Drawing.Imaging;
  31. using System.Threading;
  32. using System.Timers;
  33. using Axiom.Math;
  34. using libsecondlife;
  35. using libsecondlife.Packets;
  36. using OpenJPEGNet;
  37. using OpenSim.Framework;
  38. using OpenSim.Framework.Communications;
  39. using OpenSim.Framework.Communications.Cache;
  40. using OpenSim.Framework.Servers;
  41. using OpenSim.Region.Environment.Interfaces;
  42. using OpenSim.Region.Environment.Modules.World.Archiver;
  43. using OpenSim.Region.Environment.Modules.World.Serialiser;
  44. using OpenSim.Region.Environment.Modules.World.Terrain;
  45. using OpenSim.Region.Environment.Scenes.Scripting;
  46. using OpenSim.Region.Physics.Manager;
  47. using Nini.Config;
  48. using Caps=OpenSim.Framework.Communications.Capabilities.Caps;
  49. using Image=System.Drawing.Image;
  50. using Timer=System.Timers.Timer;
  51. namespace OpenSim.Region.Environment.Scenes
  52. {
  53. public delegate bool FilterAvatarList(ScenePresence avatar);
  54. public partial class Scene : SceneBase
  55. {
  56. public delegate void SynchronizeSceneHandler(Scene scene);
  57. public SynchronizeSceneHandler SynchronizeScene = null;
  58. public int splitID = 0;
  59. #region Fields
  60. protected Timer m_heartbeatTimer = new Timer();
  61. protected Timer m_restartWaitTimer = new Timer();
  62. protected SimStatsReporter m_statsReporter;
  63. protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>();
  64. protected List<RegionInfo> m_neighbours = new List<RegionInfo>();
  65. public InnerScene m_innerScene;
  66. /// <summary>
  67. /// The last allocated local prim id. When a new local id is requested, the next number in the sequence is
  68. /// dispenced.
  69. /// </summary>
  70. private uint m_lastAllocatedLocalId = 720000;
  71. private readonly Mutex _primAllocateMutex = new Mutex(false);
  72. private int m_timePhase = 24;
  73. private readonly Mutex updateLock;
  74. /// <summary>
  75. /// Are we applying physics to any of the prims in this scene?
  76. /// </summary>
  77. public bool m_physicalPrim;
  78. public bool m_seeIntoRegionFromNeighbor;
  79. public int MaxUndoCount = 5;
  80. private int m_RestartTimerCounter;
  81. private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing
  82. private int m_incrementsof15seconds = 0;
  83. private volatile bool m_backingup = false;
  84. protected string m_simulatorVersion = "unknown";
  85. protected ModuleLoader m_moduleLoader;
  86. protected StorageManager m_storageManager;
  87. protected AgentCircuitManager m_authenticateHandler;
  88. public CommunicationsManager CommsManager;
  89. protected SceneCommunicationService m_sceneGridService;
  90. public SceneCommunicationService SceneGridService
  91. {
  92. get { return m_sceneGridService; }
  93. }
  94. /// <summary>
  95. /// Each agent has its own capabilities handler.
  96. /// </summary>
  97. protected Dictionary<LLUUID, Caps> m_capsHandlers = new Dictionary<LLUUID, Caps>();
  98. protected BaseHttpServer m_httpListener;
  99. protected Dictionary<string, IRegionModule> m_modules = new Dictionary<string, IRegionModule>();
  100. public Dictionary<string, IRegionModule> Modules
  101. {
  102. get { return m_modules; }
  103. }
  104. protected Dictionary<Type, object> ModuleInterfaces = new Dictionary<Type, object>();
  105. protected Dictionary<string, object> ModuleAPIMethods = new Dictionary<string, object>();
  106. protected Dictionary<string, ICommander> m_moduleCommanders = new Dictionary<string, ICommander>();
  107. //API module interfaces
  108. public IXfer XferManager;
  109. protected IHttpRequests m_httpRequestModule;
  110. protected IXMLRPC m_xmlrpcModule;
  111. protected IWorldComm m_worldCommModule;
  112. protected IAvatarFactory m_AvatarFactory;
  113. protected IConfigSource m_config;
  114. protected IRegionArchiver m_archiver;
  115. protected IRegionSerialiser m_serialiser;
  116. // Central Update Loop
  117. protected int m_fps = 10;
  118. protected int m_frame = 0;
  119. protected float m_timespan = 0.089f;
  120. protected DateTime m_lastupdate = DateTime.Now;
  121. protected float m_timedilation = 1.0f;
  122. private int m_update_physics = 1;
  123. private int m_update_entitymovement = 1;
  124. private int m_update_entities = 1; // Run through all objects checking for updates
  125. private int m_update_entitiesquick = 200; // Run through objects that have scheduled updates checking for updates
  126. private int m_update_presences = 1; // Update scene presence movements
  127. private int m_update_events = 1;
  128. private int m_update_backup = 200;
  129. private int m_update_terrain = 50;
  130. private int m_update_land = 1;
  131. private int frameMS = 0;
  132. private int physicsMS2 = 0;
  133. private int physicsMS = 0;
  134. private int otherMS = 0;
  135. private bool m_physics_enabled = true;
  136. private bool m_scripts_enabled = true;
  137. #endregion
  138. #region Properties
  139. public AgentCircuitManager AuthenticateHandler
  140. {
  141. get { return m_authenticateHandler; }
  142. }
  143. // an instance to the physics plugin's Scene object.
  144. public PhysicsScene PhysicsScene
  145. {
  146. set { m_innerScene.PhysicsScene = value; }
  147. get { return (m_innerScene.PhysicsScene); }
  148. }
  149. // This gets locked so things stay thread safe.
  150. public object SyncRoot
  151. {
  152. get { return m_innerScene.m_syncRoot; }
  153. }
  154. public float TimeDilation
  155. {
  156. get { return m_timedilation; }
  157. }
  158. public int TimePhase
  159. {
  160. get { return m_timePhase; }
  161. }
  162. // Local reference to the objects in the scene (which are held in innerScene)
  163. // public Dictionary<LLUUID, SceneObjectGroup> Objects
  164. // {
  165. // get { return m_innerScene.SceneObjects; }
  166. // }
  167. // Reference to all of the agents in the scene (root and child)
  168. protected Dictionary<LLUUID, ScenePresence> m_scenePresences
  169. {
  170. get { return m_innerScene.ScenePresences; }
  171. set { m_innerScene.ScenePresences = value; }
  172. }
  173. // protected Dictionary<LLUUID, SceneObjectGroup> m_sceneObjects
  174. // {
  175. // get { return m_innerScene.SceneObjects; }
  176. // set { m_innerScene.SceneObjects = value; }
  177. // }
  178. /// <summary>
  179. /// The dictionary of all entities in this scene. The contents of this dictionary may be changed at any time.
  180. /// If you wish to add or remove entities, please use the appropriate method for that entity rather than
  181. /// editing this dictionary directly.
  182. ///
  183. /// If you want a list of entities where the list itself is guaranteed not to change, please use
  184. /// GetEntities()
  185. /// </summary>
  186. public Dictionary<LLUUID, EntityBase> Entities
  187. {
  188. get { return m_innerScene.Entities; }
  189. set { m_innerScene.Entities = value; }
  190. }
  191. public Dictionary<LLUUID, ScenePresence> m_restorePresences
  192. {
  193. get { return m_innerScene.RestorePresences; }
  194. set { m_innerScene.RestorePresences = value; }
  195. }
  196. public int objectCapacity = 45000;
  197. #endregion
  198. #region Constructors
  199. public Scene(RegionInfo regInfo, AgentCircuitManager authen,
  200. CommunicationsManager commsMan, SceneCommunicationService sceneGridService,
  201. AssetCache assetCach, StorageManager storeManager, BaseHttpServer httpServer,
  202. ModuleLoader moduleLoader, bool dumpAssetsToFile, bool physicalPrim,
  203. bool SeeIntoRegionFromNeighbor, IConfigSource config, string simulatorVersion)
  204. {
  205. m_config = config;
  206. updateLock = new Mutex(false);
  207. m_moduleLoader = moduleLoader;
  208. m_authenticateHandler = authen;
  209. CommsManager = commsMan;
  210. m_sceneGridService = sceneGridService;
  211. m_sceneGridService.debugRegionName = regInfo.RegionName;
  212. m_storageManager = storeManager;
  213. AssetCache = assetCach;
  214. m_regInfo = regInfo;
  215. m_regionHandle = m_regInfo.RegionHandle;
  216. m_regionName = m_regInfo.RegionName;
  217. m_datastore = m_regInfo.DataStore;
  218. m_physicalPrim = physicalPrim;
  219. m_seeIntoRegionFromNeighbor = SeeIntoRegionFromNeighbor;
  220. m_eventManager = new EventManager();
  221. m_externalChecks = new SceneExternalChecks(this);
  222. // Load region settings
  223. // First try database
  224. m_regInfo.RegionSettings = m_storageManager.DataStore.LoadRegionSettings(m_regInfo.RegionID);
  225. // Hook up save event
  226. m_regInfo.RegionSettings.OnSave += m_storageManager.DataStore.StoreRegionSettings;
  227. if(m_storageManager.EstateDataStore != null)
  228. {
  229. m_regInfo.EstateSettings = m_storageManager.EstateDataStore.LoadEstateSettings(m_regInfo.RegionID);
  230. m_regInfo.EstateSettings.OnSave += m_storageManager.EstateDataStore.StoreEstateSettings;
  231. }
  232. //Bind Storage Manager functions to some land manager functions for this scene
  233. EventManager.OnLandObjectAdded +=
  234. new EventManager.LandObjectAdded(m_storageManager.DataStore.StoreLandObject);
  235. EventManager.OnLandObjectRemoved +=
  236. new EventManager.LandObjectRemoved(m_storageManager.DataStore.RemoveLandObject);
  237. m_innerScene = new InnerScene(this, m_regInfo);
  238. // If the Inner scene has an Unrecoverable error, restart this sim.
  239. // Currently the only thing that causes it to happen is two kinds of specific
  240. // Physics based crashes.
  241. //
  242. // Out of memory
  243. // Operating system has killed the plugin
  244. m_innerScene.UnRecoverableError += RestartNow;
  245. RegisterDefaultSceneEvents();
  246. m_httpListener = httpServer;
  247. m_dumpAssetsToFile = dumpAssetsToFile;
  248. m_scripts_enabled = !RegionInfo.RegionSettings.DisableScripts;
  249. m_physics_enabled = !RegionInfo.RegionSettings.DisablePhysics;
  250. m_statsReporter = new SimStatsReporter(this);
  251. m_statsReporter.OnSendStatsResult += SendSimStatsPackets;
  252. m_statsReporter.SetObjectCapacity(objectCapacity);
  253. m_simulatorVersion = simulatorVersion
  254. + " ChilTasks:" + m_seeIntoRegionFromNeighbor.ToString()
  255. + " PhysPrim:" + m_physicalPrim.ToString();
  256. }
  257. #endregion
  258. #region Startup / Close Methods
  259. protected virtual void RegisterDefaultSceneEvents()
  260. {
  261. m_eventManager.OnPermissionError += SendPermissionAlert;
  262. }
  263. public override string GetSimulatorVersion()
  264. {
  265. return m_simulatorVersion;
  266. }
  267. public override bool OtherRegionUp(RegionInfo otherRegion)
  268. {
  269. // Another region is up.
  270. // Gets called from Grid Comms (SceneCommunicationService<---RegionListener<----LocalBackEnd<----OGS1)
  271. // We have to tell all our ScenePresences about it..
  272. // and add it to the neighbor list.
  273. // We only add it to the neighbor list if it's within 1 region from here.
  274. // Agents may have draw distance values that cross two regions though, so
  275. // we add it to the notify list regardless of distance.
  276. // We'll check the agent's draw distance before notifying them though.
  277. if (RegionInfo.RegionHandle != otherRegion.RegionHandle)
  278. {
  279. for (int i = 0; i < m_neighbours.Count; i++)
  280. {
  281. // The purpose of this loop is to re-update the known neighbors
  282. // when another region comes up on top of another one.
  283. // The latest region in that location ends up in the
  284. // 'known neighbors list'
  285. // Additionally, the commFailTF property gets reset to false.
  286. if (m_neighbours[i].RegionHandle == otherRegion.RegionHandle)
  287. {
  288. lock (m_neighbours)
  289. {
  290. m_neighbours[i] = otherRegion;
  291. }
  292. }
  293. }
  294. // If the value isn't in the neighbours, add it.
  295. // If the RegionInfo isn't exact but is for the same XY World location,
  296. // then the above loop will fix that.
  297. if (!(CheckNeighborRegion(otherRegion)))
  298. {
  299. lock (m_neighbours)
  300. {
  301. m_neighbours.Add(otherRegion);
  302. //m_log.Info("[UP]: " + otherRegion.RegionHandle.ToString());
  303. }
  304. }
  305. // If these are cast to INT because long + negative values + abs returns invalid data
  306. int resultX = Math.Abs((int)otherRegion.RegionLocX - (int)RegionInfo.RegionLocX);
  307. int resultY = Math.Abs((int)otherRegion.RegionLocY - (int)RegionInfo.RegionLocY);
  308. if ((resultX <= 1) &&
  309. (resultY <= 1))
  310. {
  311. try
  312. {
  313. ForEachScenePresence(delegate(ScenePresence agent)
  314. {
  315. // If agent is a root agent.
  316. if (!agent.IsChildAgent)
  317. {
  318. //agent.ControllingClient.new
  319. //this.CommsManager.InterRegion.InformRegionOfChildAgent(otherRegion.RegionHandle, agent.ControllingClient.RequestClientInfo());
  320. InformClientOfNeighbor(agent, otherRegion);
  321. }
  322. }
  323. );
  324. }
  325. catch (NullReferenceException)
  326. {
  327. // This means that we're not booted up completely yet.
  328. // This shouldn't happen too often anymore.
  329. m_log.Error("[SCENE]: Couldn't inform client of regionup because we got a null reference exception");
  330. }
  331. }
  332. else
  333. {
  334. m_log.Info("[INTERGRID]: Got notice about far away Region: " + otherRegion.RegionName.ToString() +
  335. " at (" + otherRegion.RegionLocX.ToString() + ", " +
  336. otherRegion.RegionLocY.ToString() + ")");
  337. }
  338. }
  339. return true;
  340. }
  341. // Given float seconds, this will restart the region.
  342. public void AddNeighborRegion(RegionInfo region)
  343. {
  344. lock (m_neighbours)
  345. {
  346. if (!CheckNeighborRegion(region))
  347. {
  348. m_neighbours.Add(region);
  349. }
  350. }
  351. }
  352. public bool CheckNeighborRegion(RegionInfo region)
  353. {
  354. bool found = false;
  355. lock (m_neighbours)
  356. {
  357. foreach (RegionInfo reg in m_neighbours)
  358. {
  359. if (reg.RegionHandle == region.RegionHandle)
  360. {
  361. found = true;
  362. break;
  363. }
  364. }
  365. }
  366. return found;
  367. }
  368. public virtual void Restart(float seconds)
  369. {
  370. // notifications are done in 15 second increments
  371. // so .. if the number of seconds is less then 15 seconds, it's not really a restart request
  372. // It's a 'Cancel restart' request.
  373. // RestartNow() does immediate restarting.
  374. if (seconds < 15)
  375. {
  376. m_restartTimer.Stop();
  377. SendGeneralAlert("Restart Aborted");
  378. }
  379. else
  380. {
  381. // Now we figure out what to set the timer to that does the notifications and calls, RestartNow()
  382. m_restartTimer.Interval = 15000;
  383. m_incrementsof15seconds = (int)seconds / 15;
  384. m_RestartTimerCounter = 0;
  385. m_restartTimer.AutoReset = true;
  386. m_restartTimer.Elapsed += new ElapsedEventHandler(RestartTimer_Elapsed);
  387. m_log.Error("[REGION]: Restarting Region in " + (seconds / 60) + " minutes");
  388. m_restartTimer.Start();
  389. SendRegionMessageFromEstateTools(LLUUID.Random(), LLUUID.Random(), String.Empty, RegionInfo.RegionName + ": Restarting in 2 Minutes");
  390. //SendGeneralAlert(RegionInfo.RegionName + ": Restarting in 2 Minutes");
  391. }
  392. }
  393. // The Restart timer has occured.
  394. // We have to figure out if this is a notification or if the number of seconds specified in Restart
  395. // have elapsed.
  396. // If they have elapsed, call RestartNow()
  397. public void RestartTimer_Elapsed(object sender, ElapsedEventArgs e)
  398. {
  399. m_RestartTimerCounter++;
  400. if (m_RestartTimerCounter <= m_incrementsof15seconds)
  401. {
  402. if (m_RestartTimerCounter == 4 || m_RestartTimerCounter == 6 || m_RestartTimerCounter == 7)
  403. SendRegionMessageFromEstateTools(LLUUID.Random(), LLUUID.Random(), String.Empty, RegionInfo.RegionName + ": Restarting in " +
  404. ((8 - m_RestartTimerCounter) * 15) + " seconds");
  405. // SendGeneralAlert(RegionInfo.RegionName + ": Restarting in " + ((8 - m_RestartTimerCounter)*15) +
  406. //" seconds");
  407. }
  408. else
  409. {
  410. m_restartTimer.Stop();
  411. m_restartTimer.AutoReset = false;
  412. RestartNow();
  413. }
  414. }
  415. // This causes the region to restart immediatley.
  416. public void RestartNow()
  417. {
  418. if (PhysicsScene != null)
  419. {
  420. PhysicsScene.Dispose();
  421. }
  422. m_log.Error("[REGION]: Closing");
  423. Close();
  424. m_log.Error("[REGION]: Firing Region Restart Message");
  425. base.Restart(0);
  426. }
  427. // This is a helper function that notifies root agents in this region that a new sim near them has come up
  428. // This is in the form of a timer because when an instance of OpenSim.exe is started,
  429. // Even though the sims initialize, they don't listen until 'all of the sims are initialized'
  430. // If we tell an agent about a sim that's not listening yet, the agent will not be able to connect to it.
  431. // subsequently the agent will never see the region come back online.
  432. public void RestartNotifyWaitElapsed(object sender, ElapsedEventArgs e)
  433. {
  434. m_restartWaitTimer.Stop();
  435. lock (m_regionRestartNotifyList)
  436. {
  437. foreach (RegionInfo region in m_regionRestartNotifyList)
  438. {
  439. try
  440. {
  441. ForEachScenePresence(delegate(ScenePresence agent)
  442. {
  443. // If agent is a root agent.
  444. if (!agent.IsChildAgent)
  445. {
  446. //agent.ControllingClient.new
  447. //this.CommsManager.InterRegion.InformRegionOfChildAgent(otherRegion.RegionHandle, agent.ControllingClient.RequestClientInfo());
  448. InformClientOfNeighbor(agent, region);
  449. }
  450. }
  451. );
  452. }
  453. catch (NullReferenceException)
  454. {
  455. // This means that we're not booted up completely yet.
  456. // This shouldn't happen too often anymore.
  457. }
  458. }
  459. // Reset list to nothing.
  460. m_regionRestartNotifyList.Clear();
  461. }
  462. }
  463. public void SetSceneCoreDebug(bool ScriptEngine, bool CollisionEvents, bool PhysicsEngine)
  464. {
  465. if (m_scripts_enabled != !ScriptEngine)
  466. {
  467. // Tedd! Here's the method to disable the scripting engine!
  468. if (ScriptEngine)
  469. {
  470. m_log.Info("Stopping all Scripts in Scene");
  471. lock (Entities)
  472. {
  473. foreach (EntityBase ent in Entities.Values)
  474. {
  475. if (ent is SceneObjectGroup)
  476. {
  477. ((SceneObjectGroup)ent).RemoveScriptInstances();
  478. }
  479. }
  480. }
  481. }
  482. else
  483. {
  484. m_log.Info("Starting all Scripts in Scene");
  485. lock (Entities)
  486. {
  487. foreach (EntityBase ent in Entities.Values)
  488. {
  489. if (ent is SceneObjectGroup)
  490. {
  491. ((SceneObjectGroup)ent).CreateScriptInstances(0, false);
  492. }
  493. }
  494. }
  495. }
  496. m_scripts_enabled = !ScriptEngine;
  497. m_log.Info("[TOTEDD]: Here is the method to trigger disabling of the scripting engine");
  498. }
  499. if (m_physics_enabled != !PhysicsEngine)
  500. {
  501. m_physics_enabled = !PhysicsEngine;
  502. }
  503. }
  504. public int GetInaccurateNeighborCount()
  505. {
  506. lock (m_neighbours)
  507. return m_neighbours.Count;
  508. }
  509. // This is the method that shuts down the scene.
  510. public override void Close()
  511. {
  512. m_log.InfoFormat("[SCENE]: Closing down the single simulator: {0}", RegionInfo.RegionName);
  513. // Kick all ROOT agents with the message, 'The simulator is going down'
  514. ForEachScenePresence(delegate(ScenePresence avatar)
  515. {
  516. if (avatar.KnownChildRegions.Contains(RegionInfo.RegionHandle))
  517. avatar.KnownChildRegions.Remove(RegionInfo.RegionHandle);
  518. if (!avatar.IsChildAgent)
  519. avatar.ControllingClient.Kick("The simulator is going down.");
  520. avatar.ControllingClient.SendShutdownConnectionNotice();
  521. });
  522. // Wait here, or the kick messages won't actually get to the agents before the scene terminates.
  523. Thread.Sleep(500);
  524. // Stop all client threads.
  525. ForEachScenePresence(delegate(ScenePresence avatar) { avatar.ControllingClient.Close(true); });
  526. // Stop updating the scene objects and agents.
  527. m_heartbeatTimer.Close();
  528. // close the inner scene
  529. m_innerScene.Close();
  530. // De-register with region communications (events cleanup)
  531. UnRegisterReginWithComms();
  532. // Shut down all non shared modules.
  533. foreach (IRegionModule module in Modules.Values)
  534. {
  535. if (!module.IsSharedModule)
  536. {
  537. module.Close();
  538. }
  539. }
  540. Modules.Clear();
  541. // call the base class Close method.
  542. base.Close();
  543. }
  544. /// <summary>
  545. /// Start the timer which triggers regular scene updates
  546. /// </summary>
  547. public void StartTimer()
  548. {
  549. m_log.Debug("[SCENE]: Starting timer");
  550. m_heartbeatTimer.Enabled = true;
  551. m_heartbeatTimer.Interval = (int)(m_timespan * 1000);
  552. m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat);
  553. }
  554. /// <summary>
  555. /// Sets up references to modules required by the scene
  556. /// </summary>
  557. public void SetModuleInterfaces()
  558. {
  559. m_httpRequestModule = RequestModuleInterface<IHttpRequests>();
  560. m_xmlrpcModule = RequestModuleInterface<IXMLRPC>();
  561. m_worldCommModule = RequestModuleInterface<IWorldComm>();
  562. XferManager = RequestModuleInterface<IXfer>();
  563. m_AvatarFactory = RequestModuleInterface<IAvatarFactory>();
  564. m_archiver = RequestModuleInterface<IRegionArchiver>();
  565. m_serialiser = RequestModuleInterface<IRegionSerialiser>();
  566. }
  567. #endregion
  568. #region Update Methods
  569. /// <summary>
  570. /// Performs per-frame updates regularly
  571. /// </summary>
  572. /// <param name="sender"></param>
  573. /// <param name="e"></param>
  574. private void Heartbeat(object sender, EventArgs e)
  575. {
  576. Update();
  577. }
  578. /// <summary>
  579. /// Performs per-frame updates on the scene, this should be the central scene loop
  580. /// </summary>
  581. public override void Update()
  582. {
  583. TimeSpan SinceLastFrame = DateTime.Now - m_lastupdate;
  584. // Aquire a lock so only one update call happens at once
  585. updateLock.WaitOne();
  586. float physicsFPS = 0;
  587. //m_log.Info("sadfadf" + m_neighbours.Count.ToString());
  588. int agentsInScene = m_innerScene.GetRootAgentCount() + m_innerScene.GetChildAgentCount();
  589. if (agentsInScene > 21)
  590. {
  591. if (m_update_entities == 1)
  592. {
  593. m_update_entities = 5;
  594. m_statsReporter.SetUpdateMS(6000);
  595. }
  596. }
  597. else
  598. {
  599. if (m_update_entities == 5)
  600. {
  601. m_update_entities = 1;
  602. m_statsReporter.SetUpdateMS(3000);
  603. }
  604. }
  605. frameMS = System.Environment.TickCount;
  606. try
  607. {
  608. // Increment the frame counter
  609. m_frame++;
  610. // Loop it
  611. if (m_frame == Int32.MaxValue)
  612. m_frame = 0;
  613. physicsMS2 = System.Environment.TickCount;
  614. if ((m_frame % m_update_physics == 0) && m_physics_enabled)
  615. m_innerScene.UpdatePreparePhysics();
  616. physicsMS2 = System.Environment.TickCount - physicsMS2;
  617. if (m_frame % m_update_entitymovement == 0)
  618. m_innerScene.UpdateEntityMovement();
  619. physicsMS = System.Environment.TickCount;
  620. if ((m_frame % m_update_physics == 0) && m_physics_enabled)
  621. physicsFPS = m_innerScene.UpdatePhysics(
  622. Math.Max(SinceLastFrame.TotalSeconds, m_timespan)
  623. );
  624. if (m_frame % m_update_physics == 0 && SynchronizeScene != null)
  625. SynchronizeScene(this);
  626. physicsMS = System.Environment.TickCount - physicsMS;
  627. physicsMS += physicsMS2;
  628. otherMS = System.Environment.TickCount;
  629. // run through all entities looking for updates (slow)
  630. if (m_frame % m_update_entities == 0)
  631. m_innerScene.UpdateEntities();
  632. // run through entities that have scheduled themselves for
  633. // updates looking for updates(faster)
  634. if (m_frame % m_update_entitiesquick == 0)
  635. m_innerScene.ProcessUpdates();
  636. // Run through scenepresences looking for updates
  637. if (m_frame % m_update_presences == 0)
  638. m_innerScene.UpdatePresences();
  639. if (Region_Status != RegionStatus.SlaveScene)
  640. {
  641. if (m_frame % m_update_events == 0)
  642. UpdateEvents();
  643. if (m_frame % m_update_backup == 0)
  644. {
  645. UpdateStorageBackup();
  646. }
  647. if (m_frame % m_update_terrain == 0)
  648. UpdateTerrain();
  649. if (m_frame % m_update_land == 0)
  650. UpdateLand();
  651. otherMS = System.Environment.TickCount - otherMS;
  652. // if (m_frame%m_update_avatars == 0)
  653. // UpdateInWorldTime();
  654. m_statsReporter.AddPhysicsFPS(physicsFPS);
  655. m_statsReporter.AddTimeDilation(m_timedilation);
  656. m_statsReporter.AddFPS(1);
  657. m_statsReporter.AddInPackets(0);
  658. m_statsReporter.SetRootAgents(m_innerScene.GetRootAgentCount());
  659. m_statsReporter.SetChildAgents(m_innerScene.GetChildAgentCount());
  660. m_statsReporter.SetObjects(m_innerScene.GetTotalObjectsCount());
  661. m_statsReporter.SetActiveObjects(m_innerScene.GetActiveObjectsCount());
  662. frameMS = System.Environment.TickCount - frameMS;
  663. m_statsReporter.addFrameMS(frameMS);
  664. m_statsReporter.addPhysicsMS(physicsMS);
  665. m_statsReporter.addOtherMS(otherMS);
  666. m_statsReporter.SetActiveScripts(m_innerScene.GetActiveScriptsCount());
  667. m_statsReporter.addScriptLines(m_innerScene.GetScriptLPS());
  668. }
  669. }
  670. catch (NotImplementedException)
  671. {
  672. throw;
  673. }
  674. catch (AccessViolationException e)
  675. {
  676. m_log.Error("[Scene]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
  677. }
  678. catch (NullReferenceException e)
  679. {
  680. m_log.Error("[Scene]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
  681. }
  682. catch (InvalidOperationException e)
  683. {
  684. m_log.Error("[Scene]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
  685. }
  686. catch (Exception e)
  687. {
  688. m_log.Error("[Scene]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
  689. }
  690. finally
  691. {
  692. updateLock.ReleaseMutex();
  693. // Get actual time dilation
  694. float tmpval = (m_timespan / (float)SinceLastFrame.TotalSeconds);
  695. // If actual time dilation is greater then one, we're catching up, so subtract
  696. // the amount that's greater then 1 from the time dilation
  697. if (tmpval > 1.0)
  698. {
  699. tmpval = tmpval - (tmpval - 1.0f);
  700. }
  701. m_timedilation = tmpval;
  702. m_lastupdate = DateTime.Now;
  703. }
  704. }
  705. private void SendSimStatsPackets(SimStatsPacket pack)
  706. {
  707. List<ScenePresence> StatSendAgents = GetScenePresences();
  708. foreach (ScenePresence agent in StatSendAgents)
  709. {
  710. if (!agent.IsChildAgent)
  711. {
  712. agent.ControllingClient.SendSimStats(pack);
  713. }
  714. }
  715. }
  716. private void UpdateLand()
  717. {
  718. if (LandChannel != null)
  719. {
  720. if (LandChannel.IsLandPrimCountTainted())
  721. {
  722. EventManager.TriggerParcelPrimCountUpdate();
  723. }
  724. }
  725. }
  726. private void UpdateTerrain()
  727. {
  728. EventManager.TriggerTerrainTick();
  729. }
  730. private void UpdateStorageBackup()
  731. {
  732. if (!m_backingup)
  733. {
  734. m_backingup = true;
  735. Thread backupthread = new Thread(Backup);
  736. backupthread.Name = "BackupWriter";
  737. backupthread.IsBackground = true;
  738. backupthread.Start();
  739. }
  740. }
  741. private void UpdateEvents()
  742. {
  743. m_eventManager.TriggerOnFrame();
  744. }
  745. /// <summary>
  746. /// Perform delegate action on all clients subscribing to updates from this region.
  747. /// </summary>
  748. /// <returns></returns>
  749. internal void Broadcast(Action<IClientAPI> whatToDo)
  750. {
  751. ForEachScenePresence(delegate(ScenePresence presence) { whatToDo(presence.ControllingClient); });
  752. }
  753. /// <summary>
  754. /// Backup the scene. This acts as the main method of the backup thread.
  755. /// </summary>
  756. /// <returns></returns>
  757. public void Backup()
  758. {
  759. EventManager.TriggerOnBackup(m_storageManager.DataStore);
  760. m_backingup = false;
  761. //return true;
  762. }
  763. #endregion
  764. #region Load Terrain
  765. public void ExportWorldMap(string fileName)
  766. {
  767. List<MapBlockData> mapBlocks =
  768. m_sceneGridService.RequestNeighbourMapBlocks((int)(RegionInfo.RegionLocX - 9),
  769. (int)(RegionInfo.RegionLocY - 9),
  770. (int)(RegionInfo.RegionLocX + 9),
  771. (int)(RegionInfo.RegionLocY + 9));
  772. List<AssetBase> textures = new List<AssetBase>();
  773. List<Image> bitImages = new List<Image>();
  774. foreach (MapBlockData mapBlock in mapBlocks)
  775. {
  776. AssetBase texAsset = AssetCache.GetAsset(mapBlock.MapImageId, true);
  777. if (texAsset != null)
  778. {
  779. textures.Add(texAsset);
  780. }
  781. else
  782. {
  783. texAsset = AssetCache.GetAsset(mapBlock.MapImageId, true);
  784. if (texAsset != null)
  785. {
  786. textures.Add(texAsset);
  787. }
  788. }
  789. }
  790. foreach (AssetBase asset in textures)
  791. {
  792. Image image = OpenJPEG.DecodeToImage(asset.Data);
  793. bitImages.Add(image);
  794. }
  795. Bitmap mapTexture = new Bitmap(2560, 2560);
  796. Graphics g = Graphics.FromImage(mapTexture);
  797. SolidBrush sea = new SolidBrush(Color.DarkBlue);
  798. g.FillRectangle(sea, 0, 0, 2560, 2560);
  799. for (int i = 0; i < mapBlocks.Count; i++)
  800. {
  801. ushort x = (ushort)((mapBlocks[i].X - RegionInfo.RegionLocX) + 10);
  802. ushort y = (ushort)((mapBlocks[i].Y - RegionInfo.RegionLocY) + 10);
  803. g.DrawImage(bitImages[i], (x * 128), (y * 128), 128, 128);
  804. }
  805. mapTexture.Save(fileName, ImageFormat.Jpeg);
  806. }
  807. public void SaveTerrain()
  808. {
  809. m_storageManager.DataStore.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID);
  810. }
  811. /// <summary>
  812. /// Loads the World heightmap
  813. /// </summary>
  814. ///
  815. public override void LoadWorldMap()
  816. {
  817. try
  818. {
  819. double[,] map = m_storageManager.DataStore.LoadTerrain(RegionInfo.RegionID);
  820. if (map == null)
  821. {
  822. m_log.Info("[TERRAIN]: No default terrain. Generating a new terrain.");
  823. Heightmap = new TerrainChannel();
  824. m_storageManager.DataStore.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID);
  825. }
  826. else
  827. {
  828. Heightmap = new TerrainChannel(map);
  829. }
  830. }
  831. catch (Exception e)
  832. {
  833. m_log.Warn("[terrain]: Scene.cs: LoadWorldMap() - Failed with exception " + e.ToString());
  834. }
  835. }
  836. /// <summary>
  837. /// Register this region with a grid service
  838. /// </summary>
  839. /// <exception cref="System.Exception">Thrown if registration of the region itself fails.</exception>
  840. public void RegisterRegionWithGrid()
  841. {
  842. RegisterCommsEvents();
  843. // These two 'commands' *must be* next to each other or sim rebooting fails.
  844. m_sceneGridService.RegisterRegion(RegionInfo);
  845. m_sceneGridService.InformNeighborsThatRegionisUp(RegionInfo);
  846. Dictionary<string, string> dGridSettings = m_sceneGridService.GetGridSettings();
  847. if (dGridSettings.ContainsKey("allow_forceful_banlines"))
  848. {
  849. if (dGridSettings["allow_forceful_banlines"] != "TRUE")
  850. {
  851. m_log.Info("[GRID]: Grid is disabling forceful parcel banlists");
  852. EventManager.TriggerSetAllowForcefulBan(false);
  853. }
  854. else
  855. {
  856. m_log.Info("[GRID]: Grid is allowing forceful parcel banlists");
  857. EventManager.TriggerSetAllowForcefulBan(true);
  858. }
  859. }
  860. }
  861. /// <summary>
  862. ///
  863. /// </summary>
  864. public void CreateTerrainTexture(bool temporary)
  865. {
  866. //create a texture asset of the terrain
  867. IMapImageGenerator terrain = RequestModuleInterface<IMapImageGenerator>();
  868. // Cannot create a map for a nonexistant heightmap yet.
  869. if (Heightmap == null)
  870. return;
  871. if (terrain == null)
  872. {
  873. int tc = System.Environment.TickCount;
  874. m_log.Info("[MAPTILE]: Generating Maptile Step 1: Terrain");
  875. Bitmap mapbmp = new Bitmap(256, 256);
  876. double[,] hm = Heightmap.GetDoubles();
  877. //Color prim = Color.FromArgb(120, 120, 120);
  878. //LLVector3 RayEnd = new LLVector3(0, 0, 0);
  879. //LLVector3 RayStart = new LLVector3(0, 0, 0);
  880. //LLVector3 direction = new LLVector3(0, 0, -1);
  881. //Vector3 AXOrigin = new Vector3();
  882. //Vector3 AXdirection = new Vector3();
  883. //Ray testRay = new Ray();
  884. //EntityIntersection rt = new EntityIntersection();
  885. bool terraincorruptedwarningsaid = false;
  886. float low = 255;
  887. float high = 0;
  888. for (int x = 0; x < 256; x++)
  889. {
  890. for (int y = 0; y < 256; y++)
  891. {
  892. float hmval = (float)hm[x, y];
  893. if (hmval < low)
  894. low = hmval;
  895. if (hmval > high)
  896. high = hmval;
  897. }
  898. }
  899. float mid = (high + low) * 0.5f;
  900. for (int x = 0; x < 256; x++)
  901. {
  902. //int tc = System.Environment.TickCount;
  903. for (int y = 0; y < 256; y++)
  904. {
  905. //RayEnd = new LLVector3(x, y, 0);
  906. //RayStart = new LLVector3(x, y, 255);
  907. //direction = LLVector3.Norm(RayEnd - RayStart);
  908. //AXOrigin = new Vector3(RayStart.X, RayStart.Y, RayStart.Z);
  909. //AXdirection = new Vector3(direction.X, direction.Y, direction.Z);
  910. //testRay = new Ray(AXOrigin, AXdirection);
  911. //rt = m_innerScene.GetClosestIntersectingPrim(testRay);
  912. //if (rt.HitTF)
  913. //{
  914. //mapbmp.SetPixel(x, y, prim);
  915. //}
  916. //else
  917. //{
  918. //float tmpval = (float)hm[x, y];
  919. float heightvalue = (float)hm[x, y];
  920. if (heightvalue > (float)m_regInfo.RegionSettings.WaterHeight)
  921. {
  922. // scale height value
  923. heightvalue = low + mid * (heightvalue - low) / mid;
  924. if (heightvalue > 255)
  925. heightvalue = 255;
  926. if (heightvalue < 0)
  927. heightvalue = 0;
  928. if (Single.IsInfinity(heightvalue) || Single.IsNaN(heightvalue))
  929. heightvalue = 0;
  930. try
  931. {
  932. Color green = Color.FromArgb((int)heightvalue, 100, (int)heightvalue);
  933. // Y flip the cordinates
  934. mapbmp.SetPixel(x, (256 - y) - 1, green);
  935. }
  936. catch (System.ArgumentException)
  937. {
  938. if (!terraincorruptedwarningsaid)
  939. {
  940. m_log.WarnFormat("[MAPIMAGE]: Your terrain is corrupted in region {0}, it might take a few minutes to generate the map image depending on the corruption level",RegionInfo.RegionName);
  941. terraincorruptedwarningsaid = true;
  942. }
  943. Color black = Color.Black;
  944. mapbmp.SetPixel(x, (256 - y) - 1, black);
  945. }
  946. }
  947. else
  948. {
  949. // Y flip the cordinates
  950. heightvalue = (float)m_regInfo.RegionSettings.WaterHeight - heightvalue;
  951. if (heightvalue > 19)
  952. heightvalue = 19;
  953. if (heightvalue < 0)
  954. heightvalue = 0;
  955. heightvalue = 100 - (heightvalue * 100) / 19;
  956. if (heightvalue > 255)
  957. heightvalue = 255;
  958. if (heightvalue < 0)
  959. heightvalue = 0;
  960. if (Single.IsInfinity(heightvalue) || Single.IsNaN(heightvalue))
  961. heightvalue = 0;
  962. try
  963. {
  964. Color water = Color.FromArgb((int)heightvalue, (int)heightvalue, 255);
  965. mapbmp.SetPixel(x, (256 - y) - 1, water);
  966. }
  967. catch (System.ArgumentException)
  968. {
  969. if (!terraincorruptedwarningsaid)
  970. {
  971. m_log.WarnFormat("[MAPIMAGE]: Your terrain is corrupted in region {0}, it might take a few minutes to generate the map image depending on the corruption level", RegionInfo.RegionName);
  972. terraincorruptedwarningsaid = true;
  973. }
  974. Color black = Color.Black;
  975. mapbmp.SetPixel(x, (256 - y) - 1, black);
  976. }
  977. }
  978. }
  979. //}
  980. //tc = System.Environment.TickCount - tc;
  981. //m_log.Info("[MAPTILE]: Completed One row in " + tc + " ms");
  982. }
  983. m_log.Info("[MAPTILE]: Generating Maptile Step 1: Done in " + (System.Environment.TickCount - tc) + " ms");
  984. bool drawPrimVolume = true;
  985. try
  986. {
  987. IConfig startupConfig = m_config.Configs["Startup"];
  988. drawPrimVolume = startupConfig.GetBoolean("DrawPrimOnMapTile", true);
  989. }
  990. catch (Exception)
  991. {
  992. m_log.Warn("Failed to load StarupConfg");
  993. }
  994. if (drawPrimVolume)
  995. {
  996. tc = System.Environment.TickCount;
  997. m_log.Info("[MAPTILE]: Generating Maptile Step 2: Object Volume Profile");
  998. List<EntityBase> objs = GetEntities();
  999. lock (objs)
  1000. {
  1001. foreach (EntityBase obj in objs)
  1002. {
  1003. // Only draw the contents of SceneObjectGroup
  1004. if (obj is SceneObjectGroup)
  1005. {
  1006. SceneObjectGroup mapdot = (SceneObjectGroup)obj;
  1007. Color mapdotspot = Color.Gray; // Default color when prim color is white
  1008. // Loop over prim in group
  1009. foreach (SceneObjectPart part in mapdot.Children.Values)
  1010. {
  1011. if (part == null)
  1012. continue;
  1013. // Draw if the object is at least 1 meter wide in any direction
  1014. if (part.Scale.X > 1f || part.Scale.Y > 1f || part.Scale.Z > 1f)
  1015. {
  1016. // Try to get the RGBA of the default texture entry..
  1017. //
  1018. try
  1019. {
  1020. if (part == null)
  1021. continue;
  1022. if (part.Shape == null)
  1023. continue;
  1024. if (part.Shape.PCode == (byte)PCode.Tree || part.Shape.PCode == (byte)PCode.NewTree)
  1025. continue; // eliminates trees from this since we don't really have a good tree representation
  1026. // if you want tree blocks on the map comment the above line and uncomment the below line
  1027. //mapdotspot = Color.PaleGreen;
  1028. if (part.Shape.Textures == null)
  1029. continue;
  1030. if (part.Shape.Textures.DefaultTexture == null)
  1031. continue;
  1032. LLColor texcolor = part.Shape.Textures.DefaultTexture.RGBA;
  1033. // Not sure why some of these are null, oh well.
  1034. int colorr = 255 - (int)(texcolor.R * 255f);
  1035. int colorg = 255 - (int)(texcolor.G * 255f);
  1036. int colorb = 255 - (int)(texcolor.B * 255f);
  1037. if (!(colorr == 255 && colorg == 255 && colorb == 255))
  1038. {
  1039. //Try to set the map spot color
  1040. try
  1041. {
  1042. // If the color gets goofy somehow, skip it *shakes fist at LLColor
  1043. mapdotspot = Color.FromArgb(colorr, colorg, colorb);
  1044. }
  1045. catch (ArgumentException)
  1046. {
  1047. }
  1048. }
  1049. }
  1050. catch (IndexOutOfRangeException)
  1051. {
  1052. // Windows Array
  1053. }
  1054. catch (ArgumentOutOfRangeException)
  1055. {
  1056. // Mono Array
  1057. }
  1058. LLVector3 pos = part.GetWorldPosition();
  1059. // skip prim outside of retion
  1060. if (pos.X < 0f || pos.X > 256f || pos.Y < 0f || pos.Y > 256f)
  1061. continue;
  1062. // skip prim in non-finite position
  1063. if (Single.IsNaN(pos.X) || Single.IsNaN(pos.Y) || Single.IsInfinity(pos.X)
  1064. || Single.IsInfinity(pos.Y))
  1065. continue;
  1066. // Figure out if object is under 256m above the height of the terrain
  1067. bool isBelow256AboveTerrain = false;
  1068. try
  1069. {
  1070. isBelow256AboveTerrain = (pos.Z < ((float)hm[(int)pos.X, (int)pos.Y] + 256f));
  1071. }
  1072. catch (Exception)
  1073. {
  1074. }
  1075. if (isBelow256AboveTerrain)
  1076. {
  1077. // Translate scale by rotation so scale is represented properly when object is rotated
  1078. Vector3 scale = new Vector3(part.Shape.Scale.X, part.Shape.Scale.Y, part.Shape.Scale.Z);
  1079. LLQuaternion llrot = part.GetWorldRotation();
  1080. Quaternion rot = new Quaternion(llrot.W, llrot.X, llrot.Y, llrot.Z);
  1081. scale = rot * scale;
  1082. // negative scales don't work in this situation
  1083. scale.x = Math.Abs(scale.x);
  1084. scale.y = Math.Abs(scale.y);
  1085. scale.z = Math.Abs(scale.z);
  1086. // This scaling isn't very accurate and doesn't take into account the face rotation :P
  1087. int mapdrawstartX = (int)(pos.X - scale.x);
  1088. int mapdrawstartY = (int)(pos.Y - scale.y);
  1089. int mapdrawendX = (int)(pos.X + scale.x);
  1090. int mapdrawendY = (int)(pos.Y + scale.y);
  1091. // If object is beyond the edge of the map, don't draw it to avoid errors
  1092. if (mapdrawstartX < 0 || mapdrawstartX > 255 || mapdrawendX < 0 || mapdrawendX > 255
  1093. || mapdrawstartY < 0 || mapdrawstartY > 255 || mapdrawendY < 0
  1094. || mapdrawendY > 255)
  1095. continue;
  1096. int wy = 0;
  1097. bool breakYN = false; // If we run into an error drawing, break out of the
  1098. // loop so we don't lag to death on error handling
  1099. for (int wx = mapdrawstartX; wx < mapdrawendX; wx++)
  1100. {
  1101. for (wy = mapdrawstartY; wy < mapdrawendY; wy++)
  1102. {
  1103. //m_log.InfoFormat("[MAPDEBUG]: {0},{1}({2})", wx, (255 - wy),wy);
  1104. try
  1105. {
  1106. // Remember, flip the y!
  1107. mapbmp.SetPixel(wx, (255 - wy), mapdotspot);
  1108. }
  1109. catch (ArgumentException)
  1110. {
  1111. breakYN = true;
  1112. }
  1113. if (breakYN)
  1114. break;
  1115. }
  1116. if (breakYN)
  1117. break;
  1118. }
  1119. } // Object is within 256m Z of terrain
  1120. } // object is at least a meter wide
  1121. } // loop over group children
  1122. } // entitybase is sceneobject group
  1123. } // foreach loop over entities
  1124. } // lock entities objs
  1125. m_log.Info("[MAPTILE]: Generating Maptile Step 2: Done in " + (System.Environment.TickCount - tc) + " ms");
  1126. } // end if drawPrimOnMaptle
  1127. byte[] data;
  1128. try
  1129. {
  1130. data = OpenJPEG.EncodeFromImage(mapbmp, false);
  1131. }
  1132. catch (Exception)
  1133. {
  1134. return;
  1135. }
  1136. LLUUID lastMapRegionUUID = m_regInfo.lastMapUUID;
  1137. int lastMapRefresh = 0;
  1138. int twoDays = 172800;
  1139. int RefreshSeconds = twoDays;
  1140. try
  1141. {
  1142. lastMapRefresh = Convert.ToInt32(m_regInfo.lastMapRefresh);
  1143. }
  1144. catch (ArgumentException)
  1145. {
  1146. }
  1147. catch (FormatException)
  1148. {
  1149. }
  1150. catch (OverflowException)
  1151. {
  1152. }
  1153. LLUUID TerrainImageLLUUID = LLUUID.Random();
  1154. if (lastMapRegionUUID == LLUUID.Zero || (lastMapRefresh + RefreshSeconds) < Util.UnixTimeSinceEpoch())
  1155. {
  1156. m_regInfo.SaveLastMapUUID(TerrainImageLLUUID);
  1157. m_log.Warn("[MAPTILE]: STORING MAPTILE IMAGE");
  1158. //Extra protection.. probably not needed.
  1159. }
  1160. else
  1161. {
  1162. TerrainImageLLUUID = lastMapRegionUUID;
  1163. m_log.Warn("[MAPTILE]: REUSING OLD MAPTILE IMAGE ID");
  1164. }
  1165. m_regInfo.RegionSettings.TerrainImageID = TerrainImageLLUUID;
  1166. AssetBase asset = new AssetBase();
  1167. asset.FullID = m_regInfo.RegionSettings.TerrainImageID;
  1168. asset.Data = data;
  1169. asset.Name = "terrainImage_" + m_regInfo.RegionID.ToString() + "_" + lastMapRefresh.ToString();
  1170. asset.Description = RegionInfo.RegionName;
  1171. asset.Type = 0;
  1172. asset.Temporary = temporary;
  1173. AssetCache.AddAsset(asset);
  1174. }
  1175. else
  1176. {
  1177. byte[] data = terrain.WriteJpeg2000Image("defaultstripe.png");
  1178. if (data != null)
  1179. {
  1180. LLUUID lastMapRegionUUID = m_regInfo.lastMapUUID;
  1181. int lastMapRefresh = 0;
  1182. int twoDays = 172800;
  1183. int RefreshSeconds = twoDays;
  1184. try
  1185. {
  1186. lastMapRefresh = Convert.ToInt32(m_regInfo.lastMapRefresh);
  1187. }
  1188. catch (ArgumentException)
  1189. {
  1190. }
  1191. catch (FormatException)
  1192. {
  1193. }
  1194. catch (OverflowException)
  1195. {
  1196. }
  1197. LLUUID TerrainImageLLUUID = LLUUID.Random();
  1198. if (lastMapRegionUUID == LLUUID.Zero || (lastMapRefresh + RefreshSeconds) < Util.UnixTimeSinceEpoch())
  1199. {
  1200. m_regInfo.SaveLastMapUUID(TerrainImageLLUUID);
  1201. //m_log.Warn(terrainImageID);
  1202. //Extra protection.. probably not needed.
  1203. }
  1204. else
  1205. {
  1206. TerrainImageLLUUID = lastMapRegionUUID;
  1207. }
  1208. m_regInfo.RegionSettings.TerrainImageID = TerrainImageLLUUID;
  1209. AssetBase asset = new AssetBase();
  1210. asset.FullID = m_regInfo.RegionSettings.TerrainImageID;
  1211. asset.Data = data;
  1212. asset.Name = "terrainImage_" + m_regInfo.RegionID.ToString() + "_" + lastMapRefresh.ToString();
  1213. asset.Description = RegionInfo.RegionName;
  1214. asset.Type = 0;
  1215. asset.Temporary = temporary;
  1216. AssetCache.AddAsset(asset);
  1217. }
  1218. }
  1219. }
  1220. #endregion
  1221. #region Load Land
  1222. public void loadAllLandObjectsFromStorage(LLUUID regionID)
  1223. {
  1224. m_log.Info("[SCENE]: Loading land objects from storage");
  1225. List<LandData> landData = m_storageManager.DataStore.LoadLandObjects(regionID);
  1226. if (LandChannel != null)
  1227. {
  1228. if (landData.Count == 0)
  1229. {
  1230. EventManager.TriggerNoticeNoLandDataFromStorage();
  1231. }
  1232. else
  1233. {
  1234. EventManager.TriggerIncomingLandDataFromStorage(landData);
  1235. }
  1236. }
  1237. else
  1238. {
  1239. m_log.Error("[SCENE]: Land Channel is not defined. Cannot load from storage!");
  1240. }
  1241. }
  1242. #endregion
  1243. #region Primitives Methods
  1244. /// <summary>
  1245. /// Loads the World's objects
  1246. /// </summary>
  1247. public virtual void LoadPrimsFromStorage(LLUUID regionID)
  1248. {
  1249. m_log.Info("[SCENE]: Loading objects from datastore");
  1250. List<SceneObjectGroup> PrimsFromDB = m_storageManager.DataStore.LoadObjects(regionID);
  1251. foreach (SceneObjectGroup group in PrimsFromDB)
  1252. {
  1253. AddRestoredSceneObject(group, true, true);
  1254. SceneObjectPart rootPart = group.GetChildPart(group.UUID);
  1255. rootPart.ObjectFlags &= ~(uint)LLObject.ObjectFlags.Scripted;
  1256. rootPart.TrimPermissions();
  1257. group.CheckSculptAndLoad();
  1258. //rootPart.DoPhysicsPropertyUpdate(UsePhysics, true);
  1259. }
  1260. m_log.Info("[SCENE]: Loaded " + PrimsFromDB.Count.ToString() + " SceneObject(s)");
  1261. }
  1262. /// <summary>
  1263. /// Returns a new unallocated local primitive ID
  1264. /// </summary>
  1265. /// <returns>A brand new local primitive ID</returns>
  1266. public uint PrimIDAllocate()
  1267. {
  1268. uint myID;
  1269. _primAllocateMutex.WaitOne();
  1270. myID = ++m_lastAllocatedLocalId;
  1271. _primAllocateMutex.ReleaseMutex();
  1272. return myID;
  1273. }
  1274. public LLVector3 GetNewRezLocation(LLVector3 RayStart, LLVector3 RayEnd, LLUUID RayTargetID, LLQuaternion rot, byte bypassRayCast, byte RayEndIsIntersection, bool frontFacesOnly, LLVector3 scale, bool FaceCenter)
  1275. {
  1276. LLVector3 pos = LLVector3.Zero;
  1277. if (RayEndIsIntersection == (byte)1)
  1278. {
  1279. pos = RayEnd;
  1280. return pos;
  1281. }
  1282. if (RayTargetID != LLUUID.Zero)
  1283. {
  1284. SceneObjectPart target = GetSceneObjectPart(RayTargetID);
  1285. LLVector3 direction = LLVector3.Norm(RayEnd - RayStart);
  1286. Vector3 AXOrigin = new Vector3(RayStart.X, RayStart.Y, RayStart.Z);
  1287. Vector3 AXdirection = new Vector3(direction.X, direction.Y, direction.Z);
  1288. if (target != null)
  1289. {
  1290. pos = target.AbsolutePosition;
  1291. //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());
  1292. // TODO: Raytrace better here
  1293. //EntityIntersection ei = m_innerScene.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection));
  1294. Ray NewRay = new Ray(AXOrigin, AXdirection);
  1295. // Ray Trace against target here
  1296. EntityIntersection ei = target.TestIntersectionOBB(NewRay, new Quaternion(1,0,0,0), frontFacesOnly, FaceCenter);
  1297. // Un-comment out the following line to Get Raytrace results printed to the console.
  1298. // m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString());
  1299. float ScaleOffset = 0.5f;
  1300. // If we hit something
  1301. if (ei.HitTF)
  1302. {
  1303. LLVector3 scaleComponent = new LLVector3(ei.AAfaceNormal.x, ei.AAfaceNormal.y, ei.AAfaceNormal.z);
  1304. if (scaleComponent.X != 0) ScaleOffset = scale.X;
  1305. if (scaleComponent.Y != 0) ScaleOffset = scale.Y;
  1306. if (scaleComponent.Z != 0) ScaleOffset = scale.Z;
  1307. ScaleOffset = Math.Abs(ScaleOffset);
  1308. LLVector3 intersectionpoint = new LLVector3(ei.ipoint.x, ei.ipoint.y, ei.ipoint.z);
  1309. LLVector3 normal = new LLVector3(ei.normal.x, ei.normal.y, ei.normal.z);
  1310. // Set the position to the intersection point
  1311. LLVector3 offset = (normal * (ScaleOffset / 2f));
  1312. pos = (intersectionpoint + offset);
  1313. // Un-offset the prim (it gets offset later by the consumer method)
  1314. pos.Z -= 0.25F;
  1315. }
  1316. return pos;
  1317. }
  1318. else
  1319. {
  1320. // We don't have a target here, so we're going to raytrace all the objects in the scene.
  1321. EntityIntersection ei = m_innerScene.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection), true, false);
  1322. // Un-comment the following line to print the raytrace results to the console.
  1323. //m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString());
  1324. if (ei.HitTF)
  1325. {
  1326. pos = new LLVector3(ei.ipoint.x, ei.ipoint.y, ei.ipoint.z);
  1327. }
  1328. return pos;
  1329. }
  1330. }
  1331. else
  1332. {
  1333. // fall back to our stupid functionality
  1334. pos = RayEnd;
  1335. return pos;
  1336. }
  1337. }
  1338. public virtual void AddNewPrim(LLUUID ownerID, LLVector3 RayEnd, LLQuaternion rot, PrimitiveBaseShape shape,
  1339. byte bypassRaycast, LLVector3 RayStart, LLUUID RayTargetID,
  1340. byte RayEndIsIntersection)
  1341. {
  1342. LLVector3 pos = GetNewRezLocation(RayStart, RayEnd, RayTargetID, rot, bypassRaycast, RayEndIsIntersection, true, new LLVector3(0.5f, 0.5f, 0.5f), false);
  1343. if (ExternalChecks.ExternalChecksCanRezObject(1, ownerID, pos))
  1344. {
  1345. // rez ON the ground, not IN the ground
  1346. pos.Z += 0.25F;
  1347. AddNewPrim(ownerID, pos, rot, shape);
  1348. }
  1349. }
  1350. public virtual SceneObjectGroup AddNewPrim(LLUUID ownerID, LLVector3 pos, LLQuaternion rot, PrimitiveBaseShape shape)
  1351. {
  1352. //m_log.DebugFormat(
  1353. // "[SCENE]: Scene.AddNewPrim() called for agent {0} in {1}", ownerID, RegionInfo.RegionName);
  1354. SceneObjectGroup sceneOb =
  1355. new SceneObjectGroup(this, m_regionHandle, ownerID, PrimIDAllocate(), pos, rot, shape);
  1356. SceneObjectPart rootPart = sceneOb.GetChildPart(sceneOb.UUID);
  1357. // if grass or tree, make phantom
  1358. //rootPart.TrimPermissions();
  1359. if ((rootPart.Shape.PCode == (byte)PCode.Grass) || (rootPart.Shape.PCode == (byte)PCode.Tree) || (rootPart.Shape.PCode == (byte)PCode.NewTree))
  1360. {
  1361. rootPart.AddFlag(LLObject.ObjectFlags.Phantom);
  1362. //rootPart.ObjectFlags += (uint)LLObject.ObjectFlags.Phantom;
  1363. if (rootPart.Shape.PCode != (byte)PCode.Grass)
  1364. AdaptTree(ref shape);
  1365. }
  1366. AddNewSceneObject(sceneOb, true);
  1367. return sceneOb;
  1368. }
  1369. void AdaptTree(ref PrimitiveBaseShape tree)
  1370. {
  1371. // Tree size has to be adapted depending on its type
  1372. switch ((Tree)tree.State)
  1373. {
  1374. case Tree.Cypress1:
  1375. case Tree.Cypress2:
  1376. tree.Scale = new LLVector3(4, 4, 10);
  1377. break;
  1378. // case... other tree types
  1379. // tree.Scale = new LLVector3(?, ?, ?);
  1380. // break;
  1381. default:
  1382. tree.Scale = new LLVector3(4, 4, 4);
  1383. break;
  1384. }
  1385. }
  1386. public SceneObjectGroup AddTree(LLVector3 scale, LLQuaternion rotation, LLVector3 position,
  1387. Tree treeType, bool newTree)
  1388. {
  1389. LLUUID uuid = this.RegionInfo.MasterAvatarAssignedUUID;
  1390. PrimitiveBaseShape treeShape = new PrimitiveBaseShape();
  1391. treeShape.PathCurve = 16;
  1392. treeShape.PathEnd = 49900;
  1393. treeShape.PCode = newTree ? (byte)PCode.NewTree : (byte)PCode.Tree;
  1394. treeShape.Scale = scale;
  1395. treeShape.State = (byte)treeType;
  1396. return AddNewPrim(uuid, position, rotation, treeShape);
  1397. }
  1398. /// <summary>
  1399. /// Add an object into the scene that has come from storage
  1400. /// </summary>
  1401. /// <param name="sceneObject"></param>
  1402. /// <param name="attachToBackup">
  1403. /// If true, changes to the object will be reflected in its persisted data
  1404. /// If false, the persisted data will not be changed even if the object in the scene is changed
  1405. /// </param>
  1406. /// <param name="alreadyPersisted">
  1407. /// If true, we won't persist this object until it changes
  1408. /// If false, we'll persist this object immediately
  1409. /// </param>
  1410. /// <returns>
  1411. /// true if the object was added, false if an object with the same uuid was already in the scene
  1412. /// </returns>
  1413. public bool AddRestoredSceneObject(
  1414. SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted)
  1415. {
  1416. return m_innerScene.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted);
  1417. }
  1418. /// <summary>
  1419. /// Add a newly created object to the scene
  1420. /// </summary>
  1421. /// <param name="sceneObject"></param>
  1422. /// <param name="attachToBackup">
  1423. /// If true, the object is made persistent into the scene.
  1424. /// If false, the object will not persist over server restarts
  1425. /// </param>
  1426. public bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup)
  1427. {
  1428. return m_innerScene.AddNewSceneObject(sceneObject, attachToBackup);
  1429. }
  1430. /// <summary>
  1431. /// Delete every object from the scene
  1432. /// </summary>
  1433. public void DeleteAllSceneObjects()
  1434. {
  1435. lock (Entities)
  1436. {
  1437. ICollection<EntityBase> entities = new List<EntityBase>(Entities.Values);
  1438. foreach (EntityBase e in entities)
  1439. {
  1440. if (e is SceneObjectGroup)
  1441. DeleteSceneObject((SceneObjectGroup)e);
  1442. }
  1443. }
  1444. }
  1445. /// <summary>
  1446. /// Delete the given object from the scene.
  1447. /// </summary>
  1448. /// <param name="group"></param>
  1449. public void DeleteSceneObject(SceneObjectGroup group)
  1450. {
  1451. SceneObjectPart rootPart = group.GetChildPart(group.UUID);
  1452. if (rootPart.PhysActor != null)
  1453. {
  1454. PhysicsScene.RemovePrim(rootPart.PhysActor);
  1455. rootPart.PhysActor = null;
  1456. }
  1457. if (UnlinkSceneObject(group.UUID, false))
  1458. {
  1459. EventManager.TriggerObjectBeingRemovedFromScene(group);
  1460. EventManager.TriggerParcelPrimCountTainted();
  1461. }
  1462. group.DeleteGroup();
  1463. }
  1464. /// <summary>
  1465. /// Unlink the given object from the scene. Unlike delete, this just removes the record of the object - the
  1466. /// object itself is not destroyed.
  1467. /// </summary>
  1468. /// <param name="uuid"></param>
  1469. /// <returns>true if the object was in the scene, false if it was not</returns>
  1470. public bool UnlinkSceneObject(LLUUID uuid, bool resultOfLinkingObjects)
  1471. {
  1472. if (m_innerScene.DeleteSceneObject(uuid,resultOfLinkingObjects))
  1473. {
  1474. m_storageManager.DataStore.RemoveObject(uuid, m_regInfo.RegionID);
  1475. return true;
  1476. }
  1477. return false;
  1478. }
  1479. public void LoadPrimsFromXml(string fileName, bool newIdsFlag, LLVector3 loadOffset)
  1480. {
  1481. m_serialiser.LoadPrimsFromXml(this, fileName, newIdsFlag, loadOffset);
  1482. }
  1483. public void SavePrimsToXml(string fileName)
  1484. {
  1485. m_serialiser.SavePrimsToXml(this, fileName);
  1486. }
  1487. public void LoadPrimsFromXml2(string fileName)
  1488. {
  1489. m_serialiser.LoadPrimsFromXml2(this, fileName);
  1490. }
  1491. public void SavePrimsToXml2(string fileName)
  1492. {
  1493. m_serialiser.SavePrimsToXml2(this, fileName);
  1494. }
  1495. public void SaveNamedPrimsToXml2(string primName, string fileName)
  1496. {
  1497. List<EntityBase> entityList = GetEntities();
  1498. List<EntityBase> primList = new List<EntityBase>();
  1499. foreach (EntityBase ent in entityList)
  1500. {
  1501. if (ent is SceneObjectGroup)
  1502. {
  1503. if (ent.Name == primName)
  1504. {
  1505. primList.Add(ent);
  1506. }
  1507. }
  1508. }
  1509. m_serialiser.SavePrimListToXml2(primList, fileName);
  1510. }
  1511. /// <summary>
  1512. /// Load a prim archive into the scene. This loads both prims and their assets.
  1513. /// </summary>
  1514. /// <param name="filePath"></param>
  1515. public void LoadPrimsFromArchive(string filePath)
  1516. {
  1517. m_archiver.DearchiveRegion(filePath);
  1518. }
  1519. /// <summary>
  1520. /// Save the prims in the scene to an archive. This saves both prims and their assets.
  1521. /// </summary>
  1522. /// <param name="filePath"></param>
  1523. public void SavePrimsToArchive(string filePath)
  1524. {
  1525. m_archiver.ArchiveRegion(filePath);
  1526. }
  1527. /// <summary>
  1528. /// Locate New region Handle and offset the prim position for the new region
  1529. ///
  1530. /// </summary>
  1531. /// <param name="position">current position of Group</param>
  1532. /// <param name="grp">Scene Object Group that we're crossing</param>
  1533. public void CrossPrimGroupIntoNewRegion(LLVector3 position, SceneObjectGroup grp)
  1534. {
  1535. if (grp == null)
  1536. return;
  1537. if (grp.RootPart == null)
  1538. return;
  1539. if (grp.RootPart.DIE_AT_EDGE)
  1540. {
  1541. // We remove the object here
  1542. try
  1543. {
  1544. DeleteSceneObject(grp);
  1545. }
  1546. catch (Exception)
  1547. {
  1548. m_log.Warn("[DATABASE]: exception when trying to remove the prim that crossed the border.");
  1549. }
  1550. return;
  1551. }
  1552. m_log.Warn("Prim crossing: " + grp.UUID.ToString());
  1553. int thisx = (int)RegionInfo.RegionLocX;
  1554. int thisy = (int)RegionInfo.RegionLocY;
  1555. ulong newRegionHandle = 0;
  1556. LLVector3 pos = position;
  1557. if (position.X > Constants.RegionSize + 0.1f)
  1558. {
  1559. pos.X = ((pos.X - Constants.RegionSize));
  1560. newRegionHandle = Util.UIntsToLong((uint)((thisx + 1) * Constants.RegionSize), (uint)(thisy * Constants.RegionSize));
  1561. // x + 1
  1562. }
  1563. else if (position.X < -0.1f)
  1564. {
  1565. pos.X = ((pos.X + Constants.RegionSize));
  1566. newRegionHandle = Util.UIntsToLong((uint)((thisx - 1) * Constants.RegionSize), (uint)(thisy * Constants.RegionSize));
  1567. // x - 1
  1568. }
  1569. if (position.Y > Constants.RegionSize + 0.1f)
  1570. {
  1571. pos.Y = ((pos.Y - Constants.RegionSize));
  1572. newRegionHandle = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy + 1) * Constants.RegionSize));
  1573. // y + 1
  1574. }
  1575. else if (position.Y < -1f)
  1576. {
  1577. pos.Y = ((pos.Y + Constants.RegionSize));
  1578. newRegionHandle = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy - 1) * Constants.RegionSize));
  1579. // y - 1
  1580. }
  1581. // Offset the positions for the new region across the border
  1582. grp.OffsetForNewRegion(pos);
  1583. CrossPrimGroupIntoNewRegion(newRegionHandle, grp);
  1584. }
  1585. public void CrossPrimGroupIntoNewRegion(ulong newRegionHandle, SceneObjectGroup grp)
  1586. {
  1587. int primcrossingXMLmethod = 0;
  1588. if (newRegionHandle != 0)
  1589. {
  1590. bool successYN = false;
  1591. successYN
  1592. = m_sceneGridService.PrimCrossToNeighboringRegion(
  1593. newRegionHandle, grp.UUID, m_serialiser.SaveGroupToXml2(grp), primcrossingXMLmethod);
  1594. if (successYN)
  1595. {
  1596. // We remove the object here
  1597. try
  1598. {
  1599. DeleteSceneObject(grp);
  1600. }
  1601. catch (Exception)
  1602. {
  1603. m_log.Warn("[DATABASE]: exception when trying to remove the prim that crossed the border.");
  1604. }
  1605. }
  1606. else
  1607. {
  1608. m_log.Warn("[INTERREGION]: Prim Crossing Failed!");
  1609. if (grp.RootPart != null)
  1610. {
  1611. if (grp.RootPart.PhysActor != null)
  1612. {
  1613. grp.RootPart.PhysActor.CrossingFailure();
  1614. }
  1615. }
  1616. }
  1617. }
  1618. }
  1619. public bool IncomingInterRegionPrimGroup(ulong regionHandle, LLUUID primID, string objXMLData, int XMLMethod)
  1620. {
  1621. m_log.Warn("{[INTERREGION]: A new prim arrived from a neighbor");
  1622. if (XMLMethod == 0)
  1623. {
  1624. m_serialiser.LoadGroupFromXml2(this, objXMLData);
  1625. SceneObjectPart RootPrim = GetSceneObjectPart(primID);
  1626. if (RootPrim != null)
  1627. {
  1628. if (m_regInfo.EstateSettings.IsBanned(RootPrim.OwnerID))
  1629. {
  1630. SceneObjectGroup grp = RootPrim.ParentGroup;
  1631. if (grp != null)
  1632. {
  1633. DeleteSceneObject(grp);
  1634. }
  1635. m_log.Info("[INTERREGION]: Denied prim crossing for banned avatar");
  1636. return false;
  1637. }
  1638. if (RootPrim.Shape.PCode == (byte)PCode.Prim)
  1639. {
  1640. SceneObjectGroup grp = RootPrim.ParentGroup;
  1641. if (grp != null)
  1642. {
  1643. if (RootPrim.Shape.State != 0)
  1644. {
  1645. // Attachment
  1646. ScenePresence sp = GetScenePresence(grp.OwnerID);
  1647. if (sp != null)
  1648. {
  1649. // hack assetID until we get assetID into the XML format.
  1650. // LastOwnerID is used for group deeding, so when you do stuff
  1651. // with the deeded object, it goes back to them
  1652. grp.SetFromAssetID(grp.RootPart.LastOwnerID);
  1653. m_innerScene.AttachObject(sp.ControllingClient, grp.LocalId, (uint)0, grp.GroupRotation, grp.AbsolutePosition);
  1654. }
  1655. }
  1656. }
  1657. }
  1658. }
  1659. return true;
  1660. }
  1661. else
  1662. {
  1663. return false;
  1664. }
  1665. }
  1666. #endregion
  1667. #region Add/Remove Avatar Methods
  1668. /// <summary>
  1669. ///
  1670. /// </summary>
  1671. /// <param name="client"></param
  1672. /// <param name="child"></param>
  1673. public override void AddNewClient(IClientAPI client, bool child)
  1674. {
  1675. m_log.DebugFormat(
  1676. "[CONNECTION DEBUGGING]: Creating new client for {0} at {1}",
  1677. client.AgentId, RegionInfo.RegionName);
  1678. SubscribeToClientEvents(client);
  1679. ScenePresence presence;
  1680. if (m_restorePresences.ContainsKey(client.AgentId))
  1681. {
  1682. m_log.Info("[REGION]: Restore Scene Presence");
  1683. presence = m_restorePresences[client.AgentId];
  1684. m_restorePresences.Remove(client.AgentId);
  1685. // This is one of two paths to create avatars that are
  1686. // used. This tends to get called more in standalone
  1687. // than grid, not really sure why, but as such needs
  1688. // an explicity appearance lookup here.
  1689. AvatarAppearance appearance = null;
  1690. GetAvatarAppearance(client, out appearance);
  1691. presence.Appearance = appearance;
  1692. presence.initializeScenePresence(client, RegionInfo, this);
  1693. m_innerScene.AddScenePresence(presence);
  1694. lock (m_restorePresences)
  1695. {
  1696. Monitor.PulseAll(m_restorePresences);
  1697. }
  1698. }
  1699. else
  1700. {
  1701. m_log.Info("[REGION]: Add New Scene Presence");
  1702. CommsManager.UserProfileCacheService.AddNewUser(client.AgentId);
  1703. CreateAndAddScenePresence(client, child);
  1704. }
  1705. EventManager.TriggerOnNewClient(client);
  1706. }
  1707. protected virtual void SubscribeToClientEvents(IClientAPI client)
  1708. {
  1709. client.OnRegionHandShakeReply += SendLayerData;
  1710. //remoteClient.OnRequestWearables += new GenericCall(this.GetInitialPrims);
  1711. // client.OnRequestWearables += InformClientOfNeighbours;
  1712. client.OnAddPrim += AddNewPrim;
  1713. client.OnUpdatePrimGroupPosition += m_innerScene.UpdatePrimPosition;
  1714. client.OnUpdatePrimSinglePosition += m_innerScene.UpdatePrimSinglePosition;
  1715. client.OnUpdatePrimGroupRotation += m_innerScene.UpdatePrimRotation;
  1716. client.OnUpdatePrimGroupMouseRotation += m_innerScene.UpdatePrimRotation;
  1717. client.OnUpdatePrimSingleRotation += m_innerScene.UpdatePrimSingleRotation;
  1718. client.OnUpdatePrimScale += m_innerScene.UpdatePrimScale;
  1719. client.OnUpdatePrimGroupScale += m_innerScene.UpdatePrimGroupScale;
  1720. client.OnUpdateExtraParams += m_innerScene.UpdateExtraParam;
  1721. client.OnUpdatePrimShape += m_innerScene.UpdatePrimShape;
  1722. //client.OnRequestMapBlocks += RequestMapBlocks; // handled in a module now.
  1723. client.OnUpdatePrimTexture += m_innerScene.UpdatePrimTexture;
  1724. client.OnTeleportLocationRequest += RequestTeleportLocation;
  1725. client.OnTeleportLandmarkRequest += RequestTeleportLandmark;
  1726. client.OnObjectSelect += SelectPrim;
  1727. client.OnObjectDeselect += DeselectPrim;
  1728. client.OnGrabUpdate += m_innerScene.MoveObject;
  1729. client.OnDeRezObject += DeRezObject;
  1730. client.OnRezObject += RezObject;
  1731. client.OnRezSingleAttachmentFromInv += m_innerScene.RezSingleAttachment;
  1732. client.OnDetachAttachmentIntoInv += m_innerScene.DetachSingleAttachmentToInv;
  1733. client.OnObjectAttach += m_innerScene.AttachObject;
  1734. client.OnObjectDetach += m_innerScene.DetachObject;
  1735. client.OnNameFromUUIDRequest += CommsManager.HandleUUIDNameRequest;
  1736. client.OnObjectDescription += m_innerScene.PrimDescription;
  1737. client.OnObjectName += m_innerScene.PrimName;
  1738. client.OnLinkObjects += m_innerScene.LinkObjects;
  1739. client.OnDelinkObjects += m_innerScene.DelinkObjects;
  1740. client.OnObjectDuplicate += m_innerScene.DuplicateObject;
  1741. client.OnObjectDuplicateOnRay += doObjectDuplicateOnRay;
  1742. client.OnUpdatePrimFlags += m_innerScene.UpdatePrimFlags;
  1743. client.OnRequestObjectPropertiesFamily += m_innerScene.RequestObjectPropertiesFamily;
  1744. client.OnRequestGodlikePowers += handleRequestGodlikePowers;
  1745. client.OnGodKickUser += HandleGodlikeKickUser;
  1746. client.OnObjectPermissions += HandleObjectPermissionsUpdate;
  1747. client.OnCreateNewInventoryItem += CreateNewInventoryItem;
  1748. client.OnCreateNewInventoryFolder += CommsManager.UserProfileCacheService.HandleCreateInventoryFolder;
  1749. client.OnUpdateInventoryFolder += CommsManager.UserProfileCacheService.HandleUpdateInventoryFolder;
  1750. client.OnMoveInventoryFolder += CommsManager.UserProfileCacheService.HandleMoveInventoryFolder;
  1751. client.OnFetchInventoryDescendents += CommsManager.UserProfileCacheService.HandleFetchInventoryDescendents;
  1752. client.OnPurgeInventoryDescendents += CommsManager.UserProfileCacheService.HandlePurgeInventoryDescendents;
  1753. client.OnFetchInventory += CommsManager.UserProfileCacheService.HandleFetchInventory;
  1754. client.OnUpdateInventoryItem += UpdateInventoryItemAsset;
  1755. client.OnCopyInventoryItem += CopyInventoryItem;
  1756. client.OnMoveInventoryItem += MoveInventoryItem;
  1757. client.OnRemoveInventoryItem += RemoveInventoryItem;
  1758. client.OnRemoveInventoryFolder += RemoveInventoryFolder;
  1759. client.OnRezScript += RezScript;
  1760. client.OnRequestTaskInventory += RequestTaskInventory;
  1761. client.OnRemoveTaskItem += RemoveTaskInventory;
  1762. client.OnUpdateTaskInventory += UpdateTaskInventory;
  1763. client.OnMoveTaskItem += ClientMoveTaskInventoryItem;
  1764. client.OnGrabObject += ProcessObjectGrab;
  1765. client.OnDeGrabObject += ProcessObjectDeGrab;
  1766. client.OnMoneyTransferRequest += ProcessMoneyTransferRequest;
  1767. client.OnParcelBuy += ProcessParcelBuy;
  1768. client.OnAvatarPickerRequest += ProcessAvatarPickerRequest;
  1769. client.OnPacketStats += AddPacketStats;
  1770. client.OnObjectIncludeInSearch += m_innerScene.MakeObjectSearchable;
  1771. client.OnTeleportHomeRequest += TeleportClientHome;
  1772. client.OnSetStartLocationRequest += SetHomeRezPoint;
  1773. client.OnUndo += m_innerScene.HandleUndo;
  1774. client.OnObjectGroupRequest += m_innerScene.HandleObjectGroupUpdate;
  1775. client.OnParcelReturnObjectsRequest += LandChannel.ReturnObjectsInParcel;
  1776. client.OnScriptReset += ProcessScriptReset;
  1777. client.OnGetScriptRunning += GetScriptRunning;
  1778. client.OnSetScriptRunning += SetScriptRunning;
  1779. // EventManager.TriggerOnNewClient(client);
  1780. }
  1781. public virtual void TeleportClientHome(LLUUID AgentId, IClientAPI client)
  1782. {
  1783. UserProfileData UserProfile = CommsManager.UserService.GetUserProfile(AgentId);
  1784. if (UserProfile != null)
  1785. {
  1786. ulong homeRegion = UserProfile.HomeRegion;
  1787. LLVector3 homePostion = new LLVector3(UserProfile.HomeLocationX,UserProfile.HomeLocationY,UserProfile.HomeLocationZ);
  1788. LLVector3 homeLookat = new LLVector3(UserProfile.HomeLookAt);
  1789. RequestTeleportLocation(client, homeRegion, homePostion,homeLookat,(uint)0);
  1790. }
  1791. }
  1792. public void doObjectDuplicateOnRay(uint localID, uint dupeFlags, LLUUID AgentID, LLUUID GroupID,
  1793. LLUUID RayTargetObj, LLVector3 RayEnd, LLVector3 RayStart,
  1794. bool BypassRaycast, bool RayEndIsIntersection, bool CopyCenters, bool CopyRotates)
  1795. {
  1796. LLVector3 pos;
  1797. const bool frontFacesOnly = true;
  1798. //m_log.Info("HITTARGET: " + RayTargetObj.ToString() + ", COPYTARGET: " + localID.ToString());
  1799. SceneObjectPart target = GetSceneObjectPart(localID);
  1800. SceneObjectPart target2 = GetSceneObjectPart(RayTargetObj);
  1801. if (target != null && target2 != null)
  1802. {
  1803. LLVector3 direction = LLVector3.Norm(RayEnd - RayStart);
  1804. Vector3 AXOrigin = new Vector3(RayStart.X, RayStart.Y, RayStart.Z);
  1805. Vector3 AXdirection = new Vector3(direction.X, direction.Y, direction.Z);
  1806. if (target2.ParentGroup != null)
  1807. {
  1808. pos = target2.AbsolutePosition;
  1809. //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());
  1810. // TODO: Raytrace better here
  1811. //EntityIntersection ei = m_innerScene.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection));
  1812. Ray NewRay = new Ray(AXOrigin, AXdirection);
  1813. // Ray Trace against target here
  1814. EntityIntersection ei = target2.TestIntersectionOBB(NewRay, new Quaternion(1, 0, 0, 0), frontFacesOnly, CopyCenters);
  1815. // Un-comment out the following line to Get Raytrace results printed to the console.
  1816. //m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString());
  1817. float ScaleOffset = 0.5f;
  1818. // If we hit something
  1819. if (ei.HitTF)
  1820. {
  1821. LLVector3 scale = target.Scale;
  1822. LLVector3 scaleComponent = new LLVector3(ei.AAfaceNormal.x, ei.AAfaceNormal.y, ei.AAfaceNormal.z);
  1823. if (scaleComponent.X != 0) ScaleOffset = scale.X;
  1824. if (scaleComponent.Y != 0) ScaleOffset = scale.Y;
  1825. if (scaleComponent.Z != 0) ScaleOffset = scale.Z;
  1826. ScaleOffset = Math.Abs(ScaleOffset);
  1827. LLVector3 intersectionpoint = new LLVector3(ei.ipoint.x, ei.ipoint.y, ei.ipoint.z);
  1828. LLVector3 normal = new LLVector3(ei.normal.x, ei.normal.y, ei.normal.z);
  1829. LLVector3 offset = normal * (ScaleOffset / 2f);
  1830. pos = intersectionpoint + offset;
  1831. // stick in offset format from the original prim
  1832. pos = pos - target.ParentGroup.AbsolutePosition;
  1833. if (CopyRotates)
  1834. {
  1835. LLQuaternion worldRot = target2.GetWorldRotation();
  1836. // SceneObjectGroup obj = m_innerScene.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID, new Quaternion(worldRot.W,worldRot.X,worldRot.Y,worldRot.Z));
  1837. m_innerScene.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID, new Quaternion(worldRot.W,worldRot.X,worldRot.Y,worldRot.Z));
  1838. //obj.Rotation = new Quaternion(worldRot.W, worldRot.X, worldRot.Y, worldRot.Z);
  1839. //obj.UpdateGroupRotation(worldRot);
  1840. }
  1841. else
  1842. {
  1843. m_innerScene.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID);
  1844. }
  1845. }
  1846. return;
  1847. }
  1848. return;
  1849. }
  1850. }
  1851. public virtual void SetHomeRezPoint(IClientAPI remoteClient, ulong regionHandle, LLVector3 position, LLVector3 lookAt, uint flags)
  1852. {
  1853. UserProfileData UserProfile = CommsManager.UserService.GetUserProfile(remoteClient.AgentId);
  1854. if (UserProfile != null)
  1855. {
  1856. // I know I'm ignoring the regionHandle provided by the teleport location request.
  1857. // reusing the TeleportLocationRequest delegate, so regionHandle isn't valid
  1858. UserProfile.HomeRegion = RegionInfo.RegionHandle;
  1859. // We cast these to an int so as not to cause a breaking change with old regions
  1860. // Newer regions treat this as a float on the ExpectUser method.. so we need to wait a few
  1861. // releases before setting these to floats. (r4257)
  1862. UserProfile.HomeLocationX = (int)position.X;
  1863. UserProfile.HomeLocationY = (int)position.Y;
  1864. UserProfile.HomeLocationZ = (int)position.Z;
  1865. UserProfile.HomeLookAtX = (int)lookAt.X;
  1866. UserProfile.HomeLookAtY = (int)lookAt.Y;
  1867. UserProfile.HomeLookAtZ = (int)lookAt.Z;
  1868. CommsManager.UserService.UpdateUserProfileProperties(UserProfile);
  1869. remoteClient.SendAgentAlertMessage("Set home to here if supported by login service",false);
  1870. }
  1871. else
  1872. {
  1873. remoteClient.SendAgentAlertMessage("Set Home request Failed",false);
  1874. }
  1875. }
  1876. protected virtual ScenePresence CreateAndAddScenePresence(IClientAPI client, bool child)
  1877. {
  1878. AvatarAppearance appearance = null;
  1879. GetAvatarAppearance(client, out appearance);
  1880. ScenePresence avatar = m_innerScene.CreateAndAddScenePresence(client, child, appearance);
  1881. return avatar;
  1882. }
  1883. /// <summary>
  1884. /// Get the avatar apperance for the given client.
  1885. /// </summary>
  1886. /// <param name="client"></param>
  1887. /// <param name="appearance"></param>
  1888. public void GetAvatarAppearance(IClientAPI client, out AvatarAppearance appearance)
  1889. {
  1890. appearance = null; // VS needs this line, mono doesn't
  1891. try
  1892. {
  1893. if (m_AvatarFactory == null ||
  1894. !m_AvatarFactory.TryGetAvatarAppearance(client.AgentId, out appearance))
  1895. {
  1896. m_log.Warn("[APPEARANCE]: Appearance not found, creating default");
  1897. appearance = new AvatarAppearance();
  1898. }
  1899. }
  1900. catch (Exception e)
  1901. {
  1902. m_log.ErrorFormat(
  1903. "[APPERANCE]: Problem when fetching appearance for avatar {0}, {1}, using default. {2}",
  1904. client.Name, client.AgentId, e);
  1905. appearance = new AvatarAppearance();
  1906. }
  1907. }
  1908. /// <summary>
  1909. /// Remove the given client from the scene.
  1910. /// </summary>
  1911. /// <param name="agentID"></param>
  1912. public override void RemoveClient(LLUUID agentID)
  1913. {
  1914. bool childagentYN = false;
  1915. ScenePresence avatar = GetScenePresence(agentID);
  1916. if (avatar != null)
  1917. {
  1918. childagentYN = avatar.IsChildAgent;
  1919. }
  1920. try
  1921. {
  1922. if (avatar.IsChildAgent)
  1923. {
  1924. m_innerScene.removeUserCount(false);
  1925. }
  1926. else
  1927. {
  1928. m_innerScene.removeUserCount(true);
  1929. m_sceneGridService.LogOffUser(agentID, RegionInfo.RegionID, RegionInfo.RegionHandle,
  1930. avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y,
  1931. avatar.AbsolutePosition.Z);
  1932. List<ulong> childknownRegions = new List<ulong>();
  1933. List<ulong> ckn = avatar.GetKnownRegionList();
  1934. for (int i = 0; i < ckn.Count; i++)
  1935. {
  1936. childknownRegions.Add(ckn[i]);
  1937. }
  1938. m_sceneGridService.SendCloseChildAgentConnections(agentID, childknownRegions);
  1939. RemoveCapsHandler(agentID);
  1940. CommsManager.UserProfileCacheService.RemoveUser(agentID);
  1941. }
  1942. m_eventManager.TriggerClientClosed(agentID);
  1943. }
  1944. catch (NullReferenceException)
  1945. {
  1946. // We don't know which count to remove it from
  1947. // Avatar is already disposed :/
  1948. }
  1949. m_eventManager.TriggerOnRemovePresence(agentID);
  1950. Broadcast(delegate(IClientAPI client)
  1951. {
  1952. try
  1953. {
  1954. client.SendKillObject(avatar.RegionHandle, avatar.LocalId);
  1955. }
  1956. catch (NullReferenceException)
  1957. {
  1958. //We can safely ignore null reference exceptions. It means the avatar are dead and cleaned up anyway.
  1959. }
  1960. });
  1961. ForEachScenePresence(
  1962. delegate(ScenePresence presence) { presence.CoarseLocationChange(); });
  1963. IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>();
  1964. if (agentTransactions != null)
  1965. {
  1966. agentTransactions.RemoveAgentAssetTransactions(agentID);
  1967. }
  1968. m_innerScene.RemoveScenePresence(agentID);
  1969. try
  1970. {
  1971. avatar.Close();
  1972. }
  1973. catch (NullReferenceException)
  1974. {
  1975. //We can safely ignore null reference exceptions. It means the avatar are dead and cleaned up anyway.
  1976. }
  1977. catch (Exception e)
  1978. {
  1979. m_log.Error("[SCENE] Scene.cs:RemoveClient exception: " + e.ToString());
  1980. }
  1981. // Remove client agent from profile, so new logins will work
  1982. if (!childagentYN)
  1983. {
  1984. m_sceneGridService.ClearUserAgent(agentID);
  1985. }
  1986. //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false));
  1987. //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true));
  1988. }
  1989. public void HandleRemoveKnownRegionsFromAvatar(LLUUID avatarID, List<ulong> regionslst)
  1990. {
  1991. ScenePresence av = GetScenePresence(avatarID);
  1992. if (av != null)
  1993. {
  1994. lock (av)
  1995. {
  1996. for (int i = 0; i < regionslst.Count; i++)
  1997. {
  1998. av.KnownChildRegions.Remove(regionslst[i]);
  1999. }
  2000. }
  2001. }
  2002. }
  2003. public override void CloseAllAgents(uint circuitcode)
  2004. {
  2005. // Called by ClientView to kill all circuit codes
  2006. ClientManager.CloseAllAgents(circuitcode);
  2007. }
  2008. public void NotifyMyCoarseLocationChange()
  2009. {
  2010. ForEachScenePresence(delegate(ScenePresence presence) { presence.CoarseLocationChange(); });
  2011. }
  2012. #endregion
  2013. #region Entities
  2014. public void SendKillObject(uint localID)
  2015. {
  2016. Broadcast(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, localID); });
  2017. }
  2018. #endregion
  2019. #region RegionComms
  2020. /// <summary>
  2021. ///
  2022. /// </summary>
  2023. public void RegisterCommsEvents()
  2024. {
  2025. m_sceneGridService.OnExpectUser += NewUserConnection;
  2026. m_sceneGridService.OnAvatarCrossingIntoRegion += AgentCrossing;
  2027. m_sceneGridService.OnCloseAgentConnection += CloseConnection;
  2028. m_sceneGridService.OnRegionUp += OtherRegionUp;
  2029. m_sceneGridService.OnChildAgentUpdate += IncomingChildAgentDataUpdate;
  2030. m_sceneGridService.OnExpectPrim += IncomingInterRegionPrimGroup;
  2031. m_sceneGridService.OnRemoveKnownRegionFromAvatar += HandleRemoveKnownRegionsFromAvatar;
  2032. m_sceneGridService.OnLogOffUser += HandleLogOffUserFromGrid;
  2033. m_sceneGridService.KillObject += SendKillObject;
  2034. }
  2035. /// <summary>
  2036. ///
  2037. /// </summary>
  2038. public void UnRegisterReginWithComms()
  2039. {
  2040. m_sceneGridService.KillObject -= SendKillObject;
  2041. m_sceneGridService.OnLogOffUser -= HandleLogOffUserFromGrid;
  2042. m_sceneGridService.OnRemoveKnownRegionFromAvatar -= HandleRemoveKnownRegionsFromAvatar;
  2043. m_sceneGridService.OnExpectPrim -= IncomingInterRegionPrimGroup;
  2044. m_sceneGridService.OnChildAgentUpdate -= IncomingChildAgentDataUpdate;
  2045. m_sceneGridService.OnRegionUp -= OtherRegionUp;
  2046. m_sceneGridService.OnExpectUser -= NewUserConnection;
  2047. m_sceneGridService.OnAvatarCrossingIntoRegion -= AgentCrossing;
  2048. m_sceneGridService.OnCloseAgentConnection -= CloseConnection;
  2049. m_sceneGridService.Close();
  2050. }
  2051. /// <summary>
  2052. /// Do the work necessary to initiate a new user connection.
  2053. /// At the moment, this consists of setting up the caps infrastructure
  2054. /// </summary>
  2055. /// <param name="regionHandle"></param>
  2056. /// <param name="agent"></param>
  2057. public void NewUserConnection(ulong regionHandle, AgentCircuitData agent)
  2058. {
  2059. if (regionHandle == m_regInfo.RegionHandle)
  2060. {
  2061. if (m_regInfo.EstateSettings.IsBanned(agent.AgentID))
  2062. {
  2063. m_log.WarnFormat(
  2064. "[CONNECTION DEBUGGING]: Denied access to: {0} [{1}] at {2} because the user is on the region banlist",
  2065. agent.AgentID, regionHandle, RegionInfo.RegionName);
  2066. }
  2067. capsPaths[agent.AgentID] = agent.CapsPath;
  2068. if (!agent.child)
  2069. {
  2070. AddCapsHandler(agent.AgentID);
  2071. // Honor parcel landing type and position.
  2072. ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
  2073. if (land != null)
  2074. {
  2075. if (land.landData.landingType == (byte)1 && land.landData.userLocation != LLVector3.Zero)
  2076. {
  2077. agent.startpos = land.landData.userLocation;
  2078. }
  2079. }
  2080. }
  2081. m_log.DebugFormat(
  2082. "[CONNECTION DEBUGGING]: Creating new circuit code ({0}) for avatar {1} at {2}",
  2083. agent.circuitcode, agent.AgentID, RegionInfo.RegionName);
  2084. m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent);
  2085. }
  2086. else
  2087. {
  2088. m_log.WarnFormat(
  2089. "[CONNECTION DEBUGGING]: Skipping this region for welcoming avatar {0} [{1}] at {2}",
  2090. agent.AgentID, regionHandle, RegionInfo.RegionName);
  2091. }
  2092. }
  2093. protected void HandleLogOffUserFromGrid(ulong regionHandle, LLUUID AvatarID, LLUUID RegionSecret, string message)
  2094. {
  2095. if (RegionInfo.RegionHandle == regionHandle)
  2096. {
  2097. ScenePresence loggingOffUser = null;
  2098. loggingOffUser = GetScenePresence(AvatarID);
  2099. if (loggingOffUser != null)
  2100. {
  2101. if (RegionSecret == loggingOffUser.ControllingClient.SecureSessionId)
  2102. {
  2103. loggingOffUser.ControllingClient.Kick(message);
  2104. // Give them a second to receive the message!
  2105. System.Threading.Thread.Sleep(1000);
  2106. loggingOffUser.ControllingClient.Close(true);
  2107. }
  2108. else
  2109. {
  2110. m_log.Info("[USERLOGOFF]: System sending the LogOff user message failed to sucessfully authenticate");
  2111. }
  2112. }
  2113. else
  2114. {
  2115. 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());
  2116. }
  2117. }
  2118. }
  2119. /// <summary>
  2120. /// Add a caps handler for the given agent. If the CAPS handler already exists for this agent,
  2121. /// then it is replaced by a new CAPS handler.
  2122. ///
  2123. /// FIXME: On login this is called twice, once for the login and once when the connection is made.
  2124. /// This is somewhat innefficient and should be fixed. The initial login creation is necessary
  2125. /// since the client asks for capabilities immediately after being informed of the seed.
  2126. /// </summary>
  2127. /// <param name="agentId"></param>
  2128. /// <param name="capsObjectPath"></param>
  2129. public void AddCapsHandler(LLUUID agentId)
  2130. {
  2131. String capsObjectPath = GetCapsPath(agentId);
  2132. m_log.DebugFormat(
  2133. "[CAPS]: Setting up CAPS handler for root agent {0} in {1}",
  2134. agentId, RegionInfo.RegionName);
  2135. Caps cap =
  2136. new Caps(AssetCache, m_httpListener, m_regInfo.ExternalHostName, m_httpListener.Port,
  2137. capsObjectPath, agentId, m_dumpAssetsToFile, RegionInfo.RegionName);
  2138. cap.RegisterHandlers();
  2139. EventManager.TriggerOnRegisterCaps(agentId, cap);
  2140. cap.AddNewInventoryItem = AddUploadedInventoryItem;
  2141. cap.ItemUpdatedCall = CapsUpdateInventoryItemAsset;
  2142. cap.TaskScriptUpdatedCall = CapsUpdateTaskInventoryScriptAsset;
  2143. cap.CAPSFetchInventoryDescendents = CommsManager.UserProfileCacheService.HandleFetchInventoryDescendentsCAPS;
  2144. cap.GetClient = m_innerScene.GetControllingClient;
  2145. m_capsHandlers[agentId] = cap;
  2146. }
  2147. /// <summary>
  2148. /// Remove the caps handler for a given agent.
  2149. /// </summary>
  2150. /// <param name="agentId"></param>
  2151. public void RemoveCapsHandler(LLUUID agentId)
  2152. {
  2153. lock (m_capsHandlers)
  2154. {
  2155. if (m_capsHandlers.ContainsKey(agentId))
  2156. {
  2157. m_log.DebugFormat(
  2158. "[CAPS]: Removing CAPS handler for root agent {0} in {1}",
  2159. agentId, RegionInfo.RegionName);
  2160. m_capsHandlers[agentId].DeregisterHandlers();
  2161. EventManager.TriggerOnDeregisterCaps(agentId, m_capsHandlers[agentId]);
  2162. m_capsHandlers.Remove(agentId);
  2163. }
  2164. else
  2165. {
  2166. m_log.WarnFormat(
  2167. "[CAPS]: Received request to remove CAPS handler for root agent {0} in {1}, but no such CAPS handler found!",
  2168. agentId, RegionInfo.RegionName);
  2169. }
  2170. }
  2171. }
  2172. /// <summary>
  2173. ///
  2174. /// </summary>
  2175. /// <param name="regionHandle"></param>
  2176. /// <param name="agentID"></param>
  2177. /// <param name="position"></param>
  2178. /// <param name="isFlying"></param>
  2179. public virtual void AgentCrossing(ulong regionHandle, LLUUID agentID, LLVector3 position, bool isFlying)
  2180. {
  2181. if (regionHandle == m_regInfo.RegionHandle)
  2182. {
  2183. lock (m_scenePresences)
  2184. {
  2185. if (m_scenePresences.ContainsKey(agentID))
  2186. {
  2187. try
  2188. {
  2189. m_scenePresences[agentID].MakeRootAgent(position, isFlying);
  2190. }
  2191. catch (Exception e)
  2192. {
  2193. m_log.Info("[SCENE]: Unable to do Agent Crossing.");
  2194. m_log.Debug("[SCENE]: " + e.ToString());
  2195. }
  2196. //m_innerScene.SwapRootChildAgent(false);
  2197. }
  2198. }
  2199. }
  2200. }
  2201. public virtual bool IncomingChildAgentDataUpdate(ulong regionHandle, ChildAgentDataUpdate cAgentData)
  2202. {
  2203. ScenePresence childAgentUpdate = GetScenePresence(new LLUUID(cAgentData.AgentID));
  2204. if (childAgentUpdate != null)
  2205. {
  2206. // I can't imagine *yet* why we would get an update if the agent is a root agent..
  2207. // however to avoid a race condition crossing borders..
  2208. if (childAgentUpdate.IsChildAgent)
  2209. {
  2210. uint rRegionX = (uint)(cAgentData.regionHandle >> 40);
  2211. uint rRegionY = (((uint)(cAgentData.regionHandle)) >> 8);
  2212. uint tRegionX = RegionInfo.RegionLocX;
  2213. uint tRegionY = RegionInfo.RegionLocY;
  2214. //Send Data to ScenePresence
  2215. childAgentUpdate.ChildAgentDataUpdate(cAgentData, tRegionX, tRegionY, rRegionX, rRegionY);
  2216. // Not Implemented:
  2217. //TODO: Do we need to pass the message on to one of our neighbors?
  2218. }
  2219. return true;
  2220. }
  2221. return false;
  2222. }
  2223. /// <summary>
  2224. /// Tell a single agent to disconnect from the region.
  2225. /// </summary>
  2226. /// <param name="regionHandle"></param>
  2227. /// <param name="agentID"></param>
  2228. public bool CloseConnection(ulong regionHandle, LLUUID agentID)
  2229. {
  2230. if (regionHandle == m_regionHandle)
  2231. {
  2232. ScenePresence presence = m_innerScene.GetScenePresence(agentID);
  2233. if (presence != null)
  2234. {
  2235. if (presence.IsChildAgent)
  2236. {
  2237. m_innerScene.removeUserCount(false);
  2238. }
  2239. else
  2240. {
  2241. m_innerScene.removeUserCount(true);
  2242. }
  2243. // Tell a single agent to disconnect from the region.
  2244. presence.ControllingClient.SendShutdownConnectionNotice();
  2245. presence.ControllingClient.Close(true);
  2246. }
  2247. }
  2248. return true;
  2249. }
  2250. /// <summary>
  2251. /// Tell neighboring regions about this agent
  2252. /// When the regions respond with a true value,
  2253. /// tell the agents about the region.
  2254. ///
  2255. /// We have to tell the regions about the agents first otherwise it'll deny them access
  2256. ///
  2257. /// </summary>
  2258. /// <param name="presence"></param>
  2259. public void InformClientOfNeighbours(ScenePresence presence)
  2260. {
  2261. m_sceneGridService.EnableNeighbourChildAgents(presence, m_neighbours);
  2262. }
  2263. /// <summary>
  2264. /// Tell a neighboring region about this agent
  2265. /// </summary>
  2266. /// <param name="presence"></param>
  2267. /// <param name="region"></param>
  2268. public void InformClientOfNeighbor(ScenePresence presence, RegionInfo region)
  2269. {
  2270. m_sceneGridService.InformNeighborChildAgent(presence, region, m_neighbours);
  2271. }
  2272. /// <summary>
  2273. /// Requests information about this region from gridcomms
  2274. /// </summary>
  2275. /// <param name="regionHandle"></param>
  2276. /// <returns></returns>
  2277. public RegionInfo RequestNeighbouringRegionInfo(ulong regionHandle)
  2278. {
  2279. return m_sceneGridService.RequestNeighbouringRegionInfo(regionHandle);
  2280. }
  2281. /// <summary>
  2282. /// Requests textures for map from minimum region to maximum region in world cordinates
  2283. /// </summary>
  2284. /// <param name="remoteClient"></param>
  2285. /// <param name="minX"></param>
  2286. /// <param name="minY"></param>
  2287. /// <param name="maxX"></param>
  2288. /// <param name="maxY"></param>
  2289. public void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY)
  2290. {
  2291. m_log.InfoFormat("[MAPBLOCK]: {0}-{1}, {2}-{3}", minX, minY, maxX, maxY);
  2292. m_sceneGridService.RequestMapBlocks(remoteClient, minX, minY, maxX, maxY);
  2293. }
  2294. /// <summary>
  2295. /// Tries to teleport agent to other region.
  2296. /// </summary>
  2297. /// <param name="remoteClient"></param>
  2298. /// <param name="regionHandle"></param>
  2299. /// <param name="position"></param>
  2300. /// <param name="lookAt"></param>
  2301. /// <param name="flags"></param>
  2302. public void RequestTeleportLocation(IClientAPI remoteClient, ulong regionHandle, LLVector3 position,
  2303. LLVector3 lookAt, uint flags)
  2304. {
  2305. lock (m_scenePresences)
  2306. {
  2307. if (m_scenePresences.ContainsKey(remoteClient.AgentId))
  2308. {
  2309. m_sceneGridService.RequestTeleportToLocation(m_scenePresences[remoteClient.AgentId], regionHandle,
  2310. position, lookAt, flags);
  2311. }
  2312. }
  2313. }
  2314. /// <summary>
  2315. /// Tries to teleport agent to landmark.
  2316. /// </summary>
  2317. /// <param name="remoteClient"></param>
  2318. /// <param name="regionHandle"></param>
  2319. /// <param name="position"></param>
  2320. public void RequestTeleportLandmark(IClientAPI remoteClient, ulong regionHandle, LLVector3 position)
  2321. {
  2322. lock (m_scenePresences)
  2323. {
  2324. if (m_scenePresences.ContainsKey(remoteClient.AgentId))
  2325. {
  2326. m_sceneGridService.RequestTeleportToLocation(m_scenePresences[remoteClient.AgentId], regionHandle,
  2327. position, LLVector3.Zero, 0);
  2328. }
  2329. }
  2330. }
  2331. /// <summary>
  2332. /// Agent is crossing the border into a neighbouring region. Tell the neighbour about it!
  2333. /// </summary>
  2334. /// <param name="regionHandle"></param>
  2335. /// <param name="agentID"></param>
  2336. /// <param name="position"></param>
  2337. /// <param name="isFlying"></param>
  2338. /// <returns></returns>
  2339. public bool InformNeighbourOfCrossing(ulong regionHandle, LLUUID agentID, LLVector3 position, bool isFlying)
  2340. {
  2341. return m_sceneGridService.CrossToNeighbouringRegion(regionHandle, agentID, position, isFlying);
  2342. }
  2343. public void SendOutChildAgentUpdates(ChildAgentDataUpdate cadu, ScenePresence presence)
  2344. {
  2345. m_sceneGridService.SendChildAgentDataUpdate(cadu, presence);
  2346. }
  2347. #endregion
  2348. #region Module Methods
  2349. /// <summary>
  2350. ///
  2351. /// </summary>
  2352. /// <param name="name"></param>
  2353. /// <param name="module"></param>
  2354. public void AddModule(string name, IRegionModule module)
  2355. {
  2356. if (!Modules.ContainsKey(name))
  2357. {
  2358. Modules.Add(name, module);
  2359. }
  2360. }
  2361. public void RegisterModuleCommander(string name, ICommander commander)
  2362. {
  2363. lock (m_moduleCommanders)
  2364. {
  2365. m_moduleCommanders.Add(name, commander);
  2366. }
  2367. }
  2368. public ICommander GetCommander(string name)
  2369. {
  2370. lock (m_moduleCommanders)
  2371. {
  2372. return m_moduleCommanders[name];
  2373. }
  2374. }
  2375. public Dictionary<string, ICommander> GetCommanders()
  2376. {
  2377. return m_moduleCommanders;
  2378. }
  2379. /// <summary>
  2380. /// Register an interface to a region module. This allows module methods to be called directly as
  2381. /// well as via events. If there is already a module registered for this interface, it is not replaced
  2382. /// (is this the best behaviour?)
  2383. /// </summary>
  2384. /// <param name="mod"></param>
  2385. public void RegisterModuleInterface<M>(M mod)
  2386. {
  2387. if (!ModuleInterfaces.ContainsKey(typeof(M)))
  2388. {
  2389. ModuleInterfaces.Add(typeof(M), mod);
  2390. }
  2391. }
  2392. /// <summary>
  2393. /// For the given interface, retrieve the region module which implements it.
  2394. /// </summary>
  2395. /// <returns>null if there is no module implementing that interface</returns>
  2396. public T RequestModuleInterface<T>()
  2397. {
  2398. if (ModuleInterfaces.ContainsKey(typeof(T)))
  2399. {
  2400. return (T)ModuleInterfaces[typeof(T)];
  2401. }
  2402. else
  2403. {
  2404. return default(T);
  2405. }
  2406. }
  2407. public void SetObjectCapacity(int objects)
  2408. {
  2409. if (m_statsReporter != null)
  2410. {
  2411. m_statsReporter.SetObjectCapacity(objects);
  2412. }
  2413. objectCapacity = objects;
  2414. }
  2415. public List<FriendListItem> GetFriendList(LLUUID avatarID)
  2416. {
  2417. return CommsManager.GetUserFriendList(avatarID);
  2418. }
  2419. #endregion
  2420. #region Other Methods
  2421. /// <summary>
  2422. ///
  2423. /// </summary>
  2424. /// <param name="phase"></param>
  2425. public void SetTimePhase(int phase)
  2426. {
  2427. m_timePhase = phase;
  2428. }
  2429. /// <summary>
  2430. ///
  2431. /// </summary>
  2432. /// <param name="avatarID"></param>
  2433. /// <param name="objectName"></param>
  2434. /// <param name="objectID"></param>
  2435. /// <param name="ownerID"></param>
  2436. /// <param name="groupOwned"></param>
  2437. /// <param name="message"></param>
  2438. /// <param name="url"></param>
  2439. public void SendUrlToUser(LLUUID avatarID, string objectName, LLUUID objectID, LLUUID ownerID, bool groupOwned,
  2440. string message, string url)
  2441. {
  2442. lock (m_scenePresences)
  2443. {
  2444. if (m_scenePresences.ContainsKey(avatarID))
  2445. {
  2446. m_scenePresences[avatarID].ControllingClient.SendLoadURL(objectName, objectID, ownerID, groupOwned,
  2447. message, url);
  2448. }
  2449. }
  2450. }
  2451. public void SendDialogToUser(LLUUID avatarID, string objectName, LLUUID objectID, LLUUID ownerID, string message, LLUUID TextureID, int ch, string[] buttonlabels)
  2452. {
  2453. lock (m_scenePresences)
  2454. {
  2455. if (m_scenePresences.ContainsKey(avatarID))
  2456. {
  2457. m_scenePresences[avatarID].ControllingClient.SendDialog(
  2458. objectName, objectID, ownerID, message, TextureID, ch, buttonlabels);
  2459. }
  2460. }
  2461. }
  2462. /// <summary>
  2463. ///
  2464. /// </summary>
  2465. /// <param name="url"></param>
  2466. /// <param name="type"></param>
  2467. /// <param name="body"></param>
  2468. /// <returns></returns>
  2469. public LLUUID MakeHttpRequest(string url, string type, string body)
  2470. {
  2471. if (m_httpRequestModule != null)
  2472. {
  2473. return m_httpRequestModule.MakeHttpRequest(url, type, body);
  2474. }
  2475. return LLUUID.Zero;
  2476. }
  2477. /// <summary>
  2478. /// This method is a way for the Friends Module to create an instant
  2479. /// message to the avatar and for Instant Messages that travel across
  2480. /// gridcomms to make it to the Instant Message Module.
  2481. ///
  2482. /// Friendship establishment and groups are unfortunately tied with instant messaging and
  2483. /// there's no way to separate them completely.
  2484. /// </summary>
  2485. /// <param name="message">object containing the instant message data</param>
  2486. /// <returns>void</returns>
  2487. public void TriggerGridInstantMessage(GridInstantMessage message, InstantMessageReceiver options)
  2488. {
  2489. m_eventManager.TriggerGridInstantMessage(message, options);
  2490. }
  2491. public virtual void StoreAddFriendship(LLUUID ownerID, LLUUID friendID, uint perms)
  2492. {
  2493. // TODO: m_sceneGridService.DoStuff;
  2494. m_sceneGridService.AddNewUserFriend(ownerID, friendID, perms);
  2495. }
  2496. public virtual void StoreUpdateFriendship(LLUUID ownerID, LLUUID friendID, uint perms)
  2497. {
  2498. // TODO: m_sceneGridService.DoStuff;
  2499. m_sceneGridService.UpdateUserFriendPerms(ownerID, friendID, perms);
  2500. }
  2501. public virtual void StoreRemoveFriendship(LLUUID ownerID, LLUUID ExfriendID)
  2502. {
  2503. // TODO: m_sceneGridService.DoStuff;
  2504. m_sceneGridService.RemoveUserFriend(ownerID, ExfriendID);
  2505. }
  2506. public virtual List<FriendListItem> StoreGetFriendsForUser(LLUUID ownerID)
  2507. {
  2508. // TODO: m_sceneGridService.DoStuff;
  2509. return m_sceneGridService.GetUserFriendList(ownerID);
  2510. }
  2511. public void AddPacketStats(int inPackets, int outPackets, int unAckedBytes)
  2512. {
  2513. m_statsReporter.AddInPackets(inPackets);
  2514. m_statsReporter.AddOutPackets(outPackets);
  2515. m_statsReporter.AddunAckedBytes(unAckedBytes);
  2516. }
  2517. public void AddAgentTime(int ms)
  2518. {
  2519. m_statsReporter.addFrameMS(ms);
  2520. m_statsReporter.addAgentMS(ms);
  2521. }
  2522. public void AddAgentUpdates(int count)
  2523. {
  2524. m_statsReporter.AddAgentUpdates(count);
  2525. }
  2526. public void AddPendingDownloads(int count)
  2527. {
  2528. m_statsReporter.addPendingDownload(count);
  2529. }
  2530. #endregion
  2531. #region Console Commands
  2532. #region Alert Methods
  2533. private void SendPermissionAlert(LLUUID user, string reason)
  2534. {
  2535. SendAlertToUser(user, reason, false);
  2536. }
  2537. /// <summary>
  2538. ///
  2539. /// </summary>
  2540. /// <param name="message"></param>
  2541. public void SendGeneralAlert(string message)
  2542. {
  2543. List<ScenePresence> presenceList = GetScenePresences();
  2544. foreach (ScenePresence presence in presenceList)
  2545. {
  2546. presence.ControllingClient.SendAlertMessage(message);
  2547. }
  2548. }
  2549. /// <summary>
  2550. ///
  2551. /// </summary>
  2552. /// <param name="agentID"></param>
  2553. /// <param name="message"></param>
  2554. /// <param name="modal"></param>
  2555. public void SendAlertToUser(LLUUID agentID, string message, bool modal)
  2556. {
  2557. lock (m_scenePresences)
  2558. {
  2559. if (m_scenePresences.ContainsKey(agentID))
  2560. {
  2561. m_scenePresences[agentID].ControllingClient.SendAgentAlertMessage(message, modal);
  2562. }
  2563. }
  2564. }
  2565. /// <summary>
  2566. /// Handle a request for admin rights
  2567. /// </summary>
  2568. /// <param name="agentID"></param>
  2569. /// <param name="sessionID"></param>
  2570. /// <param name="token"></param>
  2571. /// <param name="controllingClient"></param>
  2572. public void handleRequestGodlikePowers(LLUUID agentID, LLUUID sessionID, LLUUID token, bool godLike,
  2573. IClientAPI controllingClient)
  2574. {
  2575. lock (m_scenePresences)
  2576. {
  2577. // User needs to be logged into this sim
  2578. if (m_scenePresences.ContainsKey(agentID))
  2579. {
  2580. // First check that this is the sim owner
  2581. if (ExternalChecks.ExternalChecksCanBeGodLike(agentID))
  2582. {
  2583. // Next we check for spoofing.....
  2584. LLUUID testSessionID = m_scenePresences[agentID].ControllingClient.SessionId;
  2585. if (sessionID == testSessionID)
  2586. {
  2587. if (sessionID == controllingClient.SessionId)
  2588. {
  2589. //m_log.Info("godlike: " + godLike.ToString());
  2590. m_scenePresences[agentID].GrantGodlikePowers(agentID, testSessionID, token, godLike);
  2591. }
  2592. }
  2593. }
  2594. else
  2595. {
  2596. m_scenePresences[agentID].ControllingClient.SendAgentAlertMessage("Request for god powers denied", false);
  2597. }
  2598. }
  2599. }
  2600. }
  2601. /// <summary>
  2602. /// Sends a Big Blue Box message on the upper right of the screen to the client
  2603. /// for all agents in the region
  2604. /// </summary>
  2605. /// <param name="FromAvatarID">The person sending the message</param>
  2606. /// <param name="fromSessionID">The session of the person sending the message</param>
  2607. /// <param name="FromAvatarName">The name of the person doing the sending</param>
  2608. /// <param name="Message">The Message being sent to the user</param>
  2609. public void SendRegionMessageFromEstateTools(LLUUID FromAvatarID, LLUUID fromSessionID, String FromAvatarName, String Message)
  2610. {
  2611. List<ScenePresence> presenceList = GetScenePresences();
  2612. foreach (ScenePresence presence in presenceList)
  2613. {
  2614. if (!presence.IsChildAgent)
  2615. presence.ControllingClient.SendBlueBoxMessage(FromAvatarID, fromSessionID, FromAvatarName, Message);
  2616. }
  2617. }
  2618. /// <summary>
  2619. /// Sends a Big Blue Box message on the upper right of the screen to the client
  2620. /// for all agents in the estate
  2621. /// </summary>
  2622. /// <param name="FromAvatarID">The person sending the message</param>
  2623. /// <param name="fromSessionID">The session of the person sending the message</param>
  2624. /// <param name="FromAvatarName">The name of the person doing the sending</param>
  2625. /// <param name="Message">The Message being sent to the user</param>
  2626. public void SendEstateMessageFromEstateTools(LLUUID FromAvatarID, LLUUID fromSessionID, String FromAvatarName, String Message)
  2627. {
  2628. ClientManager.ForEachClient(delegate(IClientAPI controller)
  2629. {
  2630. controller.SendBlueBoxMessage(FromAvatarID, fromSessionID, FromAvatarName, Message);
  2631. }
  2632. );
  2633. }
  2634. /// <summary>
  2635. /// Kicks User specified from the simulator. This logs them off of the grid
  2636. /// If the client gets the UUID: 44e87126e7944ded05b37c42da3d5cdb it assumes
  2637. /// that you're kicking it even if the avatar's UUID isn't the UUID that the
  2638. /// agent is assigned
  2639. /// </summary>
  2640. /// <param name="godID">The person doing the kicking</param>
  2641. /// <param name="sessionID">The session of the person doing the kicking</param>
  2642. /// <param name="agentID">the person that is being kicked</param>
  2643. /// <param name="kickflags">This isn't used apparently</param>
  2644. /// <param name="reason">The message to send to the user after it's been turned into a field</param>
  2645. public void HandleGodlikeKickUser(LLUUID godID, LLUUID sessionID, LLUUID agentID, uint kickflags, byte[] reason)
  2646. {
  2647. // For some reason the client sends this seemingly hard coded UUID for kicking everyone. Dun-know.
  2648. LLUUID kickUserID = new LLUUID("44e87126e7944ded05b37c42da3d5cdb");
  2649. lock (m_scenePresences)
  2650. {
  2651. if (m_scenePresences.ContainsKey(agentID) || agentID == kickUserID)
  2652. {
  2653. if (ExternalChecks.ExternalChecksCanBeGodLike(godID))
  2654. {
  2655. if (agentID == kickUserID)
  2656. {
  2657. ClientManager.ForEachClient(delegate(IClientAPI controller)
  2658. {
  2659. if (controller.AgentId != godID)
  2660. controller.Kick(Helpers.FieldToUTF8String(reason));
  2661. }
  2662. );
  2663. // This is a bit crude. It seems the client will be null before it actually stops the thread
  2664. // The thread will kill itself eventually :/
  2665. // Is there another way to make sure *all* clients get this 'inter region' message?
  2666. ClientManager.ForEachClient(delegate(IClientAPI controller)
  2667. {
  2668. ScenePresence p = GetScenePresence(controller.AgentId);
  2669. bool childagent = p != null && p.IsChildAgent;
  2670. if (controller.AgentId != godID && !childagent)
  2671. // Do we really want to kick the initiator of this madness?
  2672. {
  2673. controller.Close(true);
  2674. }
  2675. }
  2676. );
  2677. }
  2678. else
  2679. {
  2680. m_innerScene.removeUserCount(!m_scenePresences[agentID].IsChildAgent);
  2681. m_scenePresences[agentID].ControllingClient.Kick(Helpers.FieldToUTF8String(reason));
  2682. m_scenePresences[agentID].ControllingClient.Close(true);
  2683. }
  2684. }
  2685. else
  2686. {
  2687. if (m_scenePresences.ContainsKey(godID))
  2688. m_scenePresences[godID].ControllingClient.SendAgentAlertMessage("Kick request denied", false);
  2689. }
  2690. }
  2691. }
  2692. }
  2693. public void HandleObjectPermissionsUpdate(IClientAPI controller, LLUUID agentID, LLUUID sessionID, byte field, uint localId, uint mask, byte set)
  2694. {
  2695. // Check for spoofing.. since this is permissions we're talking about here!
  2696. if ((controller.SessionId == sessionID) && (controller.AgentId == agentID))
  2697. {
  2698. // Tell the object to do permission update
  2699. if (localId != 0)
  2700. {
  2701. SceneObjectGroup chObjectGroup = GetGroupByPrim(localId);
  2702. if (chObjectGroup != null)
  2703. {
  2704. chObjectGroup.UpdatePermissions(agentID, field, localId, mask, set);
  2705. }
  2706. }
  2707. }
  2708. }
  2709. /// <summary>
  2710. ///
  2711. /// </summary>
  2712. /// <param name="firstName"></param>
  2713. /// <param name="lastName"></param>
  2714. /// <param name="message"></param>
  2715. /// <param name="modal"></param>
  2716. public void SendAlertToUser(string firstName, string lastName, string message, bool modal)
  2717. {
  2718. List<ScenePresence> presenceList = GetScenePresences();
  2719. foreach (ScenePresence presence in presenceList)
  2720. {
  2721. if ((presence.Firstname == firstName) && (presence.Lastname == lastName))
  2722. {
  2723. presence.ControllingClient.SendAgentAlertMessage(message, modal);
  2724. break;
  2725. }
  2726. }
  2727. }
  2728. /// <summary>
  2729. ///
  2730. /// </summary>
  2731. /// <param name="commandParams"></param>
  2732. public void HandleAlertCommand(string[] commandParams)
  2733. {
  2734. if (commandParams[0] == "general")
  2735. {
  2736. string message = CombineParams(commandParams, 1);
  2737. SendGeneralAlert(message);
  2738. }
  2739. else
  2740. {
  2741. string message = CombineParams(commandParams, 2);
  2742. SendAlertToUser(commandParams[0], commandParams[1], message, false);
  2743. }
  2744. }
  2745. private string CombineParams(string[] commandParams, int pos)
  2746. {
  2747. string result = String.Empty;
  2748. for (int i = pos; i < commandParams.Length; i++)
  2749. {
  2750. result += commandParams[i] + " ";
  2751. }
  2752. return result;
  2753. }
  2754. #endregion
  2755. /// <summary>
  2756. /// Causes all clients to get a full object update on all of the objects in the scene.
  2757. /// </summary>
  2758. public void ForceClientUpdate()
  2759. {
  2760. List<EntityBase> EntityList = GetEntities();
  2761. foreach (EntityBase ent in EntityList)
  2762. {
  2763. if (ent is SceneObjectGroup)
  2764. {
  2765. ((SceneObjectGroup)ent).ScheduleGroupForFullUpdate();
  2766. }
  2767. }
  2768. }
  2769. /// <summary>
  2770. /// This is currently only used for scale (to scale to MegaPrim size)
  2771. /// There is a console command that calls this in OpenSimMain
  2772. /// </summary>
  2773. /// <param name="cmdparams"></param>
  2774. public void HandleEditCommand(string[] cmdparams)
  2775. {
  2776. Console.WriteLine("Searching for Primitive: '" + cmdparams[0] + "'");
  2777. List<EntityBase> EntityList = GetEntities();
  2778. foreach (EntityBase ent in EntityList)
  2779. {
  2780. if (ent is SceneObjectGroup)
  2781. {
  2782. SceneObjectPart part = ((SceneObjectGroup)ent).GetChildPart(((SceneObjectGroup)ent).UUID);
  2783. if (part != null)
  2784. {
  2785. if (part.Name == cmdparams[0])
  2786. {
  2787. part.Resize(
  2788. new LLVector3(Convert.ToSingle(cmdparams[1]), Convert.ToSingle(cmdparams[2]),
  2789. Convert.ToSingle(cmdparams[3])));
  2790. Console.WriteLine("Edited scale of Primitive: " + part.Name);
  2791. }
  2792. }
  2793. }
  2794. }
  2795. }
  2796. /// <summary>
  2797. /// Shows various details about the sim based on the parameters supplied by the console command in openSimMain.
  2798. /// </summary>
  2799. /// <param name="showWhat"></param>
  2800. public void Show(string showWhat)
  2801. {
  2802. switch (showWhat)
  2803. {
  2804. case "users":
  2805. m_log.Error("Current Region: " + RegionInfo.RegionName);
  2806. m_log.ErrorFormat("{0,-16}{1,-16}{2,-25}{3,-25}{4,-16}{5,-16}{6,-16}", "Firstname", "Lastname",
  2807. "Agent ID", "Session ID", "Circuit", "IP", "World");
  2808. foreach (ScenePresence scenePresence in GetAvatars())
  2809. {
  2810. m_log.ErrorFormat("{0,-16}{1,-16}{2,-25}{3,-25}{4,-16},{5,-16}{6,-16}",
  2811. scenePresence.Firstname,
  2812. scenePresence.Lastname,
  2813. scenePresence.UUID,
  2814. scenePresence.ControllingClient.AgentId,
  2815. "Unknown",
  2816. "Unknown",
  2817. RegionInfo.RegionName);
  2818. }
  2819. break;
  2820. case "modules":
  2821. m_log.Error("The currently loaded modules in " + RegionInfo.RegionName + " are:");
  2822. foreach (IRegionModule module in Modules.Values)
  2823. {
  2824. if (!module.IsSharedModule)
  2825. {
  2826. m_log.Error("Region Module: " + module.Name);
  2827. }
  2828. }
  2829. break;
  2830. }
  2831. }
  2832. #endregion
  2833. #region Script Handling Methods
  2834. /// <summary>
  2835. /// Console command handler to send script command to script engine.
  2836. /// </summary>
  2837. /// <param name="args"></param>
  2838. public void SendCommandToPlugins(string[] args)
  2839. {
  2840. m_eventManager.TriggerOnPluginConsole(args);
  2841. }
  2842. public double GetLandHeight(int x, int y)
  2843. {
  2844. return Heightmap[x, y];
  2845. }
  2846. public LLUUID GetLandOwner(float x, float y)
  2847. {
  2848. ILandObject land = LandChannel.GetLandObject(x, y);
  2849. if (land == null)
  2850. {
  2851. return LLUUID.Zero;
  2852. }
  2853. else
  2854. {
  2855. return land.landData.ownerID;
  2856. }
  2857. }
  2858. public LandData GetLandData(float x, float y)
  2859. {
  2860. return LandChannel.GetLandObject(x, y).landData;
  2861. }
  2862. public void SetLandMusicURL(float x, float y, string url)
  2863. {
  2864. ILandObject land = LandChannel.GetLandObject(x, y);
  2865. if (land == null)
  2866. {
  2867. return;
  2868. }
  2869. else
  2870. {
  2871. land.landData.musicURL = url;
  2872. return;
  2873. }
  2874. }
  2875. public void SetLandMediaURL(float x, float y, string url)
  2876. {
  2877. ILandObject land = LandChannel.GetLandObject(x, y);
  2878. if (land == null)
  2879. {
  2880. return;
  2881. }
  2882. else
  2883. {
  2884. land.landData.mediaURL = url;
  2885. return;
  2886. }
  2887. }
  2888. public RegionInfo RequestClosestRegion(string name)
  2889. {
  2890. return m_sceneGridService.RequestClosestRegion(name);
  2891. }
  2892. #endregion
  2893. #region Script Engine
  2894. private List<ScriptEngineInterface> ScriptEngines = new List<ScriptEngineInterface>();
  2895. private bool m_dumpAssetsToFile;
  2896. /// <summary>
  2897. ///
  2898. /// </summary>
  2899. /// <param name="scriptEngine"></param>
  2900. public void AddScriptEngine(ScriptEngineInterface scriptEngine)
  2901. {
  2902. ScriptEngines.Add(scriptEngine);
  2903. scriptEngine.InitializeEngine(this);
  2904. }
  2905. public void TriggerObjectChanged(uint localID, uint change)
  2906. {
  2907. m_eventManager.TriggerOnScriptChangedEvent(localID, change);
  2908. }
  2909. public void TriggerAtTargetEvent(uint localID, uint handle, LLVector3 targetpos, LLVector3 currentpos)
  2910. {
  2911. m_eventManager.TriggerAtTargetEvent(localID, handle, targetpos, currentpos);
  2912. }
  2913. public void TriggerNotAtTargetEvent(uint localID)
  2914. {
  2915. m_eventManager.TriggerNotAtTargetEvent(localID);
  2916. }
  2917. private bool scriptDanger(SceneObjectPart part,LLVector3 pos)
  2918. {
  2919. ILandObject parcel = LandChannel.GetLandObject(pos.X, pos.Y);
  2920. if (part != null)
  2921. {
  2922. if (parcel != null)
  2923. {
  2924. if ((parcel.landData.landFlags & (uint)Parcel.ParcelFlags.AllowOtherScripts) != 0)
  2925. {
  2926. return true;
  2927. }
  2928. else if ((parcel.landData.landFlags & (uint)Parcel.ParcelFlags.AllowGroupScripts) != 0)
  2929. {
  2930. if (part.OwnerID == parcel.landData.ownerID || (parcel.landData.isGroupOwned && part.GroupID == parcel.landData.groupID) || ExternalChecks.ExternalChecksCanBeGodLike(part.OwnerID))
  2931. {
  2932. return true;
  2933. }
  2934. else
  2935. {
  2936. return false;
  2937. }
  2938. }
  2939. else
  2940. {
  2941. if (part.OwnerID == parcel.landData.ownerID)
  2942. {
  2943. return true;
  2944. }
  2945. else
  2946. {
  2947. return false;
  2948. }
  2949. }
  2950. }
  2951. else
  2952. {
  2953. if (pos.X > 0f && pos.X < Constants.RegionSize && pos.Y > 0f && pos.Y < Constants.RegionSize)
  2954. {
  2955. // The only time parcel != null when an object is inside a region is when
  2956. // there is nothing behind the landchannel. IE, no land plugin loaded.
  2957. return true;
  2958. }
  2959. else
  2960. {
  2961. // The object is outside of this region. Stop piping events to it.
  2962. return false;
  2963. }
  2964. }
  2965. }
  2966. else
  2967. {
  2968. return false;
  2969. }
  2970. }
  2971. public bool scriptDanger(uint localID, LLVector3 pos)
  2972. {
  2973. SceneObjectPart part = GetSceneObjectPart(localID);
  2974. if (part != null)
  2975. {
  2976. return scriptDanger(part, pos);
  2977. }
  2978. else
  2979. {
  2980. return false;
  2981. }
  2982. }
  2983. public bool pipeEventsForScript(uint localID)
  2984. {
  2985. SceneObjectPart part = GetSceneObjectPart(localID);
  2986. if (part != null)
  2987. {
  2988. LLVector3 pos = part.GetWorldPosition();
  2989. return scriptDanger(part, pos);
  2990. }
  2991. else
  2992. {
  2993. return false;
  2994. }
  2995. }
  2996. #endregion
  2997. #region InnerScene wrapper methods
  2998. /// <summary>
  2999. ///
  3000. /// </summary>
  3001. /// <param name="localID"></param>
  3002. /// <returns></returns>
  3003. public LLUUID ConvertLocalIDToFullID(uint localID)
  3004. {
  3005. return m_innerScene.ConvertLocalIDToFullID(localID);
  3006. }
  3007. public void SwapRootAgentCount(bool rootChildChildRootTF)
  3008. {
  3009. m_innerScene.SwapRootChildAgent(rootChildChildRootTF);
  3010. }
  3011. public void AddPhysicalPrim(int num)
  3012. {
  3013. m_innerScene.AddPhysicalPrim(num);
  3014. }
  3015. public void RemovePhysicalPrim(int num)
  3016. {
  3017. m_innerScene.RemovePhysicalPrim(num);
  3018. }
  3019. /// <summary>
  3020. ///
  3021. /// </summary>
  3022. /// <param name="presence"></param>
  3023. public void SendAllSceneObjectsToClient(ScenePresence presence)
  3024. {
  3025. m_innerScene.SendAllSceneObjectsToClient(presence);
  3026. }
  3027. //The idea is to have a group of method that return a list of avatars meeting some requirement
  3028. // ie it could be all m_scenePresences within a certain range of the calling prim/avatar.
  3029. /// <summary>
  3030. /// Return a list of all avatars in this region.
  3031. /// This list is a new object, so it can be iterated over without locking.
  3032. /// </summary>
  3033. /// <returns></returns>
  3034. public List<ScenePresence> GetAvatars()
  3035. {
  3036. return m_innerScene.GetAvatars();
  3037. }
  3038. /// <summary>
  3039. /// Return a list of all ScenePresences in this region. This returns child agents as well as root agents.
  3040. /// This list is a new object, so it can be iterated over without locking.
  3041. /// </summary>
  3042. /// <returns></returns>
  3043. public List<ScenePresence> GetScenePresences()
  3044. {
  3045. return m_innerScene.GetScenePresences();
  3046. }
  3047. /// <summary>
  3048. /// Request a filtered list of ScenePresences in this region.
  3049. /// This list is a new object, so it can be iterated over without locking.
  3050. /// </summary>
  3051. /// <param name="filter"></param>
  3052. /// <returns></returns>
  3053. public List<ScenePresence> GetScenePresences(FilterAvatarList filter)
  3054. {
  3055. return m_innerScene.GetScenePresences(filter);
  3056. }
  3057. /// <summary>
  3058. /// Request a scene presence by UUID
  3059. /// </summary>
  3060. /// <param name="avatarID"></param>
  3061. /// <returns></returns>
  3062. public ScenePresence GetScenePresence(LLUUID avatarID)
  3063. {
  3064. return m_innerScene.GetScenePresence(avatarID);
  3065. }
  3066. /// <summary>
  3067. /// Request an Avatar's Child Status - used by ClientView when a 'kick everyone' or 'estate message' occurs
  3068. /// </summary>
  3069. /// <param name="avatarID">AvatarID to lookup</param>
  3070. /// <returns></returns>
  3071. public override bool PresenceChildStatus(LLUUID avatarID)
  3072. {
  3073. ScenePresence cp = GetScenePresence(avatarID);
  3074. return cp.IsChildAgent;
  3075. }
  3076. /// <summary>
  3077. ///
  3078. /// </summary>
  3079. /// <param name="action"></param>
  3080. public void ForEachScenePresence(Action<ScenePresence> action)
  3081. {
  3082. // We don't want to try to send messages if there are no avatars.
  3083. if (m_scenePresences != null)
  3084. {
  3085. try
  3086. {
  3087. List<ScenePresence> presenceList = GetScenePresences();
  3088. foreach (ScenePresence presence in presenceList)
  3089. {
  3090. action(presence);
  3091. }
  3092. }
  3093. catch (Exception e)
  3094. {
  3095. m_log.Info("[BUG]: " + e.ToString());
  3096. }
  3097. }
  3098. }
  3099. /// <summary>
  3100. ///
  3101. /// </summary>
  3102. /// <param name="action"></param>
  3103. // public void ForEachObject(Action<SceneObjectGroup> action)
  3104. // {
  3105. // List<SceneObjectGroup> presenceList;
  3106. //
  3107. // lock (m_sceneObjects)
  3108. // {
  3109. // presenceList = new List<SceneObjectGroup>(m_sceneObjects.Values);
  3110. // }
  3111. //
  3112. // foreach (SceneObjectGroup presence in presenceList)
  3113. // {
  3114. // action(presence);
  3115. // }
  3116. // }
  3117. /// <summary>
  3118. ///
  3119. /// </summary>
  3120. /// <param name="localID"></param>
  3121. /// <returns></returns>
  3122. public SceneObjectPart GetSceneObjectPart(uint localID)
  3123. {
  3124. return m_innerScene.GetSceneObjectPart(localID);
  3125. }
  3126. /// <summary>
  3127. ///
  3128. /// </summary>
  3129. /// <param name="fullID"></param>
  3130. /// <returns></returns>
  3131. public SceneObjectPart GetSceneObjectPart(LLUUID fullID)
  3132. {
  3133. return m_innerScene.GetSceneObjectPart(fullID);
  3134. }
  3135. internal bool TryGetAvatar(LLUUID avatarId, out ScenePresence avatar)
  3136. {
  3137. return m_innerScene.TryGetAvatar(avatarId, out avatar);
  3138. }
  3139. internal bool TryGetAvatarByName(string avatarName, out ScenePresence avatar)
  3140. {
  3141. return m_innerScene.TryGetAvatarByName(avatarName, out avatar);
  3142. }
  3143. internal void ForEachClient(Action<IClientAPI> action)
  3144. {
  3145. m_innerScene.ForEachClient(action);
  3146. }
  3147. /// <summary>
  3148. /// Returns a list of the entities in the scene. This is a new list so operations perform on the list itself
  3149. /// will not affect the original list of objects in the scene.
  3150. /// </summary>
  3151. /// <returns></returns>
  3152. public List<EntityBase> GetEntities()
  3153. {
  3154. return m_innerScene.GetEntities();
  3155. }
  3156. #endregion
  3157. #region BaseHTTPServer wrapper methods
  3158. public bool AddHTTPHandler(string method, GenericHTTPMethod handler)
  3159. {
  3160. return m_httpListener.AddHTTPHandler(method, handler);
  3161. }
  3162. public bool AddXmlRPCHandler(string method, XmlRpcMethod handler)
  3163. {
  3164. return m_httpListener.AddXmlRPCHandler(method, handler);
  3165. }
  3166. public void AddStreamHandler(IRequestHandler handler)
  3167. {
  3168. m_httpListener.AddStreamHandler(handler);
  3169. }
  3170. public void RemoveStreamHandler(string httpMethod, string path)
  3171. {
  3172. m_httpListener.RemoveStreamHandler(httpMethod, path);
  3173. }
  3174. public void RemoveHTTPHandler(string httpMethod, string path)
  3175. {
  3176. m_httpListener.RemoveHTTPHandler(httpMethod, path);
  3177. }
  3178. #endregion
  3179. #region Avatar Appearance Default
  3180. public static void GetDefaultAvatarAppearance(out AvatarWearable[] wearables, out byte[] visualParams)
  3181. {
  3182. visualParams = GetDefaultVisualParams();
  3183. wearables = AvatarWearable.DefaultWearables;
  3184. }
  3185. private static byte[] GetDefaultVisualParams()
  3186. {
  3187. byte[] visualParams;
  3188. visualParams = new byte[218];
  3189. for (int i = 0; i < 218; i++)
  3190. {
  3191. visualParams[i] = 100;
  3192. }
  3193. return visualParams;
  3194. }
  3195. #endregion
  3196. public void ParcelMediaSetTime(float time)
  3197. {
  3198. //should be doing this by parcel, but as its only for testing
  3199. // The use of Thread.Sleep here causes the following compiler error under mono 1.2.4
  3200. // OpenSim/Region/Environment/Scenes/Scene.cs(3675,17): error CS0103: The name `Thread' does not exist
  3201. // in the context of `<>c__CompilerGenerated17'
  3202. // MW said it was okay to comment the body of this method out for now since the code is experimental
  3203. // and will be replaced anyway
  3204. // ForEachClient(delegate(IClientAPI client)
  3205. // {
  3206. // client.SendParcelMediaCommand((uint)(2), ParcelMediaCommandEnum.Pause, 0);
  3207. // Thread.Sleep(10);
  3208. // client.SendParcelMediaCommand((uint)(64), ParcelMediaCommandEnum.Time, time);
  3209. // Thread.Sleep(200);
  3210. // client.SendParcelMediaCommand((uint)(4), ParcelMediaCommandEnum.Play, 0);
  3211. // });
  3212. }
  3213. }
  3214. }