Scene.cs 194 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739
  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.Drawing;
  30. using System.Drawing.Imaging;
  31. using System.IO;
  32. using System.Text;
  33. using System.Threading;
  34. using System.Timers;
  35. using System.Xml;
  36. using Nini.Config;
  37. using OpenMetaverse;
  38. using OpenMetaverse.Imaging;
  39. using OpenSim.Framework;
  40. using OpenSim.Services.Interfaces;
  41. using OpenSim.Framework.Communications;
  42. using OpenSim.Framework.Communications.Cache;
  43. using OpenSim.Framework.Communications.Clients;
  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. public enum UpdatePrioritizationSchemes {
  58. Time = 0,
  59. Distance = 1,
  60. SimpleAngularDistance = 2,
  61. }
  62. public delegate void SynchronizeSceneHandler(Scene scene);
  63. public SynchronizeSceneHandler SynchronizeScene = null;
  64. /* Used by the loadbalancer plugin on GForge */
  65. protected int m_splitRegionID = 0;
  66. public int SplitRegionID
  67. {
  68. get { return m_splitRegionID; }
  69. set { m_splitRegionID = value; }
  70. }
  71. private const long DEFAULT_MIN_TIME_FOR_PERSISTENCE = 60L;
  72. private const long DEFAULT_MAX_TIME_FOR_PERSISTENCE = 600L;
  73. #region Fields
  74. protected Timer m_restartWaitTimer = new Timer();
  75. protected Thread m_updateEntitiesThread;
  76. public SimStatsReporter StatsReporter;
  77. protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>();
  78. protected List<RegionInfo> m_neighbours = new List<RegionInfo>();
  79. public volatile bool BordersLocked = false;
  80. public List<Border> NorthBorders = new List<Border>();
  81. public List<Border> EastBorders = new List<Border>();
  82. public List<Border> SouthBorders = new List<Border>();
  83. public List<Border> WestBorders = new List<Border>();
  84. /// <value>
  85. /// The scene graph for this scene
  86. /// </value>
  87. /// TODO: Possibly stop other classes being able to manipulate this directly.
  88. private SceneGraph m_sceneGraph;
  89. /// <summary>
  90. /// Are we applying physics to any of the prims in this scene?
  91. /// </summary>
  92. public bool m_physicalPrim;
  93. public float m_maxNonphys = 256;
  94. public float m_maxPhys = 10;
  95. public bool m_clampPrimSize = false;
  96. public bool m_trustBinaries = false;
  97. public bool m_allowScriptCrossings = false;
  98. public bool m_useFlySlow = false;
  99. public bool m_usePreJump = false;
  100. public bool m_seeIntoRegionFromNeighbor;
  101. // TODO: need to figure out how allow client agents but deny
  102. // root agents when ACL denies access to root agent
  103. public bool m_strictAccessControl = true;
  104. public int MaxUndoCount = 5;
  105. private int m_RestartTimerCounter;
  106. private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing
  107. private int m_incrementsof15seconds = 0;
  108. private volatile bool m_backingup = false;
  109. private Dictionary<UUID, ReturnInfo> m_returns = new Dictionary<UUID, ReturnInfo>();
  110. private Dictionary<UUID, SceneObjectGroup> m_groupsWithTargets = new Dictionary<UUID, SceneObjectGroup>();
  111. protected string m_simulatorVersion = "OpenSimulator Server";
  112. protected ModuleLoader m_moduleLoader;
  113. protected StorageManager m_storageManager;
  114. protected AgentCircuitManager m_authenticateHandler;
  115. public CommunicationsManager CommsManager;
  116. protected SceneCommunicationService m_sceneGridService;
  117. public bool loginsdisabled = true;
  118. public SceneCommunicationService SceneGridService
  119. {
  120. get { return m_sceneGridService; }
  121. }
  122. public IXfer XferManager;
  123. protected IAssetService m_AssetService = null;
  124. protected IAuthorizationService m_AuthorizationService = null;
  125. private Object m_heartbeatLock = new Object();
  126. public IAssetService AssetService
  127. {
  128. get
  129. {
  130. if (m_AssetService == null)
  131. {
  132. m_AssetService = RequestModuleInterface<IAssetService>();
  133. if (m_AssetService == null)
  134. {
  135. throw new Exception("No IAssetService available.");
  136. }
  137. }
  138. return m_AssetService;
  139. }
  140. }
  141. public IAuthorizationService AuthorizationService
  142. {
  143. get
  144. {
  145. if (m_AuthorizationService == null)
  146. {
  147. m_AuthorizationService = RequestModuleInterface<IAuthorizationService>();
  148. if (m_AuthorizationService == null)
  149. {
  150. // don't throw an exception if no authorization service is set for the time being
  151. m_log.InfoFormat("[SCENE]: No Authorization service is configured");
  152. }
  153. }
  154. return m_AuthorizationService;
  155. }
  156. }
  157. protected IInventoryService m_InventoryService = null;
  158. public IInventoryService InventoryService
  159. {
  160. get
  161. {
  162. if (m_InventoryService == null)
  163. {
  164. m_InventoryService = RequestModuleInterface<IInventoryService>();
  165. if (m_InventoryService == null)
  166. {
  167. 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.");
  168. }
  169. }
  170. return m_InventoryService;
  171. }
  172. }
  173. protected IGridService m_GridService = null;
  174. public IGridService GridService
  175. {
  176. get
  177. {
  178. if (m_GridService == null)
  179. {
  180. m_GridService = RequestModuleInterface<IGridService>();
  181. if (m_GridService == null)
  182. {
  183. 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.");
  184. }
  185. }
  186. return m_GridService;
  187. }
  188. }
  189. protected IXMLRPC m_xmlrpcModule;
  190. protected IWorldComm m_worldCommModule;
  191. protected IAvatarFactory m_AvatarFactory;
  192. public IAvatarFactory AvatarFactory
  193. {
  194. get { return m_AvatarFactory; }
  195. }
  196. protected IConfigSource m_config;
  197. protected IRegionSerialiserModule m_serialiser;
  198. protected IInterregionCommsOut m_interregionCommsOut;
  199. protected IInterregionCommsIn m_interregionCommsIn;
  200. protected IDialogModule m_dialogModule;
  201. protected ITeleportModule m_teleportModule;
  202. protected ICapabilitiesModule m_capsModule;
  203. public ICapabilitiesModule CapsModule
  204. {
  205. get { return m_capsModule; }
  206. }
  207. protected override IConfigSource GetConfig()
  208. {
  209. return m_config;
  210. }
  211. // Central Update Loop
  212. protected int m_fps = 10;
  213. protected int m_frame = 0;
  214. protected float m_timespan = 0.089f;
  215. protected DateTime m_lastupdate = DateTime.Now;
  216. private int m_update_physics = 1;
  217. private int m_update_entitymovement = 1;
  218. private int m_update_objects = 1; // Update objects which have scheduled themselves for updates
  219. private int m_update_presences = 1; // Update scene presence movements
  220. private int m_update_events = 1;
  221. private int m_update_backup = 200;
  222. private int m_update_terrain = 50;
  223. private int m_update_land = 1;
  224. private int frameMS = 0;
  225. private int physicsMS2 = 0;
  226. private int physicsMS = 0;
  227. private int otherMS = 0;
  228. private bool m_physics_enabled = true;
  229. private bool m_scripts_enabled = true;
  230. private string m_defaultScriptEngine;
  231. private int m_LastLogin = 0;
  232. private Thread HeartbeatThread = null;
  233. private volatile bool shuttingdown = false;
  234. private int m_lastUpdate = Environment.TickCount;
  235. private bool m_firstHeartbeat = true;
  236. private UpdatePrioritizationSchemes m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time;
  237. private bool m_reprioritization_enabled = true;
  238. private double m_reprioritization_interval = 2000.0;
  239. private double m_root_reprioritization_distance = 5.0;
  240. private double m_child_reprioritization_distance = 10.0;
  241. private object m_deleting_scene_object = new object();
  242. // the minimum time that must elapse before a changed object will be considered for persisted
  243. public long m_dontPersistBefore = DEFAULT_MIN_TIME_FOR_PERSISTENCE * 10000000L;
  244. // the maximum time that must elapse before a changed object will be considered for persisted
  245. public long m_persistAfter = DEFAULT_MAX_TIME_FOR_PERSISTENCE * 10000000L;
  246. #endregion
  247. #region Properties
  248. public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get { return this.m_update_prioritization_scheme; } }
  249. public bool IsReprioritizationEnabled { get { return m_reprioritization_enabled; } }
  250. public double ReprioritizationInterval { get { return m_reprioritization_interval; } }
  251. public double RootReprioritizationDistance { get { return m_root_reprioritization_distance; } }
  252. public double ChildReprioritizationDistance { get { return m_child_reprioritization_distance; } }
  253. public AgentCircuitManager AuthenticateHandler
  254. {
  255. get { return m_authenticateHandler; }
  256. }
  257. public SceneGraph SceneContents
  258. {
  259. get { return m_sceneGraph; }
  260. }
  261. // an instance to the physics plugin's Scene object.
  262. public PhysicsScene PhysicsScene
  263. {
  264. get { return m_sceneGraph.PhysicsScene; }
  265. set
  266. {
  267. // If we're not doing the initial set
  268. // Then we've got to remove the previous
  269. // event handler
  270. if (PhysicsScene != null && PhysicsScene.SupportsNINJAJoints)
  271. {
  272. PhysicsScene.OnJointMoved -= jointMoved;
  273. PhysicsScene.OnJointDeactivated -= jointDeactivated;
  274. PhysicsScene.OnJointErrorMessage -= jointErrorMessage;
  275. }
  276. m_sceneGraph.PhysicsScene = value;
  277. if (PhysicsScene != null && m_sceneGraph.PhysicsScene.SupportsNINJAJoints)
  278. {
  279. // register event handlers to respond to joint movement/deactivation
  280. PhysicsScene.OnJointMoved += jointMoved;
  281. PhysicsScene.OnJointDeactivated += jointDeactivated;
  282. PhysicsScene.OnJointErrorMessage += jointErrorMessage;
  283. }
  284. }
  285. }
  286. // This gets locked so things stay thread safe.
  287. public object SyncRoot
  288. {
  289. get { return m_sceneGraph.m_syncRoot; }
  290. }
  291. /// <summary>
  292. /// This is for llGetRegionFPS
  293. /// </summary>
  294. public float SimulatorFPS
  295. {
  296. get { return StatsReporter.getLastReportedSimFPS(); }
  297. }
  298. public string DefaultScriptEngine
  299. {
  300. get { return m_defaultScriptEngine; }
  301. }
  302. public EntityManager Entities
  303. {
  304. get { return m_sceneGraph.Entities; }
  305. }
  306. public Dictionary<UUID, ScenePresence> m_restorePresences
  307. {
  308. get { return m_sceneGraph.RestorePresences; }
  309. set { m_sceneGraph.RestorePresences = value; }
  310. }
  311. public int objectCapacity = 45000;
  312. #endregion
  313. #region Constructors
  314. public Scene(RegionInfo regInfo, AgentCircuitManager authen,
  315. CommunicationsManager commsMan, SceneCommunicationService sceneGridService,
  316. StorageManager storeManager,
  317. ModuleLoader moduleLoader, bool dumpAssetsToFile, bool physicalPrim,
  318. bool SeeIntoRegionFromNeighbor, IConfigSource config, string simulatorVersion)
  319. {
  320. m_config = config;
  321. Random random = new Random();
  322. BordersLocked = true;
  323. Border northBorder = new Border();
  324. northBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, (int)Constants.RegionSize); //<---
  325. northBorder.CrossDirection = Cardinals.N;
  326. NorthBorders.Add(northBorder);
  327. Border southBorder = new Border();
  328. southBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, 0); //--->
  329. southBorder.CrossDirection = Cardinals.S;
  330. SouthBorders.Add(southBorder);
  331. Border eastBorder = new Border();
  332. eastBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, (int)Constants.RegionSize); //<---
  333. eastBorder.CrossDirection = Cardinals.E;
  334. EastBorders.Add(eastBorder);
  335. Border westBorder = new Border();
  336. westBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, 0); //--->
  337. westBorder.CrossDirection = Cardinals.W;
  338. WestBorders.Add(westBorder);
  339. BordersLocked = false;
  340. m_lastAllocatedLocalId = (uint)(random.NextDouble() * (double)(uint.MaxValue/2))+(uint)(uint.MaxValue/4);
  341. m_moduleLoader = moduleLoader;
  342. m_authenticateHandler = authen;
  343. CommsManager = commsMan;
  344. m_sceneGridService = sceneGridService;
  345. m_storageManager = storeManager;
  346. m_regInfo = regInfo;
  347. m_regionHandle = m_regInfo.RegionHandle;
  348. m_regionName = m_regInfo.RegionName;
  349. m_datastore = m_regInfo.DataStore;
  350. m_physicalPrim = physicalPrim;
  351. m_seeIntoRegionFromNeighbor = SeeIntoRegionFromNeighbor;
  352. m_eventManager = new EventManager();
  353. m_permissions = new ScenePermissions(this);
  354. m_asyncSceneObjectDeleter = new AsyncSceneObjectGroupDeleter(this);
  355. m_asyncSceneObjectDeleter.Enabled = true;
  356. // Load region settings
  357. m_regInfo.RegionSettings = m_storageManager.DataStore.LoadRegionSettings(m_regInfo.RegionID);
  358. if (m_storageManager.EstateDataStore != null)
  359. {
  360. m_regInfo.EstateSettings = m_storageManager.EstateDataStore.LoadEstateSettings(m_regInfo.RegionID);
  361. }
  362. //Bind Storage Manager functions to some land manager functions for this scene
  363. EventManager.OnLandObjectAdded +=
  364. new EventManager.LandObjectAdded(m_storageManager.DataStore.StoreLandObject);
  365. EventManager.OnLandObjectRemoved +=
  366. new EventManager.LandObjectRemoved(m_storageManager.DataStore.RemoveLandObject);
  367. m_sceneGraph = new SceneGraph(this, m_regInfo);
  368. // If the scene graph has an Unrecoverable error, restart this sim.
  369. // Currently the only thing that causes it to happen is two kinds of specific
  370. // Physics based crashes.
  371. //
  372. // Out of memory
  373. // Operating system has killed the plugin
  374. m_sceneGraph.UnRecoverableError += RestartNow;
  375. RegisterDefaultSceneEvents();
  376. DumpAssetsToFile = dumpAssetsToFile;
  377. m_scripts_enabled = !RegionInfo.RegionSettings.DisableScripts;
  378. m_physics_enabled = !RegionInfo.RegionSettings.DisablePhysics;
  379. StatsReporter = new SimStatsReporter(this);
  380. StatsReporter.OnSendStatsResult += SendSimStatsPackets;
  381. StatsReporter.OnStatsIncorrect += m_sceneGraph.RecalculateStats;
  382. StatsReporter.SetObjectCapacity(objectCapacity);
  383. m_simulatorVersion = simulatorVersion
  384. + " (OS " + Util.GetOperatingSystemInformation() + ")"
  385. + " ChilTasks:" + m_seeIntoRegionFromNeighbor.ToString()
  386. + " PhysPrim:" + m_physicalPrim.ToString();
  387. try
  388. {
  389. // Region config overrides global config
  390. //
  391. IConfig startupConfig = m_config.Configs["Startup"];
  392. //Animation states
  393. m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false);
  394. // TODO: Change default to true once the feature is supported
  395. m_usePreJump = startupConfig.GetBoolean("enableprejump", false);
  396. m_maxNonphys = startupConfig.GetFloat("NonPhysicalPrimMax", m_maxNonphys);
  397. if (RegionInfo.NonphysPrimMax > 0)
  398. {
  399. m_maxNonphys = RegionInfo.NonphysPrimMax;
  400. }
  401. m_maxPhys = startupConfig.GetFloat("PhysicalPrimMax", m_maxPhys);
  402. if (RegionInfo.PhysPrimMax > 0)
  403. {
  404. m_maxPhys = RegionInfo.PhysPrimMax;
  405. }
  406. // Here, if clamping is requested in either global or
  407. // local config, it will be used
  408. //
  409. m_clampPrimSize = startupConfig.GetBoolean("ClampPrimSize", m_clampPrimSize);
  410. if (RegionInfo.ClampPrimSize)
  411. {
  412. m_clampPrimSize = true;
  413. }
  414. m_trustBinaries = startupConfig.GetBoolean("TrustBinaries", m_trustBinaries);
  415. m_allowScriptCrossings = startupConfig.GetBoolean("AllowScriptCrossing", m_allowScriptCrossings);
  416. m_dontPersistBefore =
  417. startupConfig.GetLong("MinimumTimeBeforePersistenceConsidered", DEFAULT_MIN_TIME_FOR_PERSISTENCE);
  418. m_dontPersistBefore *= 10000000;
  419. m_persistAfter =
  420. startupConfig.GetLong("MaximumTimeBeforePersistenceConsidered", DEFAULT_MAX_TIME_FOR_PERSISTENCE);
  421. m_persistAfter *= 10000000;
  422. m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "DotNetEngine");
  423. IConfig packetConfig = m_config.Configs["PacketPool"];
  424. if (packetConfig != null)
  425. {
  426. PacketPool.Instance.RecyclePackets = packetConfig.GetBoolean("RecyclePackets", true);
  427. PacketPool.Instance.RecycleDataBlocks = packetConfig.GetBoolean("RecycleDataBlocks", true);
  428. }
  429. m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl);
  430. IConfig interest_management_config = m_config.Configs["InterestManagement"];
  431. if (interest_management_config != null)
  432. {
  433. string update_prioritization_scheme = interest_management_config.GetString("UpdatePrioritizationScheme", "Time").Trim().ToLower();
  434. switch (update_prioritization_scheme)
  435. {
  436. case "time":
  437. m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time;
  438. break;
  439. case "distance":
  440. m_update_prioritization_scheme = UpdatePrioritizationSchemes.Distance;
  441. break;
  442. case "simpleangulardistance":
  443. m_update_prioritization_scheme = UpdatePrioritizationSchemes.SimpleAngularDistance;
  444. break;
  445. default:
  446. m_log.Warn("[SCENE]: UpdatePrioritizationScheme was not recognized, setting to default settomg of Time");
  447. m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time;
  448. break;
  449. }
  450. m_reprioritization_enabled = interest_management_config.GetBoolean("ReprioritizationEnabled", true);
  451. m_reprioritization_interval = interest_management_config.GetDouble("ReprioritizationInterval", 5000.0);
  452. m_root_reprioritization_distance = interest_management_config.GetDouble("RootReprioritizationDistance", 10.0);
  453. m_child_reprioritization_distance = interest_management_config.GetDouble("ChildReprioritizationDistance", 20.0);
  454. }
  455. m_log.Info("[SCENE]: Using the " + m_update_prioritization_scheme + " prioritization scheme");
  456. }
  457. catch
  458. {
  459. m_log.Warn("[SCENE]: Failed to load StartupConfig");
  460. }
  461. }
  462. /// <summary>
  463. /// Mock constructor for scene group persistency unit tests.
  464. /// SceneObjectGroup RegionId property is delegated to Scene.
  465. /// </summary>
  466. /// <param name="regInfo"></param>
  467. public Scene(RegionInfo regInfo)
  468. {
  469. BordersLocked = true;
  470. Border northBorder = new Border();
  471. northBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, (int)Constants.RegionSize); //<---
  472. northBorder.CrossDirection = Cardinals.N;
  473. NorthBorders.Add(northBorder);
  474. Border southBorder = new Border();
  475. southBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue,0); //--->
  476. southBorder.CrossDirection = Cardinals.S;
  477. SouthBorders.Add(southBorder);
  478. Border eastBorder = new Border();
  479. eastBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, (int)Constants.RegionSize); //<---
  480. eastBorder.CrossDirection = Cardinals.E;
  481. EastBorders.Add(eastBorder);
  482. Border westBorder = new Border();
  483. westBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue,0); //--->
  484. westBorder.CrossDirection = Cardinals.W;
  485. WestBorders.Add(westBorder);
  486. BordersLocked = false;
  487. m_regInfo = regInfo;
  488. m_eventManager = new EventManager();
  489. }
  490. #endregion
  491. #region Startup / Close Methods
  492. public bool ShuttingDown
  493. {
  494. get { return shuttingdown; }
  495. }
  496. /// <value>
  497. /// The scene graph for this scene
  498. /// </value>
  499. /// TODO: Possibly stop other classes being able to manipulate this directly.
  500. public SceneGraph SceneGraph
  501. {
  502. get { return m_sceneGraph; }
  503. }
  504. protected virtual void RegisterDefaultSceneEvents()
  505. {
  506. IDialogModule dm = RequestModuleInterface<IDialogModule>();
  507. if (dm != null)
  508. m_eventManager.OnPermissionError += dm.SendAlertToUser;
  509. }
  510. public override string GetSimulatorVersion()
  511. {
  512. return m_simulatorVersion;
  513. }
  514. /// <summary>
  515. /// Another region is up.
  516. ///
  517. /// We only add it to the neighbor list if it's within 1 region from here.
  518. /// Agents may have draw distance values that cross two regions though, so
  519. /// we add it to the notify list regardless of distance. We'll check
  520. /// the agent's draw distance before notifying them though.
  521. /// </summary>
  522. /// <param name="otherRegion">RegionInfo handle for the new region.</param>
  523. /// <returns>True after all operations complete, throws exceptions otherwise.</returns>
  524. public override void OtherRegionUp(GridRegion otherRegion)
  525. {
  526. uint xcell = (uint)((int)otherRegion.RegionLocX / (int)Constants.RegionSize);
  527. uint ycell = (uint)((int)otherRegion.RegionLocY / (int)Constants.RegionSize);
  528. m_log.InfoFormat("[SCENE]: (on region {0}): Region {1} up in coords {2}-{3}",
  529. RegionInfo.RegionName, otherRegion.RegionName, xcell, ycell);
  530. if (RegionInfo.RegionHandle != otherRegion.RegionHandle)
  531. {
  532. // If these are cast to INT because long + negative values + abs returns invalid data
  533. int resultX = Math.Abs((int)xcell - (int)RegionInfo.RegionLocX);
  534. int resultY = Math.Abs((int)ycell - (int)RegionInfo.RegionLocY);
  535. if (resultX <= 1 && resultY <= 1)
  536. {
  537. // Let the grid service module know, so this can be cached
  538. m_eventManager.TriggerOnRegionUp(otherRegion);
  539. RegionInfo regInfo = new RegionInfo(xcell, ycell, otherRegion.InternalEndPoint, otherRegion.ExternalHostName);
  540. regInfo.RegionID = otherRegion.RegionID;
  541. regInfo.RegionName = otherRegion.RegionName;
  542. regInfo.ScopeID = otherRegion.ScopeID;
  543. regInfo.ExternalHostName = otherRegion.ExternalHostName;
  544. try
  545. {
  546. ForEachScenePresence(delegate(ScenePresence agent)
  547. {
  548. // If agent is a root agent.
  549. if (!agent.IsChildAgent)
  550. {
  551. //agent.ControllingClient.new
  552. //this.CommsManager.InterRegion.InformRegionOfChildAgent(otherRegion.RegionHandle, agent.ControllingClient.RequestClientInfo());
  553. List<ulong> old = new List<ulong>();
  554. old.Add(otherRegion.RegionHandle);
  555. agent.DropOldNeighbours(old);
  556. InformClientOfNeighbor(agent, regInfo);
  557. }
  558. }
  559. );
  560. }
  561. catch (NullReferenceException)
  562. {
  563. // This means that we're not booted up completely yet.
  564. // This shouldn't happen too often anymore.
  565. m_log.Error("[SCENE]: Couldn't inform client of regionup because we got a null reference exception");
  566. }
  567. }
  568. else
  569. {
  570. m_log.Info("[INTERGRID]: Got notice about far away Region: " + otherRegion.RegionName.ToString() +
  571. " at (" + otherRegion.RegionLocX.ToString() + ", " +
  572. otherRegion.RegionLocY.ToString() + ")");
  573. }
  574. }
  575. }
  576. public void AddNeighborRegion(RegionInfo region)
  577. {
  578. lock (m_neighbours)
  579. {
  580. if (!CheckNeighborRegion(region))
  581. {
  582. m_neighbours.Add(region);
  583. }
  584. }
  585. }
  586. public bool CheckNeighborRegion(RegionInfo region)
  587. {
  588. bool found = false;
  589. lock (m_neighbours)
  590. {
  591. foreach (RegionInfo reg in m_neighbours)
  592. {
  593. if (reg.RegionHandle == region.RegionHandle)
  594. {
  595. found = true;
  596. break;
  597. }
  598. }
  599. }
  600. return found;
  601. }
  602. // Alias IncomingHelloNeighbour OtherRegionUp, for now
  603. public GridRegion IncomingHelloNeighbour(RegionInfo neighbour)
  604. {
  605. OtherRegionUp(new GridRegion(neighbour));
  606. return new GridRegion(RegionInfo);
  607. }
  608. /// <summary>
  609. /// Given float seconds, this will restart the region.
  610. /// </summary>
  611. /// <param name="seconds">float indicating duration before restart.</param>
  612. public virtual void Restart(float seconds)
  613. {
  614. // notifications are done in 15 second increments
  615. // so .. if the number of seconds is less then 15 seconds, it's not really a restart request
  616. // It's a 'Cancel restart' request.
  617. // RestartNow() does immediate restarting.
  618. if (seconds < 15)
  619. {
  620. m_restartTimer.Stop();
  621. m_dialogModule.SendGeneralAlert("Restart Aborted");
  622. }
  623. else
  624. {
  625. // Now we figure out what to set the timer to that does the notifications and calls, RestartNow()
  626. m_restartTimer.Interval = 15000;
  627. m_incrementsof15seconds = (int)seconds / 15;
  628. m_RestartTimerCounter = 0;
  629. m_restartTimer.AutoReset = true;
  630. m_restartTimer.Elapsed += new ElapsedEventHandler(RestartTimer_Elapsed);
  631. m_log.Info("[REGION]: Restarting Region in " + (seconds / 60) + " minutes");
  632. m_restartTimer.Start();
  633. m_dialogModule.SendNotificationToUsersInRegion(
  634. UUID.Random(), String.Empty, RegionInfo.RegionName + ": Restarting in 2 Minutes");
  635. }
  636. }
  637. // The Restart timer has occured.
  638. // We have to figure out if this is a notification or if the number of seconds specified in Restart
  639. // have elapsed.
  640. // If they have elapsed, call RestartNow()
  641. public void RestartTimer_Elapsed(object sender, ElapsedEventArgs e)
  642. {
  643. m_RestartTimerCounter++;
  644. if (m_RestartTimerCounter <= m_incrementsof15seconds)
  645. {
  646. if (m_RestartTimerCounter == 4 || m_RestartTimerCounter == 6 || m_RestartTimerCounter == 7)
  647. m_dialogModule.SendNotificationToUsersInRegion(
  648. UUID.Random(),
  649. String.Empty,
  650. RegionInfo.RegionName + ": Restarting in " + ((8 - m_RestartTimerCounter) * 15) + " seconds");
  651. }
  652. else
  653. {
  654. m_restartTimer.Stop();
  655. m_restartTimer.AutoReset = false;
  656. RestartNow();
  657. }
  658. }
  659. // This causes the region to restart immediatley.
  660. public void RestartNow()
  661. {
  662. if (PhysicsScene != null)
  663. {
  664. PhysicsScene.Dispose();
  665. }
  666. m_log.Error("[REGION]: Closing");
  667. Close();
  668. m_log.Error("[REGION]: Firing Region Restart Message");
  669. base.Restart(0);
  670. }
  671. // This is a helper function that notifies root agents in this region that a new sim near them has come up
  672. // This is in the form of a timer because when an instance of OpenSim.exe is started,
  673. // Even though the sims initialize, they don't listen until 'all of the sims are initialized'
  674. // If we tell an agent about a sim that's not listening yet, the agent will not be able to connect to it.
  675. // subsequently the agent will never see the region come back online.
  676. public void RestartNotifyWaitElapsed(object sender, ElapsedEventArgs e)
  677. {
  678. m_restartWaitTimer.Stop();
  679. lock (m_regionRestartNotifyList)
  680. {
  681. foreach (RegionInfo region in m_regionRestartNotifyList)
  682. {
  683. try
  684. {
  685. ForEachScenePresence(delegate(ScenePresence agent)
  686. {
  687. // If agent is a root agent.
  688. if (!agent.IsChildAgent)
  689. {
  690. //agent.ControllingClient.new
  691. //this.CommsManager.InterRegion.InformRegionOfChildAgent(otherRegion.RegionHandle, agent.ControllingClient.RequestClientInfo());
  692. InformClientOfNeighbor(agent, region);
  693. }
  694. }
  695. );
  696. }
  697. catch (NullReferenceException)
  698. {
  699. // This means that we're not booted up completely yet.
  700. // This shouldn't happen too often anymore.
  701. }
  702. }
  703. // Reset list to nothing.
  704. m_regionRestartNotifyList.Clear();
  705. }
  706. }
  707. public void SetSceneCoreDebug(bool ScriptEngine, bool CollisionEvents, bool PhysicsEngine)
  708. {
  709. if (m_scripts_enabled != !ScriptEngine)
  710. {
  711. // Tedd! Here's the method to disable the scripting engine!
  712. if (ScriptEngine)
  713. {
  714. m_log.Info("Stopping all Scripts in Scene");
  715. foreach (EntityBase ent in Entities)
  716. {
  717. if (ent is SceneObjectGroup)
  718. {
  719. ((SceneObjectGroup) ent).RemoveScriptInstances();
  720. }
  721. }
  722. }
  723. else
  724. {
  725. m_log.Info("Starting all Scripts in Scene");
  726. lock (Entities)
  727. {
  728. foreach (EntityBase ent in Entities)
  729. {
  730. if (ent is SceneObjectGroup)
  731. {
  732. ((SceneObjectGroup)ent).CreateScriptInstances(0, false, DefaultScriptEngine, 0);
  733. }
  734. }
  735. }
  736. }
  737. m_scripts_enabled = !ScriptEngine;
  738. m_log.Info("[TOTEDD]: Here is the method to trigger disabling of the scripting engine");
  739. }
  740. if (m_physics_enabled != !PhysicsEngine)
  741. {
  742. m_physics_enabled = !PhysicsEngine;
  743. }
  744. }
  745. public int GetInaccurateNeighborCount()
  746. {
  747. lock (m_neighbours)
  748. {
  749. return m_neighbours.Count;
  750. }
  751. }
  752. // This is the method that shuts down the scene.
  753. public override void Close()
  754. {
  755. m_log.InfoFormat("[SCENE]: Closing down the single simulator: {0}", RegionInfo.RegionName);
  756. // Kick all ROOT agents with the message, 'The simulator is going down'
  757. ForEachScenePresence(delegate(ScenePresence avatar)
  758. {
  759. if (avatar.KnownChildRegionHandles.Contains(RegionInfo.RegionHandle))
  760. avatar.KnownChildRegionHandles.Remove(RegionInfo.RegionHandle);
  761. if (!avatar.IsChildAgent)
  762. avatar.ControllingClient.Kick("The simulator is going down.");
  763. avatar.ControllingClient.SendShutdownConnectionNotice();
  764. });
  765. // Wait here, or the kick messages won't actually get to the agents before the scene terminates.
  766. Thread.Sleep(500);
  767. // Stop all client threads.
  768. ForEachScenePresence(delegate(ScenePresence avatar) { avatar.ControllingClient.Close(); });
  769. // Stop updating the scene objects and agents.
  770. //m_heartbeatTimer.Close();
  771. shuttingdown = true;
  772. m_log.Debug("[SCENE]: Persisting changed objects");
  773. List<EntityBase> entities = GetEntities();
  774. foreach (EntityBase entity in entities)
  775. {
  776. if (!entity.IsDeleted && entity is SceneObjectGroup && ((SceneObjectGroup)entity).HasGroupChanged)
  777. {
  778. ((SceneObjectGroup)entity).ProcessBackup(m_storageManager.DataStore, false);
  779. }
  780. }
  781. m_sceneGraph.Close();
  782. // De-register with region communications (events cleanup)
  783. UnRegisterRegionWithComms();
  784. // call the base class Close method.
  785. base.Close();
  786. }
  787. /// <summary>
  788. /// Start the timer which triggers regular scene updates
  789. /// </summary>
  790. public void StartTimer()
  791. {
  792. //m_log.Debug("[SCENE]: Starting timer");
  793. //m_heartbeatTimer.Enabled = true;
  794. //m_heartbeatTimer.Interval = (int)(m_timespan * 1000);
  795. //m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat);
  796. if (HeartbeatThread != null)
  797. {
  798. HeartbeatThread.Abort();
  799. HeartbeatThread = null;
  800. }
  801. m_lastUpdate = Environment.TickCount;
  802. HeartbeatThread = new Thread(new ParameterizedThreadStart(Heartbeat));
  803. HeartbeatThread.SetApartmentState(ApartmentState.MTA);
  804. HeartbeatThread.Name = string.Format("Heartbeat for region {0}", RegionInfo.RegionName);
  805. HeartbeatThread.Priority = ThreadPriority.AboveNormal;
  806. HeartbeatThread.Start();
  807. }
  808. /// <summary>
  809. /// Sets up references to modules required by the scene
  810. /// </summary>
  811. public void SetModuleInterfaces()
  812. {
  813. m_xmlrpcModule = RequestModuleInterface<IXMLRPC>();
  814. m_worldCommModule = RequestModuleInterface<IWorldComm>();
  815. XferManager = RequestModuleInterface<IXfer>();
  816. m_AvatarFactory = RequestModuleInterface<IAvatarFactory>();
  817. m_serialiser = RequestModuleInterface<IRegionSerialiserModule>();
  818. m_interregionCommsOut = RequestModuleInterface<IInterregionCommsOut>();
  819. m_interregionCommsIn = RequestModuleInterface<IInterregionCommsIn>();
  820. m_dialogModule = RequestModuleInterface<IDialogModule>();
  821. m_capsModule = RequestModuleInterface<ICapabilitiesModule>();
  822. m_teleportModule = RequestModuleInterface<ITeleportModule>();
  823. }
  824. #endregion
  825. #region Update Methods
  826. /// <summary>
  827. /// Performs per-frame updates regularly
  828. /// </summary>
  829. /// <param name="sender"></param>
  830. /// <param name="e"></param>
  831. private void Heartbeat(object sender)
  832. {
  833. if (!Monitor.TryEnter(m_heartbeatLock))
  834. return;
  835. try
  836. {
  837. Update();
  838. m_lastUpdate = Environment.TickCount;
  839. m_firstHeartbeat = false;
  840. }
  841. catch (ThreadAbortException)
  842. {
  843. }
  844. finally
  845. {
  846. Monitor.Pulse(m_heartbeatLock);
  847. Monitor.Exit(m_heartbeatLock);
  848. }
  849. }
  850. /// <summary>
  851. /// Performs per-frame updates on the scene, this should be the central scene loop
  852. /// </summary>
  853. public override void Update()
  854. {
  855. int maintc = 0;
  856. while (!shuttingdown)
  857. {
  858. //#if DEBUG
  859. // int w = 0, io = 0;
  860. // ThreadPool.GetAvailableThreads(out w, out io);
  861. // if ((w < 10) || (io < 10))
  862. // m_log.DebugFormat("[WARNING]: ThreadPool reaching exhaustion. workers = {0}; io = {1}", w, io);
  863. //#endif
  864. maintc = Environment.TickCount;
  865. TimeSpan SinceLastFrame = DateTime.Now - m_lastupdate;
  866. float physicsFPS = 0;
  867. frameMS = Environment.TickCount;
  868. try
  869. {
  870. // Increment the frame counter
  871. m_frame++;
  872. // Loop it
  873. if (m_frame == Int32.MaxValue)
  874. m_frame = 0;
  875. otherMS = Environment.TickCount;
  876. // Check if any objects have reached their targets
  877. CheckAtTargets();
  878. // Update SceneObjectGroups that have scheduled themselves for updates
  879. // Objects queue their updates onto all scene presences
  880. if (m_frame % m_update_objects == 0)
  881. m_sceneGraph.UpdateObjectGroups();
  882. // Run through all ScenePresences looking for updates
  883. // Presence updates and queued object updates for each presence are sent to clients
  884. if (m_frame % m_update_presences == 0)
  885. m_sceneGraph.UpdatePresences();
  886. physicsMS2 = Environment.TickCount;
  887. if ((m_frame % m_update_physics == 0) && m_physics_enabled)
  888. m_sceneGraph.UpdatePreparePhysics();
  889. physicsMS2 = Environment.TickCount - physicsMS2;
  890. if (m_frame % m_update_entitymovement == 0)
  891. m_sceneGraph.UpdateScenePresenceMovement();
  892. physicsMS = Environment.TickCount;
  893. if ((m_frame % m_update_physics == 0) && m_physics_enabled)
  894. physicsFPS = m_sceneGraph.UpdatePhysics(
  895. Math.Max(SinceLastFrame.TotalSeconds, m_timespan)
  896. );
  897. if (m_frame % m_update_physics == 0 && SynchronizeScene != null)
  898. SynchronizeScene(this);
  899. physicsMS = Environment.TickCount - physicsMS;
  900. physicsMS += physicsMS2;
  901. // Delete temp-on-rez stuff
  902. if (m_frame % m_update_backup == 0)
  903. CleanTempObjects();
  904. if (RegionStatus != RegionStatus.SlaveScene)
  905. {
  906. if (m_frame % m_update_events == 0)
  907. UpdateEvents();
  908. if (m_frame % m_update_backup == 0)
  909. UpdateStorageBackup();
  910. if (m_frame % m_update_terrain == 0)
  911. UpdateTerrain();
  912. if (m_frame % m_update_land == 0)
  913. UpdateLand();
  914. otherMS = Environment.TickCount - otherMS;
  915. // if (m_frame%m_update_avatars == 0)
  916. // UpdateInWorldTime();
  917. StatsReporter.AddPhysicsFPS(physicsFPS);
  918. StatsReporter.AddTimeDilation(m_timedilation);
  919. StatsReporter.AddFPS(1);
  920. StatsReporter.AddInPackets(0);
  921. StatsReporter.SetRootAgents(m_sceneGraph.GetRootAgentCount());
  922. StatsReporter.SetChildAgents(m_sceneGraph.GetChildAgentCount());
  923. StatsReporter.SetObjects(m_sceneGraph.GetTotalObjectsCount());
  924. StatsReporter.SetActiveObjects(m_sceneGraph.GetActiveObjectsCount());
  925. frameMS = Environment.TickCount - frameMS;
  926. StatsReporter.addFrameMS(frameMS);
  927. StatsReporter.addPhysicsMS(physicsMS);
  928. StatsReporter.addOtherMS(otherMS);
  929. StatsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount());
  930. StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS());
  931. }
  932. if (loginsdisabled && (m_frame > 20))
  933. {
  934. m_log.Debug("[REGION]: Enabling Logins");
  935. loginsdisabled = false;
  936. }
  937. }
  938. catch (NotImplementedException)
  939. {
  940. throw;
  941. }
  942. catch (AccessViolationException e)
  943. {
  944. m_log.Error("[Scene]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
  945. }
  946. //catch (NullReferenceException e)
  947. //{
  948. // m_log.Error("[Scene]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
  949. //}
  950. catch (InvalidOperationException e)
  951. {
  952. m_log.Error("[Scene]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
  953. }
  954. catch (Exception e)
  955. {
  956. m_log.Error("[Scene]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
  957. }
  958. finally
  959. {
  960. //updateLock.ReleaseMutex();
  961. // Get actual time dilation
  962. float tmpval = (m_timespan / (float)SinceLastFrame.TotalSeconds);
  963. // If actual time dilation is greater then one, we're catching up, so subtract
  964. // the amount that's greater then 1 from the time dilation
  965. if (tmpval > 1.0)
  966. {
  967. tmpval = tmpval - (tmpval - 1.0f);
  968. }
  969. m_timedilation = tmpval;
  970. m_lastupdate = DateTime.Now;
  971. }
  972. maintc = Environment.TickCount - maintc;
  973. maintc = (int)(m_timespan * 1000) - maintc;
  974. if ((maintc < (m_timespan * 1000)) && maintc > 0)
  975. Thread.Sleep(maintc);
  976. }
  977. }
  978. public void AddGroupTarget(SceneObjectGroup grp)
  979. {
  980. lock (m_groupsWithTargets)
  981. m_groupsWithTargets[grp.UUID] = grp;
  982. }
  983. public void RemoveGroupTarget(SceneObjectGroup grp)
  984. {
  985. lock (m_groupsWithTargets)
  986. m_groupsWithTargets.Remove(grp.UUID);
  987. }
  988. private void CheckAtTargets()
  989. {
  990. lock (m_groupsWithTargets)
  991. {
  992. foreach (KeyValuePair<UUID, SceneObjectGroup> kvp in m_groupsWithTargets)
  993. {
  994. kvp.Value.checkAtTargets();
  995. }
  996. }
  997. }
  998. /// <summary>
  999. /// Send out simstats data to all clients
  1000. /// </summary>
  1001. /// <param name="stats">Stats on the Simulator's performance</param>
  1002. private void SendSimStatsPackets(SimStats stats)
  1003. {
  1004. ForEachScenePresence(
  1005. delegate(ScenePresence agent)
  1006. {
  1007. if (!agent.IsChildAgent)
  1008. agent.ControllingClient.SendSimStats(stats);
  1009. }
  1010. );
  1011. }
  1012. /// <summary>
  1013. /// Recount SceneObjectPart in parcel aabb
  1014. /// </summary>
  1015. private void UpdateLand()
  1016. {
  1017. if (LandChannel != null)
  1018. {
  1019. if (LandChannel.IsLandPrimCountTainted())
  1020. {
  1021. EventManager.TriggerParcelPrimCountUpdate();
  1022. }
  1023. }
  1024. }
  1025. /// <summary>
  1026. /// Update the terrain if it needs to be updated.
  1027. /// </summary>
  1028. private void UpdateTerrain()
  1029. {
  1030. EventManager.TriggerTerrainTick();
  1031. }
  1032. /// <summary>
  1033. /// Back up queued up changes
  1034. /// </summary>
  1035. private void UpdateStorageBackup()
  1036. {
  1037. if (!m_backingup)
  1038. {
  1039. m_backingup = true;
  1040. System.ComponentModel.BackgroundWorker backupWorker = new System.ComponentModel.BackgroundWorker();
  1041. backupWorker.DoWork += delegate(object sender, System.ComponentModel.DoWorkEventArgs e) { Backup(); };
  1042. backupWorker.RunWorkerAsync();
  1043. }
  1044. }
  1045. /// <summary>
  1046. /// Sends out the OnFrame event to the modules
  1047. /// </summary>
  1048. private void UpdateEvents()
  1049. {
  1050. m_eventManager.TriggerOnFrame();
  1051. }
  1052. /// <summary>
  1053. /// Backup the scene. This acts as the main method of the backup thread.
  1054. /// </summary>
  1055. /// <returns></returns>
  1056. public void Backup()
  1057. {
  1058. lock (m_returns)
  1059. {
  1060. EventManager.TriggerOnBackup(m_storageManager.DataStore);
  1061. m_backingup = false;
  1062. foreach (KeyValuePair<UUID, ReturnInfo> ret in m_returns)
  1063. {
  1064. UUID transaction = UUID.Random();
  1065. GridInstantMessage msg = new GridInstantMessage();
  1066. msg.fromAgentID = new Guid(UUID.Zero.ToString()); // From server
  1067. msg.toAgentID = new Guid(ret.Key.ToString());
  1068. msg.imSessionID = new Guid(transaction.ToString());
  1069. msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
  1070. msg.fromAgentName = "Server";
  1071. msg.dialog = (byte)19; // Object msg
  1072. msg.fromGroup = false;
  1073. msg.offline = (byte)1;
  1074. msg.ParentEstateID = RegionInfo.EstateSettings.ParentEstateID;
  1075. msg.Position = Vector3.Zero;
  1076. msg.RegionID = RegionInfo.RegionID.Guid;
  1077. msg.binaryBucket = new byte[0];
  1078. if (ret.Value.count > 1)
  1079. 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);
  1080. else
  1081. 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);
  1082. IMessageTransferModule tr = RequestModuleInterface<IMessageTransferModule>();
  1083. if (tr != null)
  1084. tr.SendInstantMessage(msg, delegate(bool success) {});
  1085. }
  1086. m_returns.Clear();
  1087. }
  1088. }
  1089. /// <summary>
  1090. /// Synchronous force backup. For deletes and links/unlinks
  1091. /// </summary>
  1092. /// <param name="group">Object to be backed up</param>
  1093. public void ForceSceneObjectBackup(SceneObjectGroup group)
  1094. {
  1095. if (group != null)
  1096. {
  1097. group.ProcessBackup(m_storageManager.DataStore, true);
  1098. }
  1099. }
  1100. /// <summary>
  1101. /// Return object to avatar Message
  1102. /// </summary>
  1103. /// <param name="agentID">Avatar Unique Id</param>
  1104. /// <param name="objectName">Name of object returned</param>
  1105. /// <param name="location">Location of object returned</param>
  1106. /// <param name="reason">Reasion for object return</param>
  1107. public void AddReturn(UUID agentID, string objectName, Vector3 location, string reason)
  1108. {
  1109. lock (m_returns)
  1110. {
  1111. if (m_returns.ContainsKey(agentID))
  1112. {
  1113. ReturnInfo info = m_returns[agentID];
  1114. info.count++;
  1115. m_returns[agentID] = info;
  1116. }
  1117. else
  1118. {
  1119. ReturnInfo info = new ReturnInfo();
  1120. info.count = 1;
  1121. info.objectName = objectName;
  1122. info.location = location;
  1123. info.reason = reason;
  1124. m_returns[agentID] = info;
  1125. }
  1126. }
  1127. }
  1128. #endregion
  1129. #region Load Terrain
  1130. /// <summary>
  1131. /// Store the terrain in the persistant data store
  1132. /// </summary>
  1133. public void SaveTerrain()
  1134. {
  1135. m_storageManager.DataStore.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID);
  1136. }
  1137. /// <summary>
  1138. /// Loads the World heightmap
  1139. /// </summary>
  1140. public override void LoadWorldMap()
  1141. {
  1142. try
  1143. {
  1144. double[,] map = m_storageManager.DataStore.LoadTerrain(RegionInfo.RegionID);
  1145. if (map == null)
  1146. {
  1147. m_log.Info("[TERRAIN]: No default terrain. Generating a new terrain.");
  1148. Heightmap = new TerrainChannel();
  1149. m_storageManager.DataStore.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID);
  1150. }
  1151. else
  1152. {
  1153. Heightmap = new TerrainChannel(map);
  1154. }
  1155. }
  1156. catch (IOException e)
  1157. {
  1158. m_log.Warn("[TERRAIN]: Scene.cs: LoadWorldMap() - Failed with exception " + e.ToString() + " Regenerating");
  1159. // Non standard region size. If there's an old terrain in the database, it might read past the buffer
  1160. #pragma warning disable 0162
  1161. if ((int)Constants.RegionSize != 256)
  1162. {
  1163. Heightmap = new TerrainChannel();
  1164. m_storageManager.DataStore.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID);
  1165. }
  1166. }
  1167. catch (Exception e)
  1168. {
  1169. m_log.Warn("[TERRAIN]: Scene.cs: LoadWorldMap() - Failed with exception " + e.ToString());
  1170. }
  1171. }
  1172. /// <summary>
  1173. /// Register this region with a grid service
  1174. /// </summary>
  1175. /// <exception cref="System.Exception">Thrown if registration of the region itself fails.</exception>
  1176. public void RegisterRegionWithGrid()
  1177. {
  1178. RegisterCommsEvents();
  1179. // These two 'commands' *must be* next to each other or sim rebooting fails.
  1180. //m_sceneGridService.RegisterRegion(m_interregionCommsOut, RegionInfo);
  1181. GridRegion region = new GridRegion(RegionInfo);
  1182. bool success = GridService.RegisterRegion(RegionInfo.ScopeID, region);
  1183. if (!success)
  1184. throw new Exception("Can't register with grid");
  1185. m_sceneGridService.SetScene(this);
  1186. m_sceneGridService.InformNeighborsThatRegionisUp(RequestModuleInterface<INeighbourService>(), RegionInfo);
  1187. //Dictionary<string, string> dGridSettings = m_sceneGridService.GetGridSettings();
  1188. //if (dGridSettings.ContainsKey("allow_forceful_banlines"))
  1189. //{
  1190. // if (dGridSettings["allow_forceful_banlines"] != "TRUE")
  1191. // {
  1192. // m_log.Info("[GRID]: Grid is disabling forceful parcel banlists");
  1193. // EventManager.TriggerSetAllowForcefulBan(false);
  1194. // }
  1195. // else
  1196. // {
  1197. // m_log.Info("[GRID]: Grid is allowing forceful parcel banlists");
  1198. // EventManager.TriggerSetAllowForcefulBan(true);
  1199. // }
  1200. //}
  1201. }
  1202. /// <summary>
  1203. /// Create a terrain texture for this scene
  1204. /// </summary>
  1205. public void CreateTerrainTexture(bool temporary)
  1206. {
  1207. //create a texture asset of the terrain
  1208. IMapImageGenerator terrain = RequestModuleInterface<IMapImageGenerator>();
  1209. // Cannot create a map for a nonexistant heightmap yet.
  1210. if (Heightmap == null)
  1211. return;
  1212. if (terrain == null)
  1213. return;
  1214. byte[] data = terrain.WriteJpeg2000Image("defaultstripe.png");
  1215. if (data != null)
  1216. {
  1217. IWorldMapModule mapModule = RequestModuleInterface<IWorldMapModule>();
  1218. if (mapModule != null)
  1219. mapModule.LazySaveGeneratedMaptile(data, temporary);
  1220. }
  1221. }
  1222. #endregion
  1223. #region Load Land
  1224. /// <summary>
  1225. /// Loads all Parcel data from the datastore for region identified by regionID
  1226. /// </summary>
  1227. /// <param name="regionID">Unique Identifier of the Region to load parcel data for</param>
  1228. public void loadAllLandObjectsFromStorage(UUID regionID)
  1229. {
  1230. m_log.Info("[SCENE]: Loading land objects from storage");
  1231. List<LandData> landData = m_storageManager.DataStore.LoadLandObjects(regionID);
  1232. if (LandChannel != null)
  1233. {
  1234. if (landData.Count == 0)
  1235. {
  1236. EventManager.TriggerNoticeNoLandDataFromStorage();
  1237. }
  1238. else
  1239. {
  1240. EventManager.TriggerIncomingLandDataFromStorage(landData);
  1241. }
  1242. }
  1243. else
  1244. {
  1245. m_log.Error("[SCENE]: Land Channel is not defined. Cannot load from storage!");
  1246. }
  1247. }
  1248. #endregion
  1249. #region Primitives Methods
  1250. /// <summary>
  1251. /// Loads the World's objects
  1252. /// </summary>
  1253. public virtual void LoadPrimsFromStorage(UUID regionID)
  1254. {
  1255. m_log.Info("[SCENE]: Loading objects from datastore");
  1256. List<SceneObjectGroup> PrimsFromDB = m_storageManager.DataStore.LoadObjects(regionID);
  1257. m_log.Info("[SCENE]: Loaded " + PrimsFromDB.Count + " objects from the datastore");
  1258. foreach (SceneObjectGroup group in PrimsFromDB)
  1259. {
  1260. if (group.RootPart == null)
  1261. {
  1262. m_log.ErrorFormat("[SCENE] Found a SceneObjectGroup with m_rootPart == null and {0} children",
  1263. group.Children == null ? 0 : group.Children.Count);
  1264. }
  1265. AddRestoredSceneObject(group, true, true);
  1266. SceneObjectPart rootPart = group.GetChildPart(group.UUID);
  1267. rootPart.ObjectFlags &= ~(uint)PrimFlags.Scripted;
  1268. rootPart.TrimPermissions();
  1269. group.CheckSculptAndLoad();
  1270. //rootPart.DoPhysicsPropertyUpdate(UsePhysics, true);
  1271. }
  1272. m_log.Info("[SCENE]: Loaded " + PrimsFromDB.Count.ToString() + " SceneObject(s)");
  1273. }
  1274. /// <summary>
  1275. /// Gets a new rez location based on the raycast and the size of the object that is being rezzed.
  1276. /// </summary>
  1277. /// <param name="RayStart"></param>
  1278. /// <param name="RayEnd"></param>
  1279. /// <param name="RayTargetID"></param>
  1280. /// <param name="rot"></param>
  1281. /// <param name="bypassRayCast"></param>
  1282. /// <param name="RayEndIsIntersection"></param>
  1283. /// <param name="frontFacesOnly"></param>
  1284. /// <param name="scale"></param>
  1285. /// <param name="FaceCenter"></param>
  1286. /// <returns></returns>
  1287. public Vector3 GetNewRezLocation(Vector3 RayStart, Vector3 RayEnd, UUID RayTargetID, Quaternion rot, byte bypassRayCast, byte RayEndIsIntersection, bool frontFacesOnly, Vector3 scale, bool FaceCenter)
  1288. {
  1289. Vector3 pos = Vector3.Zero;
  1290. if (RayEndIsIntersection == (byte)1)
  1291. {
  1292. pos = RayEnd;
  1293. return pos;
  1294. }
  1295. if (RayTargetID != UUID.Zero)
  1296. {
  1297. SceneObjectPart target = GetSceneObjectPart(RayTargetID);
  1298. Vector3 direction = Vector3.Normalize(RayEnd - RayStart);
  1299. Vector3 AXOrigin = new Vector3(RayStart.X, RayStart.Y, RayStart.Z);
  1300. Vector3 AXdirection = new Vector3(direction.X, direction.Y, direction.Z);
  1301. if (target != null)
  1302. {
  1303. pos = target.AbsolutePosition;
  1304. //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());
  1305. // TODO: Raytrace better here
  1306. //EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection));
  1307. Ray NewRay = new Ray(AXOrigin, AXdirection);
  1308. // Ray Trace against target here
  1309. EntityIntersection ei = target.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, FaceCenter);
  1310. // Un-comment out the following line to Get Raytrace results printed to the console.
  1311. // m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString());
  1312. float ScaleOffset = 0.5f;
  1313. // If we hit something
  1314. if (ei.HitTF)
  1315. {
  1316. Vector3 scaleComponent = new Vector3(ei.AAfaceNormal.X, ei.AAfaceNormal.Y, ei.AAfaceNormal.Z);
  1317. if (scaleComponent.X != 0) ScaleOffset = scale.X;
  1318. if (scaleComponent.Y != 0) ScaleOffset = scale.Y;
  1319. if (scaleComponent.Z != 0) ScaleOffset = scale.Z;
  1320. ScaleOffset = Math.Abs(ScaleOffset);
  1321. Vector3 intersectionpoint = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z);
  1322. Vector3 normal = new Vector3(ei.normal.X, ei.normal.Y, ei.normal.Z);
  1323. // Set the position to the intersection point
  1324. Vector3 offset = (normal * (ScaleOffset / 2f));
  1325. pos = (intersectionpoint + offset);
  1326. //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
  1327. //And in cases when we weren't rezzing from inventory we were re-adding the 0.25 straight after calling this method
  1328. // Un-offset the prim (it gets offset later by the consumer method)
  1329. //pos.Z -= 0.25F;
  1330. }
  1331. return pos;
  1332. }
  1333. else
  1334. {
  1335. // We don't have a target here, so we're going to raytrace all the objects in the scene.
  1336. EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection), true, false);
  1337. // Un-comment the following line to print the raytrace results to the console.
  1338. //m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString());
  1339. if (ei.HitTF)
  1340. {
  1341. pos = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z);
  1342. } else
  1343. {
  1344. // fall back to our stupid functionality
  1345. pos = RayEnd;
  1346. }
  1347. return pos;
  1348. }
  1349. }
  1350. else
  1351. {
  1352. // fall back to our stupid functionality
  1353. pos = RayEnd;
  1354. //increase height so its above the ground.
  1355. //should be getting the normal of the ground at the rez point and using that?
  1356. pos.Z += scale.Z / 2f;
  1357. return pos;
  1358. }
  1359. }
  1360. /// <summary>
  1361. /// Create a New SceneObjectGroup/Part by raycasting
  1362. /// </summary>
  1363. /// <param name="ownerID"></param>
  1364. /// <param name="groupID"></param>
  1365. /// <param name="RayEnd"></param>
  1366. /// <param name="rot"></param>
  1367. /// <param name="shape"></param>
  1368. /// <param name="bypassRaycast"></param>
  1369. /// <param name="RayStart"></param>
  1370. /// <param name="RayTargetID"></param>
  1371. /// <param name="RayEndIsIntersection"></param>
  1372. public virtual void AddNewPrim(UUID ownerID, UUID groupID, Vector3 RayEnd, Quaternion rot, PrimitiveBaseShape shape,
  1373. byte bypassRaycast, Vector3 RayStart, UUID RayTargetID,
  1374. byte RayEndIsIntersection)
  1375. {
  1376. Vector3 pos = GetNewRezLocation(RayStart, RayEnd, RayTargetID, rot, bypassRaycast, RayEndIsIntersection, true, new Vector3(0.5f, 0.5f, 0.5f), false);
  1377. if (Permissions.CanRezObject(1, ownerID, pos))
  1378. {
  1379. // rez ON the ground, not IN the ground
  1380. // pos.Z += 0.25F; The rez point should now be correct so that its not in the ground
  1381. AddNewPrim(ownerID, groupID, pos, rot, shape);
  1382. }
  1383. }
  1384. public virtual SceneObjectGroup AddNewPrim(
  1385. UUID ownerID, UUID groupID, Vector3 pos, Quaternion rot, PrimitiveBaseShape shape)
  1386. {
  1387. //m_log.DebugFormat(
  1388. // "[SCENE]: Scene.AddNewPrim() pcode {0} called for {1} in {2}", shape.PCode, ownerID, RegionInfo.RegionName);
  1389. // If an entity creator has been registered for this prim type then use that
  1390. if (m_entityCreators.ContainsKey((PCode)shape.PCode))
  1391. return m_entityCreators[(PCode)shape.PCode].CreateEntity(ownerID, groupID, pos, rot, shape);
  1392. // Otherwise, use this default creation code;
  1393. SceneObjectGroup sceneObject = new SceneObjectGroup(ownerID, pos, rot, shape);
  1394. AddNewSceneObject(sceneObject, true);
  1395. sceneObject.SetGroup(groupID, null);
  1396. return sceneObject;
  1397. }
  1398. /// <summary>
  1399. /// Add an object into the scene that has come from storage
  1400. /// </summary>
  1401. ///
  1402. /// <param name="sceneObject"></param>
  1403. /// <param name="attachToBackup">
  1404. /// If true, changes to the object will be reflected in its persisted data
  1405. /// If false, the persisted data will not be changed even if the object in the scene is changed
  1406. /// </param>
  1407. /// <param name="alreadyPersisted">
  1408. /// If true, we won't persist this object until it changes
  1409. /// If false, we'll persist this object immediately
  1410. /// </param>
  1411. /// <returns>
  1412. /// true if the object was added, false if an object with the same uuid was already in the scene
  1413. /// </returns>
  1414. public bool AddRestoredSceneObject(
  1415. SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted)
  1416. {
  1417. return m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted);
  1418. }
  1419. /// <summary>
  1420. /// Add a newly created object to the scene
  1421. /// </summary>
  1422. /// <param name="sceneObject"></param>
  1423. /// <param name="attachToBackup">
  1424. /// If true, the object is made persistent into the scene.
  1425. /// If false, the object will not persist over server restarts
  1426. /// </param>
  1427. public bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup)
  1428. {
  1429. return m_sceneGraph.AddNewSceneObject(sceneObject, attachToBackup);
  1430. }
  1431. /// <summary>
  1432. /// Delete every object from the scene
  1433. /// </summary>
  1434. public void DeleteAllSceneObjects()
  1435. {
  1436. lock (Entities)
  1437. {
  1438. ICollection<EntityBase> entities = new List<EntityBase>(Entities);
  1439. foreach (EntityBase e in entities)
  1440. {
  1441. if (e is SceneObjectGroup)
  1442. DeleteSceneObject((SceneObjectGroup)e, false);
  1443. }
  1444. }
  1445. }
  1446. /// <summary>
  1447. /// Synchronously delete the given object from the scene.
  1448. /// </summary>
  1449. /// <param name="group">Object Id</param>
  1450. /// <param name="silent">Suppress broadcasting changes to other clients.</param>
  1451. public void DeleteSceneObject(SceneObjectGroup group, bool silent)
  1452. {
  1453. //SceneObjectPart rootPart = group.GetChildPart(group.UUID);
  1454. // Serialise calls to RemoveScriptInstances to avoid
  1455. // deadlocking on m_parts inside SceneObjectGroup
  1456. lock (m_deleting_scene_object)
  1457. {
  1458. group.RemoveScriptInstances();
  1459. }
  1460. foreach (SceneObjectPart part in group.Children.Values)
  1461. {
  1462. if (part.IsJoint() && ((part.ObjectFlags&(uint)PrimFlags.Physics) != 0))
  1463. {
  1464. PhysicsScene.RequestJointDeletion(part.Name); // FIXME: what if the name changed?
  1465. }
  1466. else if (part.PhysActor != null)
  1467. {
  1468. PhysicsScene.RemovePrim(part.PhysActor);
  1469. part.PhysActor = null;
  1470. }
  1471. }
  1472. // if (rootPart.PhysActor != null)
  1473. // {
  1474. // PhysicsScene.RemovePrim(rootPart.PhysActor);
  1475. // rootPart.PhysActor = null;
  1476. // }
  1477. if (UnlinkSceneObject(group.UUID, false))
  1478. {
  1479. EventManager.TriggerObjectBeingRemovedFromScene(group);
  1480. EventManager.TriggerParcelPrimCountTainted();
  1481. }
  1482. group.DeleteGroup(silent);
  1483. }
  1484. /// <summary>
  1485. /// Unlink the given object from the scene. Unlike delete, this just removes the record of the object - the
  1486. /// object itself is not destroyed.
  1487. /// </summary>
  1488. /// <param name="uuid">Id of object.</param>
  1489. /// <returns>true if the object was in the scene, false if it was not</returns>
  1490. /// <param name="softDelete">If true, only deletes from scene, but keeps object in database.</param>
  1491. public bool UnlinkSceneObject(UUID uuid, bool softDelete)
  1492. {
  1493. if (m_sceneGraph.DeleteSceneObject(uuid, softDelete))
  1494. {
  1495. if (!softDelete)
  1496. {
  1497. m_storageManager.DataStore.RemoveObject(uuid,
  1498. m_regInfo.RegionID);
  1499. }
  1500. return true;
  1501. }
  1502. return false;
  1503. }
  1504. /// <summary>
  1505. /// Move the given scene object into a new region depending on which region its absolute position has moved
  1506. /// into.
  1507. ///
  1508. /// This method locates the new region handle and offsets the prim position for the new region
  1509. /// </summary>
  1510. /// <param name="attemptedPosition">the attempted out of region position of the scene object</param>
  1511. /// <param name="grp">the scene object that we're crossing</param>
  1512. public void CrossPrimGroupIntoNewRegion(Vector3 attemptedPosition, SceneObjectGroup grp, bool silent)
  1513. {
  1514. if (grp == null)
  1515. return;
  1516. if (grp.IsDeleted)
  1517. return;
  1518. if (grp.RootPart.DIE_AT_EDGE)
  1519. {
  1520. // We remove the object here
  1521. try
  1522. {
  1523. DeleteSceneObject(grp, false);
  1524. }
  1525. catch (Exception)
  1526. {
  1527. m_log.Warn("[DATABASE]: exception when trying to remove the prim that crossed the border.");
  1528. }
  1529. return;
  1530. }
  1531. int thisx = (int)RegionInfo.RegionLocX;
  1532. int thisy = (int)RegionInfo.RegionLocY;
  1533. Vector3 EastCross = new Vector3(0.1f,0,0);
  1534. Vector3 WestCross = new Vector3(-0.1f, 0, 0);
  1535. Vector3 NorthCross = new Vector3(0, 0.1f, 0);
  1536. Vector3 SouthCross = new Vector3(0, -0.1f, 0);
  1537. // use this if no borders were crossed!
  1538. ulong newRegionHandle
  1539. = Util.UIntsToLong((uint)((thisx) * Constants.RegionSize),
  1540. (uint)((thisy) * Constants.RegionSize));
  1541. Vector3 pos = attemptedPosition;
  1542. int changeX = 1;
  1543. int changeY = 1;
  1544. if (TestBorderCross(attemptedPosition + WestCross, Cardinals.W))
  1545. {
  1546. if (TestBorderCross(attemptedPosition + SouthCross, Cardinals.S))
  1547. {
  1548. Border crossedBorderx = GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W);
  1549. if (crossedBorderx.BorderLine.Z > 0)
  1550. {
  1551. pos.X = ((pos.X + crossedBorderx.BorderLine.Z));
  1552. changeX = (int)(crossedBorderx.BorderLine.Z /(int) Constants.RegionSize);
  1553. }
  1554. else
  1555. pos.X = ((pos.X + Constants.RegionSize));
  1556. Border crossedBordery = GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S);
  1557. //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)
  1558. if (crossedBordery.BorderLine.Z > 0)
  1559. {
  1560. pos.Y = ((pos.Y + crossedBordery.BorderLine.Z));
  1561. changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize);
  1562. }
  1563. else
  1564. pos.Y = ((pos.Y + Constants.RegionSize));
  1565. newRegionHandle
  1566. = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize),
  1567. (uint)((thisy - changeY) * Constants.RegionSize));
  1568. // x - 1
  1569. // y - 1
  1570. }
  1571. else if (TestBorderCross(attemptedPosition + NorthCross, Cardinals.N))
  1572. {
  1573. Border crossedBorderx = GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W);
  1574. if (crossedBorderx.BorderLine.Z > 0)
  1575. {
  1576. pos.X = ((pos.X + crossedBorderx.BorderLine.Z));
  1577. changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize);
  1578. }
  1579. else
  1580. pos.X = ((pos.X + Constants.RegionSize));
  1581. Border crossedBordery = GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S);
  1582. //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)
  1583. if (crossedBordery.BorderLine.Z > 0)
  1584. {
  1585. pos.Y = ((pos.Y + crossedBordery.BorderLine.Z));
  1586. changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize);
  1587. }
  1588. else
  1589. pos.Y = ((pos.Y + Constants.RegionSize));
  1590. newRegionHandle
  1591. = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize),
  1592. (uint)((thisy + changeY) * Constants.RegionSize));
  1593. // x - 1
  1594. // y + 1
  1595. }
  1596. else
  1597. {
  1598. Border crossedBorderx = GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W);
  1599. if (crossedBorderx.BorderLine.Z > 0)
  1600. {
  1601. pos.X = ((pos.X + crossedBorderx.BorderLine.Z));
  1602. changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize);
  1603. }
  1604. else
  1605. pos.X = ((pos.X + Constants.RegionSize));
  1606. newRegionHandle
  1607. = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize),
  1608. (uint) (thisy*Constants.RegionSize));
  1609. // x - 1
  1610. }
  1611. }
  1612. else if (TestBorderCross(attemptedPosition + EastCross, Cardinals.E))
  1613. {
  1614. if (TestBorderCross(attemptedPosition + SouthCross, Cardinals.S))
  1615. {
  1616. pos.X = ((pos.X - Constants.RegionSize));
  1617. Border crossedBordery = GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S);
  1618. //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)
  1619. if (crossedBordery.BorderLine.Z > 0)
  1620. {
  1621. pos.Y = ((pos.Y + crossedBordery.BorderLine.Z));
  1622. changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize);
  1623. }
  1624. else
  1625. pos.Y = ((pos.Y + Constants.RegionSize));
  1626. newRegionHandle
  1627. = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize),
  1628. (uint)((thisy - changeY) * Constants.RegionSize));
  1629. // x + 1
  1630. // y - 1
  1631. }
  1632. else if (TestBorderCross(attemptedPosition + NorthCross, Cardinals.N))
  1633. {
  1634. pos.X = ((pos.X - Constants.RegionSize));
  1635. pos.Y = ((pos.Y - Constants.RegionSize));
  1636. newRegionHandle
  1637. = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize),
  1638. (uint)((thisy + changeY) * Constants.RegionSize));
  1639. // x + 1
  1640. // y + 1
  1641. }
  1642. else
  1643. {
  1644. pos.X = ((pos.X - Constants.RegionSize));
  1645. newRegionHandle
  1646. = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize),
  1647. (uint) (thisy*Constants.RegionSize));
  1648. // x + 1
  1649. }
  1650. }
  1651. else if (TestBorderCross(attemptedPosition + SouthCross, Cardinals.S))
  1652. {
  1653. Border crossedBordery = GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S);
  1654. //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)
  1655. if (crossedBordery.BorderLine.Z > 0)
  1656. {
  1657. pos.Y = ((pos.Y + crossedBordery.BorderLine.Z));
  1658. changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize);
  1659. }
  1660. else
  1661. pos.Y = ((pos.Y + Constants.RegionSize));
  1662. newRegionHandle
  1663. = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy - changeY) * Constants.RegionSize));
  1664. // y - 1
  1665. }
  1666. else if (TestBorderCross(attemptedPosition + NorthCross, Cardinals.N))
  1667. {
  1668. pos.Y = ((pos.Y - Constants.RegionSize));
  1669. newRegionHandle
  1670. = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy + changeY) * Constants.RegionSize));
  1671. // y + 1
  1672. }
  1673. // Offset the positions for the new region across the border
  1674. Vector3 oldGroupPosition = grp.RootPart.GroupPosition;
  1675. grp.OffsetForNewRegion(pos);
  1676. // If we fail to cross the border, then reset the position of the scene object on that border.
  1677. if (!CrossPrimGroupIntoNewRegion(newRegionHandle, grp, silent))
  1678. {
  1679. grp.OffsetForNewRegion(oldGroupPosition);
  1680. grp.ScheduleGroupForFullUpdate();
  1681. }
  1682. }
  1683. public Border GetCrossedBorder(Vector3 position, Cardinals gridline)
  1684. {
  1685. if (BordersLocked)
  1686. {
  1687. switch (gridline)
  1688. {
  1689. case Cardinals.N:
  1690. lock (NorthBorders)
  1691. {
  1692. foreach (Border b in NorthBorders)
  1693. {
  1694. if (b.TestCross(position))
  1695. return b;
  1696. }
  1697. }
  1698. break;
  1699. case Cardinals.S:
  1700. lock (SouthBorders)
  1701. {
  1702. foreach (Border b in SouthBorders)
  1703. {
  1704. if (b.TestCross(position))
  1705. return b;
  1706. }
  1707. }
  1708. break;
  1709. case Cardinals.E:
  1710. lock (EastBorders)
  1711. {
  1712. foreach (Border b in EastBorders)
  1713. {
  1714. if (b.TestCross(position))
  1715. return b;
  1716. }
  1717. }
  1718. break;
  1719. case Cardinals.W:
  1720. lock (WestBorders)
  1721. {
  1722. foreach (Border b in WestBorders)
  1723. {
  1724. if (b.TestCross(position))
  1725. return b;
  1726. }
  1727. }
  1728. break;
  1729. }
  1730. }
  1731. else
  1732. {
  1733. switch (gridline)
  1734. {
  1735. case Cardinals.N:
  1736. foreach (Border b in NorthBorders)
  1737. {
  1738. if (b.TestCross(position))
  1739. return b;
  1740. }
  1741. break;
  1742. case Cardinals.S:
  1743. foreach (Border b in SouthBorders)
  1744. {
  1745. if (b.TestCross(position))
  1746. return b;
  1747. }
  1748. break;
  1749. case Cardinals.E:
  1750. foreach (Border b in EastBorders)
  1751. {
  1752. if (b.TestCross(position))
  1753. return b;
  1754. }
  1755. break;
  1756. case Cardinals.W:
  1757. foreach (Border b in WestBorders)
  1758. {
  1759. if (b.TestCross(position))
  1760. return b;
  1761. }
  1762. break;
  1763. }
  1764. }
  1765. return null;
  1766. }
  1767. public bool TestBorderCross(Vector3 position, Cardinals border)
  1768. {
  1769. if (BordersLocked)
  1770. {
  1771. switch (border)
  1772. {
  1773. case Cardinals.N:
  1774. lock (NorthBorders)
  1775. {
  1776. foreach (Border b in NorthBorders)
  1777. {
  1778. if (b.TestCross(position))
  1779. return true;
  1780. }
  1781. }
  1782. break;
  1783. case Cardinals.E:
  1784. lock (EastBorders)
  1785. {
  1786. foreach (Border b in EastBorders)
  1787. {
  1788. if (b.TestCross(position))
  1789. return true;
  1790. }
  1791. }
  1792. break;
  1793. case Cardinals.S:
  1794. lock (SouthBorders)
  1795. {
  1796. foreach (Border b in SouthBorders)
  1797. {
  1798. if (b.TestCross(position))
  1799. return true;
  1800. }
  1801. }
  1802. break;
  1803. case Cardinals.W:
  1804. lock (WestBorders)
  1805. {
  1806. foreach (Border b in WestBorders)
  1807. {
  1808. if (b.TestCross(position))
  1809. return true;
  1810. }
  1811. }
  1812. break;
  1813. }
  1814. }
  1815. else
  1816. {
  1817. switch (border)
  1818. {
  1819. case Cardinals.N:
  1820. foreach (Border b in NorthBorders)
  1821. {
  1822. if (b.TestCross(position))
  1823. return true;
  1824. }
  1825. break;
  1826. case Cardinals.E:
  1827. foreach (Border b in EastBorders)
  1828. {
  1829. if (b.TestCross(position))
  1830. return true;
  1831. }
  1832. break;
  1833. case Cardinals.S:
  1834. foreach (Border b in SouthBorders)
  1835. {
  1836. if (b.TestCross(position))
  1837. return true;
  1838. }
  1839. break;
  1840. case Cardinals.W:
  1841. foreach (Border b in WestBorders)
  1842. {
  1843. if (b.TestCross(position))
  1844. return true;
  1845. }
  1846. break;
  1847. }
  1848. }
  1849. return false;
  1850. }
  1851. /// <summary>
  1852. /// Move the given scene object into a new region
  1853. /// </summary>
  1854. /// <param name="newRegionHandle"></param>
  1855. /// <param name="grp">Scene Object Group that we're crossing</param>
  1856. /// <returns>
  1857. /// true if the crossing itself was successful, false on failure
  1858. /// FIMXE: we still return true if the crossing object was not successfully deleted from the originating region
  1859. /// </returns>
  1860. public bool CrossPrimGroupIntoNewRegion(ulong newRegionHandle, SceneObjectGroup grp, bool silent)
  1861. {
  1862. //m_log.Debug(" >>> CrossPrimGroupIntoNewRegion <<<");
  1863. bool successYN = false;
  1864. grp.RootPart.UpdateFlag = 0;
  1865. //int primcrossingXMLmethod = 0;
  1866. if (newRegionHandle != 0)
  1867. {
  1868. //string objectState = grp.GetStateSnapshot();
  1869. //successYN
  1870. // = m_sceneGridService.PrimCrossToNeighboringRegion(
  1871. // newRegionHandle, grp.UUID, m_serialiser.SaveGroupToXml2(grp), primcrossingXMLmethod);
  1872. //if (successYN && (objectState != "") && m_allowScriptCrossings)
  1873. //{
  1874. // successYN = m_sceneGridService.PrimCrossToNeighboringRegion(
  1875. // newRegionHandle, grp.UUID, objectState, 100);
  1876. //}
  1877. // And the new channel...
  1878. if (m_interregionCommsOut != null)
  1879. successYN = m_interregionCommsOut.SendCreateObject(newRegionHandle, grp, true);
  1880. if (successYN)
  1881. {
  1882. // We remove the object here
  1883. try
  1884. {
  1885. DeleteSceneObject(grp, silent);
  1886. }
  1887. catch (Exception e)
  1888. {
  1889. m_log.ErrorFormat(
  1890. "[INTERREGION]: Exception deleting the old object left behind on a border crossing for {0}, {1}",
  1891. grp, e);
  1892. }
  1893. }
  1894. else
  1895. {
  1896. if (!grp.IsDeleted)
  1897. {
  1898. if (grp.RootPart.PhysActor != null)
  1899. {
  1900. grp.RootPart.PhysActor.CrossingFailure();
  1901. }
  1902. }
  1903. m_log.ErrorFormat("[INTERREGION]: Prim crossing failed for {0}", grp);
  1904. }
  1905. }
  1906. else
  1907. {
  1908. m_log.Error("[INTERREGION]: region handle was unexpectedly 0 in Scene.CrossPrimGroupIntoNewRegion()");
  1909. }
  1910. return successYN;
  1911. }
  1912. /// <summary>
  1913. /// Handle a scene object that is crossing into this region from another.
  1914. /// NOTE: Unused as of 2009-02-09. Soon to be deleted.
  1915. /// </summary>
  1916. /// <param name="regionHandle"></param>
  1917. /// <param name="primID"></param>
  1918. /// <param name="objXMLData"></param>
  1919. /// <param name="XMLMethod"></param>
  1920. /// <returns></returns>
  1921. public bool IncomingInterRegionPrimGroup(UUID primID, string objXMLData, int XMLMethod)
  1922. {
  1923. if (XMLMethod == 0)
  1924. {
  1925. m_log.DebugFormat("[INTERREGION]: A new prim {0} arrived from a neighbor", primID);
  1926. SceneObjectGroup sceneObject = m_serialiser.DeserializeGroupFromXml2(objXMLData);
  1927. if (sceneObject.IsAttachment)
  1928. sceneObject.RootPart.ObjectFlags |= (uint)PrimFlags.Phantom;
  1929. return AddSceneObject(sceneObject);
  1930. }
  1931. else if ((XMLMethod == 100) && m_allowScriptCrossings)
  1932. {
  1933. m_log.Warn("[INTERREGION]: Prim state data arrived from a neighbor");
  1934. XmlDocument doc = new XmlDocument();
  1935. doc.LoadXml(objXMLData);
  1936. XmlNodeList rootL = doc.GetElementsByTagName("ScriptData");
  1937. if (rootL.Count == 1)
  1938. {
  1939. XmlNode rootNode = rootL[0];
  1940. if (rootNode != null)
  1941. {
  1942. XmlNodeList partL = rootNode.ChildNodes;
  1943. foreach (XmlNode part in partL)
  1944. {
  1945. XmlNodeList nodeL = part.ChildNodes;
  1946. switch (part.Name)
  1947. {
  1948. case "Assemblies":
  1949. foreach (XmlNode asm in nodeL)
  1950. {
  1951. string fn = asm.Attributes.GetNamedItem("Filename").Value;
  1952. Byte[] filedata = Convert.FromBase64String(asm.InnerText);
  1953. string path = Path.Combine("ScriptEngines", RegionInfo.RegionID.ToString());
  1954. path = Path.Combine(path, fn);
  1955. if (!File.Exists(path))
  1956. {
  1957. FileStream fs = File.Create(path);
  1958. fs.Write(filedata, 0, filedata.Length);
  1959. fs.Close();
  1960. }
  1961. }
  1962. break;
  1963. case "ScriptStates":
  1964. foreach (XmlNode st in nodeL)
  1965. {
  1966. string id = st.Attributes.GetNamedItem("UUID").Value;
  1967. UUID uuid = new UUID(id);
  1968. XmlNode state = st.ChildNodes[0];
  1969. XmlDocument sdoc = new XmlDocument();
  1970. XmlNode sxmlnode = sdoc.CreateNode(
  1971. XmlNodeType.XmlDeclaration,
  1972. "", "");
  1973. sdoc.AppendChild(sxmlnode);
  1974. XmlNode newnode = sdoc.ImportNode(state, true);
  1975. sdoc.AppendChild(newnode);
  1976. string spath = Path.Combine("ScriptEngines", RegionInfo.RegionID.ToString());
  1977. spath = Path.Combine(spath, uuid.ToString());
  1978. FileStream sfs = File.Create(spath + ".state");
  1979. ASCIIEncoding enc = new ASCIIEncoding();
  1980. Byte[] buf = enc.GetBytes(sdoc.InnerXml);
  1981. sfs.Write(buf, 0, buf.Length);
  1982. sfs.Close();
  1983. }
  1984. break;
  1985. }
  1986. }
  1987. }
  1988. }
  1989. SceneObjectPart RootPrim = GetSceneObjectPart(primID);
  1990. RootPrim.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, 1);
  1991. return true;
  1992. }
  1993. return true;
  1994. }
  1995. public bool IncomingCreateObject(ISceneObject sog)
  1996. {
  1997. //m_log.Debug(" >>> IncomingCreateObject <<< " + ((SceneObjectGroup)sog).AbsolutePosition + " deleted? " + ((SceneObjectGroup)sog).IsDeleted);
  1998. SceneObjectGroup newObject;
  1999. try
  2000. {
  2001. newObject = (SceneObjectGroup)sog;
  2002. }
  2003. catch (Exception e)
  2004. {
  2005. m_log.WarnFormat("[SCENE]: Problem casting object: {0}", e.Message);
  2006. return false;
  2007. }
  2008. if (!AddSceneObject(newObject))
  2009. {
  2010. m_log.DebugFormat("[SCENE]: Problem adding scene object {0} in {1} ", sog.UUID, RegionInfo.RegionName);
  2011. return false;
  2012. }
  2013. newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, 1);
  2014. return true;
  2015. }
  2016. /// <summary>
  2017. /// Attachment rezzing
  2018. /// </summary>
  2019. /// <param name="userID">Agent Unique ID</param>
  2020. /// <param name="itemID">Object ID</param>
  2021. /// <returns>False</returns>
  2022. public virtual bool IncomingCreateObject(UUID userID, UUID itemID)
  2023. {
  2024. ScenePresence sp = GetScenePresence(userID);
  2025. if (sp != null)
  2026. {
  2027. uint attPt = (uint)sp.Appearance.GetAttachpoint(itemID);
  2028. m_sceneGraph.RezSingleAttachment(sp.ControllingClient, itemID, attPt);
  2029. }
  2030. return false;
  2031. }
  2032. /// <summary>
  2033. /// Adds a Scene Object group to the Scene.
  2034. /// Verifies that the creator of the object is not banned from the simulator.
  2035. /// Checks if the item is an Attachment
  2036. /// </summary>
  2037. /// <param name="sceneObject"></param>
  2038. /// <returns>True if the SceneObjectGroup was added, False if it was not</returns>
  2039. public bool AddSceneObject(SceneObjectGroup sceneObject)
  2040. {
  2041. // If the user is banned, we won't let any of their objects
  2042. // enter. Period.
  2043. //
  2044. if (m_regInfo.EstateSettings.IsBanned(sceneObject.OwnerID))
  2045. {
  2046. m_log.Info("[INTERREGION]: Denied prim crossing for " +
  2047. "banned avatar");
  2048. return false;
  2049. }
  2050. // Force allocation of new LocalId
  2051. //
  2052. foreach (SceneObjectPart p in sceneObject.Children.Values)
  2053. p.LocalId = 0;
  2054. if ((sceneObject.RootPart.Shape.PCode == (byte)PCode.Prim) && (sceneObject.RootPart.Shape.State != 0)) // Attachment
  2055. {
  2056. sceneObject.RootPart.AddFlag(PrimFlags.TemporaryOnRez);
  2057. sceneObject.RootPart.AddFlag(PrimFlags.Phantom);
  2058. AddRestoredSceneObject(sceneObject, false, false);
  2059. // Handle attachment special case
  2060. SceneObjectPart RootPrim = sceneObject.RootPart;
  2061. // Fix up attachment Parent Local ID
  2062. ScenePresence sp = GetScenePresence(sceneObject.OwnerID);
  2063. //uint parentLocalID = 0;
  2064. if (sp != null)
  2065. {
  2066. //parentLocalID = sp.LocalId;
  2067. //sceneObject.RootPart.IsAttachment = true;
  2068. //sceneObject.RootPart.SetParentLocalId(parentLocalID);
  2069. SceneObjectGroup grp = sceneObject;
  2070. //RootPrim.SetParentLocalId(parentLocalID);
  2071. m_log.DebugFormat("[ATTACHMENT]: Received " +
  2072. "attachment {0}, inworld asset id {1}",
  2073. //grp.RootPart.LastOwnerID.ToString(),
  2074. grp.GetFromItemID(),
  2075. grp.UUID.ToString());
  2076. //grp.SetFromAssetID(grp.RootPart.LastOwnerID);
  2077. m_log.DebugFormat("[ATTACHMENT]: Attach " +
  2078. "to avatar {0} at position {1}",
  2079. sp.UUID.ToString(), grp.AbsolutePosition);
  2080. AttachObject(sp.ControllingClient,
  2081. grp.LocalId, (uint)0,
  2082. grp.GroupRotation,
  2083. grp.AbsolutePosition, false);
  2084. RootPrim.RemFlag(PrimFlags.TemporaryOnRez);
  2085. grp.SendGroupFullUpdate();
  2086. }
  2087. else
  2088. {
  2089. RootPrim.RemFlag(PrimFlags.TemporaryOnRez);
  2090. RootPrim.AddFlag(PrimFlags.TemporaryOnRez);
  2091. }
  2092. }
  2093. else
  2094. {
  2095. AddRestoredSceneObject(sceneObject, true, false);
  2096. if (!Permissions.CanObjectEntry(sceneObject.UUID,
  2097. true, sceneObject.AbsolutePosition))
  2098. {
  2099. // Deny non attachments based on parcel settings
  2100. //
  2101. m_log.Info("[INTERREGION]: Denied prim crossing " +
  2102. "because of parcel settings");
  2103. DeleteSceneObject(sceneObject, false);
  2104. return false;
  2105. }
  2106. }
  2107. return true;
  2108. }
  2109. #endregion
  2110. #region Add/Remove Avatar Methods
  2111. /// <summary>
  2112. /// Adding a New Client and Create a Presence for it.
  2113. /// </summary>
  2114. /// <param name="client"></param>
  2115. public override void AddNewClient(IClientAPI client)
  2116. {
  2117. ClientManager.Add(client);
  2118. CheckHeartbeat();
  2119. SubscribeToClientEvents(client);
  2120. ScenePresence presence;
  2121. if (m_restorePresences.ContainsKey(client.AgentId))
  2122. {
  2123. m_log.DebugFormat("[SCENE]: Restoring agent {0} {1} in {2}", client.Name, client.AgentId, RegionInfo.RegionName);
  2124. presence = m_restorePresences[client.AgentId];
  2125. m_restorePresences.Remove(client.AgentId);
  2126. // This is one of two paths to create avatars that are
  2127. // used. This tends to get called more in standalone
  2128. // than grid, not really sure why, but as such needs
  2129. // an explicity appearance lookup here.
  2130. AvatarAppearance appearance = null;
  2131. GetAvatarAppearance(client, out appearance);
  2132. presence.Appearance = appearance;
  2133. presence.initializeScenePresence(client, RegionInfo, this);
  2134. m_sceneGraph.AddScenePresence(presence);
  2135. lock (m_restorePresences)
  2136. {
  2137. Monitor.PulseAll(m_restorePresences);
  2138. }
  2139. }
  2140. else
  2141. {
  2142. AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode);
  2143. m_log.Debug("[Scene] Adding new agent " + client.Name + " to scene " + RegionInfo.RegionName);
  2144. /*
  2145. string logMsg = string.Format("[SCENE]: Adding new {0} agent for {1} in {2}",
  2146. ((aCircuit.child == true) ? "child" : "root"), client.Name,
  2147. RegionInfo.RegionName);
  2148. m_log.Debug(logMsg);
  2149. */
  2150. CommsManager.UserProfileCacheService.AddNewUser(client.AgentId);
  2151. ScenePresence sp = CreateAndAddScenePresence(client);
  2152. // HERE!!! Do the initial attachments right here
  2153. // first agent upon login is a root agent by design.
  2154. // All other AddNewClient calls find aCircuit.child to be true
  2155. if (aCircuit == null || aCircuit.child == false)
  2156. {
  2157. sp.IsChildAgent = false;
  2158. Util.FireAndForget(delegate(object o) { sp.RezAttachments(); });
  2159. }
  2160. }
  2161. m_LastLogin = Environment.TickCount;
  2162. EventManager.TriggerOnNewClient(client);
  2163. }
  2164. /// <summary>
  2165. /// Register for events from the client
  2166. /// </summary>
  2167. /// <param name="client">The IClientAPI of the connected client</param>
  2168. public virtual void SubscribeToClientEvents(IClientAPI client)
  2169. {
  2170. SubscribeToClientTerrainEvents(client);
  2171. SubscribeToClientPrimEvents(client);
  2172. SubscribeToClientPrimRezEvents(client);
  2173. SubscribeToClientInventoryEvents(client);
  2174. SubscribeToClientAttachmentEvents(client);
  2175. SubscribeToClientTeleportEvents(client);
  2176. SubscribeToClientScriptEvents(client);
  2177. SubscribeToClientParcelEvents(client);
  2178. SubscribeToClientGridEvents(client);
  2179. SubscribeToClientGodEvents(client);
  2180. SubscribeToClientNetworkEvents(client);
  2181. // EventManager.TriggerOnNewClient(client);
  2182. }
  2183. public virtual void SubscribeToClientTerrainEvents(IClientAPI client)
  2184. {
  2185. client.OnRegionHandShakeReply += SendLayerData;
  2186. client.OnUnackedTerrain += TerrainUnAcked;
  2187. }
  2188. public virtual void SubscribeToClientPrimEvents(IClientAPI client)
  2189. {
  2190. client.OnUpdatePrimGroupPosition += m_sceneGraph.UpdatePrimPosition;
  2191. client.OnUpdatePrimSinglePosition += m_sceneGraph.UpdatePrimSinglePosition;
  2192. client.OnUpdatePrimGroupRotation += m_sceneGraph.UpdatePrimRotation;
  2193. client.OnUpdatePrimGroupMouseRotation += m_sceneGraph.UpdatePrimRotation;
  2194. client.OnUpdatePrimSingleRotation += m_sceneGraph.UpdatePrimSingleRotation;
  2195. client.OnUpdatePrimSingleRotationPosition += m_sceneGraph.UpdatePrimSingleRotationPosition;
  2196. client.OnUpdatePrimScale += m_sceneGraph.UpdatePrimScale;
  2197. client.OnUpdatePrimGroupScale += m_sceneGraph.UpdatePrimGroupScale;
  2198. client.OnUpdateExtraParams += m_sceneGraph.UpdateExtraParam;
  2199. client.OnUpdatePrimShape += m_sceneGraph.UpdatePrimShape;
  2200. client.OnUpdatePrimTexture += m_sceneGraph.UpdatePrimTexture;
  2201. client.OnObjectRequest += RequestPrim;
  2202. client.OnObjectSelect += SelectPrim;
  2203. client.OnObjectDeselect += DeselectPrim;
  2204. client.OnGrabUpdate += m_sceneGraph.MoveObject;
  2205. client.OnSpinStart += m_sceneGraph.SpinStart;
  2206. client.OnSpinUpdate += m_sceneGraph.SpinObject;
  2207. client.OnDeRezObject += DeRezObject;
  2208. client.OnObjectName += m_sceneGraph.PrimName;
  2209. client.OnObjectClickAction += m_sceneGraph.PrimClickAction;
  2210. client.OnObjectMaterial += m_sceneGraph.PrimMaterial;
  2211. client.OnLinkObjects += m_sceneGraph.LinkObjects;
  2212. client.OnDelinkObjects += m_sceneGraph.DelinkObjects;
  2213. client.OnObjectDuplicate += m_sceneGraph.DuplicateObject;
  2214. client.OnObjectDuplicateOnRay += doObjectDuplicateOnRay;
  2215. client.OnUpdatePrimFlags += m_sceneGraph.UpdatePrimFlags;
  2216. client.OnRequestObjectPropertiesFamily += m_sceneGraph.RequestObjectPropertiesFamily;
  2217. client.OnObjectPermissions += HandleObjectPermissionsUpdate;
  2218. client.OnGrabObject += ProcessObjectGrab;
  2219. client.OnDeGrabObject += ProcessObjectDeGrab;
  2220. client.OnUndo += m_sceneGraph.HandleUndo;
  2221. client.OnObjectDescription += m_sceneGraph.PrimDescription;
  2222. client.OnObjectDrop += m_sceneGraph.DropObject;
  2223. client.OnObjectSaleInfo += ObjectSaleInfo;
  2224. client.OnObjectIncludeInSearch += m_sceneGraph.MakeObjectSearchable;
  2225. client.OnObjectOwner += ObjectOwner;
  2226. }
  2227. public virtual void SubscribeToClientPrimRezEvents(IClientAPI client)
  2228. {
  2229. client.OnAddPrim += AddNewPrim;
  2230. client.OnRezObject += RezObject;
  2231. }
  2232. public virtual void SubscribeToClientInventoryEvents(IClientAPI client)
  2233. {
  2234. client.OnCreateNewInventoryItem += CreateNewInventoryItem;
  2235. client.OnCreateNewInventoryFolder += HandleCreateInventoryFolder;
  2236. client.OnUpdateInventoryFolder += HandleUpdateInventoryFolder;
  2237. client.OnMoveInventoryFolder += HandleMoveInventoryFolder; // 2; //!!
  2238. client.OnFetchInventoryDescendents += HandleFetchInventoryDescendents;
  2239. client.OnPurgeInventoryDescendents += HandlePurgeInventoryDescendents; // 2; //!!
  2240. client.OnFetchInventory += HandleFetchInventory;
  2241. client.OnUpdateInventoryItem += UpdateInventoryItemAsset;
  2242. client.OnCopyInventoryItem += CopyInventoryItem;
  2243. client.OnMoveInventoryItem += MoveInventoryItem;
  2244. client.OnRemoveInventoryItem += RemoveInventoryItem;
  2245. client.OnRemoveInventoryFolder += RemoveInventoryFolder;
  2246. client.OnRezScript += RezScript;
  2247. client.OnRequestTaskInventory += RequestTaskInventory;
  2248. client.OnRemoveTaskItem += RemoveTaskInventory;
  2249. client.OnUpdateTaskInventory += UpdateTaskInventory;
  2250. client.OnMoveTaskItem += ClientMoveTaskInventoryItem;
  2251. }
  2252. public virtual void SubscribeToClientAttachmentEvents(IClientAPI client)
  2253. {
  2254. client.OnRezSingleAttachmentFromInv += RezSingleAttachment;
  2255. client.OnRezMultipleAttachmentsFromInv += RezMultipleAttachments;
  2256. client.OnDetachAttachmentIntoInv += DetachSingleAttachmentToInv;
  2257. client.OnObjectAttach += m_sceneGraph.AttachObject;
  2258. client.OnObjectDetach += m_sceneGraph.DetachObject;
  2259. }
  2260. public virtual void SubscribeToClientTeleportEvents(IClientAPI client)
  2261. {
  2262. client.OnTeleportLocationRequest += RequestTeleportLocation;
  2263. client.OnTeleportLandmarkRequest += RequestTeleportLandmark;
  2264. client.OnTeleportHomeRequest += TeleportClientHome;
  2265. }
  2266. public virtual void SubscribeToClientScriptEvents(IClientAPI client)
  2267. {
  2268. client.OnScriptReset += ProcessScriptReset;
  2269. client.OnGetScriptRunning += GetScriptRunning;
  2270. client.OnSetScriptRunning += SetScriptRunning;
  2271. }
  2272. public virtual void SubscribeToClientParcelEvents(IClientAPI client)
  2273. {
  2274. client.OnObjectGroupRequest += m_sceneGraph.HandleObjectGroupUpdate;
  2275. client.OnParcelReturnObjectsRequest += LandChannel.ReturnObjectsInParcel;
  2276. client.OnParcelSetOtherCleanTime += LandChannel.SetParcelOtherCleanTime;
  2277. client.OnParcelBuy += ProcessParcelBuy;
  2278. }
  2279. public virtual void SubscribeToClientGridEvents(IClientAPI client)
  2280. {
  2281. client.OnNameFromUUIDRequest += CommsManager.HandleUUIDNameRequest;
  2282. client.OnMoneyTransferRequest += ProcessMoneyTransferRequest;
  2283. client.OnAvatarPickerRequest += ProcessAvatarPickerRequest;
  2284. client.OnSetStartLocationRequest += SetHomeRezPoint;
  2285. client.OnRegionHandleRequest += RegionHandleRequest;
  2286. }
  2287. public virtual void SubscribeToClientGodEvents(IClientAPI client)
  2288. {
  2289. IGodsModule godsModule = RequestModuleInterface<IGodsModule>();
  2290. client.OnGodKickUser += godsModule.KickUser;
  2291. client.OnRequestGodlikePowers += godsModule.RequestGodlikePowers;
  2292. }
  2293. public virtual void SubscribeToClientNetworkEvents(IClientAPI client)
  2294. {
  2295. client.OnNetworkStatsUpdate += StatsReporter.AddPacketsStats;
  2296. client.OnViewerEffect += ProcessViewerEffect;
  2297. }
  2298. protected virtual void UnsubscribeToClientEvents(IClientAPI client)
  2299. {
  2300. }
  2301. /// <summary>
  2302. /// Register for events from the client
  2303. /// </summary>
  2304. /// <param name="client">The IClientAPI of the connected client</param>
  2305. public virtual void UnSubscribeToClientEvents(IClientAPI client)
  2306. {
  2307. UnSubscribeToClientTerrainEvents(client);
  2308. UnSubscribeToClientPrimEvents(client);
  2309. UnSubscribeToClientPrimRezEvents(client);
  2310. UnSubscribeToClientInventoryEvents(client);
  2311. UnSubscribeToClientAttachmentEvents(client);
  2312. UnSubscribeToClientTeleportEvents(client);
  2313. UnSubscribeToClientScriptEvents(client);
  2314. UnSubscribeToClientParcelEvents(client);
  2315. UnSubscribeToClientGridEvents(client);
  2316. UnSubscribeToClientGodEvents(client);
  2317. UnSubscribeToClientNetworkEvents(client);
  2318. // EventManager.TriggerOnNewClient(client);
  2319. }
  2320. public virtual void UnSubscribeToClientTerrainEvents(IClientAPI client)
  2321. {
  2322. client.OnRegionHandShakeReply -= SendLayerData;
  2323. client.OnUnackedTerrain -= TerrainUnAcked;
  2324. }
  2325. public virtual void UnSubscribeToClientPrimEvents(IClientAPI client)
  2326. {
  2327. client.OnUpdatePrimGroupPosition -= m_sceneGraph.UpdatePrimPosition;
  2328. client.OnUpdatePrimSinglePosition -= m_sceneGraph.UpdatePrimSinglePosition;
  2329. client.OnUpdatePrimGroupRotation -= m_sceneGraph.UpdatePrimRotation;
  2330. client.OnUpdatePrimGroupMouseRotation -= m_sceneGraph.UpdatePrimRotation;
  2331. client.OnUpdatePrimSingleRotation -= m_sceneGraph.UpdatePrimSingleRotation;
  2332. client.OnUpdatePrimSingleRotationPosition -= m_sceneGraph.UpdatePrimSingleRotationPosition;
  2333. client.OnUpdatePrimScale -= m_sceneGraph.UpdatePrimScale;
  2334. client.OnUpdatePrimGroupScale -= m_sceneGraph.UpdatePrimGroupScale;
  2335. client.OnUpdateExtraParams -= m_sceneGraph.UpdateExtraParam;
  2336. client.OnUpdatePrimShape -= m_sceneGraph.UpdatePrimShape;
  2337. client.OnUpdatePrimTexture -= m_sceneGraph.UpdatePrimTexture;
  2338. client.OnObjectRequest -= RequestPrim;
  2339. client.OnObjectSelect -= SelectPrim;
  2340. client.OnObjectDeselect -= DeselectPrim;
  2341. client.OnGrabUpdate -= m_sceneGraph.MoveObject;
  2342. client.OnSpinStart -= m_sceneGraph.SpinStart;
  2343. client.OnSpinUpdate -= m_sceneGraph.SpinObject;
  2344. client.OnDeRezObject -= DeRezObject;
  2345. client.OnObjectName -= m_sceneGraph.PrimName;
  2346. client.OnObjectClickAction -= m_sceneGraph.PrimClickAction;
  2347. client.OnObjectMaterial -= m_sceneGraph.PrimMaterial;
  2348. client.OnLinkObjects -= m_sceneGraph.LinkObjects;
  2349. client.OnDelinkObjects -= m_sceneGraph.DelinkObjects;
  2350. client.OnObjectDuplicate -= m_sceneGraph.DuplicateObject;
  2351. client.OnObjectDuplicateOnRay -= doObjectDuplicateOnRay;
  2352. client.OnUpdatePrimFlags -= m_sceneGraph.UpdatePrimFlags;
  2353. client.OnRequestObjectPropertiesFamily -= m_sceneGraph.RequestObjectPropertiesFamily;
  2354. client.OnObjectPermissions -= HandleObjectPermissionsUpdate;
  2355. client.OnGrabObject -= ProcessObjectGrab;
  2356. client.OnDeGrabObject -= ProcessObjectDeGrab;
  2357. client.OnUndo -= m_sceneGraph.HandleUndo;
  2358. client.OnObjectDescription -= m_sceneGraph.PrimDescription;
  2359. client.OnObjectDrop -= m_sceneGraph.DropObject;
  2360. client.OnObjectSaleInfo -= ObjectSaleInfo;
  2361. client.OnObjectIncludeInSearch -= m_sceneGraph.MakeObjectSearchable;
  2362. client.OnObjectOwner -= ObjectOwner;
  2363. }
  2364. public virtual void UnSubscribeToClientPrimRezEvents(IClientAPI client)
  2365. {
  2366. client.OnAddPrim -= AddNewPrim;
  2367. client.OnRezObject -= RezObject;
  2368. }
  2369. public virtual void UnSubscribeToClientInventoryEvents(IClientAPI client)
  2370. {
  2371. client.OnCreateNewInventoryItem -= CreateNewInventoryItem;
  2372. client.OnCreateNewInventoryFolder -= HandleCreateInventoryFolder;
  2373. client.OnUpdateInventoryFolder -= HandleUpdateInventoryFolder;
  2374. client.OnMoveInventoryFolder -= HandleMoveInventoryFolder; // 2; //!!
  2375. client.OnFetchInventoryDescendents -= HandleFetchInventoryDescendents;
  2376. client.OnPurgeInventoryDescendents -= HandlePurgeInventoryDescendents; // 2; //!!
  2377. client.OnFetchInventory -= HandleFetchInventory;
  2378. client.OnUpdateInventoryItem -= UpdateInventoryItemAsset;
  2379. client.OnCopyInventoryItem -= CopyInventoryItem;
  2380. client.OnMoveInventoryItem -= MoveInventoryItem;
  2381. client.OnRemoveInventoryItem -= RemoveInventoryItem;
  2382. client.OnRemoveInventoryFolder -= RemoveInventoryFolder;
  2383. client.OnRezScript -= RezScript;
  2384. client.OnRequestTaskInventory -= RequestTaskInventory;
  2385. client.OnRemoveTaskItem -= RemoveTaskInventory;
  2386. client.OnUpdateTaskInventory -= UpdateTaskInventory;
  2387. client.OnMoveTaskItem -= ClientMoveTaskInventoryItem;
  2388. }
  2389. public virtual void UnSubscribeToClientAttachmentEvents(IClientAPI client)
  2390. {
  2391. client.OnRezSingleAttachmentFromInv -= RezSingleAttachment;
  2392. client.OnRezMultipleAttachmentsFromInv -= RezMultipleAttachments;
  2393. client.OnDetachAttachmentIntoInv -= DetachSingleAttachmentToInv;
  2394. client.OnObjectAttach -= m_sceneGraph.AttachObject;
  2395. client.OnObjectDetach -= m_sceneGraph.DetachObject;
  2396. }
  2397. public virtual void UnSubscribeToClientTeleportEvents(IClientAPI client)
  2398. {
  2399. client.OnTeleportLocationRequest -= RequestTeleportLocation;
  2400. client.OnTeleportLandmarkRequest -= RequestTeleportLandmark;
  2401. client.OnTeleportHomeRequest -= TeleportClientHome;
  2402. }
  2403. public virtual void UnSubscribeToClientScriptEvents(IClientAPI client)
  2404. {
  2405. client.OnScriptReset -= ProcessScriptReset;
  2406. client.OnGetScriptRunning -= GetScriptRunning;
  2407. client.OnSetScriptRunning -= SetScriptRunning;
  2408. }
  2409. public virtual void UnSubscribeToClientParcelEvents(IClientAPI client)
  2410. {
  2411. client.OnObjectGroupRequest -= m_sceneGraph.HandleObjectGroupUpdate;
  2412. client.OnParcelReturnObjectsRequest -= LandChannel.ReturnObjectsInParcel;
  2413. client.OnParcelSetOtherCleanTime -= LandChannel.SetParcelOtherCleanTime;
  2414. client.OnParcelBuy -= ProcessParcelBuy;
  2415. }
  2416. public virtual void UnSubscribeToClientGridEvents(IClientAPI client)
  2417. {
  2418. client.OnNameFromUUIDRequest -= CommsManager.HandleUUIDNameRequest;
  2419. client.OnMoneyTransferRequest -= ProcessMoneyTransferRequest;
  2420. client.OnAvatarPickerRequest -= ProcessAvatarPickerRequest;
  2421. client.OnSetStartLocationRequest -= SetHomeRezPoint;
  2422. client.OnRegionHandleRequest -= RegionHandleRequest;
  2423. }
  2424. public virtual void UnSubscribeToClientGodEvents(IClientAPI client)
  2425. {
  2426. IGodsModule godsModule = RequestModuleInterface<IGodsModule>();
  2427. client.OnGodKickUser -= godsModule.KickUser;
  2428. client.OnRequestGodlikePowers -= godsModule.RequestGodlikePowers;
  2429. }
  2430. public virtual void UnSubscribeToClientNetworkEvents(IClientAPI client)
  2431. {
  2432. client.OnNetworkStatsUpdate -= StatsReporter.AddPacketsStats;
  2433. client.OnViewerEffect -= ProcessViewerEffect;
  2434. }
  2435. /// <summary>
  2436. /// Teleport an avatar to their home region
  2437. /// </summary>
  2438. /// <param name="agentId">The avatar's Unique ID</param>
  2439. /// <param name="client">The IClientAPI for the client</param>
  2440. public virtual void TeleportClientHome(UUID agentId, IClientAPI client)
  2441. {
  2442. UserProfileData UserProfile = CommsManager.UserService.GetUserProfile(agentId);
  2443. if (UserProfile != null)
  2444. {
  2445. GridRegion regionInfo = GridService.GetRegionByUUID(UUID.Zero, UserProfile.HomeRegionID);
  2446. if (regionInfo == null)
  2447. {
  2448. uint x = 0, y = 0;
  2449. Utils.LongToUInts(UserProfile.HomeRegion, out x, out y);
  2450. regionInfo = GridService.GetRegionByPosition(UUID.Zero, (int)x, (int)y);
  2451. if (regionInfo != null) // home region can be away temporarily, too
  2452. {
  2453. UserProfile.HomeRegionID = regionInfo.RegionID;
  2454. CommsManager.UserService.UpdateUserProfile(UserProfile);
  2455. }
  2456. }
  2457. if (regionInfo == null)
  2458. {
  2459. // can't find the Home region: Tell viewer and abort
  2460. client.SendTeleportFailed("Your home-region could not be found.");
  2461. return;
  2462. }
  2463. RequestTeleportLocation(
  2464. client, regionInfo.RegionHandle, UserProfile.HomeLocation, UserProfile.HomeLookAt,
  2465. (uint)(TPFlags.SetLastToTarget | TPFlags.ViaHome));
  2466. }
  2467. }
  2468. /// <summary>
  2469. /// Duplicates object specified by localID at position raycasted against RayTargetObject using
  2470. /// RayEnd and RayStart to determine what the angle of the ray is
  2471. /// </summary>
  2472. /// <param name="localID">ID of object to duplicate</param>
  2473. /// <param name="dupeFlags"></param>
  2474. /// <param name="AgentID">Agent doing the duplication</param>
  2475. /// <param name="GroupID">Group of new object</param>
  2476. /// <param name="RayTargetObj">The target of the Ray</param>
  2477. /// <param name="RayEnd">The ending of the ray (farthest away point)</param>
  2478. /// <param name="RayStart">The Beginning of the ray (closest point)</param>
  2479. /// <param name="BypassRaycast">Bool to bypass raycasting</param>
  2480. /// <param name="RayEndIsIntersection">The End specified is the place to add the object</param>
  2481. /// <param name="CopyCenters">Position the object at the center of the face that it's colliding with</param>
  2482. /// <param name="CopyRotates">Rotate the object the same as the localID object</param>
  2483. public void doObjectDuplicateOnRay(uint localID, uint dupeFlags, UUID AgentID, UUID GroupID,
  2484. UUID RayTargetObj, Vector3 RayEnd, Vector3 RayStart,
  2485. bool BypassRaycast, bool RayEndIsIntersection, bool CopyCenters, bool CopyRotates)
  2486. {
  2487. Vector3 pos;
  2488. const bool frontFacesOnly = true;
  2489. //m_log.Info("HITTARGET: " + RayTargetObj.ToString() + ", COPYTARGET: " + localID.ToString());
  2490. SceneObjectPart target = GetSceneObjectPart(localID);
  2491. SceneObjectPart target2 = GetSceneObjectPart(RayTargetObj);
  2492. if (target != null && target2 != null)
  2493. {
  2494. Vector3 direction = Vector3.Normalize(RayEnd - RayStart);
  2495. Vector3 AXOrigin = new Vector3(RayStart.X, RayStart.Y, RayStart.Z);
  2496. Vector3 AXdirection = new Vector3(direction.X, direction.Y, direction.Z);
  2497. if (target2.ParentGroup != null)
  2498. {
  2499. pos = target2.AbsolutePosition;
  2500. //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());
  2501. // TODO: Raytrace better here
  2502. //EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection));
  2503. Ray NewRay = new Ray(AXOrigin, AXdirection);
  2504. // Ray Trace against target here
  2505. EntityIntersection ei = target2.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, CopyCenters);
  2506. // Un-comment out the following line to Get Raytrace results printed to the console.
  2507. //m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString());
  2508. float ScaleOffset = 0.5f;
  2509. // If we hit something
  2510. if (ei.HitTF)
  2511. {
  2512. Vector3 scale = target.Scale;
  2513. Vector3 scaleComponent = new Vector3(ei.AAfaceNormal.X, ei.AAfaceNormal.Y, ei.AAfaceNormal.Z);
  2514. if (scaleComponent.X != 0) ScaleOffset = scale.X;
  2515. if (scaleComponent.Y != 0) ScaleOffset = scale.Y;
  2516. if (scaleComponent.Z != 0) ScaleOffset = scale.Z;
  2517. ScaleOffset = Math.Abs(ScaleOffset);
  2518. Vector3 intersectionpoint = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z);
  2519. Vector3 normal = new Vector3(ei.normal.X, ei.normal.Y, ei.normal.Z);
  2520. Vector3 offset = normal * (ScaleOffset / 2f);
  2521. pos = intersectionpoint + offset;
  2522. // stick in offset format from the original prim
  2523. pos = pos - target.ParentGroup.AbsolutePosition;
  2524. if (CopyRotates)
  2525. {
  2526. Quaternion worldRot = target2.GetWorldRotation();
  2527. // SceneObjectGroup obj = m_sceneGraph.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID, worldRot);
  2528. m_sceneGraph.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID, worldRot);
  2529. //obj.Rotation = worldRot;
  2530. //obj.UpdateGroupRotation(worldRot);
  2531. }
  2532. else
  2533. {
  2534. m_sceneGraph.DuplicateObject(localID, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID);
  2535. }
  2536. }
  2537. return;
  2538. }
  2539. return;
  2540. }
  2541. }
  2542. /// <summary>
  2543. /// Sets the Home Point. The GridService uses this to know where to put a user when they log-in
  2544. /// </summary>
  2545. /// <param name="remoteClient"></param>
  2546. /// <param name="regionHandle"></param>
  2547. /// <param name="position"></param>
  2548. /// <param name="lookAt"></param>
  2549. /// <param name="flags"></param>
  2550. public virtual void SetHomeRezPoint(IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags)
  2551. {
  2552. UserProfileData UserProfile = CommsManager.UserService.GetUserProfile(remoteClient.AgentId);
  2553. if (UserProfile != null)
  2554. {
  2555. // I know I'm ignoring the regionHandle provided by the teleport location request.
  2556. // reusing the TeleportLocationRequest delegate, so regionHandle isn't valid
  2557. UserProfile.HomeRegionID = RegionInfo.RegionID;
  2558. // TODO: The next line can be removed, as soon as only homeRegionID based UserServers are around.
  2559. // TODO: The HomeRegion property can be removed then, too
  2560. UserProfile.HomeRegion = RegionInfo.RegionHandle;
  2561. UserProfile.HomeLocation = position;
  2562. UserProfile.HomeLookAt = lookAt;
  2563. CommsManager.UserService.UpdateUserProfile(UserProfile);
  2564. // FUBAR ALERT: this needs to be "Home position set." so the viewer saves a home-screenshot.
  2565. m_dialogModule.SendAlertToUser(remoteClient, "Home position set.");
  2566. }
  2567. else
  2568. {
  2569. m_dialogModule.SendAlertToUser(remoteClient, "Set Home request Failed.");
  2570. }
  2571. }
  2572. /// <summary>
  2573. /// Create a child agent scene presence and add it to this scene.
  2574. /// </summary>
  2575. /// <param name="client"></param>
  2576. /// <returns></returns>
  2577. protected virtual ScenePresence CreateAndAddScenePresence(IClientAPI client)
  2578. {
  2579. CheckHeartbeat();
  2580. AvatarAppearance appearance = null;
  2581. GetAvatarAppearance(client, out appearance);
  2582. ScenePresence avatar = m_sceneGraph.CreateAndAddChildScenePresence(client, appearance);
  2583. //avatar.KnownRegions = GetChildrenSeeds(avatar.UUID);
  2584. m_eventManager.TriggerOnNewPresence(avatar);
  2585. return avatar;
  2586. }
  2587. /// <summary>
  2588. /// Get the avatar apperance for the given client.
  2589. /// </summary>
  2590. /// <param name="client"></param>
  2591. /// <param name="appearance"></param>
  2592. public void GetAvatarAppearance(IClientAPI client, out AvatarAppearance appearance)
  2593. {
  2594. AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode);
  2595. if (aCircuit == null)
  2596. {
  2597. m_log.DebugFormat("[APPEARANCE] Client did not supply a circuit. Non-Linden? Creating default appearance.");
  2598. appearance = new AvatarAppearance(client.AgentId);
  2599. return;
  2600. }
  2601. appearance = aCircuit.Appearance;
  2602. if (appearance == null)
  2603. {
  2604. m_log.DebugFormat("[APPEARANCE]: Appearance not found in {0}, returning default", RegionInfo.RegionName);
  2605. appearance = new AvatarAppearance(client.AgentId);
  2606. }
  2607. }
  2608. /// <summary>
  2609. /// Remove the given client from the scene.
  2610. /// </summary>
  2611. /// <param name="agentID"></param>
  2612. public override void RemoveClient(UUID agentID)
  2613. {
  2614. CheckHeartbeat();
  2615. bool childagentYN = false;
  2616. ScenePresence avatar = GetScenePresence(agentID);
  2617. if (avatar != null)
  2618. {
  2619. childagentYN = avatar.IsChildAgent;
  2620. if (avatar.ParentID != 0)
  2621. {
  2622. avatar.StandUp();
  2623. }
  2624. try
  2625. {
  2626. m_log.DebugFormat(
  2627. "[SCENE]: Removing {0} agent {1} from region {2}",
  2628. (childagentYN ? "child" : "root"), agentID, RegionInfo.RegionName);
  2629. m_sceneGraph.removeUserCount(!childagentYN);
  2630. CapsModule.RemoveCapsHandler(agentID);
  2631. if (avatar.Scene.NeedSceneCacheClear(avatar.UUID))
  2632. {
  2633. CommsManager.UserProfileCacheService.RemoveUser(agentID);
  2634. }
  2635. if (!avatar.IsChildAgent)
  2636. {
  2637. m_sceneGridService.LogOffUser(agentID, RegionInfo.RegionID, RegionInfo.RegionHandle, avatar.AbsolutePosition, avatar.Lookat);
  2638. //List<ulong> childknownRegions = new List<ulong>();
  2639. //List<ulong> ckn = avatar.KnownChildRegionHandles;
  2640. //for (int i = 0; i < ckn.Count; i++)
  2641. //{
  2642. // childknownRegions.Add(ckn[i]);
  2643. //}
  2644. List<ulong> regions = new List<ulong>(avatar.KnownChildRegionHandles);
  2645. regions.Remove(RegionInfo.RegionHandle);
  2646. m_sceneGridService.SendCloseChildAgentConnections(agentID, regions);
  2647. }
  2648. m_eventManager.TriggerClientClosed(agentID, this);
  2649. }
  2650. catch (NullReferenceException)
  2651. {
  2652. // We don't know which count to remove it from
  2653. // Avatar is already disposed :/
  2654. }
  2655. m_eventManager.TriggerOnRemovePresence(agentID);
  2656. ForEachClient(
  2657. delegate(IClientAPI client)
  2658. {
  2659. //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway
  2660. try { client.SendKillObject(avatar.RegionHandle, avatar.LocalId); }
  2661. catch (NullReferenceException) { }
  2662. });
  2663. ForEachScenePresence(
  2664. delegate(ScenePresence presence) { presence.CoarseLocationChange(); });
  2665. IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>();
  2666. if (agentTransactions != null)
  2667. {
  2668. agentTransactions.RemoveAgentAssetTransactions(agentID);
  2669. }
  2670. // Remove the avatar from the scene
  2671. m_sceneGraph.RemoveScenePresence(agentID);
  2672. ClientManager.Remove(agentID);
  2673. try
  2674. {
  2675. avatar.Close();
  2676. }
  2677. catch (NullReferenceException)
  2678. {
  2679. //We can safely ignore null reference exceptions. It means the avatar are dead and cleaned up anyway.
  2680. }
  2681. catch (Exception e)
  2682. {
  2683. m_log.Error("[SCENE] Scene.cs:RemoveClient exception: " + e.ToString());
  2684. }
  2685. // Remove client agent from profile, so new logins will work
  2686. if (!childagentYN)
  2687. {
  2688. m_sceneGridService.ClearUserAgent(agentID);
  2689. }
  2690. m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode);
  2691. //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false));
  2692. //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true));
  2693. }
  2694. }
  2695. /// <summary>
  2696. /// 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.
  2697. ///
  2698. /// </summary>
  2699. /// <param name="avatarID"></param>
  2700. /// <param name="regionslst"></param>
  2701. public void HandleRemoveKnownRegionsFromAvatar(UUID avatarID, List<ulong> regionslst)
  2702. {
  2703. ScenePresence av = GetScenePresence(avatarID);
  2704. if (av != null)
  2705. {
  2706. lock (av)
  2707. {
  2708. for (int i = 0; i < regionslst.Count; i++)
  2709. {
  2710. av.KnownChildRegionHandles.Remove(regionslst[i]);
  2711. }
  2712. }
  2713. }
  2714. }
  2715. /// <summary>
  2716. /// Inform all other ScenePresences on this Scene that someone else has changed position on the minimap.
  2717. /// </summary>
  2718. public void NotifyMyCoarseLocationChange()
  2719. {
  2720. ForEachScenePresence(delegate(ScenePresence presence) { presence.CoarseLocationChange(); });
  2721. }
  2722. #endregion
  2723. #region Entities
  2724. public void SendKillObject(uint localID)
  2725. {
  2726. SceneObjectPart part = GetSceneObjectPart(localID);
  2727. if (part != null) // It is a prim
  2728. {
  2729. if (part.ParentGroup != null && !part.ParentGroup.IsDeleted) // Valid
  2730. {
  2731. if (part.ParentGroup.RootPart != part) // Child part
  2732. return;
  2733. }
  2734. }
  2735. ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, localID); });
  2736. }
  2737. #endregion
  2738. #region RegionComms
  2739. /// <summary>
  2740. /// Register the methods that should be invoked when this scene receives various incoming events
  2741. /// </summary>
  2742. public void RegisterCommsEvents()
  2743. {
  2744. m_sceneGridService.OnExpectUser += HandleNewUserConnection;
  2745. m_sceneGridService.OnAvatarCrossingIntoRegion += AgentCrossing;
  2746. m_sceneGridService.OnCloseAgentConnection += IncomingCloseAgent;
  2747. //m_eventManager.OnRegionUp += OtherRegionUp;
  2748. //m_sceneGridService.OnChildAgentUpdate += IncomingChildAgentDataUpdate;
  2749. m_sceneGridService.OnExpectPrim += IncomingInterRegionPrimGroup;
  2750. //m_sceneGridService.OnRemoveKnownRegionFromAvatar += HandleRemoveKnownRegionsFromAvatar;
  2751. m_sceneGridService.OnLogOffUser += HandleLogOffUserFromGrid;
  2752. m_sceneGridService.KiPrimitive += SendKillObject;
  2753. m_sceneGridService.OnGetLandData += GetLandData;
  2754. if (m_interregionCommsIn != null)
  2755. {
  2756. m_log.Debug("[SCENE]: Registering with InterregionCommsIn");
  2757. m_interregionCommsIn.OnChildAgentUpdate += IncomingChildAgentDataUpdate;
  2758. }
  2759. else
  2760. m_log.Debug("[SCENE]: Unable to register with InterregionCommsIn");
  2761. }
  2762. /// <summary>
  2763. /// Deregister this scene from receiving incoming region events
  2764. /// </summary>
  2765. public void UnRegisterRegionWithComms()
  2766. {
  2767. m_sceneGridService.KiPrimitive -= SendKillObject;
  2768. m_sceneGridService.OnLogOffUser -= HandleLogOffUserFromGrid;
  2769. //m_sceneGridService.OnRemoveKnownRegionFromAvatar -= HandleRemoveKnownRegionsFromAvatar;
  2770. m_sceneGridService.OnExpectPrim -= IncomingInterRegionPrimGroup;
  2771. //m_sceneGridService.OnChildAgentUpdate -= IncomingChildAgentDataUpdate;
  2772. //m_eventManager.OnRegionUp -= OtherRegionUp;
  2773. m_sceneGridService.OnExpectUser -= HandleNewUserConnection;
  2774. m_sceneGridService.OnAvatarCrossingIntoRegion -= AgentCrossing;
  2775. m_sceneGridService.OnCloseAgentConnection -= IncomingCloseAgent;
  2776. m_sceneGridService.OnGetLandData -= GetLandData;
  2777. if (m_interregionCommsIn != null)
  2778. m_interregionCommsIn.OnChildAgentUpdate -= IncomingChildAgentDataUpdate;
  2779. // this does nothing; should be removed
  2780. m_sceneGridService.Close();
  2781. if (!GridService.DeregisterRegion(m_regInfo.RegionID))
  2782. m_log.WarnFormat("[SCENE]: Deregister from grid failed for region {0}", m_regInfo.RegionName);
  2783. }
  2784. /// <summary>
  2785. /// A handler for the SceneCommunicationService event, to match that events return type of void.
  2786. /// Use NewUserConnection() directly if possible so the return type can refuse connections.
  2787. /// At the moment nothing actually seems to use this event,
  2788. /// as everything is switching to calling the NewUserConnection method directly.
  2789. /// </summary>
  2790. /// <param name="agent"></param>
  2791. public void HandleNewUserConnection(AgentCircuitData agent)
  2792. {
  2793. string reason;
  2794. NewUserConnection(agent, out reason);
  2795. }
  2796. /// <summary>
  2797. /// Do the work necessary to initiate a new user connection for a particular scene.
  2798. /// At the moment, this consists of setting up the caps infrastructure
  2799. /// The return bool should allow for connections to be refused, but as not all calling paths
  2800. /// take proper notice of it let, we allowed banned users in still.
  2801. /// </summary>
  2802. /// <param name="agent">CircuitData of the agent who is connecting</param>
  2803. /// <param name="reason">Outputs the reason for the false response on this string</param>
  2804. /// <returns>True if the region accepts this agent. False if it does not. False will
  2805. /// also return a reason.</returns>
  2806. public bool NewUserConnection(AgentCircuitData agent, out string reason)
  2807. {
  2808. if (loginsdisabled)
  2809. {
  2810. reason = "Logins Disabled";
  2811. return false;
  2812. }
  2813. // Don't disable this log message - it's too helpful
  2814. m_log.InfoFormat(
  2815. "[CONNECTION BEGIN]: Region {0} told of incoming {1} agent {2} {3} {4} (circuit code {5})",
  2816. RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname,
  2817. agent.AgentID, agent.circuitcode);
  2818. reason = String.Empty;
  2819. if (!AuthenticateUser(agent, out reason))
  2820. return false;
  2821. if (!AuthorizeUser(agent, out reason))
  2822. return false;
  2823. m_log.InfoFormat(
  2824. "[CONNECTION BEGIN]: Region {0} authenticated and authorized incoming {1} agent {2} {3} {4} (circuit code {5})",
  2825. RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname,
  2826. agent.AgentID, agent.circuitcode);
  2827. CapsModule.NewUserConnection(agent);
  2828. ScenePresence sp = m_sceneGraph.GetScenePresence(agent.AgentID);
  2829. if (sp != null)
  2830. {
  2831. m_log.DebugFormat(
  2832. "[SCENE]: Adjusting known seeds for existing agent {0} in {1}",
  2833. agent.AgentID, RegionInfo.RegionName);
  2834. sp.AdjustKnownSeeds();
  2835. return true;
  2836. }
  2837. CapsModule.AddCapsHandler(agent.AgentID);
  2838. if (!agent.child)
  2839. {
  2840. if (TestBorderCross(agent.startpos,Cardinals.E))
  2841. {
  2842. Border crossedBorder = GetCrossedBorder(agent.startpos, Cardinals.E);
  2843. agent.startpos.X = crossedBorder.BorderLine.Z - 1;
  2844. }
  2845. if (TestBorderCross(agent.startpos, Cardinals.N))
  2846. {
  2847. Border crossedBorder = GetCrossedBorder(agent.startpos, Cardinals.N);
  2848. agent.startpos.Y = crossedBorder.BorderLine.Z - 1;
  2849. }
  2850. // Honor parcel landing type and position.
  2851. ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
  2852. if (land != null)
  2853. {
  2854. if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero)
  2855. {
  2856. agent.startpos = land.LandData.UserLocation;
  2857. }
  2858. }
  2859. }
  2860. m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent);
  2861. // rewrite session_id
  2862. CachedUserInfo userinfo = CommsManager.UserProfileCacheService.GetUserDetails(agent.AgentID);
  2863. if (userinfo != null)
  2864. {
  2865. userinfo.SessionID = agent.SessionID;
  2866. }
  2867. else
  2868. {
  2869. m_log.WarnFormat(
  2870. "[CONNECTION BEGIN]: We couldn't find a User Info record for {0}. This is usually an indication that the UUID we're looking up is invalid", agent.AgentID);
  2871. }
  2872. return true;
  2873. }
  2874. /// <summary>
  2875. /// Verifies that the user has a session on the Grid
  2876. /// </summary>
  2877. /// <param name="agent">Circuit Data of the Agent we're verifying</param>
  2878. /// <param name="reason">Outputs the reason for the false response on this string</param>
  2879. /// <returns>True if the user has a session on the grid. False if it does not. False will
  2880. /// also return a reason.</returns>
  2881. public virtual bool AuthenticateUser(AgentCircuitData agent, out string reason)
  2882. {
  2883. reason = String.Empty;
  2884. bool result = CommsManager.UserService.VerifySession(agent.AgentID, agent.SessionID);
  2885. m_log.Debug("[CONNECTION BEGIN]: User authentication returned " + result);
  2886. if (!result)
  2887. reason = String.Format("Failed to authenticate user {0} {1}, access denied.", agent.firstname, agent.lastname);
  2888. return result;
  2889. }
  2890. /// <summary>
  2891. /// Verify if the user can connect to this region. Checks the banlist and ensures that the region is set for public access
  2892. /// </summary>
  2893. /// <param name="agent">The circuit data for the agent</param>
  2894. /// <param name="reason">outputs the reason to this string</param>
  2895. /// <returns>True if the region accepts this agent. False if it does not. False will
  2896. /// also return a reason.</returns>
  2897. protected virtual bool AuthorizeUser(AgentCircuitData agent, out string reason)
  2898. {
  2899. reason = String.Empty;
  2900. if (!m_strictAccessControl) return true;
  2901. if (Permissions.IsGod(agent.AgentID)) return true;
  2902. if (AuthorizationService != null)
  2903. {
  2904. if (!AuthorizationService.IsAuthorizedForRegion(agent.AgentID.ToString(), RegionInfo.RegionID.ToString(),out reason))
  2905. {
  2906. m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the region",
  2907. agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
  2908. //reason = String.Format("You are not currently on the access list for {0}",RegionInfo.RegionName);
  2909. return false;
  2910. }
  2911. }
  2912. if (m_regInfo.EstateSettings.IsBanned(agent.AgentID))
  2913. {
  2914. m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist",
  2915. agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
  2916. reason = String.Format("Denied access to region {0}: You have been banned from that region.",
  2917. RegionInfo.RegionName);
  2918. return false;
  2919. }
  2920. if (!m_regInfo.EstateSettings.PublicAccess &&
  2921. !m_regInfo.EstateSettings.HasAccess(agent.AgentID))
  2922. {
  2923. m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the estate",
  2924. agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
  2925. reason = String.Format("Denied access to private region {0}: You are not on the access list for that region.",
  2926. RegionInfo.RegionName);
  2927. return false;
  2928. }
  2929. // TODO: estate/region settings are not properly hooked up
  2930. // to ILandObject.isRestrictedFromLand()
  2931. // if (null != LandChannel)
  2932. // {
  2933. // // region seems to have local Id of 1
  2934. // ILandObject land = LandChannel.GetLandObject(1);
  2935. // if (null != land)
  2936. // {
  2937. // if (land.isBannedFromLand(agent.AgentID))
  2938. // {
  2939. // m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user has been banned from land",
  2940. // agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
  2941. // reason = String.Format("Denied access to private region {0}: You are banned from that region.",
  2942. // RegionInfo.RegionName);
  2943. // return false;
  2944. // }
  2945. // if (land.isRestrictedFromLand(agent.AgentID))
  2946. // {
  2947. // m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the region",
  2948. // agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
  2949. // reason = String.Format("Denied access to private region {0}: You are not on the access list for that region.",
  2950. // RegionInfo.RegionName);
  2951. // return false;
  2952. // }
  2953. // }
  2954. // }
  2955. return true;
  2956. }
  2957. /// <summary>
  2958. /// Update an AgentCircuitData object with new information
  2959. /// </summary>
  2960. /// <param name="data">Information to update the AgentCircuitData with</param>
  2961. public void UpdateCircuitData(AgentCircuitData data)
  2962. {
  2963. m_authenticateHandler.UpdateAgentData(data);
  2964. }
  2965. /// <summary>
  2966. /// Change the Circuit Code for the user's Circuit Data
  2967. /// </summary>
  2968. /// <param name="oldcc">The old Circuit Code. Must match a previous circuit code</param>
  2969. /// <param name="newcc">The new Circuit Code. Must not be an already existing circuit code</param>
  2970. /// <returns>True if we successfully changed it. False if we did not</returns>
  2971. public bool ChangeCircuitCode(uint oldcc, uint newcc)
  2972. {
  2973. return m_authenticateHandler.TryChangeCiruitCode(oldcc, newcc);
  2974. }
  2975. /// <summary>
  2976. /// The Grid has requested that we log-off a user. Log them off.
  2977. /// </summary>
  2978. /// <param name="AvatarID">Unique ID of the avatar to log-off</param>
  2979. /// <param name="RegionSecret">SecureSessionID of the user, or the RegionSecret text when logging on to the grid</param>
  2980. /// <param name="message">message to display to the user. Reason for being logged off</param>
  2981. public void HandleLogOffUserFromGrid(UUID AvatarID, UUID RegionSecret, string message)
  2982. {
  2983. ScenePresence loggingOffUser = null;
  2984. loggingOffUser = GetScenePresence(AvatarID);
  2985. if (loggingOffUser != null)
  2986. {
  2987. UUID localRegionSecret = UUID.Zero;
  2988. bool parsedsecret = UUID.TryParse(m_regInfo.regionSecret, out localRegionSecret);
  2989. // Region Secret is used here in case a new sessionid overwrites an old one on the user server.
  2990. // Will update the user server in a few revisions to use it.
  2991. if (RegionSecret == loggingOffUser.ControllingClient.SecureSessionId || (parsedsecret && RegionSecret == localRegionSecret))
  2992. {
  2993. m_sceneGridService.SendCloseChildAgentConnections(loggingOffUser.UUID, new List<ulong>(loggingOffUser.KnownRegions.Keys));
  2994. loggingOffUser.ControllingClient.Kick(message);
  2995. // Give them a second to receive the message!
  2996. Thread.Sleep(1000);
  2997. loggingOffUser.ControllingClient.Close();
  2998. }
  2999. else
  3000. {
  3001. m_log.Info("[USERLOGOFF]: System sending the LogOff user message failed to sucessfully authenticate");
  3002. }
  3003. }
  3004. else
  3005. {
  3006. 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());
  3007. }
  3008. }
  3009. /// <summary>
  3010. /// Triggered when an agent crosses into this sim. Also happens on initial login.
  3011. /// </summary>
  3012. /// <param name="agentID"></param>
  3013. /// <param name="position"></param>
  3014. /// <param name="isFlying"></param>
  3015. public virtual void AgentCrossing(UUID agentID, Vector3 position, bool isFlying)
  3016. {
  3017. ScenePresence presence;
  3018. lock (m_sceneGraph.ScenePresences)
  3019. m_sceneGraph.ScenePresences.TryGetValue(agentID, out presence);
  3020. if (presence != null)
  3021. {
  3022. try
  3023. {
  3024. presence.MakeRootAgent(position, isFlying);
  3025. }
  3026. catch (Exception e)
  3027. {
  3028. m_log.ErrorFormat("[SCENE]: Unable to do agent crossing, exception {0}", e);
  3029. }
  3030. }
  3031. else
  3032. {
  3033. m_log.ErrorFormat(
  3034. "[SCENE]: Could not find presence for agent {0} crossing into scene {1}",
  3035. agentID, RegionInfo.RegionName);
  3036. }
  3037. }
  3038. /// <summary>
  3039. /// We've got an update about an agent that sees into this region,
  3040. /// send it to ScenePresence for processing It's the full data.
  3041. /// </summary>
  3042. /// <param name="cAgentData">Agent that contains all of the relevant things about an agent.
  3043. /// Appearance, animations, position, etc.</param>
  3044. /// <returns>true if we handled it.</returns>
  3045. public virtual bool IncomingChildAgentDataUpdate(AgentData cAgentData)
  3046. {
  3047. // m_log.DebugFormat(
  3048. // "[SCENE]: Incoming child agent update for {0} in {1}", cAgentData.AgentID, RegionInfo.RegionName);
  3049. // We have to wait until the viewer contacts this region after receiving EAC.
  3050. // That calls AddNewClient, which finally creates the ScenePresence
  3051. ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID);
  3052. if (childAgentUpdate != null)
  3053. {
  3054. childAgentUpdate.ChildAgentDataUpdate(cAgentData);
  3055. return true;
  3056. }
  3057. return false;
  3058. }
  3059. /// <summary>
  3060. /// We've got an update about an agent that sees into this region,
  3061. /// send it to ScenePresence for processing It's only positional data
  3062. /// </summary>
  3063. /// <param name="cAgentData">AgentPosition that contains agent positional data so we can know what to send</param>
  3064. /// <returns>true if we handled it.</returns>
  3065. public virtual bool IncomingChildAgentDataUpdate(AgentPosition cAgentData)
  3066. {
  3067. //m_log.Debug(" XXX Scene IncomingChildAgentDataUpdate POSITION in " + RegionInfo.RegionName);
  3068. ScenePresence childAgentUpdate = GetScenePresence(cAgentData.AgentID);
  3069. if (childAgentUpdate != null)
  3070. {
  3071. // I can't imagine *yet* why we would get an update if the agent is a root agent..
  3072. // however to avoid a race condition crossing borders..
  3073. if (childAgentUpdate.IsChildAgent)
  3074. {
  3075. uint rRegionX = (uint)(cAgentData.RegionHandle >> 40);
  3076. uint rRegionY = (((uint)(cAgentData.RegionHandle)) >> 8);
  3077. uint tRegionX = RegionInfo.RegionLocX;
  3078. uint tRegionY = RegionInfo.RegionLocY;
  3079. //Send Data to ScenePresence
  3080. childAgentUpdate.ChildAgentDataUpdate(cAgentData, tRegionX, tRegionY, rRegionX, rRegionY);
  3081. // Not Implemented:
  3082. //TODO: Do we need to pass the message on to one of our neighbors?
  3083. }
  3084. return true;
  3085. }
  3086. return false;
  3087. }
  3088. protected virtual ScenePresence WaitGetScenePresence(UUID agentID)
  3089. {
  3090. int ntimes = 10;
  3091. ScenePresence childAgentUpdate = null;
  3092. while ((childAgentUpdate = GetScenePresence(agentID)) == null && (ntimes-- > 0))
  3093. Thread.Sleep(1000);
  3094. return childAgentUpdate;
  3095. }
  3096. public virtual bool IncomingRetrieveRootAgent(UUID id, out IAgentData agent)
  3097. {
  3098. agent = null;
  3099. ScenePresence sp = GetScenePresence(id);
  3100. if ((sp != null) && (!sp.IsChildAgent))
  3101. {
  3102. sp.IsChildAgent = true;
  3103. return sp.CopyAgent(out agent);
  3104. }
  3105. return false;
  3106. }
  3107. public virtual bool IncomingReleaseAgent(UUID id)
  3108. {
  3109. return m_sceneGridService.ReleaseAgent(id);
  3110. }
  3111. public void SendReleaseAgent(ulong regionHandle, UUID id, string uri)
  3112. {
  3113. m_interregionCommsOut.SendReleaseAgent(regionHandle, id, uri);
  3114. }
  3115. /// <summary>
  3116. /// Tell a single agent to disconnect from the region.
  3117. /// </summary>
  3118. /// <param name="regionHandle"></param>
  3119. /// <param name="agentID"></param>
  3120. public bool IncomingCloseAgent(UUID agentID)
  3121. {
  3122. //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID);
  3123. ScenePresence presence = m_sceneGraph.GetScenePresence(agentID);
  3124. if (presence != null)
  3125. {
  3126. // Nothing is removed here, so down count it as such
  3127. if (presence.IsChildAgent)
  3128. {
  3129. m_sceneGraph.removeUserCount(false);
  3130. }
  3131. else
  3132. {
  3133. m_sceneGraph.removeUserCount(true);
  3134. }
  3135. // Don't do this to root agents on logout, it's not nice for the viewer
  3136. if (presence.IsChildAgent)
  3137. {
  3138. // Tell a single agent to disconnect from the region.
  3139. IEventQueue eq = RequestModuleInterface<IEventQueue>();
  3140. if (eq != null)
  3141. {
  3142. eq.DisableSimulator(RegionInfo.RegionHandle, agentID);
  3143. }
  3144. else
  3145. presence.ControllingClient.SendShutdownConnectionNotice();
  3146. }
  3147. presence.ControllingClient.Close();
  3148. return true;
  3149. }
  3150. // Agent not here
  3151. return false;
  3152. }
  3153. /// <summary>
  3154. /// Tell neighboring regions about this agent
  3155. /// When the regions respond with a true value,
  3156. /// tell the agents about the region.
  3157. ///
  3158. /// We have to tell the regions about the agents first otherwise it'll deny them access
  3159. ///
  3160. /// </summary>
  3161. /// <param name="presence"></param>
  3162. public void InformClientOfNeighbours(ScenePresence presence)
  3163. {
  3164. m_sceneGridService.EnableNeighbourChildAgents(presence, m_neighbours);
  3165. }
  3166. /// <summary>
  3167. /// Tell a neighboring region about this agent
  3168. /// </summary>
  3169. /// <param name="presence"></param>
  3170. /// <param name="region"></param>
  3171. public void InformClientOfNeighbor(ScenePresence presence, RegionInfo region)
  3172. {
  3173. m_sceneGridService.EnableNeighbourChildAgents(presence, m_neighbours);
  3174. }
  3175. /// <summary>
  3176. /// Tries to teleport agent to other region.
  3177. /// </summary>
  3178. /// <param name="remoteClient"></param>
  3179. /// <param name="regionName"></param>
  3180. /// <param name="position"></param>
  3181. /// <param name="lookAt"></param>
  3182. /// <param name="teleportFlags"></param>
  3183. public void RequestTeleportLocation(IClientAPI remoteClient, string regionName, Vector3 position,
  3184. Vector3 lookat, uint teleportFlags)
  3185. {
  3186. GridRegion regionInfo = GridService.GetRegionByName(UUID.Zero, regionName);
  3187. if (regionInfo == null)
  3188. {
  3189. // can't find the region: Tell viewer and abort
  3190. remoteClient.SendTeleportFailed("The region '" + regionName + "' could not be found.");
  3191. return;
  3192. }
  3193. RequestTeleportLocation(remoteClient, regionInfo.RegionHandle, position, lookat, teleportFlags);
  3194. }
  3195. /// <summary>
  3196. /// Tries to teleport agent to other region.
  3197. /// </summary>
  3198. /// <param name="remoteClient"></param>
  3199. /// <param name="regionHandle"></param>
  3200. /// <param name="position"></param>
  3201. /// <param name="lookAt"></param>
  3202. /// <param name="teleportFlags"></param>
  3203. public void RequestTeleportLocation(IClientAPI remoteClient, ulong regionHandle, Vector3 position,
  3204. Vector3 lookAt, uint teleportFlags)
  3205. {
  3206. ScenePresence sp;
  3207. lock (m_sceneGraph.ScenePresences)
  3208. m_sceneGraph.ScenePresences.TryGetValue(remoteClient.AgentId, out sp);
  3209. if (sp != null)
  3210. {
  3211. uint regionX = m_regInfo.RegionLocX;
  3212. uint regionY = m_regInfo.RegionLocY;
  3213. Utils.LongToUInts(regionHandle, out regionX, out regionY);
  3214. int shiftx = (int) regionX - (int) m_regInfo.RegionLocX * (int)Constants.RegionSize;
  3215. int shifty = (int) regionY - (int) m_regInfo.RegionLocY * (int)Constants.RegionSize;
  3216. position.X += shiftx;
  3217. position.Y += shifty;
  3218. bool result = false;
  3219. if (TestBorderCross(position,Cardinals.N))
  3220. result = true;
  3221. if (TestBorderCross(position, Cardinals.S))
  3222. result = true;
  3223. if (TestBorderCross(position, Cardinals.E))
  3224. result = true;
  3225. if (TestBorderCross(position, Cardinals.W))
  3226. result = true;
  3227. // bordercross if position is outside of region
  3228. if (!result)
  3229. regionHandle = m_regInfo.RegionHandle;
  3230. else
  3231. {
  3232. // not in this region, undo the shift!
  3233. position.X -= shiftx;
  3234. position.Y -= shifty;
  3235. }
  3236. if (m_teleportModule != null)
  3237. {
  3238. m_teleportModule.RequestTeleportToLocation(sp, regionHandle,
  3239. position, lookAt, teleportFlags);
  3240. }
  3241. else
  3242. {
  3243. m_sceneGridService.RequestTeleportToLocation(sp, regionHandle,
  3244. position, lookAt, teleportFlags);
  3245. }
  3246. }
  3247. }
  3248. /// <summary>
  3249. /// Tries to teleport agent to landmark.
  3250. /// </summary>
  3251. /// <param name="remoteClient"></param>
  3252. /// <param name="regionHandle"></param>
  3253. /// <param name="position"></param>
  3254. public void RequestTeleportLandmark(IClientAPI remoteClient, UUID regionID, Vector3 position)
  3255. {
  3256. GridRegion info = GridService.GetRegionByUUID(UUID.Zero, regionID);
  3257. if (info == null)
  3258. {
  3259. // can't find the region: Tell viewer and abort
  3260. remoteClient.SendTeleportFailed("The teleport destination could not be found.");
  3261. return;
  3262. }
  3263. RequestTeleportLocation(remoteClient, info.RegionHandle, position, Vector3.Zero, (uint)(TPFlags.SetLastToTarget | TPFlags.ViaLandmark));
  3264. }
  3265. public void CrossAgentToNewRegion(ScenePresence agent, bool isFlying)
  3266. {
  3267. m_sceneGridService.CrossAgentToNewRegion(this, agent, isFlying);
  3268. }
  3269. public void SendOutChildAgentUpdates(AgentPosition cadu, ScenePresence presence)
  3270. {
  3271. m_sceneGridService.SendChildAgentDataUpdate(cadu, presence);
  3272. }
  3273. #endregion
  3274. #region Other Methods
  3275. public void SetObjectCapacity(int objects)
  3276. {
  3277. // Region specific config overrides global
  3278. //
  3279. if (RegionInfo.ObjectCapacity != 0)
  3280. objects = RegionInfo.ObjectCapacity;
  3281. if (StatsReporter != null)
  3282. {
  3283. StatsReporter.SetObjectCapacity(objects);
  3284. }
  3285. objectCapacity = objects;
  3286. }
  3287. public List<FriendListItem> GetFriendList(string id)
  3288. {
  3289. UUID avatarID;
  3290. if (!UUID.TryParse(id, out avatarID))
  3291. return new List<FriendListItem>();
  3292. return CommsManager.GetUserFriendList(avatarID);
  3293. }
  3294. public Dictionary<UUID, FriendRegionInfo> GetFriendRegionInfos(List<UUID> uuids)
  3295. {
  3296. return CommsManager.GetFriendRegionInfos(uuids);
  3297. }
  3298. public virtual void StoreAddFriendship(UUID ownerID, UUID friendID, uint perms)
  3299. {
  3300. m_sceneGridService.AddNewUserFriend(ownerID, friendID, perms);
  3301. }
  3302. public virtual void StoreUpdateFriendship(UUID ownerID, UUID friendID, uint perms)
  3303. {
  3304. m_sceneGridService.UpdateUserFriendPerms(ownerID, friendID, perms);
  3305. }
  3306. public virtual void StoreRemoveFriendship(UUID ownerID, UUID ExfriendID)
  3307. {
  3308. m_sceneGridService.RemoveUserFriend(ownerID, ExfriendID);
  3309. }
  3310. #endregion
  3311. public void HandleObjectPermissionsUpdate(IClientAPI controller, UUID agentID, UUID sessionID, byte field, uint localId, uint mask, byte set)
  3312. {
  3313. // Check for spoofing.. since this is permissions we're talking about here!
  3314. if ((controller.SessionId == sessionID) && (controller.AgentId == agentID))
  3315. {
  3316. // Tell the object to do permission update
  3317. if (localId != 0)
  3318. {
  3319. SceneObjectGroup chObjectGroup = GetGroupByPrim(localId);
  3320. if (chObjectGroup != null)
  3321. {
  3322. chObjectGroup.UpdatePermissions(agentID, field, localId, mask, set);
  3323. }
  3324. }
  3325. }
  3326. }
  3327. /// <summary>
  3328. /// Causes all clients to get a full object update on all of the objects in the scene.
  3329. /// </summary>
  3330. public void ForceClientUpdate()
  3331. {
  3332. List<EntityBase> EntityList = GetEntities();
  3333. foreach (EntityBase ent in EntityList)
  3334. {
  3335. if (ent is SceneObjectGroup)
  3336. {
  3337. ((SceneObjectGroup)ent).ScheduleGroupForFullUpdate();
  3338. }
  3339. }
  3340. }
  3341. /// <summary>
  3342. /// This is currently only used for scale (to scale to MegaPrim size)
  3343. /// There is a console command that calls this in OpenSimMain
  3344. /// </summary>
  3345. /// <param name="cmdparams"></param>
  3346. public void HandleEditCommand(string[] cmdparams)
  3347. {
  3348. m_log.Debug("Searching for Primitive: '" + cmdparams[2] + "'");
  3349. List<EntityBase> EntityList = GetEntities();
  3350. foreach (EntityBase ent in EntityList)
  3351. {
  3352. if (ent is SceneObjectGroup)
  3353. {
  3354. SceneObjectPart part = ((SceneObjectGroup)ent).GetChildPart(((SceneObjectGroup)ent).UUID);
  3355. if (part != null)
  3356. {
  3357. if (part.Name == cmdparams[2])
  3358. {
  3359. part.Resize(
  3360. new Vector3(Convert.ToSingle(cmdparams[3]), Convert.ToSingle(cmdparams[4]),
  3361. Convert.ToSingle(cmdparams[5])));
  3362. m_log.Debug("Edited scale of Primitive: " + part.Name);
  3363. }
  3364. }
  3365. }
  3366. }
  3367. }
  3368. public override void Show(string[] showParams)
  3369. {
  3370. base.Show(showParams);
  3371. switch (showParams[0])
  3372. {
  3373. case "users":
  3374. m_log.Error("Current Region: " + RegionInfo.RegionName);
  3375. m_log.ErrorFormat("{0,-16}{1,-16}{2,-25}{3,-25}{4,-16}{5,-16}{6,-16}", "Firstname", "Lastname",
  3376. "Agent ID", "Session ID", "Circuit", "IP", "World");
  3377. foreach (ScenePresence scenePresence in GetAvatars())
  3378. {
  3379. m_log.ErrorFormat("{0,-16}{1,-16}{2,-25}{3,-25}{4,-16},{5,-16}{6,-16}",
  3380. scenePresence.Firstname,
  3381. scenePresence.Lastname,
  3382. scenePresence.UUID,
  3383. scenePresence.ControllingClient.AgentId,
  3384. "Unknown",
  3385. "Unknown",
  3386. RegionInfo.RegionName);
  3387. }
  3388. break;
  3389. }
  3390. }
  3391. #region Script Handling Methods
  3392. /// <summary>
  3393. /// Console command handler to send script command to script engine.
  3394. /// </summary>
  3395. /// <param name="args"></param>
  3396. public void SendCommandToPlugins(string[] args)
  3397. {
  3398. m_eventManager.TriggerOnPluginConsole(args);
  3399. }
  3400. public LandData GetLandData(float x, float y)
  3401. {
  3402. return LandChannel.GetLandObject(x, y).LandData;
  3403. }
  3404. public LandData GetLandData(uint x, uint y)
  3405. {
  3406. m_log.DebugFormat("[SCENE]: returning land for {0},{1}", x, y);
  3407. return LandChannel.GetLandObject((int)x, (int)y).LandData;
  3408. }
  3409. #endregion
  3410. #region Script Engine
  3411. private List<ScriptEngineInterface> ScriptEngines = new List<ScriptEngineInterface>();
  3412. public bool DumpAssetsToFile;
  3413. /// <summary>
  3414. ///
  3415. /// </summary>
  3416. /// <param name="scriptEngine"></param>
  3417. public void AddScriptEngine(ScriptEngineInterface scriptEngine)
  3418. {
  3419. ScriptEngines.Add(scriptEngine);
  3420. scriptEngine.InitializeEngine(this);
  3421. }
  3422. private bool ScriptDanger(SceneObjectPart part,Vector3 pos)
  3423. {
  3424. ILandObject parcel = LandChannel.GetLandObject(pos.X, pos.Y);
  3425. if (part != null)
  3426. {
  3427. if (parcel != null)
  3428. {
  3429. if ((parcel.LandData.Flags & (uint)ParcelFlags.AllowOtherScripts) != 0)
  3430. {
  3431. return true;
  3432. }
  3433. else if ((parcel.LandData.Flags & (uint)ParcelFlags.AllowGroupScripts) != 0)
  3434. {
  3435. if (part.OwnerID == parcel.LandData.OwnerID
  3436. || (parcel.LandData.IsGroupOwned && part.GroupID == parcel.LandData.GroupID)
  3437. || Permissions.IsGod(part.OwnerID))
  3438. {
  3439. return true;
  3440. }
  3441. else
  3442. {
  3443. return false;
  3444. }
  3445. }
  3446. else
  3447. {
  3448. if (part.OwnerID == parcel.LandData.OwnerID)
  3449. {
  3450. return true;
  3451. }
  3452. else
  3453. {
  3454. return false;
  3455. }
  3456. }
  3457. }
  3458. else
  3459. {
  3460. if (pos.X > 0f && pos.X < Constants.RegionSize && pos.Y > 0f && pos.Y < Constants.RegionSize)
  3461. {
  3462. // The only time parcel != null when an object is inside a region is when
  3463. // there is nothing behind the landchannel. IE, no land plugin loaded.
  3464. return true;
  3465. }
  3466. else
  3467. {
  3468. // The object is outside of this region. Stop piping events to it.
  3469. return false;
  3470. }
  3471. }
  3472. }
  3473. else
  3474. {
  3475. return false;
  3476. }
  3477. }
  3478. public bool ScriptDanger(uint localID, Vector3 pos)
  3479. {
  3480. SceneObjectPart part = GetSceneObjectPart(localID);
  3481. if (part != null)
  3482. {
  3483. return ScriptDanger(part, pos);
  3484. }
  3485. else
  3486. {
  3487. return false;
  3488. }
  3489. }
  3490. public bool PipeEventsForScript(uint localID)
  3491. {
  3492. SceneObjectPart part = GetSceneObjectPart(localID);
  3493. if (part != null)
  3494. {
  3495. // Changed so that child prims of attachments return ScriptDanger for their parent, so that
  3496. // their scripts will actually run.
  3497. // -- Leaf, Tue Aug 12 14:17:05 EDT 2008
  3498. SceneObjectPart parent = part.ParentGroup.RootPart;
  3499. if (parent != null && parent.IsAttachment)
  3500. return ScriptDanger(parent, parent.GetWorldPosition());
  3501. else
  3502. return ScriptDanger(part, part.GetWorldPosition());
  3503. }
  3504. else
  3505. {
  3506. return false;
  3507. }
  3508. }
  3509. #endregion
  3510. #region SceneGraph wrapper methods
  3511. /// <summary>
  3512. ///
  3513. /// </summary>
  3514. /// <param name="localID"></param>
  3515. /// <returns></returns>
  3516. public UUID ConvertLocalIDToFullID(uint localID)
  3517. {
  3518. return m_sceneGraph.ConvertLocalIDToFullID(localID);
  3519. }
  3520. public void SwapRootAgentCount(bool rootChildChildRootTF)
  3521. {
  3522. m_sceneGraph.SwapRootChildAgent(rootChildChildRootTF);
  3523. }
  3524. public void AddPhysicalPrim(int num)
  3525. {
  3526. m_sceneGraph.AddPhysicalPrim(num);
  3527. }
  3528. public void RemovePhysicalPrim(int num)
  3529. {
  3530. m_sceneGraph.RemovePhysicalPrim(num);
  3531. }
  3532. //The idea is to have a group of method that return a list of avatars meeting some requirement
  3533. // ie it could be all m_scenePresences within a certain range of the calling prim/avatar.
  3534. /// <summary>
  3535. /// Return a list of all avatars in this region.
  3536. /// This list is a new object, so it can be iterated over without locking.
  3537. /// </summary>
  3538. /// <returns></returns>
  3539. public List<ScenePresence> GetAvatars()
  3540. {
  3541. return m_sceneGraph.GetAvatars();
  3542. }
  3543. /// <summary>
  3544. /// Return a list of all ScenePresences in this region. This returns child agents as well as root agents.
  3545. /// This list is a new object, so it can be iterated over without locking.
  3546. /// </summary>
  3547. /// <returns></returns>
  3548. public List<ScenePresence> GetScenePresences()
  3549. {
  3550. return m_sceneGraph.GetScenePresences();
  3551. }
  3552. /// <summary>
  3553. /// Request a filtered list of ScenePresences in this region.
  3554. /// This list is a new object, so it can be iterated over without locking.
  3555. /// </summary>
  3556. /// <param name="filter"></param>
  3557. /// <returns></returns>
  3558. public List<ScenePresence> GetScenePresences(FilterAvatarList filter)
  3559. {
  3560. return m_sceneGraph.GetScenePresences(filter);
  3561. }
  3562. /// <summary>
  3563. /// Request a scene presence by UUID
  3564. /// </summary>
  3565. /// <param name="avatarID"></param>
  3566. /// <returns></returns>
  3567. public ScenePresence GetScenePresence(UUID avatarID)
  3568. {
  3569. return m_sceneGraph.GetScenePresence(avatarID);
  3570. }
  3571. public override bool PresenceChildStatus(UUID avatarID)
  3572. {
  3573. ScenePresence cp = GetScenePresence(avatarID);
  3574. // FIXME: This is really crap - some logout code is relying on a NullReferenceException to halt its processing
  3575. // This needs to be fixed properly by cleaning up the logout code.
  3576. //if (cp != null)
  3577. // return cp.IsChildAgent;
  3578. //return false;
  3579. return cp.IsChildAgent;
  3580. }
  3581. /// <summary>
  3582. ///
  3583. /// </summary>
  3584. /// <param name="action"></param>
  3585. public void ForEachScenePresence(Action<ScenePresence> action)
  3586. {
  3587. // We don't want to try to send messages if there are no avatars.
  3588. if (m_sceneGraph != null && m_sceneGraph.ScenePresences != null)
  3589. {
  3590. try
  3591. {
  3592. List<ScenePresence> presenceList = GetScenePresences();
  3593. foreach (ScenePresence presence in presenceList)
  3594. {
  3595. action(presence);
  3596. }
  3597. }
  3598. catch (Exception e)
  3599. {
  3600. m_log.Info("[BUG] in " + RegionInfo.RegionName + ": " + e.ToString());
  3601. m_log.Info("[BUG] Stack Trace: " + e.StackTrace);
  3602. }
  3603. }
  3604. }
  3605. /// <summary>
  3606. ///
  3607. /// </summary>
  3608. /// <param name="action"></param>
  3609. // public void ForEachObject(Action<SceneObjectGroup> action)
  3610. // {
  3611. // List<SceneObjectGroup> presenceList;
  3612. //
  3613. // lock (m_sceneObjects)
  3614. // {
  3615. // presenceList = new List<SceneObjectGroup>(m_sceneObjects.Values);
  3616. // }
  3617. //
  3618. // foreach (SceneObjectGroup presence in presenceList)
  3619. // {
  3620. // action(presence);
  3621. // }
  3622. // }
  3623. /// <summary>
  3624. /// Get a named prim contained in this scene (will return the first
  3625. /// found, if there are more than one prim with the same name)
  3626. /// </summary>
  3627. /// <param name="name"></param>
  3628. /// <returns></returns>
  3629. public SceneObjectPart GetSceneObjectPart(string name)
  3630. {
  3631. return m_sceneGraph.GetSceneObjectPart(name);
  3632. }
  3633. /// <summary>
  3634. /// Get a prim via its local id
  3635. /// </summary>
  3636. /// <param name="localID"></param>
  3637. /// <returns></returns>
  3638. public SceneObjectPart GetSceneObjectPart(uint localID)
  3639. {
  3640. return m_sceneGraph.GetSceneObjectPart(localID);
  3641. }
  3642. /// <summary>
  3643. /// Get a prim via its UUID
  3644. /// </summary>
  3645. /// <param name="fullID"></param>
  3646. /// <returns></returns>
  3647. public SceneObjectPart GetSceneObjectPart(UUID fullID)
  3648. {
  3649. return m_sceneGraph.GetSceneObjectPart(fullID);
  3650. }
  3651. public bool TryGetAvatar(UUID avatarId, out ScenePresence avatar)
  3652. {
  3653. return m_sceneGraph.TryGetAvatar(avatarId, out avatar);
  3654. }
  3655. public bool TryGetAvatarByName(string avatarName, out ScenePresence avatar)
  3656. {
  3657. return m_sceneGraph.TryGetAvatarByName(avatarName, out avatar);
  3658. }
  3659. public void ForEachClient(Action<IClientAPI> action)
  3660. {
  3661. ClientManager.ForEach(action);
  3662. }
  3663. public void ForEachSOG(Action<SceneObjectGroup> action)
  3664. {
  3665. m_sceneGraph.ForEachSOG(action);
  3666. }
  3667. /// <summary>
  3668. /// Returns a list of the entities in the scene. This is a new list so operations perform on the list itself
  3669. /// will not affect the original list of objects in the scene.
  3670. /// </summary>
  3671. /// <returns></returns>
  3672. public List<EntityBase> GetEntities()
  3673. {
  3674. return m_sceneGraph.GetEntities();
  3675. }
  3676. #endregion
  3677. #region Avatar Appearance Default
  3678. public static void GetDefaultAvatarAppearance(out AvatarWearable[] wearables, out byte[] visualParams)
  3679. {
  3680. visualParams = AvatarAppearance.GetDefaultVisualParams();
  3681. wearables = AvatarWearable.DefaultWearables;
  3682. }
  3683. #endregion
  3684. public void RegionHandleRequest(IClientAPI client, UUID regionID)
  3685. {
  3686. ulong handle = 0;
  3687. if (regionID == RegionInfo.RegionID)
  3688. handle = RegionInfo.RegionHandle;
  3689. else
  3690. {
  3691. GridRegion r = GridService.GetRegionByUUID(UUID.Zero, regionID);
  3692. if (r != null)
  3693. handle = r.RegionHandle;
  3694. }
  3695. if (handle != 0)
  3696. client.SendRegionHandle(regionID, handle);
  3697. }
  3698. public void TerrainUnAcked(IClientAPI client, int patchX, int patchY)
  3699. {
  3700. //m_log.Debug("Terrain packet unacked, resending patch: " + patchX + " , " + patchY);
  3701. client.SendLayerData(patchX, patchY, Heightmap.GetFloatsSerialised());
  3702. }
  3703. public void SetRootAgentScene(UUID agentID)
  3704. {
  3705. IInventoryTransferModule inv = RequestModuleInterface<IInventoryTransferModule>();
  3706. if (inv == null)
  3707. return;
  3708. inv.SetRootAgentScene(agentID, this);
  3709. EventManager.TriggerSetRootAgentScene(agentID, this);
  3710. }
  3711. public bool NeedSceneCacheClear(UUID agentID)
  3712. {
  3713. IInventoryTransferModule inv = RequestModuleInterface<IInventoryTransferModule>();
  3714. if (inv == null)
  3715. return true;
  3716. return inv.NeedSceneCacheClear(agentID, this);
  3717. }
  3718. public void ObjectSaleInfo(IClientAPI client, UUID agentID, UUID sessionID, uint localID, byte saleType, int salePrice)
  3719. {
  3720. SceneObjectPart part = GetSceneObjectPart(localID);
  3721. if (part == null || part.ParentGroup == null)
  3722. return;
  3723. if (part.ParentGroup.IsDeleted)
  3724. return;
  3725. part = part.ParentGroup.RootPart;
  3726. part.ObjectSaleType = saleType;
  3727. part.SalePrice = salePrice;
  3728. part.ParentGroup.HasGroupChanged = true;
  3729. part.GetProperties(client);
  3730. }
  3731. public bool PerformObjectBuy(IClientAPI remoteClient, UUID categoryID,
  3732. uint localID, byte saleType)
  3733. {
  3734. SceneObjectPart part = GetSceneObjectPart(localID);
  3735. if (part == null)
  3736. return false;
  3737. if (part.ParentGroup == null)
  3738. return false;
  3739. SceneObjectGroup group = part.ParentGroup;
  3740. switch (saleType)
  3741. {
  3742. case 1: // Sell as original (in-place sale)
  3743. uint effectivePerms=group.GetEffectivePermissions();
  3744. if ((effectivePerms & (uint)PermissionMask.Transfer) == 0)
  3745. {
  3746. m_dialogModule.SendAlertToUser(remoteClient, "This item doesn't appear to be for sale");
  3747. return false;
  3748. }
  3749. group.SetOwnerId(remoteClient.AgentId);
  3750. group.SetRootPartOwner(part, remoteClient.AgentId,
  3751. remoteClient.ActiveGroupId);
  3752. List<SceneObjectPart> partList =
  3753. new List<SceneObjectPart>(group.Children.Values);
  3754. if (Permissions.PropagatePermissions())
  3755. {
  3756. foreach (SceneObjectPart child in partList)
  3757. {
  3758. child.Inventory.ChangeInventoryOwner(remoteClient.AgentId);
  3759. child.ApplyNextOwnerPermissions();
  3760. }
  3761. }
  3762. part.ObjectSaleType = 0;
  3763. part.SalePrice = 10;
  3764. group.HasGroupChanged = true;
  3765. part.GetProperties(remoteClient);
  3766. part.ScheduleFullUpdate();
  3767. break;
  3768. case 2: // Sell a copy
  3769. Vector3 inventoryStoredPosition = new Vector3
  3770. (((group.AbsolutePosition.X > (int)Constants.RegionSize)
  3771. ? 250
  3772. : group.AbsolutePosition.X)
  3773. ,
  3774. (group.AbsolutePosition.X > (int)Constants.RegionSize)
  3775. ? 250
  3776. : group.AbsolutePosition.X,
  3777. group.AbsolutePosition.Z);
  3778. Vector3 originalPosition = group.AbsolutePosition;
  3779. group.AbsolutePosition = inventoryStoredPosition;
  3780. string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(group);
  3781. group.AbsolutePosition = originalPosition;
  3782. uint perms=group.GetEffectivePermissions();
  3783. if ((perms & (uint)PermissionMask.Transfer) == 0)
  3784. {
  3785. m_dialogModule.SendAlertToUser(remoteClient, "This item doesn't appear to be for sale");
  3786. return false;
  3787. }
  3788. AssetBase asset = CreateAsset(
  3789. group.GetPartName(localID),
  3790. group.GetPartDescription(localID),
  3791. (sbyte)AssetType.Object,
  3792. Utils.StringToBytes(sceneObjectXml));
  3793. AssetService.Store(asset);
  3794. InventoryItemBase item = new InventoryItemBase();
  3795. item.CreatorId = part.CreatorID.ToString();
  3796. item.ID = UUID.Random();
  3797. item.Owner = remoteClient.AgentId;
  3798. item.AssetID = asset.FullID;
  3799. item.Description = asset.Description;
  3800. item.Name = asset.Name;
  3801. item.AssetType = asset.Type;
  3802. item.InvType = (int)InventoryType.Object;
  3803. item.Folder = categoryID;
  3804. uint nextPerms=(perms & 7) << 13;
  3805. if ((nextPerms & (uint)PermissionMask.Copy) == 0)
  3806. perms &= ~(uint)PermissionMask.Copy;
  3807. if ((nextPerms & (uint)PermissionMask.Transfer) == 0)
  3808. perms &= ~(uint)PermissionMask.Transfer;
  3809. if ((nextPerms & (uint)PermissionMask.Modify) == 0)
  3810. perms &= ~(uint)PermissionMask.Modify;
  3811. item.BasePermissions = perms & part.NextOwnerMask;
  3812. item.CurrentPermissions = perms & part.NextOwnerMask;
  3813. item.NextPermissions = part.NextOwnerMask;
  3814. item.EveryOnePermissions = part.EveryoneMask &
  3815. part.NextOwnerMask;
  3816. item.GroupPermissions = part.GroupMask &
  3817. part.NextOwnerMask;
  3818. item.CurrentPermissions |= 8; // Slam!
  3819. item.CreationDate = Util.UnixTimeSinceEpoch();
  3820. if (InventoryService.AddItem(item))
  3821. remoteClient.SendInventoryItemCreateUpdate(item, 0);
  3822. else
  3823. {
  3824. m_dialogModule.SendAlertToUser(remoteClient, "Cannot buy now. Your inventory is unavailable");
  3825. return false;
  3826. }
  3827. break;
  3828. case 3: // Sell contents
  3829. List<UUID> invList = part.Inventory.GetInventoryList();
  3830. bool okToSell = true;
  3831. foreach (UUID invID in invList)
  3832. {
  3833. TaskInventoryItem item1 = part.Inventory.GetInventoryItem(invID);
  3834. if ((item1.CurrentPermissions &
  3835. (uint)PermissionMask.Transfer) == 0)
  3836. {
  3837. okToSell = false;
  3838. break;
  3839. }
  3840. }
  3841. if (!okToSell)
  3842. {
  3843. m_dialogModule.SendAlertToUser(
  3844. remoteClient, "This item's inventory doesn't appear to be for sale");
  3845. return false;
  3846. }
  3847. if (invList.Count > 0)
  3848. MoveTaskInventoryItems(remoteClient.AgentId, part.Name,
  3849. part, invList);
  3850. break;
  3851. }
  3852. return true;
  3853. }
  3854. public void CleanTempObjects()
  3855. {
  3856. List<EntityBase> objs = GetEntities();
  3857. foreach (EntityBase obj in objs)
  3858. {
  3859. if (obj is SceneObjectGroup)
  3860. {
  3861. SceneObjectGroup grp = (SceneObjectGroup)obj;
  3862. if (!grp.IsDeleted)
  3863. {
  3864. if ((grp.RootPart.Flags & PrimFlags.TemporaryOnRez) != 0)
  3865. {
  3866. if (grp.RootPart.Expires <= DateTime.Now)
  3867. DeleteSceneObject(grp, false);
  3868. }
  3869. }
  3870. }
  3871. }
  3872. }
  3873. public void DeleteFromStorage(UUID uuid)
  3874. {
  3875. m_storageManager.DataStore.RemoveObject(uuid, m_regInfo.RegionID);
  3876. }
  3877. public int GetHealth()
  3878. {
  3879. // Returns:
  3880. // 1 = sim is up and accepting http requests. The heartbeat has
  3881. // stopped and the sim is probably locked up, but a remote
  3882. // admin restart may succeed
  3883. //
  3884. // 2 = Sim is up and the heartbeat is running. The sim is likely
  3885. // usable for people within and logins _may_ work
  3886. //
  3887. // 3 = We have seen a new user enter within the past 4 minutes
  3888. // which can be seen as positive confirmation of sim health
  3889. //
  3890. int health=1; // Start at 1, means we're up
  3891. if ((Environment.TickCount - m_lastUpdate) < 1000)
  3892. health+=1;
  3893. else
  3894. return health;
  3895. // A login in the last 4 mins? We can't be doing too badly
  3896. //
  3897. if ((Environment.TickCount - m_LastLogin) < 240000)
  3898. health++;
  3899. else
  3900. return health;
  3901. CheckHeartbeat();
  3902. return health;
  3903. }
  3904. // This callback allows the PhysicsScene to call back to its caller (the SceneGraph) and
  3905. // update non-physical objects like the joint proxy objects that represent the position
  3906. // of the joints in the scene.
  3907. // This routine is normally called from within a lock (OdeLock) from within the OdePhysicsScene
  3908. // WARNING: be careful of deadlocks here if you manipulate the scene. Remember you are being called
  3909. // from within the OdePhysicsScene.
  3910. protected internal void jointMoved(PhysicsJoint joint)
  3911. {
  3912. // m_parentScene.PhysicsScene.DumpJointInfo(); // non-thread-locked version; we should already be in a lock (OdeLock) when this callback is invoked
  3913. SceneObjectPart jointProxyObject = GetSceneObjectPart(joint.ObjectNameInScene);
  3914. if (jointProxyObject == null)
  3915. {
  3916. jointErrorMessage(joint, "WARNING, joint proxy not found, name " + joint.ObjectNameInScene);
  3917. return;
  3918. }
  3919. // now update the joint proxy object in the scene to have the position of the joint as returned by the physics engine
  3920. SceneObjectPart trackedBody = GetSceneObjectPart(joint.TrackedBodyName); // FIXME: causes a sequential lookup
  3921. 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.
  3922. jointProxyObject.Velocity = trackedBody.Velocity;
  3923. jointProxyObject.RotationalVelocity = trackedBody.RotationalVelocity;
  3924. switch (joint.Type)
  3925. {
  3926. case PhysicsJointType.Ball:
  3927. {
  3928. PhysicsVector jointAnchor = PhysicsScene.GetJointAnchor(joint);
  3929. Vector3 proxyPos = new Vector3(jointAnchor.X, jointAnchor.Y, jointAnchor.Z);
  3930. jointProxyObject.ParentGroup.UpdateGroupPosition(proxyPos); // schedules the entire group for a terse update
  3931. }
  3932. break;
  3933. case PhysicsJointType.Hinge:
  3934. {
  3935. PhysicsVector jointAnchor = PhysicsScene.GetJointAnchor(joint);
  3936. // Normally, we would just ask the physics scene to return the axis for the joint.
  3937. // Unfortunately, ODE sometimes returns <0,0,0> for the joint axis, which should
  3938. // never occur. Therefore we cannot rely on ODE to always return a correct joint axis.
  3939. // Therefore the following call does not always work:
  3940. //PhysicsVector phyJointAxis = _PhyScene.GetJointAxis(joint);
  3941. // instead we compute the joint orientation by saving the original joint orientation
  3942. // relative to one of the jointed bodies, and applying this transformation
  3943. // to the current position of the jointed bodies (the tracked body) to compute the
  3944. // current joint orientation.
  3945. if (joint.TrackedBodyName == null)
  3946. {
  3947. jointErrorMessage(joint, "joint.TrackedBodyName is null, joint " + joint.ObjectNameInScene);
  3948. }
  3949. Vector3 proxyPos = new Vector3(jointAnchor.X, jointAnchor.Y, jointAnchor.Z);
  3950. Quaternion q = trackedBody.RotationOffset * joint.LocalRotation;
  3951. jointProxyObject.ParentGroup.UpdateGroupPosition(proxyPos); // schedules the entire group for a terse update
  3952. jointProxyObject.ParentGroup.UpdateGroupRotation(q); // schedules the entire group for a terse update
  3953. }
  3954. break;
  3955. }
  3956. }
  3957. // This callback allows the PhysicsScene to call back to its caller (the SceneGraph) and
  3958. // update non-physical objects like the joint proxy objects that represent the position
  3959. // of the joints in the scene.
  3960. // This routine is normally called from within a lock (OdeLock) from within the OdePhysicsScene
  3961. // WARNING: be careful of deadlocks here if you manipulate the scene. Remember you are being called
  3962. // from within the OdePhysicsScene.
  3963. protected internal void jointDeactivated(PhysicsJoint joint)
  3964. {
  3965. //m_log.Debug("[NINJA] SceneGraph.jointDeactivated, joint:" + joint.ObjectNameInScene);
  3966. SceneObjectPart jointProxyObject = GetSceneObjectPart(joint.ObjectNameInScene);
  3967. if (jointProxyObject == null)
  3968. {
  3969. jointErrorMessage(joint, "WARNING, trying to deactivate (stop interpolation of) joint proxy, but not found, name " + joint.ObjectNameInScene);
  3970. return;
  3971. }
  3972. // turn the proxy non-physical, which also stops its client-side interpolation
  3973. bool wasUsingPhysics = ((jointProxyObject.ObjectFlags & (uint)PrimFlags.Physics) != 0);
  3974. if (wasUsingPhysics)
  3975. {
  3976. 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
  3977. }
  3978. }
  3979. // This callback allows the PhysicsScene to call back to its caller (the SceneGraph) and
  3980. // alert the user of errors by using the debug channel in the same way that scripts alert
  3981. // the user of compile errors.
  3982. // This routine is normally called from within a lock (OdeLock) from within the OdePhysicsScene
  3983. // WARNING: be careful of deadlocks here if you manipulate the scene. Remember you are being called
  3984. // from within the OdePhysicsScene.
  3985. public void jointErrorMessage(PhysicsJoint joint, string message)
  3986. {
  3987. if (joint != null)
  3988. {
  3989. if (joint.ErrorMessageCount > PhysicsJoint.maxErrorMessages)
  3990. return;
  3991. SceneObjectPart jointProxyObject = GetSceneObjectPart(joint.ObjectNameInScene);
  3992. if (jointProxyObject != null)
  3993. {
  3994. SimChat(Utils.StringToBytes("[NINJA]: " + message),
  3995. ChatTypeEnum.DebugChannel,
  3996. 2147483647,
  3997. jointProxyObject.AbsolutePosition,
  3998. jointProxyObject.Name,
  3999. jointProxyObject.UUID,
  4000. false);
  4001. joint.ErrorMessageCount++;
  4002. if (joint.ErrorMessageCount > PhysicsJoint.maxErrorMessages)
  4003. {
  4004. SimChat(Utils.StringToBytes("[NINJA]: Too many messages for this joint, suppressing further messages."),
  4005. ChatTypeEnum.DebugChannel,
  4006. 2147483647,
  4007. jointProxyObject.AbsolutePosition,
  4008. jointProxyObject.Name,
  4009. jointProxyObject.UUID,
  4010. false);
  4011. }
  4012. }
  4013. else
  4014. {
  4015. // couldn't find the joint proxy object; the error message is silently suppressed
  4016. }
  4017. }
  4018. }
  4019. public Scene ConsoleScene()
  4020. {
  4021. if (MainConsole.Instance == null)
  4022. return null;
  4023. if (MainConsole.Instance.ConsoleScene is Scene)
  4024. return (Scene)MainConsole.Instance.ConsoleScene;
  4025. return null;
  4026. }
  4027. public float GetGroundHeight(float x, float y)
  4028. {
  4029. if (x < 0)
  4030. x = 0;
  4031. if (x >= Heightmap.Width)
  4032. x = Heightmap.Width - 1;
  4033. if (y < 0)
  4034. y = 0;
  4035. if (y >= Heightmap.Height)
  4036. y = Heightmap.Height - 1;
  4037. Vector3 p0 = new Vector3(x, y, (float)Heightmap[(int)x, (int)y]);
  4038. Vector3 p1 = new Vector3(p0);
  4039. Vector3 p2 = new Vector3(p0);
  4040. p1.X += 1.0f;
  4041. if (p1.X < Heightmap.Width)
  4042. p1.Z = (float)Heightmap[(int)p1.X, (int)p1.Y];
  4043. p2.Y += 1.0f;
  4044. if (p2.Y < Heightmap.Height)
  4045. p2.Z = (float)Heightmap[(int)p2.X, (int)p2.Y];
  4046. Vector3 v0 = new Vector3(p1.X - p0.X, p1.Y - p0.Y, p1.Z - p0.Z);
  4047. Vector3 v1 = new Vector3(p2.X - p0.X, p2.Y - p0.Y, p2.Z - p0.Z);
  4048. v0.Normalize();
  4049. v1.Normalize();
  4050. Vector3 vsn = new Vector3();
  4051. vsn.X = (v0.Y * v1.Z) - (v0.Z * v1.Y);
  4052. vsn.Y = (v0.Z * v1.X) - (v0.X * v1.Z);
  4053. vsn.Z = (v0.X * v1.Y) - (v0.Y * v1.X);
  4054. vsn.Normalize();
  4055. float xdiff = x - (float)((int)x);
  4056. float ydiff = y - (float)((int)y);
  4057. return (((vsn.X * xdiff) + (vsn.Y * ydiff)) / (-1 * vsn.Z)) + p0.Z;
  4058. }
  4059. private void CheckHeartbeat()
  4060. {
  4061. if (m_firstHeartbeat)
  4062. return;
  4063. if (System.Environment.TickCount - m_lastUpdate > 2000)
  4064. StartTimer();
  4065. }
  4066. }
  4067. }