Scene.cs 208 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142
  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 copyrightD
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of the OpenSimulator Project nor the
  13. * names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
  17. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
  20. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. using System;
  28. using System.Collections.Generic;
  29. using System.Diagnostics;
  30. using System.Drawing;
  31. using System.Drawing.Imaging;
  32. using System.IO;
  33. using System.Text;
  34. using System.Threading;
  35. using System.Timers;
  36. using System.Xml;
  37. using Nini.Config;
  38. using OpenMetaverse;
  39. using OpenMetaverse.Packets;
  40. using OpenMetaverse.Imaging;
  41. using OpenSim.Framework;
  42. using OpenSim.Services.Interfaces;
  43. using OpenSim.Framework.Communications;
  44. using OpenSim.Framework.Console;
  45. using OpenSim.Region.Framework.Interfaces;
  46. using OpenSim.Region.Framework.Scenes.Scripting;
  47. using OpenSim.Region.Framework.Scenes.Serialization;
  48. using OpenSim.Region.Physics.Manager;
  49. using Timer=System.Timers.Timer;
  50. using TPFlags = OpenSim.Framework.Constants.TeleportFlags;
  51. using GridRegion = OpenSim.Services.Interfaces.GridRegion;
  52. namespace OpenSim.Region.Framework.Scenes
  53. {
  54. public delegate bool FilterAvatarList(ScenePresence avatar);
  55. public partial class Scene : SceneBase
  56. {
  57. private const long DEFAULT_MIN_TIME_FOR_PERSISTENCE = 60L;
  58. private const long DEFAULT_MAX_TIME_FOR_PERSISTENCE = 600L;
  59. public delegate void SynchronizeSceneHandler(Scene scene);
  60. #region Fields
  61. public bool EmergencyMonitoring = false;
  62. public SynchronizeSceneHandler SynchronizeScene;
  63. public SimStatsReporter StatsReporter;
  64. public List<Border> NorthBorders = new List<Border>();
  65. public List<Border> EastBorders = new List<Border>();
  66. public List<Border> SouthBorders = new List<Border>();
  67. public List<Border> WestBorders = new List<Border>();
  68. /// <summary>Are we applying physics to any of the prims in this scene?</summary>
  69. public bool m_physicalPrim;
  70. public float m_maxNonphys = 256;
  71. public float m_maxPhys = 10;
  72. public bool m_clampPrimSize;
  73. public bool m_trustBinaries;
  74. public bool m_allowScriptCrossings;
  75. public bool m_useFlySlow;
  76. public bool m_usePreJump;
  77. public bool m_seeIntoRegionFromNeighbor;
  78. protected float m_defaultDrawDistance = 255.0f;
  79. public float DefaultDrawDistance
  80. {
  81. get { return m_defaultDrawDistance; }
  82. }
  83. // TODO: need to figure out how allow client agents but deny
  84. // root agents when ACL denies access to root agent
  85. public bool m_strictAccessControl = true;
  86. public int MaxUndoCount = 5;
  87. // Using this for RegionReady module to prevent LoginsDisabled from changing under our feet;
  88. public bool LoginLock = false;
  89. public bool LoginsDisabled = true;
  90. public bool StartDisabled = false;
  91. public bool LoadingPrims;
  92. public IXfer XferManager;
  93. // the minimum time that must elapse before a changed object will be considered for persisted
  94. public long m_dontPersistBefore = DEFAULT_MIN_TIME_FOR_PERSISTENCE * 10000000L;
  95. // the maximum time that must elapse before a changed object will be considered for persisted
  96. public long m_persistAfter = DEFAULT_MAX_TIME_FOR_PERSISTENCE * 10000000L;
  97. protected int m_splitRegionID;
  98. protected Timer m_restartWaitTimer = new Timer();
  99. protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>();
  100. protected List<RegionInfo> m_neighbours = new List<RegionInfo>();
  101. protected string m_simulatorVersion = "OpenSimulator Server";
  102. protected ModuleLoader m_moduleLoader;
  103. protected AgentCircuitManager m_authenticateHandler;
  104. protected SceneCommunicationService m_sceneGridService;
  105. protected ISimulationDataService m_SimulationDataService;
  106. protected IEstateDataService m_EstateDataService;
  107. protected IAssetService m_AssetService;
  108. protected IAuthorizationService m_AuthorizationService;
  109. protected IInventoryService m_InventoryService;
  110. protected IGridService m_GridService;
  111. protected ILibraryService m_LibraryService;
  112. protected ISimulationService m_simulationService;
  113. protected IAuthenticationService m_AuthenticationService;
  114. protected IPresenceService m_PresenceService;
  115. protected IUserAccountService m_UserAccountService;
  116. protected IAvatarService m_AvatarService;
  117. protected IGridUserService m_GridUserService;
  118. protected IXMLRPC m_xmlrpcModule;
  119. protected IWorldComm m_worldCommModule;
  120. protected IAvatarFactory m_AvatarFactory;
  121. protected IConfigSource m_config;
  122. protected IRegionSerialiserModule m_serialiser;
  123. protected IDialogModule m_dialogModule;
  124. protected IEntityTransferModule m_teleportModule;
  125. protected ICapabilitiesModule m_capsModule;
  126. // Central Update Loop
  127. protected int m_fps = 10;
  128. /// <summary>
  129. /// Current scene frame number
  130. /// </summary>
  131. public uint Frame
  132. {
  133. get;
  134. protected set;
  135. }
  136. protected float m_timespan = 0.089f;
  137. protected DateTime m_lastupdate = DateTime.UtcNow;
  138. // TODO: Possibly stop other classes being able to manipulate this directly.
  139. private SceneGraph m_sceneGraph;
  140. private volatile int m_bordersLocked;
  141. // private int m_RestartTimerCounter;
  142. private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing
  143. // private int m_incrementsof15seconds;
  144. private volatile bool m_backingup;
  145. private Dictionary<UUID, ReturnInfo> m_returns = new Dictionary<UUID, ReturnInfo>();
  146. private Dictionary<UUID, SceneObjectGroup> m_groupsWithTargets = new Dictionary<UUID, SceneObjectGroup>();
  147. private Object m_heartbeatLock = new Object();
  148. private int m_update_physics = 1;
  149. private int m_update_entitymovement = 1;
  150. private int m_update_objects = 1; // Update objects which have scheduled themselves for updates
  151. private int m_update_presences = 1; // Update scene presence movements
  152. private int m_update_events = 1;
  153. private int m_update_backup = 200;
  154. private int m_update_terrain = 50;
  155. // private int m_update_land = 1;
  156. private int m_update_coarse_locations = 50;
  157. private int frameMS;
  158. private int physicsMS2;
  159. private int physicsMS;
  160. private int otherMS;
  161. private int tempOnRezMS;
  162. private int eventMS;
  163. private int backupMS;
  164. private int terrainMS;
  165. private int landMS;
  166. private int lastCompletedFrame;
  167. private bool m_physics_enabled = true;
  168. private bool m_scripts_enabled = true;
  169. private string m_defaultScriptEngine;
  170. private int m_LastLogin;
  171. private Thread HeartbeatThread;
  172. private volatile bool shuttingdown;
  173. private int m_lastUpdate;
  174. private bool m_firstHeartbeat = true;
  175. private object m_deleting_scene_object = new object();
  176. private object m_cleaningAttachments = new object();
  177. private bool m_cleaningTemps = false;
  178. private UpdatePrioritizationSchemes m_priorityScheme = UpdatePrioritizationSchemes.Time;
  179. private bool m_reprioritizationEnabled = true;
  180. private double m_reprioritizationInterval = 5000.0;
  181. private double m_rootReprioritizationDistance = 10.0;
  182. private double m_childReprioritizationDistance = 20.0;
  183. private Timer m_mapGenerationTimer = new Timer();
  184. private bool m_generateMaptiles;
  185. private bool m_useBackup = true;
  186. // private Dictionary<UUID, string[]> m_UserNamesCache = new Dictionary<UUID, string[]>();
  187. #endregion Fields
  188. #region Properties
  189. /* Used by the loadbalancer plugin on GForge */
  190. public int SplitRegionID
  191. {
  192. get { return m_splitRegionID; }
  193. set { m_splitRegionID = value; }
  194. }
  195. public bool BordersLocked
  196. {
  197. get { return m_bordersLocked == 1; }
  198. set
  199. {
  200. if (value == true)
  201. m_bordersLocked = 1;
  202. else
  203. m_bordersLocked = 0;
  204. }
  205. }
  206. public new float TimeDilation
  207. {
  208. get { return m_sceneGraph.PhysicsScene.TimeDilation; }
  209. }
  210. public SceneCommunicationService SceneGridService
  211. {
  212. get { return m_sceneGridService; }
  213. }
  214. public ISimulationDataService SimulationDataService
  215. {
  216. get
  217. {
  218. if (m_SimulationDataService == null)
  219. {
  220. m_SimulationDataService = RequestModuleInterface<ISimulationDataService>();
  221. if (m_SimulationDataService == null)
  222. {
  223. throw new Exception("No ISimulationDataService available.");
  224. }
  225. }
  226. return m_SimulationDataService;
  227. }
  228. }
  229. public IEstateDataService EstateDataService
  230. {
  231. get
  232. {
  233. if (m_EstateDataService == null)
  234. {
  235. m_EstateDataService = RequestModuleInterface<IEstateDataService>();
  236. if (m_EstateDataService == null)
  237. {
  238. throw new Exception("No IEstateDataService available.");
  239. }
  240. }
  241. return m_EstateDataService;
  242. }
  243. }
  244. public IAssetService AssetService
  245. {
  246. get
  247. {
  248. if (m_AssetService == null)
  249. {
  250. m_AssetService = RequestModuleInterface<IAssetService>();
  251. if (m_AssetService == null)
  252. {
  253. throw new Exception("No IAssetService available.");
  254. }
  255. }
  256. return m_AssetService;
  257. }
  258. }
  259. public IAuthorizationService AuthorizationService
  260. {
  261. get
  262. {
  263. if (m_AuthorizationService == null)
  264. {
  265. m_AuthorizationService = RequestModuleInterface<IAuthorizationService>();
  266. //if (m_AuthorizationService == null)
  267. //{
  268. // // don't throw an exception if no authorization service is set for the time being
  269. // m_log.InfoFormat("[SCENE]: No Authorization service is configured");
  270. //}
  271. }
  272. return m_AuthorizationService;
  273. }
  274. }
  275. public IInventoryService InventoryService
  276. {
  277. get
  278. {
  279. if (m_InventoryService == null)
  280. {
  281. m_InventoryService = RequestModuleInterface<IInventoryService>();
  282. if (m_InventoryService == null)
  283. {
  284. throw new Exception("No IInventoryService available. This could happen if the config_include folder doesn't exist or if the OpenSim.ini [Architecture] section isn't set. Please also check that you have the correct version of your inventory service dll. Sometimes old versions of this dll will still exist. Do a clean checkout and re-create the opensim.ini from the opensim.ini.example.");
  285. }
  286. }
  287. return m_InventoryService;
  288. }
  289. }
  290. public IGridService GridService
  291. {
  292. get
  293. {
  294. if (m_GridService == null)
  295. {
  296. m_GridService = RequestModuleInterface<IGridService>();
  297. if (m_GridService == null)
  298. {
  299. throw new Exception("No IGridService available. This could happen if the config_include folder doesn't exist or if the OpenSim.ini [Architecture] section isn't set. Please also check that you have the correct version of your inventory service dll. Sometimes old versions of this dll will still exist. Do a clean checkout and re-create the opensim.ini from the opensim.ini.example.");
  300. }
  301. }
  302. return m_GridService;
  303. }
  304. }
  305. public ILibraryService LibraryService
  306. {
  307. get
  308. {
  309. if (m_LibraryService == null)
  310. m_LibraryService = RequestModuleInterface<ILibraryService>();
  311. return m_LibraryService;
  312. }
  313. }
  314. public ISimulationService SimulationService
  315. {
  316. get
  317. {
  318. if (m_simulationService == null)
  319. m_simulationService = RequestModuleInterface<ISimulationService>();
  320. return m_simulationService;
  321. }
  322. }
  323. public IAuthenticationService AuthenticationService
  324. {
  325. get
  326. {
  327. if (m_AuthenticationService == null)
  328. m_AuthenticationService = RequestModuleInterface<IAuthenticationService>();
  329. return m_AuthenticationService;
  330. }
  331. }
  332. public IPresenceService PresenceService
  333. {
  334. get
  335. {
  336. if (m_PresenceService == null)
  337. m_PresenceService = RequestModuleInterface<IPresenceService>();
  338. return m_PresenceService;
  339. }
  340. }
  341. public IUserAccountService UserAccountService
  342. {
  343. get
  344. {
  345. if (m_UserAccountService == null)
  346. m_UserAccountService = RequestModuleInterface<IUserAccountService>();
  347. return m_UserAccountService;
  348. }
  349. }
  350. public IAvatarService AvatarService
  351. {
  352. get
  353. {
  354. if (m_AvatarService == null)
  355. m_AvatarService = RequestModuleInterface<IAvatarService>();
  356. return m_AvatarService;
  357. }
  358. }
  359. public IGridUserService GridUserService
  360. {
  361. get
  362. {
  363. if (m_GridUserService == null)
  364. m_GridUserService = RequestModuleInterface<IGridUserService>();
  365. return m_GridUserService;
  366. }
  367. }
  368. public IAttachmentsModule AttachmentsModule { get; set; }
  369. public IAvatarFactory AvatarFactory
  370. {
  371. get { return m_AvatarFactory; }
  372. }
  373. public ICapabilitiesModule CapsModule
  374. {
  375. get { return m_capsModule; }
  376. }
  377. public int MonitorFrameTime { get { return frameMS; } }
  378. public int MonitorPhysicsUpdateTime { get { return physicsMS; } }
  379. public int MonitorPhysicsSyncTime { get { return physicsMS2; } }
  380. public int MonitorOtherTime { get { return otherMS; } }
  381. public int MonitorTempOnRezTime { get { return tempOnRezMS; } }
  382. public int MonitorEventTime { get { return eventMS; } } // This may need to be divided into each event?
  383. public int MonitorBackupTime { get { return backupMS; } }
  384. public int MonitorTerrainTime { get { return terrainMS; } }
  385. public int MonitorLandTime { get { return landMS; } }
  386. public int MonitorLastFrameTick { get { return lastCompletedFrame; } }
  387. public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get { return m_priorityScheme; } }
  388. public bool IsReprioritizationEnabled { get { return m_reprioritizationEnabled; } }
  389. public double ReprioritizationInterval { get { return m_reprioritizationInterval; } }
  390. public double RootReprioritizationDistance { get { return m_rootReprioritizationDistance; } }
  391. public double ChildReprioritizationDistance { get { return m_childReprioritizationDistance; } }
  392. public AgentCircuitManager AuthenticateHandler
  393. {
  394. get { return m_authenticateHandler; }
  395. }
  396. public SceneGraph SceneContents
  397. {
  398. get { return m_sceneGraph; }
  399. }
  400. public bool UseBackup
  401. {
  402. get { return m_useBackup; }
  403. }
  404. // an instance to the physics plugin's Scene object.
  405. public PhysicsScene PhysicsScene
  406. {
  407. get { return m_sceneGraph.PhysicsScene; }
  408. set
  409. {
  410. // If we're not doing the initial set
  411. // Then we've got to remove the previous
  412. // event handler
  413. if (PhysicsScene != null && PhysicsScene.SupportsNINJAJoints)
  414. {
  415. PhysicsScene.OnJointMoved -= jointMoved;
  416. PhysicsScene.OnJointDeactivated -= jointDeactivated;
  417. PhysicsScene.OnJointErrorMessage -= jointErrorMessage;
  418. }
  419. m_sceneGraph.PhysicsScene = value;
  420. if (PhysicsScene != null && m_sceneGraph.PhysicsScene.SupportsNINJAJoints)
  421. {
  422. // register event handlers to respond to joint movement/deactivation
  423. PhysicsScene.OnJointMoved += jointMoved;
  424. PhysicsScene.OnJointDeactivated += jointDeactivated;
  425. PhysicsScene.OnJointErrorMessage += jointErrorMessage;
  426. }
  427. }
  428. }
  429. // This gets locked so things stay thread safe.
  430. public object SyncRoot
  431. {
  432. get { return m_sceneGraph.m_syncRoot; }
  433. }
  434. /// <summary>
  435. /// This is for llGetRegionFPS
  436. /// </summary>
  437. public float SimulatorFPS
  438. {
  439. get { return StatsReporter.getLastReportedSimFPS(); }
  440. }
  441. public float[] SimulatorStats
  442. {
  443. get { return StatsReporter.getLastReportedSimStats(); }
  444. }
  445. public string DefaultScriptEngine
  446. {
  447. get { return m_defaultScriptEngine; }
  448. }
  449. public EntityManager Entities
  450. {
  451. get { return m_sceneGraph.Entities; }
  452. }
  453. #endregion Properties
  454. #region Constructors
  455. public Scene(RegionInfo regInfo, AgentCircuitManager authen,
  456. SceneCommunicationService sceneGridService,
  457. ISimulationDataService simDataService, IEstateDataService estateDataService,
  458. ModuleLoader moduleLoader, bool dumpAssetsToFile, bool physicalPrim,
  459. bool SeeIntoRegionFromNeighbor, IConfigSource config, string simulatorVersion)
  460. {
  461. m_config = config;
  462. Random random = new Random();
  463. BordersLocked = true;
  464. Border northBorder = new Border();
  465. northBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, (int)Constants.RegionSize); //<---
  466. northBorder.CrossDirection = Cardinals.N;
  467. NorthBorders.Add(northBorder);
  468. Border southBorder = new Border();
  469. southBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, 0); //--->
  470. southBorder.CrossDirection = Cardinals.S;
  471. SouthBorders.Add(southBorder);
  472. Border eastBorder = new Border();
  473. eastBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, (int)Constants.RegionSize); //<---
  474. eastBorder.CrossDirection = Cardinals.E;
  475. EastBorders.Add(eastBorder);
  476. Border westBorder = new Border();
  477. westBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, 0); //--->
  478. westBorder.CrossDirection = Cardinals.W;
  479. WestBorders.Add(westBorder);
  480. BordersLocked = false;
  481. m_lastAllocatedLocalId = (uint)(random.NextDouble() * (double)(uint.MaxValue/2))+(uint)(uint.MaxValue/4);
  482. m_moduleLoader = moduleLoader;
  483. m_authenticateHandler = authen;
  484. m_sceneGridService = sceneGridService;
  485. m_SimulationDataService = simDataService;
  486. m_EstateDataService = estateDataService;
  487. m_regInfo = regInfo;
  488. m_regionHandle = m_regInfo.RegionHandle;
  489. m_regionName = m_regInfo.RegionName;
  490. m_lastUpdate = Util.EnvironmentTickCount();
  491. m_physicalPrim = physicalPrim;
  492. m_seeIntoRegionFromNeighbor = SeeIntoRegionFromNeighbor;
  493. m_eventManager = new EventManager();
  494. m_permissions = new ScenePermissions(this);
  495. m_asyncSceneObjectDeleter = new AsyncSceneObjectGroupDeleter(this);
  496. m_asyncSceneObjectDeleter.Enabled = true;
  497. m_asyncInventorySender = new AsyncInventorySender(this);
  498. #region Region Settings
  499. // Load region settings
  500. // LoadRegionSettings creates new region settings in persistence if they don't already exist for this region.
  501. // However, in this case, the default textures are not set in memory properly, so we need to do it here and
  502. // resave.
  503. // FIXME: It shouldn't be up to the database plugins to create this data - we should do it when a new
  504. // region is set up and avoid these gyrations.
  505. RegionSettings rs = simDataService.LoadRegionSettings(m_regInfo.RegionID);
  506. bool updatedTerrainTextures = false;
  507. if (rs.TerrainTexture1 == UUID.Zero)
  508. {
  509. rs.TerrainTexture1 = RegionSettings.DEFAULT_TERRAIN_TEXTURE_1;
  510. updatedTerrainTextures = true;
  511. }
  512. if (rs.TerrainTexture2 == UUID.Zero)
  513. {
  514. rs.TerrainTexture2 = RegionSettings.DEFAULT_TERRAIN_TEXTURE_2;
  515. updatedTerrainTextures = true;
  516. }
  517. if (rs.TerrainTexture3 == UUID.Zero)
  518. {
  519. rs.TerrainTexture3 = RegionSettings.DEFAULT_TERRAIN_TEXTURE_3;
  520. updatedTerrainTextures = true;
  521. }
  522. if (rs.TerrainTexture4 == UUID.Zero)
  523. {
  524. rs.TerrainTexture4 = RegionSettings.DEFAULT_TERRAIN_TEXTURE_4;
  525. updatedTerrainTextures = true;
  526. }
  527. if (updatedTerrainTextures)
  528. rs.Save();
  529. m_regInfo.RegionSettings = rs;
  530. if (estateDataService != null)
  531. m_regInfo.EstateSettings = estateDataService.LoadEstateSettings(m_regInfo.RegionID, false);
  532. #endregion Region Settings
  533. MainConsole.Instance.Commands.AddCommand("region", false, "reload estate",
  534. "reload estate",
  535. "Reload the estate data", HandleReloadEstate);
  536. MainConsole.Instance.Commands.AddCommand("region", false, "delete object owner",
  537. "delete object owner <UUID>",
  538. "Delete object by owner", HandleDeleteObject);
  539. MainConsole.Instance.Commands.AddCommand("region", false, "delete object creator",
  540. "delete object creator <UUID>",
  541. "Delete object by creator", HandleDeleteObject);
  542. MainConsole.Instance.Commands.AddCommand("region", false, "delete object uuid",
  543. "delete object uuid <UUID>",
  544. "Delete object by uuid", HandleDeleteObject);
  545. MainConsole.Instance.Commands.AddCommand("region", false, "delete object name",
  546. "delete object name <name>",
  547. "Delete object by name", HandleDeleteObject);
  548. MainConsole.Instance.Commands.AddCommand("region", false, "delete object outside",
  549. "delete object outside",
  550. "Delete all objects outside boundaries", HandleDeleteObject);
  551. //Bind Storage Manager functions to some land manager functions for this scene
  552. EventManager.OnLandObjectAdded +=
  553. new EventManager.LandObjectAdded(simDataService.StoreLandObject);
  554. EventManager.OnLandObjectRemoved +=
  555. new EventManager.LandObjectRemoved(simDataService.RemoveLandObject);
  556. m_sceneGraph = new SceneGraph(this);
  557. // If the scene graph has an Unrecoverable error, restart this sim.
  558. // Currently the only thing that causes it to happen is two kinds of specific
  559. // Physics based crashes.
  560. //
  561. // Out of memory
  562. // Operating system has killed the plugin
  563. m_sceneGraph.UnRecoverableError += RestartNow;
  564. RegisterDefaultSceneEvents();
  565. DumpAssetsToFile = dumpAssetsToFile;
  566. m_scripts_enabled = !RegionInfo.RegionSettings.DisableScripts;
  567. m_physics_enabled = !RegionInfo.RegionSettings.DisablePhysics;
  568. StatsReporter = new SimStatsReporter(this);
  569. StatsReporter.OnSendStatsResult += SendSimStatsPackets;
  570. StatsReporter.OnStatsIncorrect += m_sceneGraph.RecalculateStats;
  571. // Old
  572. /*
  573. m_simulatorVersion = simulatorVersion
  574. + " (OS " + Util.GetOperatingSystemInformation() + ")"
  575. + " ChilTasks:" + m_seeIntoRegionFromNeighbor.ToString()
  576. + " PhysPrim:" + m_physicalPrim.ToString();
  577. */
  578. m_simulatorVersion = simulatorVersion + " (" + Util.GetRuntimeInformation() + ")";
  579. #region Region Config
  580. try
  581. {
  582. // Region config overrides global config
  583. //
  584. IConfig startupConfig = m_config.Configs["Startup"];
  585. m_defaultDrawDistance = startupConfig.GetFloat("DefaultDrawDistance",m_defaultDrawDistance);
  586. m_useBackup = startupConfig.GetBoolean("UseSceneBackup", m_useBackup);
  587. if (!m_useBackup)
  588. m_log.InfoFormat("[SCENE]: Backup has been disabled for {0}", RegionInfo.RegionName);
  589. //Animation states
  590. m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false);
  591. // TODO: Change default to true once the feature is supported
  592. m_usePreJump = startupConfig.GetBoolean("enableprejump", false);
  593. m_maxNonphys = startupConfig.GetFloat("NonPhysicalPrimMax", m_maxNonphys);
  594. if (RegionInfo.NonphysPrimMax > 0)
  595. {
  596. m_maxNonphys = RegionInfo.NonphysPrimMax;
  597. }
  598. m_maxPhys = startupConfig.GetFloat("PhysicalPrimMax", m_maxPhys);
  599. if (RegionInfo.PhysPrimMax > 0)
  600. {
  601. m_maxPhys = RegionInfo.PhysPrimMax;
  602. }
  603. // Here, if clamping is requested in either global or
  604. // local config, it will be used
  605. //
  606. m_clampPrimSize = startupConfig.GetBoolean("ClampPrimSize", m_clampPrimSize);
  607. if (RegionInfo.ClampPrimSize)
  608. {
  609. m_clampPrimSize = true;
  610. }
  611. m_trustBinaries = startupConfig.GetBoolean("TrustBinaries", m_trustBinaries);
  612. m_allowScriptCrossings = startupConfig.GetBoolean("AllowScriptCrossing", m_allowScriptCrossings);
  613. m_dontPersistBefore =
  614. startupConfig.GetLong("MinimumTimeBeforePersistenceConsidered", DEFAULT_MIN_TIME_FOR_PERSISTENCE);
  615. m_dontPersistBefore *= 10000000;
  616. m_persistAfter =
  617. startupConfig.GetLong("MaximumTimeBeforePersistenceConsidered", DEFAULT_MAX_TIME_FOR_PERSISTENCE);
  618. m_persistAfter *= 10000000;
  619. m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine");
  620. IConfig packetConfig = m_config.Configs["PacketPool"];
  621. if (packetConfig != null)
  622. {
  623. PacketPool.Instance.RecyclePackets = packetConfig.GetBoolean("RecyclePackets", true);
  624. PacketPool.Instance.RecycleDataBlocks = packetConfig.GetBoolean("RecycleDataBlocks", true);
  625. }
  626. m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl);
  627. m_generateMaptiles = startupConfig.GetBoolean("GenerateMaptiles", true);
  628. if (m_generateMaptiles)
  629. {
  630. int maptileRefresh = startupConfig.GetInt("MaptileRefresh", 0);
  631. if (maptileRefresh != 0)
  632. {
  633. m_mapGenerationTimer.Interval = maptileRefresh * 1000;
  634. m_mapGenerationTimer.Elapsed += RegenerateMaptile;
  635. m_mapGenerationTimer.AutoReset = true;
  636. m_mapGenerationTimer.Start();
  637. }
  638. }
  639. else
  640. {
  641. string tile = startupConfig.GetString("MaptileStaticUUID", UUID.Zero.ToString());
  642. UUID tileID;
  643. if (UUID.TryParse(tile, out tileID))
  644. {
  645. RegionInfo.RegionSettings.TerrainImageID = tileID;
  646. }
  647. }
  648. }
  649. catch
  650. {
  651. m_log.Warn("[SCENE]: Failed to load StartupConfig");
  652. }
  653. #endregion Region Config
  654. #region Interest Management
  655. if (m_config != null)
  656. {
  657. IConfig interestConfig = m_config.Configs["InterestManagement"];
  658. if (interestConfig != null)
  659. {
  660. string update_prioritization_scheme = interestConfig.GetString("UpdatePrioritizationScheme", "Time").Trim().ToLower();
  661. try
  662. {
  663. m_priorityScheme = (UpdatePrioritizationSchemes)Enum.Parse(typeof(UpdatePrioritizationSchemes), update_prioritization_scheme, true);
  664. }
  665. catch (Exception)
  666. {
  667. m_log.Warn("[PRIORITIZER]: UpdatePrioritizationScheme was not recognized, setting to default prioritizer Time");
  668. m_priorityScheme = UpdatePrioritizationSchemes.Time;
  669. }
  670. m_reprioritizationEnabled = interestConfig.GetBoolean("ReprioritizationEnabled", true);
  671. m_reprioritizationInterval = interestConfig.GetDouble("ReprioritizationInterval", 5000.0);
  672. m_rootReprioritizationDistance = interestConfig.GetDouble("RootReprioritizationDistance", 10.0);
  673. m_childReprioritizationDistance = interestConfig.GetDouble("ChildReprioritizationDistance", 20.0);
  674. }
  675. }
  676. m_log.Info("[SCENE]: Using the " + m_priorityScheme + " prioritization scheme");
  677. #endregion Interest Management
  678. }
  679. /// <summary>
  680. /// Mock constructor for scene group persistency unit tests.
  681. /// SceneObjectGroup RegionId property is delegated to Scene.
  682. /// </summary>
  683. /// <param name="regInfo"></param>
  684. public Scene(RegionInfo regInfo)
  685. {
  686. BordersLocked = true;
  687. Border northBorder = new Border();
  688. northBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, (int)Constants.RegionSize); //<---
  689. northBorder.CrossDirection = Cardinals.N;
  690. NorthBorders.Add(northBorder);
  691. Border southBorder = new Border();
  692. southBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue,0); //--->
  693. southBorder.CrossDirection = Cardinals.S;
  694. SouthBorders.Add(southBorder);
  695. Border eastBorder = new Border();
  696. eastBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, (int)Constants.RegionSize); //<---
  697. eastBorder.CrossDirection = Cardinals.E;
  698. EastBorders.Add(eastBorder);
  699. Border westBorder = new Border();
  700. westBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue,0); //--->
  701. westBorder.CrossDirection = Cardinals.W;
  702. WestBorders.Add(westBorder);
  703. BordersLocked = false;
  704. m_regInfo = regInfo;
  705. m_eventManager = new EventManager();
  706. m_permissions = new ScenePermissions(this);
  707. m_lastUpdate = Util.EnvironmentTickCount();
  708. }
  709. #endregion
  710. #region Startup / Close Methods
  711. public bool ShuttingDown
  712. {
  713. get { return shuttingdown; }
  714. }
  715. /// <value>
  716. /// The scene graph for this scene
  717. /// </value>
  718. /// TODO: Possibly stop other classes being able to manipulate this directly.
  719. public SceneGraph SceneGraph
  720. {
  721. get { return m_sceneGraph; }
  722. }
  723. protected virtual void RegisterDefaultSceneEvents()
  724. {
  725. IDialogModule dm = RequestModuleInterface<IDialogModule>();
  726. if (dm != null)
  727. m_eventManager.OnPermissionError += dm.SendAlertToUser;
  728. }
  729. public override string GetSimulatorVersion()
  730. {
  731. return m_simulatorVersion;
  732. }
  733. /// <summary>
  734. /// Another region is up.
  735. ///
  736. /// We only add it to the neighbor list if it's within 1 region from here.
  737. /// Agents may have draw distance values that cross two regions though, so
  738. /// we add it to the notify list regardless of distance. We'll check
  739. /// the agent's draw distance before notifying them though.
  740. /// </summary>
  741. /// <param name="otherRegion">RegionInfo handle for the new region.</param>
  742. /// <returns>True after all operations complete, throws exceptions otherwise.</returns>
  743. public override void OtherRegionUp(GridRegion otherRegion)
  744. {
  745. uint xcell = (uint)((int)otherRegion.RegionLocX / (int)Constants.RegionSize);
  746. uint ycell = (uint)((int)otherRegion.RegionLocY / (int)Constants.RegionSize);
  747. //m_log.InfoFormat("[SCENE]: (on region {0}): Region {1} up in coords {2}-{3}",
  748. // RegionInfo.RegionName, otherRegion.RegionName, xcell, ycell);
  749. if (RegionInfo.RegionHandle != otherRegion.RegionHandle)
  750. {
  751. // If these are cast to INT because long + negative values + abs returns invalid data
  752. int resultX = Math.Abs((int)xcell - (int)RegionInfo.RegionLocX);
  753. int resultY = Math.Abs((int)ycell - (int)RegionInfo.RegionLocY);
  754. if (resultX <= 1 && resultY <= 1)
  755. {
  756. // Let the grid service module know, so this can be cached
  757. m_eventManager.TriggerOnRegionUp(otherRegion);
  758. try
  759. {
  760. ForEachScenePresence(delegate(ScenePresence agent)
  761. {
  762. // If agent is a root agent.
  763. if (!agent.IsChildAgent)
  764. {
  765. //agent.ControllingClient.new
  766. //this.CommsManager.InterRegion.InformRegionOfChildAgent(otherRegion.RegionHandle, agent.ControllingClient.RequestClientInfo());
  767. List<ulong> old = new List<ulong>();
  768. old.Add(otherRegion.RegionHandle);
  769. agent.DropOldNeighbours(old);
  770. if (m_teleportModule != null)
  771. m_teleportModule.EnableChildAgent(agent, otherRegion);
  772. }
  773. }
  774. );
  775. }
  776. catch (NullReferenceException)
  777. {
  778. // This means that we're not booted up completely yet.
  779. // This shouldn't happen too often anymore.
  780. m_log.Error("[SCENE]: Couldn't inform client of regionup because we got a null reference exception");
  781. }
  782. }
  783. else
  784. {
  785. m_log.Info("[INTERGRID]: Got notice about far away Region: " + otherRegion.RegionName.ToString() +
  786. " at (" + otherRegion.RegionLocX.ToString() + ", " +
  787. otherRegion.RegionLocY.ToString() + ")");
  788. }
  789. }
  790. }
  791. public void AddNeighborRegion(RegionInfo region)
  792. {
  793. lock (m_neighbours)
  794. {
  795. if (!CheckNeighborRegion(region))
  796. {
  797. m_neighbours.Add(region);
  798. }
  799. }
  800. }
  801. public bool CheckNeighborRegion(RegionInfo region)
  802. {
  803. bool found = false;
  804. lock (m_neighbours)
  805. {
  806. foreach (RegionInfo reg in m_neighbours)
  807. {
  808. if (reg.RegionHandle == region.RegionHandle)
  809. {
  810. found = true;
  811. break;
  812. }
  813. }
  814. }
  815. return found;
  816. }
  817. // Alias IncomingHelloNeighbour OtherRegionUp, for now
  818. public GridRegion IncomingHelloNeighbour(RegionInfo neighbour)
  819. {
  820. OtherRegionUp(new GridRegion(neighbour));
  821. return new GridRegion(RegionInfo);
  822. }
  823. // This causes the region to restart immediatley.
  824. public void RestartNow()
  825. {
  826. IConfig startupConfig = m_config.Configs["Startup"];
  827. if (startupConfig != null)
  828. {
  829. if (startupConfig.GetBoolean("InworldRestartShutsDown", false))
  830. {
  831. MainConsole.Instance.RunCommand("shutdown");
  832. return;
  833. }
  834. }
  835. if (PhysicsScene != null)
  836. {
  837. PhysicsScene.Dispose();
  838. }
  839. m_log.Error("[REGION]: Closing");
  840. Close();
  841. m_log.Error("[REGION]: Firing Region Restart Message");
  842. base.Restart();
  843. }
  844. // This is a helper function that notifies root agents in this region that a new sim near them has come up
  845. // This is in the form of a timer because when an instance of OpenSim.exe is started,
  846. // Even though the sims initialize, they don't listen until 'all of the sims are initialized'
  847. // If we tell an agent about a sim that's not listening yet, the agent will not be able to connect to it.
  848. // subsequently the agent will never see the region come back online.
  849. public void RestartNotifyWaitElapsed(object sender, ElapsedEventArgs e)
  850. {
  851. m_restartWaitTimer.Stop();
  852. lock (m_regionRestartNotifyList)
  853. {
  854. foreach (RegionInfo region in m_regionRestartNotifyList)
  855. {
  856. GridRegion r = new GridRegion(region);
  857. try
  858. {
  859. ForEachScenePresence(delegate(ScenePresence agent)
  860. {
  861. // If agent is a root agent.
  862. if (!agent.IsChildAgent)
  863. {
  864. if (m_teleportModule != null)
  865. m_teleportModule.EnableChildAgent(agent, r);
  866. }
  867. }
  868. );
  869. }
  870. catch (NullReferenceException)
  871. {
  872. // This means that we're not booted up completely yet.
  873. // This shouldn't happen too often anymore.
  874. }
  875. }
  876. // Reset list to nothing.
  877. m_regionRestartNotifyList.Clear();
  878. }
  879. }
  880. public void SetSceneCoreDebug(bool ScriptEngine, bool CollisionEvents, bool PhysicsEngine)
  881. {
  882. if (m_scripts_enabled != !ScriptEngine)
  883. {
  884. if (ScriptEngine)
  885. {
  886. m_log.Info("Stopping all Scripts in Scene");
  887. EntityBase[] entities = Entities.GetEntities();
  888. foreach (EntityBase ent in entities)
  889. {
  890. if (ent is SceneObjectGroup)
  891. ((SceneObjectGroup)ent).RemoveScriptInstances(false);
  892. }
  893. }
  894. else
  895. {
  896. m_log.Info("Starting all Scripts in Scene");
  897. EntityBase[] entities = Entities.GetEntities();
  898. foreach (EntityBase ent in entities)
  899. {
  900. if (ent is SceneObjectGroup)
  901. {
  902. SceneObjectGroup sog = (SceneObjectGroup)ent;
  903. sog.CreateScriptInstances(0, false, DefaultScriptEngine, 0);
  904. sog.ResumeScripts();
  905. }
  906. }
  907. }
  908. m_scripts_enabled = !ScriptEngine;
  909. m_log.Info("[TOTEDD]: Here is the method to trigger disabling of the scripting engine");
  910. }
  911. if (m_physics_enabled != !PhysicsEngine)
  912. {
  913. m_physics_enabled = !PhysicsEngine;
  914. }
  915. }
  916. public int GetInaccurateNeighborCount()
  917. {
  918. return m_neighbours.Count;
  919. }
  920. // This is the method that shuts down the scene.
  921. public override void Close()
  922. {
  923. m_log.InfoFormat("[SCENE]: Closing down the single simulator: {0}", RegionInfo.RegionName);
  924. m_restartTimer.Stop();
  925. m_restartTimer.Close();
  926. // Kick all ROOT agents with the message, 'The simulator is going down'
  927. ForEachScenePresence(delegate(ScenePresence avatar)
  928. {
  929. if (avatar.KnownChildRegionHandles.Contains(RegionInfo.RegionHandle))
  930. avatar.KnownChildRegionHandles.Remove(RegionInfo.RegionHandle);
  931. if (!avatar.IsChildAgent)
  932. avatar.ControllingClient.Kick("The simulator is going down.");
  933. avatar.ControllingClient.SendShutdownConnectionNotice();
  934. });
  935. // Wait here, or the kick messages won't actually get to the agents before the scene terminates.
  936. Thread.Sleep(500);
  937. // Stop all client threads.
  938. ForEachScenePresence(delegate(ScenePresence avatar) { avatar.ControllingClient.Close(); });
  939. // Stop updating the scene objects and agents.
  940. //m_heartbeatTimer.Close();
  941. shuttingdown = true;
  942. m_log.Debug("[SCENE]: Persisting changed objects");
  943. EventManager.TriggerSceneShuttingDown(this);
  944. EntityBase[] entities = GetEntities();
  945. foreach (EntityBase entity in entities)
  946. {
  947. if (!entity.IsDeleted && entity is SceneObjectGroup && ((SceneObjectGroup)entity).HasGroupChanged)
  948. {
  949. ((SceneObjectGroup)entity).ProcessBackup(SimulationDataService, false);
  950. }
  951. }
  952. m_sceneGraph.Close();
  953. // De-register with region communications (events cleanup)
  954. UnRegisterRegionWithComms();
  955. // call the base class Close method.
  956. base.Close();
  957. }
  958. /// <summary>
  959. /// Start the timer which triggers regular scene updates
  960. /// </summary>
  961. public void StartTimer()
  962. {
  963. //m_log.Debug("[SCENE]: Starting timer");
  964. //m_heartbeatTimer.Enabled = true;
  965. //m_heartbeatTimer.Interval = (int)(m_timespan * 1000);
  966. //m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat);
  967. if (HeartbeatThread != null)
  968. {
  969. HeartbeatThread.Abort();
  970. HeartbeatThread = null;
  971. }
  972. m_lastUpdate = Util.EnvironmentTickCount();
  973. HeartbeatThread = Watchdog.StartThread(Heartbeat, "Heartbeat for region " + RegionInfo.RegionName, ThreadPriority.Normal, false);
  974. }
  975. /// <summary>
  976. /// Sets up references to modules required by the scene
  977. /// </summary>
  978. public void SetModuleInterfaces()
  979. {
  980. m_xmlrpcModule = RequestModuleInterface<IXMLRPC>();
  981. m_worldCommModule = RequestModuleInterface<IWorldComm>();
  982. XferManager = RequestModuleInterface<IXfer>();
  983. m_AvatarFactory = RequestModuleInterface<IAvatarFactory>();
  984. AttachmentsModule = RequestModuleInterface<IAttachmentsModule>();
  985. m_serialiser = RequestModuleInterface<IRegionSerialiserModule>();
  986. m_dialogModule = RequestModuleInterface<IDialogModule>();
  987. m_capsModule = RequestModuleInterface<ICapabilitiesModule>();
  988. m_teleportModule = RequestModuleInterface<IEntityTransferModule>();
  989. }
  990. #endregion
  991. #region Update Methods
  992. /// <summary>
  993. /// Performs per-frame updates regularly
  994. /// </summary>
  995. private void Heartbeat()
  996. {
  997. if (!Monitor.TryEnter(m_heartbeatLock))
  998. {
  999. Watchdog.RemoveThread();
  1000. return;
  1001. }
  1002. try
  1003. {
  1004. while (!shuttingdown)
  1005. Update();
  1006. m_lastUpdate = Util.EnvironmentTickCount();
  1007. m_firstHeartbeat = false;
  1008. }
  1009. catch (ThreadAbortException)
  1010. {
  1011. }
  1012. finally
  1013. {
  1014. Monitor.Pulse(m_heartbeatLock);
  1015. Monitor.Exit(m_heartbeatLock);
  1016. }
  1017. Watchdog.RemoveThread();
  1018. }
  1019. public override void Update()
  1020. {
  1021. TimeSpan SinceLastFrame = DateTime.UtcNow - m_lastupdate;
  1022. float physicsFPS = 0f;
  1023. int maintc = Util.EnvironmentTickCount();
  1024. int tmpFrameMS = maintc;
  1025. tempOnRezMS = eventMS = backupMS = terrainMS = landMS = 0;
  1026. // Increment the frame counter
  1027. ++Frame;
  1028. try
  1029. {
  1030. // Check if any objects have reached their targets
  1031. CheckAtTargets();
  1032. // Update SceneObjectGroups that have scheduled themselves for updates
  1033. // Objects queue their updates onto all scene presences
  1034. if (Frame % m_update_objects == 0)
  1035. m_sceneGraph.UpdateObjectGroups();
  1036. // Run through all ScenePresences looking for updates
  1037. // Presence updates and queued object updates for each presence are sent to clients
  1038. if (Frame % m_update_presences == 0)
  1039. m_sceneGraph.UpdatePresences();
  1040. // Coarse locations relate to positions of green dots on the mini-map (on a SecondLife client)
  1041. if (Frame % m_update_coarse_locations == 0)
  1042. {
  1043. List<Vector3> coarseLocations;
  1044. List<UUID> avatarUUIDs;
  1045. SceneGraph.GetCoarseLocations(out coarseLocations, out avatarUUIDs, 60);
  1046. // Send coarse locations to clients
  1047. ForEachScenePresence(delegate(ScenePresence presence)
  1048. {
  1049. presence.SendCoarseLocations(coarseLocations, avatarUUIDs);
  1050. });
  1051. }
  1052. int tmpPhysicsMS2 = Util.EnvironmentTickCount();
  1053. if ((Frame % m_update_physics == 0) && m_physics_enabled)
  1054. m_sceneGraph.UpdatePreparePhysics();
  1055. physicsMS2 = Util.EnvironmentTickCountSubtract(tmpPhysicsMS2);
  1056. // Apply any pending avatar force input to the avatar's velocity
  1057. if (Frame % m_update_entitymovement == 0)
  1058. m_sceneGraph.UpdateScenePresenceMovement();
  1059. // Perform the main physics update. This will do the actual work of moving objects and avatars according to their
  1060. // velocity
  1061. int tmpPhysicsMS = Util.EnvironmentTickCount();
  1062. if (Frame % m_update_physics == 0)
  1063. {
  1064. if (m_physics_enabled)
  1065. physicsFPS = m_sceneGraph.UpdatePhysics(Math.Max(SinceLastFrame.TotalSeconds, m_timespan));
  1066. if (SynchronizeScene != null)
  1067. SynchronizeScene(this);
  1068. }
  1069. physicsMS = Util.EnvironmentTickCountSubtract(tmpPhysicsMS);
  1070. // Delete temp-on-rez stuff
  1071. if (Frame % 1000 == 0 && !m_cleaningTemps)
  1072. {
  1073. int tmpTempOnRezMS = Util.EnvironmentTickCount();
  1074. m_cleaningTemps = true;
  1075. Util.FireAndForget(delegate { CleanTempObjects(); m_cleaningTemps = false; });
  1076. tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpTempOnRezMS);
  1077. }
  1078. if (RegionStatus != RegionStatus.SlaveScene)
  1079. {
  1080. if (Frame % m_update_events == 0)
  1081. {
  1082. int evMS = Util.EnvironmentTickCount();
  1083. UpdateEvents();
  1084. eventMS = Util.EnvironmentTickCountSubtract(evMS); ;
  1085. }
  1086. if (Frame % m_update_backup == 0)
  1087. {
  1088. int backMS = Util.EnvironmentTickCount();
  1089. UpdateStorageBackup();
  1090. backupMS = Util.EnvironmentTickCountSubtract(backMS);
  1091. }
  1092. if (Frame % m_update_terrain == 0)
  1093. {
  1094. int terMS = Util.EnvironmentTickCount();
  1095. UpdateTerrain();
  1096. terrainMS = Util.EnvironmentTickCountSubtract(terMS);
  1097. }
  1098. //if (Frame % m_update_land == 0)
  1099. //{
  1100. // int ldMS = Util.EnvironmentTickCount();
  1101. // UpdateLand();
  1102. // landMS = Util.EnvironmentTickCountSubtract(ldMS);
  1103. //}
  1104. frameMS = Util.EnvironmentTickCountSubtract(tmpFrameMS);
  1105. otherMS = tempOnRezMS + eventMS + backupMS + terrainMS + landMS;
  1106. lastCompletedFrame = Util.EnvironmentTickCount();
  1107. // if (Frame%m_update_avatars == 0)
  1108. // UpdateInWorldTime();
  1109. StatsReporter.AddPhysicsFPS(physicsFPS);
  1110. StatsReporter.AddTimeDilation(TimeDilation);
  1111. StatsReporter.AddFPS(1);
  1112. StatsReporter.SetRootAgents(m_sceneGraph.GetRootAgentCount());
  1113. StatsReporter.SetChildAgents(m_sceneGraph.GetChildAgentCount());
  1114. StatsReporter.SetObjects(m_sceneGraph.GetTotalObjectsCount());
  1115. StatsReporter.SetActiveObjects(m_sceneGraph.GetActiveObjectsCount());
  1116. StatsReporter.addFrameMS(frameMS);
  1117. StatsReporter.addPhysicsMS(physicsMS + physicsMS2);
  1118. StatsReporter.addOtherMS(otherMS);
  1119. StatsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount());
  1120. StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS());
  1121. }
  1122. if (LoginsDisabled && Frame == 20)
  1123. {
  1124. // In 99.9% of cases it is a bad idea to manually force garbage collection. However,
  1125. // this is a rare case where we know we have just went through a long cycle of heap
  1126. // allocations, and there is no more work to be done until someone logs in
  1127. GC.Collect();
  1128. IConfig startupConfig = m_config.Configs["Startup"];
  1129. if (startupConfig == null || !startupConfig.GetBoolean("StartDisabled", false))
  1130. {
  1131. // This handles a case of a region having no scripts for the RegionReady module
  1132. if (m_sceneGraph.GetActiveScriptsCount() == 0)
  1133. {
  1134. // need to be able to tell these have changed in RegionReady
  1135. LoginLock = false;
  1136. EventManager.TriggerLoginsEnabled(RegionInfo.RegionName);
  1137. }
  1138. m_log.DebugFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName);
  1139. // For RegionReady lockouts
  1140. if( LoginLock == false)
  1141. {
  1142. LoginsDisabled = false;
  1143. }
  1144. m_sceneGridService.InformNeighborsThatRegionisUp(RequestModuleInterface<INeighbourService>(), RegionInfo);
  1145. }
  1146. else
  1147. {
  1148. StartDisabled = true;
  1149. LoginsDisabled = true;
  1150. }
  1151. }
  1152. }
  1153. catch (NotImplementedException)
  1154. {
  1155. throw;
  1156. }
  1157. catch (AccessViolationException e)
  1158. {
  1159. m_log.Error("[REGION]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
  1160. }
  1161. //catch (NullReferenceException e)
  1162. //{
  1163. // m_log.Error("[REGION]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
  1164. //}
  1165. catch (InvalidOperationException e)
  1166. {
  1167. m_log.Error("[REGION]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
  1168. }
  1169. catch (Exception e)
  1170. {
  1171. m_log.Error("[REGION]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
  1172. }
  1173. finally
  1174. {
  1175. m_lastupdate = DateTime.UtcNow;
  1176. }
  1177. maintc = Util.EnvironmentTickCountSubtract(maintc);
  1178. maintc = (int)(m_timespan * 1000) - maintc;
  1179. if (maintc > 0)
  1180. Thread.Sleep(maintc);
  1181. // Tell the watchdog that this thread is still alive
  1182. Watchdog.UpdateThread();
  1183. }
  1184. public void AddGroupTarget(SceneObjectGroup grp)
  1185. {
  1186. lock (m_groupsWithTargets)
  1187. m_groupsWithTargets[grp.UUID] = grp;
  1188. }
  1189. public void RemoveGroupTarget(SceneObjectGroup grp)
  1190. {
  1191. lock (m_groupsWithTargets)
  1192. m_groupsWithTargets.Remove(grp.UUID);
  1193. }
  1194. private void CheckAtTargets()
  1195. {
  1196. Dictionary<UUID, SceneObjectGroup>.ValueCollection objs;
  1197. lock (m_groupsWithTargets)
  1198. objs = m_groupsWithTargets.Values;
  1199. foreach (SceneObjectGroup entry in objs)
  1200. entry.checkAtTargets();
  1201. }
  1202. /// <summary>
  1203. /// Send out simstats data to all clients
  1204. /// </summary>
  1205. /// <param name="stats">Stats on the Simulator's performance</param>
  1206. private void SendSimStatsPackets(SimStats stats)
  1207. {
  1208. ForEachScenePresence(
  1209. delegate(ScenePresence agent)
  1210. {
  1211. if (!agent.IsChildAgent)
  1212. agent.ControllingClient.SendSimStats(stats);
  1213. }
  1214. );
  1215. }
  1216. /// <summary>
  1217. /// Update the terrain if it needs to be updated.
  1218. /// </summary>
  1219. private void UpdateTerrain()
  1220. {
  1221. EventManager.TriggerTerrainTick();
  1222. }
  1223. /// <summary>
  1224. /// Back up queued up changes
  1225. /// </summary>
  1226. private void UpdateStorageBackup()
  1227. {
  1228. if (!m_backingup)
  1229. {
  1230. m_backingup = true;
  1231. Util.FireAndForget(BackupWaitCallback);
  1232. }
  1233. }
  1234. /// <summary>
  1235. /// Sends out the OnFrame event to the modules
  1236. /// </summary>
  1237. private void UpdateEvents()
  1238. {
  1239. m_eventManager.TriggerOnFrame();
  1240. }
  1241. /// <summary>
  1242. /// Wrapper for Backup() that can be called with Util.FireAndForget()
  1243. /// </summary>
  1244. private void BackupWaitCallback(object o)
  1245. {
  1246. Backup(false);
  1247. }
  1248. /// <summary>
  1249. /// Backup the scene. This acts as the main method of the backup thread.
  1250. /// </summary>
  1251. /// <param name="forced">
  1252. /// If true, then any changes that have not yet been persisted are persisted. If false,
  1253. /// then the persistence decision is left to the backup code (in some situations, such as object persistence,
  1254. /// it's much more efficient to backup multiple changes at once rather than every single one).
  1255. /// <returns></returns>
  1256. public void Backup(bool forced)
  1257. {
  1258. lock (m_returns)
  1259. {
  1260. EventManager.TriggerOnBackup(SimulationDataService, forced);
  1261. m_backingup = false;
  1262. foreach (KeyValuePair<UUID, ReturnInfo> ret in m_returns)
  1263. {
  1264. UUID transaction = UUID.Random();
  1265. GridInstantMessage msg = new GridInstantMessage();
  1266. msg.fromAgentID = new Guid(UUID.Zero.ToString()); // From server
  1267. msg.toAgentID = new Guid(ret.Key.ToString());
  1268. msg.imSessionID = new Guid(transaction.ToString());
  1269. msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
  1270. msg.fromAgentName = "Server";
  1271. msg.dialog = (byte)19; // Object msg
  1272. msg.fromGroup = false;
  1273. msg.offline = (byte)1;
  1274. msg.ParentEstateID = RegionInfo.EstateSettings.ParentEstateID;
  1275. msg.Position = Vector3.Zero;
  1276. msg.RegionID = RegionInfo.RegionID.Guid;
  1277. // We must fill in a null-terminated 'empty' string here since bytes[0] will crash viewer 3.
  1278. msg.binaryBucket = Util.StringToBytes256("\0");
  1279. if (ret.Value.count > 1)
  1280. msg.message = string.Format("Your {0} objects were returned from {1} in region {2} due to {3}", ret.Value.count, ret.Value.location.ToString(), RegionInfo.RegionName, ret.Value.reason);
  1281. else
  1282. msg.message = string.Format("Your object {0} was returned from {1} in region {2} due to {3}", ret.Value.objectName, ret.Value.location.ToString(), RegionInfo.RegionName, ret.Value.reason);
  1283. IMessageTransferModule tr = RequestModuleInterface<IMessageTransferModule>();
  1284. if (tr != null)
  1285. tr.SendInstantMessage(msg, delegate(bool success) {});
  1286. }
  1287. m_returns.Clear();
  1288. }
  1289. }
  1290. /// <summary>
  1291. /// Synchronous force backup. For deletes and links/unlinks
  1292. /// </summary>
  1293. /// <param name="group">Object to be backed up</param>
  1294. public void ForceSceneObjectBackup(SceneObjectGroup group)
  1295. {
  1296. if (group != null)
  1297. {
  1298. group.ProcessBackup(SimulationDataService, true);
  1299. }
  1300. }
  1301. /// <summary>
  1302. /// Tell an agent that their object has been returned.
  1303. /// </summary>
  1304. /// <remarks>
  1305. /// The actual return is handled by the caller.
  1306. /// </remarks>
  1307. /// <param name="agentID">Avatar Unique Id</param>
  1308. /// <param name="objectName">Name of object returned</param>
  1309. /// <param name="location">Location of object returned</param>
  1310. /// <param name="reason">Reasion for object return</param>
  1311. public void AddReturn(UUID agentID, string objectName, Vector3 location, string reason)
  1312. {
  1313. lock (m_returns)
  1314. {
  1315. if (m_returns.ContainsKey(agentID))
  1316. {
  1317. ReturnInfo info = m_returns[agentID];
  1318. info.count++;
  1319. m_returns[agentID] = info;
  1320. }
  1321. else
  1322. {
  1323. ReturnInfo info = new ReturnInfo();
  1324. info.count = 1;
  1325. info.objectName = objectName;
  1326. info.location = location;
  1327. info.reason = reason;
  1328. m_returns[agentID] = info;
  1329. }
  1330. }
  1331. }
  1332. #endregion
  1333. #region Load Terrain
  1334. /// <summary>
  1335. /// Store the terrain in the persistant data store
  1336. /// </summary>
  1337. public void SaveTerrain()
  1338. {
  1339. SimulationDataService.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID);
  1340. }
  1341. public void StoreWindlightProfile(RegionLightShareData wl)
  1342. {
  1343. m_regInfo.WindlightSettings = wl;
  1344. SimulationDataService.StoreRegionWindlightSettings(wl);
  1345. m_eventManager.TriggerOnSaveNewWindlightProfile();
  1346. }
  1347. public void LoadWindlightProfile()
  1348. {
  1349. m_regInfo.WindlightSettings = SimulationDataService.LoadRegionWindlightSettings(RegionInfo.RegionID);
  1350. m_eventManager.TriggerOnSaveNewWindlightProfile();
  1351. }
  1352. /// <summary>
  1353. /// Loads the World heightmap
  1354. /// </summary>
  1355. public override void LoadWorldMap()
  1356. {
  1357. try
  1358. {
  1359. double[,] map = SimulationDataService.LoadTerrain(RegionInfo.RegionID);
  1360. if (map == null)
  1361. {
  1362. m_log.Info("[TERRAIN]: No default terrain. Generating a new terrain.");
  1363. Heightmap = new TerrainChannel();
  1364. SimulationDataService.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID);
  1365. }
  1366. else
  1367. {
  1368. Heightmap = new TerrainChannel(map);
  1369. }
  1370. }
  1371. catch (IOException e)
  1372. {
  1373. m_log.Warn("[TERRAIN]: Scene.cs: LoadWorldMap() - Failed with exception " + e.ToString() + " Regenerating");
  1374. // Non standard region size. If there's an old terrain in the database, it might read past the buffer
  1375. #pragma warning disable 0162
  1376. if ((int)Constants.RegionSize != 256)
  1377. {
  1378. Heightmap = new TerrainChannel();
  1379. SimulationDataService.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID);
  1380. }
  1381. }
  1382. catch (Exception e)
  1383. {
  1384. m_log.Warn("[TERRAIN]: Scene.cs: LoadWorldMap() - Failed with exception " + e.ToString());
  1385. }
  1386. }
  1387. /// <summary>
  1388. /// Register this region with a grid service
  1389. /// </summary>
  1390. /// <exception cref="System.Exception">Thrown if registration of the region itself fails.</exception>
  1391. public void RegisterRegionWithGrid()
  1392. {
  1393. RegisterCommsEvents();
  1394. m_sceneGridService.SetScene(this);
  1395. GridRegion region = new GridRegion(RegionInfo);
  1396. string error = GridService.RegisterRegion(RegionInfo.ScopeID, region);
  1397. if (error != String.Empty)
  1398. {
  1399. throw new Exception(error);
  1400. }
  1401. // Generate the maptile asynchronously, because sometimes it can be very slow and we
  1402. // don't want this to delay starting the region.
  1403. if (m_generateMaptiles)
  1404. {
  1405. Util.FireAndForget(delegate {
  1406. RegenerateMaptile(null, null);
  1407. });
  1408. }
  1409. }
  1410. #endregion
  1411. #region Load Land
  1412. /// <summary>
  1413. /// Loads all Parcel data from the datastore for region identified by regionID
  1414. /// </summary>
  1415. /// <param name="regionID">Unique Identifier of the Region to load parcel data for</param>
  1416. public void loadAllLandObjectsFromStorage(UUID regionID)
  1417. {
  1418. m_log.Info("[SCENE]: Loading land objects from storage");
  1419. List<LandData> landData = SimulationDataService.LoadLandObjects(regionID);
  1420. if (LandChannel != null)
  1421. {
  1422. if (landData.Count == 0)
  1423. {
  1424. EventManager.TriggerNoticeNoLandDataFromStorage();
  1425. }
  1426. else
  1427. {
  1428. EventManager.TriggerIncomingLandDataFromStorage(landData);
  1429. }
  1430. }
  1431. else
  1432. {
  1433. m_log.Error("[SCENE]: Land Channel is not defined. Cannot load from storage!");
  1434. }
  1435. }
  1436. #endregion
  1437. #region Primitives Methods
  1438. /// <summary>
  1439. /// Loads the World's objects
  1440. /// </summary>
  1441. /// <param name="regionID"></param>
  1442. public virtual void LoadPrimsFromStorage(UUID regionID)
  1443. {
  1444. LoadingPrims = true;
  1445. m_log.Info("[SCENE]: Loading objects from datastore");
  1446. List<SceneObjectGroup> PrimsFromDB = SimulationDataService.LoadObjects(regionID);
  1447. m_log.Info("[SCENE]: Loaded " + PrimsFromDB.Count + " objects from the datastore");
  1448. foreach (SceneObjectGroup group in PrimsFromDB)
  1449. {
  1450. EventManager.TriggerOnSceneObjectLoaded(group);
  1451. AddRestoredSceneObject(group, true, true);
  1452. SceneObjectPart rootPart = group.GetChildPart(group.UUID);
  1453. rootPart.Flags &= ~PrimFlags.Scripted;
  1454. rootPart.TrimPermissions();
  1455. // Don't do this here - it will get done later on when sculpt data is loaded.
  1456. // group.CheckSculptAndLoad();
  1457. }
  1458. m_log.Info("[SCENE]: Loaded " + PrimsFromDB.Count.ToString() + " SceneObject(s)");
  1459. LoadingPrims = false;
  1460. EventManager.TriggerPrimsLoaded(this);
  1461. }
  1462. /// <summary>
  1463. /// Gets a new rez location based on the raycast and the size of the object that is being rezzed.
  1464. /// </summary>
  1465. /// <param name="RayStart"></param>
  1466. /// <param name="RayEnd"></param>
  1467. /// <param name="RayTargetID"></param>
  1468. /// <param name="rot"></param>
  1469. /// <param name="bypassRayCast"></param>
  1470. /// <param name="RayEndIsIntersection"></param>
  1471. /// <param name="frontFacesOnly"></param>
  1472. /// <param name="scale"></param>
  1473. /// <param name="FaceCenter"></param>
  1474. /// <returns></returns>
  1475. public Vector3 GetNewRezLocation(Vector3 RayStart, Vector3 RayEnd, UUID RayTargetID, Quaternion rot, byte bypassRayCast, byte RayEndIsIntersection, bool frontFacesOnly, Vector3 scale, bool FaceCenter)
  1476. {
  1477. Vector3 pos = Vector3.Zero;
  1478. if (RayEndIsIntersection == (byte)1)
  1479. {
  1480. pos = RayEnd;
  1481. return pos;
  1482. }
  1483. if (RayTargetID != UUID.Zero)
  1484. {
  1485. SceneObjectPart target = GetSceneObjectPart(RayTargetID);
  1486. Vector3 direction = Vector3.Normalize(RayEnd - RayStart);
  1487. Vector3 AXOrigin = new Vector3(RayStart.X, RayStart.Y, RayStart.Z);
  1488. Vector3 AXdirection = new Vector3(direction.X, direction.Y, direction.Z);
  1489. if (target != null)
  1490. {
  1491. pos = target.AbsolutePosition;
  1492. //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());
  1493. // TODO: Raytrace better here
  1494. //EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection));
  1495. Ray NewRay = new Ray(AXOrigin, AXdirection);
  1496. // Ray Trace against target here
  1497. EntityIntersection ei = target.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, FaceCenter);
  1498. // Un-comment out the following line to Get Raytrace results printed to the console.
  1499. // m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString());
  1500. float ScaleOffset = 0.5f;
  1501. // If we hit something
  1502. if (ei.HitTF)
  1503. {
  1504. Vector3 scaleComponent = new Vector3(ei.AAfaceNormal.X, ei.AAfaceNormal.Y, ei.AAfaceNormal.Z);
  1505. if (scaleComponent.X != 0) ScaleOffset = scale.X;
  1506. if (scaleComponent.Y != 0) ScaleOffset = scale.Y;
  1507. if (scaleComponent.Z != 0) ScaleOffset = scale.Z;
  1508. ScaleOffset = Math.Abs(ScaleOffset);
  1509. Vector3 intersectionpoint = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z);
  1510. Vector3 normal = new Vector3(ei.normal.X, ei.normal.Y, ei.normal.Z);
  1511. // Set the position to the intersection point
  1512. Vector3 offset = (normal * (ScaleOffset / 2f));
  1513. pos = (intersectionpoint + offset);
  1514. //Seems to make no sense to do this as this call is used for rezzing from inventory as well, and with inventory items their size is not always 0.5f
  1515. //And in cases when we weren't rezzing from inventory we were re-adding the 0.25 straight after calling this method
  1516. // Un-offset the prim (it gets offset later by the consumer method)
  1517. //pos.Z -= 0.25F;
  1518. }
  1519. return pos;
  1520. }
  1521. else
  1522. {
  1523. // We don't have a target here, so we're going to raytrace all the objects in the scene.
  1524. EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection), true, false);
  1525. // Un-comment the following line to print the raytrace results to the console.
  1526. //m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString());
  1527. if (ei.HitTF)
  1528. {
  1529. pos = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z);
  1530. } else
  1531. {
  1532. // fall back to our stupid functionality
  1533. pos = RayEnd;
  1534. }
  1535. return pos;
  1536. }
  1537. }
  1538. else
  1539. {
  1540. // fall back to our stupid functionality
  1541. pos = RayEnd;
  1542. //increase height so its above the ground.
  1543. //should be getting the normal of the ground at the rez point and using that?
  1544. pos.Z += scale.Z / 2f;
  1545. return pos;
  1546. }
  1547. }
  1548. /// <summary>
  1549. /// Create a New SceneObjectGroup/Part by raycasting
  1550. /// </summary>
  1551. /// <param name="ownerID"></param>
  1552. /// <param name="groupID"></param>
  1553. /// <param name="RayEnd"></param>
  1554. /// <param name="rot"></param>
  1555. /// <param name="shape"></param>
  1556. /// <param name="bypassRaycast"></param>
  1557. /// <param name="RayStart"></param>
  1558. /// <param name="RayTargetID"></param>
  1559. /// <param name="RayEndIsIntersection"></param>
  1560. public virtual void AddNewPrim(UUID ownerID, UUID groupID, Vector3 RayEnd, Quaternion rot, PrimitiveBaseShape shape,
  1561. byte bypassRaycast, Vector3 RayStart, UUID RayTargetID,
  1562. byte RayEndIsIntersection)
  1563. {
  1564. Vector3 pos = GetNewRezLocation(RayStart, RayEnd, RayTargetID, rot, bypassRaycast, RayEndIsIntersection, true, new Vector3(0.5f, 0.5f, 0.5f), false);
  1565. if (Permissions.CanRezObject(1, ownerID, pos))
  1566. {
  1567. // rez ON the ground, not IN the ground
  1568. // pos.Z += 0.25F; The rez point should now be correct so that its not in the ground
  1569. AddNewPrim(ownerID, groupID, pos, rot, shape);
  1570. }
  1571. }
  1572. public virtual SceneObjectGroup AddNewPrim(
  1573. UUID ownerID, UUID groupID, Vector3 pos, Quaternion rot, PrimitiveBaseShape shape)
  1574. {
  1575. //m_log.DebugFormat(
  1576. // "[SCENE]: Scene.AddNewPrim() pcode {0} called for {1} in {2}", shape.PCode, ownerID, RegionInfo.RegionName);
  1577. SceneObjectGroup sceneObject = null;
  1578. // If an entity creator has been registered for this prim type then use that
  1579. if (m_entityCreators.ContainsKey((PCode)shape.PCode))
  1580. {
  1581. sceneObject = m_entityCreators[(PCode)shape.PCode].CreateEntity(ownerID, groupID, pos, rot, shape);
  1582. }
  1583. else
  1584. {
  1585. // Otherwise, use this default creation code;
  1586. sceneObject = new SceneObjectGroup(ownerID, pos, rot, shape);
  1587. AddNewSceneObject(sceneObject, true);
  1588. sceneObject.SetGroup(groupID, null);
  1589. }
  1590. IUserManagement uman = RequestModuleInterface<IUserManagement>();
  1591. if (uman != null)
  1592. sceneObject.RootPart.CreatorIdentification = uman.GetUserUUI(ownerID);
  1593. sceneObject.ScheduleGroupForFullUpdate();
  1594. return sceneObject;
  1595. }
  1596. /// <summary>
  1597. /// Add an object into the scene that has come from storage
  1598. /// </summary>
  1599. ///
  1600. /// <param name="sceneObject"></param>
  1601. /// <param name="attachToBackup">
  1602. /// If true, changes to the object will be reflected in its persisted data
  1603. /// If false, the persisted data will not be changed even if the object in the scene is changed
  1604. /// </param>
  1605. /// <param name="alreadyPersisted">
  1606. /// If true, we won't persist this object until it changes
  1607. /// If false, we'll persist this object immediately
  1608. /// </param>
  1609. /// <param name="sendClientUpdates">
  1610. /// If true, we send updates to the client to tell it about this object
  1611. /// If false, we leave it up to the caller to do this
  1612. /// </param>
  1613. /// <returns>
  1614. /// true if the object was added, false if an object with the same uuid was already in the scene
  1615. /// </returns>
  1616. public bool AddRestoredSceneObject(
  1617. SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates)
  1618. {
  1619. return m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates);
  1620. }
  1621. /// <summary>
  1622. /// Add an object into the scene that has come from storage
  1623. /// </summary>
  1624. ///
  1625. /// <param name="sceneObject"></param>
  1626. /// <param name="attachToBackup">
  1627. /// If true, changes to the object will be reflected in its persisted data
  1628. /// If false, the persisted data will not be changed even if the object in the scene is changed
  1629. /// </param>
  1630. /// <param name="alreadyPersisted">
  1631. /// If true, we won't persist this object until it changes
  1632. /// If false, we'll persist this object immediately
  1633. /// </param>
  1634. /// <returns>
  1635. /// true if the object was added, false if an object with the same uuid was already in the scene
  1636. /// </returns>
  1637. public bool AddRestoredSceneObject(
  1638. SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted)
  1639. {
  1640. return AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, true);
  1641. }
  1642. /// <summary>
  1643. /// Add a newly created object to the scene. Updates are also sent to viewers.
  1644. /// </summary>
  1645. /// <param name="sceneObject"></param>
  1646. /// <param name="attachToBackup">
  1647. /// If true, the object is made persistent into the scene.
  1648. /// If false, the object will not persist over server restarts
  1649. /// </param>
  1650. public bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup)
  1651. {
  1652. return AddNewSceneObject(sceneObject, attachToBackup, true);
  1653. }
  1654. /// <summary>
  1655. /// Add a newly created object to the scene
  1656. /// </summary>
  1657. /// <param name="sceneObject"></param>
  1658. /// <param name="attachToBackup">
  1659. /// If true, the object is made persistent into the scene.
  1660. /// If false, the object will not persist over server restarts
  1661. /// </param>
  1662. /// <param name="sendClientUpdates">
  1663. /// If true, updates for the new scene object are sent to all viewers in range.
  1664. /// If false, it is left to the caller to schedule the update
  1665. /// </param>
  1666. public bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates)
  1667. {
  1668. if (m_sceneGraph.AddNewSceneObject(sceneObject, attachToBackup, sendClientUpdates))
  1669. {
  1670. EventManager.TriggerObjectAddedToScene(sceneObject);
  1671. return true;
  1672. }
  1673. return false;
  1674. }
  1675. /// <summary>
  1676. /// Add a newly created object to the scene.
  1677. /// </summary>
  1678. /// <remarks>
  1679. /// This method does not send updates to the client - callers need to handle this themselves.
  1680. /// </remarks>
  1681. /// <param name="sceneObject"></param>
  1682. /// <param name="attachToBackup"></param>
  1683. /// <param name="pos">Position of the object. If null then the position stored in the object is used.</param>
  1684. /// <param name="rot">Rotation of the object. If null then the rotation stored in the object is used.</param>
  1685. /// <param name="vel">Velocity of the object. This parameter only has an effect if the object is physical</param>
  1686. /// <returns></returns>
  1687. public bool AddNewSceneObject(
  1688. SceneObjectGroup sceneObject, bool attachToBackup, Vector3? pos, Quaternion? rot, Vector3 vel)
  1689. {
  1690. if (m_sceneGraph.AddNewSceneObject(sceneObject, attachToBackup, pos, rot, vel))
  1691. {
  1692. EventManager.TriggerObjectAddedToScene(sceneObject);
  1693. return true;
  1694. }
  1695. return false;
  1696. }
  1697. /// <summary>
  1698. /// Delete every object from the scene. This does not include attachments worn by avatars.
  1699. /// </summary>
  1700. public void DeleteAllSceneObjects()
  1701. {
  1702. lock (Entities)
  1703. {
  1704. EntityBase[] entities = Entities.GetEntities();
  1705. foreach (EntityBase e in entities)
  1706. {
  1707. if (e is SceneObjectGroup)
  1708. {
  1709. SceneObjectGroup sog = (SceneObjectGroup)e;
  1710. if (!sog.IsAttachment)
  1711. DeleteSceneObject((SceneObjectGroup)e, false);
  1712. }
  1713. }
  1714. }
  1715. }
  1716. /// <summary>
  1717. /// Synchronously delete the given object from the scene.
  1718. /// </summary>
  1719. /// <param name="group">Object Id</param>
  1720. /// <param name="silent">Suppress broadcasting changes to other clients.</param>
  1721. public void DeleteSceneObject(SceneObjectGroup group, bool silent)
  1722. {
  1723. // m_log.DebugFormat("[SCENE]: Deleting scene object {0} {1}", group.Name, group.UUID);
  1724. //SceneObjectPart rootPart = group.GetChildPart(group.UUID);
  1725. // Serialise calls to RemoveScriptInstances to avoid
  1726. // deadlocking on m_parts inside SceneObjectGroup
  1727. lock (m_deleting_scene_object)
  1728. {
  1729. group.RemoveScriptInstances(true);
  1730. }
  1731. SceneObjectPart[] partList = group.Parts;
  1732. foreach (SceneObjectPart part in partList)
  1733. {
  1734. if (part.IsJoint() && ((part.Flags & PrimFlags.Physics) != 0))
  1735. {
  1736. PhysicsScene.RequestJointDeletion(part.Name); // FIXME: what if the name changed?
  1737. }
  1738. else if (part.PhysActor != null)
  1739. {
  1740. PhysicsScene.RemovePrim(part.PhysActor);
  1741. part.PhysActor = null;
  1742. }
  1743. }
  1744. // if (rootPart.PhysActor != null)
  1745. // {
  1746. // PhysicsScene.RemovePrim(rootPart.PhysActor);
  1747. // rootPart.PhysActor = null;
  1748. // }
  1749. if (UnlinkSceneObject(group, false))
  1750. {
  1751. EventManager.TriggerObjectBeingRemovedFromScene(group);
  1752. EventManager.TriggerParcelPrimCountTainted();
  1753. }
  1754. group.DeleteGroupFromScene(silent);
  1755. // m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID);
  1756. }
  1757. /// <summary>
  1758. /// Unlink the given object from the scene. Unlike delete, this just removes the record of the object - the
  1759. /// object itself is not destroyed.
  1760. /// </summary>
  1761. /// <param name="so">The scene object.</param>
  1762. /// <param name="softDelete">If true, only deletes from scene, but keeps the object in the database.</param>
  1763. /// <returns>true if the object was in the scene, false if it was not</returns>
  1764. public bool UnlinkSceneObject(SceneObjectGroup so, bool softDelete)
  1765. {
  1766. if (m_sceneGraph.DeleteSceneObject(so.UUID, softDelete))
  1767. {
  1768. if (!softDelete)
  1769. {
  1770. // Force a database update so that the scene object group ID is accurate. It's possible that the
  1771. // group has recently been delinked from another group but that this change has not been persisted
  1772. // to the DB.
  1773. // This is an expensive thing to do so only do it if absolutely necessary.
  1774. if (so.HasGroupChangedDueToDelink)
  1775. ForceSceneObjectBackup(so);
  1776. so.DetachFromBackup();
  1777. SimulationDataService.RemoveObject(so.UUID, m_regInfo.RegionID);
  1778. }
  1779. // We need to keep track of this state in case this group is still queued for further backup.
  1780. so.IsDeleted = true;
  1781. return true;
  1782. }
  1783. return false;
  1784. }
  1785. /// <summary>
  1786. /// Move the given scene object into a new region depending on which region its absolute position has moved
  1787. /// into.
  1788. ///
  1789. /// </summary>
  1790. /// <param name="attemptedPosition">the attempted out of region position of the scene object</param>
  1791. /// <param name="grp">the scene object that we're crossing</param>
  1792. public void CrossPrimGroupIntoNewRegion(Vector3 attemptedPosition, SceneObjectGroup grp, bool silent)
  1793. {
  1794. if (grp == null)
  1795. return;
  1796. if (grp.IsDeleted)
  1797. return;
  1798. if (grp.RootPart.DIE_AT_EDGE)
  1799. {
  1800. // We remove the object here
  1801. try
  1802. {
  1803. DeleteSceneObject(grp, false);
  1804. }
  1805. catch (Exception)
  1806. {
  1807. m_log.Warn("[SCENE]: exception when trying to remove the prim that crossed the border.");
  1808. }
  1809. return;
  1810. }
  1811. if (grp.RootPart.RETURN_AT_EDGE)
  1812. {
  1813. // We remove the object here
  1814. try
  1815. {
  1816. List<SceneObjectGroup> objects = new List<SceneObjectGroup>();
  1817. objects.Add(grp);
  1818. SceneObjectGroup[] objectsArray = objects.ToArray();
  1819. returnObjects(objectsArray, UUID.Zero);
  1820. }
  1821. catch (Exception)
  1822. {
  1823. m_log.Warn("[SCENE]: exception when trying to return the prim that crossed the border.");
  1824. }
  1825. return;
  1826. }
  1827. if (m_teleportModule != null)
  1828. m_teleportModule.Cross(grp, attemptedPosition, silent);
  1829. }
  1830. public Border GetCrossedBorder(Vector3 position, Cardinals gridline)
  1831. {
  1832. if (BordersLocked)
  1833. {
  1834. switch (gridline)
  1835. {
  1836. case Cardinals.N:
  1837. lock (NorthBorders)
  1838. {
  1839. foreach (Border b in NorthBorders)
  1840. {
  1841. if (b.TestCross(position))
  1842. return b;
  1843. }
  1844. }
  1845. break;
  1846. case Cardinals.S:
  1847. lock (SouthBorders)
  1848. {
  1849. foreach (Border b in SouthBorders)
  1850. {
  1851. if (b.TestCross(position))
  1852. return b;
  1853. }
  1854. }
  1855. break;
  1856. case Cardinals.E:
  1857. lock (EastBorders)
  1858. {
  1859. foreach (Border b in EastBorders)
  1860. {
  1861. if (b.TestCross(position))
  1862. return b;
  1863. }
  1864. }
  1865. break;
  1866. case Cardinals.W:
  1867. lock (WestBorders)
  1868. {
  1869. foreach (Border b in WestBorders)
  1870. {
  1871. if (b.TestCross(position))
  1872. return b;
  1873. }
  1874. }
  1875. break;
  1876. }
  1877. }
  1878. else
  1879. {
  1880. switch (gridline)
  1881. {
  1882. case Cardinals.N:
  1883. foreach (Border b in NorthBorders)
  1884. {
  1885. if (b.TestCross(position))
  1886. return b;
  1887. }
  1888. break;
  1889. case Cardinals.S:
  1890. foreach (Border b in SouthBorders)
  1891. {
  1892. if (b.TestCross(position))
  1893. return b;
  1894. }
  1895. break;
  1896. case Cardinals.E:
  1897. foreach (Border b in EastBorders)
  1898. {
  1899. if (b.TestCross(position))
  1900. return b;
  1901. }
  1902. break;
  1903. case Cardinals.W:
  1904. foreach (Border b in WestBorders)
  1905. {
  1906. if (b.TestCross(position))
  1907. return b;
  1908. }
  1909. break;
  1910. }
  1911. }
  1912. return null;
  1913. }
  1914. public bool TestBorderCross(Vector3 position, Cardinals border)
  1915. {
  1916. if (BordersLocked)
  1917. {
  1918. switch (border)
  1919. {
  1920. case Cardinals.N:
  1921. lock (NorthBorders)
  1922. {
  1923. foreach (Border b in NorthBorders)
  1924. {
  1925. if (b.TestCross(position))
  1926. return true;
  1927. }
  1928. }
  1929. break;
  1930. case Cardinals.E:
  1931. lock (EastBorders)
  1932. {
  1933. foreach (Border b in EastBorders)
  1934. {
  1935. if (b.TestCross(position))
  1936. return true;
  1937. }
  1938. }
  1939. break;
  1940. case Cardinals.S:
  1941. lock (SouthBorders)
  1942. {
  1943. foreach (Border b in SouthBorders)
  1944. {
  1945. if (b.TestCross(position))
  1946. return true;
  1947. }
  1948. }
  1949. break;
  1950. case Cardinals.W:
  1951. lock (WestBorders)
  1952. {
  1953. foreach (Border b in WestBorders)
  1954. {
  1955. if (b.TestCross(position))
  1956. return true;
  1957. }
  1958. }
  1959. break;
  1960. }
  1961. }
  1962. else
  1963. {
  1964. switch (border)
  1965. {
  1966. case Cardinals.N:
  1967. foreach (Border b in NorthBorders)
  1968. {
  1969. if (b.TestCross(position))
  1970. return true;
  1971. }
  1972. break;
  1973. case Cardinals.E:
  1974. foreach (Border b in EastBorders)
  1975. {
  1976. if (b.TestCross(position))
  1977. return true;
  1978. }
  1979. break;
  1980. case Cardinals.S:
  1981. foreach (Border b in SouthBorders)
  1982. {
  1983. if (b.TestCross(position))
  1984. return true;
  1985. }
  1986. break;
  1987. case Cardinals.W:
  1988. foreach (Border b in WestBorders)
  1989. {
  1990. if (b.TestCross(position))
  1991. return true;
  1992. }
  1993. break;
  1994. }
  1995. }
  1996. return false;
  1997. }
  1998. /// <summary>
  1999. /// Called when objects or attachments cross the border, or teleport, between regions.
  2000. /// </summary>
  2001. /// <param name="sog"></param>
  2002. /// <returns></returns>
  2003. public bool IncomingCreateObject(ISceneObject sog)
  2004. {
  2005. //m_log.DebugFormat(" >>> IncomingCreateObject(sog) <<< {0} deleted? {1} isAttach? {2}", ((SceneObjectGroup)sog).AbsolutePosition,
  2006. // ((SceneObjectGroup)sog).IsDeleted, ((SceneObjectGroup)sog).RootPart.IsAttachment);
  2007. SceneObjectGroup newObject;
  2008. try
  2009. {
  2010. newObject = (SceneObjectGroup)sog;
  2011. }
  2012. catch (Exception e)
  2013. {
  2014. m_log.WarnFormat("[SCENE]: Problem casting object: " + e.ToString());
  2015. return false;
  2016. }
  2017. if (!AddSceneObject(newObject))
  2018. {
  2019. m_log.DebugFormat("[SCENE]: Problem adding scene object {0} in {1} ", sog.UUID, RegionInfo.RegionName);
  2020. return false;
  2021. }
  2022. // For attachments, we need to wait until the agent is root
  2023. // before we restart the scripts, or else some functions won't work.
  2024. if (!newObject.IsAttachment)
  2025. {
  2026. newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject));
  2027. newObject.ResumeScripts();
  2028. }
  2029. else
  2030. {
  2031. ScenePresence sp;
  2032. if (TryGetScenePresence(newObject.OwnerID, out sp))
  2033. {
  2034. // If the scene presence is here and already a root
  2035. // agent, we came from a ;egacy region. Start the scripts
  2036. // here as they used to start.
  2037. // TODO: Remove in 0.7.3
  2038. if (!sp.IsChildAgent)
  2039. {
  2040. newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject));
  2041. newObject.ResumeScripts();
  2042. }
  2043. }
  2044. }
  2045. // Do this as late as possible so that listeners have full access to the incoming object
  2046. EventManager.TriggerOnIncomingSceneObject(newObject);
  2047. return true;
  2048. }
  2049. /// <summary>
  2050. /// Attachment rezzing
  2051. /// </summary>
  2052. /// <param name="userID">Agent Unique ID</param>
  2053. /// <param name="itemID">Object ID</param>
  2054. /// <returns>False</returns>
  2055. public virtual bool IncomingCreateObject(UUID userID, UUID itemID)
  2056. {
  2057. m_log.DebugFormat(" >>> IncomingCreateObject(userID, itemID) <<< {0} {1}", userID, itemID);
  2058. // Commented out since this is as yet unused and is arguably not the appropriate place to do this, as
  2059. // attachments are being rezzed elsewhere in AddNewClient()
  2060. // ScenePresence sp = GetScenePresence(userID);
  2061. // if (sp != null && AttachmentsModule != null)
  2062. // {
  2063. // uint attPt = (uint)sp.Appearance.GetAttachpoint(itemID);
  2064. // AttachmentsModule.RezSingleAttachmentFromInventory(sp.ControllingClient, itemID, attPt);
  2065. // }
  2066. return false;
  2067. }
  2068. /// <summary>
  2069. /// Adds a Scene Object group to the Scene.
  2070. /// Verifies that the creator of the object is not banned from the simulator.
  2071. /// Checks if the item is an Attachment
  2072. /// </summary>
  2073. /// <param name="sceneObject"></param>
  2074. /// <returns>True if the SceneObjectGroup was added, False if it was not</returns>
  2075. public bool AddSceneObject(SceneObjectGroup sceneObject)
  2076. {
  2077. // If the user is banned, we won't let any of their objects
  2078. // enter. Period.
  2079. //
  2080. if (m_regInfo.EstateSettings.IsBanned(sceneObject.OwnerID))
  2081. {
  2082. m_log.Info("[INTERREGION]: Denied prim crossing for " +
  2083. "banned avatar");
  2084. return false;
  2085. }
  2086. sceneObject.SetScene(this);
  2087. // Force allocation of new LocalId
  2088. //
  2089. SceneObjectPart[] parts = sceneObject.Parts;
  2090. for (int i = 0; i < parts.Length; i++)
  2091. parts[i].LocalId = 0;
  2092. if (sceneObject.IsAttachmentCheckFull()) // Attachment
  2093. {
  2094. sceneObject.RootPart.AddFlag(PrimFlags.TemporaryOnRez);
  2095. sceneObject.RootPart.AddFlag(PrimFlags.Phantom);
  2096. // Don't sent a full update here because this will cause full updates to be sent twice for
  2097. // attachments on region crossings, resulting in viewer glitches.
  2098. AddRestoredSceneObject(sceneObject, false, false, false);
  2099. // Handle attachment special case
  2100. SceneObjectPart RootPrim = sceneObject.RootPart;
  2101. // Fix up attachment Parent Local ID
  2102. ScenePresence sp = GetScenePresence(sceneObject.OwnerID);
  2103. if (sp != null)
  2104. {
  2105. SceneObjectGroup grp = sceneObject;
  2106. m_log.DebugFormat(
  2107. "[ATTACHMENT]: Received attachment {0}, inworld asset id {1}", grp.GetFromItemID(), grp.UUID);
  2108. m_log.DebugFormat(
  2109. "[ATTACHMENT]: Attach to avatar {0} at position {1}", sp.UUID, grp.AbsolutePosition);
  2110. RootPrim.RemFlag(PrimFlags.TemporaryOnRez);
  2111. if (AttachmentsModule != null)
  2112. AttachmentsModule.AttachObject(sp.ControllingClient, grp, 0, false);
  2113. }
  2114. else
  2115. {
  2116. RootPrim.RemFlag(PrimFlags.TemporaryOnRez);
  2117. RootPrim.AddFlag(PrimFlags.TemporaryOnRez);
  2118. }
  2119. }
  2120. else
  2121. {
  2122. AddRestoredSceneObject(sceneObject, true, false);
  2123. if (!Permissions.CanObjectEntry(sceneObject.UUID,
  2124. true, sceneObject.AbsolutePosition))
  2125. {
  2126. // Deny non attachments based on parcel settings
  2127. //
  2128. m_log.Info("[INTERREGION]: Denied prim crossing " +
  2129. "because of parcel settings");
  2130. DeleteSceneObject(sceneObject, false);
  2131. return false;
  2132. }
  2133. }
  2134. return true;
  2135. }
  2136. private int GetStateSource(SceneObjectGroup sog)
  2137. {
  2138. ScenePresence sp = GetScenePresence(sog.OwnerID);
  2139. if (sp != null)
  2140. return sp.GetStateSource();
  2141. return 2; // StateSource.PrimCrossing
  2142. }
  2143. #endregion
  2144. #region Add/Remove Avatar Methods
  2145. /// <summary>
  2146. /// Add a new client and create a child agent for it.
  2147. /// </summary>
  2148. /// <param name="client"></param>
  2149. /// <param name="type">The type of agent to add.</param>
  2150. public override void AddNewClient(IClientAPI client, PresenceType type)
  2151. {
  2152. AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode);
  2153. bool vialogin = false;
  2154. if (aCircuit == null) // no good, didn't pass NewUserConnection successfully
  2155. return;
  2156. vialogin = (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0 ||
  2157. (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0;
  2158. CheckHeartbeat();
  2159. if (GetScenePresence(client.AgentId) == null) // ensure there is no SP here
  2160. {
  2161. m_log.Debug("[SCENE]: Adding new agent " + client.Name + " to scene " + RegionInfo.RegionName);
  2162. m_clientManager.Add(client);
  2163. SubscribeToClientEvents(client);
  2164. ScenePresence sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type);
  2165. m_eventManager.TriggerOnNewPresence(sp);
  2166. sp.TeleportFlags = (TeleportFlags)aCircuit.teleportFlags;
  2167. // HERE!!! Do the initial attachments right here
  2168. // first agent upon login is a root agent by design.
  2169. // All other AddNewClient calls find aCircuit.child to be true
  2170. if (aCircuit.child == false)
  2171. {
  2172. sp.IsChildAgent = false;
  2173. Util.FireAndForget(delegate(object o) { AttachmentsModule.RezAttachments(sp); });
  2174. }
  2175. }
  2176. ScenePresence createdSp = GetScenePresence(client.AgentId);
  2177. if (createdSp != null)
  2178. {
  2179. m_LastLogin = Util.EnvironmentTickCount();
  2180. // Cache the user's name
  2181. CacheUserName(createdSp, aCircuit);
  2182. EventManager.TriggerOnNewClient(client);
  2183. if (vialogin)
  2184. EventManager.TriggerOnClientLogin(client);
  2185. }
  2186. }
  2187. /// <summary>
  2188. /// Cache the user name for later use.
  2189. /// </summary>
  2190. /// <param name="sp"></param>
  2191. /// <param name="aCircuit"></param>
  2192. private void CacheUserName(ScenePresence sp, AgentCircuitData aCircuit)
  2193. {
  2194. IUserManagement uMan = RequestModuleInterface<IUserManagement>();
  2195. if (uMan != null)
  2196. {
  2197. string first = aCircuit.firstname, last = aCircuit.lastname;
  2198. if (sp.PresenceType == PresenceType.Npc)
  2199. {
  2200. uMan.AddUser(aCircuit.AgentID, first, last);
  2201. }
  2202. else
  2203. {
  2204. string homeURL = string.Empty;
  2205. if (aCircuit.ServiceURLs.ContainsKey("HomeURI"))
  2206. homeURL = aCircuit.ServiceURLs["HomeURI"].ToString();
  2207. if (aCircuit.lastname.StartsWith("@"))
  2208. {
  2209. string[] parts = aCircuit.firstname.Split('.');
  2210. if (parts.Length >= 2)
  2211. {
  2212. first = parts[0];
  2213. last = parts[1];
  2214. }
  2215. }
  2216. uMan.AddUser(aCircuit.AgentID, first, last, homeURL);
  2217. }
  2218. }
  2219. }
  2220. private bool VerifyClient(AgentCircuitData aCircuit, System.Net.IPEndPoint ep, out bool vialogin)
  2221. {
  2222. vialogin = false;
  2223. // Do the verification here
  2224. if ((aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0)
  2225. {
  2226. m_log.DebugFormat("[SCENE]: Incoming client {0} {1} in region {2} via HG login", aCircuit.firstname, aCircuit.lastname, RegionInfo.RegionName);
  2227. vialogin = true;
  2228. IUserAgentVerificationModule userVerification = RequestModuleInterface<IUserAgentVerificationModule>();
  2229. if (userVerification != null && ep != null)
  2230. {
  2231. if (!userVerification.VerifyClient(aCircuit, ep.Address.ToString()))
  2232. {
  2233. // uh-oh, this is fishy
  2234. m_log.DebugFormat("[SCENE]: User Client Verification for {0} {1} in {2} returned false", aCircuit.firstname, aCircuit.lastname, RegionInfo.RegionName);
  2235. return false;
  2236. }
  2237. else
  2238. m_log.DebugFormat("[SCENE]: User Client Verification for {0} {1} in {2} returned true", aCircuit.firstname, aCircuit.lastname, RegionInfo.RegionName);
  2239. }
  2240. }
  2241. else if ((aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0)
  2242. {
  2243. m_log.DebugFormat("[SCENE]: Incoming client {0} {1} in region {2} via regular login. Client IP verification not performed.",
  2244. aCircuit.firstname, aCircuit.lastname, RegionInfo.RegionName);
  2245. vialogin = true;
  2246. }
  2247. return true;
  2248. }
  2249. // Called by Caps, on the first HTTP contact from the client
  2250. public override bool CheckClient(UUID agentID, System.Net.IPEndPoint ep)
  2251. {
  2252. AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(agentID);
  2253. if (aCircuit != null)
  2254. {
  2255. bool vialogin = false;
  2256. if (!VerifyClient(aCircuit, ep, out vialogin))
  2257. {
  2258. // if it doesn't pass, we remove the agentcircuitdata altogether
  2259. // and the scene presence and the client, if they exist
  2260. try
  2261. {
  2262. // We need to wait for the client to make UDP contact first.
  2263. // It's the UDP contact that creates the scene presence
  2264. ScenePresence sp = WaitGetScenePresence(agentID);
  2265. if (sp != null)
  2266. {
  2267. PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
  2268. sp.ControllingClient.Close();
  2269. }
  2270. else
  2271. {
  2272. m_log.WarnFormat("[SCENE]: Could not find scene presence for {0}", agentID);
  2273. }
  2274. // BANG! SLASH!
  2275. m_authenticateHandler.RemoveCircuit(agentID);
  2276. return false;
  2277. }
  2278. catch (Exception e)
  2279. {
  2280. m_log.DebugFormat("[SCENE]: Exception while closing aborted client: {0}", e.StackTrace);
  2281. }
  2282. }
  2283. else
  2284. return true;
  2285. }
  2286. return false;
  2287. }
  2288. /// <summary>
  2289. /// Register for events from the client
  2290. /// </summary>
  2291. /// <param name="client">The IClientAPI of the connected client</param>
  2292. public virtual void SubscribeToClientEvents(IClientAPI client)
  2293. {
  2294. SubscribeToClientTerrainEvents(client);
  2295. SubscribeToClientPrimEvents(client);
  2296. SubscribeToClientPrimRezEvents(client);
  2297. SubscribeToClientInventoryEvents(client);
  2298. SubscribeToClientTeleportEvents(client);
  2299. SubscribeToClientScriptEvents(client);
  2300. SubscribeToClientParcelEvents(client);
  2301. SubscribeToClientGridEvents(client);
  2302. SubscribeToClientNetworkEvents(client);
  2303. }
  2304. public virtual void SubscribeToClientTerrainEvents(IClientAPI client)
  2305. {
  2306. client.OnRegionHandShakeReply += SendLayerData;
  2307. }
  2308. public virtual void SubscribeToClientPrimEvents(IClientAPI client)
  2309. {
  2310. client.OnUpdatePrimGroupPosition += m_sceneGraph.UpdatePrimGroupPosition;
  2311. client.OnUpdatePrimSinglePosition += m_sceneGraph.UpdatePrimSinglePosition;
  2312. client.OnUpdatePrimGroupRotation += m_sceneGraph.UpdatePrimGroupRotation;
  2313. client.OnUpdatePrimGroupMouseRotation += m_sceneGraph.UpdatePrimGroupRotation;
  2314. client.OnUpdatePrimSingleRotation += m_sceneGraph.UpdatePrimSingleRotation;
  2315. client.OnUpdatePrimSingleRotationPosition += m_sceneGraph.UpdatePrimSingleRotationPosition;
  2316. client.OnUpdatePrimScale += m_sceneGraph.UpdatePrimScale;
  2317. client.OnUpdatePrimGroupScale += m_sceneGraph.UpdatePrimGroupScale;
  2318. client.OnUpdateExtraParams += m_sceneGraph.UpdateExtraParam;
  2319. client.OnUpdatePrimShape += m_sceneGraph.UpdatePrimShape;
  2320. client.OnUpdatePrimTexture += m_sceneGraph.UpdatePrimTexture;
  2321. client.OnObjectRequest += RequestPrim;
  2322. client.OnObjectSelect += SelectPrim;
  2323. client.OnObjectDeselect += DeselectPrim;
  2324. client.OnGrabUpdate += m_sceneGraph.MoveObject;
  2325. client.OnSpinStart += m_sceneGraph.SpinStart;
  2326. client.OnSpinUpdate += m_sceneGraph.SpinObject;
  2327. client.OnDeRezObject += DeRezObjects;
  2328. client.OnObjectName += m_sceneGraph.PrimName;
  2329. client.OnObjectClickAction += m_sceneGraph.PrimClickAction;
  2330. client.OnObjectMaterial += m_sceneGraph.PrimMaterial;
  2331. client.OnLinkObjects += LinkObjects;
  2332. client.OnDelinkObjects += DelinkObjects;
  2333. client.OnObjectDuplicate += m_sceneGraph.DuplicateObject;
  2334. client.OnObjectDuplicateOnRay += doObjectDuplicateOnRay;
  2335. client.OnUpdatePrimFlags += m_sceneGraph.UpdatePrimFlags;
  2336. client.OnRequestObjectPropertiesFamily += m_sceneGraph.RequestObjectPropertiesFamily;
  2337. client.OnObjectPermissions += HandleObjectPermissionsUpdate;
  2338. client.OnGrabObject += ProcessObjectGrab;
  2339. client.OnGrabUpdate += ProcessObjectGrabUpdate;
  2340. client.OnDeGrabObject += ProcessObjectDeGrab;
  2341. client.OnUndo += m_sceneGraph.HandleUndo;
  2342. client.OnRedo += m_sceneGraph.HandleRedo;
  2343. client.OnObjectDescription += m_sceneGraph.PrimDescription;
  2344. client.OnObjectIncludeInSearch += m_sceneGraph.MakeObjectSearchable;
  2345. client.OnObjectOwner += ObjectOwner;
  2346. }
  2347. public virtual void SubscribeToClientPrimRezEvents(IClientAPI client)
  2348. {
  2349. client.OnAddPrim += AddNewPrim;
  2350. client.OnRezObject += RezObject;
  2351. }
  2352. public virtual void SubscribeToClientInventoryEvents(IClientAPI client)
  2353. {
  2354. client.OnLinkInventoryItem += HandleLinkInventoryItem;
  2355. client.OnCreateNewInventoryFolder += HandleCreateInventoryFolder;
  2356. client.OnUpdateInventoryFolder += HandleUpdateInventoryFolder;
  2357. client.OnMoveInventoryFolder += HandleMoveInventoryFolder; // 2; //!!
  2358. client.OnFetchInventoryDescendents += HandleFetchInventoryDescendents;
  2359. client.OnPurgeInventoryDescendents += HandlePurgeInventoryDescendents; // 2; //!!
  2360. client.OnFetchInventory += m_asyncInventorySender.HandleFetchInventory;
  2361. client.OnUpdateInventoryItem += UpdateInventoryItemAsset;
  2362. client.OnCopyInventoryItem += CopyInventoryItem;
  2363. client.OnMoveInventoryItem += MoveInventoryItem;
  2364. client.OnRemoveInventoryItem += RemoveInventoryItem;
  2365. client.OnRemoveInventoryFolder += RemoveInventoryFolder;
  2366. client.OnRezScript += RezScript;
  2367. client.OnRequestTaskInventory += RequestTaskInventory;
  2368. client.OnRemoveTaskItem += RemoveTaskInventory;
  2369. client.OnUpdateTaskInventory += UpdateTaskInventory;
  2370. client.OnMoveTaskItem += ClientMoveTaskInventoryItem;
  2371. }
  2372. public virtual void SubscribeToClientTeleportEvents(IClientAPI client)
  2373. {
  2374. client.OnTeleportLocationRequest += RequestTeleportLocation;
  2375. }
  2376. public virtual void SubscribeToClientScriptEvents(IClientAPI client)
  2377. {
  2378. client.OnScriptReset += ProcessScriptReset;
  2379. client.OnGetScriptRunning += GetScriptRunning;
  2380. client.OnSetScriptRunning += SetScriptRunning;
  2381. }
  2382. public virtual void SubscribeToClientParcelEvents(IClientAPI client)
  2383. {
  2384. client.OnObjectGroupRequest += m_sceneGraph.HandleObjectGroupUpdate;
  2385. client.OnParcelReturnObjectsRequest += LandChannel.ReturnObjectsInParcel;
  2386. client.OnParcelSetOtherCleanTime += LandChannel.SetParcelOtherCleanTime;
  2387. client.OnParcelBuy += ProcessParcelBuy;
  2388. }
  2389. public virtual void SubscribeToClientGridEvents(IClientAPI client)
  2390. {
  2391. //client.OnNameFromUUIDRequest += HandleUUIDNameRequest;
  2392. client.OnMoneyTransferRequest += ProcessMoneyTransferRequest;
  2393. client.OnAvatarPickerRequest += ProcessAvatarPickerRequest;
  2394. client.OnSetStartLocationRequest += SetHomeRezPoint;
  2395. client.OnRegionHandleRequest += RegionHandleRequest;
  2396. }
  2397. public virtual void SubscribeToClientNetworkEvents(IClientAPI client)
  2398. {
  2399. client.OnNetworkStatsUpdate += StatsReporter.AddPacketsStats;
  2400. client.OnViewerEffect += ProcessViewerEffect;
  2401. }
  2402. /// <summary>
  2403. /// Unsubscribe the client from events.
  2404. /// </summary>
  2405. /// FIXME: Not called anywhere!
  2406. /// <param name="client">The IClientAPI of the client</param>
  2407. public virtual void UnSubscribeToClientEvents(IClientAPI client)
  2408. {
  2409. UnSubscribeToClientTerrainEvents(client);
  2410. UnSubscribeToClientPrimEvents(client);
  2411. UnSubscribeToClientPrimRezEvents(client);
  2412. UnSubscribeToClientInventoryEvents(client);
  2413. UnSubscribeToClientTeleportEvents(client);
  2414. UnSubscribeToClientScriptEvents(client);
  2415. UnSubscribeToClientParcelEvents(client);
  2416. UnSubscribeToClientGridEvents(client);
  2417. UnSubscribeToClientNetworkEvents(client);
  2418. }
  2419. public virtual void UnSubscribeToClientTerrainEvents(IClientAPI client)
  2420. {
  2421. client.OnRegionHandShakeReply -= SendLayerData;
  2422. }
  2423. public virtual void UnSubscribeToClientPrimEvents(IClientAPI client)
  2424. {
  2425. client.OnUpdatePrimGroupPosition -= m_sceneGraph.UpdatePrimGroupPosition;
  2426. client.OnUpdatePrimSinglePosition -= m_sceneGraph.UpdatePrimSinglePosition;
  2427. client.OnUpdatePrimGroupRotation -= m_sceneGraph.UpdatePrimGroupRotation;
  2428. client.OnUpdatePrimGroupMouseRotation -= m_sceneGraph.UpdatePrimGroupRotation;
  2429. client.OnUpdatePrimSingleRotation -= m_sceneGraph.UpdatePrimSingleRotation;
  2430. client.OnUpdatePrimSingleRotationPosition -= m_sceneGraph.UpdatePrimSingleRotationPosition;
  2431. client.OnUpdatePrimScale -= m_sceneGraph.UpdatePrimScale;
  2432. client.OnUpdatePrimGroupScale -= m_sceneGraph.UpdatePrimGroupScale;
  2433. client.OnUpdateExtraParams -= m_sceneGraph.UpdateExtraParam;
  2434. client.OnUpdatePrimShape -= m_sceneGraph.UpdatePrimShape;
  2435. client.OnUpdatePrimTexture -= m_sceneGraph.UpdatePrimTexture;
  2436. client.OnObjectRequest -= RequestPrim;
  2437. client.OnObjectSelect -= SelectPrim;
  2438. client.OnObjectDeselect -= DeselectPrim;
  2439. client.OnGrabUpdate -= m_sceneGraph.MoveObject;
  2440. client.OnSpinStart -= m_sceneGraph.SpinStart;
  2441. client.OnSpinUpdate -= m_sceneGraph.SpinObject;
  2442. client.OnDeRezObject -= DeRezObjects;
  2443. client.OnObjectName -= m_sceneGraph.PrimName;
  2444. client.OnObjectClickAction -= m_sceneGraph.PrimClickAction;
  2445. client.OnObjectMaterial -= m_sceneGraph.PrimMaterial;
  2446. client.OnLinkObjects -= LinkObjects;
  2447. client.OnDelinkObjects -= DelinkObjects;
  2448. client.OnObjectDuplicate -= m_sceneGraph.DuplicateObject;
  2449. client.OnObjectDuplicateOnRay -= doObjectDuplicateOnRay;
  2450. client.OnUpdatePrimFlags -= m_sceneGraph.UpdatePrimFlags;
  2451. client.OnRequestObjectPropertiesFamily -= m_sceneGraph.RequestObjectPropertiesFamily;
  2452. client.OnObjectPermissions -= HandleObjectPermissionsUpdate;
  2453. client.OnGrabObject -= ProcessObjectGrab;
  2454. client.OnDeGrabObject -= ProcessObjectDeGrab;
  2455. client.OnUndo -= m_sceneGraph.HandleUndo;
  2456. client.OnRedo -= m_sceneGraph.HandleRedo;
  2457. client.OnObjectDescription -= m_sceneGraph.PrimDescription;
  2458. client.OnObjectIncludeInSearch -= m_sceneGraph.MakeObjectSearchable;
  2459. client.OnObjectOwner -= ObjectOwner;
  2460. }
  2461. public virtual void UnSubscribeToClientPrimRezEvents(IClientAPI client)
  2462. {
  2463. client.OnAddPrim -= AddNewPrim;
  2464. client.OnRezObject -= RezObject;
  2465. }
  2466. public virtual void UnSubscribeToClientInventoryEvents(IClientAPI client)
  2467. {
  2468. client.OnCreateNewInventoryFolder -= HandleCreateInventoryFolder;
  2469. client.OnUpdateInventoryFolder -= HandleUpdateInventoryFolder;
  2470. client.OnMoveInventoryFolder -= HandleMoveInventoryFolder; // 2; //!!
  2471. client.OnFetchInventoryDescendents -= HandleFetchInventoryDescendents;
  2472. client.OnPurgeInventoryDescendents -= HandlePurgeInventoryDescendents; // 2; //!!
  2473. client.OnFetchInventory -= m_asyncInventorySender.HandleFetchInventory;
  2474. client.OnUpdateInventoryItem -= UpdateInventoryItemAsset;
  2475. client.OnCopyInventoryItem -= CopyInventoryItem;
  2476. client.OnMoveInventoryItem -= MoveInventoryItem;
  2477. client.OnRemoveInventoryItem -= RemoveInventoryItem;
  2478. client.OnRemoveInventoryFolder -= RemoveInventoryFolder;
  2479. client.OnRezScript -= RezScript;
  2480. client.OnRequestTaskInventory -= RequestTaskInventory;
  2481. client.OnRemoveTaskItem -= RemoveTaskInventory;
  2482. client.OnUpdateTaskInventory -= UpdateTaskInventory;
  2483. client.OnMoveTaskItem -= ClientMoveTaskInventoryItem;
  2484. }
  2485. public virtual void UnSubscribeToClientTeleportEvents(IClientAPI client)
  2486. {
  2487. client.OnTeleportLocationRequest -= RequestTeleportLocation;
  2488. //client.OnTeleportLandmarkRequest -= RequestTeleportLandmark;
  2489. //client.OnTeleportHomeRequest -= TeleportClientHome;
  2490. }
  2491. public virtual void UnSubscribeToClientScriptEvents(IClientAPI client)
  2492. {
  2493. client.OnScriptReset -= ProcessScriptReset;
  2494. client.OnGetScriptRunning -= GetScriptRunning;
  2495. client.OnSetScriptRunning -= SetScriptRunning;
  2496. }
  2497. public virtual void UnSubscribeToClientParcelEvents(IClientAPI client)
  2498. {
  2499. client.OnObjectGroupRequest -= m_sceneGraph.HandleObjectGroupUpdate;
  2500. client.OnParcelReturnObjectsRequest -= LandChannel.ReturnObjectsInParcel;
  2501. client.OnParcelSetOtherCleanTime -= LandChannel.SetParcelOtherCleanTime;
  2502. client.OnParcelBuy -= ProcessParcelBuy;
  2503. }
  2504. public virtual void UnSubscribeToClientGridEvents(IClientAPI client)
  2505. {
  2506. //client.OnNameFromUUIDRequest -= HandleUUIDNameRequest;
  2507. client.OnMoneyTransferRequest -= ProcessMoneyTransferRequest;
  2508. client.OnAvatarPickerRequest -= ProcessAvatarPickerRequest;
  2509. client.OnSetStartLocationRequest -= SetHomeRezPoint;
  2510. client.OnRegionHandleRequest -= RegionHandleRequest;
  2511. }
  2512. public virtual void UnSubscribeToClientNetworkEvents(IClientAPI client)
  2513. {
  2514. client.OnNetworkStatsUpdate -= StatsReporter.AddPacketsStats;
  2515. client.OnViewerEffect -= ProcessViewerEffect;
  2516. }
  2517. /// <summary>
  2518. /// Teleport an avatar to their home region
  2519. /// </summary>
  2520. /// <param name="agentId">The avatar's Unique ID</param>
  2521. /// <param name="client">The IClientAPI for the client</param>
  2522. public virtual void TeleportClientHome(UUID agentId, IClientAPI client)
  2523. {
  2524. if (m_teleportModule != null)
  2525. m_teleportModule.TeleportHome(agentId, client);
  2526. else
  2527. {
  2528. m_log.DebugFormat("[SCENE]: Unable to teleport user home: no AgentTransferModule is active");
  2529. client.SendTeleportFailed("Unable to perform teleports on this simulator.");
  2530. }
  2531. }
  2532. /// <summary>
  2533. /// Duplicates object specified by localID at position raycasted against RayTargetObject using
  2534. /// RayEnd and RayStart to determine what the angle of the ray is
  2535. /// </summary>
  2536. /// <param name="localID">ID of object to duplicate</param>
  2537. /// <param name="dupeFlags"></param>
  2538. /// <param name="AgentID">Agent doing the duplication</param>
  2539. /// <param name="GroupID">Group of new object</param>
  2540. /// <param name="RayTargetObj">The target of the Ray</param>
  2541. /// <param name="RayEnd">The ending of the ray (farthest away point)</param>
  2542. /// <param name="RayStart">The Beginning of the ray (closest point)</param>
  2543. /// <param name="BypassRaycast">Bool to bypass raycasting</param>
  2544. /// <param name="RayEndIsIntersection">The End specified is the place to add the object</param>
  2545. /// <param name="CopyCenters">Position the object at the center of the face that it's colliding with</param>
  2546. /// <param name="CopyRotates">Rotate the object the same as the localID object</param>
  2547. public void doObjectDuplicateOnRay(uint localID, uint dupeFlags, UUID AgentID, UUID GroupID,
  2548. UUID RayTargetObj, Vector3 RayEnd, Vector3 RayStart,
  2549. bool BypassRaycast, bool RayEndIsIntersection, bool CopyCenters, bool CopyRotates)
  2550. {
  2551. Vector3 pos;
  2552. const bool frontFacesOnly = true;
  2553. //m_log.Info("HITTARGET: " + RayTargetObj.ToString() + ", COPYTARGET: " + localID.ToString());
  2554. SceneObjectPart target = GetSceneObjectPart(localID);
  2555. SceneObjectPart target2 = GetSceneObjectPart(RayTargetObj);
  2556. if (target != null && target2 != null)
  2557. {
  2558. Vector3 direction = Vector3.Normalize(RayEnd - RayStart);
  2559. Vector3 AXOrigin = new Vector3(RayStart.X, RayStart.Y, RayStart.Z);
  2560. Vector3 AXdirection = new Vector3(direction.X, direction.Y, direction.Z);
  2561. pos = target2.AbsolutePosition;
  2562. //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());
  2563. // TODO: Raytrace better here
  2564. //EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection));
  2565. Ray NewRay = new Ray(AXOrigin, AXdirection);
  2566. // Ray Trace against target here
  2567. EntityIntersection ei = target2.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, CopyCenters);
  2568. // Un-comment out the following line to Get Raytrace results printed to the console.
  2569. //m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString());
  2570. float ScaleOffset = 0.5f;
  2571. // If we hit something
  2572. if (ei.HitTF)
  2573. {
  2574. Vector3 scale = target.Scale;
  2575. Vector3 scaleComponent = new Vector3(ei.AAfaceNormal.X, ei.AAfaceNormal.Y, ei.AAfaceNormal.Z);
  2576. if (scaleComponent.X != 0) ScaleOffset = scale.X;
  2577. if (scaleComponent.Y != 0) ScaleOffset = scale.Y;
  2578. if (scaleComponent.Z != 0) ScaleOffset = scale.Z;
  2579. ScaleOffset = Math.Abs(ScaleOffset);
  2580. Vector3 intersectionpoint = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z);
  2581. Vector3 normal = new Vector3(ei.normal.X, ei.normal.Y, ei.normal.Z);
  2582. Vector3 offset = normal * (ScaleOffset / 2f);
  2583. pos = intersectionpoint + offset;
  2584. // stick in offset format from the original prim
  2585. pos = pos - target.ParentGroup.AbsolutePosition;
  2586. if (CopyRotates)
  2587. {
  2588. Quaternion worldRot = target2.GetWorldRotation();
  2589. // SceneObjectGroup obj = m_sceneGraph.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID, worldRot);
  2590. m_sceneGraph.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID, worldRot);
  2591. //obj.Rotation = worldRot;
  2592. //obj.UpdateGroupRotationR(worldRot);
  2593. }
  2594. else
  2595. {
  2596. m_sceneGraph.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID);
  2597. }
  2598. }
  2599. }
  2600. }
  2601. /// <summary>
  2602. /// Sets the Home Point. The LoginService uses this to know where to put a user when they log-in
  2603. /// </summary>
  2604. /// <param name="remoteClient"></param>
  2605. /// <param name="regionHandle"></param>
  2606. /// <param name="position"></param>
  2607. /// <param name="lookAt"></param>
  2608. /// <param name="flags"></param>
  2609. public virtual void SetHomeRezPoint(IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags)
  2610. {
  2611. if (GridUserService != null && GridUserService.SetHome(remoteClient.AgentId.ToString(), RegionInfo.RegionID, position, lookAt))
  2612. // FUBAR ALERT: this needs to be "Home position set." so the viewer saves a home-screenshot.
  2613. m_dialogModule.SendAlertToUser(remoteClient, "Home position set.");
  2614. else
  2615. m_dialogModule.SendAlertToUser(remoteClient, "Set Home request Failed.");
  2616. }
  2617. /// <summary>
  2618. /// Get the avatar apperance for the given client.
  2619. /// </summary>
  2620. /// <param name="client"></param>
  2621. /// <param name="appearance"></param>
  2622. public void GetAvatarAppearance(IClientAPI client, out AvatarAppearance appearance)
  2623. {
  2624. AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode);
  2625. if (aCircuit == null)
  2626. {
  2627. m_log.DebugFormat("[APPEARANCE] Client did not supply a circuit. Non-Linden? Creating default appearance.");
  2628. appearance = new AvatarAppearance();
  2629. return;
  2630. }
  2631. appearance = aCircuit.Appearance;
  2632. if (appearance == null)
  2633. {
  2634. m_log.DebugFormat("[APPEARANCE]: Appearance not found in {0}, returning default", RegionInfo.RegionName);
  2635. appearance = new AvatarAppearance();
  2636. }
  2637. }
  2638. public override void RemoveClient(UUID agentID, bool closeChildAgents)
  2639. {
  2640. CheckHeartbeat();
  2641. bool childagentYN = false;
  2642. ScenePresence avatar = GetScenePresence(agentID);
  2643. if (avatar != null)
  2644. {
  2645. childagentYN = avatar.IsChildAgent;
  2646. if (avatar.ParentID != 0)
  2647. {
  2648. avatar.StandUp();
  2649. }
  2650. try
  2651. {
  2652. m_log.DebugFormat(
  2653. "[SCENE]: Removing {0} agent {1} from region {2}",
  2654. (childagentYN ? "child" : "root"), agentID, RegionInfo.RegionName);
  2655. m_sceneGraph.removeUserCount(!childagentYN);
  2656. // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop
  2657. // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI
  2658. if (closeChildAgents && CapsModule != null)
  2659. CapsModule.RemoveCaps(agentID);
  2660. // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever
  2661. // this method is doing is HORRIBLE!!!
  2662. avatar.Scene.NeedSceneCacheClear(avatar.UUID);
  2663. if (closeChildAgents && !avatar.IsChildAgent)
  2664. {
  2665. //List<ulong> childknownRegions = new List<ulong>();
  2666. //List<ulong> ckn = avatar.KnownChildRegionHandles;
  2667. //for (int i = 0; i < ckn.Count; i++)
  2668. //{
  2669. // childknownRegions.Add(ckn[i]);
  2670. //}
  2671. List<ulong> regions = new List<ulong>(avatar.KnownChildRegionHandles);
  2672. regions.Remove(RegionInfo.RegionHandle);
  2673. m_sceneGridService.SendCloseChildAgentConnections(agentID, regions);
  2674. }
  2675. m_eventManager.TriggerClientClosed(agentID, this);
  2676. }
  2677. catch (NullReferenceException)
  2678. {
  2679. // We don't know which count to remove it from
  2680. // Avatar is already disposed :/
  2681. }
  2682. m_eventManager.TriggerOnRemovePresence(agentID);
  2683. if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc)
  2684. AttachmentsModule.SaveChangedAttachments(avatar);
  2685. ForEachClient(
  2686. delegate(IClientAPI client)
  2687. {
  2688. //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway
  2689. try { client.SendKillObject(avatar.RegionHandle, avatar.LocalId); }
  2690. catch (NullReferenceException) { }
  2691. });
  2692. IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>();
  2693. if (agentTransactions != null)
  2694. {
  2695. agentTransactions.RemoveAgentAssetTransactions(agentID);
  2696. }
  2697. // Remove the avatar from the scene
  2698. m_sceneGraph.RemoveScenePresence(agentID);
  2699. m_clientManager.Remove(agentID);
  2700. try
  2701. {
  2702. avatar.Close();
  2703. }
  2704. catch (NullReferenceException)
  2705. {
  2706. //We can safely ignore null reference exceptions. It means the avatar are dead and cleaned up anyway.
  2707. }
  2708. catch (Exception e)
  2709. {
  2710. m_log.Error("[SCENE] Scene.cs:RemoveClient exception: " + e.ToString());
  2711. }
  2712. m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode);
  2713. // CleanDroppedAttachments();
  2714. //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false));
  2715. //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true));
  2716. }
  2717. }
  2718. /// <summary>
  2719. /// Removes region from an avatar's known region list. This coincides with child agents. For each child agent, there will be a known region entry.
  2720. ///
  2721. /// </summary>
  2722. /// <param name="avatarID"></param>
  2723. /// <param name="regionslst"></param>
  2724. public void HandleRemoveKnownRegionsFromAvatar(UUID avatarID, List<ulong> regionslst)
  2725. {
  2726. ScenePresence av = GetScenePresence(avatarID);
  2727. if (av != null)
  2728. {
  2729. lock (av)
  2730. {
  2731. for (int i = 0; i < regionslst.Count; i++)
  2732. {
  2733. av.KnownChildRegionHandles.Remove(regionslst[i]);
  2734. }
  2735. }
  2736. }
  2737. }
  2738. #endregion
  2739. #region Entities
  2740. public void SendKillObject(uint localID)
  2741. {
  2742. SceneObjectPart part = GetSceneObjectPart(localID);
  2743. if (part != null) // It is a prim
  2744. {
  2745. if (!part.ParentGroup.IsDeleted) // Valid
  2746. {
  2747. if (part.ParentGroup.RootPart != part) // Child part
  2748. return;
  2749. }
  2750. }
  2751. ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, localID); });
  2752. }
  2753. #endregion
  2754. #region RegionComms
  2755. /// <summary>
  2756. /// Register the methods that should be invoked when this scene receives various incoming events
  2757. /// </summary>
  2758. public void RegisterCommsEvents()
  2759. {
  2760. m_sceneGridService.OnAvatarCrossingIntoRegion += AgentCrossing;
  2761. m_sceneGridService.OnCloseAgentConnection += IncomingCloseAgent;
  2762. //m_eventManager.OnRegionUp += OtherRegionUp;
  2763. //m_sceneGridService.OnChildAgentUpdate += IncomingChildAgentDataUpdate;
  2764. //m_sceneGridService.OnRemoveKnownRegionFromAvatar += HandleRemoveKnownRegionsFromAvatar;
  2765. m_sceneGridService.OnLogOffUser += HandleLogOffUserFromGrid;
  2766. m_sceneGridService.KiPrimitive += SendKillObject;
  2767. m_sceneGridService.OnGetLandData += GetLandData;
  2768. }
  2769. /// <summary>
  2770. /// Deregister this scene from receiving incoming region events
  2771. /// </summary>
  2772. public void UnRegisterRegionWithComms()
  2773. {
  2774. m_sceneGridService.KiPrimitive -= SendKillObject;
  2775. m_sceneGridService.OnLogOffUser -= HandleLogOffUserFromGrid;
  2776. //m_sceneGridService.OnRemoveKnownRegionFromAvatar -= HandleRemoveKnownRegionsFromAvatar;
  2777. //m_sceneGridService.OnChildAgentUpdate -= IncomingChildAgentDataUpdate;
  2778. //m_eventManager.OnRegionUp -= OtherRegionUp;
  2779. m_sceneGridService.OnAvatarCrossingIntoRegion -= AgentCrossing;
  2780. m_sceneGridService.OnCloseAgentConnection -= IncomingCloseAgent;
  2781. m_sceneGridService.OnGetLandData -= GetLandData;
  2782. // this does nothing; should be removed
  2783. m_sceneGridService.Close();
  2784. if (!GridService.DeregisterRegion(m_regInfo.RegionID))
  2785. m_log.WarnFormat("[SCENE]: Deregister from grid failed for region {0}", m_regInfo.RegionName);
  2786. }
  2787. /// <summary>
  2788. /// Do the work necessary to initiate a new user connection for a particular scene.
  2789. /// At the moment, this consists of setting up the caps infrastructure
  2790. /// The return bool should allow for connections to be refused, but as not all calling paths
  2791. /// take proper notice of it let, we allowed banned users in still.
  2792. /// </summary>
  2793. /// <param name="agent">CircuitData of the agent who is connecting</param>
  2794. /// <param name="reason">Outputs the reason for the false response on this string</param>
  2795. /// <returns>True if the region accepts this agent. False if it does not. False will
  2796. /// also return a reason.</returns>
  2797. public bool NewUserConnection(AgentCircuitData agent, uint teleportFlags, out string reason)
  2798. {
  2799. return NewUserConnection(agent, teleportFlags, out reason, true);
  2800. }
  2801. /// <summary>
  2802. /// Do the work necessary to initiate a new user connection for a particular scene.
  2803. /// At the moment, this consists of setting up the caps infrastructure
  2804. /// The return bool should allow for connections to be refused, but as not all calling paths
  2805. /// take proper notice of it let, we allowed banned users in still.
  2806. /// </summary>
  2807. /// <param name="agent">CircuitData of the agent who is connecting</param>
  2808. /// <param name="reason">Outputs the reason for the false response on this string</param>
  2809. /// <param name="requirePresenceLookup">True for normal presence. False for NPC
  2810. /// or other applications where a full grid/Hypergrid presence may not be required.</param>
  2811. /// <returns>True if the region accepts this agent. False if it does not. False will
  2812. /// also return a reason.</returns>
  2813. public bool NewUserConnection(AgentCircuitData agent, uint teleportFlags, out string reason, bool requirePresenceLookup)
  2814. {
  2815. bool vialogin = ((teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0 ||
  2816. (teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0);
  2817. reason = String.Empty;
  2818. //Teleport flags:
  2819. //
  2820. // TeleportFlags.ViaGodlikeLure - Border Crossing
  2821. // TeleportFlags.ViaLogin - Login
  2822. // TeleportFlags.TeleportFlags.ViaLure - Teleport request sent by another user
  2823. // TeleportFlags.ViaLandmark | TeleportFlags.ViaLocation | TeleportFlags.ViaLandmark | TeleportFlags.Default - Regular Teleport
  2824. // Don't disable this log message - it's too helpful
  2825. m_log.DebugFormat(
  2826. "[CONNECTION BEGIN]: Region {0} told of incoming {1} agent {2} {3} {4} (circuit code {5}, teleportflags {6})",
  2827. RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname,
  2828. agent.AgentID, agent.circuitcode, teleportFlags);
  2829. if (LoginsDisabled)
  2830. {
  2831. reason = "Logins Disabled";
  2832. return false;
  2833. }
  2834. ScenePresence sp = GetScenePresence(agent.AgentID);
  2835. if (sp != null && !sp.IsChildAgent)
  2836. {
  2837. // We have a zombie from a crashed session.
  2838. // Or the same user is trying to be root twice here, won't work.
  2839. // Kill it.
  2840. m_log.DebugFormat("[SCENE]: Zombie scene presence detected for {0} in {1}", agent.AgentID, RegionInfo.RegionName);
  2841. sp.ControllingClient.Close();
  2842. sp = null;
  2843. }
  2844. ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
  2845. //On login test land permisions
  2846. if (vialogin)
  2847. {
  2848. if (land != null && !TestLandRestrictions(agent, land, out reason))
  2849. {
  2850. return false;
  2851. }
  2852. }
  2853. if (sp == null) // We don't have an [child] agent here already
  2854. {
  2855. if (requirePresenceLookup)
  2856. {
  2857. try
  2858. {
  2859. if (!VerifyUserPresence(agent, out reason))
  2860. return false;
  2861. }
  2862. catch (Exception e)
  2863. {
  2864. m_log.ErrorFormat("[CONNECTION BEGIN]: Exception verifying presence " + e.ToString());
  2865. return false;
  2866. }
  2867. }
  2868. try
  2869. {
  2870. if (!AuthorizeUser(agent, out reason))
  2871. return false;
  2872. }
  2873. catch (Exception e)
  2874. {
  2875. m_log.ErrorFormat("[CONNECTION BEGIN]: Exception authorizing user " + e.ToString());
  2876. return false;
  2877. }
  2878. m_log.InfoFormat(
  2879. "[CONNECTION BEGIN]: Region {0} authenticated and authorized incoming {1} agent {2} {3} {4} (circuit code {5})",
  2880. RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname,
  2881. agent.AgentID, agent.circuitcode);
  2882. if (CapsModule != null)
  2883. {
  2884. CapsModule.SetAgentCapsSeeds(agent);
  2885. CapsModule.CreateCaps(agent.AgentID);
  2886. }
  2887. }
  2888. else
  2889. {
  2890. // Let the SP know how we got here. This has a lot of interesting
  2891. // uses down the line.
  2892. sp.TeleportFlags = (TeleportFlags)teleportFlags;
  2893. if (sp.IsChildAgent)
  2894. {
  2895. m_log.DebugFormat(
  2896. "[SCENE]: Adjusting known seeds for existing agent {0} in {1}",
  2897. agent.AgentID, RegionInfo.RegionName);
  2898. sp.AdjustKnownSeeds();
  2899. if (CapsModule != null)
  2900. CapsModule.SetAgentCapsSeeds(agent);
  2901. }
  2902. }
  2903. // In all cases, add or update the circuit data with the new agent circuit data and teleport flags
  2904. agent.teleportFlags = teleportFlags;
  2905. m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent);
  2906. if (vialogin)
  2907. {
  2908. // CleanDroppedAttachments();
  2909. if (TestBorderCross(agent.startpos, Cardinals.E))
  2910. {
  2911. Border crossedBorder = GetCrossedBorder(agent.startpos, Cardinals.E);
  2912. agent.startpos.X = crossedBorder.BorderLine.Z - 1;
  2913. }
  2914. if (TestBorderCross(agent.startpos, Cardinals.N))
  2915. {
  2916. Border crossedBorder = GetCrossedBorder(agent.startpos, Cardinals.N);
  2917. agent.startpos.Y = crossedBorder.BorderLine.Z - 1;
  2918. }
  2919. //Mitigate http://opensimulator.org/mantis/view.php?id=3522
  2920. // Check if start position is outside of region
  2921. // If it is, check the Z start position also.. if not, leave it alone.
  2922. if (BordersLocked)
  2923. {
  2924. lock (EastBorders)
  2925. {
  2926. if (agent.startpos.X > EastBorders[0].BorderLine.Z)
  2927. {
  2928. m_log.Warn("FIX AGENT POSITION");
  2929. agent.startpos.X = EastBorders[0].BorderLine.Z * 0.5f;
  2930. if (agent.startpos.Z > 720)
  2931. agent.startpos.Z = 720;
  2932. }
  2933. }
  2934. lock (NorthBorders)
  2935. {
  2936. if (agent.startpos.Y > NorthBorders[0].BorderLine.Z)
  2937. {
  2938. m_log.Warn("FIX Agent POSITION");
  2939. agent.startpos.Y = NorthBorders[0].BorderLine.Z * 0.5f;
  2940. if (agent.startpos.Z > 720)
  2941. agent.startpos.Z = 720;
  2942. }
  2943. }
  2944. }
  2945. else
  2946. {
  2947. if (agent.startpos.X > EastBorders[0].BorderLine.Z)
  2948. {
  2949. m_log.Warn("FIX AGENT POSITION");
  2950. agent.startpos.X = EastBorders[0].BorderLine.Z * 0.5f;
  2951. if (agent.startpos.Z > 720)
  2952. agent.startpos.Z = 720;
  2953. }
  2954. if (agent.startpos.Y > NorthBorders[0].BorderLine.Z)
  2955. {
  2956. m_log.Warn("FIX Agent POSITION");
  2957. agent.startpos.Y = NorthBorders[0].BorderLine.Z * 0.5f;
  2958. if (agent.startpos.Z > 720)
  2959. agent.startpos.Z = 720;
  2960. }
  2961. }
  2962. // Honor parcel landing type and position.
  2963. if (land != null)
  2964. {
  2965. if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero)
  2966. {
  2967. agent.startpos = land.LandData.UserLocation;
  2968. }
  2969. }
  2970. }
  2971. return true;
  2972. }
  2973. private bool TestLandRestrictions(AgentCircuitData agent, ILandObject land, out string reason)
  2974. {
  2975. bool banned = land.IsBannedFromLand(agent.AgentID);
  2976. bool restricted = land.IsRestrictedFromLand(agent.AgentID);
  2977. if (banned || restricted)
  2978. {
  2979. ILandObject nearestParcel = GetNearestAllowedParcel(agent.AgentID, agent.startpos.X, agent.startpos.Y);
  2980. if (nearestParcel != null)
  2981. {
  2982. //Move agent to nearest allowed
  2983. Vector3 newPosition = GetParcelCenterAtGround(nearestParcel);
  2984. agent.startpos.X = newPosition.X;
  2985. agent.startpos.Y = newPosition.Y;
  2986. }
  2987. else
  2988. {
  2989. if (banned)
  2990. {
  2991. reason = "Cannot regioncross into banned parcel.";
  2992. }
  2993. else
  2994. {
  2995. reason = String.Format("Denied access to private region {0}: You are not on the access list for that region.",
  2996. RegionInfo.RegionName);
  2997. }
  2998. return false;
  2999. }
  3000. }
  3001. reason = "";
  3002. return true;
  3003. }
  3004. /// <summary>
  3005. /// Verifies that the user has a presence on the Grid
  3006. /// </summary>
  3007. /// <param name="agent">Circuit Data of the Agent we're verifying</param>
  3008. /// <param name="reason">Outputs the reason for the false response on this string</param>
  3009. /// <returns>True if the user has a session on the grid. False if it does not. False will
  3010. /// also return a reason.</returns>
  3011. public virtual bool VerifyUserPresence(AgentCircuitData agent, out string reason)
  3012. {
  3013. reason = String.Empty;
  3014. IPresenceService presence = RequestModuleInterface<IPresenceService>();
  3015. if (presence == null)
  3016. {
  3017. reason = String.Format("Failed to verify user presence in the grid for {0} {1} in region {2}. Presence service does not exist.", agent.firstname, agent.lastname, RegionInfo.RegionName);
  3018. return false;
  3019. }
  3020. OpenSim.Services.Interfaces.PresenceInfo pinfo = presence.GetAgent(agent.SessionID);
  3021. if (pinfo == null)
  3022. {
  3023. reason = String.Format("Failed to verify user presence in the grid for {0} {1}, access denied to region {2}.", agent.firstname, agent.lastname, RegionInfo.RegionName);
  3024. return false;
  3025. }
  3026. return true;
  3027. }
  3028. /// <summary>
  3029. /// Verify if the user can connect to this region. Checks the banlist and ensures that the region is set for public access
  3030. /// </summary>
  3031. /// <param name="agent">The circuit data for the agent</param>
  3032. /// <param name="reason">outputs the reason to this string</param>
  3033. /// <returns>True if the region accepts this agent. False if it does not. False will
  3034. /// also return a reason.</returns>
  3035. protected virtual bool AuthorizeUser(AgentCircuitData agent, out string reason)
  3036. {
  3037. reason = String.Empty;
  3038. if (!m_strictAccessControl) return true;
  3039. if (Permissions.IsGod(agent.AgentID)) return true;
  3040. if (AuthorizationService != null)
  3041. {
  3042. if (!AuthorizationService.IsAuthorizedForRegion(
  3043. agent.AgentID.ToString(), agent.firstname, agent.lastname, RegionInfo.RegionID.ToString(), out reason))
  3044. {
  3045. m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the region",
  3046. agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
  3047. return false;
  3048. }
  3049. }
  3050. if (m_regInfo.EstateSettings != null)
  3051. {
  3052. if (m_regInfo.EstateSettings.IsBanned(agent.AgentID))
  3053. {
  3054. m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist",
  3055. agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
  3056. reason = String.Format("Denied access to region {0}: You have been banned from that region.",
  3057. RegionInfo.RegionName);
  3058. return false;
  3059. }
  3060. }
  3061. else
  3062. m_log.ErrorFormat("[CONNECTION BEGIN]: Estate Settings is null!");
  3063. IGroupsModule groupsModule =
  3064. RequestModuleInterface<IGroupsModule>();
  3065. List<UUID> agentGroups = new List<UUID>();
  3066. if (groupsModule != null)
  3067. {
  3068. GroupMembershipData[] GroupMembership =
  3069. groupsModule.GetMembershipData(agent.AgentID);
  3070. if (GroupMembership != null)
  3071. {
  3072. for (int i = 0; i < GroupMembership.Length; i++)
  3073. agentGroups.Add(GroupMembership[i].GroupID);
  3074. }
  3075. else
  3076. m_log.ErrorFormat("[CONNECTION BEGIN]: GroupMembership is null!");
  3077. }
  3078. bool groupAccess = false;
  3079. UUID[] estateGroups = m_regInfo.EstateSettings.EstateGroups;
  3080. if (estateGroups != null)
  3081. {
  3082. foreach (UUID group in estateGroups)
  3083. {
  3084. if (agentGroups.Contains(group))
  3085. {
  3086. groupAccess = true;
  3087. break;
  3088. }
  3089. }
  3090. }
  3091. else
  3092. m_log.ErrorFormat("[CONNECTION BEGIN]: EstateGroups is null!");
  3093. if (!m_regInfo.EstateSettings.PublicAccess &&
  3094. !m_regInfo.EstateSettings.HasAccess(agent.AgentID) &&
  3095. !groupAccess)
  3096. {
  3097. m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the estate",
  3098. agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
  3099. reason = String.Format("Denied access to private region {0}: You are not on the access list for that region.",
  3100. RegionInfo.RegionName);
  3101. return false;
  3102. }
  3103. // TODO: estate/region settings are not properly hooked up
  3104. // to ILandObject.isRestrictedFromLand()
  3105. // if (null != LandChannel)
  3106. // {
  3107. // // region seems to have local Id of 1
  3108. // ILandObject land = LandChannel.GetLandObject(1);
  3109. // if (null != land)
  3110. // {
  3111. // if (land.isBannedFromLand(agent.AgentID))
  3112. // {
  3113. // m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user has been banned from land",
  3114. // agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
  3115. // reason = String.Format("Denied access to private region {0}: You are banned from that region.",
  3116. // RegionInfo.RegionName);
  3117. // return false;
  3118. // }
  3119. // if (land.isRestrictedFromLand(agent.AgentID))
  3120. // {
  3121. // m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the region",
  3122. // agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
  3123. // reason = String.Format("Denied access to private region {0}: You are not on the access list for that region.",
  3124. // RegionInfo.RegionName);
  3125. // return false;
  3126. // }
  3127. // }
  3128. // }
  3129. return true;
  3130. }
  3131. /// <summary>
  3132. /// Update an AgentCircuitData object with new information
  3133. /// </summary>
  3134. /// <param name="data">Information to update the AgentCircuitData with</param>
  3135. public void UpdateCircuitData(AgentCircuitData data)
  3136. {
  3137. m_authenticateHandler.UpdateAgentData(data);
  3138. }
  3139. /// <summary>
  3140. /// Change the Circuit Code for the user's Circuit Data
  3141. /// </summary>
  3142. /// <param name="oldcc">The old Circuit Code. Must match a previous circuit code</param>
  3143. /// <param name="newcc">The new Circuit Code. Must not be an already existing circuit code</param>
  3144. /// <returns>True if we successfully changed it. False if we did not</returns>
  3145. public bool ChangeCircuitCode(uint oldcc, uint newcc)
  3146. {
  3147. return m_authenticateHandler.TryChangeCiruitCode(oldcc, newcc);
  3148. }
  3149. /// <summary>
  3150. /// The Grid has requested that we log-off a user. Log them off.
  3151. /// </summary>
  3152. /// <param name="AvatarID">Unique ID of the avatar to log-off</param>
  3153. /// <param name="RegionSecret">SecureSessionID of the user, or the RegionSecret text when logging on to the grid</param>
  3154. /// <param name="message">message to display to the user. Reason for being logged off</param>
  3155. public void HandleLogOffUserFromGrid(UUID AvatarID, UUID RegionSecret, string message)
  3156. {
  3157. ScenePresence loggingOffUser = GetScenePresence(AvatarID);
  3158. if (loggingOffUser != null)
  3159. {
  3160. UUID localRegionSecret = UUID.Zero;
  3161. bool parsedsecret = UUID.TryParse(m_regInfo.regionSecret, out localRegionSecret);
  3162. // Region Secret is used here in case a new sessionid overwrites an old one on the user server.
  3163. // Will update the user server in a few revisions to use it.
  3164. if (RegionSecret == loggingOffUser.ControllingClient.SecureSessionId || (parsedsecret && RegionSecret == localRegionSecret))
  3165. {
  3166. m_sceneGridService.SendCloseChildAgentConnections(loggingOffUser.UUID, new List<ulong>(loggingOffUser.KnownRegions.Keys));
  3167. loggingOffUser.ControllingClient.Kick(message);
  3168. // Give them a second to receive the message!
  3169. Thread.Sleep(1000);
  3170. loggingOffUser.ControllingClient.Close();
  3171. }
  3172. else
  3173. {
  3174. m_log.Info("[USERLOGOFF]: System sending the LogOff user message failed to sucessfully authenticate");
  3175. }
  3176. }
  3177. else
  3178. {
  3179. 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());
  3180. }
  3181. }
  3182. /// <summary>
  3183. /// Triggered when an agent crosses into this sim. Also happens on initial login.
  3184. /// </summary>
  3185. /// <param name="agentID"></param>
  3186. /// <param name="position"></param>
  3187. /// <param name="isFlying"></param>
  3188. public virtual void AgentCrossing(UUID agentID, Vector3 position, bool isFlying)
  3189. {
  3190. ScenePresence presence = GetScenePresence(agentID);
  3191. if (presence != null)
  3192. {
  3193. try
  3194. {
  3195. presence.MakeRootAgent(position, isFlying);
  3196. }
  3197. catch (Exception e)
  3198. {
  3199. m_log.ErrorFormat("[SCENE]: Unable to do agent crossing, exception {0}", e);
  3200. }
  3201. }
  3202. else
  3203. {
  3204. m_log.ErrorFormat(
  3205. "[SCENE]: Could not find presence for agent {0} crossing into scene {1}",
  3206. agentID, RegionInfo.RegionName);
  3207. }
  3208. }
  3209. /// <summary>
  3210. /// We've got an update about an agent that sees into this region,
  3211. /// send it to ScenePresence for processing It's the full data.
  3212. /// </summary>
  3213. /// <param name="cAgentData">Agent that contains all of the relevant things about an agent.
  3214. /// Appearance, animations, position, etc.</param>
  3215. /// <returns>true if we handled it.</returns>
  3216. public virtual bool IncomingChildAgentDataUpdate(AgentData cAgentData)
  3217. {
  3218. m_log.DebugFormat(
  3219. "[SCENE]: Incoming child agent update for {0} in {1}", cAgentData.AgentID, RegionInfo.RegionName);
  3220. // XPTO: if this agent is not allowed here as root, always return false
  3221. // We have to wait until the viewer contacts this region after receiving EAC.
  3222. // That calls AddNewClient, which finally creates the ScenePresence
  3223. ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2);
  3224. if (nearestParcel == null)
  3225. {
  3226. m_log.DebugFormat("[SCENE]: Denying root agent entry to {0}: no allowed parcel", cAgentData.AgentID);
  3227. return false;
  3228. }
  3229. int num = m_sceneGraph.GetNumberOfScenePresences();
  3230. if (num >= RegionInfo.RegionSettings.AgentLimit)
  3231. {
  3232. if (!Permissions.IsAdministrator(cAgentData.AgentID))
  3233. return false;
  3234. }
  3235. ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID);
  3236. if (childAgentUpdate != null)
  3237. {
  3238. childAgentUpdate.ChildAgentDataUpdate(cAgentData);
  3239. return true;
  3240. }
  3241. return false;
  3242. }
  3243. /// <summary>
  3244. /// We've got an update about an agent that sees into this region,
  3245. /// send it to ScenePresence for processing It's only positional data
  3246. /// </summary>
  3247. /// <param name="cAgentData">AgentPosition that contains agent positional data so we can know what to send</param>
  3248. /// <returns>true if we handled it.</returns>
  3249. public virtual bool IncomingChildAgentDataUpdate(AgentPosition cAgentData)
  3250. {
  3251. //m_log.Debug(" XXX Scene IncomingChildAgentDataUpdate POSITION in " + RegionInfo.RegionName);
  3252. ScenePresence childAgentUpdate = GetScenePresence(cAgentData.AgentID);
  3253. if (childAgentUpdate != null)
  3254. {
  3255. // I can't imagine *yet* why we would get an update if the agent is a root agent..
  3256. // however to avoid a race condition crossing borders..
  3257. if (childAgentUpdate.IsChildAgent)
  3258. {
  3259. uint rRegionX = (uint)(cAgentData.RegionHandle >> 40);
  3260. uint rRegionY = (((uint)(cAgentData.RegionHandle)) >> 8);
  3261. uint tRegionX = RegionInfo.RegionLocX;
  3262. uint tRegionY = RegionInfo.RegionLocY;
  3263. //Send Data to ScenePresence
  3264. childAgentUpdate.ChildAgentDataUpdate(cAgentData, tRegionX, tRegionY, rRegionX, rRegionY);
  3265. // Not Implemented:
  3266. //TODO: Do we need to pass the message on to one of our neighbors?
  3267. }
  3268. return true;
  3269. }
  3270. return false;
  3271. }
  3272. protected virtual ScenePresence WaitGetScenePresence(UUID agentID)
  3273. {
  3274. int ntimes = 10;
  3275. ScenePresence childAgentUpdate = null;
  3276. while ((childAgentUpdate = GetScenePresence(agentID)) == null && (ntimes-- > 0))
  3277. Thread.Sleep(1000);
  3278. return childAgentUpdate;
  3279. }
  3280. public virtual bool IncomingRetrieveRootAgent(UUID id, out IAgentData agent)
  3281. {
  3282. agent = null;
  3283. ScenePresence sp = GetScenePresence(id);
  3284. if ((sp != null) && (!sp.IsChildAgent))
  3285. {
  3286. sp.IsChildAgent = true;
  3287. return sp.CopyAgent(out agent);
  3288. }
  3289. return false;
  3290. }
  3291. /// <summary>
  3292. /// Tell a single agent to disconnect from the region.
  3293. /// </summary>
  3294. /// <param name="regionHandle"></param>
  3295. /// <param name="agentID"></param>
  3296. public bool IncomingCloseAgent(UUID agentID)
  3297. {
  3298. //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID);
  3299. ScenePresence presence = m_sceneGraph.GetScenePresence(agentID);
  3300. if (presence != null)
  3301. {
  3302. // Nothing is removed here, so down count it as such
  3303. if (presence.IsChildAgent)
  3304. {
  3305. m_sceneGraph.removeUserCount(false);
  3306. }
  3307. else
  3308. {
  3309. m_sceneGraph.removeUserCount(true);
  3310. }
  3311. // Don't do this to root agents on logout, it's not nice for the viewer
  3312. if (presence.IsChildAgent)
  3313. {
  3314. // Tell a single agent to disconnect from the region.
  3315. IEventQueue eq = RequestModuleInterface<IEventQueue>();
  3316. if (eq != null)
  3317. {
  3318. eq.DisableSimulator(RegionInfo.RegionHandle, agentID);
  3319. }
  3320. else
  3321. presence.ControllingClient.SendShutdownConnectionNotice();
  3322. }
  3323. presence.ControllingClient.Close();
  3324. return true;
  3325. }
  3326. // Agent not here
  3327. return false;
  3328. }
  3329. /// <summary>
  3330. /// Tries to teleport agent to another region.
  3331. /// </summary>
  3332. /// <remarks>
  3333. /// The region name must exactly match that given.
  3334. /// </remarks>
  3335. /// <param name="remoteClient"></param>
  3336. /// <param name="regionName"></param>
  3337. /// <param name="position"></param>
  3338. /// <param name="lookAt"></param>
  3339. /// <param name="teleportFlags"></param>
  3340. public void RequestTeleportLocation(IClientAPI remoteClient, string regionName, Vector3 position,
  3341. Vector3 lookat, uint teleportFlags)
  3342. {
  3343. GridRegion region = GridService.GetRegionByName(RegionInfo.ScopeID, regionName);
  3344. if (region == null)
  3345. {
  3346. // can't find the region: Tell viewer and abort
  3347. remoteClient.SendTeleportFailed("The region '" + regionName + "' could not be found.");
  3348. return;
  3349. }
  3350. RequestTeleportLocation(remoteClient, region.RegionHandle, position, lookat, teleportFlags);
  3351. }
  3352. /// <summary>
  3353. /// Tries to teleport agent to other region.
  3354. /// </summary>
  3355. /// <param name="remoteClient"></param>
  3356. /// <param name="regionHandle"></param>
  3357. /// <param name="position"></param>
  3358. /// <param name="lookAt"></param>
  3359. /// <param name="teleportFlags"></param>
  3360. public void RequestTeleportLocation(IClientAPI remoteClient, ulong regionHandle, Vector3 position,
  3361. Vector3 lookAt, uint teleportFlags)
  3362. {
  3363. ScenePresence sp = GetScenePresence(remoteClient.AgentId);
  3364. if (sp != null)
  3365. {
  3366. uint regionX = m_regInfo.RegionLocX;
  3367. uint regionY = m_regInfo.RegionLocY;
  3368. Utils.LongToUInts(regionHandle, out regionX, out regionY);
  3369. int shiftx = (int) regionX - (int) m_regInfo.RegionLocX * (int)Constants.RegionSize;
  3370. int shifty = (int) regionY - (int) m_regInfo.RegionLocY * (int)Constants.RegionSize;
  3371. position.X += shiftx;
  3372. position.Y += shifty;
  3373. bool result = false;
  3374. if (TestBorderCross(position,Cardinals.N))
  3375. result = true;
  3376. if (TestBorderCross(position, Cardinals.S))
  3377. result = true;
  3378. if (TestBorderCross(position, Cardinals.E))
  3379. result = true;
  3380. if (TestBorderCross(position, Cardinals.W))
  3381. result = true;
  3382. // bordercross if position is outside of region
  3383. if (!result)
  3384. {
  3385. regionHandle = m_regInfo.RegionHandle;
  3386. }
  3387. else
  3388. {
  3389. // not in this region, undo the shift!
  3390. position.X -= shiftx;
  3391. position.Y -= shifty;
  3392. }
  3393. if (m_teleportModule != null)
  3394. m_teleportModule.Teleport(sp, regionHandle, position, lookAt, teleportFlags);
  3395. else
  3396. {
  3397. m_log.DebugFormat("[SCENE]: Unable to perform teleports: no AgentTransferModule is active");
  3398. sp.ControllingClient.SendTeleportFailed("Unable to perform teleports on this simulator.");
  3399. }
  3400. }
  3401. }
  3402. public bool CrossAgentToNewRegion(ScenePresence agent, bool isFlying)
  3403. {
  3404. if (m_teleportModule != null)
  3405. return m_teleportModule.Cross(agent, isFlying);
  3406. else
  3407. {
  3408. m_log.DebugFormat("[SCENE]: Unable to cross agent to neighbouring region, because there is no AgentTransferModule");
  3409. }
  3410. return false;
  3411. }
  3412. public void SendOutChildAgentUpdates(AgentPosition cadu, ScenePresence presence)
  3413. {
  3414. m_sceneGridService.SendChildAgentDataUpdate(cadu, presence);
  3415. }
  3416. #endregion
  3417. #region Other Methods
  3418. protected override IConfigSource GetConfig()
  3419. {
  3420. return m_config;
  3421. }
  3422. #endregion
  3423. public void HandleObjectPermissionsUpdate(IClientAPI controller, UUID agentID, UUID sessionID, byte field, uint localId, uint mask, byte set)
  3424. {
  3425. // Check for spoofing.. since this is permissions we're talking about here!
  3426. if ((controller.SessionId == sessionID) && (controller.AgentId == agentID))
  3427. {
  3428. // Tell the object to do permission update
  3429. if (localId != 0)
  3430. {
  3431. SceneObjectGroup chObjectGroup = GetGroupByPrim(localId);
  3432. if (chObjectGroup != null)
  3433. {
  3434. chObjectGroup.UpdatePermissions(agentID, field, localId, mask, set);
  3435. }
  3436. }
  3437. }
  3438. }
  3439. /// <summary>
  3440. /// Causes all clients to get a full object update on all of the objects in the scene.
  3441. /// </summary>
  3442. public void ForceClientUpdate()
  3443. {
  3444. EntityBase[] entityList = GetEntities();
  3445. foreach (EntityBase ent in entityList)
  3446. {
  3447. if (ent is SceneObjectGroup)
  3448. {
  3449. ((SceneObjectGroup)ent).ScheduleGroupForFullUpdate();
  3450. }
  3451. }
  3452. }
  3453. /// <summary>
  3454. /// This is currently only used for scale (to scale to MegaPrim size)
  3455. /// There is a console command that calls this in OpenSimMain
  3456. /// </summary>
  3457. /// <param name="cmdparams"></param>
  3458. public void HandleEditCommand(string[] cmdparams)
  3459. {
  3460. m_log.Debug("Searching for Primitive: '" + cmdparams[2] + "'");
  3461. EntityBase[] entityList = GetEntities();
  3462. foreach (EntityBase ent in entityList)
  3463. {
  3464. if (ent is SceneObjectGroup)
  3465. {
  3466. SceneObjectPart part = ((SceneObjectGroup)ent).GetChildPart(((SceneObjectGroup)ent).UUID);
  3467. if (part != null)
  3468. {
  3469. if (part.Name == cmdparams[2])
  3470. {
  3471. part.Resize(
  3472. new Vector3(Convert.ToSingle(cmdparams[3]), Convert.ToSingle(cmdparams[4]),
  3473. Convert.ToSingle(cmdparams[5])));
  3474. m_log.Debug("Edited scale of Primitive: " + part.Name);
  3475. }
  3476. }
  3477. }
  3478. }
  3479. }
  3480. public override void Show(string[] showParams)
  3481. {
  3482. base.Show(showParams);
  3483. switch (showParams[0])
  3484. {
  3485. case "users":
  3486. m_log.Error("Current Region: " + RegionInfo.RegionName);
  3487. m_log.ErrorFormat("{0,-16}{1,-16}{2,-25}{3,-25}{4,-16}{5,-16}{6,-16}", "Firstname", "Lastname",
  3488. "Agent ID", "Session ID", "Circuit", "IP", "World");
  3489. ForEachScenePresence(delegate(ScenePresence sp)
  3490. {
  3491. m_log.ErrorFormat("{0,-16}{1,-16}{2,-25}{3,-25}{4,-16},{5,-16}{6,-16}",
  3492. sp.Firstname,
  3493. sp.Lastname,
  3494. sp.UUID,
  3495. sp.ControllingClient.AgentId,
  3496. "Unknown",
  3497. "Unknown",
  3498. RegionInfo.RegionName);
  3499. });
  3500. break;
  3501. }
  3502. }
  3503. #region Script Handling Methods
  3504. /// <summary>
  3505. /// Console command handler to send script command to script engine.
  3506. /// </summary>
  3507. /// <param name="args"></param>
  3508. public void SendCommandToPlugins(string[] args)
  3509. {
  3510. m_eventManager.TriggerOnPluginConsole(args);
  3511. }
  3512. public LandData GetLandData(float x, float y)
  3513. {
  3514. return LandChannel.GetLandObject(x, y).LandData;
  3515. }
  3516. public LandData GetLandData(uint x, uint y)
  3517. {
  3518. m_log.DebugFormat("[SCENE]: returning land for {0},{1}", x, y);
  3519. return LandChannel.GetLandObject((int)x, (int)y).LandData;
  3520. }
  3521. #endregion
  3522. #region Script Engine
  3523. private List<ScriptEngineInterface> ScriptEngines = new List<ScriptEngineInterface>();
  3524. public bool DumpAssetsToFile;
  3525. /// <summary>
  3526. ///
  3527. /// </summary>
  3528. /// <param name="scriptEngine"></param>
  3529. public void AddScriptEngine(ScriptEngineInterface scriptEngine)
  3530. {
  3531. ScriptEngines.Add(scriptEngine);
  3532. scriptEngine.InitializeEngine(this);
  3533. }
  3534. private bool ScriptDanger(SceneObjectPart part,Vector3 pos)
  3535. {
  3536. ILandObject parcel = LandChannel.GetLandObject(pos.X, pos.Y);
  3537. if (part != null)
  3538. {
  3539. if (parcel != null)
  3540. {
  3541. if ((parcel.LandData.Flags & (uint)ParcelFlags.AllowOtherScripts) != 0)
  3542. {
  3543. return true;
  3544. }
  3545. else if ((parcel.LandData.Flags & (uint)ParcelFlags.AllowGroupScripts) != 0)
  3546. {
  3547. if (part.OwnerID == parcel.LandData.OwnerID
  3548. || (parcel.LandData.IsGroupOwned && part.GroupID == parcel.LandData.GroupID)
  3549. || Permissions.IsGod(part.OwnerID))
  3550. {
  3551. return true;
  3552. }
  3553. else
  3554. {
  3555. return false;
  3556. }
  3557. }
  3558. else
  3559. {
  3560. if (part.OwnerID == parcel.LandData.OwnerID)
  3561. {
  3562. return true;
  3563. }
  3564. else
  3565. {
  3566. return false;
  3567. }
  3568. }
  3569. }
  3570. else
  3571. {
  3572. if (pos.X > 0f && pos.X < Constants.RegionSize && pos.Y > 0f && pos.Y < Constants.RegionSize)
  3573. {
  3574. // The only time parcel != null when an object is inside a region is when
  3575. // there is nothing behind the landchannel. IE, no land plugin loaded.
  3576. return true;
  3577. }
  3578. else
  3579. {
  3580. // The object is outside of this region. Stop piping events to it.
  3581. return false;
  3582. }
  3583. }
  3584. }
  3585. else
  3586. {
  3587. return false;
  3588. }
  3589. }
  3590. public bool ScriptDanger(uint localID, Vector3 pos)
  3591. {
  3592. SceneObjectPart part = GetSceneObjectPart(localID);
  3593. if (part != null)
  3594. {
  3595. return ScriptDanger(part, pos);
  3596. }
  3597. else
  3598. {
  3599. return false;
  3600. }
  3601. }
  3602. public bool PipeEventsForScript(uint localID)
  3603. {
  3604. SceneObjectPart part = GetSceneObjectPart(localID);
  3605. if (part != null)
  3606. {
  3607. // Changed so that child prims of attachments return ScriptDanger for their parent, so that
  3608. // their scripts will actually run.
  3609. // -- Leaf, Tue Aug 12 14:17:05 EDT 2008
  3610. SceneObjectPart parent = part.ParentGroup.RootPart;
  3611. if (part.ParentGroup.IsAttachment)
  3612. return ScriptDanger(parent, parent.GetWorldPosition());
  3613. else
  3614. return ScriptDanger(part, part.GetWorldPosition());
  3615. }
  3616. else
  3617. {
  3618. return false;
  3619. }
  3620. }
  3621. #endregion
  3622. #region SceneGraph wrapper methods
  3623. /// <summary>
  3624. ///
  3625. /// </summary>
  3626. /// <param name="localID"></param>
  3627. /// <returns></returns>
  3628. public UUID ConvertLocalIDToFullID(uint localID)
  3629. {
  3630. return m_sceneGraph.ConvertLocalIDToFullID(localID);
  3631. }
  3632. public void SwapRootAgentCount(bool rootChildChildRootTF)
  3633. {
  3634. m_sceneGraph.SwapRootChildAgent(rootChildChildRootTF);
  3635. }
  3636. public void AddPhysicalPrim(int num)
  3637. {
  3638. m_sceneGraph.AddPhysicalPrim(num);
  3639. }
  3640. public void RemovePhysicalPrim(int num)
  3641. {
  3642. m_sceneGraph.RemovePhysicalPrim(num);
  3643. }
  3644. public int GetRootAgentCount()
  3645. {
  3646. return m_sceneGraph.GetRootAgentCount();
  3647. }
  3648. public int GetChildAgentCount()
  3649. {
  3650. return m_sceneGraph.GetChildAgentCount();
  3651. }
  3652. /// <summary>
  3653. /// Request a scene presence by UUID. Fast, indexed lookup.
  3654. /// </summary>
  3655. /// <param name="agentID"></param>
  3656. /// <returns>null if the presence was not found</returns>
  3657. public ScenePresence GetScenePresence(UUID agentID)
  3658. {
  3659. return m_sceneGraph.GetScenePresence(agentID);
  3660. }
  3661. /// <summary>
  3662. /// Request the scene presence by name.
  3663. /// </summary>
  3664. /// <param name="firstName"></param>
  3665. /// <param name="lastName"></param>
  3666. /// <returns>null if the presence was not found</returns>
  3667. public ScenePresence GetScenePresence(string firstName, string lastName)
  3668. {
  3669. return m_sceneGraph.GetScenePresence(firstName, lastName);
  3670. }
  3671. /// <summary>
  3672. /// Request the scene presence by localID.
  3673. /// </summary>
  3674. /// <param name="localID"></param>
  3675. /// <returns>null if the presence was not found</returns>
  3676. public ScenePresence GetScenePresence(uint localID)
  3677. {
  3678. return m_sceneGraph.GetScenePresence(localID);
  3679. }
  3680. public override bool PresenceChildStatus(UUID avatarID)
  3681. {
  3682. ScenePresence cp = GetScenePresence(avatarID);
  3683. // FIXME: This is really crap - some logout code is relying on a NullReferenceException to halt its processing
  3684. // This needs to be fixed properly by cleaning up the logout code.
  3685. //if (cp != null)
  3686. // return cp.IsChildAgent;
  3687. //return false;
  3688. return cp.IsChildAgent;
  3689. }
  3690. /// <summary>
  3691. /// Performs action on all scene presences.
  3692. /// </summary>
  3693. /// <param name="action"></param>
  3694. public void ForEachScenePresence(Action<ScenePresence> action)
  3695. {
  3696. if (m_sceneGraph != null)
  3697. {
  3698. m_sceneGraph.ForEachScenePresence(action);
  3699. }
  3700. }
  3701. /// <summary>
  3702. /// Perform the given action for each object
  3703. /// </summary>
  3704. /// <param name="action"></param>
  3705. // public void ForEachObject(Action<SceneObjectGroup> action)
  3706. // {
  3707. // List<SceneObjectGroup> presenceList;
  3708. //
  3709. // lock (m_sceneObjects)
  3710. // {
  3711. // presenceList = new List<SceneObjectGroup>(m_sceneObjects.Values);
  3712. // }
  3713. //
  3714. // foreach (SceneObjectGroup presence in presenceList)
  3715. // {
  3716. // action(presence);
  3717. // }
  3718. // }
  3719. /// <summary>
  3720. /// Get a group via its UUID
  3721. /// </summary>
  3722. /// <param name="fullID"></param>
  3723. /// <returns>null if no group with that name exists</returns>
  3724. public SceneObjectGroup GetSceneObjectGroup(UUID fullID)
  3725. {
  3726. return m_sceneGraph.GetSceneObjectGroup(fullID);
  3727. }
  3728. /// <summary>
  3729. /// Get a group by name from the scene (will return the first
  3730. /// found, if there are more than one prim with the same name)
  3731. /// </summary>
  3732. /// <param name="name"></param>
  3733. /// <returns>null if no group with that name exists</returns>
  3734. public SceneObjectGroup GetSceneObjectGroup(string name)
  3735. {
  3736. return m_sceneGraph.GetSceneObjectGroup(name);
  3737. }
  3738. /// <summary>
  3739. /// Get a prim by name from the scene (will return the first
  3740. /// found, if there are more than one prim with the same name)
  3741. /// </summary>
  3742. /// <param name="name"></param>
  3743. /// <returns></returns>
  3744. public SceneObjectPart GetSceneObjectPart(string name)
  3745. {
  3746. return m_sceneGraph.GetSceneObjectPart(name);
  3747. }
  3748. /// <summary>
  3749. /// Get a prim via its local id
  3750. /// </summary>
  3751. /// <param name="localID"></param>
  3752. /// <returns></returns>
  3753. public SceneObjectPart GetSceneObjectPart(uint localID)
  3754. {
  3755. return m_sceneGraph.GetSceneObjectPart(localID);
  3756. }
  3757. /// <summary>
  3758. /// Get a prim via its UUID
  3759. /// </summary>
  3760. /// <param name="fullID"></param>
  3761. /// <returns></returns>
  3762. public SceneObjectPart GetSceneObjectPart(UUID fullID)
  3763. {
  3764. return m_sceneGraph.GetSceneObjectPart(fullID);
  3765. }
  3766. /// <summary>
  3767. /// Get a scene object group that contains the prim with the given local id
  3768. /// </summary>
  3769. /// <param name="localID"></param>
  3770. /// <returns>null if no scene object group containing that prim is found</returns>
  3771. public SceneObjectGroup GetGroupByPrim(uint localID)
  3772. {
  3773. return m_sceneGraph.GetGroupByPrim(localID);
  3774. }
  3775. public override bool TryGetScenePresence(UUID avatarId, out ScenePresence avatar)
  3776. {
  3777. return m_sceneGraph.TryGetScenePresence(avatarId, out avatar);
  3778. }
  3779. public bool TryGetAvatarByName(string avatarName, out ScenePresence avatar)
  3780. {
  3781. return m_sceneGraph.TryGetAvatarByName(avatarName, out avatar);
  3782. }
  3783. public void ForEachClient(Action<IClientAPI> action)
  3784. {
  3785. m_clientManager.ForEachSync(action);
  3786. }
  3787. public bool TryGetClient(UUID avatarID, out IClientAPI client)
  3788. {
  3789. return m_clientManager.TryGetValue(avatarID, out client);
  3790. }
  3791. public bool TryGetClient(System.Net.IPEndPoint remoteEndPoint, out IClientAPI client)
  3792. {
  3793. return m_clientManager.TryGetValue(remoteEndPoint, out client);
  3794. }
  3795. public void ForEachSOG(Action<SceneObjectGroup> action)
  3796. {
  3797. m_sceneGraph.ForEachSOG(action);
  3798. }
  3799. /// <summary>
  3800. /// Returns a list of the entities in the scene. This is a new list so operations perform on the list itself
  3801. /// will not affect the original list of objects in the scene.
  3802. /// </summary>
  3803. /// <returns></returns>
  3804. public EntityBase[] GetEntities()
  3805. {
  3806. return m_sceneGraph.GetEntities();
  3807. }
  3808. #endregion
  3809. public void RegionHandleRequest(IClientAPI client, UUID regionID)
  3810. {
  3811. ulong handle = 0;
  3812. if (regionID == RegionInfo.RegionID)
  3813. handle = RegionInfo.RegionHandle;
  3814. else
  3815. {
  3816. GridRegion r = GridService.GetRegionByUUID(UUID.Zero, regionID);
  3817. if (r != null)
  3818. handle = r.RegionHandle;
  3819. }
  3820. if (handle != 0)
  3821. client.SendRegionHandle(regionID, handle);
  3822. }
  3823. public bool NeedSceneCacheClear(UUID agentID)
  3824. {
  3825. IInventoryTransferModule inv = RequestModuleInterface<IInventoryTransferModule>();
  3826. if (inv == null)
  3827. return true;
  3828. return inv.NeedSceneCacheClear(agentID, this);
  3829. }
  3830. public void CleanTempObjects()
  3831. {
  3832. EntityBase[] entities = GetEntities();
  3833. foreach (EntityBase obj in entities)
  3834. {
  3835. if (obj is SceneObjectGroup)
  3836. {
  3837. SceneObjectGroup grp = (SceneObjectGroup)obj;
  3838. if (!grp.IsDeleted)
  3839. {
  3840. if ((grp.RootPart.Flags & PrimFlags.TemporaryOnRez) != 0)
  3841. {
  3842. if (grp.RootPart.Expires <= DateTime.Now)
  3843. DeleteSceneObject(grp, false);
  3844. }
  3845. }
  3846. }
  3847. }
  3848. }
  3849. public void DeleteFromStorage(UUID uuid)
  3850. {
  3851. SimulationDataService.RemoveObject(uuid, m_regInfo.RegionID);
  3852. }
  3853. public int GetHealth()
  3854. {
  3855. // Returns:
  3856. // 1 = sim is up and accepting http requests. The heartbeat has
  3857. // stopped and the sim is probably locked up, but a remote
  3858. // admin restart may succeed
  3859. //
  3860. // 2 = Sim is up and the heartbeat is running. The sim is likely
  3861. // usable for people within and logins _may_ work
  3862. //
  3863. // 3 = We have seen a new user enter within the past 4 minutes
  3864. // which can be seen as positive confirmation of sim health
  3865. //
  3866. int health=1; // Start at 1, means we're up
  3867. if ((Util.EnvironmentTickCountSubtract(m_lastUpdate)) < 1000)
  3868. health+=1;
  3869. else
  3870. return health;
  3871. // A login in the last 4 mins? We can't be doing too badly
  3872. //
  3873. if ((Util.EnvironmentTickCountSubtract(m_LastLogin)) < 240000)
  3874. health++;
  3875. else
  3876. return health;
  3877. CheckHeartbeat();
  3878. return health;
  3879. }
  3880. // This callback allows the PhysicsScene to call back to its caller (the SceneGraph) and
  3881. // update non-physical objects like the joint proxy objects that represent the position
  3882. // of the joints in the scene.
  3883. // This routine is normally called from within a lock (OdeLock) from within the OdePhysicsScene
  3884. // WARNING: be careful of deadlocks here if you manipulate the scene. Remember you are being called
  3885. // from within the OdePhysicsScene.
  3886. protected internal void jointMoved(PhysicsJoint joint)
  3887. {
  3888. // m_parentScene.PhysicsScene.DumpJointInfo(); // non-thread-locked version; we should already be in a lock (OdeLock) when this callback is invoked
  3889. SceneObjectPart jointProxyObject = GetSceneObjectPart(joint.ObjectNameInScene);
  3890. if (jointProxyObject == null)
  3891. {
  3892. jointErrorMessage(joint, "WARNING, joint proxy not found, name " + joint.ObjectNameInScene);
  3893. return;
  3894. }
  3895. // now update the joint proxy object in the scene to have the position of the joint as returned by the physics engine
  3896. SceneObjectPart trackedBody = GetSceneObjectPart(joint.TrackedBodyName); // FIXME: causes a sequential lookup
  3897. if (trackedBody == null) return; // the actor may have been deleted but the joint still lingers around a few frames waiting for deletion. during this time, trackedBody is NULL to prevent further motion of the joint proxy.
  3898. jointProxyObject.Velocity = trackedBody.Velocity;
  3899. jointProxyObject.AngularVelocity = trackedBody.AngularVelocity;
  3900. switch (joint.Type)
  3901. {
  3902. case PhysicsJointType.Ball:
  3903. {
  3904. Vector3 jointAnchor = PhysicsScene.GetJointAnchor(joint);
  3905. Vector3 proxyPos = new Vector3(jointAnchor.X, jointAnchor.Y, jointAnchor.Z);
  3906. jointProxyObject.ParentGroup.UpdateGroupPosition(proxyPos); // schedules the entire group for a terse update
  3907. }
  3908. break;
  3909. case PhysicsJointType.Hinge:
  3910. {
  3911. Vector3 jointAnchor = PhysicsScene.GetJointAnchor(joint);
  3912. // Normally, we would just ask the physics scene to return the axis for the joint.
  3913. // Unfortunately, ODE sometimes returns <0,0,0> for the joint axis, which should
  3914. // never occur. Therefore we cannot rely on ODE to always return a correct joint axis.
  3915. // Therefore the following call does not always work:
  3916. //PhysicsVector phyJointAxis = _PhyScene.GetJointAxis(joint);
  3917. // instead we compute the joint orientation by saving the original joint orientation
  3918. // relative to one of the jointed bodies, and applying this transformation
  3919. // to the current position of the jointed bodies (the tracked body) to compute the
  3920. // current joint orientation.
  3921. if (joint.TrackedBodyName == null)
  3922. {
  3923. jointErrorMessage(joint, "joint.TrackedBodyName is null, joint " + joint.ObjectNameInScene);
  3924. }
  3925. Vector3 proxyPos = new Vector3(jointAnchor.X, jointAnchor.Y, jointAnchor.Z);
  3926. Quaternion q = trackedBody.RotationOffset * joint.LocalRotation;
  3927. jointProxyObject.ParentGroup.UpdateGroupPosition(proxyPos); // schedules the entire group for a terse update
  3928. jointProxyObject.ParentGroup.UpdateGroupRotationR(q); // schedules the entire group for a terse update
  3929. }
  3930. break;
  3931. }
  3932. }
  3933. // This callback allows the PhysicsScene to call back to its caller (the SceneGraph) and
  3934. // update non-physical objects like the joint proxy objects that represent the position
  3935. // of the joints in the scene.
  3936. // This routine is normally called from within a lock (OdeLock) from within the OdePhysicsScene
  3937. // WARNING: be careful of deadlocks here if you manipulate the scene. Remember you are being called
  3938. // from within the OdePhysicsScene.
  3939. protected internal void jointDeactivated(PhysicsJoint joint)
  3940. {
  3941. //m_log.Debug("[NINJA] SceneGraph.jointDeactivated, joint:" + joint.ObjectNameInScene);
  3942. SceneObjectPart jointProxyObject = GetSceneObjectPart(joint.ObjectNameInScene);
  3943. if (jointProxyObject == null)
  3944. {
  3945. jointErrorMessage(joint, "WARNING, trying to deactivate (stop interpolation of) joint proxy, but not found, name " + joint.ObjectNameInScene);
  3946. return;
  3947. }
  3948. // turn the proxy non-physical, which also stops its client-side interpolation
  3949. bool wasUsingPhysics = ((jointProxyObject.Flags & PrimFlags.Physics) != 0);
  3950. if (wasUsingPhysics)
  3951. {
  3952. jointProxyObject.UpdatePrimFlags(false, false, true, false); // FIXME: possible deadlock here; check to make sure all the scene alterations set into motion here won't deadlock
  3953. }
  3954. }
  3955. // This callback allows the PhysicsScene to call back to its caller (the SceneGraph) and
  3956. // alert the user of errors by using the debug channel in the same way that scripts alert
  3957. // the user of compile errors.
  3958. // This routine is normally called from within a lock (OdeLock) from within the OdePhysicsScene
  3959. // WARNING: be careful of deadlocks here if you manipulate the scene. Remember you are being called
  3960. // from within the OdePhysicsScene.
  3961. public void jointErrorMessage(PhysicsJoint joint, string message)
  3962. {
  3963. if (joint != null)
  3964. {
  3965. if (joint.ErrorMessageCount > PhysicsJoint.maxErrorMessages)
  3966. return;
  3967. SceneObjectPart jointProxyObject = GetSceneObjectPart(joint.ObjectNameInScene);
  3968. if (jointProxyObject != null)
  3969. {
  3970. SimChat(Utils.StringToBytes("[NINJA]: " + message),
  3971. ChatTypeEnum.DebugChannel,
  3972. 2147483647,
  3973. jointProxyObject.AbsolutePosition,
  3974. jointProxyObject.Name,
  3975. jointProxyObject.UUID,
  3976. false);
  3977. joint.ErrorMessageCount++;
  3978. if (joint.ErrorMessageCount > PhysicsJoint.maxErrorMessages)
  3979. {
  3980. SimChat(Utils.StringToBytes("[NINJA]: Too many messages for this joint, suppressing further messages."),
  3981. ChatTypeEnum.DebugChannel,
  3982. 2147483647,
  3983. jointProxyObject.AbsolutePosition,
  3984. jointProxyObject.Name,
  3985. jointProxyObject.UUID,
  3986. false);
  3987. }
  3988. }
  3989. else
  3990. {
  3991. // couldn't find the joint proxy object; the error message is silently suppressed
  3992. }
  3993. }
  3994. }
  3995. public Scene ConsoleScene()
  3996. {
  3997. if (MainConsole.Instance == null)
  3998. return null;
  3999. if (MainConsole.Instance.ConsoleScene is Scene)
  4000. return (Scene)MainConsole.Instance.ConsoleScene;
  4001. return null;
  4002. }
  4003. public float GetGroundHeight(float x, float y)
  4004. {
  4005. if (x < 0)
  4006. x = 0;
  4007. if (x >= Heightmap.Width)
  4008. x = Heightmap.Width - 1;
  4009. if (y < 0)
  4010. y = 0;
  4011. if (y >= Heightmap.Height)
  4012. y = Heightmap.Height - 1;
  4013. Vector3 p0 = new Vector3(x, y, (float)Heightmap[(int)x, (int)y]);
  4014. Vector3 p1 = new Vector3(p0);
  4015. Vector3 p2 = new Vector3(p0);
  4016. p1.X += 1.0f;
  4017. if (p1.X < Heightmap.Width)
  4018. p1.Z = (float)Heightmap[(int)p1.X, (int)p1.Y];
  4019. p2.Y += 1.0f;
  4020. if (p2.Y < Heightmap.Height)
  4021. p2.Z = (float)Heightmap[(int)p2.X, (int)p2.Y];
  4022. Vector3 v0 = new Vector3(p1.X - p0.X, p1.Y - p0.Y, p1.Z - p0.Z);
  4023. Vector3 v1 = new Vector3(p2.X - p0.X, p2.Y - p0.Y, p2.Z - p0.Z);
  4024. v0.Normalize();
  4025. v1.Normalize();
  4026. Vector3 vsn = new Vector3();
  4027. vsn.X = (v0.Y * v1.Z) - (v0.Z * v1.Y);
  4028. vsn.Y = (v0.Z * v1.X) - (v0.X * v1.Z);
  4029. vsn.Z = (v0.X * v1.Y) - (v0.Y * v1.X);
  4030. vsn.Normalize();
  4031. float xdiff = x - (float)((int)x);
  4032. float ydiff = y - (float)((int)y);
  4033. return (((vsn.X * xdiff) + (vsn.Y * ydiff)) / (-1 * vsn.Z)) + p0.Z;
  4034. }
  4035. private void CheckHeartbeat()
  4036. {
  4037. if (m_firstHeartbeat)
  4038. return;
  4039. if (Util.EnvironmentTickCountSubtract(m_lastUpdate) > 2000)
  4040. StartTimer();
  4041. }
  4042. public override ISceneObject DeserializeObject(string representation)
  4043. {
  4044. return SceneObjectSerializer.FromXml2Format(representation);
  4045. }
  4046. public override bool AllowScriptCrossings
  4047. {
  4048. get { return m_allowScriptCrossings; }
  4049. }
  4050. public Vector3? GetNearestAllowedPosition(ScenePresence avatar)
  4051. {
  4052. //simulate to make sure we have pretty up to date positions
  4053. PhysicsScene.Simulate(0);
  4054. ILandObject nearestParcel = GetNearestAllowedParcel(avatar.UUID, avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
  4055. if (nearestParcel != null)
  4056. {
  4057. Vector3 dir = Vector3.Normalize(Vector3.Multiply(avatar.Velocity, -1));
  4058. //Try to get a location that feels like where they came from
  4059. Vector3? nearestPoint = GetNearestPointInParcelAlongDirectionFromPoint(avatar.AbsolutePosition, dir, nearestParcel);
  4060. if (nearestPoint != null)
  4061. {
  4062. Debug.WriteLine("Found a sane previous position based on velocity, sending them to: " + nearestPoint.ToString());
  4063. return nearestPoint.Value;
  4064. }
  4065. //Sometimes velocity might be zero (local teleport), so try finding point along path from avatar to center of nearest parcel
  4066. Vector3 directionToParcelCenter = Vector3.Subtract(GetParcelCenterAtGround(nearestParcel), avatar.AbsolutePosition);
  4067. dir = Vector3.Normalize(directionToParcelCenter);
  4068. nearestPoint = GetNearestPointInParcelAlongDirectionFromPoint(avatar.AbsolutePosition, dir, nearestParcel);
  4069. if (nearestPoint != null)
  4070. {
  4071. Debug.WriteLine("They had a zero velocity, sending them to: " + nearestPoint.ToString());
  4072. return nearestPoint.Value;
  4073. }
  4074. //Ultimate backup if we have no idea where they are
  4075. Debug.WriteLine("Have no idea where they are, sending them to: " + avatar.lastKnownAllowedPosition.ToString());
  4076. return avatar.lastKnownAllowedPosition;
  4077. }
  4078. //Go to the edge, this happens in teleporting to a region with no available parcels
  4079. Vector3 nearestRegionEdgePoint = GetNearestRegionEdgePosition(avatar);
  4080. //Debug.WriteLine("They are really in a place they don't belong, sending them to: " + nearestRegionEdgePoint.ToString());
  4081. return nearestRegionEdgePoint;
  4082. }
  4083. private Vector3 GetParcelCenterAtGround(ILandObject parcel)
  4084. {
  4085. Vector2 center = GetParcelCenter(parcel);
  4086. return GetPositionAtGround(center.X, center.Y);
  4087. }
  4088. private Vector3? GetNearestPointInParcelAlongDirectionFromPoint(Vector3 pos, Vector3 direction, ILandObject parcel)
  4089. {
  4090. Vector3 unitDirection = Vector3.Normalize(direction);
  4091. //Making distance to search go through some sane limit of distance
  4092. for (float distance = 0; distance < Constants.RegionSize * 2; distance += .5f)
  4093. {
  4094. Vector3 testPos = Vector3.Add(pos, Vector3.Multiply(unitDirection, distance));
  4095. if (parcel.ContainsPoint((int)testPos.X, (int)testPos.Y))
  4096. {
  4097. return testPos;
  4098. }
  4099. }
  4100. return null;
  4101. }
  4102. public ILandObject GetNearestAllowedParcel(UUID avatarId, float x, float y)
  4103. {
  4104. List<ILandObject> all = AllParcels();
  4105. float minParcelDistance = float.MaxValue;
  4106. ILandObject nearestParcel = null;
  4107. foreach (var parcel in all)
  4108. {
  4109. if (!parcel.IsEitherBannedOrRestricted(avatarId))
  4110. {
  4111. float parcelDistance = GetParcelDistancefromPoint(parcel, x, y);
  4112. if (parcelDistance < minParcelDistance)
  4113. {
  4114. minParcelDistance = parcelDistance;
  4115. nearestParcel = parcel;
  4116. }
  4117. }
  4118. }
  4119. return nearestParcel;
  4120. }
  4121. private List<ILandObject> AllParcels()
  4122. {
  4123. return LandChannel.AllParcels();
  4124. }
  4125. private float GetParcelDistancefromPoint(ILandObject parcel, float x, float y)
  4126. {
  4127. return Vector2.Distance(new Vector2(x, y), GetParcelCenter(parcel));
  4128. }
  4129. //calculate the average center point of a parcel
  4130. private Vector2 GetParcelCenter(ILandObject parcel)
  4131. {
  4132. int count = 0;
  4133. int avgx = 0;
  4134. int avgy = 0;
  4135. for (int x = 0; x < Constants.RegionSize; x++)
  4136. {
  4137. for (int y = 0; y < Constants.RegionSize; y++)
  4138. {
  4139. //Just keep a running average as we check if all the points are inside or not
  4140. if (parcel.ContainsPoint(x, y))
  4141. {
  4142. if (count == 0)
  4143. {
  4144. avgx = x;
  4145. avgy = y;
  4146. }
  4147. else
  4148. {
  4149. avgx = (avgx * count + x) / (count + 1);
  4150. avgy = (avgy * count + y) / (count + 1);
  4151. }
  4152. count += 1;
  4153. }
  4154. }
  4155. }
  4156. return new Vector2(avgx, avgy);
  4157. }
  4158. private Vector3 GetNearestRegionEdgePosition(ScenePresence avatar)
  4159. {
  4160. float xdistance = avatar.AbsolutePosition.X < Constants.RegionSize / 2 ? avatar.AbsolutePosition.X : Constants.RegionSize - avatar.AbsolutePosition.X;
  4161. float ydistance = avatar.AbsolutePosition.Y < Constants.RegionSize / 2 ? avatar.AbsolutePosition.Y : Constants.RegionSize - avatar.AbsolutePosition.Y;
  4162. //find out what vertical edge to go to
  4163. if (xdistance < ydistance)
  4164. {
  4165. if (avatar.AbsolutePosition.X < Constants.RegionSize / 2)
  4166. {
  4167. return GetPositionAtAvatarHeightOrGroundHeight(avatar, 0.0f, avatar.AbsolutePosition.Y);
  4168. }
  4169. else
  4170. {
  4171. return GetPositionAtAvatarHeightOrGroundHeight(avatar, Constants.RegionSize, avatar.AbsolutePosition.Y);
  4172. }
  4173. }
  4174. //find out what horizontal edge to go to
  4175. else
  4176. {
  4177. if (avatar.AbsolutePosition.Y < Constants.RegionSize / 2)
  4178. {
  4179. return GetPositionAtAvatarHeightOrGroundHeight(avatar, avatar.AbsolutePosition.X, 0.0f);
  4180. }
  4181. else
  4182. {
  4183. return GetPositionAtAvatarHeightOrGroundHeight(avatar, avatar.AbsolutePosition.X, Constants.RegionSize);
  4184. }
  4185. }
  4186. }
  4187. private Vector3 GetPositionAtAvatarHeightOrGroundHeight(ScenePresence avatar, float x, float y)
  4188. {
  4189. Vector3 ground = GetPositionAtGround(x, y);
  4190. if (avatar.AbsolutePosition.Z > ground.Z)
  4191. {
  4192. ground.Z = avatar.AbsolutePosition.Z;
  4193. }
  4194. return ground;
  4195. }
  4196. private Vector3 GetPositionAtGround(float x, float y)
  4197. {
  4198. return new Vector3(x, y, GetGroundHeight(x, y));
  4199. }
  4200. public List<UUID> GetEstateRegions(int estateID)
  4201. {
  4202. IEstateDataService estateDataService = EstateDataService;
  4203. if (estateDataService == null)
  4204. return new List<UUID>(0);
  4205. return estateDataService.GetRegions(estateID);
  4206. }
  4207. public void ReloadEstateData()
  4208. {
  4209. IEstateDataService estateDataService = EstateDataService;
  4210. if (estateDataService != null)
  4211. {
  4212. m_regInfo.EstateSettings = estateDataService.LoadEstateSettings(m_regInfo.RegionID, false);
  4213. TriggerEstateSunUpdate();
  4214. }
  4215. }
  4216. public void TriggerEstateSunUpdate()
  4217. {
  4218. float sun;
  4219. if (RegionInfo.RegionSettings.UseEstateSun)
  4220. {
  4221. sun = (float)RegionInfo.EstateSettings.SunPosition;
  4222. if (RegionInfo.EstateSettings.UseGlobalTime)
  4223. {
  4224. sun = EventManager.GetCurrentTimeAsSunLindenHour() - 6.0f;
  4225. }
  4226. //
  4227. EventManager.TriggerEstateToolsSunUpdate(
  4228. RegionInfo.RegionHandle,
  4229. RegionInfo.EstateSettings.FixedSun,
  4230. RegionInfo.RegionSettings.UseEstateSun,
  4231. sun);
  4232. }
  4233. else
  4234. {
  4235. // Use the Sun Position from the Region Settings
  4236. sun = (float)RegionInfo.RegionSettings.SunPosition - 6.0f;
  4237. EventManager.TriggerEstateToolsSunUpdate(
  4238. RegionInfo.RegionHandle,
  4239. RegionInfo.RegionSettings.FixedSun,
  4240. RegionInfo.RegionSettings.UseEstateSun,
  4241. sun);
  4242. }
  4243. }
  4244. private void HandleDeleteObject(string module, string[] cmd)
  4245. {
  4246. if (cmd.Length < 3)
  4247. return;
  4248. string mode = cmd[2];
  4249. string o = "";
  4250. if (mode != "outside")
  4251. {
  4252. if (cmd.Length < 4)
  4253. return;
  4254. o = cmd[3];
  4255. }
  4256. List<SceneObjectGroup> deletes = new List<SceneObjectGroup>();
  4257. UUID match;
  4258. switch (mode)
  4259. {
  4260. case "owner":
  4261. if (!UUID.TryParse(o, out match))
  4262. return;
  4263. ForEachSOG(delegate (SceneObjectGroup g)
  4264. {
  4265. if (g.OwnerID == match && !g.IsAttachment)
  4266. deletes.Add(g);
  4267. });
  4268. break;
  4269. case "creator":
  4270. if (!UUID.TryParse(o, out match))
  4271. return;
  4272. ForEachSOG(delegate (SceneObjectGroup g)
  4273. {
  4274. if (g.RootPart.CreatorID == match && !g.IsAttachment)
  4275. deletes.Add(g);
  4276. });
  4277. break;
  4278. case "uuid":
  4279. if (!UUID.TryParse(o, out match))
  4280. return;
  4281. ForEachSOG(delegate (SceneObjectGroup g)
  4282. {
  4283. if (g.UUID == match && !g.IsAttachment)
  4284. deletes.Add(g);
  4285. });
  4286. break;
  4287. case "name":
  4288. ForEachSOG(delegate (SceneObjectGroup g)
  4289. {
  4290. if (g.RootPart.Name == o && !g.IsAttachment)
  4291. deletes.Add(g);
  4292. });
  4293. break;
  4294. case "outside":
  4295. ForEachSOG(delegate (SceneObjectGroup g)
  4296. {
  4297. SceneObjectPart rootPart = g.RootPart;
  4298. bool delete = false;
  4299. if (rootPart.GroupPosition.Z < 0.0 || rootPart.GroupPosition.Z > 10000.0)
  4300. {
  4301. delete = true;
  4302. }
  4303. else
  4304. {
  4305. ILandObject parcel = LandChannel.GetLandObject(rootPart.GroupPosition.X, rootPart.GroupPosition.Y);
  4306. if (parcel == null || parcel.LandData.Name == "NO LAND")
  4307. delete = true;
  4308. }
  4309. if (delete && !g.IsAttachment && !deletes.Contains(g))
  4310. deletes.Add(g);
  4311. });
  4312. break;
  4313. }
  4314. foreach (SceneObjectGroup g in deletes)
  4315. {
  4316. m_log.InfoFormat("[SCENE]: Deleting object {0}", g.UUID);
  4317. DeleteSceneObject(g, false);
  4318. }
  4319. }
  4320. private void HandleReloadEstate(string module, string[] cmd)
  4321. {
  4322. if (MainConsole.Instance.ConsoleScene == null ||
  4323. (MainConsole.Instance.ConsoleScene is Scene &&
  4324. (Scene)MainConsole.Instance.ConsoleScene == this))
  4325. {
  4326. ReloadEstateData();
  4327. }
  4328. }
  4329. /// <summary>
  4330. /// Get the volume of space that will encompass all the given objects.
  4331. /// </summary>
  4332. /// <param name="objects"></param>
  4333. /// <param name="minX"></param>
  4334. /// <param name="maxX"></param>
  4335. /// <param name="minY"></param>
  4336. /// <param name="maxY"></param>
  4337. /// <param name="minZ"></param>
  4338. /// <param name="maxZ"></param>
  4339. /// <returns></returns>
  4340. public static Vector3[] GetCombinedBoundingBox(
  4341. List<SceneObjectGroup> objects,
  4342. out float minX, out float maxX, out float minY, out float maxY, out float minZ, out float maxZ)
  4343. {
  4344. minX = 256;
  4345. maxX = -256;
  4346. minY = 256;
  4347. maxY = -256;
  4348. minZ = 8192;
  4349. maxZ = -256;
  4350. List<Vector3> offsets = new List<Vector3>();
  4351. foreach (SceneObjectGroup g in objects)
  4352. {
  4353. float ominX, ominY, ominZ, omaxX, omaxY, omaxZ;
  4354. Vector3 vec = g.AbsolutePosition;
  4355. g.GetAxisAlignedBoundingBoxRaw(out ominX, out omaxX, out ominY, out omaxY, out ominZ, out omaxZ);
  4356. // m_log.DebugFormat(
  4357. // "[SCENE]: For {0} found AxisAlignedBoundingBoxRaw {1}, {2}",
  4358. // g.Name, new Vector3(ominX, ominY, ominZ), new Vector3(omaxX, omaxY, omaxZ));
  4359. ominX += vec.X;
  4360. omaxX += vec.X;
  4361. ominY += vec.Y;
  4362. omaxY += vec.Y;
  4363. ominZ += vec.Z;
  4364. omaxZ += vec.Z;
  4365. if (minX > ominX)
  4366. minX = ominX;
  4367. if (minY > ominY)
  4368. minY = ominY;
  4369. if (minZ > ominZ)
  4370. minZ = ominZ;
  4371. if (maxX < omaxX)
  4372. maxX = omaxX;
  4373. if (maxY < omaxY)
  4374. maxY = omaxY;
  4375. if (maxZ < omaxZ)
  4376. maxZ = omaxZ;
  4377. }
  4378. foreach (SceneObjectGroup g in objects)
  4379. {
  4380. Vector3 vec = g.AbsolutePosition;
  4381. vec.X -= minX;
  4382. vec.Y -= minY;
  4383. vec.Z -= minZ;
  4384. offsets.Add(vec);
  4385. }
  4386. return offsets.ToArray();
  4387. }
  4388. public void RegenerateMaptile(object sender, ElapsedEventArgs e)
  4389. {
  4390. IWorldMapModule mapModule = RequestModuleInterface<IWorldMapModule>();
  4391. if (mapModule != null)
  4392. {
  4393. mapModule.GenerateMaptile();
  4394. string error = GridService.RegisterRegion(RegionInfo.ScopeID, new GridRegion(RegionInfo));
  4395. if (error != String.Empty)
  4396. throw new Exception(error);
  4397. }
  4398. }
  4399. // public void CleanDroppedAttachments()
  4400. // {
  4401. // List<SceneObjectGroup> objectsToDelete =
  4402. // new List<SceneObjectGroup>();
  4403. //
  4404. // lock (m_cleaningAttachments)
  4405. // {
  4406. // ForEachSOG(delegate (SceneObjectGroup grp)
  4407. // {
  4408. // if (grp.RootPart.Shape.PCode == 0 && grp.RootPart.Shape.State != 0 && (!objectsToDelete.Contains(grp)))
  4409. // {
  4410. // UUID agentID = grp.OwnerID;
  4411. // if (agentID == UUID.Zero)
  4412. // {
  4413. // objectsToDelete.Add(grp);
  4414. // return;
  4415. // }
  4416. //
  4417. // ScenePresence sp = GetScenePresence(agentID);
  4418. // if (sp == null)
  4419. // {
  4420. // objectsToDelete.Add(grp);
  4421. // return;
  4422. // }
  4423. // }
  4424. // });
  4425. // }
  4426. //
  4427. // foreach (SceneObjectGroup grp in objectsToDelete)
  4428. // {
  4429. // m_log.InfoFormat("[SCENE]: Deleting dropped attachment {0} of user {1}", grp.UUID, grp.OwnerID);
  4430. // DeleteSceneObject(grp, true);
  4431. // }
  4432. // }
  4433. // This method is called across the simulation connector to
  4434. // determine if a given agent is allowed in this region
  4435. // AS A ROOT AGENT. Returning false here will prevent them
  4436. // from logging into the region, teleporting into the region
  4437. // or corssing the broder walking, but will NOT prevent
  4438. // child agent creation, thereby emulating the SL behavior.
  4439. public bool QueryAccess(UUID agentID, Vector3 position, out string reason)
  4440. {
  4441. int num = m_sceneGraph.GetNumberOfScenePresences();
  4442. if (num >= RegionInfo.RegionSettings.AgentLimit)
  4443. {
  4444. if (!Permissions.IsAdministrator(agentID))
  4445. {
  4446. reason = "The region is full";
  4447. return false;
  4448. }
  4449. }
  4450. reason = String.Empty;
  4451. return true;
  4452. }
  4453. }
  4454. }