Scene.cs 188 KB

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