LLClientView.cs 607 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852138531385413855138561385713858138591386013861138621386313864138651386613867138681386913870138711387213873138741387513876138771387813879138801388113882138831388413885138861388713888138891389013891138921389313894138951389613897138981389913900139011390213903139041390513906139071390813909139101391113912139131391413915139161391713918139191392013921139221392313924139251392613927139281392913930139311393213933139341393513936139371393813939139401394113942139431394413945139461394713948139491395013951139521395313954139551395613957139581395913960139611396213963139641396513966139671396813969139701397113972139731397413975139761397713978139791398013981139821398313984139851398613987139881398913990139911399213993139941399513996139971399813999140001400114002140031400414005140061400714008140091401014011140121401314014140151401614017140181401914020140211402214023140241402514026140271402814029140301403114032140331403414035140361403714038140391404014041140421404314044140451404614047140481404914050140511405214053140541405514056140571405814059140601406114062140631406414065140661406714068140691407014071140721407314074140751407614077140781407914080140811408214083
  1. /*
  2. * Copyright (c) Contributors, http://opensimulator.org/
  3. * See CONTRIBUTORS.TXT for a full list of copyright holders.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of the OpenSimulator Project nor the
  13. * names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
  17. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
  20. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. using System;
  28. using System.Collections.Generic;
  29. using System.Net;
  30. using System.Reflection;
  31. using System.Runtime;
  32. using System.Text;
  33. using System.Threading;
  34. using log4net;
  35. using OpenMetaverse;
  36. using OpenMetaverse.Packets;
  37. using OpenMetaverse.StructuredData;
  38. using OpenSim.Framework;
  39. using OpenSim.Framework.Client;
  40. using OpenSim.Framework.Monitoring;
  41. using OpenSim.Region.Framework.Interfaces;
  42. using OpenSim.Region.Framework.Scenes;
  43. using OpenSim.Services.Interfaces;
  44. using AssetLandmark = OpenSim.Framework.AssetLandmark;
  45. using Caps = OpenSim.Framework.Capabilities.Caps;
  46. using PermissionMask = OpenSim.Framework.PermissionMask;
  47. using RegionFlags = OpenMetaverse.RegionFlags;
  48. namespace OpenSim.Region.ClientStack.LindenUDP
  49. {
  50. public delegate void PacketMethod(Packet packet);
  51. /// <summary>
  52. /// Handles new client connections
  53. /// Constructor takes a single Packet and authenticates everything
  54. /// </summary>
  55. public class LLClientView : IClientAPI, IClientCore, IClientIM, IClientChat, IClientInventory, IStatsCollector, IClientIPEndpoint
  56. {
  57. /// <value>
  58. /// Debug packet level. See OpenSim.RegisterConsoleCommands() for more details.
  59. /// </value>
  60. public int DebugPacketLevel { get; set; }
  61. #region Events
  62. public event BinaryGenericMessage OnBinaryGenericMessage;
  63. public event Action<IClientAPI> OnLogout;
  64. public event ObjectPermissions OnObjectPermissions;
  65. public event Action<IClientAPI> OnConnectionClosed;
  66. public event ViewerEffectEventHandler OnViewerEffect;
  67. public event ImprovedInstantMessage OnInstantMessage;
  68. public event ChatMessage OnChatFromClient;
  69. public event RezObject OnRezObject;
  70. public event DeRezObject OnDeRezObject;
  71. public event RezRestoreToWorld OnRezRestoreToWorld;
  72. public event ModifyTerrain OnModifyTerrain;
  73. public event Action<IClientAPI> OnRegionHandShakeReply;
  74. public event GenericCall1 OnRequestWearables;
  75. public event SetAppearance OnSetAppearance;
  76. public event AvatarNowWearing OnAvatarNowWearing;
  77. public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv;
  78. public event RezMultipleAttachmentsFromInv OnRezMultipleAttachmentsFromInv;
  79. public event UUIDNameRequest OnDetachAttachmentIntoInv;
  80. public event ObjectAttach OnObjectAttach;
  81. public event ObjectDeselect OnObjectDetach;
  82. public event ObjectDrop OnObjectDrop;
  83. public event Action<IClientAPI, bool> OnCompleteMovementToRegion;
  84. public event UpdateAgent OnPreAgentUpdate;
  85. public event UpdateAgent OnAgentUpdate;
  86. public event UpdateAgent OnAgentCameraUpdate;
  87. public event AgentRequestSit OnAgentRequestSit;
  88. public event AgentSit OnAgentSit;
  89. public event AvatarPickerRequest OnAvatarPickerRequest;
  90. public event ChangeAnim OnChangeAnim;
  91. public event Action<IClientAPI> OnRequestAvatarsData;
  92. public event LinkObjects OnLinkObjects;
  93. public event DelinkObjects OnDelinkObjects;
  94. public event GrabObject OnGrabObject;
  95. public event DeGrabObject OnDeGrabObject;
  96. public event SpinStart OnSpinStart;
  97. public event SpinStop OnSpinStop;
  98. public event ObjectDuplicate OnObjectDuplicate;
  99. public event ObjectDuplicateOnRay OnObjectDuplicateOnRay;
  100. public event MoveObject OnGrabUpdate;
  101. public event SpinObject OnSpinUpdate;
  102. public event AddNewPrim OnAddPrim;
  103. public event RequestGodlikePowers OnRequestGodlikePowers;
  104. public event GodKickUser OnGodKickUser;
  105. public event ObjectExtraParams OnUpdateExtraParams;
  106. public event UpdateShape OnUpdatePrimShape;
  107. public event ObjectRequest OnObjectRequest;
  108. public event ObjectSelect OnObjectSelect;
  109. public event ObjectDeselect OnObjectDeselect;
  110. public event GenericCall7 OnObjectDescription;
  111. public event GenericCall7 OnObjectName;
  112. public event GenericCall7 OnObjectClickAction;
  113. public event GenericCall7 OnObjectMaterial;
  114. public event ObjectIncludeInSearch OnObjectIncludeInSearch;
  115. public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily;
  116. public event UpdatePrimFlags OnUpdatePrimFlags;
  117. public event UpdatePrimTexture OnUpdatePrimTexture;
  118. public event ClientChangeObject onClientChangeObject;
  119. public event UpdateVector OnUpdatePrimGroupPosition;
  120. public event UpdatePrimRotation OnUpdatePrimGroupRotation;
  121. public event UpdateVector OnUpdatePrimGroupScale;
  122. public event RequestMapBlocks OnRequestMapBlocks;
  123. public event RequestMapName OnMapNameRequest;
  124. public event TeleportLocationRequest OnTeleportLocationRequest;
  125. public event TeleportLandmarkRequest OnTeleportLandmarkRequest;
  126. public event TeleportCancel OnTeleportCancel;
  127. public event RequestAvatarProperties OnRequestAvatarProperties;
  128. public event SetAlwaysRun OnSetAlwaysRun;
  129. public event AgentDataUpdate OnAgentDataUpdateRequest;
  130. public event TeleportLocationRequest OnSetStartLocationRequest;
  131. public event UpdateAvatarProperties OnUpdateAvatarProperties;
  132. public event CreateNewInventoryItem OnCreateNewInventoryItem;
  133. public event LinkInventoryItem OnLinkInventoryItem;
  134. public event CreateInventoryFolder OnCreateNewInventoryFolder;
  135. public event UpdateInventoryFolder OnUpdateInventoryFolder;
  136. public event MoveInventoryFolder OnMoveInventoryFolder;
  137. public event FetchInventoryDescendents OnFetchInventoryDescendents;
  138. public event PurgeInventoryDescendents OnPurgeInventoryDescendents;
  139. public event FetchInventory OnFetchInventory;
  140. public event RequestTaskInventory OnRequestTaskInventory;
  141. public event UpdateInventoryItem OnUpdateInventoryItem;
  142. public event CopyInventoryItem OnCopyInventoryItem;
  143. public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy;
  144. public event MoveInventoryItem OnMoveInventoryItem;
  145. public event RemoveInventoryItem OnRemoveInventoryItem;
  146. public event RemoveInventoryFolder OnRemoveInventoryFolder;
  147. public event UDPAssetUploadRequest OnAssetUploadRequest;
  148. public event XferReceive OnXferReceive;
  149. public event RequestXfer OnRequestXfer;
  150. public event ConfirmXfer OnConfirmXfer;
  151. public event AbortXfer OnAbortXfer;
  152. public event RequestTerrain OnRequestTerrain;
  153. public event RezScript OnRezScript;
  154. public event UpdateTaskInventory OnUpdateTaskInventory;
  155. public event MoveTaskInventory OnMoveTaskItem;
  156. public event RemoveTaskInventory OnRemoveTaskItem;
  157. public event UUIDNameRequest OnNameFromUUIDRequest;
  158. public event ParcelAccessListRequest OnParcelAccessListRequest;
  159. public event ParcelAccessListUpdateRequest OnParcelAccessListUpdateRequest;
  160. public event ParcelPropertiesRequest OnParcelPropertiesRequest;
  161. public event ParcelDivideRequest OnParcelDivideRequest;
  162. public event ParcelJoinRequest OnParcelJoinRequest;
  163. public event ParcelPropertiesUpdateRequest OnParcelPropertiesUpdateRequest;
  164. public event ParcelSelectObjects OnParcelSelectObjects;
  165. public event ParcelObjectOwnerRequest OnParcelObjectOwnerRequest;
  166. public event ParcelAbandonRequest OnParcelAbandonRequest;
  167. public event ParcelGodForceOwner OnParcelGodForceOwner;
  168. public event ParcelReclaim OnParcelReclaim;
  169. public event ParcelReturnObjectsRequest OnParcelReturnObjectsRequest;
  170. public event ParcelDeedToGroup OnParcelDeedToGroup;
  171. public event RegionInfoRequest OnRegionInfoRequest;
  172. public event EstateCovenantRequest OnEstateCovenantRequest;
  173. public event FriendActionDelegate OnApproveFriendRequest;
  174. public event FriendActionDelegate OnDenyFriendRequest;
  175. public event FriendshipTermination OnTerminateFriendship;
  176. public event GrantUserFriendRights OnGrantUserRights;
  177. public event MoneyTransferRequest OnMoneyTransferRequest;
  178. public event EconomyDataRequest OnEconomyDataRequest;
  179. public event MoneyBalanceRequest OnMoneyBalanceRequest;
  180. public event ParcelBuy OnParcelBuy;
  181. public event UUIDNameRequest OnTeleportHomeRequest;
  182. public event UUIDNameRequest OnUUIDGroupNameRequest;
  183. public event ScriptAnswer OnScriptAnswer;
  184. public event RequestPayPrice OnRequestPayPrice;
  185. public event ObjectSaleInfo OnObjectSaleInfo;
  186. public event ObjectBuy OnObjectBuy;
  187. public event AgentSit OnUndo;
  188. public event AgentSit OnRedo;
  189. public event LandUndo OnLandUndo;
  190. public event ForceReleaseControls OnForceReleaseControls;
  191. public event GodLandStatRequest OnLandStatRequest;
  192. public event RequestObjectPropertiesFamily OnObjectGroupRequest;
  193. public event DetailedEstateDataRequest OnDetailedEstateDataRequest;
  194. public event SetEstateFlagsRequest OnSetEstateFlagsRequest;
  195. public event SetEstateTerrainDetailTexture OnSetEstateTerrainDetailTexture;
  196. public event SetEstateTerrainTextureHeights OnSetEstateTerrainTextureHeights;
  197. public event CommitEstateTerrainTextureRequest OnCommitEstateTerrainTextureRequest;
  198. public event SetRegionTerrainSettings OnSetRegionTerrainSettings;
  199. public event BakeTerrain OnBakeTerrain;
  200. public event RequestTerrain OnUploadTerrain;
  201. public event EstateChangeInfo OnEstateChangeInfo;
  202. public event EstateManageTelehub OnEstateManageTelehub;
  203. public event EstateRestartSimRequest OnEstateRestartSimRequest;
  204. public event EstateChangeCovenantRequest OnEstateChangeCovenantRequest;
  205. public event UpdateEstateAccessDeltaRequest OnUpdateEstateAccessDeltaRequest;
  206. public event SimulatorBlueBoxMessageRequest OnSimulatorBlueBoxMessageRequest;
  207. public event EstateBlueBoxMessageRequest OnEstateBlueBoxMessageRequest;
  208. public event EstateDebugRegionRequest OnEstateDebugRegionRequest;
  209. public event EstateTeleportOneUserHomeRequest OnEstateTeleportOneUserHomeRequest;
  210. public event EstateTeleportAllUsersHomeRequest OnEstateTeleportAllUsersHomeRequest;
  211. public event RegionHandleRequest OnRegionHandleRequest;
  212. public event ParcelInfoRequest OnParcelInfoRequest;
  213. public event ScriptReset OnScriptReset;
  214. public event GetScriptRunning OnGetScriptRunning;
  215. public event SetScriptRunning OnSetScriptRunning;
  216. public event Action<Vector3, bool, bool> OnAutoPilotGo;
  217. public event ActivateGesture OnActivateGesture;
  218. public event DeactivateGesture OnDeactivateGesture;
  219. public event ObjectOwner OnObjectOwner;
  220. public event DirPlacesQuery OnDirPlacesQuery;
  221. public event DirFindQuery OnDirFindQuery;
  222. public event DirLandQuery OnDirLandQuery;
  223. public event DirPopularQuery OnDirPopularQuery;
  224. public event DirClassifiedQuery OnDirClassifiedQuery;
  225. public event EventInfoRequest OnEventInfoRequest;
  226. public event ParcelSetOtherCleanTime OnParcelSetOtherCleanTime;
  227. public event MapItemRequest OnMapItemRequest;
  228. public event OfferCallingCard OnOfferCallingCard;
  229. public event AcceptCallingCard OnAcceptCallingCard;
  230. public event DeclineCallingCard OnDeclineCallingCard;
  231. public event SoundTrigger OnSoundTrigger;
  232. public event StartLure OnStartLure;
  233. public event TeleportLureRequest OnTeleportLureRequest;
  234. public event NetworkStats OnNetworkStatsUpdate;
  235. public event ClassifiedInfoRequest OnClassifiedInfoRequest;
  236. public event ClassifiedInfoUpdate OnClassifiedInfoUpdate;
  237. public event ClassifiedDelete OnClassifiedDelete;
  238. public event ClassifiedGodDelete OnClassifiedGodDelete;
  239. public event EventNotificationAddRequest OnEventNotificationAddRequest;
  240. public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest;
  241. public event EventGodDelete OnEventGodDelete;
  242. public event ParcelDwellRequest OnParcelDwellRequest;
  243. public event UserInfoRequest OnUserInfoRequest;
  244. public event UpdateUserInfo OnUpdateUserInfo;
  245. public event RetrieveInstantMessages OnRetrieveInstantMessages;
  246. public event PickDelete OnPickDelete;
  247. public event PickGodDelete OnPickGodDelete;
  248. public event PickInfoUpdate OnPickInfoUpdate;
  249. public event AvatarNotesUpdate OnAvatarNotesUpdate;
  250. public event MuteListRequest OnMuteListRequest;
  251. public event AvatarInterestUpdate OnAvatarInterestUpdate;
  252. public event PlacesQuery OnPlacesQuery;
  253. public event AgentFOV OnAgentFOV;
  254. public event FindAgentUpdate OnFindAgent;
  255. public event TrackAgentUpdate OnTrackAgent;
  256. public event NewUserReport OnUserReport;
  257. public event SaveStateHandler OnSaveState;
  258. public event GroupAccountSummaryRequest OnGroupAccountSummaryRequest;
  259. public event GroupAccountDetailsRequest OnGroupAccountDetailsRequest;
  260. public event GroupAccountTransactionsRequest OnGroupAccountTransactionsRequest;
  261. public event FreezeUserUpdate OnParcelFreezeUser;
  262. public event EjectUserUpdate OnParcelEjectUser;
  263. public event ParcelBuyPass OnParcelBuyPass;
  264. public event ParcelGodMark OnParcelGodMark;
  265. public event GroupActiveProposalsRequest OnGroupActiveProposalsRequest;
  266. public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest;
  267. public event SimWideDeletesDelegate OnSimWideDeletes;
  268. public event SendPostcard OnSendPostcard;
  269. public event ChangeInventoryItemFlags OnChangeInventoryItemFlags;
  270. public event MuteListEntryUpdate OnUpdateMuteListEntry;
  271. public event MuteListEntryRemove OnRemoveMuteListEntry;
  272. public event GodlikeMessage onGodlikeMessage;
  273. public event GodUpdateRegionInfoUpdate OnGodUpdateRegionInfoUpdate;
  274. public event GenericCall2 OnUpdateThrottles;
  275. #pragma warning disable 0067
  276. // still unused
  277. public event GenericMessage OnGenericMessage;
  278. public event TextureRequest OnRequestTexture;
  279. public event StatusChange OnChildAgentStatus;
  280. public event GenericCall2 OnStopMovement;
  281. public event Action<UUID> OnRemoveAvatar;
  282. public event DisconnectUser OnDisconnectUser;
  283. public event RequestAsset OnRequestAsset;
  284. public event BuyObjectInventory OnBuyObjectInventory;
  285. public event SetEstateTerrainBaseTexture OnSetEstateTerrainBaseTexture;
  286. public event TerrainUnacked OnUnackedTerrain;
  287. public event CachedTextureRequest OnCachedTextureRequest;
  288. public event UpdateVector OnUpdatePrimSinglePosition;
  289. public event StartAnim OnStartAnim;
  290. public event StopAnim OnStopAnim;
  291. public event UpdatePrimSingleRotation OnUpdatePrimSingleRotation;
  292. public event UpdatePrimSingleRotationPosition OnUpdatePrimSingleRotationPosition;
  293. public event UpdatePrimGroupRotation OnUpdatePrimGroupMouseRotation;
  294. public event UpdateVector OnUpdatePrimScale;
  295. #pragma warning restore 0067
  296. #endregion Events
  297. #region Class Members
  298. // LLClientView Only
  299. public delegate void BinaryGenericMessage(Object sender, string method, byte[][] args);
  300. private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
  301. private static string LogHeader = "[LLCLIENTVIEW]";
  302. /// <summary>
  303. /// Handles UDP texture download.
  304. /// </summary>
  305. public LLImageManager ImageManager { get; private set; }
  306. public JobEngine m_asyncPacketProcess;
  307. private readonly LLUDPServer m_udpServer;
  308. private readonly LLUDPClient m_udpClient;
  309. private readonly UUID m_sessionId;
  310. private readonly UUID m_secureSessionId;
  311. protected readonly UUID m_agentId;
  312. protected readonly UUID m_scopeId;
  313. private readonly uint m_circuitCode;
  314. private readonly byte[] m_regionChannelVersion = Utils.EmptyBytes;
  315. private readonly IGroupsModule m_GroupsModule;
  316. // private int m_cachedTextureSerial;
  317. private PriorityQueue m_entityUpdates;
  318. private PriorityQueue m_entityProps;
  319. private Prioritizer m_prioritizer;
  320. private bool m_disableFacelights;
  321. // needs optimization
  322. private HashSet<SceneObjectGroup> GroupsInView = new HashSet<SceneObjectGroup>();
  323. #pragma warning disable 0414
  324. private bool m_VelocityInterpolate;
  325. #pragma warning restore 0414
  326. private const uint MaxTransferBytesPerPacket = 600;
  327. private bool m_SupportObjectAnimations;
  328. /// <value>
  329. /// Maintain a record of all the objects killed. This allows us to stop an update being sent from the
  330. /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an
  331. /// ownerless phantom.
  332. ///
  333. /// All manipulation of this set has to occur under an m_entityUpdates.SyncRoot lock
  334. ///
  335. /// </value>
  336. protected List<uint> m_killRecord;
  337. //protected HashSet<uint> m_attachmentsSent;
  338. private bool m_SendLogoutPacketWhenClosing = true;
  339. /// <summary>
  340. /// We retain a single AgentUpdateArgs so that we can constantly reuse it rather than construct a new one for
  341. /// every single incoming AgentUpdate. Every client sends 10 AgentUpdate UDP messages per second, even if it
  342. /// is doing absolutely nothing.
  343. /// </summary>
  344. /// <remarks>
  345. /// This does mean that agent updates must be processed synchronously, at least for each client, and called methods
  346. /// cannot retain a reference to it outside of that method.
  347. /// </remarks>
  348. private readonly AgentUpdateArgs m_thisAgentUpdateArgs = new AgentUpdateArgs();
  349. protected Dictionary<PacketType, PacketProcessor> m_packetHandlers = new Dictionary<PacketType, PacketProcessor>();
  350. protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers
  351. protected Scene m_scene;
  352. protected string m_firstName;
  353. protected string m_lastName;
  354. protected Vector3 m_startpos;
  355. protected UUID m_activeGroupID;
  356. protected string m_activeGroupName = String.Empty;
  357. protected ulong m_activeGroupPowers;
  358. protected Dictionary<UUID, ulong> m_groupPowers = new Dictionary<UUID, ulong>();
  359. protected int m_terrainCheckerCount;
  360. protected uint m_agentFOVCounter;
  361. protected IAssetService m_assetService;
  362. protected bool m_supportViewerCache = false;
  363. #endregion Class Members
  364. #region Properties
  365. public LLUDPClient UDPClient { get { return m_udpClient; } }
  366. public LLUDPServer UDPServer { get { return m_udpServer; } }
  367. public IPEndPoint RemoteEndPoint { get { return m_udpClient.RemoteEndPoint; } }
  368. public UUID SecureSessionId { get { return m_secureSessionId; } }
  369. public IScene Scene { get { return m_scene; } }
  370. public UUID SessionId { get { return m_sessionId; } }
  371. public Vector3 StartPos
  372. {
  373. get { return m_startpos; }
  374. set { m_startpos = value; }
  375. }
  376. public float StartFar { get; set; }
  377. public UUID AgentId { get { return m_agentId; } }
  378. public UUID ScopeId { get { return m_scopeId; } }
  379. public ISceneAgent SceneAgent { get; set; }
  380. public UUID ActiveGroupId { get { return m_activeGroupID; } set { m_activeGroupID = value; } }
  381. public string ActiveGroupName { get { return m_activeGroupName; } set { m_activeGroupName = value; } }
  382. public ulong ActiveGroupPowers { get { return m_activeGroupPowers; } set { m_activeGroupPowers = value; } }
  383. public bool IsGroupMember(UUID groupID) { return m_groupPowers.ContainsKey(groupID); }
  384. public int PingTimeMS
  385. {
  386. get
  387. {
  388. if (UDPClient != null)
  389. return UDPClient.PingTimeMS;
  390. return 0;
  391. }
  392. }
  393. /// <summary>
  394. /// Entity update queues
  395. /// </summary>
  396. public PriorityQueue EntityUpdateQueue { get { return m_entityUpdates; } }
  397. /// <summary>
  398. /// First name of the agent/avatar represented by the client
  399. /// </summary>
  400. public string FirstName { get { return m_firstName; } }
  401. /// <summary>
  402. /// Last name of the agent/avatar represented by the client
  403. /// </summary>
  404. public string LastName { get { return m_lastName; } }
  405. /// <summary>
  406. /// Full name of the client (first name and last name)
  407. /// </summary>
  408. public string Name { get { return FirstName + " " + LastName; } }
  409. public uint CircuitCode { get { return m_circuitCode; } }
  410. protected int m_animationSequenceNumber = (int)(Util.GetTimeStampTicks() & 0x5fffafL);
  411. public int NextAnimationSequenceNumber
  412. {
  413. get
  414. {
  415. int ret = Interlocked.Increment(ref m_animationSequenceNumber);
  416. if (ret <= 0)
  417. {
  418. m_animationSequenceNumber = (int)(Util.GetTimeStampTicks() & 0xafff5fL);
  419. ret = Interlocked.Increment(ref m_animationSequenceNumber);
  420. }
  421. return ret;
  422. }
  423. set
  424. {
  425. m_animationSequenceNumber = value;
  426. }
  427. }
  428. /// <summary>
  429. /// As well as it's function in IClientAPI, in LLClientView we are locking on this property in order to
  430. /// prevent race conditions by different threads calling Close().
  431. /// </summary>
  432. public bool IsActive { get; set; }
  433. /// <summary>
  434. /// Used to synchronise threads when client is being closed.
  435. /// </summary>
  436. public object CloseSyncLock { get;} = new object();
  437. public bool IsLoggingOut { get; set; }
  438. public bool DisableFacelights
  439. {
  440. get { return m_disableFacelights; }
  441. set { m_disableFacelights = value; }
  442. }
  443. public List<uint> SelectedObjects {get; private set;}
  444. public bool SendLogoutPacketWhenClosing { set { m_SendLogoutPacketWhenClosing = value; } }
  445. #endregion Properties
  446. // ~LLClientView()
  447. // {
  448. // m_log.DebugFormat("{0} Destructor called for {1}, circuit code {2}", LogHeader, Name, CircuitCode);
  449. // }
  450. /// <summary>
  451. /// Constructor
  452. /// </summary>
  453. public LLClientView(Scene scene, LLUDPServer udpServer, LLUDPClient udpClient, AuthenticateResponse sessionInfo,
  454. UUID agentId, UUID sessionId, uint circuitCode)
  455. {
  456. // DebugPacketLevel = 1;
  457. SelectedObjects = new List<uint>();
  458. RegisterInterface<IClientIM>(this);
  459. RegisterInterface<IClientInventory>(this);
  460. RegisterInterface<IClientChat>(this);
  461. m_scene = scene;
  462. int pcap = 512;
  463. if(pcap > m_scene.Entities.Count)
  464. pcap = m_scene.Entities.Count;
  465. m_entityUpdates = new PriorityQueue(pcap);
  466. m_entityProps = new PriorityQueue(pcap);
  467. m_killRecord = new List<uint>();
  468. // m_attachmentsSent = new HashSet<uint>();
  469. m_assetService = m_scene.RequestModuleInterface<IAssetService>();
  470. m_GroupsModule = scene.RequestModuleInterface<IGroupsModule>();
  471. ImageManager = new LLImageManager(this, m_assetService, Scene.RequestModuleInterface<IJ2KDecoder>());
  472. m_regionChannelVersion = Util.StringToBytes1024(scene.GetSimulatorVersion());
  473. m_agentId = agentId;
  474. m_sessionId = sessionId;
  475. m_secureSessionId = sessionInfo.LoginInfo.SecureSession;
  476. m_circuitCode = circuitCode;
  477. m_firstName = sessionInfo.LoginInfo.First;
  478. m_lastName = sessionInfo.LoginInfo.Last;
  479. m_startpos = sessionInfo.LoginInfo.StartPos;
  480. StartFar = sessionInfo.LoginInfo.StartFar;
  481. m_udpServer = udpServer;
  482. m_udpClient = udpClient;
  483. m_udpClient.OnQueueEmpty += HandleQueueEmpty;
  484. m_udpClient.HasUpdates += HandleHasUpdates;
  485. m_udpClient.OnPacketStats += PopulateStats;
  486. m_prioritizer = new Prioritizer(m_scene);
  487. // Pick up agent scope which, for gods, can be different from the region scope
  488. IUserAccountService userAccountService = m_scene.RequestModuleInterface<IUserAccountService>();
  489. var myself = userAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_agentId);
  490. RegisterLocalPacketHandlers();
  491. string name = string.Format("AsyncInUDP-{0}",m_agentId.ToString());
  492. m_asyncPacketProcess = new JobEngine(name, name, 5000);
  493. IsActive = true;
  494. m_supportViewerCache = m_udpServer.SupportViewerObjectsCache;
  495. }
  496. #region Client Methods
  497. /// <summary>
  498. /// Close down the client view
  499. /// </summary>
  500. public void Close()
  501. {
  502. Close(true, false);
  503. }
  504. public void Close(bool sendStop, bool force)
  505. {
  506. // We lock here to prevent race conditions between two threads calling close simultaneously (e.g.
  507. // a simultaneous relog just as a client is being closed out due to no packet ack from the old connection.
  508. lock (CloseSyncLock)
  509. {
  510. // We still perform a force close inside the sync lock since this is intended to attempt close where
  511. // there is some unidentified connection problem, not where we have issues due to deadlock
  512. if (!IsActive && !force)
  513. {
  514. m_log.DebugFormat( "{0} Not attempting to close inactive client {1} in {2} since force flag is not set",
  515. LogHeader, Name, m_scene.Name);
  516. return;
  517. }
  518. IsActive = false;
  519. CloseWithoutChecks(sendStop);
  520. }
  521. }
  522. /// <summary>
  523. /// Closes down the client view without first checking whether it is active.
  524. /// </summary>
  525. /// <remarks>
  526. /// This exists because LLUDPServer has to set IsActive = false in earlier synchronous code before calling
  527. /// CloseWithoutIsActiveCheck asynchronously.
  528. ///
  529. /// Callers must lock ClosingSyncLock before calling.
  530. /// </remarks>
  531. public void CloseWithoutChecks(bool sendStop)
  532. {
  533. m_log.DebugFormat(
  534. "[CLIENT]: Close has been called for {0} attached to scene {1}",
  535. Name, m_scene.RegionInfo.RegionName);
  536. if (sendStop)
  537. {
  538. // Send the STOP packet
  539. DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
  540. OutPacket(disable, ThrottleOutPacketType.Unknown);
  541. }
  542. // Fire the callback for this connection closing
  543. if (OnConnectionClosed != null)
  544. OnConnectionClosed(this);
  545. m_asyncPacketProcess.Stop();
  546. // Flush all of the packets out of the UDP server for this client
  547. if (m_udpServer != null)
  548. m_udpServer.Flush(m_udpClient);
  549. // Remove ourselves from the scene
  550. m_scene.RemoveClient(m_agentId, true);
  551. SceneAgent = null;
  552. // We can't reach into other scenes and close the connection
  553. // We need to do this over grid communications
  554. //m_scene.CloseAllAgents(CircuitCode);
  555. // Disable UDP handling for this client
  556. m_udpClient.OnQueueEmpty -= HandleQueueEmpty;
  557. m_udpClient.HasUpdates -= HandleHasUpdates;
  558. m_udpClient.OnPacketStats -= PopulateStats;
  559. m_udpClient.Shutdown();
  560. // Shutdown the image manager
  561. ImageManager.Close();
  562. ImageManager = null;
  563. m_entityUpdates.Close();
  564. m_entityProps.Close();
  565. m_killRecord.Clear();
  566. GroupsInView.Clear();
  567. if(m_scene.GetNumberOfClients() == 0)
  568. {
  569. GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
  570. GC.Collect();
  571. GC.WaitForPendingFinalizers();
  572. GC.Collect();
  573. GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.Default;
  574. }
  575. }
  576. public void Kick(string message)
  577. {
  578. if (!SceneAgent.IsChildAgent)
  579. {
  580. KickUserPacket kupack = (KickUserPacket)PacketPool.Instance.GetPacket(PacketType.KickUser);
  581. kupack.UserInfo.AgentID = m_agentId;
  582. kupack.UserInfo.SessionID = SessionId;
  583. kupack.TargetBlock.TargetIP = 0;
  584. kupack.TargetBlock.TargetPort = 0;
  585. kupack.UserInfo.Reason = Util.StringToBytes256(message);
  586. OutPacket(kupack, ThrottleOutPacketType.Task);
  587. // You must sleep here or users get no message!
  588. Thread.Sleep(500);
  589. }
  590. }
  591. public void Stop()
  592. {
  593. }
  594. #endregion Client Methods
  595. #region Packet Handling
  596. public void PopulateStats(int inPackets, int outPackets, int unAckedBytes)
  597. {
  598. OnNetworkStatsUpdate?.Invoke(inPackets, outPackets, unAckedBytes);
  599. }
  600. /// <summary>
  601. /// Add a handler for the given packet type.
  602. /// </summary>
  603. /// <remarks>
  604. /// The packet is handled on its own thread. If packets must be handled in the order in which they
  605. /// are received then please use the synchronous version of this method.
  606. /// </remarks>
  607. /// <param name="packetType"></param>
  608. /// <param name="handler"></param>
  609. /// <returns>true if the handler was added. This is currently always the case.</returns>
  610. public bool AddLocalPacketHandler(PacketType packetType, PacketMethod handler)
  611. {
  612. return AddLocalPacketHandler(packetType, handler, true);
  613. }
  614. /// <summary>
  615. /// Add a handler for the given packet type.
  616. /// </summary>
  617. /// <param name="packetType"></param>
  618. /// <param name="handler"></param>
  619. /// <param name="doAsync">
  620. /// If true, when the packet is received it is handled on its own thread rather than on the main inward bound
  621. /// packet handler thread. This vastly increases respnosiveness but some packets need to be handled
  622. /// synchronously.
  623. /// </param>
  624. /// <returns>true if the handler was added. This is currently always the case.</returns>
  625. public bool AddLocalPacketHandler(PacketType packetType, PacketMethod handler, bool doAsync)
  626. {
  627. lock (m_packetHandlers)
  628. {
  629. if (!m_packetHandlers.ContainsKey(packetType))
  630. {
  631. m_packetHandlers.Add(packetType, new PacketProcessor() { method = handler, Async = doAsync});
  632. return true;
  633. }
  634. }
  635. return false;
  636. }
  637. public bool AddGenericPacketHandler(string MethodName, GenericMessage handler)
  638. {
  639. MethodName = MethodName.ToLower().Trim();
  640. bool result = false;
  641. lock (m_genericPacketHandlers)
  642. {
  643. if (!m_genericPacketHandlers.ContainsKey(MethodName))
  644. {
  645. m_genericPacketHandlers.Add(MethodName, handler);
  646. result = true;
  647. }
  648. }
  649. return result;
  650. }
  651. /// <summary>
  652. /// Try to process a packet using registered packet handlers
  653. /// </summary>
  654. /// <param name="packet"></param>
  655. /// <returns>True if a handler was found which successfully processed the packet.</returns>
  656. protected bool ProcessPacketMethod(Packet packet)
  657. {
  658. if (m_packetHandlers.TryGetValue(packet.Type, out PacketProcessor pprocessor))
  659. {
  660. if (pprocessor.Async)
  661. {
  662. m_asyncPacketProcess.QueueJob(packet.Type.ToString(), () =>
  663. {
  664. try
  665. {
  666. pprocessor.method(packet);
  667. }
  668. catch (Exception e)
  669. {
  670. // Make sure that we see any exception caused by the asynchronous operation.
  671. m_log.Error(string.Format(
  672. "[LLCLIENTVIEW]: Caught exception while processing {0} for {1} ", packet, Name),e);
  673. }
  674. });
  675. }
  676. else
  677. {
  678. pprocessor.method(packet);
  679. }
  680. return true;
  681. }
  682. return false;
  683. }
  684. #endregion Packet Handling
  685. # region Setup
  686. public virtual void Start()
  687. {
  688. m_asyncPacketProcess.Start();
  689. m_scene.AddNewAgent(this, PresenceType.User);
  690. // RefreshGroupMembership();
  691. }
  692. # endregion
  693. public void ActivateGesture(UUID assetId, UUID gestureId)
  694. {
  695. }
  696. public void DeactivateGesture(UUID assetId, UUID gestureId)
  697. {
  698. }
  699. // Sound
  700. public void SoundTrigger(UUID soundId, UUID owerid, UUID Objectid, UUID ParentId, float Gain, Vector3 Position, UInt64 Handle)
  701. {
  702. }
  703. #region Scene/Avatar to Client
  704. // temporary here ( from estatemanagermodule)
  705. private uint GetRegionFlags()
  706. {
  707. RegionFlags flags = RegionFlags.None;
  708. if (Scene.RegionInfo.RegionSettings.AllowDamage)
  709. flags |= RegionFlags.AllowDamage;
  710. if (Scene.RegionInfo.EstateSettings.AllowLandmark)
  711. flags |= RegionFlags.AllowLandmark;
  712. if (Scene.RegionInfo.EstateSettings.AllowSetHome)
  713. flags |= RegionFlags.AllowSetHome;
  714. if (Scene.RegionInfo.EstateSettings.ResetHomeOnTeleport)
  715. flags |= RegionFlags.ResetHomeOnTeleport;
  716. if (Scene.RegionInfo.RegionSettings.FixedSun)
  717. flags |= RegionFlags.SunFixed;
  718. // allow access override (was taxfree)
  719. if (!Scene.RegionInfo.EstateSettings.TaxFree) // this is now wrong means !ALLOW_ACCESS_OVERRIDE
  720. flags |= RegionFlags.AllowParcelAccessOverride;
  721. if (Scene.RegionInfo.RegionSettings.BlockTerraform)
  722. flags |= RegionFlags.BlockTerraform;
  723. if (!Scene.RegionInfo.RegionSettings.AllowLandResell)
  724. flags |= RegionFlags.BlockLandResell;
  725. if (Scene.RegionInfo.RegionSettings.Sandbox)
  726. flags |= RegionFlags.Sandbox;
  727. // nulllayer not used
  728. if (Scene.RegionInfo.RegionSettings.Casino)
  729. flags |= RegionFlags.SkipAgentAction; // redefined
  730. if (Scene.RegionInfo.RegionSettings.GodBlockSearch)
  731. flags |= RegionFlags.SkipUpdateInterestList; // redefined
  732. if (Scene.RegionInfo.RegionSettings.DisableCollisions)
  733. flags |= RegionFlags.SkipCollisions;
  734. if (Scene.RegionInfo.RegionSettings.DisableScripts)
  735. flags |= RegionFlags.SkipScripts;
  736. if (Scene.RegionInfo.RegionSettings.DisablePhysics)
  737. flags |= RegionFlags.SkipPhysics;
  738. if (Scene.RegionInfo.EstateSettings.PublicAccess)
  739. flags |= RegionFlags.ExternallyVisible; // ???? need revision
  740. //MainlandVisible -> allow return enc object
  741. //PublicAllowed -> allow return enc estate object
  742. if (Scene.RegionInfo.EstateSettings.BlockDwell)
  743. flags |= RegionFlags.BlockDwell;
  744. if (Scene.RegionInfo.RegionSettings.BlockFly)
  745. flags |= RegionFlags.NoFly;
  746. if (Scene.RegionInfo.EstateSettings.AllowDirectTeleport)
  747. flags |= RegionFlags.AllowDirectTeleport;
  748. if (Scene.RegionInfo.EstateSettings.EstateSkipScripts)
  749. flags |= RegionFlags.EstateSkipScripts;
  750. if (Scene.RegionInfo.RegionSettings.RestrictPushing)
  751. flags |= RegionFlags.RestrictPushObject;
  752. if (Scene.RegionInfo.EstateSettings.DenyAnonymous)
  753. flags |= RegionFlags.DenyAnonymous;
  754. //DenyIdentified unused
  755. //DenyTransacted unused
  756. if (Scene.RegionInfo.RegionSettings.AllowLandJoinDivide)
  757. flags |= RegionFlags.AllowParcelChanges;
  758. //AbuseEmailToEstateOwner -> block flyover
  759. if (Scene.RegionInfo.EstateSettings.AllowVoice)
  760. flags |= RegionFlags.AllowVoice;
  761. if (Scene.RegionInfo.RegionSettings.BlockShowInSearch)
  762. flags |= RegionFlags.BlockParcelSearch;
  763. if (Scene.RegionInfo.EstateSettings.DenyMinors)
  764. flags |= RegionFlags.DenyAgeUnverified;
  765. if(Scene.RegionInfo.EstateSettings.AllowEnvironmentOverride)
  766. flags |= RegionFlags.AllowEnvironmentOverride;
  767. return (uint)flags;
  768. }
  769. // Region handshake may need a more detailed look
  770. static private readonly byte[] RegionHandshakeHeader = new byte[] {
  771. Helpers.MSG_RELIABLE | Helpers.MSG_ZEROCODED,
  772. 0, 0, 0, 0, // sequence number
  773. 0, // extra
  774. //0xff, 0xff, 0, 148 // ID 148 (low frequency bigendian)
  775. 0xff, 0xff, 0, 1, 148 // ID 148 (low frequency bigendian) zero encoded
  776. };
  777. public void SendRegionHandshake()
  778. {
  779. RegionInfo regionInfo = m_scene.RegionInfo;
  780. RegionSettings regionSettings = regionInfo.RegionSettings;
  781. EstateSettings es = regionInfo.EstateSettings;
  782. bool isEstateManager = m_scene.Permissions.IsEstateManager(m_agentId); // go by oficial path
  783. uint regionFlags = GetRegionFlags();
  784. UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
  785. Buffer.BlockCopy(RegionHandshakeHeader, 0, buf.Data, 0, 11);
  786. // inline zeroencode
  787. LLUDPZeroEncoder zc = new LLUDPZeroEncoder(buf.Data);
  788. zc.Position = 11;
  789. //RegionInfo Block
  790. //RegionFlags U32
  791. zc.AddUInt(regionFlags);
  792. //SimAccess U8
  793. zc.AddByte(regionInfo.AccessLevel);
  794. //SimName
  795. zc.AddShortString(regionInfo.RegionName, 255);
  796. //SimOwner
  797. zc.AddUUID(es.EstateOwner);
  798. //IsEstateManager
  799. zc.AddByte((byte)(isEstateManager ? 1 : 0));
  800. //WaterHeight
  801. zc.AddFloat((float)regionSettings.WaterHeight); // why is this a double ??
  802. //BillableFactor
  803. zc.AddFloat(es.BillableFactor);
  804. //CacheID
  805. zc.AddUUID(regionSettings.CacheID);
  806. //TerrainBase0
  807. //TerrainBase1
  808. //TerrainBase2
  809. //TerrainBase3
  810. // this seem not obsolete, sending zero uuids
  811. // we should send the basic low resolution default ?
  812. zc.AddZeros(16 * 4);
  813. //TerrainDetail0
  814. zc.AddUUID(regionSettings.TerrainTexture1);
  815. //TerrainDetail1
  816. zc.AddUUID(regionSettings.TerrainTexture2);
  817. //TerrainDetail2
  818. zc.AddUUID(regionSettings.TerrainTexture3);
  819. //TerrainDetail3
  820. zc.AddUUID(regionSettings.TerrainTexture4);
  821. //TerrainStartHeight00
  822. zc.AddFloat((float)regionSettings.Elevation1SW);
  823. //TerrainStartHeight01
  824. zc.AddFloat((float)regionSettings.Elevation1NW);
  825. //TerrainStartHeight10
  826. zc.AddFloat((float)regionSettings.Elevation1SE);
  827. //TerrainStartHeight11
  828. zc.AddFloat((float)regionSettings.Elevation1NE);
  829. //TerrainHeightRange00
  830. zc.AddFloat((float)regionSettings.Elevation2SW);
  831. //TerrainHeightRange01
  832. zc.AddFloat((float)regionSettings.Elevation2NW);
  833. //TerrainHeightRange10
  834. zc.AddFloat((float)regionSettings.Elevation2SE);
  835. //TerrainHeightRange11
  836. zc.AddFloat((float)regionSettings.Elevation2NE);
  837. //RegionInfo2 block
  838. //region ID
  839. zc.AddUUID(regionInfo.RegionID);
  840. //RegionInfo3 block
  841. //CPUClassID
  842. zc.AddInt(9);
  843. //CPURatio
  844. zc.AddInt(1);
  845. // ColoName (string)
  846. // ProductSKU (string)
  847. // both empty strings
  848. zc.AddZeros(2);
  849. //ProductName
  850. zc.AddShortString(regionInfo.RegionType, 255);
  851. //RegionInfo4 block
  852. //RegionFlagsExtended
  853. //zc.AddZeros(1); // if we dont have this else
  854. zc.AddByte(1);
  855. zc.AddUInt64(regionFlags); // we have nothing other base flags
  856. //RegionProtocols
  857. // bit 0 signals server side texture baking
  858. // bit 63 signals more than 6 baked textures support"
  859. zc.AddUInt64(1UL << 63);
  860. buf.DataLength = zc.Finish();
  861. m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Unknown);
  862. }
  863. static private readonly byte[] AgentMovementCompleteHeader = new byte[] {
  864. Helpers.MSG_RELIABLE,
  865. 0, 0, 0, 0, // sequence number
  866. 0, // extra
  867. 0xff, 0xff, 0, 250 // ID 250 (low frequency bigendian)
  868. };
  869. public unsafe void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look)
  870. {
  871. // reset agent update args
  872. m_thisAgentUpdateArgs.CameraAtAxis.X = float.MinValue;
  873. m_thisAgentUpdateArgs.lastUpdateTS = 0;
  874. m_thisAgentUpdateArgs.ControlFlags = 0;
  875. UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
  876. byte[] bdata = buf.Data;
  877. //setup header
  878. Buffer.BlockCopy(AgentMovementCompleteHeader, 0, bdata, 0, 10);
  879. fixed(byte* data = bdata)
  880. {
  881. //AgentData block
  882. m_agentId.ToBytes(data + 10); // 26
  883. m_sessionId.ToBytes(data + 26); // 42
  884. //Data block
  885. if ((pos.X == 0) && (pos.Y == 0) && (pos.Z == 0))
  886. m_startpos.ToBytes(data + 42); //54
  887. else
  888. pos.ToBytes(data + 42); //54
  889. look.ToBytes(data + 54); // 66
  890. //Utils.UInt64ToBytesSafepos(regInfo.RegionHandle, data + 66); // 74
  891. //Utils.UIntToBytesSafepos((uint)Util.UnixTimeSinceEpoch(), data + 74); //78
  892. Utils.UInt64ToBytes(regInfo.RegionHandle, data + 66); // 74
  893. Utils.IntToBytes((int)Util.UnixTimeSinceEpoch(), data + 74); //78
  894. //SimData
  895. int len = m_regionChannelVersion.Length;
  896. if(len == 0)
  897. {
  898. data[78] = 0;
  899. data[79] = 0;
  900. }
  901. else
  902. {
  903. data[78] = (byte)len;
  904. data[79] = (byte)(len >> 8);
  905. Buffer.BlockCopy(m_regionChannelVersion, 0, bdata, 80, len);
  906. }
  907. buf.DataLength = 80 + len;
  908. }
  909. m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Unknown);
  910. }
  911. static private readonly byte[] ChatFromSimulatorHeader = new byte[] {
  912. Helpers.MSG_RELIABLE,
  913. 0, 0, 0, 0, // sequence number
  914. 0, // extra
  915. 0xff, 0xff, 0, 139 // ID 139 (low frequency bigendian)
  916. };
  917. public void SendChatMessage(string message, byte chattype, Vector3 fromPos, string fromName,
  918. UUID sourceID, UUID ownerID, byte sourcetype, byte audible)
  919. {
  920. UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
  921. byte[] data = buf.Data;
  922. //setup header
  923. Buffer.BlockCopy(ChatFromSimulatorHeader, 0, data, 0, 10);
  924. int pos = 11;
  925. int len = Util.osUTF8Getbytes(fromName, data, 11, 255, true);
  926. data[10] = (byte)len;
  927. if (len > 0)
  928. pos += len;
  929. sourceID.ToBytes(data, pos); pos += 16;
  930. ownerID.ToBytes(data, pos); pos += 16;
  931. data[pos++] = sourcetype;
  932. data[pos++] = chattype;
  933. data[pos++] = audible;
  934. fromPos.ToBytes(data, pos); pos += 12;
  935. byte[] msg = Util.StringToBytes1024(message);
  936. len = msg.Length;
  937. if (len == 0)
  938. {
  939. data[pos++] = 0;
  940. data[pos++] = 0;
  941. }
  942. else
  943. {
  944. data[pos++] = (byte)len;
  945. data[pos++] = (byte)(len >> 8);
  946. Buffer.BlockCopy(msg, 0, data, pos, len); pos += len;
  947. }
  948. buf.DataLength = pos;
  949. m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Unknown);
  950. }
  951. /// <summary>
  952. /// Send an instant message to this client
  953. /// </summary>
  954. //
  955. static private readonly byte[] ImprovedInstantMessageHeader = new byte[] {
  956. Helpers.MSG_RELIABLE, //| Helpers.MSG_ZEROCODED, not doing spec zeroencode on this
  957. 0, 0, 0, 0, // sequence number
  958. 0, // extra
  959. 0xff, 0xff, 0, 254 // ID 139 (low frequency bigendian)
  960. };
  961. public void SendInstantMessage(GridInstantMessage im)
  962. {
  963. UUID fromAgentID = new UUID(im.fromAgentID);
  964. UUID toAgentID = new UUID(im.toAgentID);
  965. if (!m_scene.Permissions.CanInstantMessage(fromAgentID, toAgentID))
  966. return;
  967. UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
  968. byte[] data = buf.Data;
  969. //setup header
  970. Buffer.BlockCopy(ImprovedInstantMessageHeader, 0, data, 0, 10);
  971. //agentdata block
  972. fromAgentID.ToBytes(data, 10); // 26
  973. UUID.Zero.ToBytes(data, 26); // 42 sessionID zero?? TO check
  974. int pos = 42;
  975. //MessageBlock
  976. data[pos++] = (byte)((im.fromGroup) ? 1 : 0);
  977. toAgentID.ToBytes(data, pos); pos += 16;
  978. Utils.UIntToBytesSafepos(im.ParentEstateID, data, pos); pos += 4;
  979. (new UUID(im.RegionID)).ToBytes(data, pos); pos += 16;
  980. (im.Position).ToBytes(data, pos); pos += 12;
  981. data[pos++] = im.offline;
  982. data[pos++] = im.dialog;
  983. // this is odd
  984. if (im.imSessionID == UUID.Zero.Guid)
  985. (fromAgentID ^ toAgentID).ToBytes(data, pos);
  986. else
  987. (new UUID(im.imSessionID)).ToBytes(data, pos);
  988. pos += 16;
  989. Utils.UIntToBytesSafepos(im.timestamp, data, pos); pos += 4;
  990. int len = Util.osUTF8Getbytes(im.fromAgentName, data, pos + 1, 255, true);
  991. data[pos++] = (byte)len;
  992. if (len > 0)
  993. pos += len;
  994. len = Util.osUTF8Getbytes(im.message, data, pos + 2, 1024, true);
  995. if (len == 0)
  996. {
  997. data[pos++] = 0;
  998. data[pos++] = 0;
  999. }
  1000. else
  1001. {
  1002. data[pos++] = (byte)len;
  1003. data[pos++] = (byte)(len >> 8);
  1004. pos += len;
  1005. }
  1006. byte[] tmp = im.binaryBucket;
  1007. if(tmp == null)
  1008. {
  1009. data[pos++] = 0;
  1010. data[pos++] = 0;
  1011. }
  1012. else
  1013. {
  1014. len = tmp.Length;
  1015. if (len == 0)
  1016. {
  1017. data[pos++] = 0;
  1018. data[pos++] = 0;
  1019. }
  1020. else
  1021. {
  1022. data[pos++] = (byte)len;
  1023. data[pos++] = (byte)(len >> 8);
  1024. Buffer.BlockCopy(tmp, 0, data, pos, len); pos += len;
  1025. }
  1026. }
  1027. //EstateBlock does not seem in use TODO
  1028. //Utils.UIntToBytesSafepos(m_scene.RegionInfo.EstateSettings.EstateID, data, pos); pos += 4;
  1029. data[pos++] = 0;
  1030. data[pos++] = 0;
  1031. data[pos++] = 0;
  1032. data[pos++] = 0;
  1033. buf.DataLength = pos;
  1034. //m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Unknown, null, false, true);
  1035. m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Unknown);
  1036. }
  1037. static private readonly byte[] GenericMessageHeader = new byte[] {
  1038. Helpers.MSG_RELIABLE, //| Helpers.MSG_ZEROCODED, not doing spec zeroencode on this
  1039. 0, 0, 0, 0, // sequence number
  1040. 0, // extra
  1041. 0xff, 0xff, 1, 5 // ID 261 (low frequency bigendian)
  1042. };
  1043. public void SendGenericMessage(string method, UUID invoice, List<string> message)
  1044. {
  1045. UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
  1046. byte[] data = buf.Data;
  1047. //setup header
  1048. Buffer.BlockCopy(GenericMessageHeader, 0, data, 0, 10);
  1049. //agentdata block
  1050. m_agentId.ToBytes(data, 10); // 26
  1051. m_sessionId.ToBytes(data, 26); // 42 sessionID zero?? TO check
  1052. UUID.Zero.ToBytes(data, 42); // 58
  1053. int pos = 58;
  1054. //method block
  1055. int len = Util.osUTF8Getbytes(method, data, pos + 1, 255, true);
  1056. data[pos++] = (byte)len;
  1057. if (len > 0)
  1058. pos += len;
  1059. invoice.ToBytes(data, pos); pos += 16;
  1060. //ParamList block
  1061. if (message.Count == 0)
  1062. {
  1063. data[pos++] = 0;
  1064. buf.DataLength = pos;
  1065. //m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task, null, false, true);
  1066. m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task);
  1067. return;
  1068. }
  1069. int countpos = pos;
  1070. ++pos;
  1071. int count = 0;
  1072. for(int indx = 0; indx < message.Count; ++indx)
  1073. {
  1074. len = Util.osUTF8Getbytes(message[indx], data, pos + 1, 255, true);
  1075. data[pos++] = (byte)len;
  1076. if (len > 0)
  1077. pos += len;
  1078. if (pos > LLUDPServer.MAXPAYLOAD - 100)
  1079. {
  1080. data[countpos] = (byte)count;
  1081. buf.DataLength = pos;
  1082. //m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task, null, false, true);
  1083. m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task);
  1084. UDPPacketBuffer newbuf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
  1085. Buffer.BlockCopy(data, 0, newbuf.Data, 0, countpos);
  1086. buf = newbuf;
  1087. data = buf.Data;
  1088. pos = countpos + 1;
  1089. count = 1;
  1090. }
  1091. else
  1092. ++count;
  1093. }
  1094. if (count > 0)
  1095. {
  1096. data[countpos] = (byte)count;
  1097. buf.DataLength = pos;
  1098. //m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task, null, false, true);
  1099. m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task);
  1100. }
  1101. }
  1102. public void SendGenericMessage(string method, UUID invoice, List<byte[]> message)
  1103. {
  1104. UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
  1105. byte[] data = buf.Data;
  1106. //setup header
  1107. Buffer.BlockCopy(GenericMessageHeader, 0, data, 0, 10);
  1108. //agentdata block
  1109. m_agentId.ToBytes(data, 10); // 26
  1110. m_sessionId.ToBytes(data, 26); // 42 sessionID zero?? TO check
  1111. UUID.Zero.ToBytes(data, 42); // 58
  1112. int pos = 58;
  1113. //method block
  1114. int len = Util.osUTF8Getbytes(method, data, pos + 1, 255, true);
  1115. data[pos++] = (byte)len;
  1116. if (len > 0)
  1117. pos += len;
  1118. invoice.ToBytes(data, pos); pos += 16;
  1119. //ParamList block
  1120. if (message.Count == 0)
  1121. {
  1122. data[pos++] = 0;
  1123. buf.DataLength = pos;
  1124. //m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task, null, false, true);
  1125. m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task);
  1126. return;
  1127. }
  1128. int countpos = pos;
  1129. ++pos;
  1130. byte[] val;
  1131. int count = 0;
  1132. for (int indx = 0; indx < message.Count; ++indx)
  1133. {
  1134. val = message[indx];
  1135. len = val.Length;
  1136. if(len > 255)
  1137. len = 255;
  1138. if (pos + len >= LLUDPServer.MAXPAYLOAD)
  1139. {
  1140. data[countpos] = (byte)count;
  1141. buf.DataLength = pos;
  1142. //m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task, null, false, true);
  1143. m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task);
  1144. UDPPacketBuffer newbuf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
  1145. Buffer.BlockCopy(data, 0, newbuf.Data, 0, countpos);
  1146. buf = newbuf;
  1147. data = buf.Data;
  1148. pos = countpos + 1;
  1149. count = 1;
  1150. }
  1151. else
  1152. ++count;
  1153. data[pos++] = (byte)len;
  1154. if (len > 0)
  1155. Buffer.BlockCopy(val, 0, data, pos, len); pos += len;
  1156. }
  1157. if (count > 0)
  1158. {
  1159. data[countpos] = (byte)count;
  1160. buf.DataLength = pos;
  1161. //m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task, null, false, true);
  1162. m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task);
  1163. }
  1164. }
  1165. public void SendGroupActiveProposals(UUID groupID, UUID transactionID, GroupActiveProposals[] Proposals)
  1166. {
  1167. int i = 0;
  1168. foreach (GroupActiveProposals Proposal in Proposals)
  1169. {
  1170. GroupActiveProposalItemReplyPacket GAPIRP = new GroupActiveProposalItemReplyPacket();
  1171. GAPIRP.AgentData.AgentID = m_agentId;
  1172. GAPIRP.AgentData.GroupID = groupID;
  1173. GAPIRP.TransactionData.TransactionID = transactionID;
  1174. GAPIRP.TransactionData.TotalNumItems = ((uint)i+1);
  1175. GroupActiveProposalItemReplyPacket.ProposalDataBlock ProposalData = new GroupActiveProposalItemReplyPacket.ProposalDataBlock();
  1176. GAPIRP.ProposalData = new GroupActiveProposalItemReplyPacket.ProposalDataBlock[1];
  1177. ProposalData.VoteCast = Utils.StringToBytes("false");
  1178. ProposalData.VoteID = new UUID(Proposal.VoteID);
  1179. ProposalData.VoteInitiator = new UUID(Proposal.VoteInitiator);
  1180. ProposalData.Majority = (float)Convert.ToInt32(Proposal.Majority);
  1181. ProposalData.Quorum = Convert.ToInt32(Proposal.Quorum);
  1182. ProposalData.TerseDateID = Utils.StringToBytes(Proposal.TerseDateID);
  1183. ProposalData.StartDateTime = Utils.StringToBytes(Proposal.StartDateTime);
  1184. ProposalData.EndDateTime = Utils.StringToBytes(Proposal.EndDateTime);
  1185. ProposalData.ProposalText = Utils.StringToBytes(Proposal.ProposalText);
  1186. ProposalData.AlreadyVoted = false;
  1187. GAPIRP.ProposalData[i] = ProposalData;
  1188. OutPacket(GAPIRP, ThrottleOutPacketType.Task);
  1189. i++;
  1190. }
  1191. if (Proposals.Length == 0)
  1192. {
  1193. GroupActiveProposalItemReplyPacket GAPIRP = new GroupActiveProposalItemReplyPacket();
  1194. GAPIRP.AgentData.AgentID = m_agentId;
  1195. GAPIRP.AgentData.GroupID = groupID;
  1196. GAPIRP.TransactionData.TransactionID = transactionID;
  1197. GAPIRP.TransactionData.TotalNumItems = 1;
  1198. GroupActiveProposalItemReplyPacket.ProposalDataBlock ProposalData = new GroupActiveProposalItemReplyPacket.ProposalDataBlock();
  1199. GAPIRP.ProposalData = new GroupActiveProposalItemReplyPacket.ProposalDataBlock[1];
  1200. ProposalData.VoteCast = Utils.StringToBytes("false");
  1201. ProposalData.VoteID = UUID.Zero;
  1202. ProposalData.VoteInitiator = UUID.Zero;
  1203. ProposalData.Majority = 0;
  1204. ProposalData.Quorum = 0;
  1205. ProposalData.TerseDateID = Utils.StringToBytes("");
  1206. ProposalData.StartDateTime = Utils.StringToBytes("");
  1207. ProposalData.EndDateTime = Utils.StringToBytes("");
  1208. ProposalData.ProposalText = Utils.StringToBytes("");
  1209. ProposalData.AlreadyVoted = false;
  1210. GAPIRP.ProposalData[0] = ProposalData;
  1211. OutPacket(GAPIRP, ThrottleOutPacketType.Task);
  1212. }
  1213. }
  1214. public void SendGroupVoteHistory(UUID groupID, UUID transactionID, GroupVoteHistory[] Votes)
  1215. {
  1216. int i = 0;
  1217. foreach (GroupVoteHistory Vote in Votes)
  1218. {
  1219. GroupVoteHistoryItemReplyPacket GVHIRP = new GroupVoteHistoryItemReplyPacket();
  1220. GVHIRP.AgentData.AgentID = m_agentId;
  1221. GVHIRP.AgentData.GroupID = groupID;
  1222. GVHIRP.TransactionData.TransactionID = transactionID;
  1223. GVHIRP.TransactionData.TotalNumItems = ((uint)i+1);
  1224. GVHIRP.HistoryItemData.VoteID = new UUID(Vote.VoteID);
  1225. GVHIRP.HistoryItemData.VoteInitiator = new UUID(Vote.VoteInitiator);
  1226. GVHIRP.HistoryItemData.Majority = (float)Convert.ToInt32(Vote.Majority);
  1227. GVHIRP.HistoryItemData.Quorum = Convert.ToInt32(Vote.Quorum);
  1228. GVHIRP.HistoryItemData.TerseDateID = Utils.StringToBytes(Vote.TerseDateID);
  1229. GVHIRP.HistoryItemData.StartDateTime = Utils.StringToBytes(Vote.StartDateTime);
  1230. GVHIRP.HistoryItemData.EndDateTime = Utils.StringToBytes(Vote.EndDateTime);
  1231. GVHIRP.HistoryItemData.VoteType = Utils.StringToBytes(Vote.VoteType);
  1232. GVHIRP.HistoryItemData.VoteResult = Utils.StringToBytes(Vote.VoteResult);
  1233. GVHIRP.HistoryItemData.ProposalText = Utils.StringToBytes(Vote.ProposalText);
  1234. GroupVoteHistoryItemReplyPacket.VoteItemBlock VoteItem = new GroupVoteHistoryItemReplyPacket.VoteItemBlock();
  1235. GVHIRP.VoteItem = new GroupVoteHistoryItemReplyPacket.VoteItemBlock[1];
  1236. VoteItem.CandidateID = UUID.Zero;
  1237. VoteItem.NumVotes = 0; //TODO: FIX THIS!!!
  1238. VoteItem.VoteCast = Utils.StringToBytes("Yes");
  1239. GVHIRP.VoteItem[i] = VoteItem;
  1240. OutPacket(GVHIRP, ThrottleOutPacketType.Task);
  1241. i++;
  1242. }
  1243. if (Votes.Length == 0)
  1244. {
  1245. GroupVoteHistoryItemReplyPacket GVHIRP = new GroupVoteHistoryItemReplyPacket();
  1246. GVHIRP.AgentData.AgentID = m_agentId;
  1247. GVHIRP.AgentData.GroupID = groupID;
  1248. GVHIRP.TransactionData.TransactionID = transactionID;
  1249. GVHIRP.TransactionData.TotalNumItems = 0;
  1250. GVHIRP.HistoryItemData.VoteID = UUID.Zero;
  1251. GVHIRP.HistoryItemData.VoteInitiator = UUID.Zero;
  1252. GVHIRP.HistoryItemData.Majority = 0;
  1253. GVHIRP.HistoryItemData.Quorum = 0;
  1254. GVHIRP.HistoryItemData.TerseDateID = Utils.StringToBytes("");
  1255. GVHIRP.HistoryItemData.StartDateTime = Utils.StringToBytes("");
  1256. GVHIRP.HistoryItemData.EndDateTime = Utils.StringToBytes("");
  1257. GVHIRP.HistoryItemData.VoteType = Utils.StringToBytes("");
  1258. GVHIRP.HistoryItemData.VoteResult = Utils.StringToBytes("");
  1259. GVHIRP.HistoryItemData.ProposalText = Utils.StringToBytes("");
  1260. GroupVoteHistoryItemReplyPacket.VoteItemBlock VoteItem = new GroupVoteHistoryItemReplyPacket.VoteItemBlock();
  1261. GVHIRP.VoteItem = new GroupVoteHistoryItemReplyPacket.VoteItemBlock[1];
  1262. VoteItem.CandidateID = UUID.Zero;
  1263. VoteItem.NumVotes = 0; //TODO: FIX THIS!!!
  1264. VoteItem.VoteCast = Utils.StringToBytes("No");
  1265. GVHIRP.VoteItem[0] = VoteItem;
  1266. OutPacket(GVHIRP, ThrottleOutPacketType.Task);
  1267. }
  1268. }
  1269. public void SendGroupAccountingDetails(IClientAPI sender,UUID groupID, UUID transactionID, UUID sessionID, int amt)
  1270. {
  1271. GroupAccountDetailsReplyPacket GADRP = new GroupAccountDetailsReplyPacket();
  1272. GADRP.AgentData = new GroupAccountDetailsReplyPacket.AgentDataBlock();
  1273. GADRP.AgentData.AgentID = sender.AgentId;
  1274. GADRP.AgentData.GroupID = groupID;
  1275. GADRP.HistoryData = new GroupAccountDetailsReplyPacket.HistoryDataBlock[1];
  1276. GroupAccountDetailsReplyPacket.HistoryDataBlock History = new GroupAccountDetailsReplyPacket.HistoryDataBlock();
  1277. GADRP.MoneyData = new GroupAccountDetailsReplyPacket.MoneyDataBlock();
  1278. GADRP.MoneyData.CurrentInterval = 0;
  1279. GADRP.MoneyData.IntervalDays = 7;
  1280. GADRP.MoneyData.RequestID = transactionID;
  1281. GADRP.MoneyData.StartDate = Utils.StringToBytes(DateTime.Today.ToString());
  1282. History.Amount = amt;
  1283. History.Description = Utils.StringToBytes("");
  1284. GADRP.HistoryData[0] = History;
  1285. OutPacket(GADRP, ThrottleOutPacketType.Task);
  1286. }
  1287. public void SendGroupAccountingSummary(IClientAPI sender,UUID groupID, uint moneyAmt, int totalTier, int usedTier)
  1288. {
  1289. GroupAccountSummaryReplyPacket GASRP =
  1290. (GroupAccountSummaryReplyPacket)PacketPool.Instance.GetPacket(
  1291. PacketType.GroupAccountSummaryReply);
  1292. GASRP.AgentData = new GroupAccountSummaryReplyPacket.AgentDataBlock();
  1293. GASRP.AgentData.AgentID = sender.AgentId;
  1294. GASRP.AgentData.GroupID = groupID;
  1295. GASRP.MoneyData = new GroupAccountSummaryReplyPacket.MoneyDataBlock();
  1296. GASRP.MoneyData.Balance = (int)moneyAmt;
  1297. GASRP.MoneyData.TotalCredits = totalTier;
  1298. GASRP.MoneyData.TotalDebits = usedTier;
  1299. GASRP.MoneyData.StartDate = new byte[1];
  1300. GASRP.MoneyData.CurrentInterval = 1;
  1301. GASRP.MoneyData.GroupTaxCurrent = 0;
  1302. GASRP.MoneyData.GroupTaxEstimate = 0;
  1303. GASRP.MoneyData.IntervalDays = 0;
  1304. GASRP.MoneyData.LandTaxCurrent = 0;
  1305. GASRP.MoneyData.LandTaxEstimate = 0;
  1306. GASRP.MoneyData.LastTaxDate = new byte[1];
  1307. GASRP.MoneyData.LightTaxCurrent = 0;
  1308. GASRP.MoneyData.TaxDate = new byte[1];
  1309. GASRP.MoneyData.RequestID = sender.AgentId;
  1310. GASRP.MoneyData.ParcelDirFeeEstimate = 0;
  1311. GASRP.MoneyData.ParcelDirFeeCurrent = 0;
  1312. GASRP.MoneyData.ObjectTaxEstimate = 0;
  1313. GASRP.MoneyData.NonExemptMembers = 0;
  1314. GASRP.MoneyData.ObjectTaxCurrent = 0;
  1315. GASRP.MoneyData.LightTaxEstimate = 0;
  1316. OutPacket(GASRP, ThrottleOutPacketType.Task);
  1317. }
  1318. public void SendGroupTransactionsSummaryDetails(IClientAPI sender,UUID groupID, UUID transactionID, UUID sessionID, int amt)
  1319. {
  1320. GroupAccountTransactionsReplyPacket GATRP =
  1321. (GroupAccountTransactionsReplyPacket)PacketPool.Instance.GetPacket(
  1322. PacketType.GroupAccountTransactionsReply);
  1323. GATRP.AgentData = new GroupAccountTransactionsReplyPacket.AgentDataBlock();
  1324. GATRP.AgentData.AgentID = sender.AgentId;
  1325. GATRP.AgentData.GroupID = groupID;
  1326. GATRP.MoneyData = new GroupAccountTransactionsReplyPacket.MoneyDataBlock();
  1327. GATRP.MoneyData.CurrentInterval = 0;
  1328. GATRP.MoneyData.IntervalDays = 7;
  1329. GATRP.MoneyData.RequestID = transactionID;
  1330. GATRP.MoneyData.StartDate = Utils.StringToBytes(DateTime.Today.ToString());
  1331. GATRP.HistoryData = new GroupAccountTransactionsReplyPacket.HistoryDataBlock[1];
  1332. GroupAccountTransactionsReplyPacket.HistoryDataBlock History = new GroupAccountTransactionsReplyPacket.HistoryDataBlock();
  1333. History.Amount = 0;
  1334. History.Item = Utils.StringToBytes("");
  1335. History.Time = Utils.StringToBytes("");
  1336. History.Type = 0;
  1337. History.User = Utils.StringToBytes("");
  1338. GATRP.HistoryData[0] = History;
  1339. OutPacket(GATRP, ThrottleOutPacketType.Task);
  1340. }
  1341. public virtual bool CanSendLayerData()
  1342. {
  1343. int n = m_udpClient.GetPacketsQueuedCount(ThrottleOutPacketType.Land);
  1344. if ( n > 128)
  1345. return false;
  1346. return true;
  1347. }
  1348. /// <summary>
  1349. /// Send the region heightmap to the client
  1350. /// This method is only called when not doing intellegent terrain patch sending and
  1351. /// is only called when the scene presence is initially created and sends all of the
  1352. /// region's patches to the client.
  1353. /// </summary>
  1354. /// <param name="map">heightmap</param>
  1355. public virtual void SendLayerData()
  1356. {
  1357. Util.FireAndForget(DoSendLayerData, null, "LLClientView.DoSendLayerData");
  1358. }
  1359. /// <summary>
  1360. /// Send terrain layer information to the client.
  1361. /// </summary>
  1362. /// <param name="o"></param>
  1363. private void DoSendLayerData(object o)
  1364. {
  1365. TerrainData map = m_scene.Heightmap.GetTerrainData();
  1366. try
  1367. {
  1368. // Send LayerData in a spiral pattern. Fun!
  1369. SendLayerTopRight(0, 0, map.SizeX / Constants.TerrainPatchSize - 1, map.SizeY / Constants.TerrainPatchSize - 1);
  1370. }
  1371. catch (Exception e)
  1372. {
  1373. m_log.Error("[CLIENT]: SendLayerData() Failed with exception: " + e.Message, e);
  1374. }
  1375. }
  1376. private void SendLayerTopRight(int x1, int y1, int x2, int y2)
  1377. {
  1378. int[] p = new int[2];
  1379. // Row
  1380. p[1] = y1;
  1381. for (int i = x1; i <= x2; ++i)
  1382. {
  1383. p[0] = i;
  1384. SendLayerData(p);
  1385. }
  1386. // Column
  1387. p[0] = x2;
  1388. for (int j = y1 + 1; j <= y2; ++j)
  1389. {
  1390. p[1] = j;
  1391. SendLayerData(p);
  1392. }
  1393. if (x2 - x1 > 0 && y2 - y1 > 0)
  1394. SendLayerBottomLeft(x1, y1 + 1, x2 - 1, y2);
  1395. }
  1396. void SendLayerBottomLeft(int x1, int y1, int x2, int y2)
  1397. {
  1398. int[] p = new int[2];
  1399. // Row in reverse
  1400. p[1] = y2;
  1401. for (int i = x2; i >= x1; --i)
  1402. {
  1403. p[0] = i;
  1404. SendLayerData(p);
  1405. }
  1406. // Column in reverse
  1407. p[0] = x1;
  1408. for (int j = y2 - 1; j >= y1; --j)
  1409. {
  1410. p[1] = j;
  1411. SendLayerData(p);
  1412. }
  1413. if (x2 - x1 > 0 && y2 - y1 > 0)
  1414. SendLayerTopRight(x1 + 1, y1, x2, y2 - 1);
  1415. }
  1416. static private readonly byte[] TerrainPacketHeader = new byte[] {
  1417. Helpers.MSG_RELIABLE, // zero code is not as spec
  1418. 0, 0, 0, 0, // sequence number
  1419. 0, // extra
  1420. 11, // ID (high frequency)
  1421. };
  1422. private const int END_OF_PATCHES = 97;
  1423. private const int STRIDE = 264;
  1424. public void SendLayerData(int[] map)
  1425. {
  1426. if(map == null)
  1427. return;
  1428. try
  1429. {
  1430. TerrainData terrData = m_scene.Heightmap.GetTerrainData();
  1431. byte landPacketType = (terrData.SizeX > Constants.RegionSize || terrData.SizeY > Constants.RegionSize) ?
  1432. (byte)TerrainPatch.LayerType.LandExtended : (byte)TerrainPatch.LayerType.Land;
  1433. int numberPatchs = map.Length / 2;
  1434. UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
  1435. byte[] data = buf.Data;
  1436. Buffer.BlockCopy(TerrainPacketHeader, 0, data, 0, 7);
  1437. data[7] = landPacketType;
  1438. //data[8] and data[9] == datablock size to fill later
  1439. data[10] = 0; // BitPack needs this on reused packets
  1440. // start data
  1441. BitPack bitpack = new BitPack(data, 10);
  1442. bitpack.PackBits(STRIDE, 16);
  1443. bitpack.PackBitsFromByte(16);
  1444. bitpack.PackBitsFromByte(landPacketType);
  1445. int s;
  1446. int datasize = 0;
  1447. for (int i = 0; i < numberPatchs; i++)
  1448. {
  1449. s = 2 * i;
  1450. OpenSimTerrainCompressor.CreatePatchFromTerrainData(bitpack, terrData, map[s], map[s + 1]);
  1451. if (bitpack.BytePos > 900 && i != numberPatchs - 1)
  1452. {
  1453. //finish this packet
  1454. bitpack.PackBitsFromByte(END_OF_PATCHES);
  1455. // fix the datablock length
  1456. datasize = bitpack.BytePos - 9;
  1457. data[8] = (byte)datasize;
  1458. data[9] = (byte)(datasize >> 8);
  1459. buf.DataLength = bitpack.BytePos + 1;
  1460. m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Land);
  1461. // start another
  1462. buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
  1463. data = buf.Data;
  1464. Buffer.BlockCopy(TerrainPacketHeader, 0, data, 0, 7);
  1465. data[7] = landPacketType;
  1466. //data[8] and data[9] == datablock size to fill later
  1467. data[10] = 0; // BitPack needs this
  1468. // start data
  1469. bitpack = new BitPack(data, 10);
  1470. bitpack.PackBits(STRIDE, 16);
  1471. bitpack.PackBitsFromByte(16);
  1472. bitpack.PackBitsFromByte(landPacketType);
  1473. }
  1474. }
  1475. bitpack.PackBitsFromByte(END_OF_PATCHES);
  1476. datasize = bitpack.BytePos - 9;
  1477. data[8] = (byte)datasize;
  1478. data[9] = (byte)(datasize >> 8);
  1479. buf.DataLength = bitpack.BytePos + 1;
  1480. m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Land);
  1481. }
  1482. catch (Exception e)
  1483. {
  1484. m_log.Error("[CLIENT]: SendLayerData() Failed with exception: " + e.Message, e);
  1485. }
  1486. }
  1487. private void DebugSendingPatches(string pWho, int[] pX, int[] pY)
  1488. {
  1489. if (m_log.IsDebugEnabled)
  1490. {
  1491. int numPatches = pX.Length;
  1492. string Xs = "";
  1493. string Ys = "";
  1494. for (int pp = 0; pp < numPatches; pp++)
  1495. {
  1496. Xs += String.Format("{0}", (int)pX[pp]) + ",";
  1497. Ys += String.Format("{0}", (int)pY[pp]) + ",";
  1498. }
  1499. m_log.DebugFormat("{0} {1}: numPatches={2}, X={3}, Y={4}", LogHeader, pWho, numPatches, Xs, Ys);
  1500. }
  1501. }
  1502. // wind caching
  1503. private static Dictionary<ulong,int> lastWindVersion = new Dictionary<ulong,int>();
  1504. private static Dictionary<ulong,List<LayerDataPacket>> lastWindPackets =
  1505. new Dictionary<ulong,List<LayerDataPacket>>();
  1506. /// <summary>
  1507. /// Send the wind matrix to the client
  1508. /// </summary>
  1509. /// <param name="windSpeeds">16x16 array of wind speeds</param>
  1510. public virtual void SendWindData(int version, Vector2[] windSpeeds)
  1511. {
  1512. // Vector2[] windSpeeds = (Vector2[])o;
  1513. ulong handle = this.Scene.RegionInfo.RegionHandle;
  1514. bool isNewData;
  1515. lock(lastWindPackets)
  1516. {
  1517. if(!lastWindVersion.ContainsKey(handle) ||
  1518. !lastWindPackets.ContainsKey(handle))
  1519. {
  1520. lastWindVersion[handle] = 0;
  1521. lastWindPackets[handle] = new List<LayerDataPacket>();
  1522. isNewData = true;
  1523. }
  1524. else
  1525. isNewData = lastWindVersion[handle] != version;
  1526. }
  1527. if(isNewData)
  1528. {
  1529. TerrainPatch[] patches = new TerrainPatch[2];
  1530. patches[0] = new TerrainPatch { Data = new float[16 * 16] };
  1531. patches[1] = new TerrainPatch { Data = new float[16 * 16] };
  1532. for (int x = 0; x < 16 * 16; x++)
  1533. {
  1534. patches[0].Data[x] = windSpeeds[x].X;
  1535. patches[1].Data[x] = windSpeeds[x].Y;
  1536. }
  1537. // neither we or viewers have extended wind
  1538. byte layerType = (byte)TerrainPatch.LayerType.Wind;
  1539. LayerDataPacket layerpack =
  1540. OpenSimTerrainCompressor.CreateLayerDataPacketStandardSize(
  1541. patches, layerType);
  1542. layerpack.Header.Zerocoded = true;
  1543. lock(lastWindPackets)
  1544. {
  1545. lastWindPackets[handle].Clear();
  1546. lastWindPackets[handle].Add(layerpack);
  1547. lastWindVersion[handle] = version;
  1548. }
  1549. }
  1550. lock(lastWindPackets)
  1551. foreach(LayerDataPacket pkt in lastWindPackets[handle])
  1552. OutPacket(pkt, ThrottleOutPacketType.Wind);
  1553. }
  1554. /// <summary>
  1555. /// Tell the client that the given neighbour region is ready to receive a child agent.
  1556. /// </summary>
  1557. public virtual void InformClientOfNeighbour(ulong neighbourHandle, IPEndPoint neighbourEndPoint)
  1558. {
  1559. IPAddress neighbourIP = neighbourEndPoint.Address;
  1560. ushort neighbourPort = (ushort)neighbourEndPoint.Port;
  1561. EnableSimulatorPacket enablesimpacket = (EnableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.EnableSimulator);
  1562. // TODO: don't create new blocks if recycling an old packet
  1563. enablesimpacket.SimulatorInfo = new EnableSimulatorPacket.SimulatorInfoBlock();
  1564. enablesimpacket.SimulatorInfo.Handle = neighbourHandle;
  1565. byte[] byteIP = neighbourIP.GetAddressBytes();
  1566. enablesimpacket.SimulatorInfo.IP = (uint)byteIP[3] << 24;
  1567. enablesimpacket.SimulatorInfo.IP += (uint)byteIP[2] << 16;
  1568. enablesimpacket.SimulatorInfo.IP += (uint)byteIP[1] << 8;
  1569. enablesimpacket.SimulatorInfo.IP += (uint)byteIP[0];
  1570. enablesimpacket.SimulatorInfo.Port = neighbourPort;
  1571. enablesimpacket.Header.Reliable = true; // ESP's should be reliable.
  1572. OutPacket(enablesimpacket, ThrottleOutPacketType.Task);
  1573. }
  1574. public AgentCircuitData RequestClientInfo()
  1575. {
  1576. AgentCircuitData agentData = new AgentCircuitData();
  1577. agentData.AgentID = m_agentId;
  1578. agentData.SessionID = m_sessionId;
  1579. agentData.SecureSessionID = SecureSessionId;
  1580. agentData.circuitcode = m_circuitCode;
  1581. agentData.child = false;
  1582. agentData.firstname = m_firstName;
  1583. agentData.lastname = m_lastName;
  1584. ICapabilitiesModule capsModule = m_scene.RequestModuleInterface<ICapabilitiesModule>();
  1585. if (capsModule == null) // can happen when shutting down.
  1586. return agentData;
  1587. agentData.CapsPath = capsModule.GetCapsPath(m_agentId);
  1588. agentData.ChildrenCapSeeds = new Dictionary<ulong, string>(capsModule.GetChildrenSeeds(m_agentId));
  1589. return agentData;
  1590. }
  1591. public virtual void CrossRegion(ulong newRegionHandle, Vector3 pos, Vector3 lookAt, IPEndPoint externalIPEndPoint,
  1592. string capsURL)
  1593. {
  1594. Vector3 look = new Vector3(lookAt.X * 10, lookAt.Y * 10, lookAt.Z * 10);
  1595. //CrossedRegionPacket newSimPack = (CrossedRegionPacket)PacketPool.Instance.GetPacket(PacketType.CrossedRegion);
  1596. CrossedRegionPacket newSimPack = new CrossedRegionPacket();
  1597. // TODO: don't create new blocks if recycling an old packet
  1598. newSimPack.AgentData = new CrossedRegionPacket.AgentDataBlock();
  1599. newSimPack.AgentData.AgentID = m_agentId;
  1600. newSimPack.AgentData.SessionID = m_sessionId;
  1601. newSimPack.Info = new CrossedRegionPacket.InfoBlock();
  1602. newSimPack.Info.Position = pos;
  1603. newSimPack.Info.LookAt = look;
  1604. newSimPack.RegionData = new CrossedRegionPacket.RegionDataBlock();
  1605. newSimPack.RegionData.RegionHandle = newRegionHandle;
  1606. byte[] byteIP = externalIPEndPoint.Address.GetAddressBytes();
  1607. newSimPack.RegionData.SimIP = (uint)byteIP[3] << 24;
  1608. newSimPack.RegionData.SimIP += (uint)byteIP[2] << 16;
  1609. newSimPack.RegionData.SimIP += (uint)byteIP[1] << 8;
  1610. newSimPack.RegionData.SimIP += (uint)byteIP[0];
  1611. newSimPack.RegionData.SimPort = (ushort)externalIPEndPoint.Port;
  1612. newSimPack.RegionData.SeedCapability = Util.StringToBytes256(capsURL);
  1613. // Hack to get this out immediately and skip throttles
  1614. OutPacket(newSimPack, ThrottleOutPacketType.Unknown);
  1615. }
  1616. static private readonly byte[] MapBlockItemHeader = new byte[] {
  1617. Helpers.MSG_RELIABLE,
  1618. 0, 0, 0, 0, // sequence number
  1619. 0, // extra
  1620. 0xff, 0xff, 1, 155 // ID 411 (low frequency bigendian)
  1621. };
  1622. public void SendMapItemReply(mapItemReply[] replies, uint mapitemtype, uint flags)
  1623. {
  1624. UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
  1625. byte[] data = buf.Data;
  1626. //setup header and agentinfo block
  1627. Buffer.BlockCopy(MapBlockItemHeader, 0, data, 0, 10);
  1628. m_agentId.ToBytes(data, 10); // 26
  1629. Utils.UIntToBytesSafepos(flags, data, 26); // 30
  1630. //RequestData block
  1631. Utils.UIntToBytesSafepos(mapitemtype, data, 30); // 34
  1632. int countpos = 34;
  1633. int pos = 35;
  1634. int lastpos = 0;
  1635. int capacity = LLUDPServer.MAXPAYLOAD - pos;
  1636. int count = 0;
  1637. mapItemReply mr;
  1638. for (int k = 0; k < replies.Length; ++k)
  1639. {
  1640. lastpos = pos;
  1641. mr = replies[k];
  1642. Utils.UIntToBytesSafepos(mr.x, data, pos); pos += 4;
  1643. Utils.UIntToBytesSafepos(mr.y, data, pos); pos += 4;
  1644. mr.id.ToBytes(data, pos); pos += 16;
  1645. Utils.IntToBytesSafepos(mr.Extra, data, pos); pos += 4;
  1646. Utils.IntToBytesSafepos(mr.Extra2, data, pos); pos += 4;
  1647. int len = Util.osUTF8Getbytes(mr.name, data, pos + 1, 255, true);
  1648. data[pos++] = (byte)len;
  1649. if (len > 0)
  1650. pos += len;
  1651. if (pos < capacity)
  1652. ++count;
  1653. else
  1654. {
  1655. // prepare next packet
  1656. UDPPacketBuffer newbuf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
  1657. Buffer.BlockCopy(data, 0, newbuf.Data, 0, 34);
  1658. // copy the block we already did
  1659. int alreadyDone = pos - lastpos;
  1660. Buffer.BlockCopy(data, lastpos, newbuf.Data, 35, alreadyDone); // 34 is datablock size
  1661. // finish current
  1662. data[countpos] = (byte)count;
  1663. buf.DataLength = lastpos;
  1664. // send it
  1665. m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Land);
  1666. buf = newbuf;
  1667. data = buf.Data;
  1668. pos = alreadyDone + 35;
  1669. capacity = LLUDPServer.MAXPAYLOAD - pos;
  1670. count = 1;
  1671. }
  1672. }
  1673. if (count > 0)
  1674. {
  1675. data[countpos] = (byte)count;
  1676. buf.DataLength = pos;
  1677. m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Land);
  1678. }
  1679. }
  1680. static private readonly byte[] MapBlockReplyHeader = new byte[] {
  1681. Helpers.MSG_RELIABLE,
  1682. 0, 0, 0, 0, // sequence number
  1683. 0, // extra
  1684. 0xff, 0xff, 1, 153 // ID 409 (low frequency bigendian)
  1685. };
  1686. public void SendMapBlock(List<MapBlockData> mapBlocks, uint flags)
  1687. {
  1688. ushort[] sizes = new ushort[2 * mapBlocks.Count];
  1689. bool needSizes = false;
  1690. int sizesptr = 0;
  1691. // check if we will need sizes block and get them aside
  1692. int count = 0;
  1693. ushort ut;
  1694. MapBlockData md;
  1695. for (int indx = 0; indx < mapBlocks.Count; ++indx)
  1696. {
  1697. md = mapBlocks[indx];
  1698. ut = md.SizeX;
  1699. sizes[count++] = ut;
  1700. if (ut > 256)
  1701. needSizes = true;
  1702. ut = md.SizeY;
  1703. sizes[count++] = ut;
  1704. if (ut > 256)
  1705. needSizes = true;
  1706. }
  1707. UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
  1708. byte[] data = buf.Data;
  1709. //setup header and agentinfo block
  1710. Buffer.BlockCopy(MapBlockReplyHeader, 0, data, 0, 10);
  1711. m_agentId.ToBytes(data, 10); // 26
  1712. Utils.UIntToBytesSafepos(flags, data, 26); // 30
  1713. int countpos = 30;
  1714. int pos = 31;
  1715. int lastpos = 0;
  1716. int capacity = LLUDPServer.MAXPAYLOAD - pos;
  1717. count = 0;
  1718. for (int indx = 0; indx < mapBlocks.Count; ++indx)
  1719. {
  1720. md = mapBlocks[indx];
  1721. lastpos = pos;
  1722. Utils.UInt16ToBytes(md.X, data, pos); pos += 2;
  1723. Utils.UInt16ToBytes(md.Y, data, pos); pos += 2;
  1724. int len = Util.osUTF8Getbytes(md.Name, data, pos + 1, 255, true);
  1725. data[pos++] = (byte)len;
  1726. if (len > 0)
  1727. pos += len;
  1728. data[pos++] = md.Access;
  1729. Utils.UIntToBytesSafepos(md.RegionFlags, data, pos); pos += 4;
  1730. data[pos++] = md.WaterHeight;
  1731. data[pos++] = md.Agents;
  1732. md.MapImageId.ToBytes(data, pos); pos += 16;
  1733. if(needSizes)
  1734. capacity -= 4; // 2 shorts per entry
  1735. if(pos < capacity)
  1736. ++count;
  1737. else
  1738. {
  1739. // prepare next packet
  1740. UDPPacketBuffer newbuf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
  1741. Buffer.BlockCopy(data, 0, newbuf.Data, 0, 30);
  1742. // copy the block we already did
  1743. int alreadyDone = pos - lastpos;
  1744. Buffer.BlockCopy(data, lastpos, newbuf.Data, 31, alreadyDone); // 30 is datablock size
  1745. // finish current
  1746. data[countpos] = (byte)count;
  1747. if (needSizes)
  1748. {
  1749. data[lastpos++] = (byte)count;
  1750. while (--count >= 0)
  1751. {
  1752. Utils.UInt16ToBytes(sizes[sizesptr++], data, lastpos); lastpos += 2;
  1753. Utils.UInt16ToBytes(sizes[sizesptr++], data, lastpos); lastpos += 2;
  1754. }
  1755. }
  1756. else
  1757. data[lastpos++] = 0;
  1758. buf.DataLength = lastpos;
  1759. // send it
  1760. m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Land);
  1761. buf = newbuf;
  1762. data = buf.Data;
  1763. pos = alreadyDone + 31;
  1764. capacity = LLUDPServer.MAXPAYLOAD - pos;
  1765. if (needSizes)
  1766. capacity -= 4; // 2 shorts per entry
  1767. count = 1;
  1768. }
  1769. }
  1770. if (count > 0)
  1771. {
  1772. data[countpos] = (byte)count;
  1773. if (needSizes)
  1774. {
  1775. data[pos++] = (byte)count;
  1776. while (--count >= 0)
  1777. {
  1778. Utils.UInt16ToBytes(sizes[sizesptr++], data, pos); pos += 2;
  1779. Utils.UInt16ToBytes(sizes[sizesptr++], data, pos); pos += 2;
  1780. }
  1781. }
  1782. else
  1783. data[pos++] = 0;
  1784. buf.DataLength = pos;
  1785. m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Land);
  1786. }
  1787. }
  1788. public void SendLocalTeleport(Vector3 position, Vector3 lookAt, uint flags)
  1789. {
  1790. TeleportLocalPacket tpLocal = (TeleportLocalPacket)PacketPool.Instance.GetPacket(PacketType.TeleportLocal);
  1791. tpLocal.Info.AgentID = m_agentId;
  1792. tpLocal.Info.TeleportFlags = flags;
  1793. tpLocal.Info.LocationID = 2;
  1794. tpLocal.Info.LookAt = lookAt;
  1795. tpLocal.Info.Position = position;
  1796. // Hack to get this out immediately and skip throttles
  1797. OutPacket(tpLocal, ThrottleOutPacketType.Unknown);
  1798. }
  1799. public virtual void SendRegionTeleport(ulong regionHandle, byte simAccess, IPEndPoint newRegionEndPoint, uint locationID,
  1800. uint flags, string capsURL)
  1801. {
  1802. //TeleportFinishPacket teleport = (TeleportFinishPacket)PacketPool.Instance.GetPacket(PacketType.TeleportFinish);
  1803. TeleportFinishPacket teleport = new TeleportFinishPacket();
  1804. teleport.Info.AgentID = m_agentId;
  1805. teleport.Info.RegionHandle = regionHandle;
  1806. teleport.Info.SimAccess = simAccess;
  1807. teleport.Info.SeedCapability = Util.StringToBytes256(capsURL);
  1808. IPAddress oIP = newRegionEndPoint.Address;
  1809. byte[] byteIP = oIP.GetAddressBytes();
  1810. uint ip = (uint)byteIP[3] << 24;
  1811. ip += (uint)byteIP[2] << 16;
  1812. ip += (uint)byteIP[1] << 8;
  1813. ip += (uint)byteIP[0];
  1814. teleport.Info.SimIP = ip;
  1815. teleport.Info.SimPort = (ushort)newRegionEndPoint.Port;
  1816. teleport.Info.LocationID = 4;
  1817. teleport.Info.TeleportFlags = 1 << 4;
  1818. // Hack to get this out immediately and skip throttles.
  1819. OutPacket(teleport, ThrottleOutPacketType.Unknown);
  1820. }
  1821. /// <summary>
  1822. /// Inform the client that a teleport attempt has failed
  1823. /// </summary>
  1824. public void SendTeleportFailed(string reason)
  1825. {
  1826. TeleportFailedPacket tpFailed = (TeleportFailedPacket)PacketPool.Instance.GetPacket(PacketType.TeleportFailed);
  1827. tpFailed.Info.AgentID = m_agentId;
  1828. tpFailed.Info.Reason = Util.StringToBytes256(reason);
  1829. tpFailed.AlertInfo = new TeleportFailedPacket.AlertInfoBlock[0];
  1830. // Hack to get this out immediately and skip throttles
  1831. OutPacket(tpFailed, ThrottleOutPacketType.Unknown);
  1832. }
  1833. /// <summary>
  1834. ///
  1835. /// </summary>
  1836. public void SendTeleportStart(uint flags)
  1837. {
  1838. TeleportStartPacket tpStart = (TeleportStartPacket)PacketPool.Instance.GetPacket(PacketType.TeleportStart);
  1839. //TeleportStartPacket tpStart = new TeleportStartPacket();
  1840. tpStart.Info.TeleportFlags = flags; //16; // Teleport via location
  1841. // Hack to get this out immediately and skip throttles
  1842. OutPacket(tpStart, ThrottleOutPacketType.Unknown);
  1843. }
  1844. public void SendTeleportProgress(uint flags, string message)
  1845. {
  1846. TeleportProgressPacket tpProgress = (TeleportProgressPacket)PacketPool.Instance.GetPacket(PacketType.TeleportProgress);
  1847. tpProgress.AgentData.AgentID = m_agentId;
  1848. tpProgress.Info.TeleportFlags = flags;
  1849. tpProgress.Info.Message = Util.StringToBytes256(message);
  1850. // Hack to get this out immediately and skip throttles
  1851. OutPacket(tpProgress, ThrottleOutPacketType.Unknown);
  1852. }
  1853. public void SendMoneyBalance(UUID transaction, bool success, byte[] description, int balance, int transactionType, UUID sourceID, bool sourceIsGroup, UUID destID, bool destIsGroup, int amount, string item)
  1854. {
  1855. MoneyBalanceReplyPacket money = (MoneyBalanceReplyPacket)PacketPool.Instance.GetPacket(PacketType.MoneyBalanceReply);
  1856. money.MoneyData.AgentID = m_agentId;
  1857. money.MoneyData.TransactionID = transaction;
  1858. money.MoneyData.TransactionSuccess = success;
  1859. money.MoneyData.Description = description;
  1860. money.MoneyData.MoneyBalance = balance;
  1861. money.TransactionInfo.TransactionType = transactionType;
  1862. money.TransactionInfo.SourceID = sourceID;
  1863. money.TransactionInfo.IsSourceGroup = sourceIsGroup;
  1864. money.TransactionInfo.DestID = destID;
  1865. money.TransactionInfo.IsDestGroup = destIsGroup;
  1866. money.TransactionInfo.Amount = amount;
  1867. money.TransactionInfo.ItemDescription = Util.StringToBytes256(item);
  1868. OutPacket(money, ThrottleOutPacketType.Task);
  1869. }
  1870. public void SendPayPrice(UUID objectID, int[] payPrice)
  1871. {
  1872. if (payPrice[0] == 0 &&
  1873. payPrice[1] == 0 &&
  1874. payPrice[2] == 0 &&
  1875. payPrice[3] == 0 &&
  1876. payPrice[4] == 0)
  1877. return;
  1878. PayPriceReplyPacket payPriceReply = (PayPriceReplyPacket)PacketPool.Instance.GetPacket(PacketType.PayPriceReply);
  1879. payPriceReply.ObjectData.ObjectID = objectID;
  1880. payPriceReply.ObjectData.DefaultPayPrice = payPrice[0];
  1881. payPriceReply.ButtonData = new PayPriceReplyPacket.ButtonDataBlock[4];
  1882. payPriceReply.ButtonData[0] = new PayPriceReplyPacket.ButtonDataBlock();
  1883. payPriceReply.ButtonData[0].PayButton = payPrice[1];
  1884. payPriceReply.ButtonData[1] = new PayPriceReplyPacket.ButtonDataBlock();
  1885. payPriceReply.ButtonData[1].PayButton = payPrice[2];
  1886. payPriceReply.ButtonData[2] = new PayPriceReplyPacket.ButtonDataBlock();
  1887. payPriceReply.ButtonData[2].PayButton = payPrice[3];
  1888. payPriceReply.ButtonData[3] = new PayPriceReplyPacket.ButtonDataBlock();
  1889. payPriceReply.ButtonData[3].PayButton = payPrice[4];
  1890. OutPacket(payPriceReply, ThrottleOutPacketType.Task);
  1891. }
  1892. public void SendKillObject(List<uint> localIDs)
  1893. {
  1894. // foreach (uint id in localIDs)
  1895. // m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle);
  1896. // remove pending entities to reduce looping chances.
  1897. m_entityProps.Remove(localIDs);
  1898. m_entityUpdates.Remove(localIDs);
  1899. KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
  1900. int perpacket = localIDs.Count;
  1901. if(perpacket > 200)
  1902. perpacket = 200;
  1903. int nsent = 0;
  1904. kill.ObjectData = new KillObjectPacket.ObjectDataBlock[perpacket];
  1905. for (int i = 0 ; i < localIDs.Count ; i++ )
  1906. {
  1907. kill.ObjectData[nsent] = new KillObjectPacket.ObjectDataBlock();
  1908. kill.ObjectData[nsent].ID = localIDs[i];
  1909. if(++nsent >= 200)
  1910. {
  1911. OutPacket(kill, ThrottleOutPacketType.Task);
  1912. perpacket = localIDs.Count - i - 1;
  1913. if(perpacket == 0)
  1914. break;
  1915. if(perpacket > 200)
  1916. perpacket = 200;
  1917. kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
  1918. kill.ObjectData = new KillObjectPacket.ObjectDataBlock[perpacket];
  1919. nsent = 0;
  1920. }
  1921. }
  1922. if(nsent != 0)
  1923. {
  1924. OutPacket(kill, ThrottleOutPacketType.Task);
  1925. }
  1926. }
  1927. /// <summary>
  1928. /// Send information about the items contained in a folder to the client.
  1929. /// </summary>
  1930. /// <remarks>
  1931. /// XXX This method needs some refactoring loving
  1932. /// </remarks>
  1933. /// <param name="ownerID">The owner of the folder</param>
  1934. /// <param name="folderID">The id of the folder</param>
  1935. /// <param name="items">The items contained in the folder identified by folderID</param>
  1936. /// <param name="folders"></param>
  1937. /// <param name="fetchFolders">Do we need to send folder information?</param>
  1938. /// <param name="fetchItems">Do we need to send item information?</param>
  1939. public void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items,
  1940. List<InventoryFolderBase> folders, int version, int descendents,
  1941. bool fetchFolders, bool fetchItems)
  1942. {
  1943. // An inventory descendents packet consists of a single agent section and an inventory details
  1944. // section for each inventory item. The size of each inventory item is approximately 550 bytes.
  1945. // limit to what may fit on MTU
  1946. int MAX_ITEMS_PER_PACKET = 5;
  1947. int MAX_FOLDERS_PER_PACKET = 6;
  1948. int totalItems = fetchItems ? items.Count : 0;
  1949. int totalFolders = fetchFolders ? folders.Count : 0;
  1950. int itemsSent = 0;
  1951. int foldersSent = 0;
  1952. int foldersToSend = 0;
  1953. int itemsToSend = 0;
  1954. InventoryDescendentsPacket currentPacket = null;
  1955. // Handle empty folders
  1956. //
  1957. if (totalItems == 0 && totalFolders == 0)
  1958. currentPacket = CreateInventoryDescendentsPacket(ownerID, folderID, version, descendents, 0, 0);
  1959. // To preserve SL compatibility, we will NOT combine folders and items in one packet
  1960. //
  1961. while (itemsSent < totalItems || foldersSent < totalFolders)
  1962. {
  1963. if (currentPacket == null) // Start a new packet
  1964. {
  1965. foldersToSend = totalFolders - foldersSent;
  1966. if (foldersToSend > MAX_FOLDERS_PER_PACKET)
  1967. foldersToSend = MAX_FOLDERS_PER_PACKET;
  1968. if (foldersToSend == 0)
  1969. {
  1970. itemsToSend = totalItems - itemsSent;
  1971. if (itemsToSend > MAX_ITEMS_PER_PACKET)
  1972. itemsToSend = MAX_ITEMS_PER_PACKET;
  1973. }
  1974. currentPacket = CreateInventoryDescendentsPacket(ownerID, folderID, version, descendents, foldersToSend, itemsToSend);
  1975. }
  1976. if (foldersToSend-- > 0)
  1977. currentPacket.FolderData[foldersSent % MAX_FOLDERS_PER_PACKET] = CreateFolderDataBlock(folders[foldersSent++]);
  1978. else if (itemsToSend-- > 0)
  1979. currentPacket.ItemData[itemsSent % MAX_ITEMS_PER_PACKET] = CreateItemDataBlock(items[itemsSent++]);
  1980. else
  1981. {
  1982. //m_log.DebugFormat(
  1983. // "[LLCLIENTVIEW]: Sending inventory folder details packet to {0} for folder {1}", Name, folderID);
  1984. OutPacket(currentPacket, ThrottleOutPacketType.Asset, false);
  1985. currentPacket = null;
  1986. }
  1987. }
  1988. if (currentPacket != null)
  1989. {
  1990. //m_log.DebugFormat(
  1991. // "[LLCLIENTVIEW]: Sending inventory folder details packet to {0} for folder {1}", Name, folderID);
  1992. OutPacket(currentPacket, ThrottleOutPacketType.Asset, false);
  1993. }
  1994. }
  1995. private InventoryDescendentsPacket.FolderDataBlock CreateFolderDataBlock(InventoryFolderBase folder)
  1996. {
  1997. InventoryDescendentsPacket.FolderDataBlock newBlock = new InventoryDescendentsPacket.FolderDataBlock();
  1998. newBlock.FolderID = folder.ID;
  1999. newBlock.Name = Util.StringToBytes256(folder.Name);
  2000. newBlock.ParentID = folder.ParentID;
  2001. newBlock.Type = (sbyte)folder.Type;
  2002. //if (newBlock.Type == InventoryItemBase.SUITCASE_FOLDER_TYPE)
  2003. // newBlock.Type = InventoryItemBase.SUITCASE_FOLDER_FAKE_TYPE;
  2004. return newBlock;
  2005. }
  2006. private InventoryDescendentsPacket.ItemDataBlock CreateItemDataBlock(InventoryItemBase item)
  2007. {
  2008. InventoryDescendentsPacket.ItemDataBlock newBlock = new InventoryDescendentsPacket.ItemDataBlock();
  2009. newBlock.ItemID = item.ID;
  2010. newBlock.AssetID = item.AssetID;
  2011. newBlock.CreatorID = item.CreatorIdAsUuid;
  2012. newBlock.BaseMask = item.BasePermissions;
  2013. newBlock.Description = Util.StringToBytes256(item.Description);
  2014. newBlock.EveryoneMask = item.EveryOnePermissions;
  2015. newBlock.OwnerMask = item.CurrentPermissions;
  2016. newBlock.FolderID = item.Folder;
  2017. newBlock.InvType = (sbyte)item.InvType;
  2018. newBlock.Name = Util.StringToBytes256(item.Name);
  2019. newBlock.NextOwnerMask = item.NextPermissions;
  2020. newBlock.OwnerID = item.Owner;
  2021. newBlock.Type = (sbyte)item.AssetType;
  2022. newBlock.GroupID = item.GroupID;
  2023. newBlock.GroupOwned = item.GroupOwned;
  2024. newBlock.GroupMask = item.GroupPermissions;
  2025. newBlock.CreationDate = item.CreationDate;
  2026. newBlock.SalePrice = item.SalePrice;
  2027. newBlock.SaleType = item.SaleType;
  2028. newBlock.Flags = item.Flags & 0x2000ff;
  2029. newBlock.CRC =
  2030. Helpers.InventoryCRC(newBlock.CreationDate, newBlock.SaleType,
  2031. newBlock.InvType, newBlock.Type,
  2032. newBlock.AssetID, newBlock.GroupID,
  2033. newBlock.SalePrice,
  2034. newBlock.OwnerID, newBlock.CreatorID,
  2035. newBlock.ItemID, newBlock.FolderID,
  2036. newBlock.EveryoneMask,
  2037. newBlock.Flags, newBlock.OwnerMask,
  2038. newBlock.GroupMask, newBlock.NextOwnerMask);
  2039. return newBlock;
  2040. }
  2041. private void AddNullFolderBlockToDecendentsPacket(ref InventoryDescendentsPacket packet)
  2042. {
  2043. packet.FolderData = new InventoryDescendentsPacket.FolderDataBlock[1];
  2044. packet.FolderData[0] = new InventoryDescendentsPacket.FolderDataBlock();
  2045. packet.FolderData[0].FolderID = UUID.Zero;
  2046. packet.FolderData[0].ParentID = UUID.Zero;
  2047. packet.FolderData[0].Type = -1;
  2048. packet.FolderData[0].Name = Array.Empty<byte>();
  2049. }
  2050. private void AddNullItemBlockToDescendentsPacket(ref InventoryDescendentsPacket packet)
  2051. {
  2052. packet.ItemData = new InventoryDescendentsPacket.ItemDataBlock[1];
  2053. packet.ItemData[0] = new InventoryDescendentsPacket.ItemDataBlock();
  2054. packet.ItemData[0].ItemID = UUID.Zero;
  2055. packet.ItemData[0].AssetID = UUID.Zero;
  2056. packet.ItemData[0].CreatorID = UUID.Zero;
  2057. packet.ItemData[0].BaseMask = 0;
  2058. packet.ItemData[0].Description = Array.Empty<byte>();
  2059. packet.ItemData[0].EveryoneMask = 0;
  2060. packet.ItemData[0].OwnerMask = 0;
  2061. packet.ItemData[0].FolderID = UUID.Zero;
  2062. packet.ItemData[0].InvType = (sbyte)0;
  2063. packet.ItemData[0].Name = Array.Empty<byte>();
  2064. packet.ItemData[0].NextOwnerMask = 0;
  2065. packet.ItemData[0].OwnerID = UUID.Zero;
  2066. packet.ItemData[0].Type = -1;
  2067. packet.ItemData[0].GroupID = UUID.Zero;
  2068. packet.ItemData[0].GroupOwned = false;
  2069. packet.ItemData[0].GroupMask = 0;
  2070. packet.ItemData[0].CreationDate = 0;
  2071. packet.ItemData[0].SalePrice = 0;
  2072. packet.ItemData[0].SaleType = 0;
  2073. packet.ItemData[0].Flags = 0;
  2074. // No need to add CRC
  2075. }
  2076. private InventoryDescendentsPacket CreateInventoryDescendentsPacket(UUID ownerID, UUID folderID, int version, int descendents, int folders, int items)
  2077. {
  2078. InventoryDescendentsPacket descend = (InventoryDescendentsPacket)PacketPool.Instance.GetPacket(PacketType.InventoryDescendents);
  2079. descend.Header.Zerocoded = true;
  2080. descend.AgentData.AgentID = m_agentId;
  2081. descend.AgentData.OwnerID = ownerID;
  2082. descend.AgentData.FolderID = folderID;
  2083. descend.AgentData.Version = version;
  2084. descend.AgentData.Descendents = descendents;
  2085. if (folders > 0)
  2086. descend.FolderData = new InventoryDescendentsPacket.FolderDataBlock[folders];
  2087. else
  2088. AddNullFolderBlockToDecendentsPacket(ref descend);
  2089. if (items > 0)
  2090. descend.ItemData = new InventoryDescendentsPacket.ItemDataBlock[items];
  2091. else
  2092. AddNullItemBlockToDescendentsPacket(ref descend);
  2093. return descend;
  2094. }
  2095. public void SendInventoryItemDetails(InventoryItemBase[] items)
  2096. {
  2097. // Fudge this value. It's only needed to make the CRC anyway
  2098. const uint FULL_MASK_PERMISSIONS = (uint)0x7fffffff;
  2099. FetchInventoryReplyPacket inventoryReply = (FetchInventoryReplyPacket)PacketPool.Instance.GetPacket(PacketType.FetchInventoryReply);
  2100. inventoryReply.AgentData.AgentID = m_agentId;
  2101. int total = items.Length;
  2102. int count = 0;
  2103. for(int i = 0; i < items.Length; ++i)
  2104. {
  2105. if(count == 0)
  2106. {
  2107. if(total < 10)
  2108. {
  2109. inventoryReply.InventoryData = new FetchInventoryReplyPacket.InventoryDataBlock[total];
  2110. total = 0;
  2111. }
  2112. else
  2113. {
  2114. inventoryReply.InventoryData = new FetchInventoryReplyPacket.InventoryDataBlock[10];
  2115. total -= 10;
  2116. }
  2117. }
  2118. inventoryReply.InventoryData[count] = new FetchInventoryReplyPacket.InventoryDataBlock();
  2119. FetchInventoryReplyPacket.InventoryDataBlock data = inventoryReply.InventoryData[count];
  2120. data.ItemID = items[i].ID;
  2121. data.AssetID = items[i].AssetID;
  2122. data.CreatorID = items[i].CreatorIdAsUuid;
  2123. data.BaseMask = items[i].BasePermissions;
  2124. data.CreationDate = items[i].CreationDate;
  2125. data.Description = Util.StringToBytes256(items[i].Description);
  2126. data.EveryoneMask = items[i].EveryOnePermissions;
  2127. data.FolderID = items[i].Folder;
  2128. data.InvType = (sbyte)items[i].InvType;
  2129. data.Name = Util.StringToBytes256(items[i].Name);
  2130. data.NextOwnerMask = items[i].NextPermissions;
  2131. data.OwnerID = items[i].Owner;
  2132. data.OwnerMask = items[i].CurrentPermissions;
  2133. data.Type = (sbyte)items[i].AssetType;
  2134. data.GroupID = items[i].GroupID;
  2135. data.GroupOwned = items[i].GroupOwned;
  2136. data.GroupMask = items[i].GroupPermissions;
  2137. data.Flags = items[i].Flags;
  2138. data.SalePrice = items[i].SalePrice;
  2139. data.SaleType = items[i].SaleType;
  2140. data.CRC = Helpers.InventoryCRC(
  2141. 1000, 0, data.InvType, data.Type, data.AssetID,
  2142. data.GroupID, 100, data.OwnerID, data.CreatorID,
  2143. data.ItemID, data.FolderID, FULL_MASK_PERMISSIONS, 1, FULL_MASK_PERMISSIONS, FULL_MASK_PERMISSIONS,
  2144. FULL_MASK_PERMISSIONS);
  2145. ++count;
  2146. if(count == 10 || total == 0)
  2147. {
  2148. inventoryReply.Header.Zerocoded = true;
  2149. OutPacket(inventoryReply, ThrottleOutPacketType.Asset);
  2150. if(total == 0)
  2151. break;
  2152. count = 0;
  2153. }
  2154. }
  2155. }
  2156. protected void SendBulkUpdateInventoryFolder(InventoryFolderBase folderBase, UUID? transationID)
  2157. {
  2158. // We will use the same transaction id for all the separate packets to be sent out in this update.
  2159. UUID transactionId = transationID ?? UUID.Random();
  2160. List<BulkUpdateInventoryPacket.FolderDataBlock> folderDataBlocks
  2161. = new List<BulkUpdateInventoryPacket.FolderDataBlock>();
  2162. SendBulkUpdateInventoryFolderRecursive(folderBase, ref folderDataBlocks, transactionId);
  2163. if (folderDataBlocks.Count > 0)
  2164. {
  2165. // We'll end up with some unsent folder blocks if there were some empty folders at the end of the list
  2166. // Send these now
  2167. BulkUpdateInventoryPacket bulkUpdate
  2168. = (BulkUpdateInventoryPacket)PacketPool.Instance.GetPacket(PacketType.BulkUpdateInventory);
  2169. bulkUpdate.Header.Zerocoded = true;
  2170. bulkUpdate.AgentData.AgentID = m_agentId;
  2171. bulkUpdate.AgentData.TransactionID = transactionId;
  2172. bulkUpdate.FolderData = folderDataBlocks.ToArray();
  2173. List<BulkUpdateInventoryPacket.ItemDataBlock> foo = new List<BulkUpdateInventoryPacket.ItemDataBlock>();
  2174. bulkUpdate.ItemData = foo.ToArray();
  2175. //m_log.Debug("SendBulkUpdateInventory :" + bulkUpdate);
  2176. OutPacket(bulkUpdate, ThrottleOutPacketType.Asset);
  2177. }
  2178. }
  2179. /// <summary>
  2180. /// Recursively construct bulk update packets to send folders and items
  2181. /// </summary>
  2182. /// <param name="folder"></param>
  2183. /// <param name="folderDataBlocks"></param>
  2184. /// <param name="transactionId"></param>
  2185. private void SendBulkUpdateInventoryFolderRecursive(
  2186. InventoryFolderBase folder, ref List<BulkUpdateInventoryPacket.FolderDataBlock> folderDataBlocks,
  2187. UUID transactionId)
  2188. {
  2189. folderDataBlocks.Add(GenerateBulkUpdateFolderDataBlock(folder));
  2190. const int MAX_ITEMS_PER_PACKET = 5;
  2191. IInventoryService invService = m_scene.RequestModuleInterface<IInventoryService>();
  2192. // If there are any items then we have to start sending them off in this packet - the next folder will have
  2193. // to be in its own bulk update packet. Also, we can only fit 5 items in a packet (at least this was the limit
  2194. // being used on the Linden grid at 20081203).
  2195. InventoryCollection contents = invService.GetFolderContent(m_agentId, folder.ID); // folder.RequestListOfItems();
  2196. List<InventoryItemBase> items = contents.Items;
  2197. while (items.Count > 0)
  2198. {
  2199. BulkUpdateInventoryPacket bulkUpdate
  2200. = (BulkUpdateInventoryPacket)PacketPool.Instance.GetPacket(PacketType.BulkUpdateInventory);
  2201. bulkUpdate.Header.Zerocoded = true;
  2202. bulkUpdate.AgentData.AgentID = m_agentId;
  2203. bulkUpdate.AgentData.TransactionID = transactionId;
  2204. bulkUpdate.FolderData = folderDataBlocks.ToArray();
  2205. int itemsToSend = (items.Count > MAX_ITEMS_PER_PACKET ? MAX_ITEMS_PER_PACKET : items.Count);
  2206. bulkUpdate.ItemData = new BulkUpdateInventoryPacket.ItemDataBlock[itemsToSend];
  2207. for (int i = 0; i < itemsToSend; i++)
  2208. {
  2209. // Remove from the end of the list so that we don't incur a performance penalty
  2210. bulkUpdate.ItemData[i] = GenerateBulkUpdateItemDataBlock(items[items.Count - 1]);
  2211. items.RemoveAt(items.Count - 1);
  2212. }
  2213. //m_log.Debug("SendBulkUpdateInventoryRecursive :" + bulkUpdate);
  2214. OutPacket(bulkUpdate, ThrottleOutPacketType.Asset);
  2215. folderDataBlocks = new List<BulkUpdateInventoryPacket.FolderDataBlock>();
  2216. // If we're going to be sending another items packet then it needs to contain just the folder to which those
  2217. // items belong.
  2218. if (items.Count > 0)
  2219. folderDataBlocks.Add(GenerateBulkUpdateFolderDataBlock(folder));
  2220. }
  2221. List<InventoryFolderBase> subFolders = contents.Folders;
  2222. for (int indx = 0; indx < subFolders.Count; ++indx)
  2223. {
  2224. SendBulkUpdateInventoryFolderRecursive(subFolders[indx], ref folderDataBlocks, transactionId);
  2225. }
  2226. }
  2227. /// <summary>
  2228. /// Generate a bulk update inventory data block for the given folder
  2229. /// </summary>
  2230. /// <param name="folder"></param>
  2231. /// <returns></returns>
  2232. private BulkUpdateInventoryPacket.FolderDataBlock GenerateBulkUpdateFolderDataBlock(InventoryFolderBase folder)
  2233. {
  2234. BulkUpdateInventoryPacket.FolderDataBlock folderBlock = new BulkUpdateInventoryPacket.FolderDataBlock();
  2235. folderBlock.FolderID = folder.ID;
  2236. folderBlock.ParentID = folder.ParentID;
  2237. folderBlock.Type = (sbyte)folder.Type;
  2238. // Leaving this here for now, just in case we need to do this for a while
  2239. //if (folderBlock.Type == InventoryItemBase.SUITCASE_FOLDER_TYPE)
  2240. // folderBlock.Type = InventoryItemBase.SUITCASE_FOLDER_FAKE_TYPE;
  2241. folderBlock.Name = Util.StringToBytes256(folder.Name);
  2242. return folderBlock;
  2243. }
  2244. /// <summary>
  2245. /// Generate a bulk update inventory data block for the given item
  2246. /// </summary>
  2247. /// <param name="item"></param>
  2248. /// <returns></returns>
  2249. private BulkUpdateInventoryPacket.ItemDataBlock GenerateBulkUpdateItemDataBlock(InventoryItemBase item)
  2250. {
  2251. BulkUpdateInventoryPacket.ItemDataBlock itemBlock = new BulkUpdateInventoryPacket.ItemDataBlock();
  2252. itemBlock.ItemID = item.ID;
  2253. itemBlock.AssetID = item.AssetID;
  2254. itemBlock.CreatorID = item.CreatorIdAsUuid;
  2255. itemBlock.BaseMask = item.BasePermissions;
  2256. itemBlock.Description = Util.StringToBytes256(item.Description);
  2257. itemBlock.EveryoneMask = item.EveryOnePermissions;
  2258. itemBlock.FolderID = item.Folder;
  2259. itemBlock.InvType = (sbyte)item.InvType;
  2260. itemBlock.Name = Util.StringToBytes256(item.Name);
  2261. itemBlock.NextOwnerMask = item.NextPermissions;
  2262. itemBlock.OwnerID = item.Owner;
  2263. itemBlock.OwnerMask = item.CurrentPermissions;
  2264. itemBlock.Type = (sbyte)item.AssetType;
  2265. itemBlock.GroupID = item.GroupID;
  2266. itemBlock.GroupOwned = item.GroupOwned;
  2267. itemBlock.GroupMask = item.GroupPermissions;
  2268. itemBlock.Flags = item.Flags & 0x2000ff;
  2269. itemBlock.SalePrice = item.SalePrice;
  2270. itemBlock.SaleType = item.SaleType;
  2271. itemBlock.CreationDate = item.CreationDate;
  2272. itemBlock.CRC =
  2273. Helpers.InventoryCRC(
  2274. 1000, 0, itemBlock.InvType,
  2275. itemBlock.Type, itemBlock.AssetID,
  2276. itemBlock.GroupID, 100,
  2277. itemBlock.OwnerID, itemBlock.CreatorID,
  2278. itemBlock.ItemID, itemBlock.FolderID,
  2279. (uint)PermissionMask.All, 1, (uint)PermissionMask.All, (uint)PermissionMask.All,
  2280. (uint)PermissionMask.All);
  2281. return itemBlock;
  2282. }
  2283. public void SendBulkUpdateInventory(InventoryNodeBase node, UUID? transationID = null)
  2284. {
  2285. if (node is InventoryItemBase)
  2286. SendBulkUpdateInventoryItem((InventoryItemBase)node, transationID);
  2287. else if (node is InventoryFolderBase)
  2288. SendBulkUpdateInventoryFolder((InventoryFolderBase)node, transationID);
  2289. else if (node != null)
  2290. m_log.ErrorFormat("[CLIENT]: {0} sent unknown inventory node named {1}", Name, node.Name);
  2291. else
  2292. m_log.ErrorFormat("[CLIENT]: {0} sent null inventory node", Name);
  2293. }
  2294. protected void SendBulkUpdateInventoryItem(InventoryItemBase item, UUID? transationID = null)
  2295. {
  2296. IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
  2297. if (eq == null)
  2298. return;
  2299. eq.SendBulkUpdateInventoryItem(item, m_agentId, transationID);
  2300. /*
  2301. const uint FULL_MASK_PERMISSIONS = (uint)0x7ffffff;
  2302. BulkUpdateInventoryPacket bulkUpdate
  2303. = (BulkUpdateInventoryPacket)PacketPool.Instance.GetPacket(PacketType.BulkUpdateInventory);
  2304. bulkUpdate.AgentData.AgentID = m_agentId;
  2305. bulkUpdate.AgentData.TransactionID = transationID ?? UUID.Random();
  2306. bulkUpdate.FolderData = new BulkUpdateInventoryPacket.FolderDataBlock[1];
  2307. bulkUpdate.FolderData[0] = new BulkUpdateInventoryPacket.FolderDataBlock();
  2308. bulkUpdate.FolderData[0].FolderID = UUID.Zero;
  2309. bulkUpdate.FolderData[0].ParentID = UUID.Zero;
  2310. bulkUpdate.FolderData[0].Type = -1;
  2311. bulkUpdate.FolderData[0].Name = Array.Empty<byte>();
  2312. bulkUpdate.ItemData = new BulkUpdateInventoryPacket.ItemDataBlock[1];
  2313. bulkUpdate.ItemData[0] = new BulkUpdateInventoryPacket.ItemDataBlock();
  2314. bulkUpdate.ItemData[0].ItemID = item.ID;
  2315. bulkUpdate.ItemData[0].AssetID = item.AssetID;
  2316. bulkUpdate.ItemData[0].CreatorID = item.CreatorIdAsUuid;
  2317. bulkUpdate.ItemData[0].BaseMask = item.BasePermissions;
  2318. bulkUpdate.ItemData[0].CreationDate = item.CreationDate;
  2319. bulkUpdate.ItemData[0].Description = Util.StringToBytes256(item.Description);
  2320. bulkUpdate.ItemData[0].EveryoneMask = item.EveryOnePermissions;
  2321. bulkUpdate.ItemData[0].FolderID = item.Folder;
  2322. bulkUpdate.ItemData[0].InvType = (sbyte)item.InvType;
  2323. bulkUpdate.ItemData[0].Name = Util.StringToBytes256(item.Name);
  2324. bulkUpdate.ItemData[0].NextOwnerMask = item.NextPermissions;
  2325. bulkUpdate.ItemData[0].OwnerID = item.Owner;
  2326. bulkUpdate.ItemData[0].OwnerMask = item.CurrentPermissions;
  2327. bulkUpdate.ItemData[0].Type = (sbyte)item.AssetType;
  2328. bulkUpdate.ItemData[0].GroupID = item.GroupID;
  2329. bulkUpdate.ItemData[0].GroupOwned = item.GroupOwned;
  2330. bulkUpdate.ItemData[0].GroupMask = item.GroupPermissions;
  2331. bulkUpdate.ItemData[0].Flags = item.Flags & 0x2000ff;
  2332. bulkUpdate.ItemData[0].SalePrice = item.SalePrice;
  2333. bulkUpdate.ItemData[0].SaleType = item.SaleType;
  2334. bulkUpdate.ItemData[0].CRC =
  2335. Helpers.InventoryCRC(1000, 0, bulkUpdate.ItemData[0].InvType,
  2336. bulkUpdate.ItemData[0].Type, bulkUpdate.ItemData[0].AssetID,
  2337. bulkUpdate.ItemData[0].GroupID, 100,
  2338. bulkUpdate.ItemData[0].OwnerID, bulkUpdate.ItemData[0].CreatorID,
  2339. bulkUpdate.ItemData[0].ItemID, bulkUpdate.ItemData[0].FolderID,
  2340. FULL_MASK_PERMISSIONS, 1, FULL_MASK_PERMISSIONS, FULL_MASK_PERMISSIONS,
  2341. FULL_MASK_PERMISSIONS);
  2342. bulkUpdate.Header.Zerocoded = true;
  2343. OutPacket(bulkUpdate, ThrottleOutPacketType.Asset);
  2344. */
  2345. }
  2346. public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId)
  2347. {
  2348. SendInventoryItemCreateUpdate(Item, UUID.Zero, callbackId);
  2349. }
  2350. /// <see>IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase)</see>
  2351. public void SendInventoryItemCreateUpdate(InventoryItemBase Item, UUID transactionID, uint callbackId)
  2352. {
  2353. const uint FULL_MASK_PERMISSIONS = (uint)0x7fffffff;
  2354. UpdateCreateInventoryItemPacket InventoryReply
  2355. = (UpdateCreateInventoryItemPacket)PacketPool.Instance.GetPacket(
  2356. PacketType.UpdateCreateInventoryItem);
  2357. // TODO: don't create new blocks if recycling an old packet
  2358. InventoryReply.AgentData.AgentID = m_agentId;
  2359. InventoryReply.AgentData.SimApproved = true;
  2360. InventoryReply.AgentData.TransactionID = transactionID;
  2361. InventoryReply.InventoryData = new UpdateCreateInventoryItemPacket.InventoryDataBlock[1];
  2362. InventoryReply.InventoryData[0] = new UpdateCreateInventoryItemPacket.InventoryDataBlock();
  2363. InventoryReply.InventoryData[0].ItemID = Item.ID;
  2364. InventoryReply.InventoryData[0].AssetID = Item.AssetID;
  2365. InventoryReply.InventoryData[0].CreatorID = Item.CreatorIdAsUuid;
  2366. InventoryReply.InventoryData[0].BaseMask = Item.BasePermissions;
  2367. InventoryReply.InventoryData[0].Description = Util.StringToBytes256(Item.Description);
  2368. InventoryReply.InventoryData[0].EveryoneMask = Item.EveryOnePermissions;
  2369. InventoryReply.InventoryData[0].FolderID = Item.Folder;
  2370. InventoryReply.InventoryData[0].InvType = (sbyte)Item.InvType;
  2371. InventoryReply.InventoryData[0].Name = Util.StringToBytes256(Item.Name);
  2372. InventoryReply.InventoryData[0].NextOwnerMask = Item.NextPermissions;
  2373. InventoryReply.InventoryData[0].OwnerID = Item.Owner;
  2374. InventoryReply.InventoryData[0].OwnerMask = Item.CurrentPermissions;
  2375. InventoryReply.InventoryData[0].Type = (sbyte)Item.AssetType;
  2376. InventoryReply.InventoryData[0].CallbackID = callbackId;
  2377. InventoryReply.InventoryData[0].GroupID = Item.GroupID;
  2378. InventoryReply.InventoryData[0].GroupOwned = Item.GroupOwned;
  2379. InventoryReply.InventoryData[0].GroupMask = Item.GroupPermissions;
  2380. InventoryReply.InventoryData[0].Flags = Item.Flags & 0x2000ff;
  2381. InventoryReply.InventoryData[0].SalePrice = Item.SalePrice;
  2382. InventoryReply.InventoryData[0].SaleType = Item.SaleType;
  2383. InventoryReply.InventoryData[0].CreationDate = Item.CreationDate;
  2384. InventoryReply.InventoryData[0].CRC =
  2385. Helpers.InventoryCRC(1000, 0, InventoryReply.InventoryData[0].InvType,
  2386. InventoryReply.InventoryData[0].Type, InventoryReply.InventoryData[0].AssetID,
  2387. InventoryReply.InventoryData[0].GroupID, 100,
  2388. InventoryReply.InventoryData[0].OwnerID, InventoryReply.InventoryData[0].CreatorID,
  2389. InventoryReply.InventoryData[0].ItemID, InventoryReply.InventoryData[0].FolderID,
  2390. FULL_MASK_PERMISSIONS, 1, FULL_MASK_PERMISSIONS, FULL_MASK_PERMISSIONS,
  2391. FULL_MASK_PERMISSIONS);
  2392. InventoryReply.Header.Zerocoded = true;
  2393. OutPacket(InventoryReply, ThrottleOutPacketType.Asset);
  2394. }
  2395. public void SendRemoveInventoryItem(UUID itemID)
  2396. {
  2397. RemoveInventoryItemPacket remove = (RemoveInventoryItemPacket)PacketPool.Instance.GetPacket(PacketType.RemoveInventoryItem);
  2398. // TODO: don't create new blocks if recycling an old packet
  2399. remove.AgentData.AgentID = m_agentId;
  2400. remove.AgentData.SessionID = m_sessionId;
  2401. remove.InventoryData = new RemoveInventoryItemPacket.InventoryDataBlock[1];
  2402. remove.InventoryData[0] = new RemoveInventoryItemPacket.InventoryDataBlock();
  2403. remove.InventoryData[0].ItemID = itemID;
  2404. remove.Header.Zerocoded = true;
  2405. OutPacket(remove, ThrottleOutPacketType.Asset);
  2406. }
  2407. /*
  2408. private uint adjustControls(int input)
  2409. {
  2410. uint ret = (uint)input;
  2411. uint masked = ret & 0x0f;
  2412. masked <<= 19;
  2413. ret |= masked;
  2414. return ret;
  2415. }
  2416. */
  2417. public void SendTakeControls(int controls, bool passToAgent, bool TakeControls)
  2418. {
  2419. ScriptControlChangePacket scriptcontrol = (ScriptControlChangePacket)PacketPool.Instance.GetPacket(PacketType.ScriptControlChange);
  2420. ScriptControlChangePacket.DataBlock[] data = new ScriptControlChangePacket.DataBlock[1];
  2421. ScriptControlChangePacket.DataBlock ddata = new ScriptControlChangePacket.DataBlock();
  2422. // ddata.Controls = adjustControls(controls);
  2423. ddata.Controls = (uint)controls;
  2424. ddata.PassToAgent = passToAgent;
  2425. ddata.TakeControls = TakeControls;
  2426. data[0] = ddata;
  2427. scriptcontrol.Data = data;
  2428. OutPacket(scriptcontrol, ThrottleOutPacketType.Task);
  2429. }
  2430. static private readonly byte[] ReplyTaskInventoryHeader = new byte[] {
  2431. Helpers.MSG_RELIABLE, //| Helpers.MSG_ZEROCODED, not doing spec zeroencode on this
  2432. 0, 0, 0, 0, // sequence number
  2433. 0, // extra
  2434. 0xff, 0xff, 1, 34 // ID 90 (low frequency bigendian)
  2435. };
  2436. public void SendTaskInventory(UUID taskID, short serial, byte[] fileName)
  2437. {
  2438. UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
  2439. byte[] data = buf.Data;
  2440. //setup header
  2441. Buffer.BlockCopy(ReplyTaskInventoryHeader, 0, data, 0, 10);
  2442. taskID.ToBytes(data, 10); // 26
  2443. Utils.Int16ToBytes(serial, data, 26); // 28
  2444. data[28] = (byte)fileName.Length;
  2445. if(data[28] > 0)
  2446. Buffer.BlockCopy(fileName, 0, data, 29, data[28]);
  2447. buf.DataLength = 29 + data[28];
  2448. //m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task, null, false, true);
  2449. m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task);
  2450. }
  2451. static private readonly byte[] SendXferPacketHeader = new byte[] {
  2452. 0, //Helpers.MSG_RELIABLE, Xfer control must provide reliabialty
  2453. 0, 0, 0, 0, // sequence number
  2454. 0, // extra
  2455. 18 // ID (high frequency bigendian)
  2456. };
  2457. public void SendXferPacket(ulong xferID, uint packet,
  2458. byte[] XferData, int XferDataOffset, int XferDatapktLen, bool isTaskInventory)
  2459. {
  2460. UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
  2461. byte[] data = buf.Data;
  2462. //setup header
  2463. Buffer.BlockCopy(SendXferPacketHeader, 0, data, 0, 7);
  2464. Utils.UInt64ToBytesSafepos(xferID, data, 7); // 15
  2465. Utils.UIntToBytesSafepos(packet, data, 15); // 19
  2466. int len = XferDatapktLen;
  2467. if (XferDataOffset == 0) // first packet needs to send the total xfer data len
  2468. len += 4;
  2469. if (len > LLUDPServer.MAXPAYLOAD) // should never happen
  2470. len = LLUDPServer.MAXPAYLOAD;
  2471. if (len == 0)
  2472. {
  2473. data[19] = 0;
  2474. data[20] = 0;
  2475. }
  2476. else
  2477. {
  2478. data[19] = (byte)len;
  2479. data[20] = (byte)(len >> 8);
  2480. if(XferDataOffset == 0)
  2481. {
  2482. // need to send total xfer data len
  2483. Utils.IntToBytesSafepos(XferData.Length, data, 21);
  2484. if (XferDatapktLen > 0)
  2485. Buffer.BlockCopy(XferData, XferDataOffset, data, 25, XferDatapktLen);
  2486. }
  2487. else
  2488. Buffer.BlockCopy(XferData, XferDataOffset, data, 21, XferDatapktLen);
  2489. }
  2490. buf.DataLength = 21 + len;
  2491. m_udpServer.SendUDPPacket(m_udpClient, buf, isTaskInventory ? ThrottleOutPacketType.Task : ThrottleOutPacketType.Asset);
  2492. }
  2493. static private readonly byte[] AbortXferHeader = new byte[] {
  2494. Helpers.MSG_RELIABLE,
  2495. 0, 0, 0, 0, // sequence number
  2496. 0, // extra
  2497. 0xff, 0xff, 0, 157 // ID 157 (low frequency bigendian)
  2498. };
  2499. public void SendAbortXferPacket(ulong xferID)
  2500. {
  2501. UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
  2502. byte[] data = buf.Data;
  2503. //setup header
  2504. Buffer.BlockCopy(AbortXferHeader, 0, data, 0, 10);
  2505. Utils.UInt64ToBytesSafepos(xferID, data, 10); // 18
  2506. Utils.IntToBytesSafepos(0, data, 18); // 22 reason TODO
  2507. buf.DataLength = 22;
  2508. m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Asset);
  2509. }
  2510. public void SendEconomyData(float EnergyEfficiency, int ObjectCapacity, int ObjectCount, int PriceEnergyUnit,
  2511. int PriceGroupCreate, int PriceObjectClaim, float PriceObjectRent, float PriceObjectScaleFactor,
  2512. int PriceParcelClaim, float PriceParcelClaimFactor, int PriceParcelRent, int PricePublicObjectDecay,
  2513. int PricePublicObjectDelete, int PriceRentLight, int PriceUpload, int TeleportMinPrice, float TeleportPriceExponent)
  2514. {
  2515. EconomyDataPacket economyData = (EconomyDataPacket)PacketPool.Instance.GetPacket(PacketType.EconomyData);
  2516. economyData.Info.EnergyEfficiency = EnergyEfficiency;
  2517. economyData.Info.ObjectCapacity = ObjectCapacity;
  2518. economyData.Info.ObjectCount = ObjectCount;
  2519. economyData.Info.PriceEnergyUnit = PriceEnergyUnit;
  2520. economyData.Info.PriceGroupCreate = PriceGroupCreate;
  2521. economyData.Info.PriceObjectClaim = PriceObjectClaim;
  2522. economyData.Info.PriceObjectRent = PriceObjectRent;
  2523. economyData.Info.PriceObjectScaleFactor = PriceObjectScaleFactor;
  2524. economyData.Info.PriceParcelClaim = PriceParcelClaim;
  2525. economyData.Info.PriceParcelClaimFactor = PriceParcelClaimFactor;
  2526. economyData.Info.PriceParcelRent = PriceParcelRent;
  2527. economyData.Info.PricePublicObjectDecay = PricePublicObjectDecay;
  2528. economyData.Info.PricePublicObjectDelete = PricePublicObjectDelete;
  2529. economyData.Info.PriceRentLight = PriceRentLight;
  2530. economyData.Info.PriceUpload = PriceUpload;
  2531. economyData.Info.TeleportMinPrice = TeleportMinPrice;
  2532. economyData.Info.TeleportPriceExponent = TeleportPriceExponent;
  2533. economyData.Header.Reliable = true;
  2534. OutPacket(economyData, ThrottleOutPacketType.Task);
  2535. }
  2536. static private readonly byte[] AvatarPickerReplyHeader = new byte[] {
  2537. Helpers.MSG_RELIABLE,
  2538. 0, 0, 0, 0, // sequence number
  2539. 0, // extra
  2540. 0xff, 0xff, 0, 28 // ID 28 (low frequency bigendian)
  2541. };
  2542. public void SendAvatarPickerReply(UUID QueryID, List<UserData> users)
  2543. {
  2544. UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
  2545. byte[] data = buf.Data;
  2546. //setup header
  2547. Buffer.BlockCopy(AvatarPickerReplyHeader, 0, data, 0, 10);
  2548. m_agentId.ToBytes(data, 10); //26
  2549. QueryID.ToBytes(data, 26); //42
  2550. if (users.Count == 0)
  2551. {
  2552. data[42] = 0;
  2553. buf.DataLength = 43;
  2554. m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task);
  2555. return;
  2556. }
  2557. int pos = 43;
  2558. int count = 0;
  2559. for(int u = 0; u < users.Count; ++u)
  2560. {
  2561. UserData user = users[u];
  2562. user.Id.ToBytes(data,pos);
  2563. pos+= 16;
  2564. byte[] tmp = Utils.StringToBytes(user.FirstName);
  2565. data[pos++] = (byte)tmp.Length;
  2566. if(tmp.Length > 0)
  2567. {
  2568. Buffer.BlockCopy(tmp, 0, data, pos, tmp.Length);
  2569. pos += tmp.Length;
  2570. }
  2571. tmp = Utils.StringToBytes(user.LastName);
  2572. data[pos++] = (byte)tmp.Length;
  2573. if (tmp.Length > 0)
  2574. {
  2575. Buffer.BlockCopy(tmp, 0, data, pos, tmp.Length);
  2576. pos += tmp.Length;
  2577. }
  2578. ++count;
  2579. if (pos >= LLUDPServer.MAXPAYLOAD - 120)
  2580. {
  2581. data[42] = (byte)count;
  2582. buf.DataLength = pos;
  2583. m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task);
  2584. if (u < users.Count - 1)
  2585. {
  2586. UDPPacketBuffer newbuf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
  2587. byte[] newdata = newbuf.Data;
  2588. Buffer.BlockCopy(data, 0, newdata, 0, 42);
  2589. buf = newbuf;
  2590. data = newdata;
  2591. pos = 43;
  2592. }
  2593. count = 0;
  2594. }
  2595. }
  2596. if(count > 0)
  2597. {
  2598. data[42] = (byte)count;
  2599. buf.DataLength = pos;
  2600. m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task);
  2601. }
  2602. }
  2603. public void SendAgentDataUpdate(UUID agentid, UUID activegroupid, string firstname, string lastname, ulong grouppowers, string groupname, string grouptitle)
  2604. {
  2605. if (agentid.Equals(m_agentId))
  2606. {
  2607. ActiveGroupId = activegroupid;
  2608. ActiveGroupName = groupname;
  2609. ActiveGroupPowers = grouppowers;
  2610. }
  2611. AgentDataUpdatePacket sendAgentDataUpdate = (AgentDataUpdatePacket)PacketPool.Instance.GetPacket(PacketType.AgentDataUpdate);
  2612. sendAgentDataUpdate.AgentData.ActiveGroupID = activegroupid;
  2613. sendAgentDataUpdate.AgentData.AgentID = agentid;
  2614. sendAgentDataUpdate.AgentData.FirstName = Util.StringToBytes256(firstname);
  2615. sendAgentDataUpdate.AgentData.GroupName = Util.StringToBytes256(groupname);
  2616. sendAgentDataUpdate.AgentData.GroupPowers = grouppowers;
  2617. sendAgentDataUpdate.AgentData.GroupTitle = Util.StringToBytes256(grouptitle);
  2618. sendAgentDataUpdate.AgentData.LastName = Util.StringToBytes256(lastname);
  2619. OutPacket(sendAgentDataUpdate, ThrottleOutPacketType.Task);
  2620. }
  2621. /// <summary>
  2622. /// Send an alert message to the client. This pops up a brief duration information box at a corner
  2623. /// </summary>
  2624. /// <param name="message"></param>
  2625. public void SendAlertMessage(string message)
  2626. {
  2627. AlertMessagePacket alertPack = (AlertMessagePacket)PacketPool.Instance.GetPacket(PacketType.AlertMessage);
  2628. //alertPack.AgentInfo = new AlertMessagePacket.AgentInfoBlock[1];
  2629. //alertPack.AgentInfo[0] = new AlertMessagePacket.AgentInfoBlock();
  2630. //alertPack.AgentInfo[0].AgentID = m_agentId;
  2631. alertPack.AlertData = new AlertMessagePacket.AlertDataBlock();
  2632. alertPack.AlertData.Message = Util.StringToBytes256(message);
  2633. alertPack.AlertInfo = new AlertMessagePacket.AlertInfoBlock[0];
  2634. OutPacket(alertPack, ThrottleOutPacketType.Task);
  2635. }
  2636. public void SendAlertMessage(string message, string info)
  2637. {
  2638. AlertMessagePacket alertPack = (AlertMessagePacket)PacketPool.Instance.GetPacket(PacketType.AlertMessage);
  2639. //alertPack.AgentInfo = new AlertMessagePacket.AgentInfoBlock[1];
  2640. //alertPack.AgentInfo[0] = new AlertMessagePacket.AgentInfoBlock();
  2641. //alertPack.AgentInfo[0].AgentID = m_agentId;
  2642. alertPack.AlertData = new AlertMessagePacket.AlertDataBlock();
  2643. alertPack.AlertData.Message = Util.StringToBytes256(message);
  2644. alertPack.AlertInfo = new AlertMessagePacket.AlertInfoBlock[1];
  2645. alertPack.AlertInfo[0] = new AlertMessagePacket.AlertInfoBlock();
  2646. alertPack.AlertInfo[0].Message = Util.StringToBytes256(info);
  2647. alertPack.AlertInfo[0].ExtraParams = Array.Empty<byte>();
  2648. OutPacket(alertPack, ThrottleOutPacketType.Task);
  2649. }
  2650. /// <summary>
  2651. /// Send an agent alert message to the client.
  2652. /// </summary>
  2653. /// <param name="message"></param>
  2654. /// <param name="modal">On the linden client, if this true then it displays a one button text box placed in the
  2655. /// middle of the window. If false, the message is displayed in a brief duration blue information box (as for
  2656. /// the AlertMessage packet).</param>
  2657. public void SendAgentAlertMessage(string message, bool modal)
  2658. {
  2659. // Prepend a slash to make the message come up in the top right
  2660. // again.
  2661. // Allow special formats to be sent from aware modules.
  2662. if (!modal && !message.StartsWith("ALERT: ") && !message.StartsWith("NOTIFY: ") && message != "Home position set." && message != "You died and have been teleported to your home location")
  2663. message = "/" + message;
  2664. AgentAlertMessagePacket alertPack = (AgentAlertMessagePacket)PacketPool.Instance.GetPacket(PacketType.AgentAlertMessage);
  2665. alertPack.AgentData.AgentID = m_agentId;
  2666. alertPack.AlertData.Message = Util.StringToBytes256(message);
  2667. alertPack.AlertData.Modal = modal;
  2668. OutPacket(alertPack, ThrottleOutPacketType.Task);
  2669. }
  2670. public void SendLoadURL(string objectname, UUID objectID, UUID ownerID, bool groupOwned, string message,
  2671. string url)
  2672. {
  2673. LoadURLPacket loadURL = (LoadURLPacket)PacketPool.Instance.GetPacket(PacketType.LoadURL);
  2674. loadURL.Data.ObjectName = Util.StringToBytes256(objectname);
  2675. loadURL.Data.ObjectID = objectID;
  2676. loadURL.Data.OwnerID = ownerID;
  2677. loadURL.Data.OwnerIsGroup = groupOwned;
  2678. loadURL.Data.Message = Util.StringToBytes256(message);
  2679. loadURL.Data.URL = Util.StringToBytes256(url);
  2680. OutPacket(loadURL, ThrottleOutPacketType.Task);
  2681. }
  2682. public void SendDialog(
  2683. string objectname, UUID objectID, UUID ownerID, string ownerFirstName, string ownerLastName, string msg,
  2684. UUID textureID, int ch, string[] buttonlabels)
  2685. {
  2686. ScriptDialogPacket dialog = (ScriptDialogPacket)PacketPool.Instance.GetPacket(PacketType.ScriptDialog);
  2687. dialog.Data.ObjectID = objectID;
  2688. dialog.Data.ObjectName = Util.StringToBytes256(objectname);
  2689. // this is the username of the *owner*
  2690. dialog.Data.FirstName = Util.StringToBytes256(ownerFirstName);
  2691. dialog.Data.LastName = Util.StringToBytes256(ownerLastName);
  2692. dialog.Data.Message = Util.StringToBytes(msg,512);
  2693. dialog.Data.ImageID = textureID;
  2694. dialog.Data.ChatChannel = ch;
  2695. ScriptDialogPacket.ButtonsBlock[] buttons = new ScriptDialogPacket.ButtonsBlock[buttonlabels.Length];
  2696. for (int i = 0; i < buttonlabels.Length; i++)
  2697. {
  2698. buttons[i] = new ScriptDialogPacket.ButtonsBlock();
  2699. buttons[i].ButtonLabel = Util.StringToBytes(buttonlabels[i],24);
  2700. }
  2701. dialog.Buttons = buttons;
  2702. dialog.OwnerData = new ScriptDialogPacket.OwnerDataBlock[1];
  2703. dialog.OwnerData[0] = new ScriptDialogPacket.OwnerDataBlock();
  2704. dialog.OwnerData[0].OwnerID = ownerID;
  2705. OutPacket(dialog, ThrottleOutPacketType.Task);
  2706. }
  2707. public void SendPreLoadSound(UUID objectID, UUID ownerID, UUID soundID)
  2708. {
  2709. PreloadSoundPacket preSound = (PreloadSoundPacket)PacketPool.Instance.GetPacket(PacketType.PreloadSound);
  2710. // TODO: don't create new blocks if recycling an old packet
  2711. preSound.DataBlock = new PreloadSoundPacket.DataBlockBlock[1];
  2712. preSound.DataBlock[0] = new PreloadSoundPacket.DataBlockBlock();
  2713. preSound.DataBlock[0].ObjectID = objectID;
  2714. preSound.DataBlock[0].OwnerID = ownerID;
  2715. preSound.DataBlock[0].SoundID = soundID;
  2716. preSound.Header.Zerocoded = true;
  2717. OutPacket(preSound, ThrottleOutPacketType.Task);
  2718. }
  2719. public void SendPlayAttachedSound(UUID soundID, UUID objectID, UUID ownerID, float gain, byte flags)
  2720. {
  2721. AttachedSoundPacket sound = (AttachedSoundPacket)PacketPool.Instance.GetPacket(PacketType.AttachedSound);
  2722. sound.DataBlock.SoundID = soundID;
  2723. sound.DataBlock.ObjectID = objectID;
  2724. sound.DataBlock.OwnerID = ownerID;
  2725. sound.DataBlock.Gain = gain;
  2726. sound.DataBlock.Flags = flags;
  2727. OutPacket(sound, ThrottleOutPacketType.Task);
  2728. }
  2729. public void SendTransferAbort(TransferRequestPacket transferRequest)
  2730. {
  2731. TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
  2732. abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
  2733. abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
  2734. m_log.Debug("[Assets] Aborting transfer; asset request failed");
  2735. OutPacket(abort, ThrottleOutPacketType.Task);
  2736. }
  2737. public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
  2738. {
  2739. SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
  2740. sound.SoundData.SoundID = soundID;
  2741. sound.SoundData.OwnerID = ownerID;
  2742. sound.SoundData.ObjectID = objectID;
  2743. sound.SoundData.ParentID = parentID;
  2744. sound.SoundData.Handle = handle;
  2745. sound.SoundData.Position = position;
  2746. sound.SoundData.Gain = gain;
  2747. OutPacket(sound, ThrottleOutPacketType.Task);
  2748. }
  2749. public void SendAttachedSoundGainChange(UUID objectID, float gain)
  2750. {
  2751. AttachedSoundGainChangePacket sound = (AttachedSoundGainChangePacket)PacketPool.Instance.GetPacket(PacketType.AttachedSoundGainChange);
  2752. sound.DataBlock.ObjectID = objectID;
  2753. sound.DataBlock.Gain = gain;
  2754. OutPacket(sound, ThrottleOutPacketType.Task);
  2755. }
  2756. public void SendViewerTime(Vector3 sunDir, float sunphase)
  2757. {
  2758. SimulatorViewerTimeMessagePacket viewertime = (SimulatorViewerTimeMessagePacket)PacketPool.Instance.GetPacket(PacketType.SimulatorViewerTimeMessage);
  2759. viewertime.TimeInfo.UsecSinceStart = Util.UnixTimeSinceEpoch_uS();
  2760. viewertime.TimeInfo.SunDirection = sunDir;
  2761. viewertime.TimeInfo.SunPhase = sunphase;
  2762. viewertime.TimeInfo.SunAngVelocity = Vector3.Zero; //legacy
  2763. viewertime.TimeInfo.SecPerDay = 14400; // legacy
  2764. viewertime.TimeInfo.SecPerYear = 158400; // legacy
  2765. viewertime.Header.Reliable = false;
  2766. viewertime.Header.Zerocoded = true;
  2767. OutPacket(viewertime, ThrottleOutPacketType.Task);
  2768. }
  2769. public void SendViewerEffect(ViewerEffectPacket.EffectBlock[] effectBlocks)
  2770. {
  2771. ViewerEffectPacket packet = (ViewerEffectPacket)PacketPool.Instance.GetPacket(PacketType.ViewerEffect);
  2772. // packet.AgentData.AgentID = m_agentId;
  2773. // packet.AgentData.SessionID = SessionId;
  2774. packet.Effect = effectBlocks;
  2775. // OutPacket(packet, ThrottleOutPacketType.State);
  2776. OutPacket(packet, ThrottleOutPacketType.Task);
  2777. }
  2778. public void SendAvatarProperties(UUID avatarID, string aboutText, string bornOn, Byte[] membershipType,
  2779. string flAbout, uint flags, UUID flImageID, UUID imageID, string profileURL,
  2780. UUID partnerID)
  2781. {
  2782. AvatarPropertiesReplyPacket avatarReply = (AvatarPropertiesReplyPacket)PacketPool.Instance.GetPacket(PacketType.AvatarPropertiesReply);
  2783. avatarReply.AgentData.AgentID = m_agentId;
  2784. avatarReply.AgentData.AvatarID = avatarID;
  2785. if (aboutText != null)
  2786. avatarReply.PropertiesData.AboutText = Util.StringToBytes1024(aboutText);
  2787. else
  2788. avatarReply.PropertiesData.AboutText = Utils.EmptyBytes;
  2789. avatarReply.PropertiesData.BornOn = Util.StringToBytes256(bornOn);
  2790. avatarReply.PropertiesData.CharterMember = membershipType;
  2791. if (flAbout != null)
  2792. avatarReply.PropertiesData.FLAboutText = Util.StringToBytes256(flAbout);
  2793. else
  2794. avatarReply.PropertiesData.FLAboutText = Utils.EmptyBytes;
  2795. avatarReply.PropertiesData.Flags = flags;
  2796. avatarReply.PropertiesData.FLImageID = flImageID;
  2797. avatarReply.PropertiesData.ImageID = imageID;
  2798. avatarReply.PropertiesData.ProfileURL = Util.StringToBytes256(profileURL);
  2799. avatarReply.PropertiesData.PartnerID = partnerID;
  2800. OutPacket(avatarReply, ThrottleOutPacketType.Task);
  2801. }
  2802. /// <summary>
  2803. /// Send the client an Estate message blue box pop-down with a single OK button
  2804. /// </summary>
  2805. /// <param name="FromAvatarID"></param>
  2806. /// <param name="fromSessionID"></param>
  2807. /// <param name="FromAvatarName"></param>
  2808. /// <param name="Message"></param>
  2809. public void SendBlueBoxMessage(UUID FromAvatarID, String FromAvatarName, String Message)
  2810. {
  2811. if (!SceneAgent.IsChildAgent)
  2812. SendInstantMessage(new GridInstantMessage(null, FromAvatarID, FromAvatarName, m_agentId, 1, Message, false, new Vector3()));
  2813. //SendInstantMessage(FromAvatarID, fromSessionID, Message, m_agentId, SessionId, FromAvatarName, (byte)21,(uint) Util.UnixTimeSinceEpoch());
  2814. }
  2815. public void SendLogoutPacket()
  2816. {
  2817. // I know this is a bit of a hack, however there are times when you don't
  2818. // want to send this, but still need to do the rest of the shutdown process
  2819. // this method gets called from the packet server.. which makes it practically
  2820. // impossible to do any other way.
  2821. if (m_SendLogoutPacketWhenClosing)
  2822. {
  2823. LogoutReplyPacket logReply = (LogoutReplyPacket)PacketPool.Instance.GetPacket(PacketType.LogoutReply);
  2824. // TODO: don't create new blocks if recycling an old packet
  2825. logReply.AgentData.AgentID = m_agentId;
  2826. logReply.AgentData.SessionID = m_sessionId;
  2827. logReply.InventoryData = new LogoutReplyPacket.InventoryDataBlock[1];
  2828. logReply.InventoryData[0] = new LogoutReplyPacket.InventoryDataBlock();
  2829. logReply.InventoryData[0].ItemID = UUID.Zero;
  2830. OutPacket(logReply, ThrottleOutPacketType.Task);
  2831. }
  2832. }
  2833. public void SendHealth(float health)
  2834. {
  2835. HealthMessagePacket healthpacket = (HealthMessagePacket)PacketPool.Instance.GetPacket(PacketType.HealthMessage);
  2836. healthpacket.HealthData.Health = health;
  2837. OutPacket(healthpacket, ThrottleOutPacketType.Task);
  2838. }
  2839. public void SendAgentOnline(UUID[] agentIDs)
  2840. {
  2841. OnlineNotificationPacket onp = new OnlineNotificationPacket();
  2842. OnlineNotificationPacket.AgentBlockBlock[] onpb = new OnlineNotificationPacket.AgentBlockBlock[agentIDs.Length];
  2843. for (int i = 0; i < agentIDs.Length; i++)
  2844. {
  2845. OnlineNotificationPacket.AgentBlockBlock onpbl = new OnlineNotificationPacket.AgentBlockBlock();
  2846. onpbl.AgentID = agentIDs[i];
  2847. onpb[i] = onpbl;
  2848. }
  2849. onp.AgentBlock = onpb;
  2850. onp.Header.Reliable = true;
  2851. OutPacket(onp, ThrottleOutPacketType.Task);
  2852. }
  2853. public void SendAgentOffline(UUID[] agentIDs)
  2854. {
  2855. OfflineNotificationPacket offp = new OfflineNotificationPacket();
  2856. OfflineNotificationPacket.AgentBlockBlock[] offpb = new OfflineNotificationPacket.AgentBlockBlock[agentIDs.Length];
  2857. for (int i = 0; i < agentIDs.Length; i++)
  2858. {
  2859. OfflineNotificationPacket.AgentBlockBlock onpbl = new OfflineNotificationPacket.AgentBlockBlock();
  2860. onpbl.AgentID = agentIDs[i];
  2861. offpb[i] = onpbl;
  2862. }
  2863. offp.AgentBlock = offpb;
  2864. offp.Header.Reliable = true;
  2865. OutPacket(offp, ThrottleOutPacketType.Task);
  2866. }
  2867. public void SendFindAgent(UUID HunterID, UUID PreyID, double GlobalX, double GlobalY)
  2868. {
  2869. FindAgentPacket fap = new FindAgentPacket();
  2870. fap.AgentBlock.Hunter = HunterID;
  2871. fap.AgentBlock.Prey = PreyID;
  2872. fap.AgentBlock.SpaceIP = 0;
  2873. fap.LocationBlock = new FindAgentPacket.LocationBlockBlock[1];
  2874. fap.LocationBlock[0] = new FindAgentPacket.LocationBlockBlock();
  2875. fap.LocationBlock[0].GlobalX = GlobalX;
  2876. fap.LocationBlock[0].GlobalY = GlobalY;
  2877. OutPacket(fap, ThrottleOutPacketType.Task);
  2878. }
  2879. public void SendSitResponse(UUID TargetID, Vector3 OffsetPos,
  2880. Quaternion SitOrientation, bool autopilot,
  2881. Vector3 CameraAtOffset, Vector3 CameraEyeOffset, bool ForceMouseLook)
  2882. {
  2883. AvatarSitResponsePacket avatarSitResponse = new AvatarSitResponsePacket();
  2884. avatarSitResponse.SitObject.ID = TargetID;
  2885. avatarSitResponse.SitTransform.CameraAtOffset = CameraAtOffset;
  2886. avatarSitResponse.SitTransform.CameraEyeOffset = CameraEyeOffset;
  2887. avatarSitResponse.SitTransform.ForceMouselook = ForceMouseLook;
  2888. avatarSitResponse.SitTransform.AutoPilot = autopilot;
  2889. avatarSitResponse.SitTransform.SitPosition = OffsetPos;
  2890. avatarSitResponse.SitTransform.SitRotation = SitOrientation;
  2891. OutPacket(avatarSitResponse, ThrottleOutPacketType.Task);
  2892. }
  2893. public void SendAdminResponse(UUID Token, uint AdminLevel)
  2894. {
  2895. GrantGodlikePowersPacket respondPacket = new GrantGodlikePowersPacket();
  2896. GrantGodlikePowersPacket.GrantDataBlock gdb = new GrantGodlikePowersPacket.GrantDataBlock();
  2897. GrantGodlikePowersPacket.AgentDataBlock adb = new GrantGodlikePowersPacket.AgentDataBlock();
  2898. adb.AgentID = m_agentId;
  2899. adb.SessionID = m_sessionId; // More security
  2900. gdb.GodLevel = (byte)AdminLevel;
  2901. gdb.Token = Token;
  2902. //respondPacket.AgentData = (GrantGodlikePowersPacket.AgentDataBlock)ablock;
  2903. respondPacket.GrantData = gdb;
  2904. respondPacket.AgentData = adb;
  2905. OutPacket(respondPacket, ThrottleOutPacketType.Task);
  2906. }
  2907. public void SendGroupMembership(GroupMembershipData[] GroupMembership)
  2908. {
  2909. UpdateGroupMembership(GroupMembership);
  2910. SendAgentGroupDataUpdate(m_agentId, GroupMembership);
  2911. }
  2912. public void SendSelectedPartsProprieties(List<ISceneEntity> parts)
  2913. {
  2914. /* not in use
  2915. // udp part
  2916. ObjectPropertiesPacket packet =
  2917. (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties);
  2918. ObjectPropertiesPacket.ObjectDataBlock[] ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[parts.Count];
  2919. int i = 0;
  2920. foreach(SceneObjectPart sop in parts)
  2921. ObjectData[i++] = CreateObjectPropertiesBlock(sop);
  2922. packet.ObjectData = ObjectData;
  2923. packet.Header.Zerocoded = true;
  2924. // udp send splits this mega packets correctly
  2925. // mb later will avoid that to reduce gc stress
  2926. OutPacket(packet, ThrottleOutPacketType.Task, true);
  2927. // caps physics part
  2928. IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
  2929. if(eq == null)
  2930. return;
  2931. OSDArray array = new OSDArray();
  2932. foreach(SceneObjectPart sop in parts)
  2933. {
  2934. OSDMap physinfo = new OSDMap(6);
  2935. physinfo["LocalID"] = sop.LocalId;
  2936. physinfo["Density"] = sop.Density;
  2937. physinfo["Friction"] = sop.Friction;
  2938. physinfo["GravityMultiplier"] = sop.GravityModifier;
  2939. physinfo["Restitution"] = sop.Restitution;
  2940. physinfo["PhysicsShapeType"] = (int)sop.PhysicsShapeType;
  2941. array.Add(physinfo);
  2942. }
  2943. OSDMap llsdBody = new OSDMap(1);
  2944. llsdBody.Add("ObjectData", array);
  2945. eq.Enqueue(BuildEvent("ObjectPhysicsProperties", llsdBody),m_agentId);
  2946. */
  2947. }
  2948. public void SendPartPhysicsProprieties(ISceneEntity entity)
  2949. {
  2950. IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
  2951. if (eq == null)
  2952. return;
  2953. SceneObjectPart part = (SceneObjectPart)entity;
  2954. if (part == null)
  2955. return;
  2956. uint localid = part.LocalId;
  2957. byte physshapetype = part.PhysicsShapeType;
  2958. float density = part.Density;
  2959. float friction = part.Friction;
  2960. float bounce = part.Restitution;
  2961. float gravmod = part.GravityModifier;
  2962. eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod, m_agentId);
  2963. }
  2964. public void SendGroupNameReply(UUID groupLLUID, string GroupName)
  2965. {
  2966. UUIDGroupNameReplyPacket pack = new UUIDGroupNameReplyPacket();
  2967. UUIDGroupNameReplyPacket.UUIDNameBlockBlock[] uidnameblock = new UUIDGroupNameReplyPacket.UUIDNameBlockBlock[1];
  2968. UUIDGroupNameReplyPacket.UUIDNameBlockBlock uidnamebloc = new UUIDGroupNameReplyPacket.UUIDNameBlockBlock();
  2969. uidnamebloc.ID = groupLLUID;
  2970. uidnamebloc.GroupName = Util.StringToBytes256(GroupName);
  2971. uidnameblock[0] = uidnamebloc;
  2972. pack.UUIDNameBlock = uidnameblock;
  2973. OutPacket(pack, ThrottleOutPacketType.Task);
  2974. }
  2975. public void SendLandStatReply(uint reportType, uint requestFlags, uint resultCount, LandStatReportItem[] lsrpia)
  2976. {
  2977. IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
  2978. if (eq == null)
  2979. {
  2980. LandStatReplyPacket lsrp = new LandStatReplyPacket();
  2981. // LandStatReplyPacket.RequestDataBlock lsreqdpb = new LandStatReplyPacket.RequestDataBlock();
  2982. LandStatReplyPacket.ReportDataBlock[] lsrepdba = new LandStatReplyPacket.ReportDataBlock[lsrpia.Length];
  2983. //LandStatReplyPacket.ReportDataBlock lsrepdb = new LandStatReplyPacket.ReportDataBlock();
  2984. // lsrepdb.
  2985. lsrp.RequestData.ReportType = reportType;
  2986. lsrp.RequestData.RequestFlags = requestFlags;
  2987. lsrp.RequestData.TotalObjectCount = resultCount;
  2988. for (int i = 0; i < lsrpia.Length; i++)
  2989. {
  2990. LandStatReplyPacket.ReportDataBlock lsrepdb = new LandStatReplyPacket.ReportDataBlock();
  2991. lsrepdb.LocationX = lsrpia[i].LocationX;
  2992. lsrepdb.LocationY = lsrpia[i].LocationY;
  2993. lsrepdb.LocationZ = lsrpia[i].LocationZ;
  2994. lsrepdb.Score = lsrpia[i].Score;
  2995. lsrepdb.TaskID = lsrpia[i].TaskID;
  2996. lsrepdb.TaskLocalID = lsrpia[i].TaskLocalID;
  2997. lsrepdb.TaskName = Util.StringToBytes256(lsrpia[i].TaskName);
  2998. lsrepdb.OwnerName = Util.StringToBytes256(lsrpia[i].OwnerName);
  2999. lsrepdba[i] = lsrepdb;
  3000. }
  3001. lsrp.ReportData = lsrepdba;
  3002. OutPacket(lsrp, ThrottleOutPacketType.Task);
  3003. }
  3004. else
  3005. {
  3006. osUTF8 sb = eq.StartEvent("LandStatReply");
  3007. LLSDxmlEncode2.AddArrayAndMap("RequestData", sb);
  3008. LLSDxmlEncode2.AddElem("ReportType", reportType, sb);
  3009. LLSDxmlEncode2.AddElem("RequestFlags", requestFlags, sb);
  3010. LLSDxmlEncode2.AddElem("TotalObjectCount", (uint)lsrpia.Length, sb);
  3011. LLSDxmlEncode2.AddEndMapAndArray(sb);
  3012. if (lsrpia.Length > 0)
  3013. {
  3014. LLSDxmlEncode2.AddArray("ReportData", sb);
  3015. foreach (var item in lsrpia)
  3016. {
  3017. LLSDxmlEncode2.AddMap(sb);
  3018. LLSDxmlEncode2.AddElem("LocationX", item.LocationX, sb);
  3019. LLSDxmlEncode2.AddElem("LocationY", item.LocationY, sb);
  3020. LLSDxmlEncode2.AddElem("LocationZ", item.LocationZ, sb);
  3021. LLSDxmlEncode2.AddElem("OwnerName", item.OwnerName, sb);
  3022. LLSDxmlEncode2.AddElem("Score", item.Score, sb);
  3023. LLSDxmlEncode2.AddElem("TaskID", item.TaskID, sb);
  3024. LLSDxmlEncode2.AddElem("TaskLocalID", item.TaskLocalID, sb);
  3025. LLSDxmlEncode2.AddElem("TaskName", item.TaskName, sb);
  3026. LLSDxmlEncode2.AddEndMap(sb);
  3027. }
  3028. LLSDxmlEncode2.AddEndArray(sb);
  3029. LLSDxmlEncode2.AddArray("DataExtended", sb);
  3030. foreach (var item in lsrpia)
  3031. {
  3032. LLSDxmlEncode2.AddMap(sb);
  3033. LLSDxmlEncode2.AddElem("MonoScore", 0.0f, sb);
  3034. LLSDxmlEncode2.AddElem("OwnerID", item.OwnerID, sb);
  3035. LLSDxmlEncode2.AddElem("ParcelName", item.Parcel, sb);
  3036. LLSDxmlEncode2.AddElem("PublicURLs", item.Urls, sb);
  3037. LLSDxmlEncode2.AddElem("Size", (float)item.Bytes, sb);
  3038. LLSDxmlEncode2.AddElem("TimeStamp", item.Time, sb);
  3039. LLSDxmlEncode2.AddEndMap(sb);
  3040. }
  3041. LLSDxmlEncode2.AddEndArray(sb);
  3042. }
  3043. eq.Enqueue(eq.EndEventToBytes(sb), m_agentId);
  3044. }
  3045. }
  3046. public void SendScriptRunningReply(UUID objectID, UUID itemID, bool running)
  3047. {
  3048. ScriptRunningReplyPacket scriptRunningReply = new ScriptRunningReplyPacket();
  3049. scriptRunningReply.Script.ObjectID = objectID;
  3050. scriptRunningReply.Script.ItemID = itemID;
  3051. scriptRunningReply.Script.Running = running;
  3052. OutPacket(scriptRunningReply, ThrottleOutPacketType.Task);
  3053. }
  3054. public void SendAsset(AssetRequestToClient req)
  3055. {
  3056. if (req.AssetInf == null)
  3057. {
  3058. m_log.ErrorFormat("{0} Cannot send asset, because it is null", LogHeader);
  3059. return;
  3060. }
  3061. if (req.AssetInf.Data == null)
  3062. {
  3063. m_log.ErrorFormat("{0} Cannot send asset {1} ({2}), asset data is null",
  3064. LogHeader, req.AssetInf.ID, req.AssetInf.Metadata.ContentType);
  3065. return;
  3066. }
  3067. bool isWearable = false;
  3068. isWearable = ((AssetType) req.AssetInf.Type ==
  3069. AssetType.Bodypart || (AssetType) req.AssetInf.Type == AssetType.Clothing);
  3070. //m_log.Debug("sending asset " + req.RequestAssetID + ", iswearable: " + isWearable);
  3071. //if (isWearable)
  3072. // m_log.Debug((AssetType)req.AssetInf.Type);
  3073. TransferInfoPacket Transfer = new TransferInfoPacket();
  3074. Transfer.TransferInfo.ChannelType = 2;
  3075. Transfer.TransferInfo.Status = 0;
  3076. Transfer.TransferInfo.TargetType = 0;
  3077. if (req.AssetRequestSource == 2)
  3078. {
  3079. Transfer.TransferInfo.Params = new byte[20];
  3080. Array.Copy(req.RequestAssetID.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16);
  3081. int assType = req.AssetInf.Type;
  3082. Array.Copy(Utils.IntToBytes(assType), 0, Transfer.TransferInfo.Params, 16, 4);
  3083. }
  3084. else if (req.AssetRequestSource == 3)
  3085. {
  3086. Transfer.TransferInfo.Params = req.Params;
  3087. // Transfer.TransferInfo.Params = new byte[100];
  3088. //Array.Copy(req.RequestUser.AgentId.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16);
  3089. //Array.Copy(req.RequestUser.SessionId.GetBytes(), 0, Transfer.TransferInfo.Params, 16, 16);
  3090. }
  3091. Transfer.TransferInfo.Size = req.AssetInf.Data.Length;
  3092. Transfer.TransferInfo.TransferID = req.TransferRequestID;
  3093. Transfer.Header.Zerocoded = true;
  3094. OutPacket(Transfer, ThrottleOutPacketType.Asset);
  3095. if (req.NumPackets == 1)
  3096. {
  3097. TransferPacketPacket TransferPacket = new TransferPacketPacket();
  3098. TransferPacket.TransferData.Packet = 0;
  3099. TransferPacket.TransferData.ChannelType = 2;
  3100. TransferPacket.TransferData.TransferID = req.TransferRequestID;
  3101. TransferPacket.TransferData.Data = req.AssetInf.Data;
  3102. TransferPacket.TransferData.Status = 1;
  3103. TransferPacket.Header.Zerocoded = true;
  3104. OutPacket(TransferPacket, ThrottleOutPacketType.Asset);
  3105. }
  3106. else
  3107. {
  3108. int processedLength = 0;
  3109. // int maxChunkSize = Settings.MAX_PACKET_SIZE - 100;
  3110. int maxChunkSize = (int) MaxTransferBytesPerPacket;
  3111. int packetNumber = 0;
  3112. while (processedLength < req.AssetInf.Data.Length)
  3113. {
  3114. TransferPacketPacket TransferPacket = new TransferPacketPacket();
  3115. TransferPacket.TransferData.Packet = packetNumber;
  3116. TransferPacket.TransferData.ChannelType = 2;
  3117. TransferPacket.TransferData.TransferID = req.TransferRequestID;
  3118. int chunkSize = Math.Min(req.AssetInf.Data.Length - processedLength, maxChunkSize);
  3119. byte[] chunk = new byte[chunkSize];
  3120. Array.Copy(req.AssetInf.Data, processedLength, chunk, 0, chunk.Length);
  3121. TransferPacket.TransferData.Data = chunk;
  3122. // 0 indicates more packets to come, 1 indicates last packet
  3123. if (req.AssetInf.Data.Length - processedLength > maxChunkSize)
  3124. {
  3125. TransferPacket.TransferData.Status = 0;
  3126. }
  3127. else
  3128. {
  3129. TransferPacket.TransferData.Status = 1;
  3130. }
  3131. TransferPacket.Header.Zerocoded = true;
  3132. OutPacket(TransferPacket, ThrottleOutPacketType.Asset);
  3133. processedLength += chunkSize;
  3134. packetNumber++;
  3135. }
  3136. }
  3137. }
  3138. public void SendAssetNotFound(AssetRequestToClient req)
  3139. {
  3140. TransferInfoPacket Transfer = new TransferInfoPacket();
  3141. Transfer.TransferInfo.ChannelType = 2;
  3142. Transfer.TransferInfo.Status = -2;
  3143. Transfer.TransferInfo.TargetType = 0;
  3144. Transfer.TransferInfo.Params = req.Params;
  3145. Transfer.TransferInfo.Size = 0;
  3146. Transfer.TransferInfo.TransferID = req.TransferRequestID;
  3147. Transfer.Header.Zerocoded = true;
  3148. OutPacket(Transfer, ThrottleOutPacketType.Asset);
  3149. }
  3150. public void SendTexture(AssetBase TextureAsset)
  3151. {
  3152. }
  3153. public void SendRegionHandle(UUID regionID, ulong handle)
  3154. {
  3155. RegionIDAndHandleReplyPacket reply = (RegionIDAndHandleReplyPacket)PacketPool.Instance.GetPacket(PacketType.RegionIDAndHandleReply);
  3156. reply.ReplyBlock.RegionID = regionID;
  3157. reply.ReplyBlock.RegionHandle = handle;
  3158. OutPacket(reply, ThrottleOutPacketType.Land);
  3159. }
  3160. public void SendParcelInfo(RegionInfo info, LandData land, UUID parcelID, uint x, uint y)
  3161. {
  3162. ParcelInfoReplyPacket reply = (ParcelInfoReplyPacket)PacketPool.Instance.GetPacket(PacketType.ParcelInfoReply);
  3163. reply.AgentData.AgentID = m_agentId;
  3164. reply.Data.ParcelID = parcelID;
  3165. reply.Data.OwnerID = land.OwnerID;
  3166. reply.Data.Name = Utils.StringToBytes(land.Name);
  3167. if (land.Description != null && land.Description != String.Empty)
  3168. reply.Data.Desc = Utils.StringToBytes(land.Description.Substring(0, land.Description.Length > 254 ? 254: land.Description.Length));
  3169. else
  3170. reply.Data.Desc = Array.Empty<byte>();
  3171. reply.Data.ActualArea = land.Area;
  3172. reply.Data.BillableArea = land.Area; // TODO: what is this?
  3173. reply.Data.Flags = (byte)Util.ConvertAccessLevelToMaturity((byte)info.AccessLevel);
  3174. if((land.Flags & (uint)ParcelFlags.ForSale) != 0)
  3175. reply.Data.Flags |= (byte)((1 << 7));
  3176. if (land.IsGroupOwned)
  3177. reply.Data.Flags |= 0x04;
  3178. Vector3 pos = land.UserLocation;
  3179. if (pos.IsZero())
  3180. {
  3181. pos = (land.AABBMax + land.AABBMin) * 0.5f;
  3182. }
  3183. reply.Data.GlobalX = info.RegionLocX + x;
  3184. reply.Data.GlobalY = info.RegionLocY + y;
  3185. reply.Data.GlobalZ = pos.Z;
  3186. reply.Data.SimName = Utils.StringToBytes(info.RegionName);
  3187. reply.Data.SnapshotID = land.SnapshotID;
  3188. reply.Data.Dwell = land.Dwell;
  3189. reply.Data.SalePrice = land.SalePrice;
  3190. reply.Data.AuctionID = (int)land.AuctionID;
  3191. OutPacket(reply, ThrottleOutPacketType.Land);
  3192. }
  3193. public void SendScriptTeleportRequest(string objName, string simName, Vector3 pos, Vector3 lookAt)
  3194. {
  3195. ScriptTeleportRequestPacket packet = (ScriptTeleportRequestPacket)PacketPool.Instance.GetPacket(PacketType.ScriptTeleportRequest);
  3196. packet.Data.ObjectName = Utils.StringToBytes(objName);
  3197. packet.Data.SimName = Utils.StringToBytes(simName);
  3198. packet.Data.SimPosition = pos;
  3199. packet.Data.LookAt = lookAt;
  3200. OutPacket(packet, ThrottleOutPacketType.Task);
  3201. }
  3202. public void SendDirPlacesReply(UUID queryID, DirPlacesReplyData[] data)
  3203. {
  3204. DirPlacesReplyPacket packet = (DirPlacesReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirPlacesReply);
  3205. packet.AgentData = new DirPlacesReplyPacket.AgentDataBlock();
  3206. packet.QueryData = new DirPlacesReplyPacket.QueryDataBlock[1];
  3207. packet.QueryData[0] = new DirPlacesReplyPacket.QueryDataBlock();
  3208. packet.AgentData.AgentID = m_agentId;
  3209. packet.QueryData[0].QueryID = queryID;
  3210. DirPlacesReplyPacket.QueryRepliesBlock[] replies =
  3211. new DirPlacesReplyPacket.QueryRepliesBlock[0];
  3212. DirPlacesReplyPacket.StatusDataBlock[] status =
  3213. new DirPlacesReplyPacket.StatusDataBlock[0];
  3214. packet.QueryReplies = replies;
  3215. packet.StatusData = status;
  3216. foreach (DirPlacesReplyData d in data)
  3217. {
  3218. int idx = replies.Length;
  3219. Array.Resize(ref replies, idx + 1);
  3220. Array.Resize(ref status, idx + 1);
  3221. replies[idx] = new DirPlacesReplyPacket.QueryRepliesBlock();
  3222. status[idx] = new DirPlacesReplyPacket.StatusDataBlock();
  3223. replies[idx].ParcelID = d.parcelID;
  3224. replies[idx].Name = Utils.StringToBytes(d.name);
  3225. replies[idx].ForSale = d.forSale;
  3226. replies[idx].Auction = d.auction;
  3227. replies[idx].Dwell = d.dwell;
  3228. status[idx].Status = d.Status;
  3229. packet.QueryReplies = replies;
  3230. packet.StatusData = status;
  3231. if (packet.Length >= 1000)
  3232. {
  3233. OutPacket(packet, ThrottleOutPacketType.Task);
  3234. packet = (DirPlacesReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirPlacesReply);
  3235. packet.AgentData = new DirPlacesReplyPacket.AgentDataBlock();
  3236. packet.QueryData = new DirPlacesReplyPacket.QueryDataBlock[1];
  3237. packet.QueryData[0] = new DirPlacesReplyPacket.QueryDataBlock();
  3238. packet.AgentData.AgentID = m_agentId;
  3239. packet.QueryData[0].QueryID = queryID;
  3240. replies = new DirPlacesReplyPacket.QueryRepliesBlock[0];
  3241. status = new DirPlacesReplyPacket.StatusDataBlock[0];
  3242. }
  3243. }
  3244. if (replies.Length > 0 || data.Length == 0)
  3245. OutPacket(packet, ThrottleOutPacketType.Task);
  3246. }
  3247. public void SendDirPeopleReply(UUID queryID, DirPeopleReplyData[] data)
  3248. {
  3249. DirPeopleReplyPacket packet = (DirPeopleReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirPeopleReply);
  3250. packet.AgentData = new DirPeopleReplyPacket.AgentDataBlock();
  3251. packet.AgentData.AgentID = m_agentId;
  3252. packet.QueryData = new DirPeopleReplyPacket.QueryDataBlock();
  3253. packet.QueryData.QueryID = queryID;
  3254. packet.QueryReplies = new DirPeopleReplyPacket.QueryRepliesBlock[
  3255. data.Length];
  3256. int i = 0;
  3257. foreach (DirPeopleReplyData d in data)
  3258. {
  3259. packet.QueryReplies[i] = new DirPeopleReplyPacket.QueryRepliesBlock();
  3260. packet.QueryReplies[i].AgentID = d.agentID;
  3261. packet.QueryReplies[i].FirstName =
  3262. Utils.StringToBytes(d.firstName);
  3263. packet.QueryReplies[i].LastName =
  3264. Utils.StringToBytes(d.lastName);
  3265. packet.QueryReplies[i].Group =
  3266. Utils.StringToBytes(d.group);
  3267. packet.QueryReplies[i].Online = d.online;
  3268. packet.QueryReplies[i].Reputation = d.reputation;
  3269. i++;
  3270. }
  3271. OutPacket(packet, ThrottleOutPacketType.Task);
  3272. }
  3273. public void SendDirEventsReply(UUID queryID, DirEventsReplyData[] data)
  3274. {
  3275. DirEventsReplyPacket packet = (DirEventsReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirEventsReply);
  3276. packet.AgentData = new DirEventsReplyPacket.AgentDataBlock();
  3277. packet.AgentData.AgentID = m_agentId;
  3278. packet.QueryData = new DirEventsReplyPacket.QueryDataBlock();
  3279. packet.QueryData.QueryID = queryID;
  3280. packet.QueryReplies = new DirEventsReplyPacket.QueryRepliesBlock[data.Length];
  3281. packet.StatusData = new DirEventsReplyPacket.StatusDataBlock[data.Length];
  3282. int i = 0;
  3283. foreach (DirEventsReplyData d in data)
  3284. {
  3285. packet.QueryReplies[i] = new DirEventsReplyPacket.QueryRepliesBlock();
  3286. packet.StatusData[i] = new DirEventsReplyPacket.StatusDataBlock();
  3287. packet.QueryReplies[i].OwnerID = d.ownerID;
  3288. packet.QueryReplies[i].Name = Utils.StringToBytes(d.name);
  3289. packet.QueryReplies[i].EventID = d.eventID;
  3290. packet.QueryReplies[i].Date = Utils.StringToBytes(d.date);
  3291. packet.QueryReplies[i].UnixTime = d.unixTime;
  3292. packet.QueryReplies[i].EventFlags = d.eventFlags;
  3293. packet.StatusData[i].Status = d.Status;
  3294. i++;
  3295. }
  3296. OutPacket(packet, ThrottleOutPacketType.Task);
  3297. }
  3298. public void SendDirGroupsReply(UUID queryID, DirGroupsReplyData[] data)
  3299. {
  3300. DirGroupsReplyPacket packet = (DirGroupsReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirGroupsReply);
  3301. packet.AgentData = new DirGroupsReplyPacket.AgentDataBlock();
  3302. packet.AgentData.AgentID = m_agentId;
  3303. packet.QueryData = new DirGroupsReplyPacket.QueryDataBlock();
  3304. packet.QueryData.QueryID = queryID;
  3305. packet.QueryReplies = new DirGroupsReplyPacket.QueryRepliesBlock[data.Length];
  3306. int i = 0;
  3307. foreach (DirGroupsReplyData d in data)
  3308. {
  3309. packet.QueryReplies[i] = new DirGroupsReplyPacket.QueryRepliesBlock();
  3310. packet.QueryReplies[i].GroupID = d.groupID;
  3311. packet.QueryReplies[i].GroupName = Util.StringToBytes(d.groupName, 35);
  3312. packet.QueryReplies[i].Members = d.members;
  3313. packet.QueryReplies[i].SearchOrder = d.searchOrder;
  3314. ++i;
  3315. }
  3316. OutPacket(packet, ThrottleOutPacketType.Task);
  3317. }
  3318. public void SendDirClassifiedReply(UUID queryID, DirClassifiedReplyData[] data)
  3319. {
  3320. DirClassifiedReplyPacket packet = (DirClassifiedReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirClassifiedReply);
  3321. packet.AgentData = new DirClassifiedReplyPacket.AgentDataBlock();
  3322. packet.AgentData.AgentID = m_agentId;
  3323. packet.QueryData = new DirClassifiedReplyPacket.QueryDataBlock();
  3324. packet.QueryData.QueryID = queryID;
  3325. packet.QueryReplies = new DirClassifiedReplyPacket.QueryRepliesBlock[data.Length];
  3326. packet.StatusData = new DirClassifiedReplyPacket.StatusDataBlock[data.Length];
  3327. int i = 0;
  3328. foreach (DirClassifiedReplyData d in data)
  3329. {
  3330. packet.QueryReplies[i] = new DirClassifiedReplyPacket.QueryRepliesBlock();
  3331. packet.StatusData[i] = new DirClassifiedReplyPacket.StatusDataBlock();
  3332. packet.QueryReplies[i].ClassifiedID = d.classifiedID;
  3333. packet.QueryReplies[i].Name = Utils.StringToBytes(d.name);
  3334. packet.QueryReplies[i].ClassifiedFlags = d.classifiedFlags;
  3335. packet.QueryReplies[i].CreationDate = d.creationDate;
  3336. packet.QueryReplies[i].ExpirationDate = d.expirationDate;
  3337. packet.QueryReplies[i].PriceForListing = d.price;
  3338. packet.StatusData[i].Status = d.Status;
  3339. i++;
  3340. }
  3341. OutPacket(packet, ThrottleOutPacketType.Task);
  3342. }
  3343. public void SendDirLandReply(UUID queryID, DirLandReplyData[] data)
  3344. {
  3345. DirLandReplyPacket packet = (DirLandReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirLandReply);
  3346. packet.AgentData = new DirLandReplyPacket.AgentDataBlock();
  3347. packet.AgentData.AgentID = m_agentId;
  3348. packet.QueryData = new DirLandReplyPacket.QueryDataBlock();
  3349. packet.QueryData.QueryID = queryID;
  3350. packet.QueryReplies = new DirLandReplyPacket.QueryRepliesBlock[data.Length];
  3351. int i = 0;
  3352. foreach (DirLandReplyData d in data)
  3353. {
  3354. packet.QueryReplies[i] = new DirLandReplyPacket.QueryRepliesBlock();
  3355. packet.QueryReplies[i].ParcelID = d.parcelID;
  3356. packet.QueryReplies[i].Name = Utils.StringToBytes(d.name);
  3357. packet.QueryReplies[i].Auction = d.auction;
  3358. packet.QueryReplies[i].ForSale = d.forSale;
  3359. packet.QueryReplies[i].SalePrice = d.salePrice;
  3360. packet.QueryReplies[i].ActualArea = d.actualArea;
  3361. i++;
  3362. }
  3363. OutPacket(packet, ThrottleOutPacketType.Task);
  3364. }
  3365. public void SendDirPopularReply(UUID queryID, DirPopularReplyData[] data)
  3366. {
  3367. DirPopularReplyPacket packet = (DirPopularReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirPopularReply);
  3368. packet.AgentData = new DirPopularReplyPacket.AgentDataBlock();
  3369. packet.AgentData.AgentID = m_agentId;
  3370. packet.QueryData = new DirPopularReplyPacket.QueryDataBlock();
  3371. packet.QueryData.QueryID = queryID;
  3372. packet.QueryReplies = new DirPopularReplyPacket.QueryRepliesBlock[data.Length];
  3373. int i = 0;
  3374. foreach (DirPopularReplyData d in data)
  3375. {
  3376. packet.QueryReplies[i] = new DirPopularReplyPacket.QueryRepliesBlock();
  3377. packet.QueryReplies[i].ParcelID = d.parcelID;
  3378. packet.QueryReplies[i].Name = Utils.StringToBytes(d.name);
  3379. packet.QueryReplies[i].Dwell = d.dwell;
  3380. i++;
  3381. }
  3382. OutPacket(packet, ThrottleOutPacketType.Task);
  3383. }
  3384. public void SendEventInfoReply(EventData data)
  3385. {
  3386. EventInfoReplyPacket packet = (EventInfoReplyPacket)PacketPool.Instance.GetPacket(PacketType.EventInfoReply);
  3387. packet.AgentData = new EventInfoReplyPacket.AgentDataBlock();
  3388. packet.AgentData.AgentID = m_agentId;
  3389. packet.EventData = new EventInfoReplyPacket.EventDataBlock();
  3390. packet.EventData.EventID = data.eventID;
  3391. packet.EventData.Creator = Utils.StringToBytes(data.creator);
  3392. packet.EventData.Name = Utils.StringToBytes(data.name);
  3393. packet.EventData.Category = Utils.StringToBytes(data.category);
  3394. packet.EventData.Desc = Utils.StringToBytes(data.description);
  3395. packet.EventData.Date = Utils.StringToBytes(data.date);
  3396. packet.EventData.DateUTC = data.dateUTC;
  3397. packet.EventData.Duration = data.duration;
  3398. packet.EventData.Cover = data.cover;
  3399. packet.EventData.Amount = data.amount;
  3400. packet.EventData.SimName = Utils.StringToBytes(data.simName);
  3401. packet.EventData.GlobalPos = new Vector3d(data.globalPos);
  3402. packet.EventData.EventFlags = data.eventFlags;
  3403. OutPacket(packet, ThrottleOutPacketType.Task);
  3404. }
  3405. public void SendOfferCallingCard(UUID srcID, UUID transactionID)
  3406. {
  3407. // a bit special, as this uses AgentID to store the source instead
  3408. // of the destination. The destination (the receiver) goes into destID
  3409. OfferCallingCardPacket p = (OfferCallingCardPacket)PacketPool.Instance.GetPacket(PacketType.OfferCallingCard);
  3410. p.AgentData.AgentID = srcID;
  3411. p.AgentData.SessionID = UUID.Zero;
  3412. p.AgentBlock.DestID = m_agentId;
  3413. p.AgentBlock.TransactionID = transactionID;
  3414. OutPacket(p, ThrottleOutPacketType.Task);
  3415. }
  3416. public void SendAcceptCallingCard(UUID transactionID)
  3417. {
  3418. AcceptCallingCardPacket p = (AcceptCallingCardPacket)PacketPool.Instance.GetPacket(PacketType.AcceptCallingCard);
  3419. p.AgentData.AgentID = m_agentId;
  3420. p.AgentData.SessionID = UUID.Zero;
  3421. p.FolderData = new AcceptCallingCardPacket.FolderDataBlock[1];
  3422. p.FolderData[0] = new AcceptCallingCardPacket.FolderDataBlock();
  3423. p.FolderData[0].FolderID = UUID.Zero;
  3424. OutPacket(p, ThrottleOutPacketType.Task);
  3425. }
  3426. public void SendDeclineCallingCard(UUID transactionID)
  3427. {
  3428. DeclineCallingCardPacket p = (DeclineCallingCardPacket)PacketPool.Instance.GetPacket(PacketType.DeclineCallingCard);
  3429. p.AgentData.AgentID = m_agentId;
  3430. p.AgentData.SessionID = UUID.Zero;
  3431. p.TransactionBlock.TransactionID = transactionID;
  3432. OutPacket(p, ThrottleOutPacketType.Task);
  3433. }
  3434. public void SendTerminateFriend(UUID exFriendID)
  3435. {
  3436. TerminateFriendshipPacket p = (TerminateFriendshipPacket)PacketPool.Instance.GetPacket(PacketType.TerminateFriendship);
  3437. p.AgentData.AgentID = m_agentId;
  3438. p.AgentData.SessionID = SessionId;
  3439. p.ExBlock.OtherID = exFriendID;
  3440. OutPacket(p, ThrottleOutPacketType.Task);
  3441. }
  3442. public void SendAvatarGroupsReply(UUID avatarID, GroupMembershipData[] data)
  3443. {
  3444. IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
  3445. if (eq == null)
  3446. return;
  3447. // message template has a GroupData field AcceptNotices ignored by viewers
  3448. // and a array NewGroupData also ignored
  3449. osUTF8 sb = eq.StartEvent("AvatarGroupsReply");
  3450. LLSDxmlEncode2.AddArrayAndMap("AgentData", sb);
  3451. LLSDxmlEncode2.AddElem("AgentID", m_agentId, sb);
  3452. LLSDxmlEncode2.AddElem("AvatarID", avatarID, sb);
  3453. LLSDxmlEncode2.AddEndMapAndArray(sb);
  3454. bool notSameAvatar = avatarID != m_agentId;
  3455. if(data.Length == 0)
  3456. LLSDxmlEncode2.AddEmptyArray("GroupData", sb);
  3457. else
  3458. {
  3459. LLSDxmlEncode2.AddArray("GroupData", sb);
  3460. GroupMembershipData m;
  3461. for (int indx = 0; indx < data.Length; ++indx)
  3462. {
  3463. m = data[indx];
  3464. if(notSameAvatar && !m.ListInProfile)
  3465. continue;
  3466. LLSDxmlEncode2.AddMap(sb);
  3467. LLSDxmlEncode2.AddElem("GroupPowers", m.GroupPowers, sb);
  3468. LLSDxmlEncode2.AddElem("GroupTitle", m.GroupTitle, sb);
  3469. LLSDxmlEncode2.AddElem("GroupID",m.GroupID, sb);
  3470. LLSDxmlEncode2.AddElem("GroupName", m.GroupName, sb);
  3471. LLSDxmlEncode2.AddElem("GroupInsigniaID", m.GroupPicture, sb);
  3472. LLSDxmlEncode2.AddEndMap(sb);
  3473. }
  3474. LLSDxmlEncode2.AddEndArray(sb);
  3475. }
  3476. eq.Enqueue(eq.EndEventToBytes(sb), m_agentId);
  3477. }
  3478. public void SendAgentGroupDataUpdate(UUID avatarID, GroupMembershipData[] data)
  3479. {
  3480. if(avatarID != m_agentId)
  3481. m_log.Debug("[CLIENT]: SendAgentGroupDataUpdate avatarID != AgentId");
  3482. IEventQueue eq = this.Scene.RequestModuleInterface<IEventQueue>();
  3483. if(eq != null)
  3484. {
  3485. eq.GroupMembershipData(avatarID,data);
  3486. }
  3487. else
  3488. {
  3489. // use UDP if no caps
  3490. AgentGroupDataUpdatePacket Groupupdate = new AgentGroupDataUpdatePacket();
  3491. AgentGroupDataUpdatePacket.GroupDataBlock[] Groups = new AgentGroupDataUpdatePacket.GroupDataBlock[data.Length];
  3492. for (int i = 0; i < data.Length; ++i)
  3493. {
  3494. AgentGroupDataUpdatePacket.GroupDataBlock Group = new AgentGroupDataUpdatePacket.GroupDataBlock();
  3495. Group.AcceptNotices = data[i].AcceptNotices;
  3496. Group.Contribution = data[i].Contribution;
  3497. Group.GroupID = data[i].GroupID;
  3498. Group.GroupInsigniaID = data[i].GroupPicture;
  3499. Group.GroupName = Util.StringToBytes256(data[i].GroupName);
  3500. Group.GroupPowers = data[i].GroupPowers;
  3501. Groups[i] = Group;
  3502. }
  3503. Groupupdate.GroupData = Groups;
  3504. Groupupdate.AgentData = new AgentGroupDataUpdatePacket.AgentDataBlock();
  3505. Groupupdate.AgentData.AgentID = avatarID;
  3506. OutPacket(Groupupdate, ThrottleOutPacketType.Task);
  3507. }
  3508. }
  3509. public void SendJoinGroupReply(UUID groupID, bool success)
  3510. {
  3511. JoinGroupReplyPacket p = (JoinGroupReplyPacket)PacketPool.Instance.GetPacket(PacketType.JoinGroupReply);
  3512. p.AgentData = new JoinGroupReplyPacket.AgentDataBlock();
  3513. p.AgentData.AgentID = m_agentId;
  3514. p.GroupData = new JoinGroupReplyPacket.GroupDataBlock();
  3515. p.GroupData.GroupID = groupID;
  3516. p.GroupData.Success = success;
  3517. OutPacket(p, ThrottleOutPacketType.Task);
  3518. }
  3519. public void SendEjectGroupMemberReply(UUID agentID, UUID groupID, bool success)
  3520. {
  3521. EjectGroupMemberReplyPacket p = (EjectGroupMemberReplyPacket)PacketPool.Instance.GetPacket(PacketType.EjectGroupMemberReply);
  3522. p.AgentData = new EjectGroupMemberReplyPacket.AgentDataBlock();
  3523. p.AgentData.AgentID = agentID;
  3524. p.GroupData = new EjectGroupMemberReplyPacket.GroupDataBlock();
  3525. p.GroupData.GroupID = groupID;
  3526. p.EjectData = new EjectGroupMemberReplyPacket.EjectDataBlock();
  3527. p.EjectData.Success = success;
  3528. OutPacket(p, ThrottleOutPacketType.Task);
  3529. }
  3530. public void SendLeaveGroupReply(UUID groupID, bool success)
  3531. {
  3532. LeaveGroupReplyPacket p = (LeaveGroupReplyPacket)PacketPool.Instance.GetPacket(PacketType.LeaveGroupReply);
  3533. p.AgentData = new LeaveGroupReplyPacket.AgentDataBlock();
  3534. p.AgentData.AgentID = m_agentId;
  3535. p.GroupData = new LeaveGroupReplyPacket.GroupDataBlock();
  3536. p.GroupData.GroupID = groupID;
  3537. p.GroupData.Success = success;
  3538. OutPacket(p, ThrottleOutPacketType.Task);
  3539. }
  3540. public void SendAvatarClassifiedReply(UUID targetID, UUID[] classifiedID, string[] name)
  3541. {
  3542. if (classifiedID.Length != name.Length)
  3543. return;
  3544. AvatarClassifiedReplyPacket ac =
  3545. (AvatarClassifiedReplyPacket)PacketPool.Instance.GetPacket(PacketType.AvatarClassifiedReply);
  3546. ac.AgentData = new AvatarClassifiedReplyPacket.AgentDataBlock();
  3547. ac.AgentData.AgentID = m_agentId;
  3548. ac.AgentData.TargetID = targetID;
  3549. ac.Data = new AvatarClassifiedReplyPacket.DataBlock[classifiedID.Length];
  3550. int i;
  3551. for (i = 0; i < classifiedID.Length; i++)
  3552. {
  3553. ac.Data[i].ClassifiedID = classifiedID[i];
  3554. ac.Data[i].Name = Utils.StringToBytes(name[i]);
  3555. }
  3556. OutPacket(ac, ThrottleOutPacketType.Task);
  3557. }
  3558. public void SendClassifiedInfoReply(UUID classifiedID, UUID creatorID, uint creationDate, uint expirationDate, uint category, string name, string description, UUID parcelID, uint parentEstate, UUID snapshotID, string simName, Vector3 globalPos, string parcelName, byte classifiedFlags, int price)
  3559. {
  3560. // fix classifiedFlags maturity
  3561. if((classifiedFlags & 0x4e) == 0) // if none
  3562. classifiedFlags |= 0x4; // pg
  3563. ClassifiedInfoReplyPacket cr =
  3564. (ClassifiedInfoReplyPacket)PacketPool.Instance.GetPacket(PacketType.ClassifiedInfoReply);
  3565. cr.AgentData = new ClassifiedInfoReplyPacket.AgentDataBlock();
  3566. cr.AgentData.AgentID = m_agentId;
  3567. cr.Data = new ClassifiedInfoReplyPacket.DataBlock();
  3568. cr.Data.ClassifiedID = classifiedID;
  3569. cr.Data.CreatorID = creatorID;
  3570. cr.Data.CreationDate = creationDate;
  3571. cr.Data.ExpirationDate = expirationDate;
  3572. cr.Data.Category = category;
  3573. cr.Data.Name = Utils.StringToBytes(name);
  3574. cr.Data.Desc = Utils.StringToBytes(description);
  3575. cr.Data.ParcelID = parcelID;
  3576. cr.Data.ParentEstate = parentEstate;
  3577. cr.Data.SnapshotID = snapshotID;
  3578. cr.Data.SimName = Utils.StringToBytes(simName);
  3579. cr.Data.PosGlobal = new Vector3d(globalPos);
  3580. cr.Data.ParcelName = Utils.StringToBytes(parcelName);
  3581. cr.Data.ClassifiedFlags = classifiedFlags;
  3582. cr.Data.PriceForListing = price;
  3583. OutPacket(cr, ThrottleOutPacketType.Task);
  3584. }
  3585. public void SendAgentDropGroup(UUID groupID)
  3586. {
  3587. AgentDropGroupPacket dg =
  3588. (AgentDropGroupPacket)PacketPool.Instance.GetPacket(
  3589. PacketType.AgentDropGroup);
  3590. dg.AgentData = new AgentDropGroupPacket.AgentDataBlock();
  3591. dg.AgentData.AgentID = m_agentId;
  3592. dg.AgentData.GroupID = groupID;
  3593. OutPacket(dg, ThrottleOutPacketType.Task);
  3594. }
  3595. public void SendAvatarNotesReply(UUID targetID, string text)
  3596. {
  3597. AvatarNotesReplyPacket an =
  3598. (AvatarNotesReplyPacket)PacketPool.Instance.GetPacket(PacketType.AvatarNotesReply);
  3599. an.AgentData = new AvatarNotesReplyPacket.AgentDataBlock();
  3600. an.AgentData.AgentID = m_agentId;
  3601. an.Data = new AvatarNotesReplyPacket.DataBlock();
  3602. an.Data.TargetID = targetID;
  3603. an.Data.Notes = Utils.StringToBytes(text);
  3604. OutPacket(an, ThrottleOutPacketType.Task);
  3605. }
  3606. public void SendAvatarPicksReply(UUID targetID, Dictionary<UUID, string> picks)
  3607. {
  3608. AvatarPicksReplyPacket ap =
  3609. (AvatarPicksReplyPacket)PacketPool.Instance.GetPacket(PacketType.AvatarPicksReply);
  3610. ap.AgentData = new AvatarPicksReplyPacket.AgentDataBlock();
  3611. ap.AgentData.AgentID = m_agentId;
  3612. ap.AgentData.TargetID = targetID;
  3613. ap.Data = new AvatarPicksReplyPacket.DataBlock[picks.Count];
  3614. int i = 0;
  3615. foreach (KeyValuePair<UUID, string> pick in picks)
  3616. {
  3617. ap.Data[i] = new AvatarPicksReplyPacket.DataBlock();
  3618. ap.Data[i].PickID = pick.Key;
  3619. ap.Data[i].PickName = Utils.StringToBytes(pick.Value);
  3620. i++;
  3621. }
  3622. OutPacket(ap, ThrottleOutPacketType.Task);
  3623. }
  3624. public void SendAvatarClassifiedReply(UUID targetID, Dictionary<UUID, string> classifieds)
  3625. {
  3626. AvatarClassifiedReplyPacket ac =
  3627. (AvatarClassifiedReplyPacket)PacketPool.Instance.GetPacket(PacketType.AvatarClassifiedReply);
  3628. ac.AgentData = new AvatarClassifiedReplyPacket.AgentDataBlock();
  3629. ac.AgentData.AgentID = m_agentId;
  3630. ac.AgentData.TargetID = targetID;
  3631. ac.Data = new AvatarClassifiedReplyPacket.DataBlock[classifieds.Count];
  3632. int i = 0;
  3633. foreach (KeyValuePair<UUID, string> classified in classifieds)
  3634. {
  3635. ac.Data[i] = new AvatarClassifiedReplyPacket.DataBlock();
  3636. ac.Data[i].ClassifiedID = classified.Key;
  3637. ac.Data[i].Name = Utils.StringToBytes(classified.Value);
  3638. i++;
  3639. }
  3640. OutPacket(ac, ThrottleOutPacketType.Task);
  3641. }
  3642. public void SendParcelDwellReply(int localID, UUID parcelID, float dwell)
  3643. {
  3644. ParcelDwellReplyPacket pd =
  3645. (ParcelDwellReplyPacket)PacketPool.Instance.GetPacket(PacketType.ParcelDwellReply);
  3646. pd.AgentData = new ParcelDwellReplyPacket.AgentDataBlock();
  3647. pd.AgentData.AgentID = m_agentId;
  3648. pd.Data = new ParcelDwellReplyPacket.DataBlock();
  3649. pd.Data.LocalID = localID;
  3650. pd.Data.ParcelID = parcelID;
  3651. pd.Data.Dwell = dwell;
  3652. OutPacket(pd, ThrottleOutPacketType.Land);
  3653. }
  3654. public void SendUserInfoReply(bool imViaEmail, bool visible, string email)
  3655. {
  3656. UserInfoReplyPacket ur =
  3657. (UserInfoReplyPacket)PacketPool.Instance.GetPacket(PacketType.UserInfoReply);
  3658. ur.AgentData = new UserInfoReplyPacket.AgentDataBlock();
  3659. ur.AgentData.AgentID = m_agentId;
  3660. ur.UserData = new UserInfoReplyPacket.UserDataBlock();
  3661. ur.UserData.IMViaEMail = imViaEmail;
  3662. ur.UserData.DirectoryVisibility = Utils.StringToBytes(visible ? "default" : "hidden");
  3663. ur.UserData.EMail = Utils.StringToBytes(email);
  3664. OutPacket(ur, ThrottleOutPacketType.Task);
  3665. }
  3666. public void SendCreateGroupReply(UUID groupID, bool success, string message)
  3667. {
  3668. CreateGroupReplyPacket createGroupReply = (CreateGroupReplyPacket)PacketPool.Instance.GetPacket(PacketType.CreateGroupReply);
  3669. createGroupReply.AgentData = new CreateGroupReplyPacket.AgentDataBlock();
  3670. createGroupReply.ReplyData = new CreateGroupReplyPacket.ReplyDataBlock();
  3671. createGroupReply.AgentData.AgentID = m_agentId;
  3672. createGroupReply.ReplyData.GroupID = groupID;
  3673. createGroupReply.ReplyData.Success = success;
  3674. createGroupReply.ReplyData.Message = Utils.StringToBytes(message);
  3675. OutPacket(createGroupReply, ThrottleOutPacketType.Task);
  3676. }
  3677. public void SendUseCachedMuteList()
  3678. {
  3679. UseCachedMuteListPacket useCachedMuteList = (UseCachedMuteListPacket)PacketPool.Instance.GetPacket(PacketType.UseCachedMuteList);
  3680. useCachedMuteList.AgentData = new UseCachedMuteListPacket.AgentDataBlock();
  3681. useCachedMuteList.AgentData.AgentID = m_agentId;
  3682. OutPacket(useCachedMuteList, ThrottleOutPacketType.Task);
  3683. }
  3684. public void SendEmpytMuteList()
  3685. {
  3686. GenericMessagePacket gmp = new GenericMessagePacket();
  3687. gmp.AgentData.AgentID = m_agentId;
  3688. gmp.AgentData.SessionID = m_sessionId;
  3689. gmp.AgentData.TransactionID = UUID.Zero;
  3690. gmp.MethodData.Method = Util.StringToBytes256("emptymutelist");
  3691. gmp.ParamList = new GenericMessagePacket.ParamListBlock[1];
  3692. gmp.ParamList[0] = new GenericMessagePacket.ParamListBlock();
  3693. gmp.ParamList[0].Parameter = Array.Empty<byte>();
  3694. OutPacket(gmp, ThrottleOutPacketType.Task);
  3695. }
  3696. public void SendMuteListUpdate(string filename)
  3697. {
  3698. MuteListUpdatePacket muteListUpdate = (MuteListUpdatePacket)PacketPool.Instance.GetPacket(PacketType.MuteListUpdate);
  3699. muteListUpdate.MuteData = new MuteListUpdatePacket.MuteDataBlock();
  3700. muteListUpdate.MuteData.AgentID = m_agentId;
  3701. muteListUpdate.MuteData.Filename = Utils.StringToBytes(filename);
  3702. OutPacket(muteListUpdate, ThrottleOutPacketType.Task);
  3703. }
  3704. public void SendPickInfoReply(UUID pickID, UUID creatorID, bool topPick, UUID parcelID, string name, string desc, UUID snapshotID, string user, string originalName, string simName, Vector3 posGlobal, int sortOrder, bool enabled)
  3705. {
  3706. PickInfoReplyPacket pickInfoReply = (PickInfoReplyPacket)PacketPool.Instance.GetPacket(PacketType.PickInfoReply);
  3707. pickInfoReply.AgentData = new PickInfoReplyPacket.AgentDataBlock();
  3708. pickInfoReply.AgentData.AgentID = m_agentId;
  3709. pickInfoReply.Data = new PickInfoReplyPacket.DataBlock();
  3710. pickInfoReply.Data.PickID = pickID;
  3711. pickInfoReply.Data.CreatorID = creatorID;
  3712. pickInfoReply.Data.TopPick = topPick;
  3713. pickInfoReply.Data.ParcelID = parcelID;
  3714. pickInfoReply.Data.Name = Utils.StringToBytes(name);
  3715. pickInfoReply.Data.Desc = Utils.StringToBytes(desc);
  3716. pickInfoReply.Data.SnapshotID = snapshotID;
  3717. pickInfoReply.Data.User = Utils.StringToBytes(user);
  3718. pickInfoReply.Data.OriginalName = Utils.StringToBytes(originalName);
  3719. pickInfoReply.Data.SimName = Utils.StringToBytes(simName);
  3720. pickInfoReply.Data.PosGlobal = new Vector3d(posGlobal);
  3721. pickInfoReply.Data.SortOrder = sortOrder;
  3722. pickInfoReply.Data.Enabled = enabled;
  3723. OutPacket(pickInfoReply, ThrottleOutPacketType.Task);
  3724. }
  3725. #endregion Scene/Avatar to Client
  3726. // Gesture
  3727. #region Appearance/ Wearables Methods
  3728. public void SendWearables(AvatarWearable[] wearables, int serial)
  3729. {
  3730. AgentWearablesUpdatePacket aw = (AgentWearablesUpdatePacket)PacketPool.Instance.GetPacket(PacketType.AgentWearablesUpdate);
  3731. aw.AgentData.AgentID = m_agentId;
  3732. aw.AgentData.SerialNum = (uint)serial;
  3733. aw.AgentData.SessionID = m_sessionId;
  3734. int count = 0;
  3735. for (int i = 0; i < wearables.Length; i++)
  3736. count += wearables[i].Count;
  3737. // TODO: don't create new blocks if recycling an old packet
  3738. aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[count];
  3739. AgentWearablesUpdatePacket.WearableDataBlock awb;
  3740. int idx = 0;
  3741. for (int i = 0; i < wearables.Length; i++)
  3742. {
  3743. for (int j = 0; j < wearables[i].Count; j++)
  3744. {
  3745. awb = new AgentWearablesUpdatePacket.WearableDataBlock();
  3746. awb.WearableType = (byte) i;
  3747. awb.AssetID = wearables[i][j].AssetID;
  3748. awb.ItemID = wearables[i][j].ItemID;
  3749. aw.WearableData[idx] = awb;
  3750. idx++;
  3751. //m_log.DebugFormat(
  3752. // "[APPEARANCE]: Sending wearable item/asset {0} {1} (index {2}) for {3}",
  3753. // awb.ItemID, awb.AssetID, i, Name);
  3754. }
  3755. }
  3756. OutPacket(aw, ThrottleOutPacketType.Task);
  3757. }
  3758. static private readonly byte[] AvatarAppearanceHeader = new byte[] {
  3759. Helpers.MSG_RELIABLE | Helpers.MSG_ZEROCODED,
  3760. 0, 0, 0, 0, // sequence number
  3761. 0, // extra
  3762. 0xff, 0xff, 0, 158 // ID 158 (low frequency bigendian) not zeroencoded
  3763. //0xff, 0xff, 0, 1, 158 // ID 158 (low frequency bigendian) zeroencoded
  3764. };
  3765. public void SendAppearance(UUID targetID, byte[] visualParams, byte[] textureEntry, float hover)
  3766. {
  3767. // doing post zero encode, because odds of beeing bad are not that low
  3768. UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
  3769. Buffer.BlockCopy(AvatarAppearanceHeader, 0, buf.Data, 0, 10);
  3770. byte[] data = buf.Data;
  3771. int pos = 10;
  3772. //sender block
  3773. targetID.ToBytes(data, pos); pos += 16;
  3774. data[pos++] = 0;// is trial = false
  3775. // objectdata block ie texture
  3776. int len = textureEntry.Length;
  3777. if (len == 0)
  3778. {
  3779. data[pos++] = 0;
  3780. data[pos++] = 0;
  3781. }
  3782. else
  3783. {
  3784. data[pos++] = (byte)len;
  3785. data[pos++] = (byte)(len >> 8);
  3786. Buffer.BlockCopy(textureEntry, 0, data, pos, len); pos += len;
  3787. }
  3788. // visual parameters
  3789. len = visualParams.Length;
  3790. data[pos++] = (byte)len;
  3791. if(len > 0)
  3792. Buffer.BlockCopy(visualParams, 0, data, pos, len); pos += len;
  3793. // no AppearanceData
  3794. data[pos++] = 0;
  3795. // AppearanceHover vector 3
  3796. data[pos++] = 1;
  3797. Utils.FloatToBytesSafepos(0, data, pos); pos += 4;
  3798. Utils.FloatToBytesSafepos(0, data, pos); pos += 4;
  3799. Utils.FloatToBytesSafepos(hover, data, pos); pos += 4;
  3800. buf.DataLength = pos;
  3801. m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task, null, true);
  3802. }
  3803. static private readonly byte[] AvatarAnimationHeader = new byte[] {
  3804. Helpers.MSG_RELIABLE,
  3805. 0, 0, 0, 0, // sequence number
  3806. 0, // extra
  3807. 20 // ID (high frequency)
  3808. };
  3809. public void SendAnimations(UUID[] animations, int[] seqs, UUID sourceAgentId, UUID[] objectIDs)
  3810. {
  3811. // m_log.DebugFormat("[LLCLIENTVIEW]: Sending animations for {0} to {1}", sourceAgentId, Name);
  3812. UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
  3813. byte[] data = buf.Data;
  3814. //setup header
  3815. Buffer.BlockCopy(AvatarAnimationHeader, 0, data, 0, 7);
  3816. //agent block
  3817. sourceAgentId.ToBytes(data, 7);
  3818. // animations count
  3819. data[23] = (byte)animations.Length;
  3820. int pos = 24;
  3821. //self animations
  3822. if (sourceAgentId.Equals(m_agentId))
  3823. {
  3824. List<int> withobjects = new List<int>(animations.Length);
  3825. List<int> noobjects = new List<int>(animations.Length);
  3826. for (int indx = 0; indx < animations.Length; ++indx)
  3827. {
  3828. if (objectIDs[indx].Equals(sourceAgentId) || objectIDs[indx].IsZero())
  3829. noobjects.Add(indx);
  3830. else
  3831. withobjects.Add(indx);
  3832. }
  3833. int i;
  3834. // first the ones with corresponding objects
  3835. for (int indx = 0; indx < withobjects.Count; ++indx)
  3836. {
  3837. i = withobjects[indx];
  3838. animations[i].ToBytes(data, pos); pos += 16;
  3839. Utils.IntToBytesSafepos(seqs[i], data, pos); pos += 4;
  3840. }
  3841. // then the rest
  3842. for (int indx = 0; indx < noobjects.Count; ++indx)
  3843. {
  3844. i = noobjects[indx];
  3845. animations[i].ToBytes(data, pos); pos += 16;
  3846. Utils.IntToBytesSafepos(seqs[i], data, pos); pos += 4;
  3847. }
  3848. // object ids block
  3849. data[pos++] = (byte)withobjects.Count;
  3850. for (int indx = 0; indx < withobjects.Count; ++indx)
  3851. {
  3852. i = withobjects[indx];
  3853. objectIDs[i].ToBytes(data, pos); pos += 16;
  3854. }
  3855. }
  3856. else
  3857. {
  3858. for(int i = 0; i < animations.Length; ++i)
  3859. {
  3860. animations[i].ToBytes(data, pos); pos += 16;
  3861. Utils.IntToBytesSafepos(seqs[i], data, pos); pos += 4;
  3862. }
  3863. data[pos++] = 0; // no object ids
  3864. }
  3865. data[pos++] = 0; // no physical avatar events
  3866. buf.DataLength = pos;
  3867. m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task);
  3868. }
  3869. public void SendObjectAnimations(UUID[] animations, int[] seqs, UUID senderId)
  3870. {
  3871. // m_log.DebugFormat("[LLCLIENTVIEW]: Sending Object animations for {0} to {1}", sourceAgentId, Name);
  3872. if(!m_SupportObjectAnimations)
  3873. return;
  3874. ObjectAnimationPacket ani = (ObjectAnimationPacket)PacketPool.Instance.GetPacket(PacketType.ObjectAnimation);
  3875. // TODO: don't create new blocks if recycling an old packet
  3876. ani.Sender = new ObjectAnimationPacket.SenderBlock();
  3877. ani.Sender.ID = senderId;
  3878. ani.AnimationList = new ObjectAnimationPacket.AnimationListBlock[animations.Length];
  3879. for (int i = 0; i < animations.Length; ++i)
  3880. {
  3881. ani.AnimationList[i] = new ObjectAnimationPacket.AnimationListBlock();
  3882. ani.AnimationList[i].AnimID = animations[i];
  3883. ani.AnimationList[i].AnimSequenceID = seqs[i];
  3884. }
  3885. OutPacket(ani, ThrottleOutPacketType.Task);
  3886. }
  3887. #endregion
  3888. #region Avatar Packet/Data Sending Methods
  3889. /// <summary>
  3890. /// Send an ObjectUpdate packet with information about an avatar
  3891. /// </summary>
  3892. public void SendEntityFullUpdateImmediate(ISceneEntity ent)
  3893. {
  3894. if (ent == null || (!(ent is ScenePresence) && !(ent is SceneObjectPart)))
  3895. return;
  3896. UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
  3897. Buffer.BlockCopy(objectUpdateHeader, 0, buf.Data, 0, 7);
  3898. LLUDPZeroEncoder zc = new LLUDPZeroEncoder(buf.Data);
  3899. zc.Position = 7;
  3900. zc.AddUInt64(m_scene.RegionInfo.RegionHandle);
  3901. zc.AddUInt16(Utils.FloatZeroOneToushort(m_scene.TimeDilation));
  3902. zc.AddByte(1); // block count
  3903. if (ent is ScenePresence)
  3904. CreateAvatarUpdateBlock(ent as ScenePresence, zc);
  3905. else
  3906. CreatePrimUpdateBlock(ent as SceneObjectPart, (ScenePresence)SceneAgent, zc);
  3907. buf.DataLength = zc.Finish();
  3908. m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task);
  3909. }
  3910. public unsafe void SendEntityTerseUpdateImmediate(ISceneEntity ent)
  3911. {
  3912. if (ent == null)
  3913. return;
  3914. UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
  3915. //setup header and regioninfo block
  3916. Buffer.BlockCopy(terseUpdateHeader, 0, buf.Data, 0, 7);
  3917. fixed(byte* bdata = &buf.Data[0])
  3918. {
  3919. Utils.UInt16ToBytes(Utils.FloatZeroOneToushort(m_scene.TimeDilation), bdata + 15);
  3920. bdata[17] = 1;
  3921. byte* data = bdata + 18;
  3922. if (ent is ScenePresence)
  3923. {
  3924. Utils.UInt64ToBytes(((ScenePresence)ent).RegionHandle, bdata + 7);
  3925. CreateAvatartImprovedTerseBlock((ScenePresence)ent, ref data);
  3926. }
  3927. else
  3928. {
  3929. Utils.UInt64ToBytes(m_scene.RegionInfo.RegionHandle, bdata + 7);
  3930. CreatePartImprovedTerseBlock((SceneObjectPart)ent, ref data, false);
  3931. }
  3932. buf.DataLength = (int)(data - bdata);
  3933. }
  3934. m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task, null, true);
  3935. }
  3936. //UUID m_courseLocationPrey = UUID.Zero;
  3937. bool m_couseLocationLastEmpty = false;
  3938. static private readonly byte[] CoarseLocationUpdateHeader = new byte[] {
  3939. 0, // no acks plz
  3940. 0, 0, 0, 0, // sequence number
  3941. 0, // extra
  3942. 0xff, 6 // ID 6 (medium frequency)
  3943. };
  3944. public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
  3945. {
  3946. // We don't need to update inactive clients.
  3947. if (!IsActive)
  3948. return;
  3949. int totalLocations = Math.Min(CoarseLocations.Count, 60);
  3950. if(totalLocations == 0)
  3951. {
  3952. if(m_couseLocationLastEmpty)
  3953. return;
  3954. m_couseLocationLastEmpty = true;
  3955. }
  3956. else
  3957. m_couseLocationLastEmpty = false;
  3958. int totalAgents = Math.Min(users.Count, 60);
  3959. if(totalAgents > totalLocations)
  3960. totalAgents = totalLocations;
  3961. int selfindex = -1;
  3962. int preyindex = -1;
  3963. //bool doprey = m_courseLocationPrey != UUID.Zero;
  3964. UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
  3965. Buffer.BlockCopy(CoarseLocationUpdateHeader, 0, buf.Data, 0, 8);
  3966. byte[] data = buf.Data;
  3967. data[8] = (byte)totalLocations;
  3968. int pos = 9;
  3969. for (int i = 0; i < totalLocations; ++i)
  3970. {
  3971. data[pos++] = (byte)CoarseLocations[i].X;
  3972. data[pos++] = (byte)CoarseLocations[i].Y;
  3973. data[pos++] = CoarseLocations[i].Z > 1024 ? (byte)0 : (byte)(CoarseLocations[i].Z * 0.25f);
  3974. if (i < totalAgents)
  3975. {
  3976. if (users[i] == m_agentId)
  3977. selfindex = i;
  3978. //if (doprey && users[i] == m_courseLocationPrey)
  3979. // preyindex = i;
  3980. }
  3981. }
  3982. Utils.Int16ToBytes((short)selfindex, data, pos); pos += 2;
  3983. Utils.Int16ToBytes((short)preyindex, data, pos); pos += 2;
  3984. data[pos++] = (byte)totalAgents;
  3985. for (int i = 0; i < totalAgents; ++i)
  3986. {
  3987. users[i].ToBytes(data, pos);
  3988. pos += 16;
  3989. }
  3990. buf.DataLength = pos;
  3991. m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task);
  3992. }
  3993. #endregion Avatar Packet/Data Sending Methods
  3994. #region Primitive Packet/Data Sending Methods
  3995. /// <summary>
  3996. /// Generate one of the object update packets based on PrimUpdateFlags
  3997. /// and broadcast the packet to clients
  3998. /// </summary>
  3999. public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
  4000. {
  4001. if (entity is SceneObjectPart)
  4002. {
  4003. SceneObjectPart p = (SceneObjectPart)entity;
  4004. SceneObjectGroup g = p.ParentGroup;
  4005. if (g.HasPrivateAttachmentPoint && g.OwnerID != m_agentId)
  4006. return; // Don't send updates for other people's HUDs
  4007. if((updateFlags ^ PrimUpdateFlags.SendInTransit) == 0)
  4008. {
  4009. List<uint> partIDs = (new List<uint> {p.LocalId});
  4010. m_entityProps.Remove(partIDs);
  4011. m_entityUpdates.Remove(partIDs);
  4012. return;
  4013. }
  4014. }
  4015. int priority = m_prioritizer.GetUpdatePriority(this, entity);
  4016. m_entityUpdates.Enqueue(priority, EntityUpdatesPool.Get(entity, updateFlags));
  4017. }
  4018. /// <summary>
  4019. /// Requeue an EntityUpdate when it was not acknowledged by the client.
  4020. /// We will update the priority and put it in the correct queue, merging update flags
  4021. /// with any other updates that may be queued for the same entity.
  4022. /// The original update time is used for the merged update.
  4023. /// </summary>
  4024. private void ResendPrimUpdate(EntityUpdate update)
  4025. {
  4026. // If the update exists in priority queue, it will be updated.
  4027. // If it does not exist then it will be added with the current (rather than its original) priority
  4028. int priority = m_prioritizer.GetUpdatePriority(this, update.Entity);
  4029. m_entityUpdates.Enqueue(priority, update);
  4030. }
  4031. /// <summary>
  4032. /// Requeue a list of EntityUpdates when they were not acknowledged by the client.
  4033. /// We will update the priority and put it in the correct queue, merging update flags
  4034. /// with any other updates that may be queued for the same entity.
  4035. /// The original update time is used for the merged update.
  4036. /// </summary>
  4037. private void ResendPrimUpdates(List<EntityUpdate> updates, OutgoingPacket oPacket)
  4038. {
  4039. // m_log.WarnFormat("[CLIENT] resending prim updates {0}, packet sequence number {1}", updates[0].UpdateTime, oPacket.SequenceNumber);
  4040. // Remove the update packet from the list of packets waiting for acknowledgement
  4041. // because we are requeuing the list of updates. They will be resent in new packets
  4042. // with the most recent state and priority.
  4043. m_udpClient.NeedAcks.Remove(oPacket.SequenceNumber);
  4044. if (oPacket.Buffer == null)
  4045. return;
  4046. // Count this as a resent packet since we are going to requeue all of the updates contained in it
  4047. Interlocked.Increment(ref m_udpClient.PacketsResent);
  4048. m_udpServer.PacketsResentCount++;
  4049. foreach (EntityUpdate update in updates)
  4050. ResendPrimUpdate(update);
  4051. }
  4052. static private readonly byte[] objectUpdateHeader = new byte[] {
  4053. Helpers.MSG_RELIABLE | Helpers.MSG_ZEROCODED,
  4054. 0, 0, 0, 0, // sequence number
  4055. 0, // extra
  4056. 12 // ID (high frequency)
  4057. };
  4058. static private readonly byte[] terseUpdateHeader = new byte[] {
  4059. Helpers.MSG_RELIABLE | Helpers.MSG_ZEROCODED, // zero code is not as spec
  4060. 0, 0, 0, 0, // sequence number
  4061. 0, // extra
  4062. 15 // ID (high frequency)
  4063. };
  4064. static private readonly byte[] ObjectAnimationHeader = new byte[] {
  4065. Helpers.MSG_RELIABLE,
  4066. 0, 0, 0, 0, // sequence number
  4067. 0, // extra
  4068. 30 // ID (high frequency)
  4069. };
  4070. static private readonly byte[] CompressedObjectHeader = new byte[] {
  4071. Helpers.MSG_RELIABLE,
  4072. 0, 0, 0, 0, // sequence number
  4073. 0, // extra
  4074. 13 // ID (high frequency)
  4075. };
  4076. static private readonly byte[] ObjectUpdateCachedHeader = new byte[] {
  4077. Helpers.MSG_RELIABLE,
  4078. 0, 0, 0, 0, // sequence number
  4079. 0, // extra
  4080. 14 // ID (high frequency)
  4081. };
  4082. private void ProcessEntityUpdates(int maxUpdatesBytes)
  4083. {
  4084. if (!IsActive)
  4085. return;
  4086. ScenePresence mysp = (ScenePresence)SceneAgent;
  4087. if (mysp == null)
  4088. return;
  4089. List<EntityUpdate> objectUpdates = null;
  4090. List<EntityUpdate> objectUpdateProbes = null;
  4091. List<EntityUpdate> compressedUpdates = null;
  4092. List<EntityUpdate> terseUpdates = null;
  4093. List<SceneObjectPart> ObjectAnimationUpdates = null;
  4094. // Check to see if this is a flush
  4095. if (maxUpdatesBytes <= 0)
  4096. {
  4097. maxUpdatesBytes = Int32.MaxValue;
  4098. }
  4099. EntityUpdate update;
  4100. bool viewerCache = m_supportViewerCache;// && mysp.IsChildAgent; // only on child agents
  4101. bool doCulling = m_scene.ObjectsCullingByDistance;
  4102. float cullingrange = 64.0f;
  4103. Vector3 mypos = Vector3.Zero;
  4104. //bool orderedDequeue = m_scene.UpdatePrioritizationScheme == UpdatePrioritizationSchemes.SimpleAngularDistance;
  4105. bool orderedDequeue = false; // temporary off
  4106. HashSet<SceneObjectGroup> GroupsNeedFullUpdate = new HashSet<SceneObjectGroup>();
  4107. bool useCompressUpdate = false;
  4108. if (doCulling)
  4109. {
  4110. cullingrange = mysp.DrawDistance + m_scene.ReprioritizationDistance + 16f;
  4111. mypos = mysp.AbsolutePosition;
  4112. }
  4113. while (maxUpdatesBytes > 0)
  4114. {
  4115. if (!IsActive)
  4116. return;
  4117. if(orderedDequeue)
  4118. {
  4119. if (!m_entityUpdates.TryOrderedDequeue(out update))
  4120. break;
  4121. }
  4122. else
  4123. {
  4124. if (!m_entityUpdates.TryDequeue(out update))
  4125. break;
  4126. }
  4127. PrimUpdateFlags updateFlags = update.Flags;
  4128. if ((updateFlags & PrimUpdateFlags.Kill) != 0)
  4129. {
  4130. m_killRecord.Add(update.Entity.LocalId);
  4131. maxUpdatesBytes -= 30;
  4132. update.Free();
  4133. continue;
  4134. }
  4135. useCompressUpdate = false;
  4136. bool istree = false;
  4137. if (update.Entity is SceneObjectPart)
  4138. {
  4139. SceneObjectPart part = (SceneObjectPart)update.Entity;
  4140. SceneObjectGroup grp = part.ParentGroup;
  4141. if (grp.inTransit && ((update.Flags & PrimUpdateFlags.SendInTransit) == 0))
  4142. {
  4143. update.Free();
  4144. continue;
  4145. }
  4146. if (grp.IsDeleted)
  4147. {
  4148. // Don't send updates for objects that have been marked deleted.
  4149. // Instead send another kill object, because the first one may have gotten
  4150. // into a race condition
  4151. if (part == grp.RootPart && !m_killRecord.Contains(grp.LocalId))
  4152. {
  4153. m_killRecord.Add(grp.LocalId);
  4154. maxUpdatesBytes -= 30;
  4155. }
  4156. update.Free();
  4157. continue;
  4158. }
  4159. if (grp.IsAttachment)
  4160. {
  4161. // animated attachments are nasty if not supported by viewer
  4162. if(!m_SupportObjectAnimations && grp.RootPart.Shape.MeshFlagEntry)
  4163. {
  4164. update.Free();
  4165. continue;
  4166. }
  4167. // Someone else's HUD, why are we getting these?
  4168. if (grp.HasPrivateAttachmentPoint && grp.OwnerID != m_agentId)
  4169. {
  4170. update.Free();
  4171. continue;
  4172. }
  4173. // if owner gone don't update it to anyone
  4174. ScenePresence sp;
  4175. if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
  4176. {
  4177. update.Free();
  4178. continue;
  4179. }
  4180. // On vehicle crossing, the attachments are received
  4181. // while the avatar is still a child. Don't send
  4182. // updates here because the LocalId has not yet
  4183. // been updated and the viewer will derender the
  4184. // attachments until the avatar becomes root.
  4185. if (sp.IsChildAgent)
  4186. {
  4187. update.Free();
  4188. continue;
  4189. }
  4190. // It's an attachment of a valid avatar, but
  4191. // doesn't seem to be attached, skip
  4192. List<SceneObjectGroup> atts = sp.GetAttachments();
  4193. bool found = false;
  4194. for (int indx = 0; indx < atts.Count; ++indx)
  4195. {
  4196. if (atts[indx] == grp)
  4197. {
  4198. found = true;
  4199. break;
  4200. }
  4201. }
  4202. if (!found)
  4203. {
  4204. update.Free();
  4205. continue;
  4206. }
  4207. if (m_disableFacelights)
  4208. {
  4209. if (grp.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
  4210. grp.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
  4211. {
  4212. part.Shape.LightEntry = false;
  4213. }
  4214. }
  4215. }
  4216. else if (doCulling)
  4217. {
  4218. if(GroupsNeedFullUpdate.Contains(grp))
  4219. {
  4220. update.Free();
  4221. continue;
  4222. }
  4223. bool inViewGroups = false;
  4224. lock(GroupsInView)
  4225. inViewGroups = GroupsInView.Contains(grp);
  4226. if(!inViewGroups)
  4227. {
  4228. Vector3 partpos = grp.getCenterOffset();
  4229. float dpos = (partpos - mypos).LengthSquared();
  4230. float maxview = grp.GetBoundsRadius() + cullingrange;
  4231. if (dpos > maxview * maxview)
  4232. {
  4233. update.Free();
  4234. continue;
  4235. }
  4236. if (!viewerCache || ((updateFlags & PrimUpdateFlags.UpdateProbe) == 0))
  4237. {
  4238. GroupsNeedFullUpdate.Add(grp);
  4239. update.Free();
  4240. continue;
  4241. }
  4242. }
  4243. }
  4244. if ((updateFlags & PrimUpdateFlags.UpdateProbe) != 0)
  4245. {
  4246. if (objectUpdateProbes == null)
  4247. {
  4248. objectUpdateProbes = new List<EntityUpdate>(64);
  4249. maxUpdatesBytes -= 18;
  4250. }
  4251. objectUpdateProbes.Add(update);
  4252. maxUpdatesBytes -= 12;
  4253. continue;
  4254. }
  4255. if ((updateFlags & PrimUpdateFlags.Animations) != 0)
  4256. {
  4257. if (m_SupportObjectAnimations && part.Animations != null)
  4258. {
  4259. if (ObjectAnimationUpdates == null)
  4260. ObjectAnimationUpdates = new List<SceneObjectPart>(8);
  4261. ObjectAnimationUpdates.Add(part);
  4262. maxUpdatesBytes -= 20 * part.Animations.Count + 24;
  4263. }
  4264. }
  4265. if(viewerCache)
  4266. useCompressUpdate = grp.IsViewerCachable;
  4267. istree = (part.Shape.PCode == (byte)PCode.Grass || part.Shape.PCode == (byte)PCode.NewTree || part.Shape.PCode == (byte)PCode.Tree);
  4268. }
  4269. else if (update.Entity is ScenePresence)
  4270. {
  4271. ScenePresence presence = (ScenePresence)update.Entity;
  4272. if (presence.IsDeleted)
  4273. {
  4274. update.Free();
  4275. continue;
  4276. }
  4277. // If ParentUUID is not UUID.Zero and ParentID is 0, this
  4278. // avatar is in the process of crossing regions while
  4279. // sat on an object. In this state, we don't want any
  4280. // updates because they will visually orbit the avatar.
  4281. // Update will be forced once crossing is completed anyway.
  4282. if (!presence.ParentUUID.IsZero() && presence.ParentID == 0)
  4283. {
  4284. update.Free();
  4285. continue;
  4286. }
  4287. }
  4288. else // what is this update ?
  4289. {
  4290. update.Free();
  4291. continue;
  4292. }
  4293. #region UpdateFlags to packet type conversion
  4294. updateFlags &= PrimUpdateFlags.FullUpdate; // clear other control bits already handled
  4295. if(updateFlags == PrimUpdateFlags.None)
  4296. {
  4297. update.Free();
  4298. continue;
  4299. }
  4300. const PrimUpdateFlags canNotUseImprovedMask = ~(
  4301. PrimUpdateFlags.AttachmentPoint |
  4302. PrimUpdateFlags.Position |
  4303. PrimUpdateFlags.Rotation |
  4304. PrimUpdateFlags.Velocity |
  4305. PrimUpdateFlags.Acceleration |
  4306. PrimUpdateFlags.AngularVelocity |
  4307. PrimUpdateFlags.CollisionPlane |
  4308. PrimUpdateFlags.Textures
  4309. );
  4310. #endregion UpdateFlags to packet type conversion
  4311. #region Block Construction
  4312. if ((updateFlags & canNotUseImprovedMask) == 0)
  4313. {
  4314. if (terseUpdates == null)
  4315. {
  4316. terseUpdates = new List<EntityUpdate>(16);
  4317. maxUpdatesBytes -= 18;
  4318. }
  4319. terseUpdates.Add(update);
  4320. if (update.Entity is ScenePresence)
  4321. maxUpdatesBytes -= 63; // no texture entry
  4322. else
  4323. {
  4324. if ((updateFlags & PrimUpdateFlags.Textures) == 0)
  4325. maxUpdatesBytes -= 47;
  4326. else
  4327. maxUpdatesBytes -= 150; // aprox
  4328. }
  4329. }
  4330. else
  4331. {
  4332. if (update.Entity is ScenePresence)
  4333. {
  4334. maxUpdatesBytes -= 150; // crude estimation
  4335. if (objectUpdates == null)
  4336. {
  4337. objectUpdates = new List<EntityUpdate>(16);
  4338. maxUpdatesBytes -= 18;
  4339. }
  4340. objectUpdates.Add(update);
  4341. }
  4342. else
  4343. {
  4344. if (useCompressUpdate)
  4345. {
  4346. if (istree)
  4347. maxUpdatesBytes -= 64;
  4348. else
  4349. maxUpdatesBytes -= 120; // crude estimation
  4350. if (compressedUpdates == null)
  4351. {
  4352. compressedUpdates = new List<EntityUpdate>(16);
  4353. maxUpdatesBytes -= 18;
  4354. }
  4355. compressedUpdates.Add(update);
  4356. }
  4357. else
  4358. {
  4359. if (istree)
  4360. maxUpdatesBytes -= 70;
  4361. else
  4362. maxUpdatesBytes -= 150; // crude estimation
  4363. if (objectUpdates == null)
  4364. {
  4365. objectUpdates = new List<EntityUpdate>(16);
  4366. maxUpdatesBytes -= 18;
  4367. }
  4368. objectUpdates.Add(update);
  4369. }
  4370. }
  4371. }
  4372. #endregion Block Construction
  4373. }
  4374. #region Packet Sending
  4375. ushort timeDilation;
  4376. if (!IsActive)
  4377. return;
  4378. timeDilation = Utils.FloatZeroOneToushort(m_scene.TimeDilation);
  4379. if(objectUpdates != null)
  4380. {
  4381. //List<EntityUpdate> tau = new List<EntityUpdate>(30);
  4382. UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
  4383. Buffer.BlockCopy(objectUpdateHeader, 0, buf.Data, 0, 7);
  4384. LLUDPZeroEncoder zc = new LLUDPZeroEncoder(buf.Data);
  4385. zc.Position = 7;
  4386. zc.AddUInt64(m_scene.RegionInfo.RegionHandle);
  4387. zc.AddUInt16(timeDilation);
  4388. zc.AddByte(1); // tmp block count
  4389. int countposition = zc.Position - 1;
  4390. int lastpos = 0;
  4391. int lastzc = 0;
  4392. int count = 0;
  4393. bool shouldCreateSelected = false; //mantis 8639
  4394. EntityUpdate eu;
  4395. for(int indx = 0; indx < objectUpdates.Count; ++indx)
  4396. {
  4397. eu = objectUpdates[indx];
  4398. lastpos = zc.Position;
  4399. lastzc = zc.ZeroCount;
  4400. if (eu.Entity is ScenePresence)
  4401. CreateAvatarUpdateBlock((ScenePresence)eu.Entity, zc);
  4402. else
  4403. {
  4404. SceneObjectPart part = (SceneObjectPart)eu.Entity;
  4405. shouldCreateSelected = part.CreateSelected;
  4406. CreatePrimUpdateBlock(part, mysp, zc);
  4407. }
  4408. if (zc.Position < LLUDPServer.MAXPAYLOAD - 300)
  4409. {
  4410. //tau.Add(eu);
  4411. ++count;
  4412. }
  4413. else
  4414. {
  4415. // we need more packets
  4416. UDPPacketBuffer newbuf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
  4417. Buffer.BlockCopy(buf.Data, 0, newbuf.Data, 0, countposition); // start is the same
  4418. buf.Data[countposition] = (byte)count;
  4419. // get pending zeros at cut point
  4420. if(lastzc > 0)
  4421. {
  4422. buf.Data[lastpos++] = 0;
  4423. buf.Data[lastpos++] = (byte)lastzc;
  4424. }
  4425. buf.DataLength = lastpos;
  4426. m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task,
  4427. //delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false, false);
  4428. null, false);
  4429. buf = newbuf;
  4430. zc.Data = buf.Data;
  4431. zc.ZeroCount = 0;
  4432. zc.Position = countposition + 1;
  4433. // im lazy now, just do last again
  4434. if (eu.Entity is ScenePresence)
  4435. CreateAvatarUpdateBlock((ScenePresence)eu.Entity, zc);
  4436. else
  4437. {
  4438. if(shouldCreateSelected) //mantis 8639 recover selected state
  4439. ((SceneObjectPart)eu.Entity).CreateSelected = true;
  4440. CreatePrimUpdateBlock((SceneObjectPart)eu.Entity, mysp, zc);
  4441. }
  4442. //tau = new List<EntityUpdate>(30);
  4443. //tau.Add(eu);
  4444. count = 1;
  4445. }
  4446. eu.Free(); //remove if using resend
  4447. }
  4448. if (count > 0)
  4449. {
  4450. buf.Data[countposition] = (byte)count;
  4451. buf.DataLength = zc.Finish();
  4452. m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task,
  4453. //delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false, false);
  4454. null, false);
  4455. }
  4456. }
  4457. /* no zero encode compressed updates
  4458. if(compressedUpdates != null)
  4459. {
  4460. List<EntityUpdate> tau = new List<EntityUpdate>(30);
  4461. UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
  4462. byte[] data = buf.Data;
  4463. Buffer.BlockCopy(CompressedObjectHeader, 0, data , 0, 7);
  4464. Utils.UInt64ToBytesSafepos(m_scene.RegionInfo.RegionHandle, data, 7); // 15
  4465. Utils.UInt16ToBytes(timeDilation, data, 15); // 17
  4466. int countposition = 17; // blocks count position
  4467. int pos = 18;
  4468. int lastpos = 0;
  4469. int count = 0;
  4470. foreach (EntityUpdate eu in compressedUpdates)
  4471. {
  4472. SceneObjectPart sop = (SceneObjectPart)eu.Entity;
  4473. if (sop.ParentGroup == null || sop.ParentGroup.IsDeleted)
  4474. continue;
  4475. lastpos = pos;
  4476. CreateCompressedUpdateBlock(sop, mysp, data, ref pos);
  4477. if (pos < LLUDPServer.MAXPAYLOAD)
  4478. {
  4479. tau.Add(eu);
  4480. ++count;
  4481. }
  4482. else
  4483. {
  4484. // we need more packets
  4485. UDPPacketBuffer newbuf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
  4486. Buffer.BlockCopy(buf.Data, 0, newbuf.Data, 0, countposition); // start is the same
  4487. buf.Data[countposition] = (byte)count;
  4488. buf.DataLength = lastpos;
  4489. m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task,
  4490. delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false, false);
  4491. buf = newbuf;
  4492. data = buf.Data;
  4493. pos = 18;
  4494. // im lazy now, just do last again
  4495. CreateCompressedUpdateBlock(sop, mysp, data, ref pos);
  4496. tau = new List<EntityUpdate>(30);
  4497. tau.Add(eu);
  4498. count = 1;
  4499. }
  4500. }
  4501. if (count > 0)
  4502. {
  4503. buf.Data[countposition] = (byte)count;
  4504. buf.DataLength = pos;
  4505. m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task,
  4506. delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false, false);
  4507. }
  4508. }
  4509. */
  4510. if (compressedUpdates != null)
  4511. {
  4512. //List<EntityUpdate> tau = new List<EntityUpdate>(30);
  4513. UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
  4514. byte[] data = buf.Data;
  4515. Buffer.BlockCopy(CompressedObjectHeader, 0, data, 0, 7);
  4516. data[0] |= Helpers.MSG_ZEROCODED;
  4517. LLUDPZeroEncoder zc = new LLUDPZeroEncoder(buf.Data);
  4518. zc.Position = 7;
  4519. zc.AddUInt64(m_scene.RegionInfo.RegionHandle);
  4520. zc.AddUInt16(timeDilation);
  4521. zc.AddByte(1); // tmp block count
  4522. int countposition = zc.Position - 1;
  4523. int lastpos = 0;
  4524. int lastzc = 0;
  4525. int count = 0;
  4526. bool shouldCreateSelected = false; //mantis 8639
  4527. EntityUpdate eu;
  4528. for (int indx = 0; indx < compressedUpdates.Count; ++indx)
  4529. {
  4530. eu = compressedUpdates[indx];
  4531. SceneObjectPart sop = (SceneObjectPart)eu.Entity;
  4532. if (sop.ParentGroup == null || sop.ParentGroup.IsDeleted)
  4533. continue;
  4534. shouldCreateSelected = sop.CreateSelected;
  4535. lastpos = zc.Position;
  4536. lastzc = zc.ZeroCount;
  4537. CreateCompressedUpdateBlockZC(sop, mysp, zc);
  4538. if (zc.Position < LLUDPServer.MAXPAYLOAD - 200)
  4539. {
  4540. //tau.Add(eu);
  4541. ++count;
  4542. }
  4543. else
  4544. {
  4545. // we need more packets
  4546. UDPPacketBuffer newbuf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
  4547. Buffer.BlockCopy(buf.Data, 0, newbuf.Data, 0, countposition); // start is the same
  4548. buf.Data[countposition] = (byte)count;
  4549. // get pending zeros at cut point
  4550. if (lastzc > 0)
  4551. {
  4552. buf.Data[lastpos++] = 0;
  4553. buf.Data[lastpos++] = (byte)lastzc;
  4554. }
  4555. buf.DataLength = lastpos;
  4556. m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task,
  4557. //delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false, false);
  4558. null, false);
  4559. buf = newbuf;
  4560. zc.Data = buf.Data;
  4561. data[0] |= Helpers.MSG_ZEROCODED;
  4562. zc.ZeroCount = 0;
  4563. zc.Position = countposition + 1;
  4564. if (shouldCreateSelected) //mantis 8639 recover selected state
  4565. sop.CreateSelected = true;
  4566. // im lazy now, just do last again
  4567. CreateCompressedUpdateBlockZC(sop, mysp, zc);
  4568. //tau = new List<EntityUpdate>(30);
  4569. //tau.Add(eu);
  4570. count = 1;
  4571. }
  4572. eu.Free(); //remove if using resend
  4573. }
  4574. if (count > 0)
  4575. {
  4576. buf.Data[countposition] = (byte)count;
  4577. buf.DataLength = zc.Finish();
  4578. m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task,
  4579. //delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false, false);
  4580. null, false);
  4581. }
  4582. }
  4583. if (objectUpdateProbes != null)
  4584. {
  4585. UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
  4586. byte[] data = buf.Data;
  4587. Buffer.BlockCopy(ObjectUpdateCachedHeader, 0, data, 0, 7);
  4588. Utils.UInt64ToBytesSafepos(m_scene.RegionInfo.RegionHandle, data, 7); // 15
  4589. Utils.UInt16ToBytes(timeDilation, data, 15); // 17
  4590. const int countposition = 17; // blocks count index
  4591. int pos = countposition + 1;
  4592. int count = 0;
  4593. EntityUpdate eu;
  4594. int indx = 0;
  4595. while (indx < objectUpdateProbes.Count)
  4596. {
  4597. unsafe
  4598. {
  4599. fixed(byte* bdata = &data[countposition + 1])
  4600. {
  4601. byte* ptr = bdata;
  4602. while (indx < objectUpdateProbes.Count)
  4603. {
  4604. eu = objectUpdateProbes[indx++];
  4605. SceneObjectPart sop = (SceneObjectPart)eu.Entity;
  4606. if (sop.ParentGroup == null || sop.ParentGroup.IsDeleted)
  4607. continue;
  4608. uint primflags = m_scene.Permissions.GenerateClientFlags(sop, mysp);
  4609. if (mysp.UUID.NotEqual(sop.OwnerID))
  4610. primflags &= ~(uint)PrimFlags.CreateSelected;
  4611. else
  4612. {
  4613. if (sop.CreateSelected)
  4614. primflags |= (uint)PrimFlags.CreateSelected;
  4615. else
  4616. primflags &= ~(uint)PrimFlags.CreateSelected;
  4617. }
  4618. Utils.UIntToBytes(sop.LocalId, ptr); ptr += 4;
  4619. Utils.UIntToBytes((uint)sop.PseudoCRC, ptr); ptr += 4; //WRONG
  4620. Utils.UIntToBytes(primflags, ptr); ptr += 4;
  4621. eu.Free();
  4622. ++count;
  4623. pos += 12;
  4624. if (pos > (LLUDPServer.MAXPAYLOAD - 13))
  4625. {
  4626. // we need more packets
  4627. UDPPacketBuffer newbuf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
  4628. Buffer.BlockCopy(data, 0, newbuf.Data, 0, countposition); // start is the same
  4629. data[countposition] = (byte)count;
  4630. buf.DataLength = pos;
  4631. m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task, null, false);
  4632. buf = newbuf;
  4633. data = buf.Data;
  4634. count = 0;
  4635. pos = countposition + 1;
  4636. break;
  4637. }
  4638. }
  4639. }
  4640. }
  4641. }
  4642. if (count > 0)
  4643. {
  4644. data[countposition] = (byte)count;
  4645. buf.DataLength = pos;
  4646. m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task, null, false);
  4647. }
  4648. }
  4649. if (terseUpdates != null)
  4650. {
  4651. int blocks = terseUpdates.Count;
  4652. //List<EntityUpdate> tau = new List<EntityUpdate>(30);
  4653. UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
  4654. //setup header and regioninfo block
  4655. Buffer.BlockCopy(terseUpdateHeader, 0, buf.Data, 0, 7);
  4656. Utils.UInt64ToBytesSafepos(m_scene.RegionInfo.RegionHandle, buf.Data, 7);
  4657. Utils.UInt16ToBytes(timeDilation, buf.Data, 15);
  4658. const int COUNTINDEX = 17;
  4659. int pos = COUNTINDEX + 1;
  4660. int lastpos = 0;
  4661. int count = 0;
  4662. EntityUpdate eu;
  4663. int indx = 0;
  4664. while (indx < terseUpdates.Count)
  4665. {
  4666. unsafe
  4667. {
  4668. fixed(byte* bdata = &buf.Data[0])
  4669. {
  4670. byte* data = bdata + pos;
  4671. while (indx < terseUpdates.Count)
  4672. {
  4673. eu = terseUpdates[indx++];
  4674. lastpos = pos;
  4675. if(eu.Entity is ScenePresence sp)
  4676. CreateAvatartImprovedTerseBlock(sp, ref data);
  4677. else
  4678. CreatePartImprovedTerseBlock((SceneObjectPart)eu.Entity, ref data, (eu.Flags & PrimUpdateFlags.Textures) != 0);
  4679. eu.Free();
  4680. pos = (int)(data - bdata);
  4681. --blocks;
  4682. if (pos < LLUDPServer.MAXPAYLOAD)
  4683. {
  4684. //tau.Add(eu);
  4685. ++count;
  4686. }
  4687. else if (blocks > 0)
  4688. {
  4689. // we need more packets
  4690. UDPPacketBuffer newbuf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
  4691. Buffer.BlockCopy(buf.Data, 0, newbuf.Data, 0, COUNTINDEX); // start is the same
  4692. // copy what we done in excess
  4693. int extralen = pos - lastpos;
  4694. if(extralen > 0)
  4695. Buffer.BlockCopy(buf.Data, lastpos, newbuf.Data, 18, extralen);
  4696. pos = COUNTINDEX + 1 + extralen;
  4697. buf.Data[COUNTINDEX] = (byte)count;
  4698. buf.DataLength = lastpos;
  4699. // zero encode is not as spec
  4700. m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task,
  4701. //delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, true);
  4702. null, true);
  4703. //tau = new List<EntityUpdate>(30);
  4704. //tau.Add(eu);
  4705. count = 1;
  4706. buf = newbuf;
  4707. break;
  4708. }
  4709. }
  4710. }
  4711. }
  4712. }
  4713. if (count > 0)
  4714. {
  4715. buf.Data[COUNTINDEX] = (byte)count;
  4716. buf.DataLength = pos;
  4717. m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task,
  4718. //delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, true);
  4719. null, true);
  4720. }
  4721. }
  4722. if (ObjectAnimationUpdates != null)
  4723. {
  4724. SceneObjectPart sop;
  4725. for (int indx = 0; indx < ObjectAnimationUpdates.Count; ++indx)
  4726. {
  4727. sop = ObjectAnimationUpdates[indx];
  4728. if (sop.Animations == null)
  4729. continue;
  4730. SceneObjectGroup sog = sop.ParentGroup;
  4731. if (sog == null || sog.IsDeleted)
  4732. continue;
  4733. SceneObjectPart root = sog.RootPart;
  4734. if (root == null || root.Shape == null || !root.Shape.MeshFlagEntry)
  4735. continue;
  4736. UUID[] ids = null;
  4737. int[] seqs = null;
  4738. int count = sop.GetAnimations(out ids, out seqs);
  4739. UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
  4740. byte[] data = buf.Data;
  4741. //setup header
  4742. Buffer.BlockCopy(ObjectAnimationHeader, 0, data , 0, 7);
  4743. // sender block
  4744. sop.UUID.ToBytes(data, 7); // 23
  4745. //animations block
  4746. if (count > 255)
  4747. count = 255;
  4748. data[23] = (byte)count;
  4749. int pos = 24;
  4750. for(int i = 0; i < count; i++)
  4751. {
  4752. ids[i].ToBytes(data, pos); pos += 16;
  4753. Utils.IntToBytesSafepos(seqs[i], data, pos); pos += 4;
  4754. }
  4755. buf.DataLength = pos;
  4756. m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task);
  4757. }
  4758. }
  4759. #endregion Packet Sending
  4760. #region Handle deleted objects
  4761. if (m_killRecord.Count > 0)
  4762. {
  4763. SendKillObject(m_killRecord);
  4764. m_killRecord.Clear();
  4765. }
  4766. if(GroupsNeedFullUpdate.Count > 0)
  4767. {
  4768. foreach(SceneObjectGroup grp in GroupsNeedFullUpdate)
  4769. {
  4770. lock (GroupsInView)
  4771. GroupsInView.Add(grp);
  4772. PrimUpdateFlags flags = PrimUpdateFlags.CancelKill;
  4773. if(viewerCache && grp.IsViewerCachable)
  4774. flags |= PrimUpdateFlags.UpdateProbe;
  4775. foreach (SceneObjectPart p in grp.Parts)
  4776. SendEntityUpdate(p, flags);
  4777. }
  4778. }
  4779. #endregion
  4780. }
  4781. // hack.. dont use
  4782. /*
  4783. public void SendPartFullUpdate(ISceneEntity ent, uint? parentID)
  4784. {
  4785. if (ent is SceneObjectPart)
  4786. {
  4787. SceneObjectPart part = (SceneObjectPart)ent;
  4788. ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
  4789. packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
  4790. packet.RegionData.TimeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f);
  4791. packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
  4792. ObjectUpdatePacket.ObjectDataBlock blk = CreatePrimUpdateBlock(part, mysp);
  4793. if (parentID.HasValue)
  4794. {
  4795. blk.ParentID = parentID.Value;
  4796. }
  4797. packet.ObjectData[0] = blk;
  4798. OutPacket(packet, ThrottleOutPacketType.Task, true);
  4799. }
  4800. // m_log.DebugFormat(
  4801. // "[LLCLIENTVIEW]: Sent {0} updates in ProcessEntityUpdates() for {1} {2} in {3}",
  4802. // updatesThisCall, Name, SceneAgent.IsChildAgent ? "child" : "root", Scene.Name);
  4803. //
  4804. }
  4805. */
  4806. public void ReprioritizeUpdates()
  4807. {
  4808. m_entityUpdates.Reprioritize(UpdatePriorityHandler);
  4809. CheckGroupsInView();
  4810. }
  4811. private bool CheckGroupsInViewBusy = false;
  4812. public void CheckGroupsInView()
  4813. {
  4814. bool doCulling = m_scene.ObjectsCullingByDistance;
  4815. if(!doCulling)
  4816. return;
  4817. if (!IsActive)
  4818. return;
  4819. if (CheckGroupsInViewBusy)
  4820. return;
  4821. ScenePresence mysp = (ScenePresence)SceneAgent;
  4822. if (mysp == null || mysp.IsDeleted)
  4823. return;
  4824. CheckGroupsInViewBusy = true;
  4825. float cullingrange = mysp.DrawDistance + m_scene.ReprioritizationDistance + 16f;
  4826. Vector3 mypos = mysp.AbsolutePosition;
  4827. HashSet<SceneObjectGroup> NewGroupsInView = new HashSet<SceneObjectGroup>();
  4828. HashSet<SceneObjectGroup> GroupsNeedFullUpdate = new HashSet<SceneObjectGroup>();
  4829. List<SceneObjectGroup> kills = new List<SceneObjectGroup>();
  4830. EntityBase[] entities = m_scene.Entities.GetEntities();
  4831. foreach (EntityBase e in entities)
  4832. {
  4833. if (!IsActive)
  4834. return;
  4835. if (e != null && e is SceneObjectGroup)
  4836. {
  4837. SceneObjectGroup grp = (SceneObjectGroup)e;
  4838. if(grp.IsDeleted || grp.IsAttachment )
  4839. continue;
  4840. bool inviewgroups;
  4841. lock (GroupsInView)
  4842. inviewgroups = GroupsInView.Contains(grp);
  4843. //temp handling of sits
  4844. if(grp.GetSittingAvatarsCount() > 0)
  4845. {
  4846. if (!inviewgroups)
  4847. GroupsNeedFullUpdate.Add(grp);
  4848. NewGroupsInView.Add(grp);
  4849. }
  4850. else
  4851. {
  4852. Vector3 grppos = grp.getCenterOffset();
  4853. float dpos = (grppos - mypos).LengthSquared();
  4854. float maxview = grp.GetBoundsRadius() + cullingrange;
  4855. if (dpos > maxview * maxview)
  4856. {
  4857. if(inviewgroups)
  4858. kills.Add(grp);
  4859. }
  4860. else
  4861. {
  4862. if (!inviewgroups)
  4863. GroupsNeedFullUpdate.Add(grp);
  4864. NewGroupsInView.Add(grp);
  4865. }
  4866. }
  4867. }
  4868. }
  4869. lock(GroupsInView)
  4870. GroupsInView = NewGroupsInView;
  4871. if (kills.Count > 0)
  4872. {
  4873. List<uint> partIDs = new List<uint>();
  4874. foreach(SceneObjectGroup grp in kills)
  4875. {
  4876. SendEntityUpdate(grp.RootPart, PrimUpdateFlags.Kill);
  4877. foreach(SceneObjectPart p in grp.Parts)
  4878. {
  4879. if(p != grp.RootPart)
  4880. partIDs.Add(p.LocalId);
  4881. }
  4882. }
  4883. kills.Clear();
  4884. if(partIDs.Count > 0)
  4885. {
  4886. m_entityProps.Remove(partIDs);
  4887. m_entityUpdates.Remove(partIDs);
  4888. }
  4889. }
  4890. if(GroupsNeedFullUpdate.Count > 0)
  4891. {
  4892. bool sendProbes = m_supportViewerCache && (m_viewerHandShakeFlags & 2) == 0;
  4893. if(sendProbes)
  4894. {
  4895. foreach (SceneObjectGroup grp in GroupsNeedFullUpdate)
  4896. {
  4897. PrimUpdateFlags flags = PrimUpdateFlags.CancelKill;
  4898. if (grp.IsViewerCachable)
  4899. flags |= PrimUpdateFlags.UpdateProbe;
  4900. foreach (SceneObjectPart p in grp.Parts)
  4901. SendEntityUpdate(p, flags);
  4902. }
  4903. }
  4904. else
  4905. {
  4906. m_viewerHandShakeFlags &= ~2U; // nexttime send probes
  4907. PrimUpdateFlags flags = PrimUpdateFlags.CancelKill;
  4908. foreach (SceneObjectGroup grp in GroupsNeedFullUpdate)
  4909. {
  4910. foreach (SceneObjectPart p in grp.Parts)
  4911. SendEntityUpdate(p, flags);
  4912. }
  4913. }
  4914. }
  4915. CheckGroupsInViewBusy = false;
  4916. }
  4917. private bool UpdatePriorityHandler(ref int priority, ISceneEntity entity)
  4918. {
  4919. if (!IsActive)
  4920. return false;
  4921. priority = m_prioritizer.GetUpdatePriority(this, entity);
  4922. return true;
  4923. }
  4924. public void FlushPrimUpdates()
  4925. {
  4926. m_log.WarnFormat("[CLIENT]: Flushing prim updates to " + m_firstName + " " + m_lastName);
  4927. while (m_entityUpdates.Count > 0)
  4928. ProcessEntityUpdates(-1);
  4929. }
  4930. #endregion Primitive Packet/Data Sending Methods
  4931. // These are used to implement an adaptive backoff in the number
  4932. // of updates converted to packets. Since we don't want packets
  4933. // to sit in the queue with old data, only convert enough updates
  4934. // to packets that can be sent in 30ms.
  4935. void HandleQueueEmpty(ThrottleOutPacketTypeFlags categories)
  4936. {
  4937. if(m_scene == null)
  4938. return;
  4939. if ((categories & ThrottleOutPacketTypeFlags.Task) != 0)
  4940. {
  4941. int maxUpdateBytes = m_udpClient.GetCatBytesCanSend(ThrottleOutPacketType.Task, 30);
  4942. if (m_entityUpdates.Count > 0)
  4943. ProcessEntityUpdates(maxUpdateBytes);
  4944. if (m_entityProps.Count > 0)
  4945. ProcessEntityPropertyRequests(maxUpdateBytes);
  4946. }
  4947. if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0)
  4948. ImageManager.ProcessImageQueue(m_udpServer.TextureSendLimit);
  4949. }
  4950. internal bool HandleHasUpdates(ThrottleOutPacketTypeFlags categories)
  4951. {
  4952. if ((categories & ThrottleOutPacketTypeFlags.Task) != 0)
  4953. {
  4954. if (m_entityUpdates.Count > 0)
  4955. return true;
  4956. if (m_entityProps.Count > 0)
  4957. return true;
  4958. }
  4959. if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0)
  4960. {
  4961. if (ImageManager.HasUpdates())
  4962. return true;
  4963. }
  4964. return false;
  4965. }
  4966. public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID)
  4967. {
  4968. AssetUploadCompletePacket newPack = new AssetUploadCompletePacket();
  4969. newPack.AssetBlock.Type = AssetType;
  4970. newPack.AssetBlock.Success = Success;
  4971. newPack.AssetBlock.UUID = AssetFullID;
  4972. newPack.Header.Zerocoded = true;
  4973. OutPacket(newPack, ThrottleOutPacketType.Asset);
  4974. }
  4975. public void SendXferRequest(ulong XferID, short AssetType, UUID vFileID, byte FilePath, byte[] FileName)
  4976. {
  4977. RequestXferPacket newPack = new RequestXferPacket();
  4978. newPack.XferID.ID = XferID;
  4979. newPack.XferID.VFileType = AssetType;
  4980. newPack.XferID.VFileID = vFileID;
  4981. newPack.XferID.FilePath = FilePath;
  4982. newPack.XferID.Filename = FileName;
  4983. newPack.Header.Zerocoded = true;
  4984. OutPacket(newPack, ThrottleOutPacketType.Asset);
  4985. }
  4986. public void SendConfirmXfer(ulong xferID, uint PacketID)
  4987. {
  4988. ConfirmXferPacketPacket newPack = new ConfirmXferPacketPacket();
  4989. newPack.XferID.ID = xferID;
  4990. newPack.XferID.Packet = PacketID;
  4991. newPack.Header.Zerocoded = true;
  4992. OutPacket(newPack, ThrottleOutPacketType.Asset);
  4993. }
  4994. public void SendInitiateDownload(string simFileName, string clientFileName)
  4995. {
  4996. InitiateDownloadPacket newPack = new InitiateDownloadPacket();
  4997. newPack.AgentData.AgentID = m_agentId;
  4998. newPack.FileData.SimFilename = Utils.StringToBytes(simFileName);
  4999. newPack.FileData.ViewerFilename = Utils.StringToBytes(clientFileName);
  5000. OutPacket(newPack, ThrottleOutPacketType.Asset);
  5001. }
  5002. public void SendImageFirstPart(
  5003. ushort numParts, UUID ImageUUID, uint ImageSize, byte[] ImageData, byte imageCodec)
  5004. {
  5005. ImageDataPacket im = new ImageDataPacket();
  5006. im.ImageID.Packets = numParts;
  5007. im.ImageID.ID = ImageUUID;
  5008. if (ImageSize > 0)
  5009. im.ImageID.Size = ImageSize;
  5010. im.ImageData.Data = ImageData;
  5011. im.ImageID.Codec = imageCodec;
  5012. im.Header.Zerocoded = true;
  5013. OutPacket(im, ThrottleOutPacketType.Texture);
  5014. }
  5015. public void SendImageNextPart(ushort partNumber, UUID imageUuid, byte[] imageData)
  5016. {
  5017. ImagePacketPacket im = new ImagePacketPacket();
  5018. im.ImageID.Packet = partNumber;
  5019. im.ImageID.ID = imageUuid;
  5020. im.ImageData.Data = imageData;
  5021. OutPacket(im, ThrottleOutPacketType.Texture);
  5022. }
  5023. public void SendImageNotFound(UUID imageid)
  5024. {
  5025. ImageNotInDatabasePacket notFoundPacket
  5026. = (ImageNotInDatabasePacket)PacketPool.Instance.GetPacket(PacketType.ImageNotInDatabase);
  5027. notFoundPacket.ImageID.ID = imageid;
  5028. OutPacket(notFoundPacket, ThrottleOutPacketType.Texture);
  5029. }
  5030. public void SendShutdownConnectionNotice()
  5031. {
  5032. OutPacket(PacketPool.Instance.GetPacket(PacketType.DisableSimulator), ThrottleOutPacketType.Unknown);
  5033. }
  5034. static private readonly byte[] SimStatsHeader = new byte[] {
  5035. 0,
  5036. 0, 0, 0, 0, // sequence number
  5037. 0, // extra
  5038. 0xff, 0xff, 0, 140 // ID 140 (low frequency bigendian)
  5039. };
  5040. public void SendSimStats(SimStats stats)
  5041. {
  5042. UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
  5043. byte[] data = buf.Data;
  5044. //setup header
  5045. Buffer.BlockCopy(SimStatsHeader, 0, data, 0, 10);
  5046. // Region Block
  5047. Utils.UIntToBytesSafepos(stats.RegionX, data, 10);
  5048. Utils.UIntToBytesSafepos(stats.RegionY, data, 14);
  5049. Utils.UIntToBytesSafepos(stats.RegionFlags, data, 18);
  5050. Utils.UIntToBytesSafepos(stats.ObjectCapacity, data, 22); // 26
  5051. // stats
  5052. data[26] = (byte)StatsIndex.ViewerArraySize;
  5053. int pos = 27;
  5054. int i = 0;
  5055. for (; i < (int)StatsIndex.UnAckedBytes; ++i)
  5056. {
  5057. Utils.UIntToBytesSafepos(SimStats.StatsIndexID[i], data, pos); pos += 4;
  5058. Utils.FloatToBytesSafepos(stats.StatsValues[i], data, pos); pos += 4;
  5059. }
  5060. // unack Bytes is in KB
  5061. Utils.UIntToBytesSafepos(SimStats.StatsIndexID[i], data, pos); pos += 4;
  5062. Utils.FloatToBytesSafepos(stats.StatsValues[i] / 1024, data, pos); pos += 4;
  5063. ++i;
  5064. for (; i < (int)StatsIndex.ViewerArraySize; ++i)
  5065. {
  5066. Utils.UIntToBytesSafepos(SimStats.StatsIndexID[i], data, pos); pos += 4;
  5067. Utils.FloatToBytesSafepos(stats.StatsValues[i], data, pos); pos += 4;
  5068. }
  5069. //no PID
  5070. Utils.IntToBytesSafepos(0, data, pos); pos += 4;
  5071. // no regioninfo (extended flags)
  5072. data[pos++] = 0; // = 1;
  5073. //Utils.UInt64ToBytesSafepos(RegionFlagsExtended, data, pos); pos += 8;
  5074. buf.DataLength = pos;
  5075. m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task);
  5076. }
  5077. public void SendObjectPropertiesFamilyData(ISceneEntity entity, uint requestFlags)
  5078. {
  5079. m_entityProps.Enqueue(0, EntityUpdatesPool.Get(entity, (PrimUpdateFlags)requestFlags, true, false));
  5080. }
  5081. private void ResendPropertyUpdate(EntityUpdate update)
  5082. {
  5083. m_entityProps.Enqueue(0, update);
  5084. }
  5085. private void ResendPropertyUpdates(List<EntityUpdate> updates, OutgoingPacket oPacket)
  5086. {
  5087. // m_log.WarnFormat("[CLIENT] resending object property {0}",updates[0].UpdateTime);
  5088. // Remove the update packet from the list of packets waiting for acknowledgement
  5089. // because we are requeuing the list of updates. They will be resent in new packets
  5090. // with the most recent state.
  5091. m_udpClient.NeedAcks.Remove(oPacket.SequenceNumber);
  5092. // Count this as a resent packet since we are going to requeue all of the updates contained in it
  5093. Interlocked.Increment(ref m_udpClient.PacketsResent);
  5094. // We're not going to worry about interlock yet since its not currently critical that this total count
  5095. // is 100% correct
  5096. m_udpServer.PacketsResentCount++;
  5097. foreach (EntityUpdate update in updates)
  5098. ResendPropertyUpdate(update);
  5099. }
  5100. public void SendObjectPropertiesReply(ISceneEntity entity)
  5101. {
  5102. m_entityProps.Enqueue(0, EntityUpdatesPool.Get(entity,0,false,true));
  5103. }
  5104. static private readonly byte[] ObjectPropertyUpdateHeader = new byte[] {
  5105. Helpers.MSG_RELIABLE | Helpers.MSG_ZEROCODED,
  5106. 0, 0, 0, 0, // sequence number
  5107. 0, // extra
  5108. 0xff, 9 // ID (medium frequency)
  5109. };
  5110. static private readonly byte[] ObjectFamilyUpdateHeader = new byte[] {
  5111. Helpers.MSG_RELIABLE | Helpers.MSG_ZEROCODED,
  5112. 0, 0, 0, 0, // sequence number
  5113. 0, // extra
  5114. 0xff, 10 // ID (medium frequency)
  5115. };
  5116. private void ProcessEntityPropertyRequests(int maxUpdateBytes)
  5117. {
  5118. List<EntityUpdate> objectPropertiesUpdates = null;
  5119. List<EntityUpdate> objectPropertiesFamilyUpdates = null;
  5120. List<EntityUpdate> used = new List<EntityUpdate>(64);
  5121. List<SceneObjectPart> needPhysics = null;
  5122. // bool orderedDequeue = m_scene.UpdatePrioritizationScheme == UpdatePrioritizationSchemes.SimpleAngularDistance;
  5123. bool orderedDequeue = false; // for now
  5124. EntityUpdate update;
  5125. while (maxUpdateBytes > 0)
  5126. {
  5127. if(orderedDequeue)
  5128. {
  5129. if (!m_entityProps.TryOrderedDequeue(out update))
  5130. break;
  5131. }
  5132. else
  5133. {
  5134. if (!m_entityProps.TryDequeue(out update))
  5135. break;
  5136. }
  5137. if (update.PropsFlags == 0)
  5138. {
  5139. update.Free();
  5140. continue;
  5141. }
  5142. SceneObjectPart sop = (SceneObjectPart)update.Entity as SceneObjectPart;
  5143. if(sop == null)
  5144. {
  5145. update.Free();
  5146. continue;
  5147. }
  5148. used.Add(update);
  5149. if ((update.PropsFlags & ObjectPropertyUpdateFlags.Family) != 0)
  5150. {
  5151. if(objectPropertiesFamilyUpdates == null)
  5152. objectPropertiesFamilyUpdates = new List<EntityUpdate>();
  5153. objectPropertiesFamilyUpdates.Add(update);
  5154. maxUpdateBytes -= 100;
  5155. }
  5156. if ((update.PropsFlags & ObjectPropertyUpdateFlags.Object) != 0)
  5157. {
  5158. if(needPhysics == null)
  5159. needPhysics = new List<SceneObjectPart>();
  5160. needPhysics.Add(sop);
  5161. if(objectPropertiesUpdates == null)
  5162. objectPropertiesUpdates = new List<EntityUpdate>();
  5163. objectPropertiesUpdates.Add(update);
  5164. maxUpdateBytes -= 200; // aprox
  5165. }
  5166. }
  5167. if (objectPropertiesUpdates != null)
  5168. {
  5169. int blocks = objectPropertiesUpdates.Count;
  5170. //List<EntityUpdate> tau = new List<EntityUpdate>(30);
  5171. UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
  5172. Buffer.BlockCopy(ObjectPropertyUpdateHeader, 0, buf.Data, 0, 8);
  5173. LLUDPZeroEncoder zc = new LLUDPZeroEncoder(buf.Data);
  5174. zc.Position = 8;
  5175. zc.AddByte(1); // tmp block count
  5176. int countposition = zc.Position - 1;
  5177. int lastpos = 0;
  5178. int lastzc = 0;
  5179. int count = 0;
  5180. foreach (EntityUpdate eu in objectPropertiesUpdates)
  5181. {
  5182. lastpos = zc.Position;
  5183. lastzc = zc.ZeroCount;
  5184. CreateObjectPropertiesBlock((SceneObjectPart)eu.Entity, zc);
  5185. if (zc.Position < LLUDPServer.MAXPAYLOAD)
  5186. {
  5187. //tau.Add(eu);
  5188. ++count;
  5189. --blocks;
  5190. }
  5191. else if (blocks > 0)
  5192. {
  5193. // we need more packets
  5194. UDPPacketBuffer newbuf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
  5195. Buffer.BlockCopy(buf.Data, 0, newbuf.Data, 0, countposition); // start is the same
  5196. buf.Data[countposition] = (byte)count;
  5197. // get pending zeros at cut point
  5198. if (lastzc > 0)
  5199. {
  5200. buf.Data[lastpos++] = 0;
  5201. buf.Data[lastpos++] = (byte)lastzc;
  5202. }
  5203. buf.DataLength = lastpos;
  5204. //m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task,
  5205. // delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false, false);
  5206. m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task);
  5207. buf = newbuf;
  5208. zc.Data = buf.Data;
  5209. zc.ZeroCount = 0;
  5210. zc.Position = countposition + 1;
  5211. // im lazy now, just do last again
  5212. CreateObjectPropertiesBlock((SceneObjectPart)eu.Entity, zc);
  5213. //tau = new List<EntityUpdate>(30);
  5214. //tau.Add(eu);
  5215. count = 1;
  5216. --blocks;
  5217. }
  5218. }
  5219. if (count > 0)
  5220. {
  5221. buf.Data[countposition] = (byte)count;
  5222. buf.DataLength = zc.Finish();
  5223. //m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task,
  5224. // delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false, false);
  5225. m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task);
  5226. }
  5227. }
  5228. if (objectPropertiesFamilyUpdates != null)
  5229. {
  5230. foreach (EntityUpdate eu in objectPropertiesFamilyUpdates)
  5231. {
  5232. UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
  5233. Buffer.BlockCopy(ObjectFamilyUpdateHeader, 0, buf.Data, 0, 8);
  5234. LLUDPZeroEncoder zc = new LLUDPZeroEncoder(buf.Data);
  5235. zc.Position = 8;
  5236. CreateObjectPropertiesFamilyBlock((SceneObjectPart)eu.Entity, eu.Flags, zc);
  5237. buf.DataLength = zc.Finish();
  5238. //List<EntityUpdate> tau = new List<EntityUpdate>(1);
  5239. //tau.Add(new ObjectPropertyUpdate((ISceneEntity) eu, (uint)eu.Flags, true, false));
  5240. //m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task,
  5241. // delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false, false);
  5242. m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task);
  5243. }
  5244. }
  5245. if (needPhysics != null)
  5246. {
  5247. IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
  5248. if(eq != null)
  5249. {
  5250. osUTF8 sb = eq.StartEvent("ObjectPhysicsProperties");
  5251. LLSDxmlEncode2.AddArray("ObjectData", sb);
  5252. foreach (SceneObjectPart sop in needPhysics)
  5253. {
  5254. LLSDxmlEncode2.AddMap(sb);
  5255. LLSDxmlEncode2.AddElem("LocalID",(int)sop.LocalId, sb);
  5256. LLSDxmlEncode2.AddElem("Density", sop.Density, sb);
  5257. LLSDxmlEncode2.AddElem("Friction", sop.Friction, sb);
  5258. LLSDxmlEncode2.AddElem("GravityMultiplier", sop.GravityModifier, sb);
  5259. LLSDxmlEncode2.AddElem("Restitution", sop.Restitution, sb);
  5260. LLSDxmlEncode2.AddElem("PhysicsShapeType", (int)sop.PhysicsShapeType, sb);
  5261. LLSDxmlEncode2.AddEndMap(sb);
  5262. }
  5263. LLSDxmlEncode2.AddEndArray(sb);
  5264. eq.Enqueue(eq.EndEventToBytes(sb), m_agentId);
  5265. }
  5266. }
  5267. foreach(EntityUpdate eu in used)
  5268. eu.Free();
  5269. }
  5270. private void CreateObjectPropertiesFamilyBlock(SceneObjectPart sop, PrimUpdateFlags requestFlags, LLUDPZeroEncoder zc)
  5271. {
  5272. SceneObjectPart root = sop.ParentGroup.RootPart;
  5273. zc.AddUInt((uint)requestFlags);
  5274. zc.AddUUID(sop.UUID);
  5275. if (sop.OwnerID == sop.GroupID)
  5276. zc.AddZeros(16);
  5277. else
  5278. zc.AddUUID(sop.OwnerID);
  5279. zc.AddUUID(sop.GroupID);
  5280. zc.AddUInt(root.BaseMask);
  5281. zc.AddUInt(root.OwnerMask);
  5282. zc.AddUInt(root.GroupMask);
  5283. zc.AddUInt(root.EveryoneMask);
  5284. zc.AddUInt(root.NextOwnerMask);
  5285. zc.AddZeros(4); // int ownership cost
  5286. //sale info block
  5287. zc.AddByte(root.ObjectSaleType);
  5288. zc.AddInt(root.SalePrice);
  5289. zc.AddUInt(sop.Category); //Category
  5290. zc.AddUUID(sop.LastOwnerID);
  5291. //name
  5292. zc.AddShortLimitedUTF8(sop.osUTF8Name);
  5293. //Description
  5294. zc.AddShortLimitedUTF8(sop.osUTF8Description);
  5295. }
  5296. private void CreateObjectPropertiesBlock(SceneObjectPart sop, LLUDPZeroEncoder zc)
  5297. {
  5298. SceneObjectPart root = sop.ParentGroup.RootPart;
  5299. zc.AddUUID(sop.UUID);
  5300. zc.AddUUID(sop.CreatorID);
  5301. if (sop.OwnerID == sop.GroupID)
  5302. zc.AddZeros(16);
  5303. else
  5304. zc.AddUUID(sop.OwnerID);
  5305. zc.AddUUID(sop.GroupID);
  5306. zc.AddUInt64((ulong)sop.CreationDate * 1000000UL);
  5307. zc.AddUInt(root.BaseMask);
  5308. zc.AddUInt(root.OwnerMask);
  5309. zc.AddUInt(root.GroupMask);
  5310. zc.AddUInt(root.EveryoneMask);
  5311. zc.AddUInt(root.NextOwnerMask);
  5312. zc.AddZeros(4); // int ownership cost
  5313. //sale info block
  5314. zc.AddByte(root.ObjectSaleType);
  5315. zc.AddInt(root.SalePrice);
  5316. //aggregated perms we may will need to fix this
  5317. zc.AddByte(0); //AggregatePerms
  5318. zc.AddByte(0); //AggregatePermTextures;
  5319. zc.AddByte(0); //AggregatePermTexturesOwner
  5320. //inventory info
  5321. zc.AddUInt(sop.Category); //Category
  5322. zc.AddInt16((short)sop.InventorySerial);
  5323. zc.AddUUID(sop.FromUserInventoryItemID);
  5324. zc.AddUUID(UUID.Zero); //FolderID
  5325. zc.AddUUID(UUID.Zero); //FromTaskID
  5326. zc.AddUUID(sop.LastOwnerID);
  5327. //name
  5328. zc.AddShortLimitedUTF8(sop.osUTF8Name);
  5329. //Description
  5330. zc.AddShortLimitedUTF8(sop.osUTF8Description);
  5331. // touch name
  5332. zc.AddShortLimitedUTF8(sop.osUTF8TouchName);
  5333. // sit name
  5334. zc.AddShortLimitedUTF8(sop.osUTF8SitName);
  5335. //texture ids block
  5336. // still not sending, not clear the impact on viewers, if any.
  5337. // does seem redundant
  5338. // to send we will need proper list of face texture ids without having to unpack texture entry all the time
  5339. zc.AddZeros(1);
  5340. }
  5341. #region Estate Data Sending Methods
  5342. private static bool convertParamStringToBool(byte[] field)
  5343. {
  5344. string s = Utils.BytesToString(field);
  5345. if (s == "1" || s.ToLower() == "y" || s.ToLower() == "yes" || s.ToLower() == "t" || s.ToLower() == "true")
  5346. {
  5347. return true;
  5348. }
  5349. return false;
  5350. }
  5351. public void SendEstateList(UUID invoice, int code, UUID[] Data, uint estateID)
  5352. {
  5353. int TotalnumberIDs = Data.Length;
  5354. int numberIDs;
  5355. int IDIndex = 0;
  5356. do
  5357. {
  5358. if(TotalnumberIDs > 63)
  5359. numberIDs = 63;
  5360. else
  5361. numberIDs = TotalnumberIDs;
  5362. TotalnumberIDs -= numberIDs;
  5363. EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket();
  5364. packet.AgentData.TransactionID = UUID.Random();
  5365. packet.AgentData.AgentID = m_agentId;
  5366. packet.AgentData.SessionID = SessionId;
  5367. packet.MethodData.Invoice = invoice;
  5368. packet.MethodData.Method = Utils.StringToBytes("setaccess");
  5369. EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + numberIDs];
  5370. for (int i = 0; i < (6 + numberIDs); i++)
  5371. {
  5372. returnblock[i] = new EstateOwnerMessagePacket.ParamListBlock();
  5373. }
  5374. returnblock[0].Parameter = Utils.StringToBytes(estateID.ToString());
  5375. returnblock[1].Parameter = Utils.StringToBytes(code.ToString());
  5376. if((code & 1) != 0) // allowagents
  5377. returnblock[2].Parameter = Utils.StringToBytes(numberIDs.ToString());
  5378. else
  5379. returnblock[2].Parameter = Utils.StringToBytes("0");
  5380. if((code & 2) != 0) // groups
  5381. returnblock[3].Parameter = Utils.StringToBytes(numberIDs.ToString());
  5382. else
  5383. returnblock[3].Parameter = Utils.StringToBytes("0");
  5384. if((code & 4) != 0) // bans
  5385. returnblock[4].Parameter = Utils.StringToBytes(numberIDs.ToString());
  5386. else
  5387. returnblock[4].Parameter = Utils.StringToBytes("0");
  5388. if((code & 8) != 0) // managers
  5389. returnblock[5].Parameter = Utils.StringToBytes(numberIDs.ToString());
  5390. else
  5391. returnblock[5].Parameter = Utils.StringToBytes("0");
  5392. int j = 6;
  5393. for (int i = 0; i < numberIDs; i++)
  5394. {
  5395. returnblock[j].Parameter = Data[IDIndex].GetBytes();
  5396. j++;
  5397. IDIndex++;
  5398. }
  5399. packet.ParamList = returnblock;
  5400. packet.Header.Reliable = true;
  5401. OutPacket(packet, ThrottleOutPacketType.Task);
  5402. } while (TotalnumberIDs > 0);
  5403. }
  5404. public void SendBannedUserList(UUID invoice, EstateBan[] bl, uint estateID)
  5405. {
  5406. List<UUID> BannedUsers = new List<UUID>();
  5407. for (int i = 0; i < bl.Length; i++)
  5408. {
  5409. if (bl[i] == null)
  5410. continue;
  5411. if (bl[i].BannedUserID.IsZero())
  5412. continue;
  5413. BannedUsers.Add(bl[i].BannedUserID);
  5414. }
  5415. SendEstateList(invoice, 4, BannedUsers.ToArray(), estateID);
  5416. }
  5417. public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args)
  5418. {
  5419. RegionInfoPacket rinfopack = new RegionInfoPacket();
  5420. RegionInfoPacket.RegionInfoBlock rinfoblk = new RegionInfoPacket.RegionInfoBlock();
  5421. rinfopack.AgentData.AgentID = m_agentId;
  5422. rinfopack.AgentData.SessionID = SessionId;
  5423. rinfoblk.BillableFactor = args.billableFactor;
  5424. rinfoblk.EstateID = args.estateID;
  5425. rinfoblk.MaxAgents = (byte)args.maxAgents;
  5426. rinfoblk.ObjectBonusFactor = args.objectBonusFactor;
  5427. rinfoblk.ParentEstateID = args.parentEstateID;
  5428. rinfoblk.PricePerMeter = args.pricePerMeter;
  5429. rinfoblk.RedirectGridX = args.redirectGridX;
  5430. rinfoblk.RedirectGridY = args.redirectGridY;
  5431. rinfoblk.RegionFlags = args.regionFlags;
  5432. rinfoblk.SimAccess = args.simAccess;
  5433. rinfoblk.SunHour = args.sunHour;
  5434. rinfoblk.TerrainLowerLimit = args.terrainLowerLimit;
  5435. rinfoblk.TerrainRaiseLimit = args.terrainRaiseLimit;
  5436. rinfoblk.UseEstateSun = args.useEstateSun;
  5437. rinfoblk.WaterHeight = args.waterHeight;
  5438. rinfoblk.SimName = Utils.StringToBytes(args.simName);
  5439. rinfopack.RegionInfo2 = new RegionInfoPacket.RegionInfo2Block();
  5440. rinfopack.RegionInfo2.HardMaxAgents = (uint)args.AgentCapacity;
  5441. rinfopack.RegionInfo2.HardMaxObjects = (uint)args.ObjectsCapacity;
  5442. rinfopack.RegionInfo2.MaxAgents32 = (uint)args.maxAgents;
  5443. rinfopack.RegionInfo2.ProductName = Util.StringToBytes256(args.regionType);
  5444. rinfopack.RegionInfo2.ProductSKU = Utils.EmptyBytes;
  5445. rinfopack.HasVariableBlocks = true;
  5446. rinfopack.RegionInfo = rinfoblk;
  5447. rinfopack.AgentData = new RegionInfoPacket.AgentDataBlock();
  5448. rinfopack.AgentData.AgentID = m_agentId;
  5449. rinfopack.AgentData.SessionID = m_sessionId;
  5450. rinfopack.RegionInfo3 = new RegionInfoPacket.RegionInfo3Block[0];
  5451. OutPacket(rinfopack, ThrottleOutPacketType.Task);
  5452. }
  5453. public void SendEstateCovenantInformation(UUID covenant)
  5454. {
  5455. // m_log.DebugFormat("[LLCLIENTVIEW]: Sending estate covenant asset id of {0} to {1}", covenant, Name);
  5456. EstateCovenantReplyPacket einfopack = new EstateCovenantReplyPacket();
  5457. EstateCovenantReplyPacket.DataBlock edata = new EstateCovenantReplyPacket.DataBlock();
  5458. edata.CovenantID = covenant;
  5459. edata.CovenantTimestamp = (uint) m_scene.RegionInfo.RegionSettings.CovenantChangedDateTime;
  5460. edata.EstateOwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
  5461. edata.EstateName = Utils.StringToBytes(m_scene.RegionInfo.EstateSettings.EstateName);
  5462. einfopack.Data = edata;
  5463. OutPacket(einfopack, ThrottleOutPacketType.Task);
  5464. }
  5465. public void SendDetailedEstateData(
  5466. UUID invoice, string estateName, uint estateID, uint parentEstate, uint estateFlags, uint sunPosition,
  5467. UUID covenant, uint covenantChanged, string abuseEmail, UUID estateOwner)
  5468. {
  5469. // m_log.DebugFormat(
  5470. // "[LLCLIENTVIEW]: Sending detailed estate data to {0} with covenant asset id {1}", Name, covenant);
  5471. EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket();
  5472. packet.MethodData.Invoice = invoice;
  5473. packet.AgentData.TransactionID = UUID.Random();
  5474. packet.MethodData.Method = Utils.StringToBytes("estateupdateinfo");
  5475. EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[10];
  5476. for (int i = 0; i < 10; i++)
  5477. {
  5478. returnblock[i] = new EstateOwnerMessagePacket.ParamListBlock();
  5479. }
  5480. //Sending Estate Settings
  5481. returnblock[0].Parameter = Utils.StringToBytes(estateName);
  5482. returnblock[1].Parameter = Utils.StringToBytes(estateOwner.ToString());
  5483. returnblock[2].Parameter = Utils.StringToBytes(estateID.ToString());
  5484. returnblock[3].Parameter = Utils.StringToBytes(estateFlags.ToString());
  5485. returnblock[4].Parameter = Utils.StringToBytes(sunPosition.ToString());
  5486. returnblock[5].Parameter = Utils.StringToBytes(parentEstate.ToString());
  5487. returnblock[6].Parameter = Utils.StringToBytes(covenant.ToString());
  5488. returnblock[7].Parameter = Utils.StringToBytes(covenantChanged.ToString());
  5489. returnblock[8].Parameter = Utils.StringToBytes("1"); // what is this?
  5490. returnblock[9].Parameter = Utils.StringToBytes(abuseEmail);
  5491. packet.ParamList = returnblock;
  5492. //m_log.Debug("[ESTATE]: SIM--->" + packet.ToString());
  5493. OutPacket(packet, ThrottleOutPacketType.Task);
  5494. }
  5495. public void SendTelehubInfo(UUID ObjectID, string ObjectName, Vector3 ObjectPos, Quaternion ObjectRot, List<Vector3> SpawnPoint)
  5496. {
  5497. TelehubInfoPacket packet = (TelehubInfoPacket)PacketPool.Instance.GetPacket(PacketType.TelehubInfo);
  5498. packet.TelehubBlock.ObjectID = ObjectID;
  5499. packet.TelehubBlock.ObjectName = Utils.StringToBytes(ObjectName);
  5500. packet.TelehubBlock.TelehubPos = ObjectPos;
  5501. packet.TelehubBlock.TelehubRot = ObjectRot;
  5502. packet.SpawnPointBlock = new TelehubInfoPacket.SpawnPointBlockBlock[SpawnPoint.Count];
  5503. for (int n = 0; n < SpawnPoint.Count; n++)
  5504. {
  5505. packet.SpawnPointBlock[n] = new TelehubInfoPacket.SpawnPointBlockBlock{SpawnPointPos = SpawnPoint[n]};
  5506. }
  5507. OutPacket(packet, ThrottleOutPacketType.Task);
  5508. }
  5509. #endregion
  5510. #region Land Data Sending Methods
  5511. public void SendLandParcelOverlay(byte[] data, int sequence_id)
  5512. {
  5513. ParcelOverlayPacket packet = (ParcelOverlayPacket)PacketPool.Instance.GetPacket(PacketType.ParcelOverlay);
  5514. packet.ParcelData.Data = data;
  5515. packet.ParcelData.SequenceID = sequence_id;
  5516. // OutPacket(packet, ThrottleOutPacketType.Task);
  5517. OutPacket(packet, ThrottleOutPacketType.Land);
  5518. }
  5519. public void SendLandProperties(
  5520. int sequence_id, bool snap_selection, int request_result, ILandObject lo,
  5521. float simObjectBonusFactor, int parcelObjectCapacity, int simObjectCapacity, uint regionFlags)
  5522. {
  5523. // m_log.DebugFormat("[LLCLIENTVIEW]: Sending land properties for {0} to {1}", lo.LandData.GlobalID, Name);
  5524. IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
  5525. if (eq == null)
  5526. {
  5527. m_log.Warn("[LLCLIENTVIEW]: No EQ Interface when sending parcel data.");
  5528. return;
  5529. }
  5530. LandData landData = lo.LandData;
  5531. IPrimCounts pc = lo.PrimCounts;
  5532. int cap = 4 * landData.Bitmap.Length / 3 + 2048;
  5533. osUTF8 sb = eq.StartEvent("ParcelProperties", cap);
  5534. LLSDxmlEncode2.AddArrayAndMap("ParcelData", sb);
  5535. LLSDxmlEncode2.AddElem("LocalID", landData.LocalID, sb);
  5536. LLSDxmlEncode2.AddElem("AABBMax", landData.AABBMax, sb);
  5537. LLSDxmlEncode2.AddElem("AABBMin", landData.AABBMin, sb);
  5538. LLSDxmlEncode2.AddElem("Area", landData.Area, sb);
  5539. LLSDxmlEncode2.AddElem("AuctionID", (int)landData.AuctionID, sb);
  5540. LLSDxmlEncode2.AddElem("AuthBuyerID", landData.AuthBuyerID, sb);
  5541. LLSDxmlEncode2.AddElem("Bitmap", landData.Bitmap, sb);
  5542. LLSDxmlEncode2.AddElem("Category", (int)landData.Category, sb);
  5543. LLSDxmlEncode2.AddElem("ClaimDate", Util.ToDateTime(landData.ClaimDate), sb);
  5544. LLSDxmlEncode2.AddElem("ClaimPrice", landData.ClaimPrice, sb);
  5545. LLSDxmlEncode2.AddElem("Desc", landData.Description, sb);
  5546. LLSDxmlEncode2.AddElem("ParcelFlags", landData.Flags, sb);
  5547. LLSDxmlEncode2.AddElem("GroupID", landData.GroupID, sb);
  5548. LLSDxmlEncode2.AddElem("GroupPrims", pc.Group, sb);
  5549. LLSDxmlEncode2.AddElem("IsGroupOwned", landData.IsGroupOwned, sb);
  5550. LLSDxmlEncode2.AddElem("LandingType", (int)landData.LandingType, sb);
  5551. if (landData.Area > 0)
  5552. LLSDxmlEncode2.AddElem("MaxPrims", parcelObjectCapacity, sb);
  5553. else
  5554. LLSDxmlEncode2.AddElem("MaxPrims", (int)0, sb);
  5555. LLSDxmlEncode2.AddElem("MediaID", landData.MediaID, sb);
  5556. LLSDxmlEncode2.AddElem("MediaURL", landData.MediaURL, sb);
  5557. LLSDxmlEncode2.AddElem("MediaAutoScale", landData.MediaAutoScale != 0, sb);
  5558. LLSDxmlEncode2.AddElem("MusicURL", landData.MusicURL, sb);
  5559. LLSDxmlEncode2.AddElem("Name", landData.Name, sb);
  5560. LLSDxmlEncode2.AddElem("OtherCleanTime", landData.OtherCleanTime, sb);
  5561. LLSDxmlEncode2.AddElem("OtherCount", (int)0 , sb); //TODO
  5562. LLSDxmlEncode2.AddElem("OtherPrims", pc.Others, sb);
  5563. LLSDxmlEncode2.AddElem("OwnerID", landData.OwnerID, sb);
  5564. LLSDxmlEncode2.AddElem("OwnerPrims", pc.Owner, sb);
  5565. LLSDxmlEncode2.AddElem("ParcelPrimBonus", simObjectBonusFactor, sb);
  5566. LLSDxmlEncode2.AddElem("PassHours", landData.PassHours, sb);
  5567. LLSDxmlEncode2.AddElem("PassPrice", landData.PassPrice, sb);
  5568. LLSDxmlEncode2.AddElem("PublicCount", (int)0, sb); //TODO
  5569. LLSDxmlEncode2.AddElem("RegionDenyAnonymous", (regionFlags & (uint)RegionFlags.DenyAnonymous) != 0, sb);
  5570. LLSDxmlEncode2.AddElem("RegionDenyIdentified", false, sb);
  5571. LLSDxmlEncode2.AddElem("RegionDenyTransacted", false, sb);
  5572. LLSDxmlEncode2.AddElem("RegionPushOverride", (regionFlags & (uint)RegionFlags.RestrictPushObject) != 0, sb);
  5573. LLSDxmlEncode2.AddElem("RentPrice", (int) 0, sb);;
  5574. LLSDxmlEncode2.AddElem("RequestResult", request_result, sb);
  5575. LLSDxmlEncode2.AddElem("SalePrice", landData.SalePrice, sb);
  5576. LLSDxmlEncode2.AddElem("SelectedPrims", pc.Selected, sb);
  5577. LLSDxmlEncode2.AddElem("SelfCount", (int)0, sb); //TODO
  5578. LLSDxmlEncode2.AddElem("SequenceID", sequence_id, sb);
  5579. if (landData.SimwideArea > 0)
  5580. LLSDxmlEncode2.AddElem("SimWideMaxPrims", lo.GetSimulatorMaxPrimCount(), sb);
  5581. else
  5582. LLSDxmlEncode2.AddElem("SimWideMaxPrims", (int)0, sb);
  5583. LLSDxmlEncode2.AddElem("SimWideTotalPrims", pc.Simulator, sb);
  5584. LLSDxmlEncode2.AddElem("SnapSelection", snap_selection, sb);
  5585. LLSDxmlEncode2.AddElem("SnapshotID", landData.SnapshotID, sb);
  5586. LLSDxmlEncode2.AddElem("Status", (int)landData.Status, sb);
  5587. LLSDxmlEncode2.AddElem("TotalPrims", pc.Total, sb);
  5588. LLSDxmlEncode2.AddElem("UserLocation", landData.UserLocation, sb);
  5589. LLSDxmlEncode2.AddElem("UserLookAt", landData.UserLookAt, sb);
  5590. LLSDxmlEncode2.AddElem("SeeAVs", landData.SeeAVs, sb);
  5591. LLSDxmlEncode2.AddElem("AnyAVSounds", landData.AnyAVSounds, sb);
  5592. LLSDxmlEncode2.AddElem("GroupAVSounds", landData.GroupAVSounds, sb);
  5593. LLSDxmlEncode2.AddEndMapAndArray(sb);
  5594. LLSDxmlEncode2.AddArrayAndMap("MediaData", sb);
  5595. LLSDxmlEncode2.AddElem("MediaDesc", landData.MediaDescription, sb);
  5596. LLSDxmlEncode2.AddElem("MediaHeight", landData.MediaHeight, sb);
  5597. LLSDxmlEncode2.AddElem("MediaWidth", landData.MediaWidth, sb);
  5598. LLSDxmlEncode2.AddElem("MediaLoop", landData.MediaLoop, sb);
  5599. LLSDxmlEncode2.AddElem("MediaType", landData.MediaType, sb);
  5600. //LLSDxmlEncode2.AddElem("ObscureMedia", landData.ObscureMedia, sb);
  5601. LLSDxmlEncode2.AddElem("ObscureMedia", false, sb); //obsolete
  5602. //LLSDxmlEncode2.AddElem("ObscureMusic", landData.ObscureMusic, sb);
  5603. LLSDxmlEncode2.AddElem("ObscureMusic", false, sb); //obsolete
  5604. LLSDxmlEncode2.AddEndMapAndArray(sb);
  5605. LLSDxmlEncode2.AddArrayAndMap("ParcelExtendedFlags", sb); // obscure moap
  5606. LLSDxmlEncode2.AddElem("Flags", (uint)(landData.ObscureMedia ? 1 : (int)0), sb);
  5607. LLSDxmlEncode2.AddEndMapAndArray(sb);
  5608. LLSDxmlEncode2.AddArrayAndMap("AgeVerificationBlock", sb);
  5609. LLSDxmlEncode2.AddElem("RegionDenyAgeUnverified", (regionFlags & (uint)RegionFlags.DenyAgeUnverified) != 0, sb);
  5610. LLSDxmlEncode2.AddEndMapAndArray(sb);
  5611. bool allowenvovr = (regionFlags & (uint)RegionFlags.AllowEnvironmentOverride) != 0;
  5612. int envVersion;
  5613. if(allowenvovr)
  5614. {
  5615. ScenePresence sp = SceneAgent as ScenePresence;
  5616. if(sp != null && sp.EnvironmentVersion > 0)
  5617. envVersion = -1;
  5618. else
  5619. envVersion = landData.EnvironmentVersion;
  5620. }
  5621. else
  5622. envVersion = -1;
  5623. LLSDxmlEncode2.AddArrayAndMap("ParcelEnvironmentBlock", sb);
  5624. LLSDxmlEncode2.AddElem("ParcelEnvironmentVersion", envVersion, sb);
  5625. LLSDxmlEncode2.AddElem("RegionAllowEnvironmentOverride", allowenvovr, sb);
  5626. LLSDxmlEncode2.AddEndMapAndArray(sb);
  5627. bool accessovr = !Scene.RegionInfo.EstateSettings.TaxFree;
  5628. LLSDxmlEncode2.AddArrayAndMap("RegionAllowAccessBlock", sb);
  5629. LLSDxmlEncode2.AddElem("RegionAllowAccessOverride", accessovr, sb);
  5630. LLSDxmlEncode2.AddEndMapAndArray(sb);
  5631. eq.Enqueue(eq.EndEventToBytes(sb), m_agentId);
  5632. }
  5633. public void SendLandAccessListData(List<LandAccessEntry> accessList, uint accessFlag, int localLandID)
  5634. {
  5635. ParcelAccessListReplyPacket replyPacket = (ParcelAccessListReplyPacket)PacketPool.Instance.GetPacket(PacketType.ParcelAccessListReply);
  5636. replyPacket.Data.AgentID = m_agentId;
  5637. replyPacket.Data.Flags = accessFlag;
  5638. replyPacket.Data.LocalID = localLandID;
  5639. replyPacket.Data.SequenceID = 0;
  5640. List<ParcelAccessListReplyPacket.ListBlock> list = new List<ParcelAccessListReplyPacket.ListBlock>();
  5641. foreach (LandAccessEntry entry in accessList)
  5642. {
  5643. ParcelAccessListReplyPacket.ListBlock block = new ParcelAccessListReplyPacket.ListBlock();
  5644. block.Flags = accessFlag;
  5645. block.ID = entry.AgentID;
  5646. block.Time = entry.Expires;
  5647. list.Add(block);
  5648. }
  5649. replyPacket.List = list.ToArray();
  5650. replyPacket.Header.Zerocoded = true;
  5651. OutPacket(replyPacket, ThrottleOutPacketType.Task);
  5652. }
  5653. public void SendForceClientSelectObjects(List<uint> ObjectIDs)
  5654. {
  5655. // m_log.DebugFormat("[LLCLIENTVIEW] sending select with {0} objects", ObjectIDs.Count);
  5656. bool firstCall = true;
  5657. const int MAX_OBJECTS_PER_PACKET = 251;
  5658. ForceObjectSelectPacket pack = (ForceObjectSelectPacket)PacketPool.Instance.GetPacket(PacketType.ForceObjectSelect);
  5659. ForceObjectSelectPacket.DataBlock[] data;
  5660. while (ObjectIDs.Count > 0)
  5661. {
  5662. if (firstCall)
  5663. {
  5664. pack._Header.ResetList = true;
  5665. firstCall = false;
  5666. }
  5667. else
  5668. {
  5669. pack._Header.ResetList = false;
  5670. }
  5671. if (ObjectIDs.Count > MAX_OBJECTS_PER_PACKET)
  5672. {
  5673. data = new ForceObjectSelectPacket.DataBlock[MAX_OBJECTS_PER_PACKET];
  5674. }
  5675. else
  5676. {
  5677. data = new ForceObjectSelectPacket.DataBlock[ObjectIDs.Count];
  5678. }
  5679. int i;
  5680. for (i = 0; i < MAX_OBJECTS_PER_PACKET && ObjectIDs.Count > 0; i++)
  5681. {
  5682. data[i] = new ForceObjectSelectPacket.DataBlock();
  5683. data[i].LocalID = Convert.ToUInt32(ObjectIDs[0]);
  5684. ObjectIDs.RemoveAt(0);
  5685. }
  5686. pack.Data = data;
  5687. pack.Header.Zerocoded = true;
  5688. OutPacket(pack, ThrottleOutPacketType.Task);
  5689. }
  5690. }
  5691. public void SendCameraConstraint(Vector4 ConstraintPlane)
  5692. {
  5693. CameraConstraintPacket cpack = (CameraConstraintPacket)PacketPool.Instance.GetPacket(PacketType.CameraConstraint);
  5694. cpack.CameraCollidePlane = new CameraConstraintPacket.CameraCollidePlaneBlock();
  5695. cpack.CameraCollidePlane.Plane = ConstraintPlane;
  5696. //m_log.DebugFormat("[CLIENTVIEW]: Constraint {0}", ConstraintPlane);
  5697. OutPacket(cpack, ThrottleOutPacketType.Task);
  5698. }
  5699. public void SendLandObjectOwners(LandData land, List<UUID> groups, Dictionary<UUID, int> ownersAndCount)
  5700. {
  5701. int notifyCount = ownersAndCount.Count;
  5702. ParcelObjectOwnersReplyPacket pack = (ParcelObjectOwnersReplyPacket)PacketPool.Instance.GetPacket(PacketType.ParcelObjectOwnersReply);
  5703. if (notifyCount > 0)
  5704. {
  5705. // if (notifyCount > 32)
  5706. // {
  5707. // m_log.InfoFormat(
  5708. // "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
  5709. // + " - a developer might want to investigate whether this is a hard limit", 32);
  5710. //
  5711. // notifyCount = 32;
  5712. // }
  5713. ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
  5714. = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
  5715. int num = 0;
  5716. foreach (UUID owner in ownersAndCount.Keys)
  5717. {
  5718. dataBlock[num] = new ParcelObjectOwnersReplyPacket.DataBlock();
  5719. dataBlock[num].Count = ownersAndCount[owner];
  5720. if (land.GroupID == owner || groups.Contains(owner))
  5721. dataBlock[num].IsGroupOwned = true;
  5722. dataBlock[num].OnlineStatus = true; //TODO: fix me later
  5723. dataBlock[num].OwnerID = owner;
  5724. num++;
  5725. if (num >= notifyCount)
  5726. {
  5727. break;
  5728. }
  5729. }
  5730. pack.Data = dataBlock;
  5731. }
  5732. else
  5733. {
  5734. pack.Data = new ParcelObjectOwnersReplyPacket.DataBlock[0];
  5735. }
  5736. pack.Header.Zerocoded = true;
  5737. this.OutPacket(pack, ThrottleOutPacketType.Task);
  5738. }
  5739. #endregion
  5740. #region Helper Methods
  5741. private void ClampVectorForUint(ref Vector3 v, float max)
  5742. {
  5743. float a, b;
  5744. a = Math.Abs(v.X);
  5745. b = Math.Abs(v.Y);
  5746. if (b > a)
  5747. a = b;
  5748. b = Math.Abs(v.Z);
  5749. if (b > a)
  5750. a = b;
  5751. if (a > max)
  5752. {
  5753. a = max / a;
  5754. v.X *= a;
  5755. v.Y *= a;
  5756. v.Z *= a;
  5757. }
  5758. }
  5759. protected void CreateImprovedTerseBlock(ISceneEntity entity, byte[] data, ref int pos, bool includeTexture)
  5760. {
  5761. #region ScenePresence/SOP Handling
  5762. bool avatar = (entity is ScenePresence);
  5763. uint attachPoint;
  5764. Vector4 collisionPlane;
  5765. Vector3 position, velocity, acceleration, angularVelocity;
  5766. Quaternion rotation;
  5767. byte datasize;
  5768. byte[] te = null;
  5769. if (avatar)
  5770. {
  5771. ScenePresence presence = (ScenePresence)entity;
  5772. position = presence.OffsetPosition;
  5773. velocity = presence.Velocity;
  5774. acceleration = Vector3.Zero;
  5775. rotation = presence.Rotation;
  5776. // tpvs can only see rotations around Z in some cases
  5777. if (!presence.Flying && !presence.IsSatOnObject)
  5778. {
  5779. rotation.X = 0f;
  5780. rotation.Y = 0f;
  5781. }
  5782. rotation.Normalize();
  5783. angularVelocity = presence.AngularVelocity;
  5784. //m_log.DebugFormat(
  5785. // "[LLCLIENTVIEW]: Sending terse update to {0} with position {1} in {2}", Name, presence.OffsetPosition, m_scene.Name);
  5786. attachPoint = presence.State;
  5787. collisionPlane = presence.CollisionPlane;
  5788. datasize = 60;
  5789. }
  5790. else
  5791. {
  5792. SceneObjectPart part = (SceneObjectPart)entity;
  5793. attachPoint = part.ParentGroup.AttachmentPoint;
  5794. attachPoint = ((attachPoint % 16) * 16 + (attachPoint / 16));
  5795. //m_log.DebugFormat(
  5796. // "[LLCLIENTVIEW]: Sending attachPoint {0} for {1} {2} to {3}",
  5797. // attachPoint, part.Name, part.LocalId, Name);
  5798. collisionPlane = Vector4.Zero;
  5799. position = part.RelativePosition;
  5800. velocity = part.Velocity;
  5801. acceleration = part.Acceleration;
  5802. angularVelocity = part.AngularVelocity;
  5803. rotation = part.RotationOffset;
  5804. datasize = 44;
  5805. if (includeTexture)
  5806. te = part.Shape.TextureEntry;
  5807. }
  5808. #endregion ScenePresence/SOP Handling
  5809. //object block size
  5810. data[pos++] = datasize;
  5811. // LocalID
  5812. Utils.UIntToBytes(entity.LocalId, data, pos);
  5813. pos += 4;
  5814. data[pos++] = (byte)attachPoint;
  5815. // Avatar/CollisionPlane
  5816. if (avatar)
  5817. {
  5818. data[pos++] = 1;
  5819. //m_log.DebugFormat("CollisionPlane: {0}",collisionPlane);
  5820. if (collisionPlane == Vector4.Zero)
  5821. Vector4.UnitW.ToBytes(data, pos);
  5822. else
  5823. collisionPlane.ToBytes(data, pos);
  5824. pos += 16;
  5825. }
  5826. else
  5827. {
  5828. data[pos++] = 0;
  5829. }
  5830. // Position
  5831. position.ToBytes(data, pos);
  5832. pos += 12;
  5833. // Velocity
  5834. ClampVectorForUint(ref velocity, 128f);
  5835. Utils.FloatToUInt16Bytes(velocity.X, 128.0f, data, pos); pos += 2;
  5836. Utils.FloatToUInt16Bytes(velocity.Y, 128.0f, data, pos); pos += 2;
  5837. Utils.FloatToUInt16Bytes(velocity.Z, 128.0f, data, pos); pos += 2;
  5838. // Acceleration
  5839. ClampVectorForUint(ref acceleration, 64f);
  5840. Utils.FloatToUInt16Bytes(acceleration.X, 64.0f, data, pos); pos += 2;
  5841. Utils.FloatToUInt16Bytes(acceleration.Y, 64.0f, data, pos); pos += 2;
  5842. Utils.FloatToUInt16Bytes(acceleration.Z, 64.0f, data, pos); pos += 2;
  5843. // Rotation
  5844. Utils.FloatToUInt16Bytes(rotation.X, 1.0f, data, pos); pos += 2;
  5845. Utils.FloatToUInt16Bytes(rotation.Y, 1.0f, data, pos); pos += 2;
  5846. Utils.FloatToUInt16Bytes(rotation.Z, 1.0f, data, pos); pos += 2;
  5847. Utils.FloatToUInt16Bytes(rotation.W, 1.0f, data, pos); pos += 2;
  5848. // Angular Velocity
  5849. ClampVectorForUint(ref angularVelocity, 64f);
  5850. Utils.FloatToUInt16Bytes(angularVelocity.X, 64.0f, data, pos); pos += 2;
  5851. Utils.FloatToUInt16Bytes(angularVelocity.Y, 64.0f, data, pos); pos += 2;
  5852. Utils.FloatToUInt16Bytes(angularVelocity.Z, 64.0f, data, pos); pos += 2;
  5853. // texture entry block size
  5854. if (te == null)
  5855. {
  5856. data[pos++] = 0;
  5857. data[pos++] = 0;
  5858. }
  5859. else
  5860. {
  5861. int len = te.Length & 0x7fff;
  5862. int totlen = len + 4;
  5863. data[pos++] = (byte)totlen;
  5864. data[pos++] = (byte)(totlen >> 8);
  5865. data[pos++] = (byte)len; // wtf ???
  5866. data[pos++] = (byte)(len >> 8);
  5867. data[pos++] = 0;
  5868. data[pos++] = 0;
  5869. Buffer.BlockCopy(te, 0, data, pos, len);
  5870. pos += len;
  5871. }
  5872. // total size 63 or 47 + (texture size + 4)
  5873. }
  5874. protected void CreatePartImprovedTerseBlock(SceneObjectPart part, byte[] data, ref int pos, bool includeTexture)
  5875. {
  5876. //object block size
  5877. data[pos++] = 44;
  5878. // LocalID
  5879. Utils.UIntToBytesSafepos(part.LocalId, data, pos);
  5880. pos += 4;
  5881. if (part.ParentGroup.AttachmentPoint == 0)
  5882. data[pos++] = 0;
  5883. else
  5884. {
  5885. uint attachPoint = 0xff & part.ParentGroup.AttachmentPoint;
  5886. data[pos++] = (byte)(attachPoint << 4 | attachPoint >> 4);
  5887. }
  5888. // no Avatar/CollisionPlane
  5889. data[pos++] = 0;
  5890. // Position
  5891. part.RelativePosition.ToBytes(data, pos);
  5892. pos += 12;
  5893. // Velocity
  5894. part.Velocity.ClampedToShortsBytes(128f, data, pos); pos += 6;
  5895. // Acceleration
  5896. part.Acceleration.ClampedToShortsBytes(64f, data, pos); pos += 6;
  5897. // Rotation
  5898. part.RotationOffset.ToShortsBytes(data, pos); pos += 8;
  5899. // Angular Velocity
  5900. part.AngularVelocity.ClampedToShortsBytes(64f, data, pos); pos += 6;
  5901. // texture entry block size
  5902. if (includeTexture && part.Shape.TextureEntry != null)
  5903. {
  5904. byte[] te = part.Shape.TextureEntry;
  5905. int len = te.Length & 0x7fff;
  5906. int totlen = len + 4;
  5907. data[pos++] = (byte)totlen;
  5908. data[pos++] = (byte)(totlen >> 8);
  5909. data[pos++] = (byte)len; // wtf ???
  5910. data[pos++] = (byte)(len >> 8);
  5911. data[pos++] = 0;
  5912. data[pos++] = 0;
  5913. Buffer.BlockCopy(te, 0, data, pos, len);
  5914. pos += len;
  5915. }
  5916. else
  5917. {
  5918. data[pos++] = 0;
  5919. data[pos++] = 0;
  5920. }
  5921. // total size 47 + (texture size + 4)
  5922. }
  5923. protected unsafe void CreatePartImprovedTerseBlock(SceneObjectPart part, ref byte* data, bool includeTexture)
  5924. {
  5925. //object block size
  5926. *data++ = 44;
  5927. // LocalID
  5928. Utils.UIntToBytes(part.LocalId, data); data += 4;
  5929. if (part.ParentGroup.AttachmentPoint == 0)
  5930. *data++ = 0;
  5931. else
  5932. {
  5933. uint attachPoint = 0xff & part.ParentGroup.AttachmentPoint;
  5934. *data++ = (byte)(attachPoint << 4 | attachPoint >> 4);
  5935. }
  5936. // no Avatar/CollisionPlane
  5937. *data++ = 0;
  5938. // Position
  5939. part.RelativePosition.ToBytes(data); data += 12;
  5940. // Velocity
  5941. part.Velocity.ClampedToShortsBytes(128f, data); data += 6;
  5942. // Acceleration
  5943. part.Acceleration.ClampedToShortsBytes(64f, data); data += 6;
  5944. // Rotation
  5945. part.RotationOffset.ToShortsBytes(data); data += 8;
  5946. // Angular Velocity
  5947. part.AngularVelocity.ClampedToShortsBytes(64f, data); data += 6;
  5948. // texture entry block size
  5949. if (includeTexture && part.Shape.TextureEntry != null)
  5950. {
  5951. byte[] te = part.Shape.TextureEntry;
  5952. uint len = (uint)te.Length & 0x7fff;
  5953. ushort totlen = (ushort)(len + 4);
  5954. Utils.UInt16ToBytes(totlen, data); data += 2;
  5955. Utils.UIntToBytes(len, data); data += 4;
  5956. fixed(byte* t = &te[0])
  5957. Buffer.MemoryCopy(t, data, 4096, (long)len);
  5958. data += len;
  5959. }
  5960. else
  5961. {
  5962. *data++ = 0;
  5963. *data++ = 0;
  5964. }
  5965. // total size 47 + (texture size + 4)
  5966. }
  5967. protected void CreateAvatartImprovedTerseBlock(ScenePresence presence, byte[] data, ref int pos)
  5968. {
  5969. //m_log.DebugFormat(
  5970. // "[LLCLIENTVIEW]: Sending terse update to {0} with position {1} in {2}", Name, presence.OffsetPosition, m_scene.Name);
  5971. //object block size
  5972. data[pos++] = 60;
  5973. // LocalID
  5974. Utils.UIntToBytesSafepos(presence.LocalId, data, pos);
  5975. pos += 4;
  5976. data[pos++] = presence.State;
  5977. // Avatar/CollisionPlane
  5978. data[pos++] = 1;
  5979. //m_log.DebugFormat("CollisionPlane: {0}",collisionPlane);
  5980. if (presence.CollisionPlane.IsZero())
  5981. Vector4.UnitW.ToBytes(data, pos);
  5982. else
  5983. presence.CollisionPlane.ToBytes(data, pos);
  5984. pos += 16;
  5985. // Position
  5986. presence.OffsetPosition.ToBytes(data, pos);
  5987. pos += 12;
  5988. // Velocity
  5989. presence.Velocity.ClampedToShortsBytes(128f, data, pos); pos += 6;
  5990. // Acceleration is zero
  5991. Utils.UIntToBytesSafepos(0x7fff7fff, data, pos); pos += 4;
  5992. Utils.UInt16ToBytes(0x7fff, data, pos); pos += 2;
  5993. // Rotation
  5994. // tpvs can only see rotations around Z in some cases
  5995. Quaternion rotation = presence.Rotation;
  5996. if (!presence.Flying && !presence.IsSatOnObject)
  5997. {
  5998. Utils.UIntToBytesSafepos(0x7fff7fff, data, pos); pos += 4;
  5999. float rz = rotation.Z;
  6000. float rw = rotation.W;
  6001. float a = rz * rz + rw * rw;
  6002. if (a > -1e-6f && a < 1e-6f)
  6003. {
  6004. Utils.UIntToBytesSafepos(0xffff7fff, data, pos); pos += 4;
  6005. }
  6006. else
  6007. {
  6008. a = 1.0f / (float)Math.Sqrt(a);
  6009. Utils.FloatToUInt16Bytes(rz * a, 1.0f, data, pos); pos += 2;
  6010. Utils.FloatToUInt16Bytes(rw * a, 1.0f, data, pos); pos += 2;
  6011. }
  6012. }
  6013. else
  6014. {
  6015. rotation.ToShortsBytes(data, pos); pos += 8;
  6016. }
  6017. // Angular Velocity
  6018. presence.AngularVelocity.ClampedToShortsBytes(64f, data, pos); pos += 6;
  6019. //texture
  6020. data[pos++] = 0;
  6021. data[pos++] = 0;
  6022. // total size 63
  6023. }
  6024. protected unsafe void CreateAvatartImprovedTerseBlock(ScenePresence presence, ref byte* data)
  6025. {
  6026. //m_log.DebugFormat(
  6027. // "[LLCLIENTVIEW]: Sending terse update to {0} with position {1} in {2}", Name, presence.OffsetPosition, m_scene.Name);
  6028. //object block size
  6029. *data++ = 60;
  6030. // LocalID
  6031. Utils.UIntToBytes(presence.LocalId, data); data += 4;
  6032. *data++ = presence.State;
  6033. // Avatar/CollisionPlane
  6034. *data++ = 1;
  6035. //m_log.DebugFormat("CollisionPlane: {0}",collisionPlane);
  6036. if (presence.CollisionPlane.IsZero())
  6037. Vector4.UnitW.ToBytes(data);
  6038. else
  6039. presence.CollisionPlane.ToBytes(data);
  6040. data += 16;
  6041. // Position
  6042. presence.OffsetPosition.ToBytes(data); data += 12;
  6043. // Velocity
  6044. presence.Velocity.ClampedToShortsBytes(128f, data); data += 6;
  6045. // Acceleration is zero
  6046. Utils.UIntToBytes(0x7fff7fff, data); data += 4;
  6047. Utils.UInt16ToBytes(0x7fff, data); data += 2;
  6048. // Rotation
  6049. // tpvs can only see rotations around Z in some cases
  6050. Quaternion rotation = presence.Rotation;
  6051. if (!presence.Flying && !presence.IsSatOnObject)
  6052. {
  6053. Utils.UIntToBytes(0x7fff7fff, data); data += 4;
  6054. float rz = rotation.Z;
  6055. float rw = rotation.W;
  6056. float a = rz * rz + rw * rw;
  6057. if (a > -1e-6f && a < 1e-6f)
  6058. {
  6059. Utils.UIntToBytes(0xffff7fff, data); data += 4;
  6060. }
  6061. else
  6062. {
  6063. a = 1.0f / (float)Math.Sqrt(a);
  6064. Utils.UInt16ToBytes(Utils.FloatToUnitUInt16(rz * a), data); data += 2;
  6065. Utils.UInt16ToBytes(Utils.FloatToUnitUInt16(rw * a), data); data += 2;
  6066. }
  6067. }
  6068. else
  6069. {
  6070. rotation.ToShortsBytes(data); data += 8;
  6071. }
  6072. // Angular Velocity
  6073. presence.AngularVelocity.ClampedToShortsBytes(64f, data); data += 6;
  6074. //texture
  6075. *data++ = 0;
  6076. *data++ = 0;
  6077. // total size 63
  6078. }
  6079. protected void CreateAvatarUpdateBlock(ScenePresence data, byte[] dest, ref int pos)
  6080. {
  6081. Utils.UIntToBytesSafepos(data.LocalId, dest, pos); pos += 4;
  6082. dest[pos++] = 0; // state
  6083. data.UUID.ToBytes(dest, pos); pos += 16;
  6084. Utils.UIntToBytesSafepos(0 , dest, pos); pos += 4; // crc
  6085. dest[pos++] = (byte)PCode.Avatar;
  6086. dest[pos++] = (byte)Material.Flesh;
  6087. dest[pos++] = 0; // clickaction
  6088. data.Appearance.AvatarSize.ToBytes(dest, pos); pos += 12;
  6089. // objectdata block
  6090. dest[pos++] = 76;
  6091. data.CollisionPlane.ToBytes(dest, pos); pos += 16;
  6092. data.OffsetPosition.ToBytes(dest, pos); pos += 12;
  6093. data.Velocity.ToBytes(dest, pos); pos += 12;
  6094. //acceleration.ToBytes(dest, pos); pos += 12;
  6095. Array.Clear(dest, pos, 12); pos += 12;
  6096. Quaternion rotation = data.Rotation;
  6097. // tpvs can only see rotations around Z in some cases
  6098. if (!data.Flying && !data.IsSatOnObject)
  6099. {
  6100. rotation.X = 0f;
  6101. rotation.Y = 0f;
  6102. }
  6103. rotation.ToBytes(dest, pos); pos += 12;
  6104. //angularvelocity.ToBytes(dest, pos); pos += 12;
  6105. Array.Clear(dest, pos, 12); pos += 12;
  6106. SceneObjectPart parentPart = data.ParentPart;
  6107. if (parentPart != null)
  6108. {
  6109. Utils.UIntToBytesSafepos(parentPart.ParentGroup.LocalId, dest, pos);
  6110. pos += 4;
  6111. }
  6112. else
  6113. {
  6114. //Utils.UIntToBytesSafepos(0, dest, pos);
  6115. //pos += 4;
  6116. dest[pos++] = 0;
  6117. dest[pos++] = 0;
  6118. dest[pos++] = 0;
  6119. dest[pos++] = 0;
  6120. }
  6121. //Utils.UIntToBytesSafepos(0, dest, pos); pos += 4; //update flags
  6122. dest[pos++] = 0;
  6123. dest[pos++] = 0;
  6124. dest[pos++] = 0;
  6125. dest[pos++] = 0;
  6126. //pbs
  6127. dest[pos++] = 16;
  6128. dest[pos++] = 1;
  6129. //Utils.UInt16ToBytes(0, dest, pos); pos += 2;
  6130. //Utils.UInt16ToBytes(0, dest, pos); pos += 2;
  6131. dest[pos++] = 0;
  6132. dest[pos++] = 0;
  6133. dest[pos++] = 0;
  6134. dest[pos++] = 0;
  6135. dest[pos++] = 100;
  6136. dest[pos++] = 100;
  6137. // rest of pbs is 0 (15), texture entry (2) and texture anim (1)
  6138. const int pbszeros = 15 + 2 + 1;
  6139. Array.Clear(dest, pos, pbszeros); pos += pbszeros;
  6140. //NameValue
  6141. byte[] nv;
  6142. if (data.HideTitle)
  6143. nv = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " +
  6144. data.Lastname + "\nTitle STRING RW SV ");
  6145. else
  6146. nv = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " +
  6147. data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle);
  6148. int len = nv.Length;
  6149. dest[pos++] = (byte)len;
  6150. dest[pos++] = (byte)(len >> 8);
  6151. Buffer.BlockCopy(nv, 0, dest, pos, len); pos += len;
  6152. // data(2), text(1), text color(4), media url(1), PBblock(1), ExtramParams(1),
  6153. // sound id(16), sound owner(16) gain (4), flags (1), radius (4)
  6154. // jointtype(1) joint pivot(12) joint offset(12)
  6155. const int lastzeros = 2 + 1 + 4 + 1 + 1 + 1 + 16 + 16 + 4 + 1 + 4 + 1 + 12 + 12;
  6156. Array.Clear(dest, pos, lastzeros); pos += lastzeros;
  6157. }
  6158. protected void CreateAvatarUpdateBlock(ScenePresence data, LLUDPZeroEncoder zc)
  6159. {
  6160. Quaternion rotation = data.Rotation;
  6161. // tpvs can only see rotations around Z in some cases
  6162. if (!data.Flying && !data.IsSatOnObject)
  6163. {
  6164. rotation.X = 0f;
  6165. rotation.Y = 0f;
  6166. }
  6167. zc.AddUInt(data.LocalId);
  6168. zc.AddByte(0);
  6169. zc.AddUUID(data.UUID);
  6170. zc.AddZeros(4); // crc unused
  6171. zc.AddByte((byte)PCode.Avatar);
  6172. zc.AddByte((byte)Material.Flesh);
  6173. zc.AddByte(0); // clickaction
  6174. zc.AddVector3(data.Appearance.AvatarSize);
  6175. // objectdata block
  6176. zc.AddByte(76); // fixed avatar block size
  6177. zc.AddVector4(data.CollisionPlane);
  6178. zc.AddVector3(data.OffsetPosition);
  6179. zc.AddVector3(data.Velocity);
  6180. //zc.AddVector3(acceleration);
  6181. zc.AddZeros(12);
  6182. zc.AddNormQuat(rotation);
  6183. //zc.AddVector3(angularvelocity);
  6184. zc.AddZeros(12);
  6185. SceneObjectPart parentPart = data.ParentPart;
  6186. if (parentPart != null)
  6187. zc.AddUInt(parentPart.ParentGroup.LocalId);
  6188. else
  6189. zc.AddZeros(4);
  6190. zc.AddZeros(4); //update flags
  6191. //pbs volume data 23
  6192. //texture entry 2
  6193. //texture anim (1)
  6194. const int pbszeros = 23 + 2 + 1;
  6195. zc.AddZeros(pbszeros);
  6196. //NameValue
  6197. byte[] nv;
  6198. if (data.HideTitle)
  6199. nv = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " +
  6200. data.Lastname + "\nTitle STRING RW SV ");
  6201. else
  6202. nv = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " +
  6203. data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle);
  6204. int len = nv.Length;
  6205. zc.AddByte((byte)len);
  6206. zc.AddByte((byte)(len >> 8));
  6207. zc.AddBytes(nv, len);
  6208. // data(2), text(1), text color(4), media url(1), PBblock(1), ExtramParams(1),
  6209. // sound id(16), sound owner(16) gain (4), flags (1), radius (4)
  6210. // jointtype(1) joint pivot(12) joint offset(12)
  6211. const int lastzeros = 2 + 1 + 4 + 1 + 1 + 1 + 16 + 16 + 4 + 1 + 4 + 1 + 12 + 12;
  6212. zc.AddZeros(lastzeros);
  6213. }
  6214. protected void CreatePrimUpdateBlock(SceneObjectPart part, ScenePresence sp, LLUDPZeroEncoder zc)
  6215. {
  6216. // prepare data
  6217. #region PrimFlags
  6218. // prim/update flags
  6219. PrimFlags primflags = (PrimFlags)m_scene.Permissions.GenerateClientFlags(part, sp);
  6220. // Don't send the CreateSelected flag to everyone
  6221. primflags &= ~PrimFlags.CreateSelected;
  6222. if (sp.UUID == part.OwnerID)
  6223. {
  6224. if (part.CreateSelected)
  6225. {
  6226. // Only send this flag once, then unset it
  6227. primflags |= PrimFlags.CreateSelected;
  6228. part.CreateSelected = false;
  6229. }
  6230. }
  6231. #endregion PrimFlags
  6232. // data block
  6233. byte[] data = null;
  6234. byte state = part.Shape.State;
  6235. PCode pcode = (PCode)part.Shape.PCode;
  6236. //vegetation is special so just do it inline
  6237. if(pcode == PCode.Grass || pcode == PCode.Tree || pcode == PCode.NewTree)
  6238. {
  6239. zc.AddUInt(part.LocalId);
  6240. zc.AddByte(state); // state
  6241. zc.AddUUID(part.UUID);
  6242. zc.AddUInt((uint)part.PseudoCRC);
  6243. zc.AddByte((byte)pcode);
  6244. // material 1
  6245. // clickaction 1
  6246. zc.AddZeros(2);
  6247. zc.AddVector3(part.Shape.Scale);
  6248. // objectdata block
  6249. zc.AddByte(60); // fixed object block size
  6250. zc.AddVector3(part.RelativePosition);
  6251. if (pcode == PCode.Grass)
  6252. zc.AddZeros(48);
  6253. else
  6254. {
  6255. zc.AddZeros(24);
  6256. zc.AddNormQuat(part.RotationOffset);
  6257. zc.AddZeros(12);
  6258. }
  6259. zc.AddUInt(part.ParentID);
  6260. zc.AddUInt((uint)primflags); //update flags
  6261. /*
  6262. if (pcode == PCode.Grass)
  6263. {
  6264. //pbs volume data 23
  6265. //texture entry 2
  6266. //texture anim 1
  6267. //name value 2
  6268. // data 1
  6269. // text 5
  6270. // media url 1
  6271. // particle system 1
  6272. // Extraparams 1
  6273. // sound id 16
  6274. // ownwer 16
  6275. // sound gain 4
  6276. // sound flags 1
  6277. // sound radius 4
  6278. // jointtype 1
  6279. // joint pivot 12
  6280. // joint offset 12
  6281. zc.AddZeros(23 + 2 + 1 + 2 + 1 + 5 + 1 + 1 + 1 + 16 + 16 + 4 + 1 + 4 + 1 + 12 + 12);
  6282. return;
  6283. }
  6284. */
  6285. //pbs volume data 23
  6286. //texture entry 2
  6287. //texture anim 1
  6288. //name value 2
  6289. zc.AddZeros(23 + 2 + 1 + 2);
  6290. //data: the tree type
  6291. zc.AddByte(1);
  6292. zc.AddZeros(1);
  6293. zc.AddByte(state);
  6294. // text 5
  6295. // media url 1
  6296. // particle system 1
  6297. // Extraparams 1
  6298. // sound id 16
  6299. // ownwer 16
  6300. // sound gain 4
  6301. // sound flags 1
  6302. // sound radius 4
  6303. // jointtype 1
  6304. // joint pivot 12
  6305. // joint offset 12
  6306. zc.AddZeros(5 + 1 + 1 + 1 + 16 + 16 + 4 + 1 + 4 + 1 + 12 + 12);
  6307. return;
  6308. }
  6309. //NameValue and state
  6310. byte[] nv = null;
  6311. if (part.ParentGroup.IsAttachment)
  6312. {
  6313. if (part.IsRoot)
  6314. {
  6315. if (part.ParentGroup.FromItemID.IsZero())
  6316. nv = Util.StringToBytes256("AttachItemID STRING RW SV " + part.UUID.ToString());
  6317. else
  6318. nv = Util.StringToBytes256("AttachItemID STRING RW SV " + part.ParentGroup.FromItemID.ToString());
  6319. }
  6320. int st = 0xff & (int)part.ParentGroup.AttachmentPoint;
  6321. state = (byte)((st >> 4) | (st << 4));
  6322. }
  6323. // filter out mesh faces hack
  6324. ushort profileBegin = part.Shape.ProfileBegin;
  6325. ushort profileHollow = part.Shape.ProfileHollow;
  6326. byte profileCurve = part.Shape.ProfileCurve;
  6327. byte pathScaleY = part.Shape.PathScaleY;
  6328. if (part.Shape.SculptType == (byte)SculptType.Mesh) // filter out hack
  6329. {
  6330. profileCurve = (byte)(part.Shape.ProfileCurve & 0x0f);
  6331. // fix old values that confused viewers
  6332. if (profileBegin == 1)
  6333. profileBegin = 9375;
  6334. if (profileHollow == 1)
  6335. profileHollow = 27500;
  6336. // fix torus hole size Y that also confuse some viewers
  6337. if (profileCurve == (byte)ProfileShape.Circle && pathScaleY < 150)
  6338. pathScaleY = 150;
  6339. }
  6340. // do encode the things
  6341. zc.AddUInt(part.LocalId);
  6342. zc.AddByte(state); // state
  6343. zc.AddUUID(part.UUID);
  6344. zc.AddUInt((uint)part.PseudoCRC);
  6345. zc.AddByte((byte)pcode);
  6346. zc.AddByte(part.Material);
  6347. zc.AddByte(part.ClickAction); // clickaction
  6348. zc.AddVector3(part.Shape.Scale);
  6349. // objectdata block
  6350. zc.AddByte(60); // fixed object block size
  6351. zc.AddVector3(part.RelativePosition);
  6352. zc.AddVector3(part.Velocity);
  6353. zc.AddVector3(part.Acceleration);
  6354. zc.AddNormQuat(part.RotationOffset);
  6355. zc.AddVector3(part.AngularVelocity);
  6356. zc.AddUInt(part.ParentID);
  6357. zc.AddUInt((uint)primflags); //update flags
  6358. //pbs
  6359. zc.AddByte(part.Shape.PathCurve);
  6360. zc.AddByte(profileCurve);
  6361. zc.AddUInt16(part.Shape.PathBegin);
  6362. zc.AddUInt16(part.Shape.PathEnd);
  6363. zc.AddByte(part.Shape.PathScaleX);
  6364. zc.AddByte(pathScaleY);
  6365. zc.AddByte(part.Shape.PathShearX);
  6366. zc.AddByte(part.Shape.PathShearY);
  6367. zc.AddByte((byte)part.Shape.PathTwist);
  6368. zc.AddByte((byte)part.Shape.PathTwistBegin);
  6369. zc.AddByte((byte)part.Shape.PathRadiusOffset);
  6370. zc.AddByte((byte)part.Shape.PathTaperX);
  6371. zc.AddByte((byte)part.Shape.PathTaperY);
  6372. zc.AddByte(part.Shape.PathRevolutions);
  6373. zc.AddByte((byte)part.Shape.PathSkew);
  6374. zc.AddUInt16(profileBegin);
  6375. zc.AddUInt16(part.Shape.ProfileEnd);
  6376. zc.AddUInt16(profileHollow);
  6377. // texture
  6378. byte[] tentry = part.Shape.TextureEntry;
  6379. if (tentry == null)
  6380. zc.AddZeros(2);
  6381. else
  6382. {
  6383. int len = tentry.Length;
  6384. zc.AddByte((byte)len);
  6385. zc.AddByte((byte)(len >> 8));
  6386. zc.AddBytes(tentry, len);
  6387. }
  6388. // texture animation
  6389. byte[] tanim = part.TextureAnimation;
  6390. if (tanim == null)
  6391. zc.AddZeros(1);
  6392. else
  6393. {
  6394. int len = tanim.Length;
  6395. zc.AddByte((byte)len);
  6396. zc.AddBytes(tanim, len);
  6397. }
  6398. //NameValue
  6399. if(nv == null)
  6400. zc.AddZeros(2);
  6401. else
  6402. {
  6403. int len = nv.Length;
  6404. zc.AddByte((byte)len);
  6405. zc.AddByte((byte)(len >> 8));
  6406. zc.AddBytes(nv, len);
  6407. }
  6408. // data
  6409. if (data == null)
  6410. zc.AddZeros(2);
  6411. else
  6412. {
  6413. int len = data.Length;
  6414. zc.AddByte((byte)len);
  6415. zc.AddByte((byte)(len >> 8));
  6416. zc.AddBytes(data, len);
  6417. }
  6418. //text
  6419. osUTF8 osUTF8PartText = part.osUTF8Text;
  6420. if (osUTF8PartText == null || osUTF8PartText.Length == 0)
  6421. zc.AddZeros(5);
  6422. else
  6423. {
  6424. zc.AddShortLimitedUTF8(osUTF8PartText);
  6425. //textcolor
  6426. byte[] tc = part.GetTextColor().GetBytes(false);
  6427. zc.AddBytes(tc, 4);
  6428. }
  6429. //media url
  6430. zc.AddShortLimitedUTF8(part.osUTFMediaUrl);
  6431. bool hasps = false;
  6432. //particle system
  6433. byte[] ps = part.ParticleSystem;
  6434. if (ps == null || ps.Length < 1)
  6435. zc.AddZeros(1);
  6436. else
  6437. {
  6438. int len = ps.Length;
  6439. zc.AddByte((byte)len);
  6440. zc.AddBytes(ps, len);
  6441. hasps = true;
  6442. }
  6443. //Extraparams
  6444. byte[] ep = part.Shape.ExtraParams;
  6445. if (ep == null || ep.Length < 2)
  6446. zc.AddZeros(1);
  6447. else
  6448. {
  6449. int len = ep.Length;
  6450. zc.AddByte((byte)len);
  6451. zc.AddBytes(ep, len);
  6452. }
  6453. bool hassound = part.Sound.IsNotZero() || part.SoundFlags != 0;
  6454. if (hassound)
  6455. zc.AddUUID(part.Sound);
  6456. else
  6457. zc.AddZeros(16);
  6458. if (hassound || hasps)
  6459. zc.AddUUID(part.OwnerID);
  6460. else
  6461. zc.AddZeros(16);
  6462. if (hassound)
  6463. {
  6464. zc.AddFloat((float)part.SoundGain);
  6465. zc.AddByte(part.SoundFlags);
  6466. zc.AddFloat((float)part.SoundRadius);
  6467. }
  6468. else
  6469. zc.AddZeros(9);
  6470. // jointtype(1) joint pivot(12) joint offset(12)
  6471. const int lastzeros = 1 + 12 + 12;
  6472. zc.AddZeros(lastzeros);
  6473. }
  6474. [Flags]
  6475. private enum CompressedFlags : uint
  6476. {
  6477. None = 0x00,
  6478. /// <summary>Unknown</summary>
  6479. ScratchPad = 0x01,
  6480. /// <summary>Whether the object has a TreeSpecies</summary>
  6481. Tree = 0x02,
  6482. /// <summary>Whether the object has floating text ala llSetText</summary>
  6483. HasText = 0x04,
  6484. /// <summary>Whether the object has an active particle system</summary>
  6485. HasParticlesLegacy = 0x08,
  6486. /// <summary>Whether the object has sound attached to it</summary>
  6487. HasSound = 0x10,
  6488. /// <summary>Whether the object is attached to a root object or not</summary>
  6489. HasParent = 0x20,
  6490. /// <summary>Whether the object has texture animation settings</summary>
  6491. TextureAnimation = 0x40,
  6492. /// <summary>Whether the object has an angular velocity</summary>
  6493. HasAngularVelocity = 0x80,
  6494. /// <summary>Whether the object has a name value pairs string</summary>
  6495. HasNameValues = 0x100,
  6496. /// <summary>Whether the object has a Media URL set</summary>
  6497. MediaURL = 0x200,
  6498. HasParticlesNew = 0x400
  6499. }
  6500. /*
  6501. protected void CreateCompressedUpdateBlock(SceneObjectPart part, ScenePresence sp, byte[] dest, ref int pos)
  6502. {
  6503. // prepare data
  6504. CompressedFlags cflags = CompressedFlags.None;
  6505. // prim/update flags
  6506. PrimFlags primflags = (PrimFlags)m_scene.Permissions.GenerateClientFlags(part, sp);
  6507. // Don't send the CreateSelected flag to everyone
  6508. primflags &= ~PrimFlags.CreateSelected;
  6509. if (sp.UUID == part.OwnerID)
  6510. {
  6511. if (part.CreateSelected)
  6512. {
  6513. // Only send this flag once, then unset it
  6514. primflags |= PrimFlags.CreateSelected;
  6515. part.CreateSelected = false;
  6516. }
  6517. }
  6518. byte state = part.Shape.State;
  6519. PCode pcode = (PCode)part.Shape.PCode;
  6520. bool hastree = false;
  6521. if (pcode == PCode.Grass || pcode == PCode.Tree || pcode == PCode.NewTree)
  6522. {
  6523. cflags |= CompressedFlags.Tree;
  6524. hastree = true;
  6525. }
  6526. //NameValue and state
  6527. byte[] nv = null;
  6528. if (part.ParentGroup.IsAttachment)
  6529. {
  6530. if (part.IsRoot)
  6531. {
  6532. UUID fromID = part.ParentGroup.FromItemID;
  6533. if (fromID == UUID.Zero)
  6534. fromID = part.UUID;
  6535. nv = Util.StringToBytes256("AttachItemID STRING RW SV " + fromID.ToString());
  6536. }
  6537. int st = 0xff & (int)part.ParentGroup.AttachmentPoint;
  6538. state = (byte)((st & >> 4) | (st << 4));
  6539. }
  6540. bool hastext = part.Text != null && part.Text.Length > 0;
  6541. bool hassound = part.Sound != UUID.Zero || part.SoundFlags != 0;
  6542. bool hasps = part.ParticleSystem != null && part.ParticleSystem.Length > 1;
  6543. bool hastexanim = part.TextureAnimation != null && part.TextureAnimation.Length > 0;
  6544. bool hasangvel = part.AngularVelocity.LengthSquared() > 1e-8f;
  6545. bool hasmediaurl = part.MediaUrl != null && part.MediaUrl.Length > 1;
  6546. bool haspsnew = false;
  6547. if (hastext)
  6548. cflags |= CompressedFlags.HasText;
  6549. if (hasps)
  6550. {
  6551. if(part.ParticleSystem.Length > 86)
  6552. {
  6553. hasps= false;
  6554. cflags |= CompressedFlags.HasParticlesNew;
  6555. haspsnew = true;
  6556. }
  6557. else
  6558. cflags |= CompressedFlags.HasParticlesLegacy;
  6559. }
  6560. if (hassound)
  6561. cflags |= CompressedFlags.HasSound;
  6562. if (part.ParentID != 0)
  6563. cflags |= CompressedFlags.HasParent;
  6564. if (hastexanim)
  6565. cflags |= CompressedFlags.TextureAnimation;
  6566. if (hasangvel)
  6567. cflags |= CompressedFlags.HasAngularVelocity;
  6568. if (hasmediaurl)
  6569. cflags |= CompressedFlags.MediaURL;
  6570. if (nv != null)
  6571. cflags |= CompressedFlags.HasNameValues;
  6572. // filter out mesh faces hack
  6573. ushort profileBegin = part.Shape.ProfileBegin;
  6574. ushort profileHollow = part.Shape.ProfileHollow;
  6575. byte profileCurve = part.Shape.ProfileCurve;
  6576. byte pathScaleY = part.Shape.PathScaleY;
  6577. if (part.Shape.SculptType == (byte)SculptType.Mesh) // filter out hack
  6578. {
  6579. profileCurve = (byte)(part.Shape.ProfileCurve & 0x0f);
  6580. // fix old values that confused viewers
  6581. if (profileBegin == 1)
  6582. profileBegin = 9375;
  6583. if (profileHollow == 1)
  6584. profileHollow = 27500;
  6585. // fix torus hole size Y that also confuse some viewers
  6586. if (profileCurve == (byte)ProfileShape.Circle && pathScaleY < 150)
  6587. pathScaleY = 150;
  6588. }
  6589. // first is primFlags
  6590. Utils.UIntToBytesSafepos((uint)primflags, dest, pos); pos += 4;
  6591. // datablock len to fill later
  6592. int lenpos = pos;
  6593. pos += 2;
  6594. // data block
  6595. part.UUID.ToBytes(dest, pos); pos += 16;
  6596. Utils.UIntToBytesSafepos(part.LocalId, dest, pos); pos += 4;
  6597. dest[pos++] = (byte)pcode;
  6598. dest[pos++] = state;
  6599. Utils.UIntToBytesSafepos((uint)part.ParentGroup.PseudoCRC, dest, pos); pos += 4;
  6600. dest[pos++] = part.Material;
  6601. dest[pos++] = part.ClickAction;
  6602. part.Shape.Scale.ToBytes(dest, pos); pos += 12;
  6603. part.RelativePosition.ToBytes(dest, pos); pos += 12;
  6604. if(pcode == PCode.Grass)
  6605. Vector3.Zero.ToBytes(dest, pos);
  6606. else
  6607. {
  6608. Quaternion rotation = part.RotationOffset;
  6609. rotation.Normalize();
  6610. rotation.ToBytes(dest, pos);
  6611. }
  6612. pos += 12;
  6613. Utils.UIntToBytesSafepos((uint)cflags, dest, pos); pos += 4;
  6614. if (hasps || haspsnew || hassound)
  6615. part.OwnerID.ToBytes(dest, pos);
  6616. else
  6617. UUID.Zero.ToBytes(dest, pos);
  6618. pos += 16;
  6619. if (hasangvel)
  6620. {
  6621. part.AngularVelocity.ToBytes(dest, pos); pos += 12;
  6622. }
  6623. if (part.ParentID != 0)
  6624. {
  6625. Utils.UIntToBytesSafepos(part.ParentID, dest, pos); pos += 4;
  6626. }
  6627. if (hastree)
  6628. dest[pos++] = state;
  6629. if (hastext)
  6630. {
  6631. byte[] text = Util.StringToBytes256(part.Text); // must be null term
  6632. Buffer.BlockCopy(text, 0, dest, pos, text.Length); pos += text.Length;
  6633. byte[] tc = part.GetTextColor().GetBytes(false);
  6634. Buffer.BlockCopy(tc, 0, dest, pos, tc.Length); pos += tc.Length;
  6635. }
  6636. if (hasmediaurl)
  6637. {
  6638. byte[] mu = Util.StringToBytes256(part.MediaUrl); // must be null term
  6639. Buffer.BlockCopy(mu, 0, dest, pos, mu.Length); pos += mu.Length;
  6640. }
  6641. if (hasps)
  6642. {
  6643. byte[] ps = part.ParticleSystem;
  6644. Buffer.BlockCopy(ps, 0, dest, pos, ps.Length); pos += ps.Length;
  6645. }
  6646. byte[] ex = part.Shape.ExtraParams;
  6647. if (ex == null || ex.Length < 2)
  6648. dest[pos++] = 0;
  6649. else
  6650. {
  6651. Buffer.BlockCopy(ex, 0, dest, pos, ex.Length); pos += ex.Length;
  6652. }
  6653. if (hassound)
  6654. {
  6655. part.Sound.ToBytes(dest, pos); pos += 16;
  6656. Utils.FloatToBytesSafepos((float)part.SoundGain, dest, pos); pos += 4;
  6657. dest[pos++] = part.SoundFlags;
  6658. Utils.FloatToBytesSafepos((float)part.SoundRadius, dest, pos); pos += 4;
  6659. }
  6660. if (nv != null)
  6661. {
  6662. Buffer.BlockCopy(nv, 0, dest, pos, nv.Length); pos += nv.Length;
  6663. }
  6664. dest[pos++] = part.Shape.PathCurve;
  6665. Utils.UInt16ToBytes(part.Shape.PathBegin, dest, pos); pos += 2;
  6666. Utils.UInt16ToBytes(part.Shape.PathEnd, dest, pos); pos += 2;
  6667. dest[pos++] = part.Shape.PathScaleX;
  6668. dest[pos++] = pathScaleY;
  6669. dest[pos++] = part.Shape.PathShearX;
  6670. dest[pos++] = part.Shape.PathShearY;
  6671. dest[pos++] = (byte)part.Shape.PathTwist;
  6672. dest[pos++] = (byte)part.Shape.PathTwistBegin;
  6673. dest[pos++] = (byte)part.Shape.PathRadiusOffset;
  6674. dest[pos++] = (byte)part.Shape.PathTaperX;
  6675. dest[pos++] = (byte)part.Shape.PathTaperY;
  6676. dest[pos++] = part.Shape.PathRevolutions;
  6677. dest[pos++] = (byte)part.Shape.PathSkew;
  6678. dest[pos++] = profileCurve;
  6679. Utils.UInt16ToBytes(profileBegin, dest, pos); pos += 2;
  6680. Utils.UInt16ToBytes(part.Shape.ProfileEnd, dest, pos); pos += 2;
  6681. Utils.UInt16ToBytes(profileHollow, dest, pos); pos += 2;
  6682. byte[] te = part.Shape.TextureEntry;
  6683. if (te == null)
  6684. {
  6685. dest[pos++] = 0;
  6686. dest[pos++] = 0;
  6687. dest[pos++] = 0;
  6688. dest[pos++] = 0;
  6689. }
  6690. else
  6691. {
  6692. int len = te.Length & 0x7fff;
  6693. dest[pos++] = (byte)len;
  6694. dest[pos++] = (byte)(len >> 8);
  6695. dest[pos++] = 0;
  6696. dest[pos++] = 0;
  6697. Buffer.BlockCopy(te, 0, dest, pos, len);
  6698. pos += len;
  6699. }
  6700. if (hastexanim)
  6701. {
  6702. byte[] ta = part.TextureAnimation;
  6703. int len = ta.Length & 0x7fff;
  6704. dest[pos++] = (byte)len;
  6705. dest[pos++] = (byte)(len >> 8);
  6706. dest[pos++] = 0;
  6707. dest[pos++] = 0;
  6708. Buffer.BlockCopy(ta, 0, dest, pos, len);
  6709. pos += len;
  6710. }
  6711. if (haspsnew)
  6712. {
  6713. byte[] ps = part.ParticleSystem;
  6714. Buffer.BlockCopy(ps, 0, dest, pos, ps.Length); pos += ps.Length;
  6715. }
  6716. int totlen = pos - lenpos - 2;
  6717. dest[lenpos++] = (byte)totlen;
  6718. dest[lenpos++] = (byte)(totlen >> 8);
  6719. }
  6720. */
  6721. protected void CreateCompressedUpdateBlockZC(SceneObjectPart part, ScenePresence sp, LLUDPZeroEncoder zc)
  6722. {
  6723. // prepare data
  6724. CompressedFlags cflags = CompressedFlags.None;
  6725. // prim/update flags
  6726. PrimFlags primflags = (PrimFlags)m_scene.Permissions.GenerateClientFlags(part, sp);
  6727. // Don't send the CreateSelected flag to everyone
  6728. primflags &= ~PrimFlags.CreateSelected;
  6729. if (sp.UUID.Equals(part.OwnerID))
  6730. {
  6731. if (part.CreateSelected)
  6732. {
  6733. // Only send this flag once, then unset it
  6734. primflags |= PrimFlags.CreateSelected;
  6735. part.CreateSelected = false;
  6736. }
  6737. }
  6738. byte state = part.Shape.State;
  6739. PCode pcode = (PCode)part.Shape.PCode;
  6740. // trees and grass are a lot more compact
  6741. if (pcode == PCode.Grass || pcode == PCode.Tree || pcode == PCode.NewTree)
  6742. {
  6743. // first is primFlags
  6744. zc.AddUInt((uint)primflags);
  6745. // datablock len
  6746. zc.AddByte(113);
  6747. zc.AddZeros(1);
  6748. // data block
  6749. zc.AddUUID(part.UUID);
  6750. zc.AddUInt(part.LocalId);
  6751. zc.AddByte((byte)pcode);
  6752. zc.AddByte(state);
  6753. zc.AddUInt((uint)part.PseudoCRC);
  6754. zc.AddZeros(2); // material and click action
  6755. zc.AddVector3(part.Shape.Scale);
  6756. zc.AddVector3(part.RelativePosition);
  6757. if (pcode == PCode.Grass)
  6758. zc.AddZeros(12);
  6759. else
  6760. zc.AddNormQuat(part.RotationOffset);
  6761. zc.AddUInt((uint)CompressedFlags.Tree); // cflags
  6762. zc.AddZeros(16); // owner id
  6763. zc.AddByte(state); // tree parameter
  6764. zc.AddZeros(28); //extraparameters 1, pbs 23, texture 4
  6765. return;
  6766. }
  6767. //NameValue and state
  6768. byte[] nv = null;
  6769. if (part.ParentGroup.IsAttachment)
  6770. {
  6771. if (part.IsRoot)
  6772. {
  6773. if (part.ParentGroup.FromItemID.IsZero())
  6774. nv = Util.StringToBytes256("AttachItemID STRING RW SV " + part.UUID.ToString());
  6775. else
  6776. nv = Util.StringToBytes256("AttachItemID STRING RW SV " + part.ParentGroup.FromItemID.ToString());
  6777. }
  6778. int st = 0xff & (int)part.ParentGroup.AttachmentPoint;
  6779. state = (byte)((st >> 4) | (st << 4));
  6780. }
  6781. bool hastext = false;
  6782. bool hassound = false;
  6783. bool hasps = false;
  6784. bool hastexanim = false;
  6785. bool hasangvel = false;
  6786. bool hasmediaurl = false;
  6787. bool haspsnew = false;
  6788. int BlockLengh = 111;
  6789. byte[] extraParamBytes = part.Shape.ExtraParams;
  6790. if (extraParamBytes == null || extraParamBytes.Length < 2)
  6791. {
  6792. ++BlockLengh;
  6793. extraParamBytes = null;
  6794. }
  6795. else
  6796. BlockLengh += extraParamBytes.Length;
  6797. byte[] hoverTextColor = null;
  6798. osUTF8 osUTF8PartText = part.osUTF8Text;
  6799. if (osUTF8PartText != null && osUTF8PartText.Length > 0)
  6800. {
  6801. cflags |= CompressedFlags.HasText;
  6802. BlockLengh += osUTF8PartText.Length;
  6803. if (osUTF8PartText[osUTF8PartText.Length - 1] != 0)
  6804. ++BlockLengh;
  6805. hoverTextColor = part.GetTextColor().GetBytes(false);
  6806. BlockLengh += hoverTextColor.Length;
  6807. hastext = true;
  6808. }
  6809. if (part.ParticleSystem != null && part.ParticleSystem.Length > 1)
  6810. {
  6811. BlockLengh += part.ParticleSystem.Length;
  6812. if (part.ParticleSystem.Length > 86)
  6813. {
  6814. hasps = false;
  6815. cflags |= CompressedFlags.HasParticlesNew;
  6816. haspsnew = true;
  6817. }
  6818. else
  6819. {
  6820. cflags |= CompressedFlags.HasParticlesLegacy;
  6821. hasps = true;
  6822. }
  6823. }
  6824. if (part.Sound.IsNotZero() || part.SoundFlags != 0)
  6825. {
  6826. BlockLengh += 25;
  6827. cflags |= CompressedFlags.HasSound;
  6828. hassound = true;
  6829. }
  6830. if (part.ParentID != 0)
  6831. {
  6832. BlockLengh += 4;
  6833. cflags |= CompressedFlags.HasParent;
  6834. }
  6835. if (part.TextureAnimation != null && part.TextureAnimation.Length > 0)
  6836. {
  6837. BlockLengh += part.TextureAnimation.Length + 4;
  6838. cflags |= CompressedFlags.TextureAnimation;
  6839. hastexanim = true;
  6840. }
  6841. if (part.AngularVelocity.LengthSquared() > 1e-8f)
  6842. {
  6843. BlockLengh += 12;
  6844. cflags |= CompressedFlags.HasAngularVelocity;
  6845. hasangvel = true;
  6846. }
  6847. osUTF8 osUTFMediaUrl = part.osUTFMediaUrl;
  6848. if (osUTFMediaUrl != null && osUTFMediaUrl.Length > 0)
  6849. {
  6850. BlockLengh += osUTFMediaUrl.Length;
  6851. if (osUTFMediaUrl[osUTFMediaUrl.Length - 1] != 0)
  6852. ++BlockLengh;
  6853. cflags |= CompressedFlags.MediaURL;
  6854. hasmediaurl = true;
  6855. }
  6856. if (nv != null)
  6857. {
  6858. BlockLengh += nv.Length;
  6859. cflags |= CompressedFlags.HasNameValues;
  6860. }
  6861. byte[] textureEntry = part.Shape.TextureEntry;
  6862. if(textureEntry != null)
  6863. BlockLengh += textureEntry.Length;
  6864. // filter out mesh faces hack
  6865. ushort profileBegin = part.Shape.ProfileBegin;
  6866. ushort profileHollow = part.Shape.ProfileHollow;
  6867. byte profileCurve = part.Shape.ProfileCurve;
  6868. byte pathScaleY = part.Shape.PathScaleY;
  6869. if (part.Shape.SculptType == (byte)SculptType.Mesh) // filter out hack
  6870. {
  6871. profileCurve = (byte)(part.Shape.ProfileCurve & 0x0f);
  6872. // fix old values that confused viewers
  6873. if (profileBegin == 1)
  6874. profileBegin = 9375;
  6875. if (profileHollow == 1)
  6876. profileHollow = 27500;
  6877. // fix torus hole size Y that also confuse some viewers
  6878. if (profileCurve == (byte)ProfileShape.Circle && pathScaleY < 150)
  6879. pathScaleY = 150;
  6880. }
  6881. // first is primFlags
  6882. zc.AddUInt((uint)primflags);
  6883. // datablock len
  6884. zc.AddByte((byte)BlockLengh);
  6885. zc.AddByte((byte)(BlockLengh >> 8));
  6886. // data block
  6887. zc.AddUUID(part.UUID);
  6888. zc.AddUInt(part.LocalId);
  6889. zc.AddByte((byte)pcode);
  6890. zc.AddByte(state);
  6891. zc.AddUInt((uint)part.PseudoCRC);
  6892. zc.AddByte(part.Material);
  6893. zc.AddByte(part.ClickAction);
  6894. zc.AddVector3(part.Shape.Scale);
  6895. zc.AddVector3(part.RelativePosition);
  6896. zc.AddNormQuat(part.RotationOffset);
  6897. zc.AddUInt((uint)cflags);
  6898. if (hasps || haspsnew || hassound)
  6899. zc.AddUUID(part.OwnerID);
  6900. else
  6901. zc.AddZeros(16);
  6902. if (hasangvel)
  6903. {
  6904. zc.AddVector3(part.AngularVelocity);
  6905. }
  6906. if (part.ParentID != 0)
  6907. {
  6908. zc.AddUInt(part.ParentID);
  6909. }
  6910. if (hastext)
  6911. {
  6912. zc.AddBytes(osUTF8PartText.GetArray(), osUTF8PartText.Length);
  6913. if (osUTF8PartText[osUTF8PartText.Length - 1] != 0)
  6914. zc.AddZeros(1);
  6915. zc.AddBytes(hoverTextColor, hoverTextColor.Length);
  6916. }
  6917. if (hasmediaurl)
  6918. {
  6919. zc.AddBytes(osUTFMediaUrl.GetArray(), osUTFMediaUrl.Length);
  6920. if (osUTFMediaUrl[osUTFMediaUrl.Length - 1] != 0)
  6921. zc.AddZeros(1);
  6922. }
  6923. if (hasps)
  6924. {
  6925. byte[] ps = part.ParticleSystem;
  6926. zc.AddBytes(ps, ps.Length);
  6927. }
  6928. if (extraParamBytes == null)
  6929. zc.AddZeros(1);
  6930. else
  6931. {
  6932. zc.AddBytes(extraParamBytes, extraParamBytes.Length);
  6933. }
  6934. if (hassound)
  6935. {
  6936. zc.AddUUID(part.Sound);
  6937. zc.AddFloat((float)part.SoundGain);
  6938. zc.AddByte(part.SoundFlags);
  6939. zc.AddFloat((float)part.SoundRadius);
  6940. }
  6941. if (nv != null)
  6942. {
  6943. zc.AddBytes(nv, nv.Length);
  6944. }
  6945. zc.AddByte(part.Shape.PathCurve);
  6946. zc.AddUInt16(part.Shape.PathBegin);
  6947. zc.AddUInt16(part.Shape.PathEnd);
  6948. zc.AddByte(part.Shape.PathScaleX);
  6949. zc.AddByte(pathScaleY);
  6950. zc.AddByte(part.Shape.PathShearX);
  6951. zc.AddByte(part.Shape.PathShearY);
  6952. zc.AddByte((byte)part.Shape.PathTwist);
  6953. zc.AddByte((byte)part.Shape.PathTwistBegin);
  6954. zc.AddByte((byte)part.Shape.PathRadiusOffset);
  6955. zc.AddByte((byte)part.Shape.PathTaperX);
  6956. zc.AddByte((byte)part.Shape.PathTaperY);
  6957. zc.AddByte(part.Shape.PathRevolutions);
  6958. zc.AddByte((byte)part.Shape.PathSkew);
  6959. zc.AddByte(profileCurve);
  6960. zc.AddUInt16(profileBegin);
  6961. zc.AddUInt16(part.Shape.ProfileEnd);
  6962. zc.AddUInt16(profileHollow);
  6963. if (textureEntry == null)
  6964. {
  6965. zc.AddZeros(4);
  6966. }
  6967. else
  6968. {
  6969. int len = textureEntry.Length;
  6970. zc.AddByte((byte)len);
  6971. zc.AddByte((byte)(len >> 8));
  6972. zc.AddZeros(2);
  6973. zc.AddBytes(textureEntry, len);
  6974. }
  6975. if (hastexanim)
  6976. {
  6977. byte[] ta = part.TextureAnimation;
  6978. int len = ta.Length;
  6979. zc.AddByte((byte)len);
  6980. zc.AddByte((byte)(len >> 8));
  6981. zc.AddZeros(2);
  6982. zc.AddBytes(ta, len);
  6983. }
  6984. if (haspsnew)
  6985. {
  6986. byte[] ps = part.ParticleSystem;
  6987. zc.AddBytes(ps, ps.Length);
  6988. }
  6989. }
  6990. public void SendNameReply(UUID profileId, string firstname, string lastname)
  6991. {
  6992. UUIDNameReplyPacket packet = (UUIDNameReplyPacket)PacketPool.Instance.GetPacket(PacketType.UUIDNameReply);
  6993. // TODO: don't create new blocks if recycling an old packet
  6994. packet.UUIDNameBlock = new UUIDNameReplyPacket.UUIDNameBlockBlock[1];
  6995. packet.UUIDNameBlock[0] = new UUIDNameReplyPacket.UUIDNameBlockBlock();
  6996. packet.UUIDNameBlock[0].ID = profileId;
  6997. packet.UUIDNameBlock[0].FirstName = Util.StringToBytes256(firstname);
  6998. packet.UUIDNameBlock[0].LastName = Util.StringToBytes256(lastname);
  6999. OutPacket(packet, ThrottleOutPacketType.Task);
  7000. }
  7001. public Dictionary<UUID, ulong> GetGroupPowers()
  7002. {
  7003. lock(m_groupPowers)
  7004. {
  7005. return new Dictionary<UUID, ulong>(m_groupPowers);
  7006. }
  7007. }
  7008. public void SetGroupPowers(Dictionary<UUID, ulong> powers)
  7009. {
  7010. lock(m_groupPowers)
  7011. {
  7012. m_groupPowers.Clear();
  7013. m_groupPowers = powers;
  7014. }
  7015. }
  7016. public ulong GetGroupPowers(UUID groupID)
  7017. {
  7018. lock(m_groupPowers)
  7019. {
  7020. if (m_groupPowers.ContainsKey(groupID))
  7021. return m_groupPowers[groupID];
  7022. }
  7023. return 0;
  7024. }
  7025. #endregion
  7026. protected virtual void RegisterLocalPacketHandlers()
  7027. {
  7028. AddLocalPacketHandler(PacketType.LogoutRequest, HandleLogout);
  7029. // If AgentUpdate is ever handled asynchronously, then we will also need to construct a new AgentUpdateArgs
  7030. // for each AgentUpdate packet.
  7031. AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate, false);
  7032. AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect, false);
  7033. AddLocalPacketHandler(PacketType.VelocityInterpolateOff, HandleVelocityInterpolateOff, false);
  7034. AddLocalPacketHandler(PacketType.VelocityInterpolateOn, HandleVelocityInterpolateOn, false);
  7035. AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false);
  7036. AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false);
  7037. AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest, false);
  7038. AddLocalPacketHandler(PacketType.ParcelBuy, HandleParcelBuyRequest, false);
  7039. AddLocalPacketHandler(PacketType.UUIDGroupNameRequest, HandleUUIDGroupNameRequest);
  7040. AddLocalPacketHandler(PacketType.ObjectGroup, HandleObjectGroupRequest);
  7041. AddLocalPacketHandler(PacketType.GenericMessage, HandleGenericMessage);
  7042. AddLocalPacketHandler(PacketType.AvatarPropertiesRequest, HandleAvatarPropertiesRequest);
  7043. AddLocalPacketHandler(PacketType.ChatFromViewer, HandleChatFromViewer);
  7044. AddLocalPacketHandler(PacketType.AvatarPropertiesUpdate, HandlerAvatarPropertiesUpdate);
  7045. AddLocalPacketHandler(PacketType.ScriptDialogReply, HandlerScriptDialogReply);
  7046. AddLocalPacketHandler(PacketType.ImprovedInstantMessage, HandlerImprovedInstantMessage);
  7047. AddLocalPacketHandler(PacketType.AcceptFriendship, HandlerAcceptFriendship);
  7048. AddLocalPacketHandler(PacketType.DeclineFriendship, HandlerDeclineFriendship);
  7049. AddLocalPacketHandler(PacketType.TerminateFriendship, HandlerTerminateFriendship);
  7050. AddLocalPacketHandler(PacketType.RezObject, HandlerRezObject);
  7051. AddLocalPacketHandler(PacketType.DeRezObject, HandlerDeRezObject);
  7052. AddLocalPacketHandler(PacketType.RezRestoreToWorld, HandlerRezRestoreToWorld);
  7053. AddLocalPacketHandler(PacketType.ModifyLand, HandlerModifyLand);
  7054. AddLocalPacketHandler(PacketType.RegionHandshakeReply, HandlerRegionHandshakeReply, false);
  7055. AddLocalPacketHandler(PacketType.AgentWearablesRequest, HandlerAgentWearablesRequest);
  7056. AddLocalPacketHandler(PacketType.AgentSetAppearance, HandlerAgentSetAppearance);
  7057. AddLocalPacketHandler(PacketType.AgentIsNowWearing, HandlerAgentIsNowWearing);
  7058. AddLocalPacketHandler(PacketType.RezSingleAttachmentFromInv, HandlerRezSingleAttachmentFromInv);
  7059. AddLocalPacketHandler(PacketType.RezMultipleAttachmentsFromInv, HandleRezMultipleAttachmentsFromInv);
  7060. AddLocalPacketHandler(PacketType.DetachAttachmentIntoInv, HandleDetachAttachmentIntoInv);
  7061. AddLocalPacketHandler(PacketType.ObjectAttach, HandleObjectAttach);
  7062. AddLocalPacketHandler(PacketType.ObjectDetach, HandleObjectDetach);
  7063. AddLocalPacketHandler(PacketType.ObjectDrop, HandleObjectDrop);
  7064. AddLocalPacketHandler(PacketType.SetAlwaysRun, HandleSetAlwaysRun, false);
  7065. AddLocalPacketHandler(PacketType.CompleteAgentMovement, HandleCompleteAgentMovement);
  7066. AddLocalPacketHandler(PacketType.AgentAnimation, HandleAgentAnimation, false);
  7067. AddLocalPacketHandler(PacketType.AgentRequestSit, HandleAgentRequestSit);
  7068. AddLocalPacketHandler(PacketType.AgentSit, HandleAgentSit);
  7069. AddLocalPacketHandler(PacketType.SoundTrigger, HandleSoundTrigger);
  7070. AddLocalPacketHandler(PacketType.AvatarPickerRequest, HandleAvatarPickerRequest);
  7071. AddLocalPacketHandler(PacketType.AgentDataUpdateRequest, HandleAgentDataUpdateRequest);
  7072. AddLocalPacketHandler(PacketType.UserInfoRequest, HandleUserInfoRequest);
  7073. AddLocalPacketHandler(PacketType.UpdateUserInfo, HandleUpdateUserInfo);
  7074. AddLocalPacketHandler(PacketType.SetStartLocationRequest, HandleSetStartLocationRequest);
  7075. AddLocalPacketHandler(PacketType.AgentThrottle, HandleAgentThrottle, false);
  7076. AddLocalPacketHandler(PacketType.AgentPause, HandleAgentPause, false);
  7077. AddLocalPacketHandler(PacketType.AgentResume, HandleAgentResume, false);
  7078. AddLocalPacketHandler(PacketType.ForceScriptControlRelease, HandleForceScriptControlRelease);
  7079. AddLocalPacketHandler(PacketType.ObjectLink, HandleObjectLink);
  7080. AddLocalPacketHandler(PacketType.ObjectDelink, HandleObjectDelink);
  7081. AddLocalPacketHandler(PacketType.ObjectAdd, HandleObjectAdd);
  7082. AddLocalPacketHandler(PacketType.ObjectShape, HandleObjectShape);
  7083. AddLocalPacketHandler(PacketType.ObjectExtraParams, HandleObjectExtraParams);
  7084. AddLocalPacketHandler(PacketType.ObjectDuplicate, HandleObjectDuplicate);
  7085. AddLocalPacketHandler(PacketType.RequestMultipleObjects, HandleRequestMultipleObjects);
  7086. AddLocalPacketHandler(PacketType.ObjectSelect, HandleObjectSelect);
  7087. AddLocalPacketHandler(PacketType.ObjectDeselect, HandleObjectDeselect);
  7088. AddLocalPacketHandler(PacketType.ObjectPosition, HandleObjectPosition);
  7089. AddLocalPacketHandler(PacketType.ObjectScale, HandleObjectScale);
  7090. AddLocalPacketHandler(PacketType.ObjectRotation, HandleObjectRotation);
  7091. AddLocalPacketHandler(PacketType.ObjectFlagUpdate, HandleObjectFlagUpdate);
  7092. // Handle ObjectImage (TextureEntry) updates synchronously, since when updating multiple prim faces at once,
  7093. // some clients will send out a separate ObjectImage packet for each face
  7094. AddLocalPacketHandler(PacketType.ObjectImage, HandleObjectImage, false);
  7095. AddLocalPacketHandler(PacketType.ObjectGrab, HandleObjectGrab, false);
  7096. AddLocalPacketHandler(PacketType.ObjectGrabUpdate, HandleObjectGrabUpdate, false);
  7097. AddLocalPacketHandler(PacketType.ObjectDeGrab, HandleObjectDeGrab);
  7098. AddLocalPacketHandler(PacketType.ObjectSpinStart, HandleObjectSpinStart, false);
  7099. AddLocalPacketHandler(PacketType.ObjectSpinUpdate, HandleObjectSpinUpdate, false);
  7100. AddLocalPacketHandler(PacketType.ObjectSpinStop, HandleObjectSpinStop, false);
  7101. AddLocalPacketHandler(PacketType.ObjectDescription, HandleObjectDescription, false);
  7102. AddLocalPacketHandler(PacketType.ObjectName, HandleObjectName, false);
  7103. AddLocalPacketHandler(PacketType.ObjectPermissions, HandleObjectPermissions, false);
  7104. AddLocalPacketHandler(PacketType.Undo, HandleUndo, false);
  7105. AddLocalPacketHandler(PacketType.UndoLand, HandleLandUndo, false);
  7106. AddLocalPacketHandler(PacketType.Redo, HandleRedo, false);
  7107. AddLocalPacketHandler(PacketType.ObjectDuplicateOnRay, HandleObjectDuplicateOnRay);
  7108. AddLocalPacketHandler(PacketType.RequestObjectPropertiesFamily, HandleRequestObjectPropertiesFamily, false);
  7109. AddLocalPacketHandler(PacketType.ObjectIncludeInSearch, HandleObjectIncludeInSearch);
  7110. AddLocalPacketHandler(PacketType.ScriptAnswerYes, HandleScriptAnswerYes, false);
  7111. AddLocalPacketHandler(PacketType.ObjectClickAction, HandleObjectClickAction, false);
  7112. AddLocalPacketHandler(PacketType.ObjectMaterial, HandleObjectMaterial, false);
  7113. AddLocalPacketHandler(PacketType.RequestImage, HandleRequestImage, false);
  7114. AddLocalPacketHandler(PacketType.TransferRequest, HandleTransferRequest, false);
  7115. AddLocalPacketHandler(PacketType.AssetUploadRequest, HandleAssetUploadRequest);
  7116. AddLocalPacketHandler(PacketType.RequestXfer, HandleRequestXfer);
  7117. AddLocalPacketHandler(PacketType.SendXferPacket, HandleSendXferPacket);
  7118. AddLocalPacketHandler(PacketType.ConfirmXferPacket, HandleConfirmXferPacket, false);
  7119. AddLocalPacketHandler(PacketType.AbortXfer, HandleAbortXfer);
  7120. AddLocalPacketHandler(PacketType.CreateInventoryFolder, HandleCreateInventoryFolder);
  7121. AddLocalPacketHandler(PacketType.UpdateInventoryFolder, HandleUpdateInventoryFolder);
  7122. AddLocalPacketHandler(PacketType.MoveInventoryFolder, HandleMoveInventoryFolder);
  7123. AddLocalPacketHandler(PacketType.CreateInventoryItem, HandleCreateInventoryItem);
  7124. AddLocalPacketHandler(PacketType.LinkInventoryItem, HandleLinkInventoryItem);
  7125. AddLocalPacketHandler(PacketType.FetchInventory, HandleFetchInventory);
  7126. AddLocalPacketHandler(PacketType.FetchInventoryDescendents, HandleFetchInventoryDescendents);
  7127. AddLocalPacketHandler(PacketType.PurgeInventoryDescendents, HandlePurgeInventoryDescendents);
  7128. AddLocalPacketHandler(PacketType.UpdateInventoryItem, HandleUpdateInventoryItem);
  7129. AddLocalPacketHandler(PacketType.CopyInventoryItem, HandleCopyInventoryItem);
  7130. AddLocalPacketHandler(PacketType.MoveInventoryItem, HandleMoveInventoryItem);
  7131. AddLocalPacketHandler(PacketType.RemoveInventoryItem, HandleRemoveInventoryItem);
  7132. AddLocalPacketHandler(PacketType.RemoveInventoryFolder, HandleRemoveInventoryFolder);
  7133. AddLocalPacketHandler(PacketType.RemoveInventoryObjects, HandleRemoveInventoryObjects);
  7134. AddLocalPacketHandler(PacketType.RequestTaskInventory, HandleRequestTaskInventory);
  7135. AddLocalPacketHandler(PacketType.UpdateTaskInventory, HandleUpdateTaskInventory);
  7136. AddLocalPacketHandler(PacketType.RemoveTaskInventory, HandleRemoveTaskInventory);
  7137. AddLocalPacketHandler(PacketType.MoveTaskInventory, HandleMoveTaskInventory);
  7138. AddLocalPacketHandler(PacketType.RezScript, HandleRezScript);
  7139. AddLocalPacketHandler(PacketType.MapLayerRequest, HandleMapLayerRequest);
  7140. AddLocalPacketHandler(PacketType.MapBlockRequest, HandleMapBlockRequest);
  7141. AddLocalPacketHandler(PacketType.MapNameRequest, HandleMapNameRequest);
  7142. AddLocalPacketHandler(PacketType.TeleportLandmarkRequest, HandleTeleportLandmarkRequest);
  7143. AddLocalPacketHandler(PacketType.TeleportCancel, HandleTeleportCancel);
  7144. AddLocalPacketHandler(PacketType.TeleportLocationRequest, HandleTeleportLocationRequest);
  7145. AddLocalPacketHandler(PacketType.UUIDNameRequest, HandleUUIDNameRequest, false);
  7146. AddLocalPacketHandler(PacketType.RegionHandleRequest, HandleRegionHandleRequest, false);
  7147. AddLocalPacketHandler(PacketType.ParcelInfoRequest, HandleParcelInfoRequest);
  7148. AddLocalPacketHandler(PacketType.ParcelAccessListRequest, HandleParcelAccessListRequest, false);
  7149. AddLocalPacketHandler(PacketType.ParcelAccessListUpdate, HandleParcelAccessListUpdate, false);
  7150. AddLocalPacketHandler(PacketType.ParcelPropertiesRequest, HandleParcelPropertiesRequest, false);
  7151. AddLocalPacketHandler(PacketType.ParcelDivide, HandleParcelDivide);
  7152. AddLocalPacketHandler(PacketType.ParcelJoin, HandleParcelJoin);
  7153. AddLocalPacketHandler(PacketType.ParcelPropertiesUpdate, HandleParcelPropertiesUpdate);
  7154. AddLocalPacketHandler(PacketType.ParcelSelectObjects, HandleParcelSelectObjects);
  7155. AddLocalPacketHandler(PacketType.ParcelObjectOwnersRequest, HandleParcelObjectOwnersRequest);
  7156. AddLocalPacketHandler(PacketType.ParcelGodForceOwner, HandleParcelGodForceOwner);
  7157. AddLocalPacketHandler(PacketType.ParcelRelease, HandleParcelRelease);
  7158. AddLocalPacketHandler(PacketType.ParcelReclaim, HandleParcelReclaim);
  7159. AddLocalPacketHandler(PacketType.ParcelReturnObjects, HandleParcelReturnObjects);
  7160. AddLocalPacketHandler(PacketType.ParcelSetOtherCleanTime, HandleParcelSetOtherCleanTime);
  7161. AddLocalPacketHandler(PacketType.LandStatRequest, HandleLandStatRequest);
  7162. AddLocalPacketHandler(PacketType.ParcelDwellRequest, HandleParcelDwellRequest);
  7163. AddLocalPacketHandler(PacketType.EstateOwnerMessage, HandleEstateOwnerMessage);
  7164. AddLocalPacketHandler(PacketType.RequestRegionInfo, HandleRequestRegionInfo, false);
  7165. AddLocalPacketHandler(PacketType.EstateCovenantRequest, HandleEstateCovenantRequest);
  7166. AddLocalPacketHandler(PacketType.RequestGodlikePowers, HandleRequestGodlikePowers);
  7167. AddLocalPacketHandler(PacketType.GodKickUser, HandleGodKickUser);
  7168. AddLocalPacketHandler(PacketType.MoneyBalanceRequest, HandleMoneyBalanceRequest);
  7169. AddLocalPacketHandler(PacketType.EconomyDataRequest, HandleEconomyDataRequest);
  7170. AddLocalPacketHandler(PacketType.RequestPayPrice, HandleRequestPayPrice);
  7171. AddLocalPacketHandler(PacketType.ObjectSaleInfo, HandleObjectSaleInfo);
  7172. AddLocalPacketHandler(PacketType.ObjectBuy, HandleObjectBuy);
  7173. AddLocalPacketHandler(PacketType.GetScriptRunning, HandleGetScriptRunning);
  7174. AddLocalPacketHandler(PacketType.SetScriptRunning, HandleSetScriptRunning);
  7175. AddLocalPacketHandler(PacketType.ScriptReset, HandleScriptReset);
  7176. AddLocalPacketHandler(PacketType.ActivateGestures, HandleActivateGestures);
  7177. AddLocalPacketHandler(PacketType.DeactivateGestures, HandleDeactivateGestures);
  7178. AddLocalPacketHandler(PacketType.ObjectOwner, HandleObjectOwner);
  7179. AddLocalPacketHandler(PacketType.AgentFOV, HandleAgentFOV, false);
  7180. AddLocalPacketHandler(PacketType.ViewerStats, HandleViewerStats);
  7181. AddLocalPacketHandler(PacketType.MapItemRequest, HandleMapItemRequest, false);
  7182. AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
  7183. AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
  7184. AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
  7185. AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
  7186. AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
  7187. AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
  7188. AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
  7189. AddLocalPacketHandler(PacketType.DirFindQuery, HandleDirFindQuery);
  7190. AddLocalPacketHandler(PacketType.DirLandQuery, HandleDirLandQuery);
  7191. AddLocalPacketHandler(PacketType.DirPopularQuery, HandleDirPopularQuery);
  7192. AddLocalPacketHandler(PacketType.DirClassifiedQuery, HandleDirClassifiedQuery);
  7193. AddLocalPacketHandler(PacketType.EventInfoRequest, HandleEventInfoRequest);
  7194. AddLocalPacketHandler(PacketType.OfferCallingCard, HandleOfferCallingCard);
  7195. AddLocalPacketHandler(PacketType.AcceptCallingCard, HandleAcceptCallingCard);
  7196. AddLocalPacketHandler(PacketType.DeclineCallingCard, HandleDeclineCallingCard);
  7197. AddLocalPacketHandler(PacketType.ActivateGroup, HandleActivateGroup);
  7198. AddLocalPacketHandler(PacketType.GroupTitlesRequest, HandleGroupTitlesRequest);
  7199. AddLocalPacketHandler(PacketType.GroupProfileRequest, HandleGroupProfileRequest);
  7200. AddLocalPacketHandler(PacketType.GroupMembersRequest, HandleGroupMembersRequest);
  7201. AddLocalPacketHandler(PacketType.GroupRoleDataRequest, HandleGroupRoleDataRequest);
  7202. AddLocalPacketHandler(PacketType.GroupRoleMembersRequest, HandleGroupRoleMembersRequest);
  7203. AddLocalPacketHandler(PacketType.CreateGroupRequest, HandleCreateGroupRequest);
  7204. AddLocalPacketHandler(PacketType.UpdateGroupInfo, HandleUpdateGroupInfo);
  7205. AddLocalPacketHandler(PacketType.SetGroupAcceptNotices, HandleSetGroupAcceptNotices);
  7206. AddLocalPacketHandler(PacketType.GroupTitleUpdate, HandleGroupTitleUpdate);
  7207. AddLocalPacketHandler(PacketType.ParcelDeedToGroup, HandleParcelDeedToGroup);
  7208. AddLocalPacketHandler(PacketType.GroupNoticesListRequest, HandleGroupNoticesListRequest);
  7209. AddLocalPacketHandler(PacketType.GroupNoticeRequest, HandleGroupNoticeRequest);
  7210. AddLocalPacketHandler(PacketType.GroupRoleUpdate, HandleGroupRoleUpdate);
  7211. AddLocalPacketHandler(PacketType.GroupRoleChanges, HandleGroupRoleChanges);
  7212. AddLocalPacketHandler(PacketType.JoinGroupRequest, HandleJoinGroupRequest);
  7213. AddLocalPacketHandler(PacketType.LeaveGroupRequest, HandleLeaveGroupRequest);
  7214. AddLocalPacketHandler(PacketType.EjectGroupMemberRequest, HandleEjectGroupMemberRequest);
  7215. AddLocalPacketHandler(PacketType.InviteGroupRequest, HandleInviteGroupRequest);
  7216. AddLocalPacketHandler(PacketType.StartLure, HandleStartLure);
  7217. AddLocalPacketHandler(PacketType.TeleportLureRequest, HandleTeleportLureRequest);
  7218. AddLocalPacketHandler(PacketType.ClassifiedInfoRequest, HandleClassifiedInfoRequest);
  7219. AddLocalPacketHandler(PacketType.ClassifiedInfoUpdate, HandleClassifiedInfoUpdate);
  7220. AddLocalPacketHandler(PacketType.ClassifiedDelete, HandleClassifiedDelete);
  7221. AddLocalPacketHandler(PacketType.ClassifiedGodDelete, HandleClassifiedGodDelete);
  7222. AddLocalPacketHandler(PacketType.EventGodDelete, HandleEventGodDelete);
  7223. AddLocalPacketHandler(PacketType.EventNotificationAddRequest, HandleEventNotificationAddRequest);
  7224. AddLocalPacketHandler(PacketType.EventNotificationRemoveRequest, HandleEventNotificationRemoveRequest);
  7225. AddLocalPacketHandler(PacketType.RetrieveInstantMessages, HandleRetrieveInstantMessages);
  7226. AddLocalPacketHandler(PacketType.PickDelete, HandlePickDelete);
  7227. AddLocalPacketHandler(PacketType.PickGodDelete, HandlePickGodDelete);
  7228. AddLocalPacketHandler(PacketType.PickInfoUpdate, HandlePickInfoUpdate);
  7229. AddLocalPacketHandler(PacketType.AvatarNotesUpdate, HandleAvatarNotesUpdate);
  7230. AddLocalPacketHandler(PacketType.AvatarInterestsUpdate, HandleAvatarInterestsUpdate);
  7231. AddLocalPacketHandler(PacketType.GrantUserRights, HandleGrantUserRights);
  7232. AddLocalPacketHandler(PacketType.PlacesQuery, HandlePlacesQuery);
  7233. AddLocalPacketHandler(PacketType.UpdateMuteListEntry, HandleUpdateMuteListEntry);
  7234. AddLocalPacketHandler(PacketType.RemoveMuteListEntry, HandleRemoveMuteListEntry);
  7235. AddLocalPacketHandler(PacketType.UserReport, HandleUserReport);
  7236. AddLocalPacketHandler(PacketType.FindAgent, HandleFindAgent);
  7237. AddLocalPacketHandler(PacketType.TrackAgent, HandleTrackAgent);
  7238. AddLocalPacketHandler(PacketType.GodUpdateRegionInfo, HandleGodUpdateRegionInfoUpdate);
  7239. AddLocalPacketHandler(PacketType.GodlikeMessage, HandleGodlikeMessage);
  7240. AddLocalPacketHandler(PacketType.StateSave, HandleSaveStatePacket);
  7241. AddLocalPacketHandler(PacketType.GroupAccountDetailsRequest, HandleGroupAccountDetailsRequest);
  7242. AddLocalPacketHandler(PacketType.GroupAccountSummaryRequest, HandleGroupAccountSummaryRequest);
  7243. AddLocalPacketHandler(PacketType.GroupAccountTransactionsRequest, HandleGroupTransactionsDetailsRequest);
  7244. AddLocalPacketHandler(PacketType.FreezeUser, HandleFreezeUser);
  7245. AddLocalPacketHandler(PacketType.EjectUser, HandleEjectUser);
  7246. AddLocalPacketHandler(PacketType.ParcelBuyPass, HandleParcelBuyPass);
  7247. AddLocalPacketHandler(PacketType.ParcelGodMarkAsContent, HandleParcelGodMarkAsContent);
  7248. AddLocalPacketHandler(PacketType.GroupActiveProposalsRequest, HandleGroupActiveProposalsRequest);
  7249. AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest);
  7250. AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes);
  7251. AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard);
  7252. AddLocalPacketHandler(PacketType.ChangeInventoryItemFlags, HandleChangeInventoryItemFlags);
  7253. AddLocalPacketHandler(PacketType.RevokePermissions, HandleRevokePermissions);
  7254. AddGenericPacketHandler("autopilot", HandleAutopilot);
  7255. }
  7256. #region Packet Handlers
  7257. public int TotalAgentUpdates { get; set; }
  7258. #region Scene/Avatar
  7259. // Threshold for body rotation to be a significant agent update
  7260. // use the abs of cos
  7261. private const float QDELTABody = 1.0f - 0.00001f;
  7262. private const float QDELTAHead = 1.0f - 0.00001f;
  7263. // Threshold for camera rotation to be a significant agent update
  7264. private const float VDELTA = 0.01f;
  7265. /// <summary>
  7266. /// This checks the update significance against the last update made.
  7267. /// </summary>
  7268. /// <remarks>Can only be called by one thread at a time</remarks>
  7269. /// <returns></returns>
  7270. /// <param name='x'></param>
  7271. public bool CheckAgentUpdateSignificance(AgentUpdatePacket.AgentDataBlock x)
  7272. {
  7273. return CheckAgentMovementUpdateSignificance(x) || CheckAgentCameraUpdateSignificance(x);
  7274. }
  7275. /// <summary>
  7276. /// This checks the movement/state update significance against the last update made.
  7277. /// </summary>
  7278. /// <remarks>Can only be called by one thread at a time</remarks>
  7279. /// <returns></returns>
  7280. /// <param name='x'></param>
  7281. private bool CheckAgentMovementUpdateSignificance(AgentUpdatePacket.AgentDataBlock x)
  7282. {
  7283. if(
  7284. (x.ControlFlags != m_thisAgentUpdateArgs.ControlFlags) // significant if control flags changed
  7285. || (x.ControlFlags & ~(uint)AgentManager.ControlFlags.AGENT_CONTROL_FINISH_ANIM) != (uint)AgentManager.ControlFlags.NONE
  7286. || (x.Flags != m_thisAgentUpdateArgs.Flags) // significant if Flags changed
  7287. || (x.State != m_thisAgentUpdateArgs.State) // significant if Stats changed
  7288. || (Math.Abs(x.Far - m_thisAgentUpdateArgs.Far) >= 32) // significant if far distance changed
  7289. )
  7290. return true;
  7291. float qdelta = Math.Abs(x.BodyRotation.Dot(m_thisAgentUpdateArgs.BodyRotation));
  7292. return qdelta < QDELTABody; // significant if body rotation above(below cos) threshold
  7293. }
  7294. /// <summary>
  7295. /// This checks the camera update significance against the last update made.
  7296. /// </summary>
  7297. /// <remarks>Can only be called by one thread at a time</remarks>
  7298. /// <returns></returns>
  7299. /// <param name='x'></param>
  7300. private bool CheckAgentCameraUpdateSignificance(AgentUpdatePacket.AgentDataBlock x)
  7301. {
  7302. return (Math.Abs(x.CameraCenter.X - m_thisAgentUpdateArgs.CameraCenter.X) > VDELTA ||
  7303. Math.Abs(x.CameraCenter.Y - m_thisAgentUpdateArgs.CameraCenter.Y) > VDELTA ||
  7304. Math.Abs(x.CameraCenter.Z - m_thisAgentUpdateArgs.CameraCenter.Z) > VDELTA ||
  7305. Math.Abs(x.CameraAtAxis.X - m_thisAgentUpdateArgs.CameraAtAxis.X) > VDELTA ||
  7306. Math.Abs(x.CameraAtAxis.Y - m_thisAgentUpdateArgs.CameraAtAxis.Y) > VDELTA ||
  7307. Math.Abs(x.CameraUpAxis.X - m_thisAgentUpdateArgs.CameraUpAxis.X) > VDELTA ||
  7308. Math.Abs(x.CameraUpAxis.Y - m_thisAgentUpdateArgs.CameraUpAxis.Y) > VDELTA
  7309. );
  7310. }
  7311. private void HandleAgentUpdate(Packet packet)
  7312. {
  7313. if(OnAgentUpdate == null)
  7314. return;
  7315. AgentUpdatePacket agentUpdate = (AgentUpdatePacket)packet;
  7316. AgentUpdatePacket.AgentDataBlock x = agentUpdate.AgentData;
  7317. if (x.AgentID.NotEqual(m_agentId) || x.SessionID.NotEqual(m_sessionId))
  7318. return;
  7319. uint seq = packet.Header.Sequence;
  7320. TotalAgentUpdates++;
  7321. // dont let ignored updates pollute this throttles
  7322. if(SceneAgent == null || SceneAgent.IsChildAgent ||
  7323. SceneAgent.IsInTransit || seq <= m_thisAgentUpdateArgs.lastpacketSequence )
  7324. {
  7325. // throttle reset is done at MoveAgentIntoRegion()
  7326. // called by scenepresence on completemovement
  7327. //PacketPool.Instance.ReturnPacket(packet);
  7328. return;
  7329. }
  7330. m_thisAgentUpdateArgs.lastpacketSequence = seq;
  7331. OnPreAgentUpdate?.Invoke(this, m_thisAgentUpdateArgs);
  7332. bool movement;
  7333. bool camera;
  7334. double now = Util.GetTimeStampMS();
  7335. if(now - m_thisAgentUpdateArgs.lastUpdateTS > 500.0) // at least 2 per sec
  7336. {
  7337. movement = true;
  7338. camera = true;
  7339. }
  7340. else
  7341. {
  7342. movement = CheckAgentMovementUpdateSignificance(x);
  7343. camera = CheckAgentCameraUpdateSignificance(x);
  7344. }
  7345. // Was there a significant movement/state change?
  7346. if (movement)
  7347. {
  7348. m_thisAgentUpdateArgs.BodyRotation = x.BodyRotation;
  7349. m_thisAgentUpdateArgs.ControlFlags = x.ControlFlags;
  7350. m_thisAgentUpdateArgs.Far = x.Far;
  7351. m_thisAgentUpdateArgs.Flags = x.Flags;
  7352. m_thisAgentUpdateArgs.HeadRotation = x.HeadRotation;
  7353. m_thisAgentUpdateArgs.State = x.State;
  7354. m_thisAgentUpdateArgs.NeedsCameraCollision = !camera;
  7355. OnAgentUpdate?.Invoke(this, m_thisAgentUpdateArgs);
  7356. }
  7357. // Was there a significant camera(s) change?
  7358. if (camera)
  7359. {
  7360. m_thisAgentUpdateArgs.CameraAtAxis = x.CameraAtAxis;
  7361. m_thisAgentUpdateArgs.CameraCenter = x.CameraCenter;
  7362. m_thisAgentUpdateArgs.CameraLeftAxis = x.CameraLeftAxis;
  7363. m_thisAgentUpdateArgs.CameraUpAxis = x.CameraUpAxis;
  7364. m_thisAgentUpdateArgs.NeedsCameraCollision = true;
  7365. OnAgentCameraUpdate?.Invoke(this, m_thisAgentUpdateArgs);
  7366. }
  7367. if(movement && camera)
  7368. m_thisAgentUpdateArgs.lastUpdateTS = now;
  7369. }
  7370. private void HandleMoneyTransferRequest(Packet Pack)
  7371. {
  7372. if(OnMoneyTransferRequest == null)
  7373. return;
  7374. MoneyTransferRequestPacket money = (MoneyTransferRequestPacket)Pack;
  7375. // validate the agent owns the agentID and sessionID
  7376. if (money.MoneyData.SourceID.Equals(m_agentId) && money.AgentData.AgentID.Equals(m_agentId) &&
  7377. money.AgentData.SessionID.Equals(m_sessionId))
  7378. {
  7379. OnMoneyTransferRequest?.Invoke(money.MoneyData.SourceID, money.MoneyData.DestID,
  7380. money.MoneyData.Amount, money.MoneyData.TransactionType,
  7381. Util.FieldToString(money.MoneyData.Description));
  7382. }
  7383. }
  7384. private void HandleParcelGodMarkAsContent(Packet packet)
  7385. {
  7386. if(OnParcelGodMark == null)
  7387. return;
  7388. ParcelGodMarkAsContentPacket ParcelGodMarkAsContent = (ParcelGodMarkAsContentPacket)packet;
  7389. if(m_sessionId != ParcelGodMarkAsContent.AgentData.SessionID || m_agentId != ParcelGodMarkAsContent.AgentData.AgentID)
  7390. return;
  7391. OnParcelGodMark?.Invoke(this,
  7392. m_agentId,
  7393. ParcelGodMarkAsContent.ParcelData.LocalID);
  7394. }
  7395. private void HandleFreezeUser(Packet packet)
  7396. {
  7397. if(OnParcelFreezeUser == null)
  7398. return;
  7399. FreezeUserPacket FreezeUser = (FreezeUserPacket)packet;
  7400. if(m_sessionId != FreezeUser.AgentData.SessionID || m_agentId != FreezeUser.AgentData.AgentID)
  7401. return;
  7402. OnParcelFreezeUser?.Invoke(this,
  7403. m_agentId,
  7404. FreezeUser.Data.Flags,
  7405. FreezeUser.Data.TargetID);
  7406. }
  7407. private void HandleEjectUser(Packet packet)
  7408. {
  7409. if(OnParcelEjectUser == null)
  7410. return;
  7411. EjectUserPacket EjectUser = (EjectUserPacket)packet;
  7412. if(m_sessionId != EjectUser.AgentData.SessionID || m_agentId != EjectUser.AgentData.AgentID)
  7413. return;
  7414. OnParcelEjectUser?.Invoke(this,
  7415. m_agentId,
  7416. EjectUser.Data.Flags,
  7417. EjectUser.Data.TargetID);
  7418. }
  7419. private void HandleParcelBuyPass(Packet packet)
  7420. {
  7421. if(OnParcelBuyPass == null)
  7422. return;
  7423. ParcelBuyPassPacket ParcelBuyPass = (ParcelBuyPassPacket)packet;
  7424. if(m_sessionId != ParcelBuyPass.AgentData.SessionID || m_agentId != ParcelBuyPass.AgentData.AgentID)
  7425. return;
  7426. OnParcelBuyPass?.Invoke(this,
  7427. m_agentId,
  7428. ParcelBuyPass.ParcelData.LocalID);
  7429. }
  7430. private void HandleParcelBuyRequest(Packet Pack)
  7431. {
  7432. ParcelBuyPacket parcel = (ParcelBuyPacket)Pack;
  7433. if (parcel.AgentData.AgentID.Equals(m_agentId) && parcel.AgentData.SessionID.Equals(m_sessionId))
  7434. {
  7435. OnParcelBuy?.Invoke(m_agentId, parcel.Data.GroupID, parcel.Data.Final,
  7436. parcel.Data.IsGroupOwned,
  7437. parcel.Data.RemoveContribution, parcel.Data.LocalID, parcel.ParcelData.Area,
  7438. parcel.ParcelData.Price,
  7439. false);
  7440. }
  7441. }
  7442. private void HandleUUIDGroupNameRequest(Packet Pack)
  7443. {
  7444. if(OnUUIDGroupNameRequest == null)
  7445. return;
  7446. ScenePresence sp = (ScenePresence)SceneAgent;
  7447. if(sp == null || sp.IsDeleted || (sp.IsInTransit && !sp.IsInLocalTransit))
  7448. return;
  7449. UUIDGroupNameRequestPacket upack = (UUIDGroupNameRequestPacket)Pack;
  7450. for (int i = 0; i < upack.UUIDNameBlock.Length; i++)
  7451. {
  7452. OnUUIDGroupNameRequest?.Invoke(upack.UUIDNameBlock[i].ID, this);
  7453. }
  7454. }
  7455. public void HandleGenericMessage(Packet pack)
  7456. {
  7457. if (m_genericPacketHandlers.Count == 0)
  7458. return;
  7459. GenericMessagePacket gmpack = (GenericMessagePacket)pack;
  7460. if (gmpack.AgentData.SessionID.NotEqual(m_sessionId) || gmpack.AgentData.AgentID.NotEqual(m_agentId))
  7461. return;
  7462. string method = Util.FieldToString(gmpack.MethodData.Method).ToLower().Trim();
  7463. if (m_genericPacketHandlers.TryGetValue(method, out GenericMessage handlerGenericMessage))
  7464. {
  7465. List<string> msg = new List<string>();
  7466. List<byte[]> msgBytes = new List<byte[]>();
  7467. foreach (GenericMessagePacket.ParamListBlock block in gmpack.ParamList)
  7468. {
  7469. msg.Add(Util.FieldToString(block.Parameter));
  7470. msgBytes.Add(block.Parameter);
  7471. }
  7472. try
  7473. {
  7474. OnBinaryGenericMessage?.Invoke(this, method, msgBytes.ToArray());
  7475. handlerGenericMessage?.Invoke(this, method, msg);
  7476. }
  7477. catch (Exception e)
  7478. {
  7479. m_log.ErrorFormat(
  7480. "[LLCLIENTVIEW]: Exception when handling generic message {0}{1}", e.Message, e.StackTrace);
  7481. }
  7482. }
  7483. }
  7484. public void HandleObjectGroupRequest(Packet Pack)
  7485. {
  7486. if(OnObjectGroupRequest == null)
  7487. return;
  7488. ObjectGroupPacket ogpack = (ObjectGroupPacket)Pack;
  7489. if (ogpack.AgentData.SessionID.NotEqual(m_sessionId))
  7490. return;
  7491. for (int i = 0; i < ogpack.ObjectData.Length; i++)
  7492. {
  7493. OnObjectGroupRequest?.Invoke(this, ogpack.AgentData.GroupID, ogpack.ObjectData[i].ObjectLocalID, UUID.Zero);
  7494. }
  7495. }
  7496. private void HandleViewerEffect(Packet Pack)
  7497. {
  7498. if(OnViewerEffect == null)
  7499. return;
  7500. ViewerEffectPacket viewer = (ViewerEffectPacket)Pack;
  7501. if (viewer.AgentData.SessionID.NotEqual(m_sessionId) || m_agentId != viewer.AgentData.AgentID)
  7502. return;
  7503. int length = viewer.Effect.Length;
  7504. List<ViewerEffectEventHandlerArg> args = new List<ViewerEffectEventHandlerArg>(length);
  7505. for (int i = 0; i < length; i++)
  7506. {
  7507. //copy the effects block arguments into the event handler arg.
  7508. ViewerEffectEventHandlerArg argument = new ViewerEffectEventHandlerArg();
  7509. argument.AgentID = viewer.Effect[i].AgentID;
  7510. argument.Color = viewer.Effect[i].Color;
  7511. argument.Duration = viewer.Effect[i].Duration;
  7512. argument.ID = viewer.Effect[i].ID;
  7513. argument.Type = viewer.Effect[i].Type;
  7514. argument.TypeData = viewer.Effect[i].TypeData;
  7515. args.Add(argument);
  7516. }
  7517. OnViewerEffect?.Invoke(this, args);
  7518. }
  7519. private void HandleVelocityInterpolateOff(Packet Pack)
  7520. {
  7521. VelocityInterpolateOffPacket p = (VelocityInterpolateOffPacket)Pack;
  7522. if (p.AgentData.SessionID.NotEqual(m_sessionId) || p.AgentData.AgentID.NotEqual(m_agentId))
  7523. return ;
  7524. m_VelocityInterpolate = false;
  7525. }
  7526. private void HandleVelocityInterpolateOn(Packet Pack)
  7527. {
  7528. VelocityInterpolateOnPacket p = (VelocityInterpolateOnPacket)Pack;
  7529. if (p.AgentData.SessionID.NotEqual(m_sessionId) || p.AgentData.AgentID.NotEqual(m_agentId))
  7530. return;
  7531. m_VelocityInterpolate = true;
  7532. }
  7533. private void HandleAvatarPropertiesRequest(Packet Pack)
  7534. {
  7535. AvatarPropertiesRequestPacket avatarProperties = (AvatarPropertiesRequestPacket)Pack;
  7536. if (avatarProperties.AgentData.SessionID.NotEqual(m_sessionId) || avatarProperties.AgentData.AgentID.NotEqual(m_agentId))
  7537. return;
  7538. OnRequestAvatarProperties?.Invoke(this, avatarProperties.AgentData.AvatarID);
  7539. }
  7540. private void HandleChatFromViewer(Packet Pack)
  7541. {
  7542. if (OnChatFromClient == null)
  7543. return;
  7544. ChatFromViewerPacket inchatpack = (ChatFromViewerPacket)Pack;
  7545. if (inchatpack.AgentData.SessionID.NotEqual(m_sessionId) || inchatpack.AgentData.AgentID.NotEqual(m_agentId))
  7546. return;
  7547. ChatFromViewerPacket.ChatDataBlock packdata = inchatpack.ChatData;
  7548. OSChatMessage args = new OSChatMessage()
  7549. {
  7550. Channel = packdata.Channel,
  7551. Message = Utils.BytesToString(packdata.Message),
  7552. Type = (ChatTypeEnum)packdata.Type,
  7553. Position = SceneAgent.AbsolutePosition,
  7554. Scene = Scene,
  7555. Sender = this
  7556. };
  7557. OnChatFromClient?.Invoke(this, args);
  7558. }
  7559. private void HandlerAvatarPropertiesUpdate(Packet Pack)
  7560. {
  7561. if (OnUpdateAvatarProperties == null)
  7562. return;
  7563. AvatarPropertiesUpdatePacket avatarProps = (AvatarPropertiesUpdatePacket)Pack;
  7564. if (avatarProps.AgentData.SessionID.NotEqual(m_sessionId) || avatarProps.AgentData.AgentID.NotEqual(m_agentId))
  7565. return;
  7566. AvatarPropertiesUpdatePacket.PropertiesDataBlock Properties = avatarProps.PropertiesData;
  7567. UserProfileProperties UserProfile = new UserProfileProperties
  7568. {
  7569. UserId = AgentId,
  7570. WebUrl = Utils.BytesToString(Properties.ProfileURL),
  7571. ImageId = Properties.ImageID,
  7572. FirstLifeImageId = Properties.FLImageID,
  7573. AboutText = Utils.BytesToString(Properties.AboutText),
  7574. FirstLifeText = Utils.BytesToString(Properties.FLAboutText),
  7575. PublishProfile = Properties.AllowPublish,
  7576. PublishMature = Properties.MaturePublish
  7577. };
  7578. OnUpdateAvatarProperties?.Invoke(this, UserProfile);
  7579. }
  7580. private void HandlerScriptDialogReply(Packet Pack)
  7581. {
  7582. if (OnChatFromClient == null)
  7583. return;
  7584. ScriptDialogReplyPacket rdialog = (ScriptDialogReplyPacket)Pack;
  7585. //m_log.DebugFormat("[CLIENT]: Received ScriptDialogReply from {0}", rdialog.Data.ObjectID);
  7586. if (rdialog.AgentData.SessionID.NotEqual(m_sessionId) || rdialog.AgentData.AgentID.NotEqual(m_agentId))
  7587. return;
  7588. ScriptDialogReplyPacket.DataBlock rdialogData = rdialog.Data;
  7589. OSChatMessage args = new OSChatMessage()
  7590. {
  7591. Channel = rdialogData.ChatChannel,
  7592. Message = Utils.BytesToString(rdialogData.ButtonLabel),
  7593. Type = ChatTypeEnum.Region, //Behaviour in SL is that the response can be heard from any distance
  7594. Scene = Scene,
  7595. Sender = this
  7596. };
  7597. OnChatFromClient?.Invoke(this, args);
  7598. }
  7599. private void HandlerImprovedInstantMessage(Packet Pack)
  7600. {
  7601. if(OnInstantMessage == null)
  7602. return;
  7603. ImprovedInstantMessagePacket msgpack = (ImprovedInstantMessagePacket)Pack;
  7604. if (msgpack.AgentData.SessionID.NotEqual(m_sessionId) || msgpack.AgentData.AgentID.NotEqual(m_agentId))
  7605. return;
  7606. string IMfromName = Util.FieldToString(msgpack.MessageBlock.FromAgentName);
  7607. string IMmessage = Utils.BytesToString(msgpack.MessageBlock.Message);
  7608. GridInstantMessage im = new GridInstantMessage(Scene,
  7609. msgpack.AgentData.AgentID,
  7610. IMfromName,
  7611. msgpack.MessageBlock.ToAgentID,
  7612. msgpack.MessageBlock.Dialog,
  7613. msgpack.MessageBlock.FromGroup,
  7614. IMmessage,
  7615. msgpack.MessageBlock.ID,
  7616. msgpack.MessageBlock.Offline != 0 ? true : false,
  7617. msgpack.MessageBlock.Position,
  7618. msgpack.MessageBlock.BinaryBucket,
  7619. true);
  7620. OnInstantMessage?.Invoke(this, im);
  7621. }
  7622. private void HandlerAcceptFriendship(Packet Pack)
  7623. {
  7624. if(OnApproveFriendRequest == null)
  7625. return;
  7626. AcceptFriendshipPacket afriendpack = (AcceptFriendshipPacket)Pack;
  7627. if (afriendpack.AgentData.SessionID.NotEqual(m_sessionId) || afriendpack.AgentData.AgentID.NotEqual(m_agentId))
  7628. return;
  7629. // My guess is this is the folder to stick the calling card into
  7630. List<UUID> callingCardFolders = new List<UUID>();
  7631. UUID transactionID = afriendpack.TransactionBlock.TransactionID;
  7632. for (int fi = 0; fi < afriendpack.FolderData.Length; fi++)
  7633. {
  7634. callingCardFolders.Add(afriendpack.FolderData[fi].FolderID);
  7635. }
  7636. OnApproveFriendRequest?.Invoke(this, transactionID, callingCardFolders);
  7637. }
  7638. private void HandlerDeclineFriendship(Packet Pack)
  7639. {
  7640. DeclineFriendshipPacket dfriendpack = (DeclineFriendshipPacket)Pack;
  7641. if (dfriendpack.AgentData.SessionID.NotEqual(m_sessionId) || dfriendpack.AgentData.AgentID.NotEqual(m_agentId))
  7642. return;
  7643. OnDenyFriendRequest?.Invoke(this,
  7644. dfriendpack.TransactionBlock.TransactionID,
  7645. null);
  7646. }
  7647. private void HandlerTerminateFriendship(Packet Pack)
  7648. {
  7649. TerminateFriendshipPacket tfriendpack = (TerminateFriendshipPacket)Pack;
  7650. if (tfriendpack.AgentData.SessionID.NotEqual(m_sessionId) || tfriendpack.AgentData.AgentID.NotEqual(m_agentId))
  7651. return;
  7652. UUID exFriendID = tfriendpack.ExBlock.OtherID;
  7653. FriendshipTermination TerminateFriendshipHandler = OnTerminateFriendship;
  7654. TerminateFriendshipHandler?.Invoke(this, exFriendID);
  7655. }
  7656. private void HandleFindAgent(Packet packet)
  7657. {
  7658. FindAgentPacket FindAgent = (FindAgentPacket)packet;
  7659. OnFindAgent?.Invoke(this,FindAgent.AgentBlock.Hunter,FindAgent.AgentBlock.Prey);
  7660. }
  7661. private void HandleTrackAgent(Packet packet)
  7662. {
  7663. TrackAgentPacket TrackAgent = (TrackAgentPacket)packet;
  7664. if(TrackAgent.AgentData.AgentID.NotEqual(m_agentId) || TrackAgent.AgentData.SessionID.NotEqual(m_sessionId))
  7665. return;
  7666. OnTrackAgent?.Invoke(this,
  7667. TrackAgent.AgentData.AgentID,
  7668. TrackAgent.TargetData.PreyID);
  7669. }
  7670. private void HandlerRezObject(Packet Pack)
  7671. {
  7672. RezObjectPacket rezPacket = (RezObjectPacket)Pack;
  7673. if (rezPacket.AgentData.SessionID.NotEqual(m_sessionId) || rezPacket.AgentData.AgentID.NotEqual(m_agentId))
  7674. return;
  7675. UUID rezGroupID = rezPacket.AgentData.GroupID;
  7676. if(!IsGroupMember(rezGroupID))
  7677. rezGroupID = UUID.Zero;
  7678. OnRezObject?.Invoke(this, rezPacket.InventoryData.ItemID, rezGroupID, rezPacket.RezData.RayEnd,
  7679. rezPacket.RezData.RayStart, rezPacket.RezData.RayTargetID,
  7680. rezPacket.RezData.BypassRaycast, rezPacket.RezData.RayEndIsIntersection,
  7681. rezPacket.RezData.RezSelected, rezPacket.RezData.RemoveItem,
  7682. rezPacket.RezData.FromTaskID);
  7683. }
  7684. private class DeRezObjectInfo
  7685. {
  7686. public List<uint> objectids;
  7687. public HashSet<int> rcvedpackets;
  7688. }
  7689. private Dictionary<UUID, DeRezObjectInfo> m_DeRezObjectDelayed;
  7690. private void HandlerDeRezObject(Packet Pack)
  7691. {
  7692. if (OnDeRezObject == null)
  7693. return;
  7694. DeRezObjectPacket DeRezPacket = (DeRezObjectPacket)Pack;
  7695. DeRezObjectPacket.AgentDataBlock DeRezPacketAgentData = DeRezPacket.AgentData;
  7696. if (DeRezPacketAgentData.AgentID.NotEqual(m_agentId) || DeRezPacketAgentData.SessionID.NotEqual(m_sessionId))
  7697. return;
  7698. List<uint> deRezIDs;
  7699. DeRezObjectPacket.AgentBlockBlock DeRezPacketAgentBlock = DeRezPacket.AgentBlock;
  7700. DeRezAction action = (DeRezAction)DeRezPacketAgentBlock.Destination;
  7701. int numberPackets = DeRezPacketAgentBlock.PacketCount;
  7702. int curPacket = DeRezPacketAgentBlock.PacketNumber;
  7703. UUID id = DeRezPacketAgentBlock.TransactionID;
  7704. if (numberPackets > 1)
  7705. {
  7706. if(m_DeRezObjectDelayed == null)
  7707. m_DeRezObjectDelayed = new Dictionary<UUID, DeRezObjectInfo>();
  7708. if (!m_DeRezObjectDelayed.TryGetValue(id, out DeRezObjectInfo info))
  7709. {
  7710. deRezIDs = new List<uint>(DeRezPacket.ObjectData.Length);
  7711. info = new DeRezObjectInfo();
  7712. info.rcvedpackets = new HashSet<int>() { curPacket };
  7713. info.objectids = deRezIDs;
  7714. m_DeRezObjectDelayed[id] = info;
  7715. }
  7716. else
  7717. {
  7718. if(info.rcvedpackets.Contains(curPacket))
  7719. return;
  7720. info.rcvedpackets.Add(curPacket);
  7721. deRezIDs = info.objectids;
  7722. }
  7723. foreach (DeRezObjectPacket.ObjectDataBlock data in DeRezPacket.ObjectData)
  7724. {
  7725. deRezIDs.Add(data.ObjectLocalID);
  7726. }
  7727. if (info.rcvedpackets.Count < numberPackets)
  7728. return;
  7729. m_DeRezObjectDelayed.Remove(id);
  7730. info.objectids = null;
  7731. info.rcvedpackets = null;
  7732. }
  7733. else
  7734. {
  7735. deRezIDs = new List<uint>(DeRezPacket.ObjectData.Length);
  7736. foreach (DeRezObjectPacket.ObjectDataBlock data in DeRezPacket.ObjectData)
  7737. {
  7738. deRezIDs.Add(data.ObjectLocalID);
  7739. }
  7740. }
  7741. OnDeRezObject?.Invoke(this, deRezIDs, DeRezPacketAgentBlock.GroupID,
  7742. action, DeRezPacketAgentBlock.DestinationID);
  7743. }
  7744. private void HandlerRezRestoreToWorld(Packet Pack)
  7745. {
  7746. RezRestoreToWorldPacket restore = (RezRestoreToWorldPacket)Pack;
  7747. if (restore.AgentData.SessionID.NotEqual(m_sessionId) || restore.AgentData.AgentID.NotEqual(m_agentId))
  7748. return;
  7749. OnRezRestoreToWorld?.Invoke(this, restore.InventoryData.ItemID);
  7750. }
  7751. private void HandlerModifyLand(Packet Pack)
  7752. {
  7753. if (OnModifyTerrain == null)
  7754. return;
  7755. ModifyLandPacket modify = (ModifyLandPacket)Pack;
  7756. if (modify.ParcelData.Length == 0)
  7757. return;
  7758. if (modify.AgentData.SessionID.NotEqual(m_sessionId) || modify.AgentData.AgentID.NotEqual(m_agentId))
  7759. return;
  7760. //m_log.Info("[LAND]: LAND:" + modify.ToString());
  7761. for (int i = 0; i < modify.ParcelData.Length; i++)
  7762. {
  7763. OnModifyTerrain?.Invoke(m_agentId, modify.ModifyBlock.Height, modify.ModifyBlock.Seconds,
  7764. modify.ModifyBlockExtended[i].BrushSize, modify.ModifyBlock.Action,
  7765. modify.ParcelData[i].North, modify.ParcelData[i].West,
  7766. modify.ParcelData[i].South, modify.ParcelData[i].East,
  7767. modify.ParcelData[i].LocalID);
  7768. }
  7769. }
  7770. public uint m_viewerHandShakeFlags = 0;
  7771. private void HandlerRegionHandshakeReply(Packet Pack)
  7772. {
  7773. if (OnRegionHandShakeReply == null)
  7774. return; // silence the warning
  7775. RegionHandshakeReplyPacket rsrpkt = (RegionHandshakeReplyPacket)Pack;
  7776. if(rsrpkt.AgentData.AgentID.NotEqual(m_agentId) || rsrpkt.AgentData.SessionID.NotEqual(m_sessionId))
  7777. return;
  7778. if(m_supportViewerCache)
  7779. m_viewerHandShakeFlags = rsrpkt.RegionInfo.Flags;
  7780. else
  7781. m_viewerHandShakeFlags = 0;
  7782. OnRegionHandShakeReply?.Invoke(this);
  7783. }
  7784. private void HandlerAgentWearablesRequest(Packet Pack)
  7785. {
  7786. OnRequestWearables?.Invoke(this);
  7787. OnRequestAvatarsData?.Invoke(this);
  7788. }
  7789. private void HandlerAgentSetAppearance(Packet Pack)
  7790. {
  7791. if(OnSetAppearance == null)
  7792. return;
  7793. AgentSetAppearancePacket appear = (AgentSetAppearancePacket)Pack;
  7794. if (appear.AgentData.SessionID.NotEqual(m_sessionId) || appear.AgentData.AgentID.NotEqual(m_agentId))
  7795. return;
  7796. try
  7797. {
  7798. Vector3 avSize = appear.AgentData.Size;
  7799. byte[] visualparams = new byte[appear.VisualParam.Length];
  7800. for (int i = 0; i < appear.VisualParam.Length; i++)
  7801. visualparams[i] = appear.VisualParam[i].ParamValue;
  7802. //var b = appear.WearableData[0];
  7803. Primitive.TextureEntry te = null;
  7804. if (appear.ObjectData.TextureEntry.Length > 1)
  7805. te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length);
  7806. WearableCacheItem[] cacheitems = new WearableCacheItem[appear.WearableData.Length];
  7807. for (int i=0; i<appear.WearableData.Length;i++)
  7808. cacheitems[i] = new WearableCacheItem(){
  7809. CacheId = appear.WearableData[i].CacheID,
  7810. TextureIndex=Convert.ToUInt32(appear.WearableData[i].TextureIndex)
  7811. };
  7812. OnSetAppearance?.Invoke(this, te, visualparams,avSize, cacheitems);
  7813. }
  7814. catch (Exception e)
  7815. {
  7816. m_log.ErrorFormat(
  7817. "[CLIENT VIEW]: AgentSetApperance packet handler threw an exception, {0}",
  7818. e);
  7819. }
  7820. }
  7821. private void HandlerAgentIsNowWearing(Packet Pack)
  7822. {
  7823. if (OnAvatarNowWearing == null)
  7824. return;
  7825. AgentIsNowWearingPacket nowWearing = (AgentIsNowWearingPacket)Pack;
  7826. if (nowWearing.AgentData.SessionID.NotEqual(m_sessionId) || nowWearing.AgentData.AgentID.NotEqual(m_agentId))
  7827. return;
  7828. AvatarWearingArgs wearingArgs = new AvatarWearingArgs();
  7829. for (int i = 0; i < nowWearing.WearableData.Length; i++)
  7830. {
  7831. //m_log.DebugFormat("[XXX]: Wearable type {0} item {1}", nowWearing.WearableData[i].WearableType, nowWearing.WearableData[i].ItemID);
  7832. AvatarWearingArgs.Wearable wearable =
  7833. new AvatarWearingArgs.Wearable(nowWearing.WearableData[i].ItemID,
  7834. nowWearing.WearableData[i].WearableType);
  7835. wearingArgs.NowWearing.Add(wearable);
  7836. }
  7837. OnAvatarNowWearing?.Invoke(this, wearingArgs);
  7838. }
  7839. private void HandlerRezSingleAttachmentFromInv(Packet Pack)
  7840. {
  7841. RezSingleAttachmentFromInvPacket rez = (RezSingleAttachmentFromInvPacket)Pack;
  7842. if (rez.AgentData.SessionID.NotEqual(m_sessionId) || rez.AgentData.AgentID.NotEqual(m_agentId))
  7843. return;
  7844. OnRezSingleAttachmentFromInv?.Invoke(this, rez.ObjectData.ItemID,
  7845. rez.ObjectData.AttachmentPt);
  7846. }
  7847. private void HandleRezMultipleAttachmentsFromInv(Packet Pack)
  7848. {
  7849. if(OnRezMultipleAttachmentsFromInv == null)
  7850. return;
  7851. RezMultipleAttachmentsFromInvPacket rez = (RezMultipleAttachmentsFromInvPacket)Pack;
  7852. RezMultipleAttachmentsFromInvPacket.AgentDataBlock rezAgentData = rez.AgentData;
  7853. if (rezAgentData.SessionID.NotEqual(m_sessionId) || rezAgentData.AgentID.NotEqual(m_agentId))
  7854. return;
  7855. List<KeyValuePair<UUID, uint>> rezlist = new List<KeyValuePair<UUID, uint>>();
  7856. foreach (RezMultipleAttachmentsFromInvPacket.ObjectDataBlock obj in rez.ObjectData)
  7857. rezlist.Add(new KeyValuePair<UUID, uint>(obj.ItemID, obj.AttachmentPt));
  7858. OnRezMultipleAttachmentsFromInv?.Invoke(this, rezlist);
  7859. }
  7860. private void HandleDetachAttachmentIntoInv(Packet Pack)
  7861. {
  7862. if (OnDetachAttachmentIntoInv == null)
  7863. return;
  7864. DetachAttachmentIntoInvPacket detachtoInv = (DetachAttachmentIntoInvPacket)Pack;
  7865. if(detachtoInv.ObjectData.AgentID.NotEqual(m_agentId))
  7866. return;
  7867. OnDetachAttachmentIntoInv?.Invoke(detachtoInv.ObjectData.ItemID, this);
  7868. }
  7869. private void HandleObjectAttach(Packet Pack)
  7870. {
  7871. if (OnObjectAttach == null)
  7872. return;
  7873. ObjectAttachPacket att = (ObjectAttachPacket)Pack;
  7874. if (att.AgentData.SessionID.NotEqual(m_sessionId) || att.AgentData.AgentID.NotEqual(m_agentId))
  7875. return;
  7876. if (att.ObjectData.Length > 0)
  7877. OnObjectAttach?.Invoke(this, att.ObjectData[0].ObjectLocalID, att.AgentData.AttachmentPoint, false);
  7878. }
  7879. private void HandleObjectDetach(Packet Pack)
  7880. {
  7881. if(OnObjectDetach == null)
  7882. return;
  7883. ObjectDetachPacket dett = (ObjectDetachPacket)Pack;
  7884. if (dett.AgentData.SessionID.NotEqual(m_sessionId) || dett.AgentData.AgentID.NotEqual(m_agentId))
  7885. return;
  7886. for (int j = 0; j < dett.ObjectData.Length; j++)
  7887. {
  7888. uint obj = dett.ObjectData[j].ObjectLocalID;
  7889. OnObjectDetach?.Invoke(obj, this);
  7890. }
  7891. }
  7892. private void HandleObjectDrop(Packet Pack)
  7893. {
  7894. if(OnObjectDrop == null)
  7895. return;
  7896. ObjectDropPacket dropp = (ObjectDropPacket)Pack;
  7897. if (dropp.AgentData.SessionID.NotEqual(m_sessionId) || dropp.AgentData.AgentID.NotEqual(m_agentId))
  7898. return;
  7899. for (int j = 0; j < dropp.ObjectData.Length; j++)
  7900. {
  7901. uint obj = dropp.ObjectData[j].ObjectLocalID;
  7902. OnObjectDrop?.Invoke(obj, this);
  7903. }
  7904. }
  7905. private void HandleSetAlwaysRun(Packet Pack)
  7906. {
  7907. SetAlwaysRunPacket run = (SetAlwaysRunPacket)Pack;
  7908. if (run.AgentData.SessionID.NotEqual(m_sessionId) || run.AgentData.AgentID.NotEqual(m_agentId))
  7909. return;
  7910. OnSetAlwaysRun?.Invoke(this, run.AgentData.AlwaysRun);
  7911. }
  7912. private void HandleCompleteAgentMovement(Packet Pack)
  7913. {
  7914. //m_log.DebugFormat("[LLClientView] HandleCompleteAgentMovement");
  7915. CompleteAgentMovementPacket cmp = (CompleteAgentMovementPacket)Pack;
  7916. if(cmp.AgentData.AgentID.NotEqual(m_agentId) || cmp.AgentData.SessionID.NotEqual(m_sessionId) || cmp.AgentData.CircuitCode != m_circuitCode)
  7917. return;
  7918. OnCompleteMovementToRegion?.Invoke(this, true);
  7919. }
  7920. private void HandleAgentAnimation(Packet Pack)
  7921. {
  7922. if(OnChangeAnim == null)
  7923. return;
  7924. AgentAnimationPacket AgentAni = (AgentAnimationPacket)Pack;
  7925. if (AgentAni.AgentData.SessionID.NotEqual(m_sessionId) || AgentAni.AgentData.AgentID.NotEqual(m_agentId))
  7926. return;
  7927. for (int i = 0; i < AgentAni.AnimationList.Length; i++)
  7928. OnChangeAnim?.Invoke(AgentAni.AnimationList[i].AnimID, AgentAni.AnimationList[i].StartAnim, false);
  7929. OnChangeAnim?.Invoke(UUID.Zero, false, true);
  7930. }
  7931. private void HandleAgentRequestSit(Packet Pack)
  7932. {
  7933. if (OnAgentRequestSit == null)
  7934. return;
  7935. AgentRequestSitPacket agentRequestSit = (AgentRequestSitPacket)Pack;
  7936. if (agentRequestSit.AgentData.SessionID.NotEqual(m_sessionId) || agentRequestSit.AgentData.AgentID.NotEqual(m_agentId))
  7937. return;
  7938. if (SceneAgent.IsChildAgent)
  7939. {
  7940. SendCantSitBecauseChildAgentResponse();
  7941. return;
  7942. }
  7943. OnAgentRequestSit?.Invoke(this, agentRequestSit.AgentData.AgentID,
  7944. agentRequestSit.TargetObject.TargetID, agentRequestSit.TargetObject.Offset);
  7945. }
  7946. private void HandleAgentSit(Packet Pack)
  7947. {
  7948. if (OnAgentSit == null)
  7949. return;
  7950. AgentSitPacket agentSit = (AgentSitPacket)Pack;
  7951. if (agentSit.AgentData.SessionID.NotEqual(m_sessionId) || agentSit.AgentData.AgentID.NotEqual(m_agentId))
  7952. return;
  7953. if (SceneAgent.IsChildAgent)
  7954. {
  7955. SendCantSitBecauseChildAgentResponse();
  7956. return;
  7957. }
  7958. OnAgentSit?.Invoke(this, agentSit.AgentData.AgentID);
  7959. }
  7960. /// <summary>
  7961. /// Used when a child agent gets a sit response which should not be fulfilled.
  7962. /// </summary>
  7963. private void SendCantSitBecauseChildAgentResponse()
  7964. {
  7965. SendAlertMessage("Try moving closer. Can't sit on object because it is not in the same region as you.");
  7966. }
  7967. private void HandleSoundTrigger(Packet Pack)
  7968. {
  7969. SoundTriggerPacket soundTriggerPacket = (SoundTriggerPacket)Pack;
  7970. // UUIDS are sent as zeroes by the client, substitute agent's id
  7971. OnSoundTrigger?.Invoke(soundTriggerPacket.SoundData.SoundID, m_agentId,
  7972. m_agentId, m_agentId,
  7973. soundTriggerPacket.SoundData.Gain, soundTriggerPacket.SoundData.Position,
  7974. soundTriggerPacket.SoundData.Handle);
  7975. }
  7976. private void HandleAvatarPickerRequest(Packet Pack)
  7977. {
  7978. AvatarPickerRequestPacket avRequestQuery = (AvatarPickerRequestPacket)Pack;
  7979. if (avRequestQuery.AgentData.SessionID.NotEqual(m_sessionId) || avRequestQuery.AgentData.AgentID.NotEqual(m_agentId))
  7980. return;
  7981. AvatarPickerRequestPacket.AgentDataBlock Requestdata = avRequestQuery.AgentData;
  7982. AvatarPickerRequestPacket.DataBlock querydata = avRequestQuery.Data;
  7983. //m_log.Debug("Agent Sends:" + Utils.BytesToString(querydata.Name));
  7984. OnAvatarPickerRequest?.Invoke(this, Requestdata.AgentID, Requestdata.QueryID,
  7985. Utils.BytesToString(querydata.Name));
  7986. }
  7987. private void HandleAgentDataUpdateRequest(Packet Pack)
  7988. {
  7989. AgentDataUpdateRequestPacket avRequestDataUpdatePacket = (AgentDataUpdateRequestPacket)Pack;
  7990. if (avRequestDataUpdatePacket.AgentData.SessionID.NotEqual(m_sessionId) || avRequestDataUpdatePacket.AgentData.AgentID.NotEqual(m_agentId))
  7991. return;
  7992. OnAgentDataUpdateRequest?.Invoke(this, avRequestDataUpdatePacket.AgentData.AgentID, avRequestDataUpdatePacket.AgentData.SessionID);
  7993. }
  7994. private void HandleUserInfoRequest(Packet Pack)
  7995. {
  7996. if (OnUserInfoRequest != null)
  7997. {
  7998. OnUserInfoRequest(this);
  7999. }
  8000. else
  8001. {
  8002. SendUserInfoReply(false, true, "");
  8003. }
  8004. }
  8005. private void HandleUpdateUserInfo(Packet Pack)
  8006. {
  8007. if(OnUpdateUserInfo == null)
  8008. return;
  8009. UpdateUserInfoPacket updateUserInfo = (UpdateUserInfoPacket)Pack;
  8010. if (updateUserInfo.AgentData.SessionID.NotEqual(m_sessionId) || updateUserInfo.AgentData.AgentID.NotEqual(m_agentId))
  8011. return;
  8012. bool visible = true;
  8013. string DirectoryVisibility = Utils.BytesToString(updateUserInfo.UserData.DirectoryVisibility);
  8014. if (DirectoryVisibility == "hidden")
  8015. visible = false;
  8016. OnUpdateUserInfo?.Invoke( updateUserInfo.UserData.IMViaEMail, visible, this);
  8017. }
  8018. private void HandleSetStartLocationRequest(Packet Pack)
  8019. {
  8020. SetStartLocationRequestPacket avSetStartLocationRequestPacket = (SetStartLocationRequestPacket)Pack;
  8021. if (avSetStartLocationRequestPacket.AgentData.SessionID.NotEqual(m_sessionId) ||
  8022. avSetStartLocationRequestPacket.AgentData.AgentID.NotEqual(m_agentId))
  8023. return;
  8024. float packX = avSetStartLocationRequestPacket.StartLocationData.LocationPos.X;
  8025. float packY = avSetStartLocationRequestPacket.StartLocationData.LocationPos.Y;
  8026. // Linden Client limitation..
  8027. if (packX == 255.5f || packY == 255.5f)
  8028. {
  8029. ScenePresence avatar = null;
  8030. if (((Scene)m_scene).TryGetScenePresence(m_agentId, out avatar))
  8031. {
  8032. if (packX == 255.5f)
  8033. {
  8034. avSetStartLocationRequestPacket.StartLocationData.LocationPos.X = avatar.AbsolutePosition.X;
  8035. }
  8036. if (packY == 255.5f)
  8037. {
  8038. avSetStartLocationRequestPacket.StartLocationData.LocationPos.Y = avatar.AbsolutePosition.Y;
  8039. }
  8040. }
  8041. }
  8042. OnSetStartLocationRequest?.Invoke(this, 0, avSetStartLocationRequestPacket.StartLocationData.LocationPos,
  8043. avSetStartLocationRequestPacket.StartLocationData.LocationLookAt,
  8044. avSetStartLocationRequestPacket.StartLocationData.LocationID);
  8045. }
  8046. private void HandleAgentThrottle(Packet Pack)
  8047. {
  8048. AgentThrottlePacket atpack = (AgentThrottlePacket)Pack;
  8049. if (atpack.AgentData.SessionID.NotEqual(m_sessionId) || atpack.AgentData.AgentID.NotEqual(m_agentId))
  8050. return;
  8051. m_udpClient.SetThrottles(atpack.Throttle.Throttles);
  8052. OnUpdateThrottles?.Invoke();
  8053. }
  8054. private void HandleAgentPause(Packet Pack)
  8055. {
  8056. m_udpClient.IsPaused = true;
  8057. }
  8058. private void HandleAgentResume(Packet Pack)
  8059. {
  8060. m_udpClient.IsPaused = false;
  8061. m_udpServer.SendPing(m_udpClient);
  8062. }
  8063. private void HandleForceScriptControlRelease(Packet Pack)
  8064. {
  8065. OnForceReleaseControls?.Invoke(this, m_agentId);
  8066. }
  8067. #endregion Scene/Avatar
  8068. #region Objects/m_sceneObjects
  8069. private void HandleObjectLink(Packet Pack)
  8070. {
  8071. ObjectLinkPacket link = (ObjectLinkPacket)Pack;
  8072. if (link.AgentData.SessionID.NotEqual(m_sessionId) || link.AgentData.AgentID.NotEqual(m_agentId))
  8073. return;
  8074. uint parentprimid = 0;
  8075. List<uint> childrenprims = new List<uint>();
  8076. if (link.ObjectData.Length > 1)
  8077. {
  8078. parentprimid = link.ObjectData[0].ObjectLocalID;
  8079. for (int i = 1; i < link.ObjectData.Length; i++)
  8080. {
  8081. childrenprims.Add(link.ObjectData[i].ObjectLocalID);
  8082. }
  8083. }
  8084. OnLinkObjects?.Invoke(this, parentprimid, childrenprims);
  8085. }
  8086. private void HandleObjectDelink(Packet Pack)
  8087. {
  8088. ObjectDelinkPacket delink = (ObjectDelinkPacket)Pack;
  8089. if (delink.AgentData.SessionID.NotEqual(m_sessionId) || delink.AgentData.AgentID.NotEqual(m_agentId))
  8090. return;
  8091. // It appears the prim at index 0 is not always the root prim (for
  8092. // instance, when one prim of a link set has been edited independently
  8093. // of the others). Therefore, we'll pass all the ids onto the delink
  8094. // method for it to decide which is the root.
  8095. List<uint> prims = new List<uint>();
  8096. for (int i = 0; i < delink.ObjectData.Length; i++)
  8097. {
  8098. prims.Add(delink.ObjectData[i].ObjectLocalID);
  8099. }
  8100. OnDelinkObjects?.Invoke(prims, this);
  8101. }
  8102. private void HandleObjectAdd(Packet Pack)
  8103. {
  8104. ObjectAddPacket addPacket = (ObjectAddPacket)Pack;
  8105. if (addPacket.AgentData.SessionID.NotEqual(m_sessionId) || addPacket.AgentData.AgentID.NotEqual(m_agentId))
  8106. return;
  8107. ObjectAddPacket.ObjectDataBlock datablk = addPacket.ObjectData;
  8108. PrimitiveBaseShape shape = GetShapeFromAddPacket(addPacket);
  8109. OnAddPrim?.Invoke(m_agentId, addPacket.AgentData.GroupID, datablk.RayEnd,
  8110. datablk.Rotation, shape,
  8111. datablk.BypassRaycast, datablk.RayStart, datablk.RayTargetID, datablk.RayEndIsIntersection,
  8112. datablk.AddFlags);
  8113. }
  8114. private void HandleObjectShape(Packet Pack)
  8115. {
  8116. if(OnUpdatePrimShape == null)
  8117. return;
  8118. ObjectShapePacket shapePacket = (ObjectShapePacket)Pack;
  8119. if (shapePacket.AgentData.SessionID.NotEqual(m_sessionId) || shapePacket.AgentData.AgentID.NotEqual(m_agentId))
  8120. return;
  8121. for (int i = 0; i < shapePacket.ObjectData.Length; i++)
  8122. {
  8123. UpdateShapeArgs shapeData = new UpdateShapeArgs();
  8124. uint id = shapePacket.ObjectData[i].ObjectLocalID;
  8125. shapeData.ObjectLocalID = id;
  8126. shapeData.PathBegin = shapePacket.ObjectData[i].PathBegin;
  8127. shapeData.PathCurve = shapePacket.ObjectData[i].PathCurve;
  8128. shapeData.PathEnd = shapePacket.ObjectData[i].PathEnd;
  8129. shapeData.PathRadiusOffset = shapePacket.ObjectData[i].PathRadiusOffset;
  8130. shapeData.PathRevolutions = shapePacket.ObjectData[i].PathRevolutions;
  8131. shapeData.PathScaleX = shapePacket.ObjectData[i].PathScaleX;
  8132. shapeData.PathScaleY = shapePacket.ObjectData[i].PathScaleY;
  8133. shapeData.PathShearX = shapePacket.ObjectData[i].PathShearX;
  8134. shapeData.PathShearY = shapePacket.ObjectData[i].PathShearY;
  8135. shapeData.PathSkew = shapePacket.ObjectData[i].PathSkew;
  8136. shapeData.PathTaperX = shapePacket.ObjectData[i].PathTaperX;
  8137. shapeData.PathTaperY = shapePacket.ObjectData[i].PathTaperY;
  8138. shapeData.PathTwist = shapePacket.ObjectData[i].PathTwist;
  8139. shapeData.PathTwistBegin = shapePacket.ObjectData[i].PathTwistBegin;
  8140. shapeData.ProfileBegin = shapePacket.ObjectData[i].ProfileBegin;
  8141. shapeData.ProfileCurve = shapePacket.ObjectData[i].ProfileCurve;
  8142. shapeData.ProfileEnd = shapePacket.ObjectData[i].ProfileEnd;
  8143. shapeData.ProfileHollow = shapePacket.ObjectData[i].ProfileHollow;
  8144. OnUpdatePrimShape?.Invoke(m_agentId, id, shapeData);
  8145. }
  8146. }
  8147. private void HandleObjectExtraParams(Packet Pack)
  8148. {
  8149. ObjectExtraParamsPacket extraPar = (ObjectExtraParamsPacket)Pack;
  8150. if (extraPar.AgentData.SessionID.NotEqual(m_sessionId) || extraPar.AgentData.AgentID.NotEqual(m_agentId))
  8151. return;
  8152. ObjectExtraParams handlerUpdateExtraParams = OnUpdateExtraParams;
  8153. if (handlerUpdateExtraParams != null)
  8154. {
  8155. for (int i = 0; i < extraPar.ObjectData.Length; i++)
  8156. {
  8157. OnUpdateExtraParams?.Invoke(m_agentId, extraPar.ObjectData[i].ObjectLocalID,
  8158. extraPar.ObjectData[i].ParamType,
  8159. extraPar.ObjectData[i].ParamInUse, extraPar.ObjectData[i].ParamData);
  8160. }
  8161. }
  8162. }
  8163. private void HandleObjectDuplicate(Packet Pack)
  8164. {
  8165. if(OnObjectDuplicate == null)
  8166. return;
  8167. ObjectDuplicatePacket dupe = (ObjectDuplicatePacket)Pack;
  8168. if (dupe.AgentData.SessionID.NotEqual(m_sessionId) || dupe.AgentData.AgentID.NotEqual(m_agentId))
  8169. return;
  8170. // ObjectDuplicatePacket.AgentDataBlock AgentandGroupData = dupe.AgentData;
  8171. for (int i = 0; i < dupe.ObjectData.Length; i++)
  8172. {
  8173. UUID rezGroupID = dupe.AgentData.GroupID;
  8174. if(!IsGroupMember(rezGroupID))
  8175. rezGroupID = UUID.Zero;
  8176. OnObjectDuplicate?.Invoke(dupe.ObjectData[i].ObjectLocalID, dupe.SharedData.Offset,
  8177. dupe.SharedData.DuplicateFlags, m_agentId,
  8178. rezGroupID);
  8179. }
  8180. }
  8181. private void HandleRequestMultipleObjects(Packet Pack)
  8182. {
  8183. if (OnObjectRequest == null)
  8184. return;
  8185. RequestMultipleObjectsPacket incomingRequest = (RequestMultipleObjectsPacket)Pack;
  8186. if (incomingRequest.AgentData.SessionID.NotEqual(m_sessionId) || incomingRequest.AgentData.AgentID.NotEqual(m_agentId))
  8187. return;
  8188. for (int i = 0; i < incomingRequest.ObjectData.Length; i++)
  8189. OnObjectRequest?.Invoke(incomingRequest.ObjectData[i].ID, this);
  8190. }
  8191. private void HandleObjectSelect(Packet Pack)
  8192. {
  8193. if(OnObjectSelect == null)
  8194. return;
  8195. ObjectSelectPacket incomingselect = (ObjectSelectPacket)Pack;
  8196. if (incomingselect.AgentData.SessionID.NotEqual(m_sessionId) || incomingselect.AgentData.AgentID.NotEqual(m_agentId))
  8197. return;
  8198. List<uint> thisSelection = new List<uint>();
  8199. for (int i = 0; i < incomingselect.ObjectData.Length; i++)
  8200. thisSelection.Add(incomingselect.ObjectData[i].ObjectLocalID);
  8201. OnObjectSelect?.Invoke(thisSelection, this);
  8202. }
  8203. private void HandleObjectDeselect(Packet Pack)
  8204. {
  8205. if(OnObjectDeselect == null)
  8206. return;
  8207. ObjectDeselectPacket incomingdeselect = (ObjectDeselectPacket)Pack;
  8208. if (incomingdeselect.AgentData.SessionID.NotEqual(m_sessionId) || incomingdeselect.AgentData.AgentID.NotEqual(m_agentId))
  8209. return;
  8210. for (int i = 0; i < incomingdeselect.ObjectData.Length; i++)
  8211. {
  8212. OnObjectDeselect?.Invoke(incomingdeselect.ObjectData[i].ObjectLocalID, this);
  8213. }
  8214. }
  8215. private void HandleObjectPosition(Packet Pack)
  8216. {
  8217. if (OnUpdatePrimGroupPosition == null)
  8218. return;
  8219. // DEPRECATED: but till libsecondlife removes it, people will use it
  8220. ObjectPositionPacket position = (ObjectPositionPacket)Pack;
  8221. if (position.AgentData.SessionID.NotEqual(m_sessionId) || position.AgentData.AgentID.NotEqual(m_agentId))
  8222. return;
  8223. for (int i = 0; i < position.ObjectData.Length; i++)
  8224. OnUpdatePrimGroupPosition?.Invoke(position.ObjectData[i].ObjectLocalID, position.ObjectData[i].Position, this);
  8225. }
  8226. private void HandleObjectScale(Packet Pack)
  8227. {
  8228. if (OnUpdatePrimGroupScale == null)
  8229. return;
  8230. // DEPRECATED: but till libsecondlife removes it, people will use it
  8231. ObjectScalePacket scale = (ObjectScalePacket)Pack;
  8232. if (scale.AgentData.SessionID.NotEqual(m_sessionId) || scale.AgentData.AgentID.NotEqual(m_agentId))
  8233. return;
  8234. for (int i = 0; i < scale.ObjectData.Length; i++)
  8235. OnUpdatePrimGroupScale?.Invoke(scale.ObjectData[i].ObjectLocalID, scale.ObjectData[i].Scale, this);
  8236. }
  8237. private void HandleObjectRotation(Packet Pack)
  8238. {
  8239. if (OnUpdatePrimGroupRotation == null)
  8240. return;
  8241. // DEPRECATED: but till libsecondlife removes it, people will use it
  8242. ObjectRotationPacket rotation = (ObjectRotationPacket)Pack;
  8243. if (rotation.AgentData.SessionID.NotEqual(m_sessionId) || rotation.AgentData.AgentID.NotEqual(m_agentId))
  8244. return;
  8245. for (int i = 0; i < rotation.ObjectData.Length; i++)
  8246. OnUpdatePrimGroupRotation?.Invoke(rotation.ObjectData[i].ObjectLocalID, rotation.ObjectData[i].Rotation, this);
  8247. }
  8248. private void HandleObjectFlagUpdate(Packet Pack)
  8249. {
  8250. if(OnUpdatePrimFlags == null)
  8251. return;
  8252. ObjectFlagUpdatePacket flags = (ObjectFlagUpdatePacket)Pack;
  8253. if (flags.AgentData.SessionID.NotEqual(m_sessionId) || flags.AgentData.AgentID.NotEqual(m_agentId))
  8254. return;
  8255. // byte[] data = Pack.ToBytes();
  8256. // 46,47,48 are special positions within the packet
  8257. // This may change so perhaps we need a better way
  8258. // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?)
  8259. /*
  8260. bool UsePhysics = (data[46] != 0) ? true : false;
  8261. bool IsTemporary = (data[47] != 0) ? true : false;
  8262. bool IsPhantom = (data[48] != 0) ? true : false;
  8263. handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, this);
  8264. */
  8265. bool UsePhysics = flags.AgentData.UsePhysics;
  8266. bool IsPhantom = flags.AgentData.IsPhantom;
  8267. bool IsTemporary = flags.AgentData.IsTemporary;
  8268. ObjectFlagUpdatePacket.ExtraPhysicsBlock[] blocks = flags.ExtraPhysics;
  8269. ExtraPhysicsData physdata = new ExtraPhysicsData();
  8270. if (blocks == null || blocks.Length == 0)
  8271. {
  8272. physdata.PhysShapeType = PhysShapeType.invalid;
  8273. }
  8274. else
  8275. {
  8276. ObjectFlagUpdatePacket.ExtraPhysicsBlock phsblock = blocks[0];
  8277. physdata.PhysShapeType = (PhysShapeType)phsblock.PhysicsShapeType;
  8278. physdata.Bounce = phsblock.Restitution;
  8279. physdata.Density = phsblock.Density;
  8280. physdata.Friction = phsblock.Friction;
  8281. physdata.GravitationModifier = phsblock.GravityMultiplier;
  8282. }
  8283. OnUpdatePrimFlags?.Invoke(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, physdata, this);
  8284. }
  8285. Dictionary<uint, uint> objImageSeqs = null;
  8286. double lastobjImageSeqsMS = 0.0;
  8287. private void HandleObjectImage(Packet Pack)
  8288. {
  8289. if (OnUpdatePrimTexture == null)
  8290. return;
  8291. ObjectImagePacket imagePack = (ObjectImagePacket)Pack;
  8292. if (imagePack.AgentData.SessionID.NotEqual(m_sessionId) || imagePack.AgentData.AgentID.NotEqual(m_agentId))
  8293. return;
  8294. double now = Util.GetTimeStampMS();
  8295. if(objImageSeqs == null || ( now - lastobjImageSeqsMS > 30000.0))
  8296. {
  8297. objImageSeqs = null; // yeah i know superstition...
  8298. objImageSeqs = new Dictionary<uint, uint>(16);
  8299. }
  8300. lastobjImageSeqsMS = now;
  8301. uint seq = Pack.Header.Sequence;
  8302. uint id;
  8303. uint lastseq;
  8304. ObjectImagePacket.ObjectDataBlock o;
  8305. for (int i = 0; i < imagePack.ObjectData.Length; i++)
  8306. {
  8307. o = imagePack.ObjectData[i];
  8308. id = o.ObjectLocalID;
  8309. if(objImageSeqs.TryGetValue(id, out lastseq))
  8310. {
  8311. if(seq <= lastseq)
  8312. continue;
  8313. }
  8314. objImageSeqs[id] = seq;
  8315. OnUpdatePrimTexture?.Invoke(id, o.TextureEntry, this);
  8316. }
  8317. }
  8318. private void HandleObjectGrab(Packet Pack)
  8319. {
  8320. if(OnGrabObject == null)
  8321. return;
  8322. ObjectGrabPacket grab = (ObjectGrabPacket)Pack;
  8323. if (grab.AgentData.SessionID.NotEqual(m_sessionId) || grab.AgentData.AgentID.NotEqual(m_agentId))
  8324. return;
  8325. List<SurfaceTouchEventArgs> touchArgs = new List<SurfaceTouchEventArgs>();
  8326. if ((grab.SurfaceInfo != null) && (grab.SurfaceInfo.Length > 0))
  8327. {
  8328. foreach (ObjectGrabPacket.SurfaceInfoBlock surfaceInfo in grab.SurfaceInfo)
  8329. {
  8330. SurfaceTouchEventArgs arg = new SurfaceTouchEventArgs();
  8331. arg.Binormal = surfaceInfo.Binormal;
  8332. arg.FaceIndex = surfaceInfo.FaceIndex;
  8333. arg.Normal = surfaceInfo.Normal;
  8334. arg.Position = surfaceInfo.Position;
  8335. arg.STCoord = surfaceInfo.STCoord;
  8336. arg.UVCoord = surfaceInfo.UVCoord;
  8337. touchArgs.Add(arg);
  8338. }
  8339. }
  8340. OnGrabObject?.Invoke(grab.ObjectData.LocalID, grab.ObjectData.GrabOffset, this, touchArgs);
  8341. }
  8342. private void HandleObjectGrabUpdate(Packet Pack)
  8343. {
  8344. if (OnGrabUpdate == null)
  8345. return;
  8346. ObjectGrabUpdatePacket grabUpdate = (ObjectGrabUpdatePacket)Pack;
  8347. if (grabUpdate.AgentData.SessionID.NotEqual(m_sessionId) || grabUpdate.AgentData.AgentID.NotEqual(m_agentId))
  8348. return;
  8349. List<SurfaceTouchEventArgs> touchArgs = new List<SurfaceTouchEventArgs>();
  8350. if ((grabUpdate.SurfaceInfo != null) && (grabUpdate.SurfaceInfo.Length > 0))
  8351. {
  8352. foreach (ObjectGrabUpdatePacket.SurfaceInfoBlock surfaceInfo in grabUpdate.SurfaceInfo)
  8353. {
  8354. SurfaceTouchEventArgs arg = new SurfaceTouchEventArgs();
  8355. arg.Binormal = surfaceInfo.Binormal;
  8356. arg.FaceIndex = surfaceInfo.FaceIndex;
  8357. arg.Normal = surfaceInfo.Normal;
  8358. arg.Position = surfaceInfo.Position;
  8359. arg.STCoord = surfaceInfo.STCoord;
  8360. arg.UVCoord = surfaceInfo.UVCoord;
  8361. touchArgs.Add(arg);
  8362. }
  8363. }
  8364. OnGrabUpdate?.Invoke(grabUpdate.ObjectData.ObjectID, grabUpdate.ObjectData.GrabOffsetInitial,
  8365. grabUpdate.ObjectData.GrabPosition, this, touchArgs);
  8366. }
  8367. private void HandleObjectDeGrab(Packet Pack)
  8368. {
  8369. if (OnDeGrabObject == null)
  8370. return;
  8371. ObjectDeGrabPacket deGrab = (ObjectDeGrabPacket)Pack;
  8372. if (deGrab.AgentData.SessionID.NotEqual(m_sessionId) || deGrab.AgentData.AgentID.NotEqual(m_agentId))
  8373. return;
  8374. List<SurfaceTouchEventArgs> touchArgs = new List<SurfaceTouchEventArgs>();
  8375. if ((deGrab.SurfaceInfo != null) && (deGrab.SurfaceInfo.Length > 0))
  8376. {
  8377. foreach (ObjectDeGrabPacket.SurfaceInfoBlock surfaceInfo in deGrab.SurfaceInfo)
  8378. {
  8379. SurfaceTouchEventArgs arg = new SurfaceTouchEventArgs();
  8380. arg.Binormal = surfaceInfo.Binormal;
  8381. arg.FaceIndex = surfaceInfo.FaceIndex;
  8382. arg.Normal = surfaceInfo.Normal;
  8383. arg.Position = surfaceInfo.Position;
  8384. arg.STCoord = surfaceInfo.STCoord;
  8385. arg.UVCoord = surfaceInfo.UVCoord;
  8386. touchArgs.Add(arg);
  8387. }
  8388. }
  8389. OnDeGrabObject?.Invoke(deGrab.ObjectData.LocalID, this, touchArgs);
  8390. }
  8391. private void HandleObjectSpinStart(Packet Pack)
  8392. {
  8393. //m_log.Warn("[CLIENT]: unhandled ObjectSpinStart packet");
  8394. ObjectSpinStartPacket spinStart = (ObjectSpinStartPacket)Pack;
  8395. if (spinStart.AgentData.SessionID.NotEqual(m_sessionId) || spinStart.AgentData.AgentID.NotEqual(m_agentId))
  8396. return;
  8397. OnSpinStart?.Invoke(spinStart.ObjectData.ObjectID, this);
  8398. }
  8399. private void HandleObjectSpinUpdate(Packet Pack)
  8400. {
  8401. //m_log.Warn("[CLIENT]: unhandled ObjectSpinUpdate packet");
  8402. ObjectSpinUpdatePacket spinUpdate = (ObjectSpinUpdatePacket)Pack;
  8403. if (spinUpdate.AgentData.SessionID.NotEqual(m_sessionId) || spinUpdate.AgentData.AgentID.NotEqual(m_agentId))
  8404. return;
  8405. Vector3 axis;
  8406. float angle;
  8407. spinUpdate.ObjectData.Rotation.GetAxisAngle(out axis, out angle);
  8408. //m_log.Warn("[CLIENT]: ObjectSpinUpdate packet rot axis:" + axis + " angle:" + angle);
  8409. OnSpinUpdate?.Invoke(spinUpdate.ObjectData.ObjectID, spinUpdate.ObjectData.Rotation, this);
  8410. }
  8411. private void HandleObjectSpinStop(Packet Pack)
  8412. {
  8413. //m_log.Warn("[CLIENT]: unhandled ObjectSpinStop packet");
  8414. ObjectSpinStopPacket spinStop = (ObjectSpinStopPacket)Pack;
  8415. if (spinStop.AgentData.SessionID.NotEqual(m_sessionId) || spinStop.AgentData.AgentID.NotEqual(m_agentId))
  8416. return;
  8417. OnSpinStop?.Invoke(spinStop.ObjectData.ObjectID, this);
  8418. }
  8419. private void HandleObjectDescription(Packet Pack)
  8420. {
  8421. if(OnObjectDescription == null)
  8422. return;
  8423. ObjectDescriptionPacket objDes = (ObjectDescriptionPacket)Pack;
  8424. if (objDes.AgentData.SessionID.NotEqual(m_sessionId) || objDes.AgentData.AgentID.NotEqual(m_agentId))
  8425. return;
  8426. for (int i = 0; i < objDes.ObjectData.Length; i++)
  8427. OnObjectDescription?.Invoke(this, objDes.ObjectData[i].LocalID,
  8428. Util.FieldToString(objDes.ObjectData[i].Description));
  8429. }
  8430. private void HandleObjectName(Packet Pack)
  8431. {
  8432. if(OnObjectName == null)
  8433. return;
  8434. ObjectNamePacket objName = (ObjectNamePacket)Pack;
  8435. if (objName.AgentData.SessionID.NotEqual(m_sessionId) || objName.AgentData.AgentID.NotEqual(m_agentId))
  8436. return;
  8437. for (int i = 0; i < objName.ObjectData.Length; i++)
  8438. OnObjectName?.Invoke(this, objName.ObjectData[i].LocalID,
  8439. Util.FieldToString(objName.ObjectData[i].Name));
  8440. }
  8441. private void HandleObjectPermissions(Packet Pack)
  8442. {
  8443. if (OnObjectPermissions == null)
  8444. return;
  8445. ObjectPermissionsPacket newobjPerms = (ObjectPermissionsPacket)Pack;
  8446. UUID SessionID = newobjPerms.AgentData.SessionID;
  8447. if (SessionID.NotEqual(m_sessionId))
  8448. return;
  8449. UUID AgentID = newobjPerms.AgentData.AgentID;
  8450. if(AgentID.NotEqual(m_agentId))
  8451. return;
  8452. for (int i = 0; i < newobjPerms.ObjectData.Length; i++)
  8453. {
  8454. ObjectPermissionsPacket.ObjectDataBlock permChanges = newobjPerms.ObjectData[i];
  8455. byte field = permChanges.Field;
  8456. uint localID = permChanges.ObjectLocalID;
  8457. uint mask = permChanges.Mask;
  8458. byte set = permChanges.Set;
  8459. OnObjectPermissions?.Invoke(this, AgentID, SessionID, field, localID, mask, set);
  8460. }
  8461. // Here's our data,
  8462. // PermField contains the field the info goes into
  8463. // PermField determines which mask we're changing
  8464. //
  8465. // chmask is the mask of the change
  8466. // setTF is whether we're adding it or taking it away
  8467. //
  8468. // objLocalID is the localID of the object.
  8469. // Unfortunately, we have to pass the event the packet because objData is an array
  8470. // That means multiple object perms may be updated in a single packet.
  8471. }
  8472. private void HandleUndo(Packet Pack)
  8473. {
  8474. if(OnUndo == null)
  8475. return;
  8476. UndoPacket undoitem = (UndoPacket)Pack;
  8477. if (undoitem.AgentData.SessionID.NotEqual(m_sessionId) || undoitem.AgentData.AgentID.NotEqual(m_agentId))
  8478. return;
  8479. for (int i = 0; i < undoitem.ObjectData.Length; i++)
  8480. OnUndo?.Invoke(this, undoitem.ObjectData[i].ObjectID);
  8481. }
  8482. private void HandleLandUndo(Packet Pack)
  8483. {
  8484. UndoLandPacket undolanditem = (UndoLandPacket)Pack;
  8485. if (undolanditem.AgentData.SessionID.NotEqual(m_sessionId) || undolanditem.AgentData.AgentID.NotEqual(m_agentId))
  8486. return;
  8487. OnLandUndo?.Invoke(this);
  8488. }
  8489. private void HandleRedo(Packet Pack)
  8490. {
  8491. if(OnRedo == null)
  8492. return;
  8493. RedoPacket redoitem = (RedoPacket)Pack;
  8494. if (redoitem.AgentData.SessionID.NotEqual(m_sessionId) || redoitem.AgentData.AgentID.NotEqual(m_agentId))
  8495. return;
  8496. for (int i = 0; i < redoitem.ObjectData.Length; i++)
  8497. OnRedo?.Invoke(this, redoitem.ObjectData[i].ObjectID);
  8498. }
  8499. private void HandleObjectDuplicateOnRay(Packet Pack)
  8500. {
  8501. if(OnObjectDuplicateOnRay == null)
  8502. return;
  8503. ObjectDuplicateOnRayPacket dupeOnRay = (ObjectDuplicateOnRayPacket)Pack;
  8504. if (dupeOnRay.AgentData.SessionID.NotEqual(m_sessionId) || dupeOnRay.AgentData.AgentID.NotEqual(m_agentId))
  8505. return;
  8506. for (int i = 0; i < dupeOnRay.ObjectData.Length; i++)
  8507. {
  8508. UUID rezGroupID = dupeOnRay.AgentData.GroupID;
  8509. if(!IsGroupMember(rezGroupID))
  8510. rezGroupID = UUID.Zero;
  8511. OnObjectDuplicateOnRay?.Invoke(dupeOnRay.ObjectData[i].ObjectLocalID,
  8512. dupeOnRay.AgentData.DuplicateFlags, m_agentId, rezGroupID,
  8513. dupeOnRay.AgentData.RayTargetID, dupeOnRay.AgentData.RayEnd,
  8514. dupeOnRay.AgentData.RayStart, dupeOnRay.AgentData.BypassRaycast,
  8515. dupeOnRay.AgentData.RayEndIsIntersection,
  8516. dupeOnRay.AgentData.CopyCenters, dupeOnRay.AgentData.CopyRotates);
  8517. }
  8518. }
  8519. private void HandleRequestObjectPropertiesFamily(Packet Pack)
  8520. {
  8521. //This powers the little tooltip that appears when you move your mouse over an object
  8522. RequestObjectPropertiesFamilyPacket packToolTip = (RequestObjectPropertiesFamilyPacket)Pack;
  8523. if (packToolTip.AgentData.SessionID.NotEqual(m_sessionId) || packToolTip.AgentData.AgentID.NotEqual(m_agentId))
  8524. return;
  8525. RequestObjectPropertiesFamilyPacket.ObjectDataBlock packObjBlock = packToolTip.ObjectData;
  8526. OnRequestObjectPropertiesFamily?.Invoke(this, m_agentId, packObjBlock.RequestFlags,
  8527. packObjBlock.ObjectID);
  8528. }
  8529. private void HandleObjectIncludeInSearch(Packet Pack)
  8530. {
  8531. if(OnObjectIncludeInSearch == null)
  8532. return;
  8533. //This lets us set objects to appear in search (stuff like DataSnapshot, etc)
  8534. ObjectIncludeInSearchPacket packInSearch = (ObjectIncludeInSearchPacket)Pack;
  8535. if (packInSearch.AgentData.SessionID.NotEqual(m_sessionId) || packInSearch.AgentData.AgentID.NotEqual(m_agentId))
  8536. return;
  8537. foreach (ObjectIncludeInSearchPacket.ObjectDataBlock objData in packInSearch.ObjectData)
  8538. {
  8539. bool inSearch = objData.IncludeInSearch;
  8540. uint localID = objData.ObjectLocalID;
  8541. OnObjectIncludeInSearch?.Invoke(this, inSearch, localID);
  8542. }
  8543. }
  8544. private void HandleScriptAnswerYes(Packet Pack)
  8545. {
  8546. ScriptAnswerYesPacket scriptAnswer = (ScriptAnswerYesPacket)Pack;
  8547. if (scriptAnswer.AgentData.SessionID.NotEqual(m_sessionId) || scriptAnswer.AgentData.AgentID.NotEqual(m_agentId))
  8548. return;
  8549. OnScriptAnswer?.Invoke(this, scriptAnswer.Data.TaskID, scriptAnswer.Data.ItemID, scriptAnswer.Data.Questions);
  8550. }
  8551. private void HandleObjectClickAction(Packet Pack)
  8552. {
  8553. if(OnObjectClickAction == null)
  8554. return;
  8555. ObjectClickActionPacket ocpacket = (ObjectClickActionPacket)Pack;
  8556. if (ocpacket.AgentData.SessionID.NotEqual(m_sessionId) || ocpacket.AgentData.AgentID.NotEqual(m_agentId))
  8557. return;
  8558. foreach (ObjectClickActionPacket.ObjectDataBlock odata in ocpacket.ObjectData)
  8559. {
  8560. byte action = odata.ClickAction;
  8561. uint localID = odata.ObjectLocalID;
  8562. OnObjectClickAction?.Invoke(this, localID, action.ToString());
  8563. }
  8564. }
  8565. private void HandleObjectMaterial(Packet Pack)
  8566. {
  8567. if(OnObjectMaterial == null)
  8568. return;
  8569. ObjectMaterialPacket ompacket = (ObjectMaterialPacket)Pack;
  8570. if (ompacket.AgentData.SessionID.NotEqual(m_sessionId) || ompacket.AgentData.AgentID.NotEqual(m_agentId))
  8571. return;
  8572. foreach (ObjectMaterialPacket.ObjectDataBlock odata in ompacket.ObjectData)
  8573. {
  8574. byte material = odata.Material;
  8575. uint localID = odata.ObjectLocalID;
  8576. OnObjectMaterial?.Invoke(this, localID, material.ToString());
  8577. }
  8578. }
  8579. #endregion Objects/m_sceneObjects
  8580. #region Inventory/Asset/Other related packets
  8581. private void HandleRequestImage(Packet Pack)
  8582. {
  8583. RequestImagePacket imageRequest = (RequestImagePacket)Pack;
  8584. if (imageRequest.AgentData.SessionID.NotEqual(m_sessionId) || imageRequest.AgentData.AgentID.NotEqual(m_agentId))
  8585. return;
  8586. //handlerTextureRequest = null;
  8587. for (int i = 0; i < imageRequest.RequestImage.Length; i++)
  8588. {
  8589. TextureRequestArgs args = new TextureRequestArgs();
  8590. RequestImagePacket.RequestImageBlock block = imageRequest.RequestImage[i];
  8591. args.RequestedAssetID = block.Image;
  8592. args.DiscardLevel = block.DiscardLevel;
  8593. args.PacketNumber = block.Packet;
  8594. args.Priority = block.DownloadPriority;
  8595. args.requestSequence = imageRequest.Header.Sequence;
  8596. // NOTE: This is not a built in part of the LLUDP protocol, but we double the
  8597. // priority of avatar textures to get avatars rezzing in faster than the
  8598. // surrounding scene
  8599. if ((ImageType)block.Type == ImageType.Baked)
  8600. args.Priority *= 2.0f;
  8601. ImageManager.EnqueueReq(args);
  8602. }
  8603. }
  8604. /// <summary>
  8605. /// This is the entry point for the UDP route by which the client can retrieve asset data. If the request
  8606. /// is successful then a TransferInfo packet will be sent back, followed by one or more TransferPackets
  8607. /// </summary>
  8608. /// <param name="sender"></param>
  8609. /// <param name="Pack"></param>
  8610. /// <returns>This parameter may be ignored since we appear to return true whatever happens</returns>
  8611. private void HandleTransferRequest(Packet Pack)
  8612. {
  8613. //m_log.Debug("ClientView.ProcessPackets.cs:ProcessInPacket() - Got transfer request");
  8614. TransferRequestPacket transfer = (TransferRequestPacket)Pack;
  8615. UUID taskID = UUID.Zero;
  8616. if (transfer.TransferInfo.SourceType == (int)SourceType.SimInventoryItem)
  8617. {
  8618. if (!(((Scene)m_scene).Permissions.BypassPermissions()))
  8619. {
  8620. // We're spawning a thread because the permissions check can block this thread
  8621. Util.FireAndForget(delegate
  8622. {
  8623. // This requests the asset if needed
  8624. HandleSimInventoryTransferRequestWithPermsCheck(this, transfer);
  8625. }, null, "LLClientView.HandleTransferRequest");
  8626. return;
  8627. }
  8628. }
  8629. else if (transfer.TransferInfo.SourceType == (int)SourceType.SimEstate)
  8630. {
  8631. //TransferRequestPacket does not include covenant uuid?
  8632. //get scene covenant uuid
  8633. taskID = m_scene.RegionInfo.RegionSettings.Covenant;
  8634. }
  8635. // This is non-blocking
  8636. MakeAssetRequest(transfer, taskID);
  8637. }
  8638. private void HandleSimInventoryTransferRequestWithPermsCheck(IClientAPI sender, TransferRequestPacket transfer)
  8639. {
  8640. UUID taskID = new UUID(transfer.TransferInfo.Params, 48);
  8641. UUID itemID = new UUID(transfer.TransferInfo.Params, 64);
  8642. UUID requestID = new UUID(transfer.TransferInfo.Params, 80);
  8643. //m_log.DebugFormat(
  8644. // "[CLIENT]: Got request for asset {0} from item {1} in prim {2} by {3}",
  8645. // requestID, itemID, taskID, Name);
  8646. //m_log.Debug("Transfer Request: " + transfer.ToString());
  8647. // Validate inventory transfers
  8648. // Has to be done here, because AssetCache can't do it
  8649. //
  8650. if (!taskID.IsZero()) // Prim
  8651. {
  8652. SceneObjectPart part = ((Scene)m_scene).GetSceneObjectPart(taskID);
  8653. if (part == null)
  8654. {
  8655. m_log.WarnFormat(
  8656. "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but prim does not exist",
  8657. Name, requestID, itemID, taskID);
  8658. return;
  8659. }
  8660. TaskInventoryItem tii = part.Inventory.GetInventoryItem(itemID);
  8661. if (tii == null)
  8662. {
  8663. m_log.WarnFormat(
  8664. "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but item does not exist",
  8665. Name, requestID, itemID, taskID);
  8666. return;
  8667. }
  8668. if (tii.Type == (int)AssetType.LSLText)
  8669. {
  8670. if (!((Scene)m_scene).Permissions.CanEditScript(itemID, taskID, m_agentId))
  8671. return;
  8672. }
  8673. else if (tii.Type == (int)AssetType.Notecard)
  8674. {
  8675. if (!((Scene)m_scene).Permissions.CanEditNotecard(itemID, taskID, m_agentId))
  8676. return;
  8677. }
  8678. else
  8679. {
  8680. // TODO: Change this code to allow items other than notecards and scripts to be successfully
  8681. // shared with group. In fact, this whole block of permissions checking should move to an IPermissionsModule
  8682. if (part.OwnerID != m_agentId)
  8683. {
  8684. m_log.WarnFormat(
  8685. "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but the prim is owned by {4}",
  8686. Name, requestID, itemID, taskID, part.OwnerID);
  8687. return;
  8688. }
  8689. if ((part.OwnerMask & (uint)PermissionMask.Modify) == 0)
  8690. {
  8691. m_log.WarnFormat(
  8692. "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but modify permissions are not set",
  8693. Name, requestID, itemID, taskID);
  8694. return;
  8695. }
  8696. if (tii.OwnerID != m_agentId)
  8697. {
  8698. m_log.WarnFormat(
  8699. "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but the item is owned by {4}",
  8700. Name, requestID, itemID, taskID, tii.OwnerID);
  8701. return;
  8702. }
  8703. if ((
  8704. tii.CurrentPermissions & ((uint)PermissionMask.Modify | (uint)PermissionMask.Copy | (uint)PermissionMask.Transfer))
  8705. != ((uint)PermissionMask.Modify | (uint)PermissionMask.Copy | (uint)PermissionMask.Transfer))
  8706. {
  8707. m_log.WarnFormat(
  8708. "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but item permissions are not modify/copy/transfer",
  8709. Name, requestID, itemID, taskID);
  8710. return;
  8711. }
  8712. if (tii.AssetID != requestID)
  8713. {
  8714. m_log.WarnFormat(
  8715. "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but this does not match item's asset {4}",
  8716. Name, requestID, itemID, taskID, tii.AssetID);
  8717. return;
  8718. }
  8719. }
  8720. }
  8721. else // Agent
  8722. {
  8723. IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>();
  8724. if (invAccess != null)
  8725. {
  8726. if (!invAccess.CanGetAgentInventoryItem(this, itemID, requestID))
  8727. return;
  8728. }
  8729. else
  8730. {
  8731. return;
  8732. }
  8733. }
  8734. // Permissions out of the way, let's request the asset
  8735. MakeAssetRequest(transfer, taskID);
  8736. }
  8737. private void HandleAssetUploadRequest(Packet Pack)
  8738. {
  8739. AssetUploadRequestPacket request = (AssetUploadRequestPacket)Pack;
  8740. // m_log.Debug("upload request " + request.ToString());
  8741. // m_log.Debug("upload request was for assetid: " + request.AssetBlock.TransactionID.Combine(this.SecureSessionId).ToString());
  8742. UUID temp = UUID.Combine(request.AssetBlock.TransactionID, SecureSessionId);
  8743. OnAssetUploadRequest?.Invoke(this, temp,
  8744. request.AssetBlock.TransactionID, request.AssetBlock.Type,
  8745. request.AssetBlock.AssetData, request.AssetBlock.StoreLocal,
  8746. request.AssetBlock.Tempfile);
  8747. }
  8748. private void HandleRequestXfer(Packet Pack)
  8749. {
  8750. RequestXferPacket xferReq = (RequestXferPacket)Pack;
  8751. OnRequestXfer?.Invoke(this, xferReq.XferID.ID, Util.FieldToString(xferReq.XferID.Filename));
  8752. }
  8753. private void HandleSendXferPacket(Packet Pack)
  8754. {
  8755. SendXferPacketPacket xferRec = (SendXferPacketPacket)Pack;
  8756. OnXferReceive?.Invoke(this, xferRec.XferID.ID, xferRec.XferID.Packet, xferRec.DataPacket.Data);
  8757. }
  8758. private void HandleConfirmXferPacket(Packet Pack)
  8759. {
  8760. ConfirmXferPacketPacket confirmXfer = (ConfirmXferPacketPacket)Pack;
  8761. OnConfirmXfer?.Invoke(this, confirmXfer.XferID.ID, confirmXfer.XferID.Packet);
  8762. }
  8763. private void HandleAbortXfer(Packet Pack)
  8764. {
  8765. AbortXferPacket abortXfer = (AbortXferPacket)Pack;
  8766. OnAbortXfer?.Invoke(this, abortXfer.XferID.ID);
  8767. }
  8768. private void HandleCreateInventoryFolder(Packet Pack)
  8769. {
  8770. CreateInventoryFolderPacket invFolder = (CreateInventoryFolderPacket)Pack;
  8771. if (invFolder.AgentData.SessionID.NotEqual(m_sessionId) || invFolder.AgentData.AgentID.NotEqual(m_agentId))
  8772. return;
  8773. OnCreateNewInventoryFolder?.Invoke(this, invFolder.FolderData.FolderID,
  8774. (ushort)invFolder.FolderData.Type,
  8775. Util.FieldToString(invFolder.FolderData.Name),
  8776. invFolder.FolderData.ParentID);
  8777. }
  8778. private void HandleUpdateInventoryFolder(Packet Pack)
  8779. {
  8780. if (OnUpdateInventoryFolder == null)
  8781. return;
  8782. UpdateInventoryFolderPacket invFolderx = (UpdateInventoryFolderPacket)Pack;
  8783. if (invFolderx.AgentData.SessionID.NotEqual(m_sessionId) || invFolderx.AgentData.AgentID.NotEqual(m_agentId))
  8784. return;
  8785. for (int i = 0; i < invFolderx.FolderData.Length; i++)
  8786. {
  8787. OnUpdateInventoryFolder?.Invoke(this, invFolderx.FolderData[i].FolderID,
  8788. (ushort)invFolderx.FolderData[i].Type,
  8789. Util.FieldToString(invFolderx.FolderData[i].Name),
  8790. invFolderx.FolderData[i].ParentID);
  8791. }
  8792. }
  8793. private void HandleMoveInventoryFolder(Packet Pack)
  8794. {
  8795. if (OnMoveInventoryFolder == null)
  8796. return;
  8797. MoveInventoryFolderPacket invFoldery = (MoveInventoryFolderPacket)Pack;
  8798. if (invFoldery.AgentData.SessionID.NotEqual(m_sessionId) || invFoldery.AgentData.AgentID.NotEqual(m_agentId))
  8799. return;
  8800. for (int i = 0; i < invFoldery.InventoryData.Length; i++)
  8801. {
  8802. OnMoveInventoryFolder?.Invoke(this, invFoldery.InventoryData[i].FolderID,
  8803. invFoldery.InventoryData[i].ParentID);
  8804. }
  8805. }
  8806. private void HandleCreateInventoryItem(Packet Pack)
  8807. {
  8808. CreateInventoryItemPacket createItem = (CreateInventoryItemPacket)Pack;
  8809. if (createItem.AgentData.SessionID.NotEqual(m_sessionId) || createItem.AgentData.AgentID.NotEqual(m_agentId))
  8810. return;
  8811. OnCreateNewInventoryItem?.Invoke(this, createItem.InventoryBlock.TransactionID,
  8812. createItem.InventoryBlock.FolderID,
  8813. createItem.InventoryBlock.CallbackID,
  8814. Util.FieldToString(createItem.InventoryBlock.Description),
  8815. Util.FieldToString(createItem.InventoryBlock.Name),
  8816. createItem.InventoryBlock.InvType,
  8817. createItem.InventoryBlock.Type,
  8818. createItem.InventoryBlock.WearableType,
  8819. createItem.InventoryBlock.NextOwnerMask,
  8820. Util.UnixTimeSinceEpoch());
  8821. }
  8822. private void HandleLinkInventoryItem(Packet Pack)
  8823. {
  8824. LinkInventoryItemPacket createLink = (LinkInventoryItemPacket)Pack;
  8825. if (createLink.AgentData.SessionID.NotEqual(m_sessionId) || createLink.AgentData.AgentID.NotEqual(m_agentId))
  8826. return;
  8827. OnLinkInventoryItem?.Invoke(
  8828. this,
  8829. createLink.InventoryBlock.TransactionID,
  8830. createLink.InventoryBlock.FolderID,
  8831. createLink.InventoryBlock.CallbackID,
  8832. Util.FieldToString(createLink.InventoryBlock.Description),
  8833. Util.FieldToString(createLink.InventoryBlock.Name),
  8834. createLink.InventoryBlock.InvType,
  8835. createLink.InventoryBlock.Type,
  8836. createLink.InventoryBlock.OldItemID);
  8837. }
  8838. private void HandleFetchInventory(Packet Pack)
  8839. {
  8840. if (OnFetchInventory == null)
  8841. return;
  8842. FetchInventoryPacket FetchInventoryx = (FetchInventoryPacket)Pack;
  8843. if (FetchInventoryx.AgentData.SessionID.NotEqual(m_sessionId) || FetchInventoryx.AgentData.AgentID.NotEqual(m_agentId))
  8844. return;
  8845. FetchInventoryPacket.InventoryDataBlock[] data = FetchInventoryx.InventoryData;
  8846. UUID[] items = new UUID[data.Length];
  8847. UUID[] owners = new UUID[data.Length];
  8848. for (int i = 0; i < data.Length; ++i)
  8849. {
  8850. items[i] =data[i].ItemID;
  8851. owners[i] = data[i].OwnerID;
  8852. }
  8853. OnFetchInventory?.Invoke(this, items, owners);
  8854. }
  8855. private void HandleFetchInventoryDescendents(Packet Pack)
  8856. {
  8857. FetchInventoryDescendentsPacket Fetch = (FetchInventoryDescendentsPacket)Pack;
  8858. if (Fetch.AgentData.SessionID.NotEqual(m_sessionId) || Fetch.AgentData.AgentID.NotEqual(m_agentId))
  8859. return;
  8860. FetchInventoryDescendentsPacket.InventoryDataBlock data = Fetch.InventoryData;
  8861. OnFetchInventoryDescendents?.Invoke(this, data.FolderID, data.OwnerID,
  8862. data.FetchFolders, data.FetchItems,
  8863. data.SortOrder);
  8864. }
  8865. private void HandlePurgeInventoryDescendents(Packet Pack)
  8866. {
  8867. PurgeInventoryDescendentsPacket Purge = (PurgeInventoryDescendentsPacket)Pack;
  8868. if (Purge.AgentData.SessionID.NotEqual(m_sessionId) || Purge.AgentData.AgentID.NotEqual(m_agentId))
  8869. return;
  8870. OnPurgeInventoryDescendents?.Invoke(this, Purge.InventoryData.FolderID);
  8871. }
  8872. private void HandleUpdateInventoryItem(Packet Pack)
  8873. {
  8874. if (OnUpdateInventoryItem == null)
  8875. return;
  8876. UpdateInventoryItemPacket inventoryItemUpdate = (UpdateInventoryItemPacket)Pack;
  8877. if (inventoryItemUpdate.AgentData.SessionID.NotEqual(m_sessionId) || inventoryItemUpdate.AgentData.AgentID.NotEqual(m_agentId))
  8878. return;
  8879. for (int i = 0; i < inventoryItemUpdate.InventoryData.Length; i++)
  8880. {
  8881. InventoryItemBase itemUpd = new InventoryItemBase();
  8882. itemUpd.ID = inventoryItemUpdate.InventoryData[i].ItemID;
  8883. itemUpd.Name = Util.FieldToString(inventoryItemUpdate.InventoryData[i].Name);
  8884. itemUpd.Description = Util.FieldToString(inventoryItemUpdate.InventoryData[i].Description);
  8885. itemUpd.GroupID = inventoryItemUpdate.InventoryData[i].GroupID;
  8886. itemUpd.GroupOwned = inventoryItemUpdate.InventoryData[i].GroupOwned;
  8887. itemUpd.GroupPermissions = inventoryItemUpdate.InventoryData[i].GroupMask;
  8888. itemUpd.NextPermissions = inventoryItemUpdate.InventoryData[i].NextOwnerMask;
  8889. itemUpd.EveryOnePermissions = inventoryItemUpdate.InventoryData[i].EveryoneMask;
  8890. itemUpd.CreationDate = inventoryItemUpdate.InventoryData[i].CreationDate;
  8891. itemUpd.Folder = inventoryItemUpdate.InventoryData[i].FolderID;
  8892. itemUpd.InvType = inventoryItemUpdate.InventoryData[i].InvType;
  8893. itemUpd.SalePrice = inventoryItemUpdate.InventoryData[i].SalePrice;
  8894. itemUpd.SaleType = inventoryItemUpdate.InventoryData[i].SaleType;
  8895. itemUpd.Flags = inventoryItemUpdate.InventoryData[i].Flags;
  8896. OnUpdateInventoryItem?.Invoke(this, inventoryItemUpdate.InventoryData[i].TransactionID,
  8897. inventoryItemUpdate.InventoryData[i].ItemID,
  8898. itemUpd);
  8899. }
  8900. }
  8901. private void HandleCopyInventoryItem(Packet Pack)
  8902. {
  8903. if(OnCopyInventoryItem == null)
  8904. return;
  8905. CopyInventoryItemPacket copyitem = (CopyInventoryItemPacket)Pack;
  8906. if (copyitem.AgentData.SessionID.NotEqual(m_sessionId) || copyitem.AgentData.AgentID.NotEqual(m_agentId))
  8907. return;
  8908. foreach (CopyInventoryItemPacket.InventoryDataBlock datablock in copyitem.InventoryData)
  8909. {
  8910. OnCopyInventoryItem?.Invoke(this, datablock.CallbackID, datablock.OldAgentID,
  8911. datablock.OldItemID, datablock.NewFolderID,
  8912. Util.FieldToString(datablock.NewName));
  8913. }
  8914. }
  8915. private void HandleMoveInventoryItem(Packet Pack)
  8916. {
  8917. if (OnMoveInventoryItem == null)
  8918. return;
  8919. MoveInventoryItemPacket moveitem = (MoveInventoryItemPacket)Pack;
  8920. if (moveitem.AgentData.SessionID.NotEqual(m_sessionId) || moveitem.AgentData.AgentID.NotEqual(m_agentId))
  8921. return;
  8922. InventoryItemBase itm = null;
  8923. List<InventoryItemBase> items = new List<InventoryItemBase>();
  8924. foreach (MoveInventoryItemPacket.InventoryDataBlock datablock in moveitem.InventoryData)
  8925. {
  8926. itm = new InventoryItemBase(datablock.ItemID, m_agentId);
  8927. itm.Folder = datablock.FolderID;
  8928. itm.Name = Util.FieldToString(datablock.NewName);
  8929. // weird, comes out as empty string
  8930. //m_log.DebugFormat("[XXX] new name: {0}", itm.Name);
  8931. items.Add(itm);
  8932. }
  8933. OnMoveInventoryItem?.Invoke(this, items);
  8934. }
  8935. private void HandleRemoveInventoryItem(Packet Pack)
  8936. {
  8937. if(OnRemoveInventoryItem == null)
  8938. return;
  8939. RemoveInventoryItemPacket removeItem = (RemoveInventoryItemPacket)Pack;
  8940. if (removeItem.AgentData.SessionID.NotEqual(m_sessionId) || removeItem.AgentData.AgentID.NotEqual(m_agentId))
  8941. return;
  8942. List<UUID> uuids = new List<UUID>();
  8943. foreach (RemoveInventoryItemPacket.InventoryDataBlock datablock in removeItem.InventoryData)
  8944. {
  8945. uuids.Add(datablock.ItemID);
  8946. }
  8947. OnRemoveInventoryItem?.Invoke(this, uuids);
  8948. }
  8949. private void HandleRemoveInventoryFolder(Packet Pack)
  8950. {
  8951. if (OnRemoveInventoryFolder == null)
  8952. return;
  8953. RemoveInventoryFolderPacket removeFolder = (RemoveInventoryFolderPacket)Pack;
  8954. if (removeFolder.AgentData.SessionID.NotEqual(m_sessionId) || removeFolder.AgentData.AgentID.NotEqual(m_agentId))
  8955. return;
  8956. List<UUID> uuids = new List<UUID>();
  8957. foreach (RemoveInventoryFolderPacket.FolderDataBlock datablock in removeFolder.FolderData)
  8958. {
  8959. uuids.Add(datablock.FolderID);
  8960. }
  8961. OnRemoveInventoryFolder?.Invoke(this, uuids);
  8962. }
  8963. private void HandleRemoveInventoryObjects(Packet Pack)
  8964. {
  8965. if (OnRemoveInventoryFolder == null || OnRemoveInventoryItem == null)
  8966. return;
  8967. RemoveInventoryObjectsPacket removeObject = (RemoveInventoryObjectsPacket)Pack;
  8968. if (removeObject.AgentData.SessionID.NotEqual(m_sessionId) || removeObject.AgentData.AgentID.NotEqual(m_agentId))
  8969. return;
  8970. List<UUID> uuids = new List<UUID>();
  8971. foreach (RemoveInventoryObjectsPacket.FolderDataBlock datablock in removeObject.FolderData)
  8972. uuids.Add(datablock.FolderID);
  8973. OnRemoveInventoryFolder?.Invoke(this, uuids);
  8974. uuids.Clear();
  8975. foreach (RemoveInventoryObjectsPacket.ItemDataBlock datablock in removeObject.ItemData)
  8976. uuids.Add(datablock.ItemID);
  8977. OnRemoveInventoryItem?.Invoke(this, uuids);
  8978. }
  8979. private void HandleRequestTaskInventory(Packet Pack)
  8980. {
  8981. RequestTaskInventoryPacket requesttask = (RequestTaskInventoryPacket)Pack;
  8982. if (requesttask.AgentData.SessionID.NotEqual(m_sessionId) || requesttask.AgentData.AgentID.NotEqual(m_agentId))
  8983. return;
  8984. OnRequestTaskInventory?.Invoke(this, requesttask.InventoryData.LocalID);
  8985. }
  8986. private void HandleUpdateTaskInventory(Packet Pack)
  8987. {
  8988. if (OnUpdateTaskInventory == null)
  8989. return;
  8990. UpdateTaskInventoryPacket updatetask = (UpdateTaskInventoryPacket)Pack;
  8991. if (updatetask.UpdateData.Key != 0)
  8992. return; // only do inventory not assets
  8993. if (updatetask.AgentData.SessionID.NotEqual(m_sessionId) || updatetask.AgentData.AgentID.NotEqual(m_agentId))
  8994. return;
  8995. TaskInventoryItem newTaskItem = new TaskInventoryItem
  8996. {
  8997. ItemID = updatetask.InventoryData.ItemID,
  8998. ParentID = updatetask.InventoryData.FolderID,
  8999. CreatorID = updatetask.InventoryData.CreatorID,
  9000. OwnerID = updatetask.InventoryData.OwnerID,
  9001. GroupID = updatetask.InventoryData.GroupID,
  9002. BasePermissions = updatetask.InventoryData.BaseMask,
  9003. CurrentPermissions = updatetask.InventoryData.OwnerMask,
  9004. GroupPermissions = updatetask.InventoryData.GroupMask,
  9005. EveryonePermissions = updatetask.InventoryData.EveryoneMask,
  9006. NextPermissions = updatetask.InventoryData.NextOwnerMask,
  9007. // Unused? Clicking share with group sets GroupPermissions instead, so perhaps this is something
  9008. // different
  9009. //newTaskItem.GroupOwned=updatetask.InventoryData.GroupOwned,
  9010. Type = updatetask.InventoryData.Type,
  9011. InvType = updatetask.InventoryData.InvType,
  9012. Flags = updatetask.InventoryData.Flags,
  9013. //newTaskItem.SaleType=updatetask.InventoryData.SaleType,
  9014. //newTaskItem.SalePrice=updatetask.InventoryData.SalePrice,
  9015. Name = Util.FieldToString(updatetask.InventoryData.Name),
  9016. Description = Util.FieldToString(updatetask.InventoryData.Description),
  9017. CreationDate = (uint)updatetask.InventoryData.CreationDate
  9018. };
  9019. OnUpdateTaskInventory?.Invoke(this, updatetask.InventoryData.TransactionID,
  9020. newTaskItem, updatetask.UpdateData.LocalID);
  9021. }
  9022. private void HandleRemoveTaskInventory(Packet Pack)
  9023. {
  9024. RemoveTaskInventoryPacket removeTask = (RemoveTaskInventoryPacket)Pack;
  9025. if (removeTask.AgentData.SessionID.NotEqual(m_sessionId) || removeTask.AgentData.AgentID.NotEqual(m_agentId))
  9026. return;
  9027. OnRemoveTaskItem?.Invoke(this, removeTask.InventoryData.ItemID, removeTask.InventoryData.LocalID);
  9028. }
  9029. private void HandleMoveTaskInventory(Packet Pack)
  9030. {
  9031. MoveTaskInventoryPacket moveTaskInventoryPacket = (MoveTaskInventoryPacket)Pack;
  9032. if (moveTaskInventoryPacket.AgentData.SessionID.NotEqual(m_sessionId) || moveTaskInventoryPacket.AgentData.AgentID.NotEqual(m_agentId))
  9033. return;
  9034. OnMoveTaskItem?.Invoke(
  9035. this, moveTaskInventoryPacket.AgentData.FolderID,
  9036. moveTaskInventoryPacket.InventoryData.LocalID,
  9037. moveTaskInventoryPacket.InventoryData.ItemID);
  9038. }
  9039. private void HandleRezScript(Packet Pack)
  9040. {
  9041. if(OnRezScript == null)
  9042. return;
  9043. //m_log.Debug(Pack.ToString());
  9044. RezScriptPacket rezScriptx = (RezScriptPacket)Pack;
  9045. if (rezScriptx.AgentData.SessionID.NotEqual(m_sessionId) || rezScriptx.AgentData.AgentID.NotEqual(m_agentId))
  9046. return;
  9047. InventoryItemBase item = new InventoryItemBase
  9048. {
  9049. ID = rezScriptx.InventoryBlock.ItemID,
  9050. Folder = rezScriptx.InventoryBlock.FolderID,
  9051. CreatorId = rezScriptx.InventoryBlock.CreatorID.ToString(),
  9052. Owner = rezScriptx.InventoryBlock.OwnerID,
  9053. BasePermissions = rezScriptx.InventoryBlock.BaseMask,
  9054. CurrentPermissions = rezScriptx.InventoryBlock.OwnerMask,
  9055. EveryOnePermissions = rezScriptx.InventoryBlock.EveryoneMask,
  9056. NextPermissions = rezScriptx.InventoryBlock.NextOwnerMask,
  9057. GroupPermissions = rezScriptx.InventoryBlock.GroupMask,
  9058. GroupOwned = rezScriptx.InventoryBlock.GroupOwned,
  9059. GroupID = rezScriptx.InventoryBlock.GroupID,
  9060. AssetType = rezScriptx.InventoryBlock.Type,
  9061. InvType = rezScriptx.InventoryBlock.InvType,
  9062. Flags = rezScriptx.InventoryBlock.Flags,
  9063. SaleType = rezScriptx.InventoryBlock.SaleType,
  9064. SalePrice = rezScriptx.InventoryBlock.SalePrice,
  9065. Name = Util.FieldToString(rezScriptx.InventoryBlock.Name),
  9066. Description = Util.FieldToString(rezScriptx.InventoryBlock.Description),
  9067. CreationDate = rezScriptx.InventoryBlock.CreationDate
  9068. };
  9069. OnRezScript?.Invoke(this, item, rezScriptx.InventoryBlock.TransactionID, rezScriptx.UpdateBlock.ObjectLocalID);
  9070. }
  9071. private void HandleMapLayerRequest(Packet Pack)
  9072. {
  9073. RequestMapLayer();
  9074. }
  9075. private void HandleMapBlockRequest(Packet Pack)
  9076. {
  9077. MapBlockRequestPacket MapRequest = (MapBlockRequestPacket)Pack;
  9078. if (MapRequest.AgentData.SessionID.NotEqual(m_sessionId) || MapRequest.AgentData.AgentID.NotEqual(m_agentId))
  9079. return;
  9080. OnRequestMapBlocks?.Invoke(this, MapRequest.PositionData.MinX, MapRequest.PositionData.MinY,
  9081. MapRequest.PositionData.MaxX, MapRequest.PositionData.MaxY, MapRequest.AgentData.Flags);
  9082. }
  9083. private void HandleMapNameRequest(Packet Pack)
  9084. {
  9085. MapNameRequestPacket map = (MapNameRequestPacket)Pack;
  9086. if (map.AgentData.SessionID.NotEqual(m_sessionId) || map.AgentData.AgentID.NotEqual(m_agentId))
  9087. return;
  9088. string mapName = (map.NameData.Name.Length == 0) ? m_scene.RegionInfo.RegionName :
  9089. Util.UTF8.GetString(map.NameData.Name, 0, map.NameData.Name.Length - 1);
  9090. OnMapNameRequest?.Invoke(this, mapName, map.AgentData.Flags);
  9091. }
  9092. private void HandleTeleportLandmarkRequest(Packet Pack)
  9093. {
  9094. TeleportLandmarkRequestPacket tpReq = (TeleportLandmarkRequestPacket)Pack;
  9095. if (tpReq.Info.SessionID.NotEqual(m_sessionId) || tpReq.Info.AgentID.NotEqual(m_agentId))
  9096. return;
  9097. UUID lmid = tpReq.Info.LandmarkID;
  9098. AssetLandmark lm;
  9099. if (!lmid.IsZero())
  9100. {
  9101. //AssetBase lma = m_assetCache.GetAsset(lmid, false);
  9102. AssetBase lma = m_assetService.Get(lmid.ToString());
  9103. if (lma == null)
  9104. {
  9105. // Failed to find landmark
  9106. // Let's try to search in the user's home asset server
  9107. lma = FindAssetInUserAssetServer(lmid.ToString());
  9108. if (lma == null)
  9109. {
  9110. // Really doesn't exist
  9111. m_log.WarnFormat("[llClient]: landmark asset {0} not found",lmid.ToString());
  9112. SendTeleportFailed("Could not find the landmark asset data");
  9113. return;
  9114. }
  9115. }
  9116. try
  9117. {
  9118. lm = new AssetLandmark(lma);
  9119. }
  9120. catch (NullReferenceException)
  9121. {
  9122. // asset not found generates null ref inside the assetlandmark constructor.
  9123. SendTeleportFailed("Could not find the landmark asset data");
  9124. return;
  9125. }
  9126. }
  9127. else
  9128. {
  9129. // Teleport home request
  9130. OnTeleportHomeRequest?.Invoke(m_agentId, this);
  9131. return;
  9132. }
  9133. OnTeleportLandmarkRequest?.Invoke(this, lm);
  9134. }
  9135. private void HandleTeleportCancel(Packet Pack)
  9136. {
  9137. TeleportCancelPacket pkt = (TeleportCancelPacket) Pack;
  9138. if(pkt.Info.AgentID.NotEqual(m_agentId) || pkt.Info.SessionID.NotEqual(m_sessionId))
  9139. return;
  9140. OnTeleportCancel?.Invoke(this);
  9141. }
  9142. private AssetBase FindAssetInUserAssetServer(string id)
  9143. {
  9144. AgentCircuitData aCircuit = ((Scene)Scene).AuthenticateHandler.GetAgentCircuitData(CircuitCode);
  9145. if (aCircuit != null && aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("AssetServerURI"))
  9146. {
  9147. string assetServer = aCircuit.ServiceURLs["AssetServerURI"].ToString();
  9148. if (!string.IsNullOrEmpty(assetServer))
  9149. return ((Scene)Scene).AssetService.Get(id, assetServer, false);
  9150. }
  9151. return null;
  9152. }
  9153. private void HandleTeleportLocationRequest(Packet Pack)
  9154. {
  9155. if(OnTeleportLocationRequest == null)
  9156. {
  9157. SendTeleportFailed("Could not process the teleport");
  9158. return;
  9159. }
  9160. TeleportLocationRequestPacket tpLocReq = (TeleportLocationRequestPacket)Pack;
  9161. if (tpLocReq.AgentData.SessionID.NotEqual(m_sessionId) || tpLocReq.AgentData.AgentID.NotEqual(m_agentId))
  9162. return;
  9163. // Adjust teleport location to base of a larger region if requested to teleport to a sub-region
  9164. uint locX, locY;
  9165. Util.RegionHandleToWorldLoc(tpLocReq.Info.RegionHandle, out locX, out locY);
  9166. if ((locX >= m_scene.RegionInfo.WorldLocX)
  9167. && (locX < (m_scene.RegionInfo.WorldLocX + m_scene.RegionInfo.RegionSizeX))
  9168. && (locY >= m_scene.RegionInfo.WorldLocY)
  9169. && (locY < (m_scene.RegionInfo.WorldLocY + m_scene.RegionInfo.RegionSizeY)))
  9170. {
  9171. tpLocReq.Info.RegionHandle = m_scene.RegionInfo.RegionHandle;
  9172. tpLocReq.Info.Position.X += locX - m_scene.RegionInfo.WorldLocX;
  9173. tpLocReq.Info.Position.Y += locY - m_scene.RegionInfo.WorldLocY;
  9174. }
  9175. OnTeleportLocationRequest?.Invoke(this, tpLocReq.Info.RegionHandle, tpLocReq.Info.Position,
  9176. tpLocReq.Info.LookAt, 16);
  9177. }
  9178. #endregion Inventory/Asset/Other related packets
  9179. private void HandleUUIDNameRequest(Packet Pack)
  9180. {
  9181. if(OnNameFromUUIDRequest == null)
  9182. return;
  9183. ScenePresence sp = (ScenePresence)SceneAgent;
  9184. if(sp == null || sp.IsDeleted || (sp.IsInTransit && !sp.IsInLocalTransit))
  9185. return;
  9186. UUIDNameRequestPacket incoming = (UUIDNameRequestPacket)Pack;
  9187. foreach (UUIDNameRequestPacket.UUIDNameBlockBlock UUIDBlock in incoming.UUIDNameBlock)
  9188. OnNameFromUUIDRequest?.Invoke(UUIDBlock.ID, this);
  9189. }
  9190. #region Parcel related packets
  9191. private void HandleRegionHandleRequest(Packet Pack)
  9192. {
  9193. RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack;
  9194. OnRegionHandleRequest?.Invoke(this, rhrPack.RequestBlock.RegionID);
  9195. }
  9196. private void HandleParcelInfoRequest(Packet Pack)
  9197. {
  9198. if(OnParcelInfoRequest == null)
  9199. return;
  9200. ParcelInfoRequestPacket pirPack = (ParcelInfoRequestPacket)Pack;
  9201. if (pirPack.AgentData.SessionID.NotEqual(m_sessionId) || pirPack.AgentData.AgentID.NotEqual(m_agentId))
  9202. return;
  9203. OnParcelInfoRequest?.Invoke(this, pirPack.Data.ParcelID);
  9204. }
  9205. private void HandleParcelAccessListRequest(Packet Pack)
  9206. {
  9207. ParcelAccessListRequestPacket requestPacket = (ParcelAccessListRequestPacket)Pack;
  9208. if (requestPacket.AgentData.SessionID.NotEqual(m_sessionId) || requestPacket.AgentData.AgentID.NotEqual(m_agentId))
  9209. return;
  9210. OnParcelAccessListRequest?.Invoke(requestPacket.AgentData.AgentID, requestPacket.AgentData.SessionID,
  9211. requestPacket.Data.Flags, requestPacket.Data.SequenceID,
  9212. requestPacket.Data.LocalID, this);
  9213. }
  9214. private void HandleParcelAccessListUpdate(Packet Pack)
  9215. {
  9216. if(OnParcelAccessListUpdateRequest == null)
  9217. return;
  9218. ParcelAccessListUpdatePacket updatePacket = (ParcelAccessListUpdatePacket)Pack;
  9219. if (updatePacket.AgentData.SessionID.NotEqual(m_sessionId) || updatePacket.AgentData.AgentID.NotEqual(m_agentId))
  9220. return;
  9221. // viewers do send estimated number of packets and sequenceID, but don't seem reliable.
  9222. List<LandAccessEntry> entries = new List<LandAccessEntry>();
  9223. foreach (ParcelAccessListUpdatePacket.ListBlock block in updatePacket.List)
  9224. {
  9225. LandAccessEntry entry = new LandAccessEntry();
  9226. entry.AgentID = block.ID;
  9227. entry.Flags = (AccessList)block.Flags;
  9228. entry.Expires = block.Time;
  9229. entries.Add(entry);
  9230. }
  9231. OnParcelAccessListUpdateRequest?.Invoke(updatePacket.AgentData.AgentID,
  9232. updatePacket.Data.Flags,
  9233. updatePacket.Data.TransactionID,
  9234. updatePacket.Data.LocalID,
  9235. entries, this);
  9236. }
  9237. private void HandleParcelPropertiesRequest(Packet Pack)
  9238. {
  9239. ParcelPropertiesRequestPacket propertiesRequest = (ParcelPropertiesRequestPacket)Pack;
  9240. if (propertiesRequest.AgentData.SessionID.NotEqual(m_sessionId) || propertiesRequest.AgentData.AgentID.NotEqual(m_agentId))
  9241. return;
  9242. ParcelPropertiesRequestPacket.ParcelDataBlock pdb = propertiesRequest.ParcelData;
  9243. OnParcelPropertiesRequest?.Invoke((int)Math.Round(pdb.West), (int)Math.Round(pdb.South),
  9244. (int)Math.Round(pdb.East), (int)Math.Round(pdb.North),
  9245. pdb.SequenceID, pdb.SnapSelection, this);
  9246. }
  9247. private void HandleParcelDivide(Packet Pack)
  9248. {
  9249. ParcelDividePacket landDivide = (ParcelDividePacket)Pack;
  9250. if (landDivide.AgentData.SessionID.NotEqual(m_sessionId) || landDivide.AgentData.AgentID.NotEqual(m_agentId))
  9251. return;
  9252. OnParcelDivideRequest?.Invoke((int)Math.Round(landDivide.ParcelData.West),
  9253. (int)Math.Round(landDivide.ParcelData.South),
  9254. (int)Math.Round(landDivide.ParcelData.East),
  9255. (int)Math.Round(landDivide.ParcelData.North), this);
  9256. }
  9257. private void HandleParcelJoin(Packet Pack)
  9258. {
  9259. ParcelJoinPacket landJoin = (ParcelJoinPacket)Pack;
  9260. if (landJoin.AgentData.SessionID.NotEqual(m_sessionId) || landJoin.AgentData.AgentID.NotEqual(m_agentId))
  9261. return;
  9262. OnParcelJoinRequest?.Invoke((int)Math.Round(landJoin.ParcelData.West),
  9263. (int)Math.Round(landJoin.ParcelData.South),
  9264. (int)Math.Round(landJoin.ParcelData.East),
  9265. (int)Math.Round(landJoin.ParcelData.North), this);
  9266. }
  9267. private void HandleParcelPropertiesUpdate(Packet Pack)
  9268. {
  9269. if (OnParcelPropertiesUpdateRequest == null)
  9270. return;
  9271. ParcelPropertiesUpdatePacket parcelPropertiesPacket = (ParcelPropertiesUpdatePacket)Pack;
  9272. if (parcelPropertiesPacket.AgentData.SessionID.NotEqual(m_sessionId) || parcelPropertiesPacket.AgentData.AgentID.NotEqual(m_agentId))
  9273. return;
  9274. LandUpdateArgs args = new LandUpdateArgs();
  9275. args.AuthBuyerID = parcelPropertiesPacket.ParcelData.AuthBuyerID;
  9276. args.Category = (ParcelCategory)parcelPropertiesPacket.ParcelData.Category;
  9277. args.Desc = Utils.BytesToString(parcelPropertiesPacket.ParcelData.Desc);
  9278. args.GroupID = parcelPropertiesPacket.ParcelData.GroupID;
  9279. args.LandingType = parcelPropertiesPacket.ParcelData.LandingType;
  9280. args.MediaAutoScale = parcelPropertiesPacket.ParcelData.MediaAutoScale;
  9281. args.MediaID = parcelPropertiesPacket.ParcelData.MediaID;
  9282. args.MediaURL = Utils.BytesToString(parcelPropertiesPacket.ParcelData.MediaURL);
  9283. args.MusicURL = Utils.BytesToString(parcelPropertiesPacket.ParcelData.MusicURL);
  9284. args.Name = Utils.BytesToString(parcelPropertiesPacket.ParcelData.Name);
  9285. args.ParcelFlags = parcelPropertiesPacket.ParcelData.ParcelFlags;
  9286. args.PassHours = parcelPropertiesPacket.ParcelData.PassHours;
  9287. args.PassPrice = parcelPropertiesPacket.ParcelData.PassPrice;
  9288. args.SalePrice = parcelPropertiesPacket.ParcelData.SalePrice;
  9289. args.SnapshotID = parcelPropertiesPacket.ParcelData.SnapshotID;
  9290. args.UserLocation = parcelPropertiesPacket.ParcelData.UserLocation;
  9291. args.UserLookAt = parcelPropertiesPacket.ParcelData.UserLookAt;
  9292. OnParcelPropertiesUpdateRequest?.Invoke(args, parcelPropertiesPacket.ParcelData.LocalID, this);
  9293. }
  9294. private void HandleParcelSelectObjects(Packet Pack)
  9295. {
  9296. if(OnParcelSelectObjects == null)
  9297. return;
  9298. ParcelSelectObjectsPacket selectPacket = (ParcelSelectObjectsPacket)Pack;
  9299. if (selectPacket.AgentData.SessionID.NotEqual(m_sessionId) || selectPacket.AgentData.AgentID.NotEqual(m_agentId))
  9300. return;
  9301. List<UUID> returnIDs = new List<UUID>();
  9302. foreach (ParcelSelectObjectsPacket.ReturnIDsBlock rb in selectPacket.ReturnIDs)
  9303. {
  9304. returnIDs.Add(rb.ReturnID);
  9305. }
  9306. OnParcelSelectObjects?.Invoke(selectPacket.ParcelData.LocalID,
  9307. Convert.ToInt32(selectPacket.ParcelData.ReturnType), returnIDs, this);
  9308. }
  9309. private void HandleParcelObjectOwnersRequest(Packet Pack)
  9310. {
  9311. ParcelObjectOwnersRequestPacket reqPacket = (ParcelObjectOwnersRequestPacket)Pack;
  9312. if (reqPacket.AgentData.SessionID.NotEqual(m_sessionId) || reqPacket.AgentData.AgentID.NotEqual(m_agentId))
  9313. return;
  9314. OnParcelObjectOwnerRequest?.Invoke(reqPacket.ParcelData.LocalID, this);
  9315. }
  9316. private void HandleParcelGodForceOwner(Packet Pack)
  9317. {
  9318. ParcelGodForceOwnerPacket godForceOwnerPacket = (ParcelGodForceOwnerPacket)Pack;
  9319. if (godForceOwnerPacket.AgentData.SessionID.NotEqual(m_sessionId) || godForceOwnerPacket.AgentData.AgentID.NotEqual(m_agentId))
  9320. return;
  9321. OnParcelGodForceOwner?.Invoke(godForceOwnerPacket.Data.LocalID, godForceOwnerPacket.Data.OwnerID, this);
  9322. }
  9323. private void HandleParcelRelease(Packet Pack)
  9324. {
  9325. ParcelReleasePacket releasePacket = (ParcelReleasePacket)Pack;
  9326. if (releasePacket.AgentData.SessionID.NotEqual(m_sessionId) || releasePacket.AgentData.AgentID.NotEqual(m_agentId))
  9327. return;
  9328. OnParcelAbandonRequest?.Invoke(releasePacket.Data.LocalID, this);
  9329. }
  9330. private void HandleParcelReclaim(Packet Pack)
  9331. {
  9332. ParcelReclaimPacket reclaimPacket = (ParcelReclaimPacket)Pack;
  9333. if (reclaimPacket.AgentData.SessionID.NotEqual(m_sessionId) || reclaimPacket.AgentData.AgentID.NotEqual(m_agentId))
  9334. return;
  9335. OnParcelReclaim?.Invoke(reclaimPacket.Data.LocalID, this);
  9336. }
  9337. private void HandleParcelReturnObjects(Packet Pack)
  9338. {
  9339. if(OnParcelReturnObjectsRequest == null)
  9340. return;
  9341. ParcelReturnObjectsPacket parcelReturnObjects = (ParcelReturnObjectsPacket)Pack;
  9342. if (parcelReturnObjects.AgentData.SessionID.NotEqual(m_sessionId) || parcelReturnObjects.AgentData.AgentID.NotEqual(m_agentId))
  9343. return;
  9344. UUID[] puserselectedOwnerIDs = new UUID[parcelReturnObjects.OwnerIDs.Length];
  9345. for (int parceliterator = 0; parceliterator < parcelReturnObjects.OwnerIDs.Length; parceliterator++)
  9346. puserselectedOwnerIDs[parceliterator] = parcelReturnObjects.OwnerIDs[parceliterator].OwnerID;
  9347. UUID[] puserselectedTaskIDs = new UUID[parcelReturnObjects.TaskIDs.Length];
  9348. for (int parceliterator = 0; parceliterator < parcelReturnObjects.TaskIDs.Length; parceliterator++)
  9349. puserselectedTaskIDs[parceliterator] = parcelReturnObjects.TaskIDs[parceliterator].TaskID;
  9350. OnParcelReturnObjectsRequest?.Invoke(parcelReturnObjects.ParcelData.LocalID, parcelReturnObjects.ParcelData.ReturnType, puserselectedOwnerIDs, puserselectedTaskIDs, this);
  9351. }
  9352. private void HandleParcelSetOtherCleanTime(Packet Pack)
  9353. {
  9354. ParcelSetOtherCleanTimePacket parcelSetOtherCleanTimePacket = (ParcelSetOtherCleanTimePacket)Pack;
  9355. if (parcelSetOtherCleanTimePacket.AgentData.SessionID.NotEqual(m_sessionId) || parcelSetOtherCleanTimePacket.AgentData.AgentID.NotEqual(m_agentId))
  9356. return;
  9357. OnParcelSetOtherCleanTime?.Invoke(this,
  9358. parcelSetOtherCleanTimePacket.ParcelData.LocalID,
  9359. parcelSetOtherCleanTimePacket.ParcelData.OtherCleanTime);
  9360. }
  9361. private void HandleLandStatRequest(Packet Pack)
  9362. {
  9363. LandStatRequestPacket lsrp = (LandStatRequestPacket)Pack;
  9364. if (lsrp.AgentData.SessionID.NotEqual(m_sessionId) || lsrp.AgentData.AgentID.NotEqual(m_agentId))
  9365. return;
  9366. OnLandStatRequest?.Invoke(lsrp.RequestData.ParcelLocalID, lsrp.RequestData.ReportType, lsrp.RequestData.RequestFlags, Utils.BytesToString(lsrp.RequestData.Filter), this);
  9367. }
  9368. private void HandleParcelDwellRequest(Packet Pack)
  9369. {
  9370. ParcelDwellRequestPacket dwellrq = (ParcelDwellRequestPacket)Pack;
  9371. if (dwellrq.AgentData.SessionID.NotEqual(m_sessionId) || dwellrq.AgentData.AgentID.NotEqual(m_agentId))
  9372. return;
  9373. OnParcelDwellRequest?.Invoke(dwellrq.Data.LocalID, this);
  9374. }
  9375. #endregion Parcel related packets
  9376. #region Estate Packets
  9377. private static double m_lastMapRegenTime = Double.MinValue;
  9378. private void HandleEstateOwnerMessage(Packet Pack)
  9379. {
  9380. EstateOwnerMessagePacket messagePacket = (EstateOwnerMessagePacket)Pack;
  9381. if (messagePacket.AgentData.SessionID.NotEqual(m_sessionId) || messagePacket.AgentData.AgentID.NotEqual(m_agentId))
  9382. return;
  9383. string method = Utils.BytesToString(messagePacket.MethodData.Method);
  9384. switch (method)
  9385. {
  9386. case "getinfo":
  9387. if (m_scene.Permissions.CanIssueEstateCommand(m_agentId, false))
  9388. {
  9389. OnDetailedEstateDataRequest?.Invoke(this, messagePacket.MethodData.Invoice);
  9390. }
  9391. return;
  9392. case "setregioninfo":
  9393. if (m_scene.Permissions.CanIssueEstateCommand(m_agentId, false))
  9394. {
  9395. OnSetEstateFlagsRequest?.Invoke(convertParamStringToBool(messagePacket.ParamList[0].Parameter), convertParamStringToBool(messagePacket.ParamList[1].Parameter),
  9396. convertParamStringToBool(messagePacket.ParamList[2].Parameter), !convertParamStringToBool(messagePacket.ParamList[3].Parameter),
  9397. Convert.ToInt16(Convert.ToDecimal(Utils.BytesToString(messagePacket.ParamList[4].Parameter), Culture.NumberFormatInfo)),
  9398. (float)Convert.ToDecimal(Utils.BytesToString(messagePacket.ParamList[5].Parameter), Culture.NumberFormatInfo),
  9399. Convert.ToInt16(Utils.BytesToString(messagePacket.ParamList[6].Parameter)),
  9400. convertParamStringToBool(messagePacket.ParamList[7].Parameter), convertParamStringToBool(messagePacket.ParamList[8].Parameter));
  9401. }
  9402. return;
  9403. // case "texturebase":
  9404. // if (((Scene)m_scene).Permissions.CanIssueEstateCommand(m_agentId, false))
  9405. // {
  9406. // foreach (EstateOwnerMessagePacket.ParamListBlock block in messagePacket.ParamList)
  9407. // {
  9408. // string s = Utils.BytesToString(block.Parameter);
  9409. // string[] splitField = s.Split(' ');
  9410. // if (splitField.Length == 2)
  9411. // {
  9412. // UUID tempUUID = new UUID(splitField[1]);
  9413. // OnSetEstateTerrainBaseTexture(this, Convert.ToInt16(splitField[0]), tempUUID);
  9414. // }
  9415. // }
  9416. // }
  9417. // break;
  9418. case "texturedetail":
  9419. if (m_scene.Permissions.CanIssueEstateCommand(m_agentId, false))
  9420. {
  9421. foreach (EstateOwnerMessagePacket.ParamListBlock block in messagePacket.ParamList)
  9422. {
  9423. string s = Utils.BytesToString(block.Parameter);
  9424. string[] splitField = s.Split(' ');
  9425. if (splitField.Length == 2)
  9426. {
  9427. Int16 corner = Convert.ToInt16(splitField[0]);
  9428. UUID textureUUID = new UUID(splitField[1]);
  9429. OnSetEstateTerrainDetailTexture?.Invoke(this, corner, textureUUID);
  9430. }
  9431. }
  9432. }
  9433. return;
  9434. case "textureheights":
  9435. if (m_scene.Permissions.CanIssueEstateCommand(m_agentId, false))
  9436. {
  9437. foreach (EstateOwnerMessagePacket.ParamListBlock block in messagePacket.ParamList)
  9438. {
  9439. string s = Utils.BytesToString(block.Parameter);
  9440. string[] splitField = s.Split(' ');
  9441. if (splitField.Length == 3)
  9442. {
  9443. Int16 corner = Convert.ToInt16(splitField[0]);
  9444. float lowValue = (float)Convert.ToDecimal(splitField[1], Culture.NumberFormatInfo);
  9445. float highValue = (float)Convert.ToDecimal(splitField[2], Culture.NumberFormatInfo);
  9446. OnSetEstateTerrainTextureHeights?.Invoke(this, corner, lowValue, highValue);
  9447. }
  9448. }
  9449. }
  9450. return;
  9451. case "texturecommit":
  9452. OnCommitEstateTerrainTextureRequest?.Invoke(this);
  9453. return;
  9454. case "setregionterrain":
  9455. if (m_scene.Permissions.CanIssueEstateCommand(m_agentId, false))
  9456. {
  9457. if (messagePacket.ParamList.Length != 9)
  9458. {
  9459. m_log.Error("EstateOwnerMessage: SetRegionTerrain method has a ParamList of invalid length");
  9460. }
  9461. else
  9462. {
  9463. try
  9464. {
  9465. string tmp = Utils.BytesToString(messagePacket.ParamList[0].Parameter);
  9466. if (!tmp.Contains(".")) tmp += ".00";
  9467. float WaterHeight = (float)Convert.ToDecimal(tmp, Culture.NumberFormatInfo);
  9468. tmp = Utils.BytesToString(messagePacket.ParamList[1].Parameter);
  9469. if (!tmp.Contains(".")) tmp += ".00";
  9470. float TerrainRaiseLimit = (float)Convert.ToDecimal(tmp, Culture.NumberFormatInfo);
  9471. tmp = Utils.BytesToString(messagePacket.ParamList[2].Parameter);
  9472. if (!tmp.Contains(".")) tmp += ".00";
  9473. float TerrainLowerLimit = (float)Convert.ToDecimal(tmp, Culture.NumberFormatInfo);
  9474. bool UseEstateSun = convertParamStringToBool(messagePacket.ParamList[3].Parameter);
  9475. bool UseFixedSun = convertParamStringToBool(messagePacket.ParamList[4].Parameter);
  9476. float SunHour = (float)Convert.ToDecimal(Utils.BytesToString(messagePacket.ParamList[5].Parameter), Culture.NumberFormatInfo);
  9477. bool UseGlobal = convertParamStringToBool(messagePacket.ParamList[6].Parameter);
  9478. bool EstateFixedSun = convertParamStringToBool(messagePacket.ParamList[7].Parameter);
  9479. float EstateSunHour = (float)Convert.ToDecimal(Utils.BytesToString(messagePacket.ParamList[8].Parameter), Culture.NumberFormatInfo);
  9480. OnSetRegionTerrainSettings?.Invoke(WaterHeight, TerrainRaiseLimit, TerrainLowerLimit, UseEstateSun, UseFixedSun, SunHour, UseGlobal, EstateFixedSun, EstateSunHour);
  9481. }
  9482. catch (Exception ex)
  9483. {
  9484. m_log.Error("EstateOwnerMessage: Exception while setting terrain settings: \n" + messagePacket + "\n" + ex);
  9485. }
  9486. }
  9487. }
  9488. return;
  9489. case "restart":
  9490. if (m_scene.Permissions.CanIssueEstateCommand(m_agentId, false))
  9491. {
  9492. // There's only 1 block in the estateResetSim.. and that's the number of seconds till restart.
  9493. foreach (EstateOwnerMessagePacket.ParamListBlock block in messagePacket.ParamList)
  9494. {
  9495. float timeSeconds;
  9496. Utils.TryParseSingle(Utils.BytesToString(block.Parameter), out timeSeconds);
  9497. timeSeconds = (int)timeSeconds;
  9498. OnEstateRestartSimRequest?.Invoke(this, (int)timeSeconds);
  9499. }
  9500. }
  9501. return;
  9502. case "estatechangecovenantid":
  9503. if (m_scene.Permissions.CanIssueEstateCommand(m_agentId, false))
  9504. {
  9505. foreach (EstateOwnerMessagePacket.ParamListBlock block in messagePacket.ParamList)
  9506. {
  9507. UUID newCovenantID = new UUID(Utils.BytesToString(block.Parameter));
  9508. OnEstateChangeCovenantRequest?.Invoke(this, newCovenantID);
  9509. }
  9510. }
  9511. return;
  9512. case "estateaccessdelta": // Estate access delta manages the banlist and allow list too.
  9513. if (m_scene.Permissions.CanIssueEstateCommand(m_agentId, false))
  9514. {
  9515. int estateAccessType = Convert.ToInt16(Utils.BytesToString(messagePacket.ParamList[1].Parameter));
  9516. OnUpdateEstateAccessDeltaRequest?.Invoke(this, messagePacket.MethodData.Invoice, estateAccessType, new UUID(Utils.BytesToString(messagePacket.ParamList[2].Parameter)));
  9517. }
  9518. return;
  9519. case "simulatormessage":
  9520. if (m_scene.Permissions.CanIssueEstateCommand(m_agentId, false))
  9521. {
  9522. UUID invoice = messagePacket.MethodData.Invoice;
  9523. UUID SenderID = new UUID(Utils.BytesToString(messagePacket.ParamList[2].Parameter));
  9524. string SenderName = Utils.BytesToString(messagePacket.ParamList[3].Parameter);
  9525. string Message = Utils.BytesToString(messagePacket.ParamList[4].Parameter);
  9526. UUID sessionID = messagePacket.AgentData.SessionID;
  9527. OnSimulatorBlueBoxMessageRequest?.Invoke(this, invoice, SenderID, sessionID, SenderName, Message);
  9528. }
  9529. return;
  9530. case "instantmessage":
  9531. if (m_scene.Permissions.CanIssueEstateCommand(m_agentId, false))
  9532. {
  9533. if (messagePacket.ParamList.Length < 2)
  9534. return;
  9535. UUID invoice = messagePacket.MethodData.Invoice;
  9536. UUID sessionID = messagePacket.AgentData.SessionID;
  9537. UUID SenderID;
  9538. string SenderName;
  9539. string Message;
  9540. if (messagePacket.ParamList.Length < 5)
  9541. {
  9542. SenderID = m_agentId;
  9543. SenderName = Utils.BytesToString(messagePacket.ParamList[0].Parameter);
  9544. Message = Utils.BytesToString(messagePacket.ParamList[1].Parameter);
  9545. }
  9546. else
  9547. {
  9548. SenderID = new UUID(Utils.BytesToString(messagePacket.ParamList[2].Parameter));
  9549. SenderName = Utils.BytesToString(messagePacket.ParamList[3].Parameter);
  9550. Message = Utils.BytesToString(messagePacket.ParamList[4].Parameter);
  9551. }
  9552. OnEstateBlueBoxMessageRequest?.Invoke(this, invoice, SenderID, sessionID, SenderName, Message);
  9553. }
  9554. return;
  9555. case "setregiondebug":
  9556. if (m_scene.Permissions.CanIssueEstateCommand(m_agentId, false))
  9557. {
  9558. UUID invoice = messagePacket.MethodData.Invoice;
  9559. UUID SenderID = messagePacket.AgentData.AgentID;
  9560. bool scripted = convertParamStringToBool(messagePacket.ParamList[0].Parameter);
  9561. bool collisionEvents = convertParamStringToBool(messagePacket.ParamList[1].Parameter);
  9562. bool physics = convertParamStringToBool(messagePacket.ParamList[2].Parameter);
  9563. OnEstateDebugRegionRequest?.Invoke(this, invoice, SenderID, scripted, collisionEvents, physics);
  9564. }
  9565. return;
  9566. case "teleporthomeuser":
  9567. if (m_scene.Permissions.CanIssueEstateCommand(m_agentId, false))
  9568. {
  9569. UUID invoice = messagePacket.MethodData.Invoice;
  9570. UUID SenderID = messagePacket.AgentData.AgentID;
  9571. UUID Prey;
  9572. if(UUID.TryParse(Utils.BytesToString(messagePacket.ParamList[1].Parameter), out Prey))
  9573. OnEstateTeleportOneUserHomeRequest?.Invoke(this, invoice, SenderID, Prey, false);
  9574. }
  9575. return;
  9576. case "teleporthomeallusers":
  9577. if (m_scene.Permissions.CanIssueEstateCommand(m_agentId, false))
  9578. {
  9579. UUID invoice = messagePacket.MethodData.Invoice;
  9580. UUID SenderID = messagePacket.AgentData.AgentID;
  9581. OnEstateTeleportAllUsersHomeRequest?.Invoke(this, invoice, SenderID);
  9582. }
  9583. return;
  9584. case "colliders":
  9585. OnLandStatRequest?.Invoke(0, 1, 0, "", this);
  9586. return;
  9587. case "scripts":
  9588. OnLandStatRequest?.Invoke(0, 0, 0, "", this);
  9589. return;
  9590. case "terrain":
  9591. if (m_scene.Permissions.CanIssueEstateCommand(m_agentId, false))
  9592. {
  9593. if (messagePacket.ParamList.Length > 0)
  9594. {
  9595. string p0 = Utils.BytesToString(messagePacket.ParamList[0].Parameter);
  9596. if (p0 == "bake")
  9597. {
  9598. OnBakeTerrain?.Invoke(this);
  9599. }
  9600. else if (p0 == "download filename")
  9601. {
  9602. if (messagePacket.ParamList.Length > 1)
  9603. {
  9604. OnRequestTerrain?.Invoke(this, Utils.BytesToString(messagePacket.ParamList[1].Parameter));
  9605. }
  9606. }
  9607. else if (p0 == "upload filename")
  9608. {
  9609. if (messagePacket.ParamList.Length > 1)
  9610. {
  9611. OnUploadTerrain?.Invoke(this, Utils.BytesToString(messagePacket.ParamList[1].Parameter));
  9612. }
  9613. }
  9614. }
  9615. }
  9616. return;
  9617. case "estatechangeinfo":
  9618. if (m_scene.Permissions.CanIssueEstateCommand(m_agentId, false))
  9619. {
  9620. UUID invoice = messagePacket.MethodData.Invoice;
  9621. UUID SenderID = messagePacket.AgentData.AgentID;
  9622. UInt32 param1 = Convert.ToUInt32(Utils.BytesToString(messagePacket.ParamList[1].Parameter));
  9623. UInt32 param2 = Convert.ToUInt32(Utils.BytesToString(messagePacket.ParamList[2].Parameter));
  9624. OnEstateChangeInfo?.Invoke(this, invoice, SenderID, param1, param2);
  9625. }
  9626. return;
  9627. case "telehub":
  9628. if (m_scene.Permissions.CanIssueEstateCommand(m_agentId, false))
  9629. {
  9630. UUID invoice = messagePacket.MethodData.Invoice;
  9631. UUID SenderID = messagePacket.AgentData.AgentID;
  9632. UInt32 param1 = 0u;
  9633. string command = Utils.BytesToString(messagePacket.ParamList[0].Parameter);
  9634. if (command != "info ui")
  9635. {
  9636. try
  9637. {
  9638. param1 = Convert.ToUInt32(Utils.BytesToString(messagePacket.ParamList[1].Parameter));
  9639. }
  9640. catch
  9641. {
  9642. }
  9643. }
  9644. OnEstateManageTelehub?.Invoke(this, invoice, SenderID, command, param1);
  9645. }
  9646. return;
  9647. case "refreshmapvisibility":
  9648. if (m_scene.Permissions.CanIssueEstateCommand(m_agentId, false))
  9649. {
  9650. IWorldMapModule mapModule = Scene.RequestModuleInterface<IWorldMapModule>();
  9651. if (mapModule == null)
  9652. {
  9653. SendAlertMessage("Terrain map generator not avaiable");
  9654. return;
  9655. }
  9656. if (m_lastMapRegenTime == Double.MaxValue)
  9657. {
  9658. SendAlertMessage("Terrain map generation still in progress");
  9659. return;
  9660. }
  9661. double now = Util.GetTimeStamp();
  9662. if (now - m_lastMapRegenTime < 120) // 2 minutes global cool down
  9663. {
  9664. SendAlertMessage("Please wait at least 2 minutes between map generation commands");
  9665. return;
  9666. }
  9667. m_lastMapRegenTime = Double.MaxValue;
  9668. m_scene.RegenerateMaptileAndReregister(this, null);
  9669. SendAlertMessage("Terrain map generated");
  9670. m_lastMapRegenTime = now;
  9671. }
  9672. return;
  9673. case "kickestate":
  9674. if(m_scene.Permissions.CanIssueEstateCommand(m_agentId, false))
  9675. {
  9676. UUID invoice = messagePacket.MethodData.Invoice;
  9677. UUID SenderID = messagePacket.AgentData.AgentID;
  9678. UUID Prey;
  9679. UUID.TryParse(Utils.BytesToString(messagePacket.ParamList[0].Parameter), out Prey);
  9680. OnEstateTeleportOneUserHomeRequest?.Invoke(this, invoice, SenderID, Prey, true);
  9681. }
  9682. return;
  9683. default:
  9684. m_log.WarnFormat(
  9685. "[LLCLIENTVIEW]: EstateOwnerMessage: Unknown method {0} requested for {1} in {2}",
  9686. method, Name, Scene.Name);
  9687. for (int i = 0; i < messagePacket.ParamList.Length; i++)
  9688. {
  9689. EstateOwnerMessagePacket.ParamListBlock block = messagePacket.ParamList[i];
  9690. string data = (string)Utils.BytesToString(block.Parameter);
  9691. m_log.DebugFormat("[LLCLIENTVIEW]: Param {0}={1}", i, data);
  9692. }
  9693. return;
  9694. }
  9695. //int parcelID, uint reportType, uint requestflags, string filter
  9696. //lsrp.RequestData.ParcelLocalID;
  9697. //lsrp.RequestData.ReportType; // 1 = colliders, 0 = scripts
  9698. //lsrp.RequestData.RequestFlags;
  9699. //lsrp.RequestData.Filter;
  9700. }
  9701. private void HandleRequestRegionInfo(Packet Pack)
  9702. {
  9703. RequestRegionInfoPacket.AgentDataBlock mPacket = ((RequestRegionInfoPacket)Pack).AgentData;
  9704. if (mPacket.SessionID.NotEqual(m_sessionId) || mPacket.AgentID.NotEqual(m_agentId))
  9705. return;
  9706. OnRegionInfoRequest?.Invoke(this);
  9707. }
  9708. private void HandleEstateCovenantRequest(Packet Pack)
  9709. {
  9710. EstateCovenantRequestPacket.AgentDataBlock epack = ((EstateCovenantRequestPacket)Pack).AgentData;
  9711. if (epack.SessionID.NotEqual(m_sessionId) || epack.AgentID.NotEqual(m_agentId))
  9712. return;
  9713. OnEstateCovenantRequest?.Invoke(this);
  9714. }
  9715. #endregion Estate Packets
  9716. #region GodPackets
  9717. private void HandleRequestGodlikePowers(Packet Pack)
  9718. {
  9719. RequestGodlikePowersPacket rglpPack = (RequestGodlikePowersPacket)Pack;
  9720. RequestGodlikePowersPacket.AgentDataBlock ablock = rglpPack.AgentData;
  9721. if (ablock.SessionID.NotEqual(m_sessionId) || ablock.AgentID.NotEqual(m_agentId))
  9722. return;
  9723. RequestGodlikePowersPacket.RequestBlockBlock rblock = rglpPack.RequestBlock;
  9724. UUID token = rblock.Token;
  9725. OnRequestGodlikePowers?.Invoke(ablock.AgentID, ablock.SessionID, token, rblock.Godlike);
  9726. }
  9727. private void HandleGodUpdateRegionInfoUpdate(Packet packet)
  9728. {
  9729. GodUpdateRegionInfoPacket GodUpdateRegionInfo = (GodUpdateRegionInfoPacket)packet;
  9730. if (GodUpdateRegionInfo.AgentData.SessionID.NotEqual(m_sessionId) || GodUpdateRegionInfo.AgentData.AgentID.NotEqual(m_agentId))
  9731. return;
  9732. OnGodUpdateRegionInfoUpdate?.Invoke(this,
  9733. GodUpdateRegionInfo.RegionInfo.BillableFactor,
  9734. GodUpdateRegionInfo.RegionInfo.EstateID,
  9735. GodUpdateRegionInfo.RegionInfo.RegionFlags,
  9736. GodUpdateRegionInfo.RegionInfo.SimName,
  9737. GodUpdateRegionInfo.RegionInfo.RedirectGridX,
  9738. GodUpdateRegionInfo.RegionInfo.RedirectGridY);
  9739. }
  9740. private void HandleSimWideDeletes(Packet packet)
  9741. {
  9742. SimWideDeletesPacket SimWideDeletesRequest = (SimWideDeletesPacket)packet;
  9743. if(SimWideDeletesRequest.AgentData.AgentID.NotEqual(m_agentId) || SimWideDeletesRequest.AgentData.SessionID.NotEqual(m_sessionId))
  9744. return;
  9745. OnSimWideDeletes?.Invoke(this, SimWideDeletesRequest.AgentData.AgentID,(int)SimWideDeletesRequest.DataBlock.Flags,SimWideDeletesRequest.DataBlock.TargetID);
  9746. }
  9747. private void HandleGodlikeMessage(Packet packet)
  9748. {
  9749. GodlikeMessagePacket GodlikeMessage = (GodlikeMessagePacket)packet;
  9750. if (GodlikeMessage.AgentData.SessionID.NotEqual(m_sessionId) || GodlikeMessage.AgentData.AgentID.NotEqual(m_agentId))
  9751. return;
  9752. onGodlikeMessage?.Invoke(this,
  9753. GodlikeMessage.MethodData.Invoice,
  9754. GodlikeMessage.MethodData.Method,
  9755. GodlikeMessage.ParamList[0].Parameter);
  9756. }
  9757. private void HandleSaveStatePacket(Packet packet)
  9758. {
  9759. StateSavePacket SaveStateMessage = (StateSavePacket)packet;
  9760. if (SaveStateMessage.AgentData.SessionID.NotEqual(m_sessionId) || SaveStateMessage.AgentData.AgentID.NotEqual(m_agentId))
  9761. return;
  9762. OnSaveState?.Invoke(this,SaveStateMessage.AgentData.AgentID);
  9763. }
  9764. private void HandleGodKickUser(Packet Pack)
  9765. {
  9766. GodKickUserPacket gkupack = (GodKickUserPacket)Pack;
  9767. if (gkupack.UserInfo.GodSessionID.NotEqual(m_sessionId) || gkupack.UserInfo.GodID.NotEqual(m_agentId))
  9768. return;
  9769. OnGodKickUser?.Invoke(gkupack.UserInfo.GodID, gkupack.UserInfo.AgentID, gkupack.UserInfo.KickFlags, gkupack.UserInfo.Reason);
  9770. }
  9771. #endregion GodPackets
  9772. #region Economy/Transaction Packets
  9773. private void HandleMoneyBalanceRequest(Packet Pack)
  9774. {
  9775. MoneyBalanceRequestPacket moneybalancerequestpacket = (MoneyBalanceRequestPacket)Pack;
  9776. if (moneybalancerequestpacket.AgentData.SessionID.NotEqual(m_sessionId) || moneybalancerequestpacket.AgentData.AgentID.NotEqual(m_agentId))
  9777. return;
  9778. OnMoneyBalanceRequest?.Invoke(this, moneybalancerequestpacket.AgentData.AgentID, moneybalancerequestpacket.AgentData.SessionID, moneybalancerequestpacket.MoneyData.TransactionID);
  9779. }
  9780. private void HandleEconomyDataRequest(Packet Pack)
  9781. {
  9782. OnEconomyDataRequest?.Invoke(this);
  9783. }
  9784. private void HandleRequestPayPrice(Packet Pack)
  9785. {
  9786. RequestPayPricePacket requestPayPricePacket = (RequestPayPricePacket)Pack;
  9787. OnRequestPayPrice?.Invoke(this, requestPayPricePacket.ObjectData.ObjectID);
  9788. }
  9789. private void HandleObjectSaleInfo(Packet Pack)
  9790. {
  9791. if(OnObjectSaleInfo == null)
  9792. return;
  9793. ObjectSaleInfoPacket objectSaleInfoPacket = (ObjectSaleInfoPacket)Pack;
  9794. if (objectSaleInfoPacket.AgentData.SessionID.NotEqual(m_sessionId) || objectSaleInfoPacket.AgentData.AgentID.NotEqual(m_agentId))
  9795. return;
  9796. foreach (ObjectSaleInfoPacket.ObjectDataBlock d in objectSaleInfoPacket.ObjectData)
  9797. {
  9798. OnObjectSaleInfo?.Invoke(this,
  9799. m_agentId,
  9800. SessionId,
  9801. d.LocalID,
  9802. d.SaleType,
  9803. d.SalePrice);
  9804. }
  9805. }
  9806. private void HandleObjectBuy(Packet Pack)
  9807. {
  9808. if(OnObjectBuy == null)
  9809. return;
  9810. ObjectBuyPacket objectBuyPacket = (ObjectBuyPacket)Pack;
  9811. if (objectBuyPacket.AgentData.SessionID.NotEqual(m_sessionId) || objectBuyPacket.AgentData.AgentID.NotEqual(m_agentId))
  9812. return;
  9813. foreach (ObjectBuyPacket.ObjectDataBlock d in objectBuyPacket.ObjectData)
  9814. {
  9815. OnObjectBuy?.Invoke(this,
  9816. objectBuyPacket.AgentData.AgentID,
  9817. objectBuyPacket.AgentData.SessionID,
  9818. objectBuyPacket.AgentData.GroupID,
  9819. objectBuyPacket.AgentData.CategoryID,
  9820. d.ObjectLocalID,
  9821. d.SaleType,
  9822. d.SalePrice);
  9823. }
  9824. }
  9825. #endregion Economy/Transaction Packets
  9826. #region Script Packets
  9827. private void HandleGetScriptRunning(Packet Pack)
  9828. {
  9829. GetScriptRunningPacket scriptRunning = (GetScriptRunningPacket)Pack;
  9830. OnGetScriptRunning?.Invoke(this, scriptRunning.Script.ObjectID, scriptRunning.Script.ItemID);
  9831. }
  9832. private void HandleSetScriptRunning(Packet Pack)
  9833. {
  9834. SetScriptRunningPacket setScriptRunning = (SetScriptRunningPacket)Pack;
  9835. if (setScriptRunning.AgentData.SessionID.NotEqual(m_sessionId) || setScriptRunning.AgentData.AgentID.NotEqual(m_agentId))
  9836. return;
  9837. OnSetScriptRunning?.Invoke(this, setScriptRunning.Script.ObjectID, setScriptRunning.Script.ItemID, setScriptRunning.Script.Running);
  9838. }
  9839. private void HandleScriptReset(Packet Pack)
  9840. {
  9841. ScriptResetPacket scriptResetPacket = (ScriptResetPacket)Pack;
  9842. if (scriptResetPacket.AgentData.SessionID.NotEqual(m_sessionId) || scriptResetPacket.AgentData.AgentID.NotEqual(m_agentId))
  9843. return;
  9844. OnScriptReset?.Invoke(this, scriptResetPacket.Script.ObjectID, scriptResetPacket.Script.ItemID);
  9845. }
  9846. #endregion Script Packets
  9847. #region Gesture Managment
  9848. private void HandleActivateGestures(Packet Pack)
  9849. {
  9850. if(OnActivateGesture == null)
  9851. return;
  9852. ActivateGesturesPacket activateGesturePacket = (ActivateGesturesPacket)Pack;
  9853. if (activateGesturePacket.AgentData.SessionID.NotEqual(m_sessionId) || activateGesturePacket.AgentData.AgentID.NotEqual(m_agentId))
  9854. return;
  9855. ActivateGesturesPacket.DataBlock[] data = activateGesturePacket.Data;
  9856. for (int i= 0; i < data.Length; ++i)
  9857. {
  9858. OnActivateGesture?.Invoke(this,
  9859. data[i].AssetID,
  9860. data[i].ItemID);
  9861. }
  9862. }
  9863. private void HandleDeactivateGestures(Packet Pack)
  9864. {
  9865. if(OnDeactivateGesture == null)
  9866. return;
  9867. DeactivateGesturesPacket deactivateGesturePacket = (DeactivateGesturesPacket)Pack;
  9868. if (deactivateGesturePacket.AgentData.SessionID.NotEqual(m_sessionId) || deactivateGesturePacket.AgentData.AgentID.NotEqual(m_agentId))
  9869. return;
  9870. DeactivateGesturesPacket.DataBlock[] data = deactivateGesturePacket.Data;
  9871. for (int i = 0; i < data.Length; ++i)
  9872. {
  9873. OnDeactivateGesture?.Invoke(this, data[i].ItemID);
  9874. }
  9875. }
  9876. #endregion Gesture Managment
  9877. private void HandleObjectOwner(Packet Pack)
  9878. {
  9879. if (OnObjectOwner == null)
  9880. return;
  9881. ObjectOwnerPacket objectOwnerPacket = (ObjectOwnerPacket)Pack;
  9882. if (objectOwnerPacket.AgentData.SessionID.NotEqual(m_sessionId) || objectOwnerPacket.AgentData.AgentID.NotEqual(m_agentId))
  9883. return;
  9884. List<uint> localIDs = new List<uint>();
  9885. foreach (ObjectOwnerPacket.ObjectDataBlock d in objectOwnerPacket.ObjectData)
  9886. localIDs.Add(d.ObjectLocalID);
  9887. OnObjectOwner?.Invoke(this, objectOwnerPacket.HeaderData.OwnerID, objectOwnerPacket.HeaderData.GroupID, localIDs);
  9888. }
  9889. private void HandleAgentFOV(Packet Pack)
  9890. {
  9891. AgentFOVPacket fovPacket = (AgentFOVPacket)Pack;
  9892. if(fovPacket.AgentData.AgentID.NotEqual(m_agentId) || fovPacket.AgentData.SessionID.NotEqual(m_sessionId))
  9893. return;
  9894. uint genCounter = fovPacket.FOVBlock.GenCounter;
  9895. if (genCounter == 0 || genCounter > m_agentFOVCounter)
  9896. {
  9897. m_agentFOVCounter = genCounter;
  9898. OnAgentFOV?.Invoke(this, fovPacket.FOVBlock.VerticalAngle);
  9899. }
  9900. }
  9901. #region unimplemented handlers
  9902. private void HandleViewerStats(Packet Pack)
  9903. {
  9904. // TODO: handle this packet
  9905. //m_log.Warn("[CLIENT]: unhandled ViewerStats packet");
  9906. }
  9907. private void HandleMapItemRequest(Packet Pack)
  9908. {
  9909. MapItemRequestPacket mirpk = (MapItemRequestPacket)Pack;
  9910. if (mirpk.AgentData.SessionID.NotEqual(m_sessionId) || mirpk.AgentData.AgentID.NotEqual(m_agentId))
  9911. return;
  9912. //m_log.Debug(mirpk.ToString());
  9913. try
  9914. {
  9915. OnMapItemRequest?.Invoke(this, mirpk.AgentData.Flags, mirpk.AgentData.EstateID,
  9916. mirpk.AgentData.Godlike, mirpk.RequestData.ItemType,
  9917. mirpk.RequestData.RegionHandle);
  9918. }
  9919. catch( Exception e)
  9920. {
  9921. m_log.ErrorFormat("{0} HandleMapItemRequest exception: {1} : {2}", LogHeader, e.Message, e.StackTrace);
  9922. }
  9923. }
  9924. private void HandleTransferAbort(Packet Pack)
  9925. {
  9926. }
  9927. private void HandleMuteListRequest(Packet Pack)
  9928. {
  9929. MuteListRequestPacket muteListRequest = (MuteListRequestPacket)Pack;
  9930. if (muteListRequest.AgentData.SessionID.NotEqual(m_sessionId) || muteListRequest.AgentData.AgentID.NotEqual(m_agentId))
  9931. return;
  9932. if (OnMuteListRequest != null)
  9933. {
  9934. OnMuteListRequest?.Invoke(this, muteListRequest.MuteData.MuteCRC);
  9935. }
  9936. else
  9937. {
  9938. if(muteListRequest.MuteData.MuteCRC == 0)
  9939. SendEmpytMuteList();
  9940. else
  9941. SendUseCachedMuteList();
  9942. }
  9943. }
  9944. private void HandleUpdateMuteListEntry(Packet packet)
  9945. {
  9946. UpdateMuteListEntryPacket UpdateMuteListEntry = (UpdateMuteListEntryPacket)packet;
  9947. if (UpdateMuteListEntry.AgentData.SessionID.NotEqual(m_sessionId) || UpdateMuteListEntry.AgentData.AgentID.NotEqual(m_agentId))
  9948. return;
  9949. OnUpdateMuteListEntry?.Invoke(this, UpdateMuteListEntry.MuteData.MuteID,
  9950. Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
  9951. UpdateMuteListEntry.MuteData.MuteType,
  9952. UpdateMuteListEntry.MuteData.MuteFlags);
  9953. }
  9954. private void HandleRemoveMuteListEntry(Packet packet)
  9955. {
  9956. RemoveMuteListEntryPacket RemoveMuteListEntry = (RemoveMuteListEntryPacket)packet;
  9957. if (RemoveMuteListEntry.AgentData.SessionID.NotEqual(m_sessionId) || RemoveMuteListEntry.AgentData.AgentID.NotEqual(m_agentId))
  9958. return;
  9959. OnRemoveMuteListEntry?.Invoke(this,
  9960. RemoveMuteListEntry.MuteData.MuteID,
  9961. Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
  9962. }
  9963. private void HandleUserReport(Packet packet)
  9964. {
  9965. UserReportPacket UserReport = (UserReportPacket)packet;
  9966. if (UserReport.AgentData.SessionID.NotEqual(m_sessionId) || UserReport.AgentData.AgentID.NotEqual(m_agentId))
  9967. return;
  9968. OnUserReport?.Invoke(this,
  9969. Utils.BytesToString(UserReport.ReportData.AbuseRegionName),
  9970. UserReport.ReportData.AbuserID,
  9971. UserReport.ReportData.Category,
  9972. UserReport.ReportData.CheckFlags,
  9973. Utils.BytesToString(UserReport.ReportData.Details),
  9974. UserReport.ReportData.ObjectID,
  9975. UserReport.ReportData.Position,
  9976. UserReport.ReportData.ReportType,
  9977. UserReport.ReportData.ScreenshotID,
  9978. Utils.BytesToString(UserReport.ReportData.Summary),
  9979. UserReport.AgentData.AgentID);
  9980. }
  9981. private void HandleSendPostcard(Packet packet)
  9982. {
  9983. // SendPostcardPacket SendPostcard =
  9984. // (SendPostcardPacket)packet;
  9985. OnSendPostcard?.Invoke(this);
  9986. }
  9987. private void HandleChangeInventoryItemFlags(Packet packet)
  9988. {
  9989. if(OnChangeInventoryItemFlags == null)
  9990. return;
  9991. ChangeInventoryItemFlagsPacket ChangeInventoryItemFlags = (ChangeInventoryItemFlagsPacket)packet;
  9992. if (ChangeInventoryItemFlags.AgentData.SessionID.NotEqual(m_sessionId) || ChangeInventoryItemFlags.AgentData.AgentID.NotEqual(m_agentId))
  9993. return;
  9994. foreach(ChangeInventoryItemFlagsPacket.InventoryDataBlock b in ChangeInventoryItemFlags.InventoryData)
  9995. OnChangeInventoryItemFlags?.Invoke(this, b.ItemID, b.Flags);
  9996. }
  9997. private void HandleUseCircuitCode(Packet Pack)
  9998. {
  9999. /*
  10000. UseCircuitCodePacket uccp = (UseCircuitCodePacket)Pack;
  10001. if(uccp.CircuitCode.ID == m_agentId &&
  10002. uccp.CircuitCode.SessionID.Equals(m_sessionId) &&
  10003. uccp.CircuitCode.Code == m_circuitCode &&
  10004. SceneAgent != null &&
  10005. !((ScenePresence)SceneAgent).IsDeleted
  10006. )
  10007. SendRegionHandshake(); // possible someone returning
  10008. */
  10009. }
  10010. private void HandleCreateNewOutfitAttachments(Packet Pack)
  10011. {
  10012. if(OnMoveItemsAndLeaveCopy == null)
  10013. return;
  10014. CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
  10015. if (packet.AgentData.SessionID.NotEqual(m_sessionId) || packet.AgentData.AgentID.NotEqual(m_agentId))
  10016. return;
  10017. List<InventoryItemBase> items = new List<InventoryItemBase>();
  10018. foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
  10019. {
  10020. InventoryItemBase b = new InventoryItemBase();
  10021. b.ID = n.OldItemID;
  10022. b.Folder = n.OldFolderID;
  10023. items.Add(b);
  10024. }
  10025. OnMoveItemsAndLeaveCopy?.Invoke(this, items, packet.HeaderData.NewFolderID);
  10026. }
  10027. private void HandleAgentHeightWidth(Packet Pack)
  10028. {
  10029. }
  10030. private void HandleInventoryDescendents(Packet Pack)
  10031. {
  10032. }
  10033. #endregion unimplemented handlers
  10034. #region Dir handlers
  10035. private void HandleDirPlacesQuery(Packet Pack)
  10036. {
  10037. DirPlacesQueryPacket dirPlacesQueryPacket = (DirPlacesQueryPacket)Pack;
  10038. if (dirPlacesQueryPacket.AgentData.SessionID.NotEqual(m_sessionId) || dirPlacesQueryPacket.AgentData.AgentID.NotEqual(m_agentId))
  10039. return;
  10040. OnDirPlacesQuery?.Invoke(this,
  10041. dirPlacesQueryPacket.QueryData.QueryID,
  10042. Utils.BytesToString(
  10043. dirPlacesQueryPacket.QueryData.QueryText),
  10044. (int)dirPlacesQueryPacket.QueryData.QueryFlags,
  10045. (int)dirPlacesQueryPacket.QueryData.Category,
  10046. Utils.BytesToString(
  10047. dirPlacesQueryPacket.QueryData.SimName),
  10048. dirPlacesQueryPacket.QueryData.QueryStart);
  10049. }
  10050. private void HandleDirFindQuery(Packet Pack)
  10051. {
  10052. DirFindQueryPacket dirFindQueryPacket = (DirFindQueryPacket)Pack;
  10053. if (dirFindQueryPacket.AgentData.SessionID.NotEqual(m_sessionId) || dirFindQueryPacket.AgentData.AgentID.NotEqual(m_agentId))
  10054. return;
  10055. OnDirFindQuery?.Invoke(this,
  10056. dirFindQueryPacket.QueryData.QueryID,
  10057. Utils.BytesToString(
  10058. dirFindQueryPacket.QueryData.QueryText).Trim(),
  10059. dirFindQueryPacket.QueryData.QueryFlags,
  10060. dirFindQueryPacket.QueryData.QueryStart);
  10061. }
  10062. private void HandleDirLandQuery(Packet Pack)
  10063. {
  10064. DirLandQueryPacket dirLandQueryPacket = (DirLandQueryPacket)Pack;
  10065. if (dirLandQueryPacket.AgentData.SessionID.NotEqual(m_sessionId) || dirLandQueryPacket.AgentData.AgentID.NotEqual(m_agentId))
  10066. return;
  10067. OnDirLandQuery?.Invoke(this,
  10068. dirLandQueryPacket.QueryData.QueryID,
  10069. dirLandQueryPacket.QueryData.QueryFlags,
  10070. dirLandQueryPacket.QueryData.SearchType,
  10071. dirLandQueryPacket.QueryData.Price,
  10072. dirLandQueryPacket.QueryData.Area,
  10073. dirLandQueryPacket.QueryData.QueryStart);
  10074. }
  10075. private void HandleDirPopularQuery(Packet Pack)
  10076. {
  10077. DirPopularQueryPacket dirPopularQueryPacket = (DirPopularQueryPacket)Pack;
  10078. if (dirPopularQueryPacket.AgentData.SessionID.NotEqual(m_sessionId) || dirPopularQueryPacket.AgentData.AgentID.NotEqual(m_agentId))
  10079. return;
  10080. OnDirPopularQuery?.Invoke(this,
  10081. dirPopularQueryPacket.QueryData.QueryID,
  10082. dirPopularQueryPacket.QueryData.QueryFlags);
  10083. }
  10084. private void HandleDirClassifiedQuery(Packet Pack)
  10085. {
  10086. DirClassifiedQueryPacket dirClassifiedQueryPacket = (DirClassifiedQueryPacket)Pack;
  10087. if (dirClassifiedQueryPacket.AgentData.SessionID.NotEqual(m_sessionId) || dirClassifiedQueryPacket.AgentData.AgentID.NotEqual(m_agentId))
  10088. return;
  10089. OnDirClassifiedQuery?.Invoke(this,
  10090. dirClassifiedQueryPacket.QueryData.QueryID,
  10091. Utils.BytesToString(
  10092. dirClassifiedQueryPacket.QueryData.QueryText),
  10093. dirClassifiedQueryPacket.QueryData.QueryFlags,
  10094. dirClassifiedQueryPacket.QueryData.Category,
  10095. dirClassifiedQueryPacket.QueryData.QueryStart);
  10096. }
  10097. private void HandleEventInfoRequest(Packet Pack)
  10098. {
  10099. EventInfoRequestPacket eventInfoRequestPacket = (EventInfoRequestPacket)Pack;
  10100. if (eventInfoRequestPacket.AgentData.SessionID.NotEqual(m_sessionId) || eventInfoRequestPacket.AgentData.AgentID.NotEqual(m_agentId))
  10101. return;
  10102. OnEventInfoRequest?.Invoke(this, eventInfoRequestPacket.EventData.EventID);
  10103. }
  10104. #endregion
  10105. #region Calling Card
  10106. private void HandleOfferCallingCard(Packet Pack)
  10107. {
  10108. OfferCallingCardPacket offerCallingCardPacket = (OfferCallingCardPacket)Pack;
  10109. if (offerCallingCardPacket.AgentData.SessionID.NotEqual(m_sessionId) || offerCallingCardPacket.AgentData.AgentID.NotEqual(m_agentId))
  10110. return;
  10111. OnOfferCallingCard?.Invoke(this,
  10112. offerCallingCardPacket.AgentBlock.DestID,
  10113. offerCallingCardPacket.AgentBlock.TransactionID);
  10114. }
  10115. private void HandleAcceptCallingCard(Packet Pack)
  10116. {
  10117. AcceptCallingCardPacket acceptCallingCardPacket = (AcceptCallingCardPacket)Pack;
  10118. if (acceptCallingCardPacket.AgentData.SessionID.NotEqual(m_sessionId) || acceptCallingCardPacket.AgentData.AgentID.NotEqual(m_agentId))
  10119. return;
  10120. // according to http://wiki.secondlife.com/wiki/AcceptCallingCard FolderData should
  10121. // contain exactly one entry
  10122. if (acceptCallingCardPacket.FolderData.Length > 0)
  10123. {
  10124. OnAcceptCallingCard?.Invoke(this,
  10125. acceptCallingCardPacket.TransactionBlock.TransactionID,
  10126. acceptCallingCardPacket.FolderData[0].FolderID);
  10127. }
  10128. }
  10129. private void HandleDeclineCallingCard(Packet Pack)
  10130. {
  10131. DeclineCallingCardPacket declineCallingCardPacket = (DeclineCallingCardPacket)Pack;
  10132. if (declineCallingCardPacket.AgentData.SessionID.NotEqual(m_sessionId) || declineCallingCardPacket.AgentData.AgentID.NotEqual(m_agentId))
  10133. return;
  10134. OnDeclineCallingCard?.Invoke(this,
  10135. declineCallingCardPacket.TransactionBlock.TransactionID);
  10136. }
  10137. #endregion Calling Card
  10138. #region Groups
  10139. private void HandleActivateGroup(Packet Pack)
  10140. {
  10141. if (m_GroupsModule == null)
  10142. return;
  10143. ActivateGroupPacket activateGroupPacket = (ActivateGroupPacket)Pack;
  10144. if (activateGroupPacket.AgentData.SessionID.NotEqual(m_sessionId) || activateGroupPacket.AgentData.AgentID.NotEqual(m_agentId))
  10145. return;
  10146. m_GroupsModule.ActivateGroup(this, activateGroupPacket.AgentData.GroupID);
  10147. }
  10148. private void HandleGroupVoteHistoryRequest(Packet packet)
  10149. {
  10150. GroupVoteHistoryRequestPacket GroupVoteHistoryRequest = (GroupVoteHistoryRequestPacket)packet;
  10151. if (GroupVoteHistoryRequest.AgentData.SessionID.NotEqual(m_sessionId) || GroupVoteHistoryRequest.AgentData.AgentID.NotEqual(m_agentId))
  10152. return;
  10153. OnGroupVoteHistoryRequest?.Invoke(this, m_agentId, SessionId, GroupVoteHistoryRequest.GroupData.GroupID, GroupVoteHistoryRequest.TransactionData.TransactionID);
  10154. }
  10155. private void HandleGroupActiveProposalsRequest(Packet packet)
  10156. {
  10157. GroupActiveProposalsRequestPacket GroupActiveProposalsRequest = (GroupActiveProposalsRequestPacket)packet;
  10158. if (GroupActiveProposalsRequest.AgentData.SessionID.NotEqual(m_sessionId) || GroupActiveProposalsRequest.AgentData.AgentID.NotEqual(m_agentId))
  10159. return;
  10160. OnGroupActiveProposalsRequest?.Invoke(this, m_agentId, SessionId, GroupActiveProposalsRequest.GroupData.GroupID, GroupActiveProposalsRequest.TransactionData.TransactionID);
  10161. }
  10162. private void HandleGroupAccountDetailsRequest(Packet packet)
  10163. {
  10164. GroupAccountDetailsRequestPacket GroupAccountDetailsRequest = (GroupAccountDetailsRequestPacket)packet;
  10165. if (GroupAccountDetailsRequest.AgentData.SessionID.NotEqual(m_sessionId) || GroupAccountDetailsRequest.AgentData.AgentID.NotEqual(m_agentId))
  10166. return;
  10167. OnGroupAccountDetailsRequest?.Invoke(this, m_agentId, GroupAccountDetailsRequest.AgentData.GroupID, GroupAccountDetailsRequest.MoneyData.RequestID, SessionId);
  10168. }
  10169. private void HandleGroupAccountSummaryRequest(Packet packet)
  10170. {
  10171. GroupAccountSummaryRequestPacket GroupAccountSummaryRequest = (GroupAccountSummaryRequestPacket)packet;
  10172. if (GroupAccountSummaryRequest.AgentData.SessionID.NotEqual(m_sessionId) || GroupAccountSummaryRequest.AgentData.AgentID.NotEqual(m_agentId))
  10173. return;
  10174. OnGroupAccountSummaryRequest?.Invoke(this, m_agentId, GroupAccountSummaryRequest.AgentData.GroupID);
  10175. }
  10176. private void HandleGroupTransactionsDetailsRequest(Packet packet)
  10177. {
  10178. GroupAccountTransactionsRequestPacket GroupAccountTransactionsRequest = (GroupAccountTransactionsRequestPacket)packet;
  10179. if (GroupAccountTransactionsRequest.AgentData.SessionID.NotEqual(m_sessionId) || GroupAccountTransactionsRequest.AgentData.AgentID.NotEqual(m_agentId))
  10180. return;
  10181. OnGroupAccountTransactionsRequest?.Invoke(this, m_agentId, GroupAccountTransactionsRequest.AgentData.GroupID,GroupAccountTransactionsRequest.MoneyData.RequestID, SessionId);
  10182. }
  10183. private void HandleGroupTitlesRequest(Packet Pack)
  10184. {
  10185. if (m_GroupsModule == null)
  10186. return;
  10187. GroupTitlesRequestPacket groupTitlesRequest = (GroupTitlesRequestPacket)Pack;
  10188. if (groupTitlesRequest.AgentData.SessionID.NotEqual(m_sessionId) || groupTitlesRequest.AgentData.AgentID.NotEqual(m_agentId))
  10189. return;
  10190. GroupTitlesReplyPacket groupTitlesReply = (GroupTitlesReplyPacket)PacketPool.Instance.GetPacket(PacketType.GroupTitlesReply);
  10191. groupTitlesReply.AgentData = new GroupTitlesReplyPacket.AgentDataBlock();
  10192. groupTitlesReply.AgentData.AgentID = m_agentId;
  10193. groupTitlesReply.AgentData.GroupID = groupTitlesRequest.AgentData.GroupID;
  10194. groupTitlesReply.AgentData.RequestID = groupTitlesRequest.AgentData.RequestID;
  10195. List<GroupTitlesData> titles = m_GroupsModule.GroupTitlesRequest(this,
  10196. groupTitlesRequest.AgentData.GroupID);
  10197. groupTitlesReply.GroupData = new GroupTitlesReplyPacket.GroupDataBlock[titles.Count];
  10198. int i = 0;
  10199. foreach (GroupTitlesData d in titles)
  10200. {
  10201. groupTitlesReply.GroupData[i] = new GroupTitlesReplyPacket.GroupDataBlock();
  10202. groupTitlesReply.GroupData[i].Title = Util.StringToBytes256(d.Name);
  10203. groupTitlesReply.GroupData[i].RoleID = d.UUID;
  10204. groupTitlesReply.GroupData[i].Selected = d.Selected;
  10205. i++;
  10206. }
  10207. OutPacket(groupTitlesReply, ThrottleOutPacketType.Task);
  10208. }
  10209. UUID lastGroupProfileRequestID = UUID.Zero;
  10210. double lastGroupProfileRequestTS = Util.GetTimeStampMS();
  10211. private void HandleGroupProfileRequest(Packet Pack)
  10212. {
  10213. if(m_GroupsModule == null)
  10214. return;
  10215. GroupProfileRequestPacket groupProfileRequest = (GroupProfileRequestPacket)Pack;
  10216. if (groupProfileRequest.AgentData.SessionID.NotEqual(m_sessionId) || groupProfileRequest.AgentData.AgentID.NotEqual(m_agentId))
  10217. return;
  10218. UUID grpID = groupProfileRequest.GroupData.GroupID;
  10219. double ts = Util.GetTimeStampMS();
  10220. if(grpID == lastGroupProfileRequestID && ts - lastGroupProfileRequestTS < 10000)
  10221. return;
  10222. lastGroupProfileRequestID = grpID;
  10223. lastGroupProfileRequestTS = ts;
  10224. GroupProfileReplyPacket groupProfileReply = (GroupProfileReplyPacket)PacketPool.Instance.GetPacket(PacketType.GroupProfileReply);
  10225. groupProfileReply.AgentData = new GroupProfileReplyPacket.AgentDataBlock();
  10226. groupProfileReply.GroupData = new GroupProfileReplyPacket.GroupDataBlock();
  10227. groupProfileReply.AgentData.AgentID = m_agentId;
  10228. GroupProfileData d = m_GroupsModule.GroupProfileRequest(this, groupProfileRequest.GroupData.GroupID);
  10229. if(d.GroupID.IsZero()) // don't send broken data
  10230. return;
  10231. groupProfileReply.GroupData.GroupID = d.GroupID;
  10232. groupProfileReply.GroupData.Name = Util.StringToBytes256(d.Name);
  10233. groupProfileReply.GroupData.Charter = Util.StringToBytes1024(d.Charter);
  10234. groupProfileReply.GroupData.ShowInList = d.ShowInList;
  10235. groupProfileReply.GroupData.MemberTitle = Util.StringToBytes256(d.MemberTitle);
  10236. groupProfileReply.GroupData.PowersMask = d.PowersMask;
  10237. groupProfileReply.GroupData.InsigniaID = d.InsigniaID;
  10238. groupProfileReply.GroupData.FounderID = d.FounderID;
  10239. groupProfileReply.GroupData.MembershipFee = d.MembershipFee;
  10240. groupProfileReply.GroupData.OpenEnrollment = d.OpenEnrollment;
  10241. groupProfileReply.GroupData.Money = d.Money;
  10242. groupProfileReply.GroupData.GroupMembershipCount = d.GroupMembershipCount;
  10243. groupProfileReply.GroupData.GroupRolesCount = d.GroupRolesCount;
  10244. groupProfileReply.GroupData.AllowPublish = d.AllowPublish;
  10245. groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
  10246. groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
  10247. if (m_scene.Permissions.IsGod(m_agentId) && (!IsGroupMember(groupProfileRequest.GroupData.GroupID)))
  10248. {
  10249. ScenePresence p;
  10250. if (m_scene.TryGetScenePresence(m_agentId, out p))
  10251. {
  10252. if (p.IsViewerUIGod)
  10253. {
  10254. groupProfileReply.GroupData.OpenEnrollment = true;
  10255. groupProfileReply.GroupData.MembershipFee = 0;
  10256. }
  10257. }
  10258. }
  10259. OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
  10260. if(grpID == lastGroupProfileRequestID)
  10261. lastGroupProfileRequestTS = Util.GetTimeStampMS() - 7000;
  10262. }
  10263. private void HandleGroupMembersRequest(Packet Pack)
  10264. {
  10265. if (m_GroupsModule == null)
  10266. return;
  10267. GroupMembersRequestPacket groupMembersRequestPacket =
  10268. (GroupMembersRequestPacket)Pack;
  10269. if (groupMembersRequestPacket.AgentData.SessionID.NotEqual(m_sessionId) || groupMembersRequestPacket.AgentData.AgentID.NotEqual(m_agentId))
  10270. return;
  10271. List<GroupMembersData> members =
  10272. m_GroupsModule.GroupMembersRequest(this, groupMembersRequestPacket.GroupData.GroupID);
  10273. int memberCount = members.Count;
  10274. int indx = 0;
  10275. while (indx < memberCount)
  10276. {
  10277. int blockCount = memberCount - indx;
  10278. if (blockCount > 25)
  10279. blockCount = 25;
  10280. GroupMembersReplyPacket groupMembersReply = (GroupMembersReplyPacket)PacketPool.Instance.GetPacket(PacketType.GroupMembersReply);
  10281. groupMembersReply.AgentData = new GroupMembersReplyPacket.AgentDataBlock();
  10282. groupMembersReply.GroupData = new GroupMembersReplyPacket.GroupDataBlock();
  10283. groupMembersReply.MemberData = new GroupMembersReplyPacket.MemberDataBlock[blockCount];
  10284. groupMembersReply.AgentData.AgentID = m_agentId;
  10285. groupMembersReply.GroupData.GroupID = groupMembersRequestPacket.GroupData.GroupID;
  10286. groupMembersReply.GroupData.RequestID = groupMembersRequestPacket.GroupData.RequestID;
  10287. groupMembersReply.GroupData.MemberCount = memberCount;
  10288. for (int i = 0; i < blockCount; i++)
  10289. {
  10290. GroupMembersData m = members[indx++];
  10291. groupMembersReply.MemberData[i] = new GroupMembersReplyPacket.MemberDataBlock();
  10292. groupMembersReply.MemberData[i].AgentID = m.AgentID;
  10293. groupMembersReply.MemberData[i].Contribution = m.Contribution;
  10294. groupMembersReply.MemberData[i].OnlineStatus = Util.StringToBytes256(m.OnlineStatus);
  10295. groupMembersReply.MemberData[i].AgentPowers = m.AgentPowers;
  10296. groupMembersReply.MemberData[i].Title = Util.StringToBytes256(m.Title);
  10297. groupMembersReply.MemberData[i].IsOwner = m.IsOwner;
  10298. }
  10299. OutPacket(groupMembersReply, ThrottleOutPacketType.Task);
  10300. }
  10301. }
  10302. private void HandleGroupRoleDataRequest(Packet Pack)
  10303. {
  10304. if (m_GroupsModule == null)
  10305. return;
  10306. GroupRoleDataRequestPacket groupRolesRequest = (GroupRoleDataRequestPacket)Pack;
  10307. if (groupRolesRequest.AgentData.SessionID.NotEqual(m_sessionId) || groupRolesRequest.AgentData.AgentID.NotEqual(m_agentId))
  10308. return;
  10309. GroupRoleDataReplyPacket groupRolesReply = (GroupRoleDataReplyPacket)PacketPool.Instance.GetPacket(PacketType.GroupRoleDataReply);
  10310. groupRolesReply.AgentData = new GroupRoleDataReplyPacket.AgentDataBlock();
  10311. groupRolesReply.AgentData.AgentID = m_agentId;
  10312. groupRolesReply.GroupData = new GroupRoleDataReplyPacket.GroupDataBlock();
  10313. groupRolesReply.GroupData.GroupID = groupRolesRequest.GroupData.GroupID;
  10314. groupRolesReply.GroupData.RequestID = groupRolesRequest.GroupData.RequestID;
  10315. List<GroupRolesData> titles = m_GroupsModule.GroupRoleDataRequest(this,
  10316. groupRolesRequest.GroupData.GroupID);
  10317. groupRolesReply.GroupData.RoleCount = titles.Count;
  10318. groupRolesReply.RoleData = new GroupRoleDataReplyPacket.RoleDataBlock[titles.Count];
  10319. int i = 0;
  10320. foreach (GroupRolesData d in titles)
  10321. {
  10322. groupRolesReply.RoleData[i] = new GroupRoleDataReplyPacket.RoleDataBlock();
  10323. groupRolesReply.RoleData[i].RoleID = d.RoleID;
  10324. groupRolesReply.RoleData[i].Name = Util.StringToBytes256(d.Name);
  10325. groupRolesReply.RoleData[i].Title = Util.StringToBytes256(d.Title);
  10326. groupRolesReply.RoleData[i].Description = Util.StringToBytes1024(d.Description);
  10327. groupRolesReply.RoleData[i].Powers = d.Powers;
  10328. groupRolesReply.RoleData[i].Members = (uint)d.Members;
  10329. i++;
  10330. }
  10331. OutPacket(groupRolesReply, ThrottleOutPacketType.Task);
  10332. }
  10333. private void HandleGroupRoleMembersRequest(Packet Pack)
  10334. {
  10335. if (m_GroupsModule == null)
  10336. return;
  10337. GroupRoleMembersRequestPacket groupRoleMembersRequest = (GroupRoleMembersRequestPacket)Pack;
  10338. if (groupRoleMembersRequest.AgentData.SessionID.NotEqual(m_sessionId) || groupRoleMembersRequest.AgentData.AgentID.NotEqual(m_agentId))
  10339. return;
  10340. List<GroupRoleMembersData> mappings = m_GroupsModule.GroupRoleMembersRequest(this,
  10341. groupRoleMembersRequest.GroupData.GroupID);
  10342. int mappingsCount = mappings.Count;
  10343. while (mappings.Count > 0)
  10344. {
  10345. int pairs = mappings.Count;
  10346. if (pairs > 32)
  10347. pairs = 32;
  10348. GroupRoleMembersReplyPacket groupRoleMembersReply = (GroupRoleMembersReplyPacket)PacketPool.Instance.GetPacket(PacketType.GroupRoleMembersReply);
  10349. groupRoleMembersReply.AgentData = new GroupRoleMembersReplyPacket.AgentDataBlock();
  10350. groupRoleMembersReply.AgentData.AgentID = m_agentId;
  10351. groupRoleMembersReply.AgentData.GroupID = groupRoleMembersRequest.GroupData.GroupID;
  10352. groupRoleMembersReply.AgentData.RequestID = groupRoleMembersRequest.GroupData.RequestID;
  10353. groupRoleMembersReply.AgentData.TotalPairs = (uint)mappingsCount;
  10354. groupRoleMembersReply.MemberData = new GroupRoleMembersReplyPacket.MemberDataBlock[pairs];
  10355. for (int i = 0; i < pairs; i++)
  10356. {
  10357. GroupRoleMembersData d = mappings[0];
  10358. mappings.RemoveAt(0);
  10359. groupRoleMembersReply.MemberData[i] = new GroupRoleMembersReplyPacket.MemberDataBlock();
  10360. groupRoleMembersReply.MemberData[i].RoleID = d.RoleID;
  10361. groupRoleMembersReply.MemberData[i].MemberID = d.MemberID;
  10362. }
  10363. OutPacket(groupRoleMembersReply, ThrottleOutPacketType.Task);
  10364. }
  10365. }
  10366. private void HandleCreateGroupRequest(Packet Pack)
  10367. {
  10368. if (m_GroupsModule == null)
  10369. return;
  10370. CreateGroupRequestPacket createGroupRequest = (CreateGroupRequestPacket)Pack;
  10371. if (createGroupRequest.AgentData.SessionID.NotEqual(m_sessionId) || createGroupRequest.AgentData.AgentID.NotEqual(m_agentId))
  10372. return;
  10373. m_GroupsModule.CreateGroup(this,
  10374. Utils.BytesToString(createGroupRequest.GroupData.Name),
  10375. Utils.BytesToString(createGroupRequest.GroupData.Charter),
  10376. createGroupRequest.GroupData.ShowInList,
  10377. createGroupRequest.GroupData.InsigniaID,
  10378. createGroupRequest.GroupData.MembershipFee,
  10379. createGroupRequest.GroupData.OpenEnrollment,
  10380. createGroupRequest.GroupData.AllowPublish,
  10381. createGroupRequest.GroupData.MaturePublish);
  10382. }
  10383. private void HandleUpdateGroupInfo(Packet Pack)
  10384. {
  10385. if (m_GroupsModule == null)
  10386. return;
  10387. UpdateGroupInfoPacket updateGroupInfo = (UpdateGroupInfoPacket)Pack;
  10388. if (updateGroupInfo.AgentData.SessionID.NotEqual(m_sessionId) || updateGroupInfo.AgentData.AgentID.NotEqual(m_agentId))
  10389. return;
  10390. m_GroupsModule.UpdateGroupInfo(this,
  10391. updateGroupInfo.GroupData.GroupID,
  10392. Utils.BytesToString(updateGroupInfo.GroupData.Charter),
  10393. updateGroupInfo.GroupData.ShowInList,
  10394. updateGroupInfo.GroupData.InsigniaID,
  10395. updateGroupInfo.GroupData.MembershipFee,
  10396. updateGroupInfo.GroupData.OpenEnrollment,
  10397. updateGroupInfo.GroupData.AllowPublish,
  10398. updateGroupInfo.GroupData.MaturePublish);
  10399. }
  10400. private void HandleSetGroupAcceptNotices(Packet Pack)
  10401. {
  10402. if (m_GroupsModule == null)
  10403. return;
  10404. SetGroupAcceptNoticesPacket setGroupAcceptNotices = (SetGroupAcceptNoticesPacket)Pack;
  10405. if (setGroupAcceptNotices.AgentData.SessionID.NotEqual(m_sessionId) || setGroupAcceptNotices.AgentData.AgentID.NotEqual(m_agentId))
  10406. return;
  10407. m_GroupsModule.SetGroupAcceptNotices(this,
  10408. setGroupAcceptNotices.Data.GroupID,
  10409. setGroupAcceptNotices.Data.AcceptNotices,
  10410. setGroupAcceptNotices.NewData.ListInProfile);
  10411. }
  10412. private void HandleGroupTitleUpdate(Packet Pack)
  10413. {
  10414. GroupTitleUpdatePacket groupTitleUpdate = (GroupTitleUpdatePacket)Pack;
  10415. if (groupTitleUpdate.AgentData.SessionID.NotEqual(m_sessionId) || groupTitleUpdate.AgentData.AgentID.NotEqual(m_agentId))
  10416. return;
  10417. m_GroupsModule.GroupTitleUpdate(this,
  10418. groupTitleUpdate.AgentData.GroupID,
  10419. groupTitleUpdate.AgentData.TitleRoleID);
  10420. }
  10421. private void HandleParcelDeedToGroup(Packet Pack)
  10422. {
  10423. if (m_GroupsModule == null)
  10424. return;
  10425. ParcelDeedToGroupPacket parcelDeedToGroup = (ParcelDeedToGroupPacket)Pack;
  10426. if (parcelDeedToGroup.AgentData.SessionID.NotEqual(m_sessionId) || parcelDeedToGroup.AgentData.AgentID.NotEqual(m_agentId))
  10427. return;
  10428. OnParcelDeedToGroup?.Invoke(parcelDeedToGroup.Data.LocalID, parcelDeedToGroup.Data.GroupID, this);
  10429. }
  10430. private void HandleGroupNoticesListRequest(Packet Pack)
  10431. {
  10432. if (m_GroupsModule == null)
  10433. return;
  10434. GroupNoticesListRequestPacket groupNoticesListRequest = (GroupNoticesListRequestPacket)Pack;
  10435. if (groupNoticesListRequest.AgentData.SessionID.NotEqual(m_sessionId) || groupNoticesListRequest.AgentData.AgentID.NotEqual(m_agentId))
  10436. return;
  10437. GroupNoticeData[] gn = m_GroupsModule.GroupNoticesListRequest(this, groupNoticesListRequest.Data.GroupID);
  10438. GroupNoticesListReplyPacket groupNoticesListReply = (GroupNoticesListReplyPacket)PacketPool.Instance.GetPacket(PacketType.GroupNoticesListReply);
  10439. groupNoticesListReply.AgentData = new GroupNoticesListReplyPacket.AgentDataBlock();
  10440. groupNoticesListReply.AgentData.AgentID = m_agentId;
  10441. groupNoticesListReply.AgentData.GroupID = groupNoticesListRequest.Data.GroupID;
  10442. groupNoticesListReply.Data = new GroupNoticesListReplyPacket.DataBlock[gn.Length];
  10443. int i = 0;
  10444. foreach (GroupNoticeData g in gn)
  10445. {
  10446. groupNoticesListReply.Data[i] = new GroupNoticesListReplyPacket.DataBlock();
  10447. groupNoticesListReply.Data[i].NoticeID = g.NoticeID;
  10448. groupNoticesListReply.Data[i].Timestamp = g.Timestamp;
  10449. groupNoticesListReply.Data[i].FromName = Util.StringToBytes256(g.FromName);
  10450. groupNoticesListReply.Data[i].Subject = Util.StringToBytes256(g.Subject);
  10451. groupNoticesListReply.Data[i].HasAttachment = g.HasAttachment;
  10452. groupNoticesListReply.Data[i].AssetType = g.AssetType;
  10453. i++;
  10454. }
  10455. OutPacket(groupNoticesListReply, ThrottleOutPacketType.Task);
  10456. }
  10457. private void HandleGroupNoticeRequest(Packet Pack)
  10458. {
  10459. if (m_GroupsModule == null)
  10460. return;
  10461. GroupNoticeRequestPacket groupNoticeRequest = (GroupNoticeRequestPacket)Pack;
  10462. if (groupNoticeRequest.AgentData.SessionID.NotEqual(m_sessionId) || groupNoticeRequest.AgentData.AgentID.NotEqual(m_agentId))
  10463. return;
  10464. m_GroupsModule.GroupNoticeRequest(this, groupNoticeRequest.Data.GroupNoticeID);
  10465. }
  10466. private void HandleGroupRoleUpdate(Packet Pack)
  10467. {
  10468. if (m_GroupsModule == null)
  10469. return;
  10470. GroupRoleUpdatePacket groupRoleUpdate = (GroupRoleUpdatePacket)Pack;
  10471. if (groupRoleUpdate.AgentData.SessionID.NotEqual(m_sessionId) || groupRoleUpdate.AgentData.AgentID.NotEqual(m_agentId))
  10472. return;
  10473. foreach (GroupRoleUpdatePacket.RoleDataBlock d in groupRoleUpdate.RoleData)
  10474. {
  10475. m_GroupsModule.GroupRoleUpdate(this,
  10476. groupRoleUpdate.AgentData.GroupID,
  10477. d.RoleID,
  10478. Utils.BytesToString(d.Name),
  10479. Utils.BytesToString(d.Description),
  10480. Utils.BytesToString(d.Title),
  10481. d.Powers,
  10482. d.UpdateType);
  10483. }
  10484. m_GroupsModule.NotifyChange(groupRoleUpdate.AgentData.GroupID);
  10485. }
  10486. private void HandleGroupRoleChanges(Packet Pack)
  10487. {
  10488. if (m_GroupsModule == null)
  10489. return;
  10490. GroupRoleChangesPacket groupRoleChanges = (GroupRoleChangesPacket)Pack;
  10491. if (groupRoleChanges.AgentData.SessionID.NotEqual(m_sessionId) || groupRoleChanges.AgentData.AgentID.NotEqual(m_agentId))
  10492. return;
  10493. foreach (GroupRoleChangesPacket.RoleChangeBlock d in groupRoleChanges.RoleChange)
  10494. {
  10495. m_GroupsModule.GroupRoleChanges(this,
  10496. groupRoleChanges.AgentData.GroupID,
  10497. d.RoleID,
  10498. d.MemberID,
  10499. d.Change);
  10500. }
  10501. m_GroupsModule.NotifyChange(groupRoleChanges.AgentData.GroupID);
  10502. }
  10503. private void HandleJoinGroupRequest(Packet Pack)
  10504. {
  10505. if (m_GroupsModule == null)
  10506. return;
  10507. JoinGroupRequestPacket joinGroupRequest = (JoinGroupRequestPacket)Pack;
  10508. if (joinGroupRequest.AgentData.SessionID.NotEqual(m_sessionId) || joinGroupRequest.AgentData.AgentID.NotEqual(m_agentId))
  10509. return;
  10510. m_GroupsModule.JoinGroupRequest(this, joinGroupRequest.GroupData.GroupID);
  10511. }
  10512. private void HandleLeaveGroupRequest(Packet Pack)
  10513. {
  10514. if (m_GroupsModule == null)
  10515. return;
  10516. LeaveGroupRequestPacket leaveGroupRequest = (LeaveGroupRequestPacket)Pack;
  10517. if (leaveGroupRequest.AgentData.SessionID.NotEqual(m_sessionId) || leaveGroupRequest.AgentData.AgentID.NotEqual(m_agentId))
  10518. return;
  10519. m_GroupsModule.LeaveGroupRequest(this, leaveGroupRequest.GroupData.GroupID);
  10520. }
  10521. private void HandleEjectGroupMemberRequest(Packet Pack)
  10522. {
  10523. if (m_GroupsModule == null)
  10524. return;
  10525. EjectGroupMemberRequestPacket ejectGroupMemberRequest = (EjectGroupMemberRequestPacket)Pack;
  10526. if (ejectGroupMemberRequest.AgentData.SessionID.NotEqual(m_sessionId) || ejectGroupMemberRequest.AgentData.AgentID.NotEqual(m_agentId))
  10527. return;
  10528. foreach (EjectGroupMemberRequestPacket.EjectDataBlock e in ejectGroupMemberRequest.EjectData)
  10529. {
  10530. m_GroupsModule.EjectGroupMemberRequest(this,
  10531. ejectGroupMemberRequest.GroupData.GroupID,
  10532. e.EjecteeID);
  10533. }
  10534. }
  10535. private void HandleInviteGroupRequest(Packet Pack)
  10536. {
  10537. if (m_GroupsModule == null)
  10538. return;
  10539. InviteGroupRequestPacket inviteGroupRequest = (InviteGroupRequestPacket)Pack;
  10540. if (inviteGroupRequest.AgentData.SessionID.NotEqual(m_sessionId) || inviteGroupRequest.AgentData.AgentID.NotEqual(m_agentId))
  10541. return;
  10542. foreach (InviteGroupRequestPacket.InviteDataBlock b in inviteGroupRequest.InviteData)
  10543. {
  10544. m_GroupsModule.InviteGroupRequest(this,
  10545. inviteGroupRequest.GroupData.GroupID,
  10546. b.InviteeID,
  10547. b.RoleID);
  10548. }
  10549. }
  10550. #endregion Groups
  10551. private void HandleStartLure(Packet Pack)
  10552. {
  10553. if(OnStartLure == null)
  10554. return;
  10555. StartLurePacket startLureRequest = (StartLurePacket)Pack;
  10556. if (startLureRequest.AgentData.SessionID.NotEqual(m_sessionId) || startLureRequest.AgentData.AgentID.NotEqual(m_agentId))
  10557. return;
  10558. for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
  10559. {
  10560. OnStartLure?.Invoke(startLureRequest.Info.LureType,
  10561. Utils.BytesToString(
  10562. startLureRequest.Info.Message),
  10563. startLureRequest.TargetData[i].TargetID,
  10564. this);
  10565. }
  10566. }
  10567. private void HandleTeleportLureRequest(Packet Pack)
  10568. {
  10569. TeleportLureRequestPacket teleportLureRequest = (TeleportLureRequestPacket)Pack;
  10570. if (teleportLureRequest.Info.SessionID.NotEqual(m_sessionId) || teleportLureRequest.Info.AgentID.NotEqual(m_agentId))
  10571. return;
  10572. OnTeleportLureRequest?.Invoke(
  10573. teleportLureRequest.Info.LureID,
  10574. teleportLureRequest.Info.TeleportFlags,
  10575. this);
  10576. }
  10577. private void HandleClassifiedInfoRequest(Packet Pack)
  10578. {
  10579. ClassifiedInfoRequestPacket classifiedInfoRequest = (ClassifiedInfoRequestPacket)Pack;
  10580. if (classifiedInfoRequest.AgentData.SessionID.NotEqual(m_sessionId) || classifiedInfoRequest.AgentData.AgentID.NotEqual(m_agentId))
  10581. return;
  10582. OnClassifiedInfoRequest?.Invoke(
  10583. classifiedInfoRequest.Data.ClassifiedID,
  10584. this);
  10585. }
  10586. private void HandleClassifiedInfoUpdate(Packet Pack)
  10587. {
  10588. ClassifiedInfoUpdatePacket classifiedInfoUpdate = (ClassifiedInfoUpdatePacket)Pack;
  10589. if (classifiedInfoUpdate.AgentData.SessionID.NotEqual(m_sessionId) || classifiedInfoUpdate.AgentData.AgentID.NotEqual(m_agentId))
  10590. return;
  10591. // fix classifiedFlags maturity
  10592. byte classifiedFlags = classifiedInfoUpdate.Data.ClassifiedFlags;
  10593. if ((classifiedFlags & 0x4e) == 0) // if none
  10594. classifiedFlags |= 0x4; // pg
  10595. OnClassifiedInfoUpdate?.Invoke(
  10596. classifiedInfoUpdate.Data.ClassifiedID,
  10597. classifiedInfoUpdate.Data.Category,
  10598. Utils.BytesToString(
  10599. classifiedInfoUpdate.Data.Name),
  10600. Utils.BytesToString(
  10601. classifiedInfoUpdate.Data.Desc),
  10602. classifiedInfoUpdate.Data.ParcelID,
  10603. classifiedInfoUpdate.Data.ParentEstate,
  10604. classifiedInfoUpdate.Data.SnapshotID,
  10605. new Vector3(
  10606. classifiedInfoUpdate.Data.PosGlobal),
  10607. classifiedFlags,
  10608. classifiedInfoUpdate.Data.PriceForListing,
  10609. this);
  10610. }
  10611. private void HandleClassifiedDelete(Packet Pack)
  10612. {
  10613. ClassifiedDeletePacket classifiedDelete = (ClassifiedDeletePacket)Pack;
  10614. if (classifiedDelete.AgentData.SessionID.NotEqual(m_sessionId) || classifiedDelete.AgentData.AgentID.NotEqual(m_agentId))
  10615. return;
  10616. OnClassifiedDelete?.Invoke(
  10617. classifiedDelete.Data.ClassifiedID,
  10618. this);
  10619. }
  10620. private void HandleClassifiedGodDelete(Packet Pack)
  10621. {
  10622. ClassifiedGodDeletePacket classifiedGodDelete = (ClassifiedGodDeletePacket)Pack;
  10623. if (classifiedGodDelete.AgentData.SessionID.NotEqual(m_sessionId) || classifiedGodDelete.AgentData.AgentID.NotEqual(m_agentId))
  10624. return;
  10625. OnClassifiedGodDelete?.Invoke(
  10626. classifiedGodDelete.Data.ClassifiedID,
  10627. classifiedGodDelete.Data.QueryID,
  10628. this);
  10629. }
  10630. private void HandleEventGodDelete(Packet Pack)
  10631. {
  10632. EventGodDeletePacket eventGodDelete = (EventGodDeletePacket)Pack;
  10633. if (eventGodDelete.AgentData.SessionID.NotEqual(m_sessionId) || eventGodDelete.AgentData.AgentID.NotEqual(m_agentId))
  10634. return;
  10635. OnEventGodDelete?.Invoke(
  10636. eventGodDelete.EventData.EventID,
  10637. eventGodDelete.QueryData.QueryID,
  10638. Utils.BytesToString(
  10639. eventGodDelete.QueryData.QueryText),
  10640. eventGodDelete.QueryData.QueryFlags,
  10641. eventGodDelete.QueryData.QueryStart,
  10642. this);
  10643. }
  10644. private void HandleEventNotificationAddRequest(Packet Pack)
  10645. {
  10646. EventNotificationAddRequestPacket eventNotificationAdd = (EventNotificationAddRequestPacket)Pack;
  10647. if (eventNotificationAdd.AgentData.SessionID.NotEqual(m_sessionId) || eventNotificationAdd.AgentData.AgentID.NotEqual(m_agentId))
  10648. return;
  10649. OnEventNotificationAddRequest?.Invoke(eventNotificationAdd.EventData.EventID, this);
  10650. }
  10651. private void HandleEventNotificationRemoveRequest(Packet Pack)
  10652. {
  10653. EventNotificationRemoveRequestPacket eventNotificationRemove = (EventNotificationRemoveRequestPacket)Pack;
  10654. if (eventNotificationRemove.AgentData.SessionID.NotEqual(m_sessionId) || eventNotificationRemove.AgentData.AgentID.NotEqual(m_agentId))
  10655. return;
  10656. OnEventNotificationRemoveRequest?.Invoke(eventNotificationRemove.EventData.EventID, this);
  10657. }
  10658. private void HandleRetrieveInstantMessages(Packet Pack)
  10659. {
  10660. RetrieveInstantMessagesPacket rimpInstantMessagePack = (RetrieveInstantMessagesPacket)Pack;
  10661. if (rimpInstantMessagePack.AgentData.SessionID.NotEqual(m_sessionId) || rimpInstantMessagePack.AgentData.AgentID.NotEqual(m_agentId))
  10662. return;
  10663. OnRetrieveInstantMessages?.Invoke(this);
  10664. }
  10665. private void HandlePickDelete(Packet Pack)
  10666. {
  10667. PickDeletePacket pickDelete = (PickDeletePacket)Pack;
  10668. if (pickDelete.AgentData.SessionID.NotEqual(m_sessionId) || pickDelete.AgentData.AgentID.NotEqual(m_agentId))
  10669. return;
  10670. OnPickDelete?.Invoke(this, pickDelete.Data.PickID);
  10671. }
  10672. private void HandlePickGodDelete(Packet Pack)
  10673. {
  10674. PickGodDeletePacket pickGodDelete = (PickGodDeletePacket)Pack;
  10675. if (pickGodDelete.AgentData.SessionID.NotEqual(m_sessionId) || pickGodDelete.AgentData.AgentID.NotEqual(m_agentId))
  10676. return;
  10677. OnPickGodDelete?.Invoke(this,
  10678. pickGodDelete.AgentData.AgentID,
  10679. pickGodDelete.Data.PickID,
  10680. pickGodDelete.Data.QueryID);
  10681. }
  10682. private void HandlePickInfoUpdate(Packet Pack)
  10683. {
  10684. PickInfoUpdatePacket pickInfoUpdate = (PickInfoUpdatePacket)Pack;
  10685. if (pickInfoUpdate.AgentData.SessionID.NotEqual(m_sessionId) || pickInfoUpdate.AgentData.AgentID.NotEqual(m_agentId))
  10686. return;
  10687. OnPickInfoUpdate?.Invoke(this,
  10688. pickInfoUpdate.Data.PickID,
  10689. pickInfoUpdate.Data.CreatorID,
  10690. pickInfoUpdate.Data.TopPick,
  10691. Utils.BytesToString(pickInfoUpdate.Data.Name),
  10692. Utils.BytesToString(pickInfoUpdate.Data.Desc),
  10693. pickInfoUpdate.Data.SnapshotID,
  10694. pickInfoUpdate.Data.SortOrder,
  10695. pickInfoUpdate.Data.Enabled);
  10696. }
  10697. private void HandleAvatarNotesUpdate(Packet Pack)
  10698. {
  10699. AvatarNotesUpdatePacket avatarNotesUpdate = (AvatarNotesUpdatePacket)Pack;
  10700. if (avatarNotesUpdate.AgentData.SessionID.NotEqual(m_sessionId) || avatarNotesUpdate.AgentData.AgentID.NotEqual(m_agentId))
  10701. return;
  10702. OnAvatarNotesUpdate?.Invoke(this,
  10703. avatarNotesUpdate.Data.TargetID,
  10704. Utils.BytesToString(avatarNotesUpdate.Data.Notes));
  10705. }
  10706. private void HandleAvatarInterestsUpdate(Packet Pack)
  10707. {
  10708. AvatarInterestsUpdatePacket avatarInterestUpdate = (AvatarInterestsUpdatePacket)Pack;
  10709. if (avatarInterestUpdate.AgentData.SessionID.NotEqual(m_sessionId) || avatarInterestUpdate.AgentData.AgentID.NotEqual(m_agentId))
  10710. return;
  10711. OnAvatarInterestUpdate?.Invoke(this,
  10712. avatarInterestUpdate.PropertiesData.WantToMask,
  10713. Utils.BytesToString(avatarInterestUpdate.PropertiesData.WantToText),
  10714. avatarInterestUpdate.PropertiesData.SkillsMask,
  10715. Utils.BytesToString(avatarInterestUpdate.PropertiesData.SkillsText),
  10716. Utils.BytesToString(avatarInterestUpdate.PropertiesData.LanguagesText));
  10717. }
  10718. private void HandleGrantUserRights(Packet Pack)
  10719. {
  10720. GrantUserRightsPacket GrantUserRights = (GrantUserRightsPacket)Pack;
  10721. if (GrantUserRights.AgentData.SessionID.NotEqual(m_sessionId) || GrantUserRights.AgentData.AgentID.NotEqual(m_agentId))
  10722. return;
  10723. OnGrantUserRights?.Invoke(this,
  10724. GrantUserRights.Rights[0].AgentRelated,
  10725. GrantUserRights.Rights[0].RelatedRights);
  10726. }
  10727. private double m_nextRevokePermissionsTime = Double.MinValue;
  10728. private uint m_lastRevokePermissionsSeq = uint.MinValue;
  10729. private void HandleRevokePermissions(Packet Pack)
  10730. {
  10731. RevokePermissionsPacket pkt = (RevokePermissionsPacket)Pack;
  10732. if (pkt.AgentData.SessionID.NotEqual(m_sessionId) || pkt .AgentData.AgentID.NotEqual(m_agentId))
  10733. return;
  10734. uint thisSeq = pkt.Header.Sequence;
  10735. if (thisSeq == m_lastRevokePermissionsSeq)
  10736. return;
  10737. m_lastRevokePermissionsSeq = thisSeq;
  10738. ScenePresence sp = (ScenePresence)SceneAgent;
  10739. if(sp != null && !sp.IsDeleted && !sp.IsInTransit)
  10740. {
  10741. UUID objectID = pkt.Data.ObjectID;
  10742. double now = Util.GetTimeStampMS();
  10743. if (now < m_nextRevokePermissionsTime)
  10744. return;
  10745. if (objectID == m_scene.RegionInfo.RegionID)
  10746. m_nextRevokePermissionsTime = now + 2000;
  10747. else
  10748. m_nextRevokePermissionsTime = now + 50;
  10749. uint permissions = pkt.Data.ObjectPermissions;
  10750. sp.HandleRevokePermissions(objectID , permissions);
  10751. }
  10752. }
  10753. private void HandlePlacesQuery(Packet Pack)
  10754. {
  10755. PlacesQueryPacket placesQueryPacket = (PlacesQueryPacket)Pack;
  10756. if (placesQueryPacket.AgentData.SessionID.NotEqual(m_sessionId) || placesQueryPacket.AgentData.AgentID.NotEqual(m_agentId))
  10757. return;
  10758. OnPlacesQuery?.Invoke(placesQueryPacket.AgentData.QueryID,
  10759. placesQueryPacket.TransactionData.TransactionID,
  10760. Utils.BytesToString(
  10761. placesQueryPacket.QueryData.QueryText),
  10762. placesQueryPacket.QueryData.QueryFlags,
  10763. (byte)placesQueryPacket.QueryData.Category,
  10764. Utils.BytesToString(
  10765. placesQueryPacket.QueryData.SimName),
  10766. this);
  10767. }
  10768. #endregion Packet Handlers
  10769. public void SendScriptQuestion(UUID taskID, string taskName, string ownerName, UUID itemID, int question)
  10770. {
  10771. ScriptQuestionPacket scriptQuestion = (ScriptQuestionPacket)PacketPool.Instance.GetPacket(PacketType.ScriptQuestion);
  10772. scriptQuestion.Data = new ScriptQuestionPacket.DataBlock();
  10773. // TODO: don't create new blocks if recycling an old packet
  10774. scriptQuestion.Data.TaskID = taskID;
  10775. scriptQuestion.Data.ItemID = itemID;
  10776. scriptQuestion.Data.Questions = question;
  10777. scriptQuestion.Data.ObjectName = Util.StringToBytes256(taskName);
  10778. scriptQuestion.Data.ObjectOwner = Util.StringToBytes256(ownerName);
  10779. OutPacket(scriptQuestion, ThrottleOutPacketType.Task);
  10780. }
  10781. /// <summary>
  10782. /// Handler called when we receive a logout packet.
  10783. /// </summary>
  10784. /// <param name="client"></param>
  10785. /// <param name="packet"></param>
  10786. /// <returns></returns>
  10787. protected virtual void HandleLogout(Packet packet)
  10788. {
  10789. if (packet.Type == PacketType.LogoutRequest)
  10790. {
  10791. if (((LogoutRequestPacket)packet).AgentData.SessionID.NotEqual(m_sessionId))
  10792. return;
  10793. }
  10794. Logout(this);
  10795. }
  10796. /// <summary>
  10797. ///
  10798. /// </summary>
  10799. /// <param name="client"></param>
  10800. /// <returns></returns>
  10801. protected virtual void Logout(IClientAPI client)
  10802. {
  10803. m_log.InfoFormat("[CLIENT]: Got a logout request for {0} in {1}", Name, Scene.RegionInfo.RegionName);
  10804. OnLogout?.Invoke(client);
  10805. }
  10806. /// <summary>
  10807. /// </summary>
  10808. /// <remarks>
  10809. /// At the moment, we always reply that there is no cached texture.
  10810. /// </remarks>
  10811. /// <param name="simclient"></param>
  10812. /// <param name="packet"></param>
  10813. /// <returns></returns>
  10814. protected void HandleAgentTextureCached(Packet packet)
  10815. {
  10816. //m_log.Debug("texture cached: " + packet.ToString());
  10817. AgentCachedTexturePacket cachedtex = (AgentCachedTexturePacket)packet;
  10818. AgentCachedTextureResponsePacket cachedresp =
  10819. (AgentCachedTextureResponsePacket)PacketPool.Instance.GetPacket(PacketType.AgentCachedTextureResponse);
  10820. if (cachedtex.AgentData.SessionID.NotEqual(m_sessionId) || cachedtex.AgentData.AgentID.NotEqual(m_agentId))
  10821. return;
  10822. cachedresp.AgentData.AgentID = m_agentId;
  10823. cachedresp.AgentData.SessionID = m_sessionId;
  10824. cachedresp.AgentData.SerialNum = cachedtex.AgentData.SerialNum;
  10825. cachedresp.WearableData = new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length];
  10826. int cacheHits = 0;
  10827. // We need to make sure the asset stored in the bake is available on this server also by it's assetid before we map it to a Cacheid
  10828. WearableCacheItem[] cacheItems = null;
  10829. ScenePresence p = m_scene.GetScenePresence(m_agentId);
  10830. if (p != null && p.Appearance != null)
  10831. {
  10832. cacheItems = p.Appearance.WearableCacheItems;
  10833. }
  10834. int maxWearablesLoop = cachedtex.WearableData.Length;
  10835. if (cacheItems != null)
  10836. {
  10837. if (maxWearablesLoop > cacheItems.Length)
  10838. maxWearablesLoop = cacheItems.Length;
  10839. for (int i = 0; i < maxWearablesLoop; i++)
  10840. {
  10841. var checkdWear = cachedtex.WearableData[i];
  10842. int idx = checkdWear.TextureIndex;
  10843. var respWear = new AgentCachedTextureResponsePacket.WearableDataBlock()
  10844. {
  10845. TextureIndex = (byte)idx,
  10846. HostName = Array.Empty<byte>()
  10847. };
  10848. if (checkdWear.ID.Equals(cacheItems[idx].CacheId))
  10849. {
  10850. respWear.TextureID = cacheItems[idx].TextureID;
  10851. cacheHits++;
  10852. }
  10853. else
  10854. {
  10855. respWear.TextureID = UUID.Zero;
  10856. }
  10857. cachedresp.WearableData[i] = respWear;
  10858. }
  10859. }
  10860. else
  10861. {
  10862. for (int i = 0; i < maxWearablesLoop; i++)
  10863. {
  10864. var newWear = new AgentCachedTextureResponsePacket.WearableDataBlock()
  10865. {
  10866. TextureIndex = cachedtex.WearableData[i].TextureIndex,
  10867. TextureID = UUID.Zero,
  10868. HostName = Array.Empty<byte>()
  10869. };
  10870. cachedresp.WearableData[i] = newWear;
  10871. }
  10872. }
  10873. //m_log.DebugFormat("texture cached: hits {0}", cacheHits);
  10874. cachedresp.Header.Zerocoded = true;
  10875. OutPacket(cachedresp, ThrottleOutPacketType.Task);
  10876. }
  10877. /// <summary>
  10878. /// Send a response back to a client when it asks the asset server (via the region server) if it has
  10879. /// its appearance texture cached.
  10880. /// </summary>
  10881. /// <param name="avatar"></param>
  10882. /// <param name="serial"></param>
  10883. /// <param name="cachedTextures"></param>
  10884. /// <returns></returns>
  10885. public void SendCachedTextureResponse(ISceneEntity avatar, int serial, List<CachedTextureResponseArg> cachedTextures)
  10886. {
  10887. ScenePresence presence = avatar as ScenePresence;
  10888. if (presence == null)
  10889. return;
  10890. AgentCachedTextureResponsePacket cachedresp = (AgentCachedTextureResponsePacket)PacketPool.Instance.GetPacket(PacketType.AgentCachedTextureResponse);
  10891. // TODO: don't create new blocks if recycling an old packet
  10892. cachedresp.AgentData.AgentID = m_agentId;
  10893. cachedresp.AgentData.SessionID = m_sessionId;
  10894. cachedresp.AgentData.SerialNum = serial;
  10895. cachedresp.WearableData = new AgentCachedTextureResponsePacket.WearableDataBlock[cachedTextures.Count];
  10896. for (int i = 0; i < cachedTextures.Count; i++)
  10897. {
  10898. cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
  10899. cachedresp.WearableData[i].TextureIndex = (byte)cachedTextures[i].BakedTextureIndex;
  10900. cachedresp.WearableData[i].TextureID = cachedTextures[i].BakedTextureID;
  10901. cachedresp.WearableData[i].HostName = Array.Empty<byte>();
  10902. }
  10903. cachedresp.Header.Zerocoded = true;
  10904. OutPacket(cachedresp, ThrottleOutPacketType.Task);
  10905. }
  10906. protected void HandleMultipleObjUpdate(Packet packet)
  10907. {
  10908. MultipleObjectUpdatePacket multipleupdate = (MultipleObjectUpdatePacket)packet;
  10909. if (multipleupdate.AgentData.SessionID.NotEqual(m_sessionId) || multipleupdate.AgentData.AgentID.NotEqual(m_agentId))
  10910. return;
  10911. // m_log.DebugFormat(
  10912. // "[CLIENT]: Incoming MultipleObjectUpdatePacket contained {0} blocks", multipleupdate.ObjectData.Length);
  10913. Scene tScene = (Scene)m_scene;
  10914. for (int i = 0; i < multipleupdate.ObjectData.Length; i++)
  10915. {
  10916. MultipleObjectUpdatePacket.ObjectDataBlock block = multipleupdate.ObjectData[i];
  10917. // Can't act on Null Data
  10918. if (block.Data != null)
  10919. {
  10920. uint localId = block.ObjectLocalID;
  10921. SceneObjectPart part = tScene.GetSceneObjectPart(localId);
  10922. if (part == null)
  10923. {
  10924. // It's a ghost! tell the client to delete it from view.
  10925. SendKillObject(new List<uint> { localId });
  10926. }
  10927. else
  10928. {
  10929. ClientChangeObject updatehandler = onClientChangeObject;
  10930. if (updatehandler != null)
  10931. {
  10932. ObjectChangeData udata = new ObjectChangeData();
  10933. /*ubit from ll JIRA:
  10934. * 0x01 position
  10935. * 0x02 rotation
  10936. * 0x04 scale
  10937. * 0x08 LINK_SET
  10938. * 0x10 UNIFORM for scale
  10939. */
  10940. // translate to internal changes
  10941. // not all cases .. just the ones older code did
  10942. switch (block.Type)
  10943. {
  10944. case 1: //change position sp
  10945. udata.position = new Vector3(block.Data, 0);
  10946. udata.change = ObjectChangeType.primP;
  10947. updatehandler(localId, udata, this);
  10948. break;
  10949. case 2: // rotation sp
  10950. udata.rotation = new Quaternion(block.Data, 0, true);
  10951. udata.change = ObjectChangeType.primR;
  10952. updatehandler(localId, udata, this);
  10953. break;
  10954. case 3: // position plus rotation
  10955. udata.position = new Vector3(block.Data, 0);
  10956. udata.rotation = new Quaternion(block.Data, 12, true);
  10957. udata.change = ObjectChangeType.primPR;
  10958. updatehandler(localId, udata, this);
  10959. break;
  10960. case 4: // scale sp
  10961. udata.scale = new Vector3(block.Data, 0);
  10962. udata.change = ObjectChangeType.primS;
  10963. updatehandler(localId, udata, this);
  10964. break;
  10965. case 0x14: // uniform scale sp
  10966. udata.scale = new Vector3(block.Data, 0);
  10967. udata.change = ObjectChangeType.primUS;
  10968. updatehandler(localId, udata, this);
  10969. break;
  10970. case 5: // scale and position sp
  10971. udata.position = new Vector3(block.Data, 0);
  10972. udata.scale = new Vector3(block.Data, 12);
  10973. udata.change = ObjectChangeType.primPS;
  10974. updatehandler(localId, udata, this);
  10975. break;
  10976. case 0x15: //uniform scale and position
  10977. udata.position = new Vector3(block.Data, 0);
  10978. udata.scale = new Vector3(block.Data, 12);
  10979. udata.change = ObjectChangeType.primPUS;
  10980. updatehandler(localId, udata, this);
  10981. break;
  10982. // now group related (bit 4)
  10983. case 9: //( 8 + 1 )group position
  10984. udata.position = new Vector3(block.Data, 0);
  10985. udata.change = ObjectChangeType.groupP;
  10986. updatehandler(localId, udata, this);
  10987. break;
  10988. case 0x0A: // (8 + 2) group rotation
  10989. udata.rotation = new Quaternion(block.Data, 0, true);
  10990. udata.change = ObjectChangeType.groupR;
  10991. updatehandler(localId, udata, this);
  10992. break;
  10993. case 0x0B: //( 8 + 2 + 1) group rotation and position
  10994. udata.position = new Vector3(block.Data, 0);
  10995. udata.rotation = new Quaternion(block.Data, 12, true);
  10996. udata.change = ObjectChangeType.groupPR;
  10997. updatehandler(localId, udata, this);
  10998. break;
  10999. case 0x0C: // (8 + 4) group scale
  11000. // only afects root prim and only sent by viewer editor object tab scaling
  11001. // mouse edition only allows uniform scaling
  11002. // SL MAY CHANGE THIS in viewers
  11003. udata.scale = new Vector3(block.Data, 0);
  11004. udata.change = ObjectChangeType.groupS;
  11005. updatehandler(localId, udata, this);
  11006. break;
  11007. case 0x0D: //(8 + 4 + 1) group scale and position
  11008. // exception as above
  11009. udata.position = new Vector3(block.Data, 0);
  11010. udata.scale = new Vector3(block.Data, 12);
  11011. udata.change = ObjectChangeType.groupPS;
  11012. updatehandler(localId, udata, this);
  11013. break;
  11014. case 0x1C: // (0x10 + 8 + 4 ) group scale UNIFORM
  11015. udata.scale = new Vector3(block.Data, 0);
  11016. udata.change = ObjectChangeType.groupUS;
  11017. updatehandler(localId, udata, this);
  11018. break;
  11019. case 0x1D: // (UNIFORM + GROUP + SCALE + POS)
  11020. udata.position = new Vector3(block.Data, 0);
  11021. udata.scale = new Vector3(block.Data, 12);
  11022. udata.change = ObjectChangeType.groupPUS;
  11023. updatehandler(localId, udata, this);
  11024. break;
  11025. default:
  11026. m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type));
  11027. break;
  11028. }
  11029. }
  11030. }
  11031. }
  11032. }
  11033. }
  11034. public void RequestMapLayer()
  11035. {
  11036. //should be getting the map layer from the grid server
  11037. //send a layer covering the 800,800 - 1200,1200 area (should be covering the requested area)
  11038. MapLayerReplyPacket mapReply = (MapLayerReplyPacket)PacketPool.Instance.GetPacket(PacketType.MapLayerReply);
  11039. // TODO: don't create new blocks if recycling an old packet
  11040. mapReply.AgentData.AgentID = m_agentId;
  11041. mapReply.AgentData.Flags = 0;
  11042. mapReply.LayerData = new MapLayerReplyPacket.LayerDataBlock[1];
  11043. mapReply.LayerData[0] = new MapLayerReplyPacket.LayerDataBlock();
  11044. mapReply.LayerData[0].Bottom = 0;
  11045. mapReply.LayerData[0].Left = 0;
  11046. mapReply.LayerData[0].Top = 30000;
  11047. mapReply.LayerData[0].Right = 30000;
  11048. mapReply.LayerData[0].ImageID = new UUID("00000000-0000-1111-9999-000000000006");
  11049. mapReply.Header.Zerocoded = true;
  11050. OutPacket(mapReply, ThrottleOutPacketType.Land);
  11051. }
  11052. public void RequestMapBlocksX(int minX, int minY, int maxX, int maxY)
  11053. {
  11054. /*
  11055. IList simMapProfiles = m_gridServer.RequestMapBlocks(minX, minY, maxX, maxY);
  11056. MapBlockReplyPacket mbReply = new MapBlockReplyPacket();
  11057. mbReply.AgentData.AgentId = m_agentId;
  11058. int len;
  11059. if (simMapProfiles == null)
  11060. len = 0;
  11061. else
  11062. len = simMapProfiles.Count;
  11063. mbReply.Data = new MapBlockReplyPacket.DataBlock[len];
  11064. int iii;
  11065. for (iii = 0; iii < len; iii++)
  11066. {
  11067. Hashtable mp = (Hashtable)simMapProfiles[iii];
  11068. mbReply.Data[iii] = new MapBlockReplyPacket.DataBlock();
  11069. mbReply.Data[iii].Name = Util.UTF8.GetBytes((string)mp["name"]);
  11070. mbReply.Data[iii].Access = System.Convert.ToByte(mp["access"]);
  11071. mbReply.Data[iii].Agents = System.Convert.ToByte(mp["agents"]);
  11072. mbReply.Data[iii].MapImageID = new UUID((string)mp["map-image-id"]);
  11073. mbReply.Data[iii].RegionFlags = System.Convert.ToUInt32(mp["region-flags"]);
  11074. mbReply.Data[iii].WaterHeight = System.Convert.ToByte(mp["water-height"]);
  11075. mbReply.Data[iii].X = System.Convert.ToUInt16(mp["x"]);
  11076. mbReply.Data[iii].Y = System.Convert.ToUInt16(mp["y"]);
  11077. }
  11078. this.OutPacket(mbReply, ThrottleOutPacketType.Land);
  11079. */
  11080. }
  11081. /// <summary>
  11082. /// Sets the throttles from values supplied by the client
  11083. /// </summary>
  11084. /// <param name="throttles"></param>
  11085. public void SetChildAgentThrottle(byte[] throttles)
  11086. {
  11087. SetChildAgentThrottle(throttles, 1.0f);
  11088. }
  11089. public void SetChildAgentThrottle(byte[] throttles,float factor)
  11090. {
  11091. m_udpClient.SetThrottles(throttles, factor);
  11092. GenericCall2 handler = OnUpdateThrottles;
  11093. if (handler != null)
  11094. {
  11095. handler();
  11096. }
  11097. }
  11098. /// <summary>
  11099. /// Sets the throttles from values supplied caller
  11100. /// </summary>
  11101. /// <param name="throttles"></param>
  11102. public void SetAgentThrottleSilent(int throttle, int setting)
  11103. {
  11104. m_udpClient.ForceThrottleSetting(throttle,setting);
  11105. }
  11106. public int GetAgentThrottleSilent(int throttle)
  11107. {
  11108. return m_udpClient.GetThrottleSetting(throttle);
  11109. }
  11110. /// <summary>
  11111. /// Get the current throttles for this client as a packed byte array
  11112. /// </summary>
  11113. /// <param name="multiplier">Unused</param>
  11114. /// <returns></returns>
  11115. public byte[] GetThrottlesPacked(float multiplier)
  11116. {
  11117. return m_udpClient.GetThrottlesPacked(multiplier);
  11118. }
  11119. /// <summary>
  11120. /// Cruft?
  11121. /// </summary>
  11122. public virtual void InPacket(object NewPack)
  11123. {
  11124. throw new NotImplementedException();
  11125. }
  11126. /// <summary>
  11127. /// This is the starting point for sending a simulator packet out to the client
  11128. /// </summary>
  11129. /// <param name="packet">Packet to send</param>
  11130. /// <param name="throttlePacketType">Throttling category for the packet</param>
  11131. protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType)
  11132. {
  11133. #region BinaryStats
  11134. LLUDPServer.LogPacketHeader(false, m_circuitCode, 0, packet.Type, (ushort)packet.Length);
  11135. #endregion BinaryStats
  11136. OutPacket(packet, throttlePacketType, true, null);
  11137. }
  11138. /// <summary>
  11139. /// This is the starting point for sending a simulator packet out to the client
  11140. /// </summary>
  11141. /// <param name="packet">Packet to send</param>
  11142. /// <param name="throttlePacketType">Throttling category for the packet</param>
  11143. /// <param name="doAutomaticSplitting">True to automatically split oversized
  11144. /// packets (the default), or false to disable splitting if the calling code
  11145. /// handles splitting manually</param>
  11146. protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting)
  11147. {
  11148. OutPacket(packet, throttlePacketType, doAutomaticSplitting, null);
  11149. }
  11150. /// <summary>
  11151. /// This is the starting point for sending a simulator packet out to the client
  11152. /// </summary>
  11153. /// <param name="packet">Packet to send</param>
  11154. /// <param name="throttlePacketType">Throttling category for the packet</param>
  11155. /// <param name="doAutomaticSplitting">True to automatically split oversized
  11156. /// packets (the default), or false to disable splitting if the calling code
  11157. /// handles splitting manually</param>
  11158. /// <param name="method">The method to be called in the event this packet is reliable
  11159. /// and unacknowledged. The server will provide normal resend capability if you do not
  11160. /// provide your own method.</param>
  11161. protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting, UnackedPacketMethod method)
  11162. {
  11163. if (m_outPacketsToDrop != null)
  11164. {
  11165. if (m_outPacketsToDrop.Contains(packet.Type.ToString()))
  11166. {
  11167. PacketPool.Instance.ReturnPacket(packet);
  11168. return;
  11169. }
  11170. }
  11171. if (DebugPacketLevel > 0)
  11172. {
  11173. bool logPacket = true;
  11174. if (DebugPacketLevel <= 255
  11175. && (packet.Type == PacketType.SimStats || packet.Type == PacketType.SimulatorViewerTimeMessage))
  11176. logPacket = false;
  11177. if (DebugPacketLevel <= 200
  11178. && (packet.Type == PacketType.ImagePacket
  11179. || packet.Type == PacketType.ImageData
  11180. || packet.Type == PacketType.LayerData
  11181. || packet.Type == PacketType.CoarseLocationUpdate))
  11182. logPacket = false;
  11183. if (DebugPacketLevel <= 100 && (packet.Type == PacketType.AvatarAnimation || packet.Type == PacketType.ViewerEffect))
  11184. logPacket = false;
  11185. if (DebugPacketLevel <= 50
  11186. && (packet.Type == PacketType.ImprovedTerseObjectUpdate || packet.Type == PacketType.ObjectUpdate))
  11187. logPacket = false;
  11188. if (DebugPacketLevel <= 25 && packet.Type == PacketType.ObjectPropertiesFamily)
  11189. logPacket = false;
  11190. if (logPacket)
  11191. m_log.DebugFormat(
  11192. "[CLIENT]: PACKET OUT to {0} ({1}) in {2} - {3}",
  11193. Name, SceneAgent.IsChildAgent ? "child" : "root ", m_scene.RegionInfo.RegionName, packet.Type);
  11194. }
  11195. m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, doAutomaticSplitting, method);
  11196. }
  11197. protected void HandleAutopilot(Object sender, string method, List<String> args)
  11198. {
  11199. if(OnAutoPilotGo == null)
  11200. return;
  11201. float locx = 0;
  11202. float locy = 0;
  11203. float locz = 0;
  11204. uint regionX = 0;
  11205. uint regionY = 0;
  11206. Utils.LongToUInts(m_scene.RegionInfo.RegionHandle, out regionX, out regionY);
  11207. locx = (float)(Convert.ToDouble(args[0]) - (double)regionX);
  11208. locy = (float)(Convert.ToDouble(args[1]) - (double)regionY);
  11209. locz = Convert.ToSingle(args[2]);
  11210. OnAutoPilotGo?.Invoke(new Vector3(locx, locy, locz), false, true);
  11211. }
  11212. /// <summary>
  11213. /// Entryway from the client to the simulator. All UDP packets from the client will end up here
  11214. /// </summary>
  11215. /// <param name="Pack">OpenMetaverse.packet</param>
  11216. public void ProcessInPacket(Packet packet)
  11217. {
  11218. if (m_inPacketsToDrop != null)
  11219. if (m_inPacketsToDrop.Contains(packet.Type.ToString()))
  11220. return;
  11221. if (DebugPacketLevel > 0)
  11222. {
  11223. bool logPacket = true;
  11224. if (DebugPacketLevel <= 255 && packet.Type == PacketType.AgentUpdate)
  11225. logPacket = false;
  11226. if (DebugPacketLevel <= 200 && packet.Type == PacketType.RequestImage)
  11227. logPacket = false;
  11228. if (DebugPacketLevel <= 100 && (packet.Type == PacketType.ViewerEffect || packet.Type == PacketType.AgentAnimation))
  11229. logPacket = false;
  11230. if (DebugPacketLevel <= 25 && packet.Type == PacketType.RequestObjectPropertiesFamily)
  11231. logPacket = false;
  11232. if (logPacket)
  11233. m_log.DebugFormat(
  11234. "[CLIENT]: PACKET IN from {0} ({1}) in {2} - {3}",
  11235. Name, SceneAgent.IsChildAgent ? "child" : "root ", Scene.Name, packet.Type);
  11236. }
  11237. if (!ProcessPacketMethod(packet))
  11238. m_log.WarnFormat(
  11239. "[CLIENT]: Unhandled packet {0} from {1} ({2}) in {3}. Ignoring.",
  11240. packet.Type, Name, SceneAgent.IsChildAgent ? "child" : "root ", Scene.Name);
  11241. }
  11242. private static PrimitiveBaseShape GetShapeFromAddPacket(ObjectAddPacket addPacket)
  11243. {
  11244. PrimitiveBaseShape shape = new PrimitiveBaseShape();
  11245. shape.PCode = addPacket.ObjectData.PCode;
  11246. shape.State = addPacket.ObjectData.State;
  11247. shape.LastAttachPoint = addPacket.ObjectData.State;
  11248. shape.PathBegin = addPacket.ObjectData.PathBegin;
  11249. shape.PathEnd = addPacket.ObjectData.PathEnd;
  11250. shape.PathScaleX = addPacket.ObjectData.PathScaleX;
  11251. shape.PathScaleY = addPacket.ObjectData.PathScaleY;
  11252. shape.PathShearX = addPacket.ObjectData.PathShearX;
  11253. shape.PathShearY = addPacket.ObjectData.PathShearY;
  11254. shape.PathSkew = addPacket.ObjectData.PathSkew;
  11255. shape.ProfileBegin = addPacket.ObjectData.ProfileBegin;
  11256. shape.ProfileEnd = addPacket.ObjectData.ProfileEnd;
  11257. shape.Scale = addPacket.ObjectData.Scale;
  11258. shape.PathCurve = addPacket.ObjectData.PathCurve;
  11259. shape.ProfileCurve = addPacket.ObjectData.ProfileCurve;
  11260. shape.ProfileHollow = addPacket.ObjectData.ProfileHollow;
  11261. shape.PathRadiusOffset = addPacket.ObjectData.PathRadiusOffset;
  11262. shape.PathRevolutions = addPacket.ObjectData.PathRevolutions;
  11263. shape.PathTaperX = addPacket.ObjectData.PathTaperX;
  11264. shape.PathTaperY = addPacket.ObjectData.PathTaperY;
  11265. shape.PathTwist = addPacket.ObjectData.PathTwist;
  11266. shape.PathTwistBegin = addPacket.ObjectData.PathTwistBegin;
  11267. Primitive.TextureEntry ntex = new Primitive.TextureEntry(new UUID("89556747-24cb-43ed-920b-47caed15465f"));
  11268. shape.TextureEntry = ntex.GetBytes();
  11269. //shape.Textures = ntex;
  11270. return shape;
  11271. }
  11272. public ClientInfo GetClientInfo()
  11273. {
  11274. ClientInfo info = m_udpClient.GetClientInfo();
  11275. info.proxyEP = null;
  11276. if (info.agentcircuit == null)
  11277. info.agentcircuit = RequestClientInfo();
  11278. return info;
  11279. }
  11280. public void SetClientInfo(ClientInfo info)
  11281. {
  11282. m_udpClient.SetClientInfo(info);
  11283. }
  11284. #region Media Parcel Members
  11285. public void SendParcelMediaCommand(uint flags, ParcelMediaCommandEnum command, float time)
  11286. {
  11287. ParcelMediaCommandMessagePacket commandMessagePacket = new ParcelMediaCommandMessagePacket();
  11288. commandMessagePacket.CommandBlock.Flags = flags;
  11289. commandMessagePacket.CommandBlock.Command = (uint)command;
  11290. commandMessagePacket.CommandBlock.Time = time;
  11291. OutPacket(commandMessagePacket, ThrottleOutPacketType.Task);
  11292. }
  11293. public void SendParcelMediaUpdate(string mediaUrl, UUID mediaTextureID,
  11294. byte autoScale, string mediaType, string mediaDesc, int mediaWidth, int mediaHeight,
  11295. byte mediaLoop)
  11296. {
  11297. ParcelMediaUpdatePacket updatePacket = new ParcelMediaUpdatePacket();
  11298. updatePacket.DataBlock.MediaURL = Util.StringToBytes256(mediaUrl);
  11299. updatePacket.DataBlock.MediaID = mediaTextureID;
  11300. updatePacket.DataBlock.MediaAutoScale = autoScale;
  11301. updatePacket.DataBlockExtended.MediaType = Util.StringToBytes256(mediaType);
  11302. updatePacket.DataBlockExtended.MediaDesc = Util.StringToBytes256(mediaDesc);
  11303. updatePacket.DataBlockExtended.MediaWidth = mediaWidth;
  11304. updatePacket.DataBlockExtended.MediaHeight = mediaHeight;
  11305. updatePacket.DataBlockExtended.MediaLoop = mediaLoop;
  11306. OutPacket(updatePacket, ThrottleOutPacketType.Task);
  11307. }
  11308. #endregion
  11309. #region Camera
  11310. public void SendSetFollowCamProperties(UUID objectID, SortedDictionary<int, float> parameters)
  11311. {
  11312. SetFollowCamPropertiesPacket packet = (SetFollowCamPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.SetFollowCamProperties);
  11313. packet.ObjectData.ObjectID = objectID;
  11314. SetFollowCamPropertiesPacket.CameraPropertyBlock[] camPropBlock = new SetFollowCamPropertiesPacket.CameraPropertyBlock[parameters.Count];
  11315. uint idx = 0;
  11316. foreach (KeyValuePair<int, float> pair in parameters)
  11317. {
  11318. SetFollowCamPropertiesPacket.CameraPropertyBlock block = new SetFollowCamPropertiesPacket.CameraPropertyBlock();
  11319. block.Type = pair.Key;
  11320. block.Value = pair.Value;
  11321. camPropBlock[idx++] = block;
  11322. }
  11323. packet.CameraProperty = camPropBlock;
  11324. OutPacket(packet, ThrottleOutPacketType.Task);
  11325. }
  11326. public void SendClearFollowCamProperties(UUID objectID)
  11327. {
  11328. ClearFollowCamPropertiesPacket packet = (ClearFollowCamPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ClearFollowCamProperties);
  11329. packet.ObjectData.ObjectID = objectID;
  11330. OutPacket(packet, ThrottleOutPacketType.Task);
  11331. }
  11332. #endregion
  11333. public void SetClientOption(string option, string value)
  11334. {
  11335. switch (option)
  11336. {
  11337. default:
  11338. break;
  11339. }
  11340. }
  11341. public string GetClientOption(string option)
  11342. {
  11343. switch (option)
  11344. {
  11345. default:
  11346. break;
  11347. }
  11348. return string.Empty;
  11349. }
  11350. #region IClientCore
  11351. private readonly Dictionary<Type, object> m_clientInterfaces = new Dictionary<Type, object>();
  11352. /// <summary>
  11353. /// Register an interface on this client, should only be called in the constructor.
  11354. /// </summary>
  11355. /// <typeparam name="T"></typeparam>
  11356. /// <param name="iface"></param>
  11357. protected void RegisterInterface<T>(T iface)
  11358. {
  11359. lock (m_clientInterfaces)
  11360. {
  11361. if (!m_clientInterfaces.ContainsKey(typeof(T)))
  11362. {
  11363. m_clientInterfaces.Add(typeof(T), iface);
  11364. }
  11365. }
  11366. }
  11367. public bool TryGet<T>(out T iface)
  11368. {
  11369. if(m_clientInterfaces.TryGetValue(typeof(T), out object o))
  11370. {
  11371. iface = (T)o;
  11372. return true;
  11373. }
  11374. iface = default(T);
  11375. return false;
  11376. }
  11377. public T Get<T>()
  11378. {
  11379. return (T)m_clientInterfaces[typeof(T)];
  11380. }
  11381. public void Disconnect(string reason)
  11382. {
  11383. Kick(reason);
  11384. Thread.Sleep(1000);
  11385. Disconnect();
  11386. }
  11387. public void Disconnect()
  11388. {
  11389. Close();
  11390. }
  11391. #endregion
  11392. public void RefreshGroupMembership()
  11393. {
  11394. lock(m_groupPowers)
  11395. {
  11396. GroupMembershipData activeMembership = null;
  11397. if (m_GroupsModule != null)
  11398. {
  11399. GroupMembershipData[] GroupMembership =
  11400. m_GroupsModule.GetMembershipData(m_agentId);
  11401. m_groupPowers.Clear();
  11402. if (GroupMembership != null)
  11403. {
  11404. for (int i = 0; i < GroupMembership.Length; i++)
  11405. {
  11406. m_groupPowers[GroupMembership[i].GroupID] = GroupMembership[i].GroupPowers;
  11407. }
  11408. }
  11409. activeMembership = m_GroupsModule.GetActiveMembershipData(m_agentId);
  11410. if(activeMembership != null)
  11411. {
  11412. if(!m_groupPowers.ContainsKey(activeMembership.GroupID))
  11413. activeMembership = null;
  11414. else
  11415. {
  11416. m_activeGroupID = activeMembership.GroupID;
  11417. m_activeGroupName = activeMembership.GroupName;
  11418. m_activeGroupPowers = ActiveGroupPowers;
  11419. }
  11420. }
  11421. }
  11422. if(activeMembership == null)
  11423. {
  11424. m_activeGroupID = UUID.Zero;
  11425. m_activeGroupName = "";
  11426. m_activeGroupPowers = 0;
  11427. }
  11428. }
  11429. }
  11430. public void UpdateGroupMembership(GroupMembershipData[] data)
  11431. {
  11432. lock(m_groupPowers)
  11433. {
  11434. m_groupPowers.Clear();
  11435. if (data != null)
  11436. {
  11437. for (int i = 0; i < data.Length; i++)
  11438. m_groupPowers[data[i].GroupID] = data[i].GroupPowers;
  11439. }
  11440. }
  11441. }
  11442. public void GroupMembershipRemove(UUID GroupID)
  11443. {
  11444. lock(m_groupPowers)
  11445. {
  11446. if(m_groupPowers.ContainsKey(GroupID))
  11447. m_groupPowers.Remove(GroupID);
  11448. }
  11449. }
  11450. public void GroupMembershipAddReplace(UUID GroupID,ulong GroupPowers)
  11451. {
  11452. lock(m_groupPowers)
  11453. {
  11454. m_groupPowers[GroupID] = GroupPowers;
  11455. }
  11456. }
  11457. public string Report()
  11458. {
  11459. return m_udpClient.GetStats();
  11460. }
  11461. public string XReport(string uptime, string version)
  11462. {
  11463. return String.Empty;
  11464. }
  11465. public OSDMap OReport(string uptime, string version)
  11466. {
  11467. return new OSDMap();
  11468. }
  11469. /// <summary>
  11470. /// Make an asset request to the asset service in response to a client request.
  11471. /// </summary>
  11472. /// <param name="transferRequest"></param>
  11473. /// <param name="taskID"></param>
  11474. protected void MakeAssetRequest(TransferRequestPacket transferRequest, UUID taskID)
  11475. {
  11476. UUID requestID;
  11477. int sourceType = transferRequest.TransferInfo.SourceType;
  11478. switch(sourceType)
  11479. {
  11480. case (int)SourceType.Asset:
  11481. requestID = new UUID(transferRequest.TransferInfo.Params, 0);
  11482. break;
  11483. case (int)SourceType.SimInventoryItem:
  11484. requestID = new UUID(transferRequest.TransferInfo.Params, 80);
  11485. break;
  11486. case (int)SourceType.SimEstate:
  11487. requestID = taskID;
  11488. break;
  11489. default:
  11490. requestID = UUID.Zero;
  11491. break;
  11492. }
  11493. //m_log.DebugFormat(
  11494. // "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}",
  11495. // requestID, taskID, (SourceType)sourceType, Name);
  11496. //Note, the bool returned from the below function is useless since it is always false.
  11497. m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
  11498. }
  11499. /// <summary>
  11500. /// When we get a reply back from the asset service in response to a client request, send back the data.
  11501. /// </summary>
  11502. /// <param name="id"></param>
  11503. /// <param name="sender"></param>
  11504. /// <param name="asset"></param>
  11505. protected void AssetReceived(string id, Object sender, AssetBase asset)
  11506. {
  11507. TransferRequestPacket transferRequest = (TransferRequestPacket)sender;
  11508. UUID requestID = UUID.Zero;
  11509. byte source = (byte)SourceType.Asset;
  11510. AssetRequestToClient req = new AssetRequestToClient();
  11511. if (asset == null)
  11512. {
  11513. // Try the user's asset server
  11514. IInventoryAccessModule inventoryAccessModule = Scene.RequestModuleInterface<IInventoryAccessModule>();
  11515. string assetServerURL = string.Empty;
  11516. if (inventoryAccessModule.IsForeignUser(m_agentId, out assetServerURL) && !string.IsNullOrEmpty(assetServerURL))
  11517. {
  11518. if (!assetServerURL.EndsWith("/") && !assetServerURL.EndsWith("="))
  11519. assetServerURL = assetServerURL + "/";
  11520. //m_log.DebugFormat("[LLCLIENTVIEW]: asset {0} not found in local storage. Trying user's storage.", assetServerURL + id);
  11521. asset = m_scene.AssetService.Get(assetServerURL + id);
  11522. }
  11523. if (asset == null)
  11524. {
  11525. req.AssetInf = null;
  11526. req.AssetRequestSource = source;
  11527. req.IsTextureRequest = false;
  11528. req.NumPackets = 0;
  11529. req.Params = transferRequest.TransferInfo.Params;
  11530. req.RequestAssetID = requestID;
  11531. req.TransferRequestID = transferRequest.TransferInfo.TransferID;
  11532. SendAssetNotFound(req);
  11533. return;
  11534. }
  11535. }
  11536. if (transferRequest.TransferInfo.SourceType == (int)SourceType.Asset)
  11537. {
  11538. requestID = new UUID(transferRequest.TransferInfo.Params, 0);
  11539. }
  11540. else if (transferRequest.TransferInfo.SourceType == (int)SourceType.SimInventoryItem)
  11541. {
  11542. requestID = new UUID(transferRequest.TransferInfo.Params, 80);
  11543. source = (byte)SourceType.SimInventoryItem;
  11544. //m_log.Debug("asset request " + requestID);
  11545. }
  11546. // Scripts cannot be retrieved by direct request
  11547. if (transferRequest.TransferInfo.SourceType == (int)SourceType.Asset && asset.Type == (sbyte)AssetType.LSLText)
  11548. return;
  11549. // The asset is known to exist and is in our cache, so add it to the AssetRequests list
  11550. req.AssetInf = asset;
  11551. req.AssetRequestSource = source;
  11552. req.IsTextureRequest = false;
  11553. req.NumPackets = CalculateNumPackets(asset.Data);
  11554. req.Params = transferRequest.TransferInfo.Params;
  11555. req.RequestAssetID = requestID;
  11556. req.TransferRequestID = transferRequest.TransferInfo.TransferID;
  11557. SendAsset(req);
  11558. }
  11559. /// <summary>
  11560. /// Calculate the number of packets required to send the asset to the client.
  11561. /// </summary>
  11562. /// <param name="data"></param>
  11563. /// <returns></returns>
  11564. private static int CalculateNumPackets(byte[] data)
  11565. {
  11566. // const uint m_maxPacketSize = 600;
  11567. uint m_maxPacketSize = MaxTransferBytesPerPacket;
  11568. int numPackets = 1;
  11569. if (data == null)
  11570. return 0;
  11571. if (data.LongLength > m_maxPacketSize)
  11572. {
  11573. // over max number of bytes so split up file
  11574. long restData = data.LongLength - m_maxPacketSize;
  11575. int restPackets = (int)((restData + m_maxPacketSize - 1) / m_maxPacketSize);
  11576. numPackets += restPackets;
  11577. }
  11578. return numPackets;
  11579. }
  11580. public void SendRebakeAvatarTextures(UUID textureID)
  11581. {
  11582. RebakeAvatarTexturesPacket pack =
  11583. (RebakeAvatarTexturesPacket)PacketPool.Instance.GetPacket(PacketType.RebakeAvatarTextures);
  11584. pack.TextureData = new RebakeAvatarTexturesPacket.TextureDataBlock();
  11585. pack.TextureData.TextureID = textureID;
  11586. OutPacket(pack, ThrottleOutPacketType.Task);
  11587. }
  11588. public struct PacketProcessor
  11589. {
  11590. /// <summary>
  11591. /// Packet handling method.
  11592. /// </summary>
  11593. public PacketMethod method;
  11594. /// <summary>
  11595. /// Should this packet be handled asynchronously?
  11596. /// </summary>
  11597. public bool Async;
  11598. }
  11599. public void SendAvatarInterestsReply(UUID avatarID, uint wantMask, string wantText, uint skillsMask, string skillsText, string languages)
  11600. {
  11601. AvatarInterestsReplyPacket packet = (AvatarInterestsReplyPacket)PacketPool.Instance.GetPacket(PacketType.AvatarInterestsReply);
  11602. packet.AgentData = new AvatarInterestsReplyPacket.AgentDataBlock();
  11603. packet.AgentData.AgentID = m_agentId;
  11604. packet.AgentData.AvatarID = avatarID;
  11605. packet.PropertiesData = new AvatarInterestsReplyPacket.PropertiesDataBlock();
  11606. packet.PropertiesData.WantToMask = wantMask;
  11607. packet.PropertiesData.WantToText = Utils.StringToBytes(wantText);
  11608. packet.PropertiesData.SkillsMask = skillsMask;
  11609. packet.PropertiesData.SkillsText = Utils.StringToBytes(skillsText);
  11610. packet.PropertiesData.LanguagesText = Utils.StringToBytes(languages);
  11611. OutPacket(packet, ThrottleOutPacketType.Task);
  11612. }
  11613. public void SendChangeUserRights(UUID agentID, UUID friendID, int rights)
  11614. {
  11615. ChangeUserRightsPacket packet = (ChangeUserRightsPacket)PacketPool.Instance.GetPacket(PacketType.ChangeUserRights);
  11616. packet.AgentData = new ChangeUserRightsPacket.AgentDataBlock();
  11617. packet.AgentData.AgentID = agentID;
  11618. packet.Rights = new ChangeUserRightsPacket.RightsBlock[1];
  11619. packet.Rights[0] = new ChangeUserRightsPacket.RightsBlock();
  11620. packet.Rights[0].AgentRelated = friendID;
  11621. packet.Rights[0].RelatedRights = rights;
  11622. OutPacket(packet, ThrottleOutPacketType.Task);
  11623. }
  11624. public void SendTextBoxRequest(string message, int chatChannel, string objectname, UUID ownerID, string ownerFirstName, string ownerLastName, UUID objectId)
  11625. {
  11626. ScriptDialogPacket dialog = (ScriptDialogPacket)PacketPool.Instance.GetPacket(PacketType.ScriptDialog);
  11627. dialog.Data.ObjectID = objectId;
  11628. dialog.Data.ChatChannel = chatChannel;
  11629. dialog.Data.ImageID = UUID.Zero;
  11630. dialog.Data.ObjectName = Util.StringToBytes256(objectname);
  11631. // this is the username of the *owner*
  11632. dialog.Data.FirstName = Util.StringToBytes256(ownerFirstName);
  11633. dialog.Data.LastName = Util.StringToBytes256(ownerLastName);
  11634. dialog.Data.Message = Util.StringToBytes(message,512);
  11635. ScriptDialogPacket.ButtonsBlock[] buttons = new ScriptDialogPacket.ButtonsBlock[1];
  11636. buttons[0] = new ScriptDialogPacket.ButtonsBlock();
  11637. buttons[0].ButtonLabel = Util.StringToBytes256("!!llTextBox!!");
  11638. dialog.Buttons = buttons;
  11639. dialog.OwnerData = new ScriptDialogPacket.OwnerDataBlock[1];
  11640. dialog.OwnerData[0] = new ScriptDialogPacket.OwnerDataBlock();
  11641. dialog.OwnerData[0].OwnerID = ownerID;
  11642. OutPacket(dialog, ThrottleOutPacketType.Task);
  11643. }
  11644. public void SendAgentTerseUpdate(ISceneEntity p)
  11645. {
  11646. if (p is ScenePresence)
  11647. {
  11648. UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
  11649. //setup header and regioninfo block
  11650. Buffer.BlockCopy(terseUpdateHeader, 0, buf.Data, 0, 7);
  11651. unsafe
  11652. {
  11653. fixed(byte* bdata = &buf.Data[0])
  11654. {
  11655. Utils.UInt64ToBytes(m_scene.RegionInfo.RegionHandle, bdata + 7);
  11656. Utils.UInt16ToBytes(Utils.FloatZeroOneToushort(m_scene.TimeDilation), bdata + 15);
  11657. bdata[17] = 1;
  11658. byte* data = bdata + 18;
  11659. CreateAvatartImprovedTerseBlock((ScenePresence)p, ref data);
  11660. buf.DataLength = (int)(data - bdata);
  11661. }
  11662. }
  11663. m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task, null, true);
  11664. }
  11665. }
  11666. public void SendPlacesReply(UUID queryID, UUID transactionID,
  11667. PlacesReplyData[] data)
  11668. {
  11669. PlacesReplyPacket reply = null;
  11670. PlacesReplyPacket.QueryDataBlock[] dataBlocks =
  11671. new PlacesReplyPacket.QueryDataBlock[0];
  11672. for (int i = 0 ; i < data.Length ; i++)
  11673. {
  11674. PlacesReplyPacket.QueryDataBlock block =
  11675. new PlacesReplyPacket.QueryDataBlock();
  11676. block.OwnerID = data[i].OwnerID;
  11677. block.Name = Util.StringToBytes256(data[i].Name);
  11678. block.Desc = Util.StringToBytes1024(data[i].Desc);
  11679. block.ActualArea = data[i].ActualArea;
  11680. block.BillableArea = data[i].BillableArea;
  11681. block.Flags = data[i].Flags;
  11682. block.GlobalX = data[i].GlobalX;
  11683. block.GlobalY = data[i].GlobalY;
  11684. block.GlobalZ = data[i].GlobalZ;
  11685. block.SimName = Util.StringToBytes256(data[i].SimName);
  11686. block.SnapshotID = data[i].SnapshotID;
  11687. block.Dwell = data[i].Dwell;
  11688. block.Price = data[i].Price;
  11689. if (reply != null && reply.Length + block.Length > 1400)
  11690. {
  11691. OutPacket(reply, ThrottleOutPacketType.Task);
  11692. reply = null;
  11693. dataBlocks = new PlacesReplyPacket.QueryDataBlock[0];
  11694. }
  11695. if (reply == null)
  11696. {
  11697. reply = (PlacesReplyPacket)PacketPool.Instance.GetPacket(PacketType.PlacesReply);
  11698. reply.AgentData = new PlacesReplyPacket.AgentDataBlock();
  11699. reply.AgentData.AgentID = m_agentId;
  11700. reply.AgentData.QueryID = queryID;
  11701. reply.TransactionData = new PlacesReplyPacket.TransactionDataBlock();
  11702. reply.TransactionData.TransactionID = transactionID;
  11703. reply.QueryData = dataBlocks;
  11704. }
  11705. Array.Resize(ref dataBlocks, dataBlocks.Length + 1);
  11706. dataBlocks[dataBlocks.Length - 1] = block;
  11707. reply.QueryData = dataBlocks;
  11708. }
  11709. if (reply != null)
  11710. OutPacket(reply, ThrottleOutPacketType.Task);
  11711. }
  11712. public void SendRemoveInventoryItems(UUID[] items)
  11713. {
  11714. IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
  11715. if (eq == null)
  11716. {
  11717. m_log.DebugFormat("[LLCLIENT]: Null event queue");
  11718. return;
  11719. }
  11720. osUTF8 sb = eq.StartEvent("RemoveInventoryItem");
  11721. LLSDxmlEncode2.AddArrayAndMap("AgentData", sb);
  11722. LLSDxmlEncode2.AddElem("AgentID", m_agentId, sb);
  11723. LLSDxmlEncode2.AddElem("SessionID", SessionId, sb);
  11724. LLSDxmlEncode2.AddEndMapAndArray(sb);
  11725. LLSDxmlEncode2.AddArray("InventoryData", sb);
  11726. foreach (UUID item in items)
  11727. {
  11728. LLSDxmlEncode2.AddMap(sb);
  11729. LLSDxmlEncode2.AddElem("ItemID",item, sb);
  11730. LLSDxmlEncode2.AddEndMap(sb);
  11731. }
  11732. LLSDxmlEncode2.AddEndArray(sb);
  11733. eq.Enqueue(eq.EndEventToBytes(sb), m_agentId);
  11734. }
  11735. public void SendRemoveInventoryFolders(UUID[] folders)
  11736. {
  11737. IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
  11738. if (eq == null)
  11739. {
  11740. m_log.DebugFormat("[LLCLIENT]: Null event queue");
  11741. return;
  11742. }
  11743. osUTF8 sb = eq.StartEvent("RemoveInventoryFolder");
  11744. LLSDxmlEncode2.AddArrayAndMap("AgentData", sb);
  11745. LLSDxmlEncode2.AddElem("AgentID", m_agentId, sb);
  11746. LLSDxmlEncode2.AddElem("SessionID", SessionId, sb);
  11747. LLSDxmlEncode2.AddEndMapAndArray(sb);
  11748. LLSDxmlEncode2.AddArray("FolderData", sb);
  11749. foreach (UUID folder in folders)
  11750. {
  11751. LLSDxmlEncode2.AddMap(sb);
  11752. LLSDxmlEncode2.AddElem("FolderID", folder, sb);
  11753. LLSDxmlEncode2.AddEndMap(sb);
  11754. }
  11755. LLSDxmlEncode2.AddEndArray(sb);
  11756. eq.Enqueue(eq.EndEventToBytes(sb), m_agentId);
  11757. }
  11758. public void SendBulkUpdateInventory(InventoryFolderBase[] folders, InventoryItemBase[] items)
  11759. {
  11760. IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
  11761. if (eq == null)
  11762. {
  11763. m_log.DebugFormat("[LLCLIENT]: Null event queue");
  11764. return;
  11765. }
  11766. osUTF8 sb = eq.StartEvent("BulkUpdateInventory");
  11767. LLSDxmlEncode2.AddArrayAndMap("AgentData", sb);
  11768. LLSDxmlEncode2.AddElem("AgentID", m_agentId, sb);
  11769. LLSDxmlEncode2.AddElem("TransactionID", UUID.Random(), sb);
  11770. LLSDxmlEncode2.AddEndMapAndArray(sb);
  11771. if(folders.Length == 0)
  11772. {
  11773. LLSDxmlEncode2.AddEmptyArray("FolderData", sb);
  11774. }
  11775. else
  11776. {
  11777. LLSDxmlEncode2.AddArray("FolderData", sb);
  11778. foreach (InventoryFolderBase folder in folders)
  11779. {
  11780. LLSDxmlEncode2.AddMap(sb);
  11781. LLSDxmlEncode2.AddElem("FolderID", folder.ID, sb);
  11782. LLSDxmlEncode2.AddElem("ParentID", folder.ParentID, sb);
  11783. LLSDxmlEncode2.AddElem("Type", (int)folder.Type, sb);
  11784. LLSDxmlEncode2.AddElem("Name", folder.Name, sb);
  11785. LLSDxmlEncode2.AddEndMap(sb);
  11786. }
  11787. LLSDxmlEncode2.AddEndArray(sb);
  11788. }
  11789. if(items.Length == 0)
  11790. {
  11791. LLSDxmlEncode2.AddEmptyArray("ItemData", sb);
  11792. }
  11793. else
  11794. {
  11795. LLSDxmlEncode2.AddArray("ItemData", sb);
  11796. foreach (InventoryItemBase item in items)
  11797. {
  11798. LLSDxmlEncode2.AddMap(sb);
  11799. LLSDxmlEncode2.AddElem("ItemID", item.ID, sb);
  11800. LLSDxmlEncode2.AddElem("CallbackID", (uint)0, sb);
  11801. LLSDxmlEncode2.AddElem("FolderID", item.Folder, sb);
  11802. LLSDxmlEncode2.AddElem("CreatorID", item.CreatorIdAsUuid, sb);
  11803. LLSDxmlEncode2.AddElem("OwnerID", item.Owner, sb);
  11804. LLSDxmlEncode2.AddElem("GroupID", item.GroupID, sb);
  11805. LLSDxmlEncode2.AddElem("BaseMask", item.BasePermissions, sb);
  11806. LLSDxmlEncode2.AddElem("OwnerMask", item.CurrentPermissions, sb);
  11807. LLSDxmlEncode2.AddElem("GroupMask", item.GroupPermissions, sb);
  11808. LLSDxmlEncode2.AddElem("EveryoneMask", item.EveryOnePermissions, sb);
  11809. LLSDxmlEncode2.AddElem("NextOwnerMask", item.NextPermissions, sb);
  11810. LLSDxmlEncode2.AddElem("GroupOwned", item.GroupOwned, sb);
  11811. LLSDxmlEncode2.AddElem("AssetID", item.AssetID, sb);
  11812. LLSDxmlEncode2.AddElem("Type", item.AssetType, sb);
  11813. LLSDxmlEncode2.AddElem("InvType", item.InvType, sb);
  11814. LLSDxmlEncode2.AddElem("Flags", item.Flags, sb);
  11815. LLSDxmlEncode2.AddElem("SaleType", item.SaleType, sb);
  11816. LLSDxmlEncode2.AddElem("SalePrice", item.SalePrice, sb);
  11817. LLSDxmlEncode2.AddElem("Name", item.Name, sb);
  11818. LLSDxmlEncode2.AddElem("Description", item.Description, sb);
  11819. LLSDxmlEncode2.AddElem("CreationDate", item.CreationDate, sb);
  11820. LLSDxmlEncode2.AddElem("CRC",
  11821. Helpers.InventoryCRC(1000, 0, (sbyte)item.InvType,
  11822. (sbyte)item.AssetType, item.AssetID,
  11823. item.GroupID, 100,
  11824. item.Owner, item.CreatorIdAsUuid,
  11825. item.ID, item.Folder,
  11826. (uint)PermissionMask.All, 1, (uint)PermissionMask.All, (uint)PermissionMask.All,
  11827. (uint)PermissionMask.All),
  11828. sb);
  11829. LLSDxmlEncode2.AddEndMap(sb);
  11830. }
  11831. LLSDxmlEncode2.AddEndArray(sb);
  11832. }
  11833. eq.Enqueue(eq.EndEventToBytes(sb), m_agentId);
  11834. }
  11835. private HashSet<string> m_outPacketsToDrop;
  11836. public bool AddOutPacketToDropSet(string packetName)
  11837. {
  11838. if (m_outPacketsToDrop == null)
  11839. m_outPacketsToDrop = new HashSet<string>();
  11840. return m_outPacketsToDrop.Add(packetName);
  11841. }
  11842. public bool RemoveOutPacketFromDropSet(string packetName)
  11843. {
  11844. if (m_outPacketsToDrop == null)
  11845. return false;
  11846. return m_outPacketsToDrop.Remove(packetName);
  11847. }
  11848. public HashSet<string> GetOutPacketDropSet()
  11849. {
  11850. return new HashSet<string>(m_outPacketsToDrop);
  11851. }
  11852. private HashSet<string> m_inPacketsToDrop;
  11853. public bool AddInPacketToDropSet(string packetName)
  11854. {
  11855. if (m_inPacketsToDrop == null)
  11856. m_inPacketsToDrop = new HashSet<string>();
  11857. return m_inPacketsToDrop.Add(packetName);
  11858. }
  11859. public bool RemoveInPacketFromDropSet(string packetName)
  11860. {
  11861. if (m_inPacketsToDrop == null)
  11862. return false;
  11863. return m_inPacketsToDrop.Remove(packetName);
  11864. }
  11865. public HashSet<string> GetInPacketDropSet()
  11866. {
  11867. return new HashSet<string>(m_inPacketsToDrop);
  11868. }
  11869. public uint GetViewerCaps()
  11870. {
  11871. m_SupportObjectAnimations = false;
  11872. uint ret;
  11873. if(m_supportViewerCache)
  11874. ret = m_viewerHandShakeFlags;
  11875. else
  11876. ret = (m_viewerHandShakeFlags & 4) | 2; // disable probes
  11877. if (m_scene.CapsModule != null)
  11878. {
  11879. Caps cap = m_scene.CapsModule.GetCapsForUser(CircuitCode);
  11880. if(cap != null)
  11881. {
  11882. if((cap.Flags & Caps.CapsFlags.SentSeeds) != 0)
  11883. ret |= 0x1000;
  11884. if ((cap.Flags & Caps.CapsFlags.ObjectAnim) != 0)
  11885. {
  11886. m_SupportObjectAnimations = true;
  11887. ret |= 0x2000;
  11888. }
  11889. if ((cap.Flags & Caps.CapsFlags.WLEnv) != 0)
  11890. ret |= 0x4000;
  11891. if ((cap.Flags & Caps.CapsFlags.AdvEnv) != 0)
  11892. ret |= 0x8000;
  11893. }
  11894. }
  11895. return ret;
  11896. }
  11897. }
  11898. }