TitanInterface.cpp 231 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557
  1. // TitanInterface
  2. #include <process.h>
  3. #include <sys/stat.h>
  4. #include "common/won.h"
  5. #include "common/DataObject.h"
  6. #include <winsock.h>
  7. #include "common/ThreadBase.h"
  8. #include "common/WONException.h"
  9. #include "db/dbconstants.h"
  10. #include "msg/TMessage.h"
  11. #include "msg/MServiceTypes.h"
  12. #include "msg/SServiceTypes.h"
  13. #include "msg/TServiceTypes.h"
  14. #include "msg/comm/MMsgTypesComm.h"
  15. #include "msg/comm/MMsgCommPing.h"
  16. #include "msg/comm/MMsgCommGetNumUsers.h"
  17. #include "msg/comm/SMsgTypesComm.h"
  18. #include "msg/comm/SMsgCommStatusReply.h"
  19. #include "msg/comm/TMsgTypesComm.h"
  20. #include "msg/comm/TMsgCommStatusReply.h"
  21. #include "msg/dir/DirG2Flags.h"
  22. #include "msg/dir/SMsgTypesDir.h"
  23. #include "msg/dir/SMsgDirG2GetEntity.h"
  24. #include "msg/dir/SMsgDirG2MultiEntityReply.h"
  25. #include "msg/event/SMsgEventTaggedRecordEvent.h"
  26. #include "msg/fact/SMsgTypesFact.h"
  27. #include "msg/fact/SMsgFactStatusReply.h"
  28. #include "msg/fact/SMsgFactStartProcessUnicode.h"
  29. #include "msg/firewall/SMsgTypesFirewall.h"
  30. #include "msg/firewall/SMsgFirewallDetect.h"
  31. #include "msg/firewall/SMsgFirewallStatusReply.h"
  32. #include "msg/auth/TMsgTypesAuth.h"
  33. #include "msg/auth/TMsgAuth1GetPubKeys.h"
  34. #include "msg/auth/TMsgAuth1LoginHW.h"
  35. #include "msg/auth/TMsgAuth1LoginReply.h"
  36. #include "msg/auth/TMsgAuth1PeerToPeer.h"
  37. #include "msg/routing/MMsgTypesRouting.h"
  38. #include "msg/routing/MMsgRoutingCreateDataObject.h"
  39. #include "msg/routing/MMsgRoutingDeleteDataObject.h"
  40. #include "msg/routing/MMsgRoutingDisconnectClient.h"
  41. #include "msg/routing/MMsgRoutingGetClientList.h"
  42. #include "msg/routing/MMsgRoutingGroupChange.h"
  43. #include "msg/routing/MMsgRoutingPeerChat.h"
  44. #include "msg/routing/MMsgRoutingPeerData.h"
  45. #include "msg/routing/MMsgRoutingPeerDataMultiple.h"
  46. #include "msg/routing/MMsgRoutingRegisterClient.h"
  47. #include "msg/routing/MMsgRoutingReadDataObjectReply.h"
  48. #include "msg/routing/MMsgRoutingRenewDataObject.h"
  49. #include "msg/routing/MMsgRoutingReplaceDataObject.h"
  50. #include "msg/routing/MMsgRoutingStatusReply.h"
  51. #include "msg/routing/MMsgRoutingSendChat.h"
  52. #include "msg/routing/MMsgRoutingSendData.h"
  53. #include "msg/routing/MMsgRoutingSendDataBroadcast.h"
  54. #include "msg/routing/MMsgRoutingSubscribeDataObject.h"
  55. #include "msg/routing/MMsgRoutingReconnectClient.h"
  56. #include "TitanPacketMsg.h"
  57. #include "EasySocket/EasySocketEngine.h"
  58. #include "EasySocket/EasySocket.h"
  59. #include "EasySocket/SocketPipe.h"
  60. #include "EasySocket/PipeCmd.h"
  61. #include "TitanInterface.h"
  62. #include "ClientCDKey.h"
  63. #include "wassert.h"
  64. #include <crtdbg.h>
  65. #define DEBUG_DISCONNECT 0
  66. #define CLOCK_COMMANDS_THRU_ENGINE
  67. #define LOG_MESSAGE_SIZE
  68. extern "C"
  69. {
  70. #include "TitanInterfaceC.h"
  71. #include "Titan.h"
  72. #include "StringsOnly.h"
  73. extern char filePrependPath[];
  74. void mgStartSpecificFactServerFailedCB(void);
  75. void mgStartGame(char*name,void*atom);
  76. void mgStartGameCB(void);
  77. void mgDisplayMsgBox(void);
  78. void mgDisplayMessage(char *message);
  79. void clCommandMessage(char *msg);
  80. void LockMutex(void *mutex);
  81. void UnLockMutex(void *mutex);
  82. }
  83. // Private namespace for using and constants
  84. namespace {
  85. using namespace WONDatabase;
  86. using WONCommon::AutoCrit;
  87. using WONCommon::StringToWString;
  88. using WONCommon::WStringToString;
  89. using WONCommon::WONException;
  90. using WONCrypt::BFSymmetricKey;
  91. using WONCrypt::EGPublicKey;
  92. using WONCrypt::EGPrivateKey;
  93. using WONCrypt::CryptKeyBase;
  94. using WONAuth::Auth1PublicKeyBlock;
  95. using WONAuth::Auth1Certificate;
  96. using WONMsg::TRawMsg;
  97. using WONMsg::TMessage;
  98. using WONMsg::BaseMessage;
  99. using WONMsg::MiniMessage;
  100. using WONMsg::SmallMessage;
  101. using WONMsg::MMsgRoutingPeerDataMultiple::PeerDataMessage;
  102. using WONMsg::MMsgRoutingReadDataObjectReply::DataObjectWithIds;
  103. using WONMisc::EasySocketEngine;
  104. using WONMisc::EasySocket;
  105. using WONMisc::ES_ErrorType;
  106. using WONMisc::SocketPipe;
  107. using WONMisc::PipeCmd;
  108. using WONMisc::OpenCmd;
  109. using WONMisc::BindCmd;
  110. using WONMisc::CloseCmd;
  111. using WONMisc::CloseNowCmd;
  112. using WONMisc::SmartConnectCmd;
  113. using WONMisc::ListenCmd;
  114. using WONMisc::AcceptCmd;
  115. using WONMisc::RecvPrefCmd;
  116. using WONMisc::RecvFromCmd;
  117. using WONMisc::SendCmd;
  118. using WONMisc::SendToCmd;
  119. using WONMisc::BroadcastCmd;
  120. using WONMisc::SetEventCmd;
  121. using WONMisc::WaitForEventCmd;
  122. using WONMisc::TimerCmd;
  123. using WONMisc::NoOpPayloadCmd;
  124. // Constants
  125. const wchar_t* HOMEWORLD_DIR = L"/Homeworld"; // Dir Server directory for Homeworld rooms
  126. const wchar_t* HWDS_DIR = L"HWDS"; // sub-dir of Homeworld where HWDS's register
  127. const wchar_t* TITANSERVER_DIR = L"/TitanServers"; // Parent directory of dirs holding auth, firewall, and event servers.
  128. const wchar_t* AUTH_SERV = L"AuthServer"; // Service name for auth servers
  129. const wchar_t* CHATROOM_SERV = L"TitanRoutingServer"; // Service name for chat rooms (chat Routing Servers)
  130. const wchar_t* FACTORY_SERV = L"TitanFactoryServer"; // Service name for factory servers
  131. const wchar_t* FIREWALL_SERV = L"TitanFirewallDetector"; // Service name for firewall servers
  132. const wchar_t* EVENT_SERV = L"TitanEventServer"; // Service name for event servers
  133. const WONCommon::RawBuffer VALIDVERSIONS_OBJ(reinterpret_cast<unsigned char*>("HomeworldValidVersions")); // Data object that contains valid Homeworld version strings (attached to TitanServers dir)
  134. const WONCommon::RawBuffer DESCRIPTION_OBJ(reinterpret_cast<unsigned char*>("Description")); // Data object that contains the HWDS server/chat room's description (attached to Routing Server entries in Homeworld dir & Factory Server entries in the HWDS dir)
  135. const WONCommon::RawBuffer ROOM_FLAGS_OBJ(reinterpret_cast<unsigned char*>("RoomFlags")); // Data object that contains the chat room flags (attached to Routing Server entries in Homeworld dir)
  136. const WONCommon::RawBuffer ROOM_CLIENTCOUNT_OBJ(reinterpret_cast<unsigned char*>("__RSClientCount")); // Data object that contains some indication of a chat room's fullness (attached to Routing Server entries in Homeworld dir)
  137. const WONCommon::RawBuffer FACT_CUR_SERVER_COUNT_OBJ(reinterpret_cast<unsigned char*>("__FactCur_RoutingServHWGame")); // Data object that contains the current number of game servers currently running on a particular machine/Factory Server (attached to Factory Server entries in HWDS dir)
  138. const WONCommon::RawBuffer FACT_TOTAL_SERVER_COUNT_OBJ(reinterpret_cast<unsigned char*>("__FactTotal_RoutingServHWGame")); // Data object that contains the total number of game servers that have been run by a particular machine/Factory Server (attached to Factory Server entries in HWDS dir)
  139. const WONCommon::RawBuffer SERVER_UPTIME_OBJ(reinterpret_cast<unsigned char*>("__ServerUptime")); // Data object that contains the number of seconds that a particular server has been up (attached to Factory Server entries in HWDS dir)
  140. const unsigned char* gameTag = reinterpret_cast<unsigned char*>("HW"); // tag prepended to game names when creating Routing Server data types (game objects)
  141. const unsigned char* keyTag = reinterpret_cast<unsigned char*>("HK"); // tag prepended to game names when creating Routing Server data types (symmetric keys)
  142. const char* ROUTINGSERV_CHAT = "RoutingServHWChat";
  143. const char* ROUTINGSERV_GAME = "RoutingServHWGame";
  144. const char* MEDIAMETRIX_URL = "http://homeworld.won.net";
  145. const int PREPOST_MAX = 10;
  146. const unsigned short CHAT_GROUP = 4;
  147. char *VERIFIER_KEY_FILE_NAME = "kver.kp"; // took out const so C won't bitch
  148. const char *LOGIN_KEY_FILE_NAME = "login.ks";
  149. const unsigned char LAN_GAMEKEY[GAMEKEY_SIZE] = {
  150. 0x23, 0xFD, 0x77, 0xAB, 0x69, 0x17, 0x99, 0xCE
  151. };
  152. const unsigned long NUM_EVENTS_TO_SEND = 3; // number of TaggedRecordEvent messages to send each time we try to record an event
  153. const unsigned long TIME_BETWEEN_EVENTS = 20; // milliseconds
  154. };
  155. // Global Instance of TitanInterface (allocated by titanStart)
  156. TitanInterface* titanInterface = NULL;
  157. extern "C"
  158. {
  159. extern unsigned long multiPlayerGame;
  160. extern unsigned long TITAN_GAME_EXPIRE_TIME;
  161. extern unsigned long TITAN_CHANNEL_EXPIRE_TIME;
  162. extern unsigned long GAME_PORT;
  163. extern unsigned long AD_PORT;
  164. extern char ROUTING_SERVER_NAME[];
  165. extern char utyName[];
  166. extern HWND ghMainWindow;
  167. extern char versionString[];
  168. extern unsigned long strCurLanguage;
  169. extern unsigned long ShortCircuitWON;
  170. extern signed long numPendingIn;
  171. extern signed long numPendingOut;
  172. }
  173. /*=============================================================================
  174. Titan C code wrapper
  175. =============================================================================*/
  176. Address TitanInterface::GetMyPingAddress(void)
  177. {
  178. Address myPingAddress;
  179. if (mBehindFirewall)
  180. {
  181. long IP = mRoutingAddress[0].sin_addr.s_addr;
  182. short int Port = ntohs(mRoutingAddress[0].sin_port);
  183. CreateInternetAddress(myPingAddress,IP,Port);
  184. }
  185. else
  186. {
  187. myPingAddress = mMyIPAddress;
  188. }
  189. return myPingAddress;
  190. }
  191. Address titanGetMyPingAddress(void)
  192. {
  193. return titanInterface->GetMyPingAddress();
  194. }
  195. /*
  196. void titanQueryRoutingServers(void) {
  197. titanInterface->QueryRoutingServers();
  198. }
  199. */
  200. void titanLeaveGameNotify(void) {
  201. captainIndex = -1;
  202. if (IPGame)
  203. {
  204. titanInterface->LeaveGameNotify();
  205. }
  206. }
  207. unsigned long titanReadyToStartGame(unsigned char *routingaddress) {
  208. return titanInterface->CheckStartingGame(routingaddress) ? 1 : 0;
  209. }
  210. void TitanInterface::LeaveGameNotify(void)
  211. {
  212. captainIndex = -1;
  213. // If the player is leaving a game that has started, record an event indicating
  214. // that the player has exitted the game
  215. if (mGameCreationState == GAME_STARTED)
  216. {
  217. mGameDisconnectWasVoluntary = true;
  218. RecordEvent(ACTIVITYTYPE_HOMEWORLD_GAME_EXIT);
  219. }
  220. if(!mUseOldScheme) {
  221. mUseRoutingServer = true;
  222. mRoutingReconnectNum[0] = 0;
  223. mRoutingReconnectNum[1] = 0;
  224. CloseRoutingServerConnection(1);
  225. mGameCreationState = GAME_NOT_STARTED;
  226. myAddress.AddrPart.IP = mMyClientId[0];
  227. myAddress.Port = mMyClientId[0];
  228. }
  229. if (IPGame) // don't close old client connections if IPX Lan
  230. {
  231. // Close all old client connections.
  232. AutoCrit aCrit(mClientCrit);
  233. ClientToPipe::iterator anItr = mClientMap.begin();
  234. while(anItr!=mClientMap.end())
  235. {
  236. SocketPipe *aPipe = anItr->second.pipe;
  237. if(aPipe!=NULL)
  238. aPipe->AddOutgoingCmd(new CloseCmd(false, false, 0, false));
  239. anItr++;
  240. }
  241. mClientMap.clear();
  242. }
  243. }
  244. void TitanInterface::ConnectingCancelHit()
  245. {
  246. if (mGameCreationState == GAME_STARTING)
  247. {
  248. mGameCreationState = GAME_NOT_STARTED;
  249. }
  250. }
  251. void titanConnectingCancelHit(void)
  252. {
  253. titanInterface->ConnectingCancelHit();
  254. }
  255. bool TitanInterface::CheckStartingGame(unsigned char *routingaddress) {
  256. if(mIsLan || mUseOldScheme || tpGameCreated.numPlayers==1) {
  257. mGameCreationState = GAME_STARTED;
  258. InitPacketList();
  259. //CloseRoutingServerConnection(0);
  260. return true;
  261. }
  262. if(mGameCreationState==GAME_NOT_STARTED) {
  263. mgDisplayMsgBox();
  264. mgDisplayMessage(strGetString(strStartingGame));
  265. mGameCreationState = GAME_STARTING;
  266. mOldtpGameCreated = tpGameCreated;
  267. mNumPlayersJoined = 1;
  268. if(tpGameCreated.userBehindFirewall) {
  269. mgDisplayMessage(strGetString(strDetectedUserBehindFirewall));
  270. mgDisplayMessage(strGetString(strStartingRoutingServer));
  271. mUseRoutingServer = true;
  272. StartRoutingServer(L"",L"",L"",true,routingaddress);
  273. }
  274. else {
  275. mgDisplayMessage(strGetString(strTellingPlayersToConnectToMe));
  276. BeginStartGamePacket aPacket;
  277. aPacket.routingAddress = mMyIPAddress;
  278. aPacket.oldCaptainAddress = myAddress;
  279. aPacket.newCaptainAddress = mMyIPAddress;
  280. titanBroadcastPacket(TITANMSGTYPE_BEGINSTARTGAME, &aPacket, sizeof(aPacket));
  281. OnCaptainStartedGame();
  282. ChangeAddress(&(aPacket.oldCaptainAddress), &(aPacket.newCaptainAddress));
  283. myAddress = mMyIPAddress;
  284. mUseRoutingServer = false;
  285. }
  286. return false;
  287. }
  288. else if(mGameCreationState==GAME_STARTING)
  289. return false;
  290. else
  291. return true;
  292. }
  293. unsigned long titanBehindFirewall(void) {
  294. return titanInterface->BehindFirewall() ? 1 : 0;
  295. }
  296. bool TitanInterface::BehindFirewall() {
  297. return mBehindFirewall;
  298. }
  299. void titanRefreshRequest(char* theDir)
  300. {
  301. if (theDir != NULL)
  302. {
  303. return;
  304. }
  305. titanInterface->RequestDirectory();
  306. }
  307. void titanCreateGame(wchar_t *str, DirectoryCustomInfo* myInfo)
  308. {
  309. titanInterface->RequestCreateGame(str, myInfo);
  310. }
  311. void titanRemoveGame(wchar_t *str)
  312. {
  313. titanInterface->RequestDeleteGame(str);
  314. }
  315. void titanReplaceGameInfo(wchar_t *str, DirectoryCustomInfo* myInfo, unsigned long replaceTimeout)
  316. {
  317. titanInterface->RequestReplaceGame(str, myInfo, replaceTimeout);
  318. }
  319. void titanConnectToClient(Address* address)
  320. {
  321. titanInterface->ConnectToClient(address);
  322. }
  323. //void titanConnectToClient(unsigned long theIP, unsigned long thePort)
  324. //{
  325. // titanInterface->ConnectToClient(theIP, thePort);
  326. //}
  327. void titanSendPing(Address* address,unsigned int pingsizebytes)
  328. {
  329. titanInterface->SendPing(address,pingsizebytes);
  330. }
  331. //void titanSendPing(unsigned long theIP, unsigned long thePort)
  332. //{
  333. // titanInterface->SendPing(theIP, thePort);
  334. //}
  335. int titanStartChatServer(wchar_t* thePassword)
  336. {
  337. return titanInterface->StartRoutingServer(GetCurrentChannel(), GetCurrentChannelDescription(), thePassword, false, NULL);
  338. }
  339. void
  340. titanSendLanBroadcast(const void* thePacket, unsigned short theLen)
  341. {
  342. titanInterface->SendLanBroadcast(thePacket, theLen);
  343. }
  344. void
  345. titanSendPacketTo(Address *theAddressP, unsigned char titanMsgType,
  346. const void* thePacket, unsigned short theLen)
  347. {
  348. titanInterface->SendPacketTo(theAddressP, titanMsgType, thePacket, theLen);
  349. }
  350. //void
  351. //titanSendPacketTo(unsigned long theIP, unsigned long thePort, unsigned char titanMsgType,
  352. // const void* thePacket, unsigned short theLen)
  353. //{
  354. // titanInterface->SendPacketTo(theIP, thePort, titanMsgType, thePacket, theLen);
  355. //}
  356. void
  357. titanBroadcastPacket(unsigned char titanMsgType, const void* thePacket, unsigned short theLen)
  358. {
  359. titanInterface->BroadcastPacket(titanMsgType, thePacket, theLen);
  360. }
  361. void
  362. titanAnyoneSendPacketTo(Address *address, unsigned char titanMsgType,
  363. const void* thePacket, unsigned short theLen)
  364. {
  365. titanInterface->ConnectToClient(address);
  366. titanInterface->SendPacketTo(address, titanMsgType, thePacket, theLen);
  367. }
  368. //void
  369. //titanAnyoneSendPacketTo(unsigned long theIP, unsigned long thePort, unsigned char titanMsgType,
  370. // const void* thePacket, unsigned short theLen)
  371. //{
  372. // titanInterface->ConnectToClient(theIP, thePort);
  373. // titanInterface->SendPacketTo(theIP, thePort, titanMsgType, thePacket, theLen);
  374. //}
  375. void
  376. titanAnyoneBroadcastPacket(unsigned char titanMsgType, const void* thePacket, unsigned short theLen)
  377. {
  378. int i;
  379. for (i=0;i<tpGameCreated.numPlayers;i++)
  380. {
  381. if (!AddressesAreEqual(tpGameCreated.playerInfo[i].address,myAddress))
  382. {
  383. titanInterface->ConnectToClient(&(tpGameCreated.playerInfo[i].address));
  384. titanInterface->SendPacketTo(&(tpGameCreated.playerInfo[i].address), titanMsgType, thePacket, theLen);
  385. }
  386. }
  387. }
  388. // provided for temporary backward compatability
  389. void titanStartOld(signed long isLan)
  390. {
  391. if ( isLan )
  392. titanStart(1,0);
  393. else
  394. titanStart(0,1);
  395. }
  396. // note: assumes titanInterface not intialized
  397. unsigned long titanCheckCanNetwork(unsigned long isLan, unsigned long isIP)
  398. {
  399. if (!titanInterface)
  400. {
  401. titanInterface = new TitanInterface(isLan,isIP);
  402. if ( titanInterface->CanNetwork() == 0 )
  403. {
  404. delete titanInterface;
  405. titanInterface = NULL;
  406. return 0;
  407. }
  408. else
  409. {
  410. delete titanInterface;
  411. titanInterface = NULL;
  412. return 1;
  413. }
  414. }
  415. return 0;
  416. }
  417. unsigned long titanStart(unsigned long isLan, unsigned long isIP)
  418. {
  419. if (!titanInterface)
  420. {
  421. titanLogFileOpen();
  422. titanInterface = new TitanInterface(isLan,isIP);
  423. if ( titanInterface->CanNetwork() == 0 )
  424. {
  425. delete titanInterface;
  426. titanInterface = NULL;
  427. return 0;
  428. }
  429. if (!isLan)
  430. titanInterface->loadVerifierKey();
  431. titanInterface->startThread();
  432. if (!isLan)
  433. // Get Auth Server list and valid versions string
  434. titanInterface->RequestDirectory();
  435. }
  436. multiPlayerGame = TRUE;
  437. TitanActive = TRUE;
  438. TitanReadyToShutdown = FALSE;
  439. ResetChannel();
  440. //SetChannel(L"Default",L"Default"); // room now intelligently picked
  441. return 1;
  442. }
  443. // --MikeN
  444. // Call this method to begin shutdown of titan. Parameters specify packet to send
  445. // to connected client(s) (a shutdown message). The callback titanNoClientsCB() will
  446. // be invoked when complete.
  447. void titanStartShutdown(unsigned long titanMsgType, const void* thePacket,
  448. unsigned short theLen)
  449. {
  450. if (titanInterface)
  451. titanInterface->StartShutdown(titanMsgType,thePacket,theLen);
  452. }
  453. void titanShutdown(void)
  454. {
  455. if (titanInterface)
  456. {
  457. titanLogFileClose();
  458. titanInterface->stopThread();
  459. delete titanInterface;
  460. titanInterface = NULL;
  461. }
  462. multiPlayerGame = FALSE;
  463. TitanActive = FALSE;
  464. TitanReadyToShutdown = FALSE;
  465. }
  466. void titanPumpEngine()
  467. {
  468. titanInterface->PumpEngine();
  469. }
  470. #define WAIT_SHUTDOWN_MS 1000
  471. void titanWaitShutdown(void)
  472. {
  473. long waitfor = 0;
  474. for (;;)
  475. {
  476. if (TitanReadyToShutdown)
  477. {
  478. titanDebug("Titan ready to shut down...shutting down");
  479. break;
  480. }
  481. if (TitanActive)
  482. {
  483. titanPumpEngine();
  484. }
  485. Sleep(10);
  486. waitfor += 10;
  487. if (waitfor >= WAIT_SHUTDOWN_MS)
  488. {
  489. titanDebug("Titan timed out waiting for shutdown ready...shutting down");
  490. break;
  491. }
  492. }
  493. titanShutdown();
  494. }
  495. /*=============================================================================
  496. C code wrapper for chat functions:
  497. =============================================================================*/
  498. void chatConnect(wchar_t* thePassword)
  499. {
  500. titanInterface->ConnectToRoutingServer(StringToWString(utyName), thePassword, 0);
  501. }
  502. void chatClose(void)
  503. {
  504. if (titanInterface)
  505. titanInterface->CloseRoutingServerConnection(0);
  506. }
  507. void BroadcastChatMessage(unsigned short size, const void* chatData)
  508. {
  509. titanInterface->RoutingSendChatBroadcast(size, (const unsigned char*)chatData);
  510. }
  511. void SendPrivateChatMessage(unsigned long* userIDList, unsigned short numUsersInList, unsigned short size, const void* chatData)
  512. {
  513. titanInterface->RoutingSendChatWhisper(userIDList, numUsersInList, size, (const unsigned char*)chatData);
  514. }
  515. void titanSetGameKey(unsigned char *key)
  516. {
  517. titanInterface->SetGameKey(key);
  518. }
  519. const unsigned char *titanGetGameKey(void)
  520. {
  521. return titanInterface->GetGameKey();
  522. }
  523. int titanGetPatch(char *filename,char *saveFileName)
  524. {
  525. return titanInterface->GetPatch(filename,saveFileName);
  526. }
  527. /*=============================================================================
  528. Authentication server wrapper functions.:
  529. =============================================================================*/
  530. void authAuthenticate(char *loginName, char *password)
  531. {
  532. titanInterface->Authenticate(string(loginName), string(password), "", false);
  533. }
  534. void authCreateUser(char *loginName, char *password)
  535. {
  536. titanInterface->Authenticate(string(loginName), string(password), "", true);
  537. }
  538. void authChangePassword(char *loginName, char *oldpassword, char *newpassword)
  539. {
  540. titanInterface->Authenticate(string(loginName), string(oldpassword), string(newpassword), false);
  541. }
  542. ///////////////////////////////////////////////////////////////////////////////////////////
  543. ///////////////////////////////////////////////////////////////////////////////////////////
  544. TitanInterface::TitanInterface(unsigned long isLan, unsigned long isIP) :
  545. ThreadBase("TitanInterface"),
  546. mEngine(NULL),
  547. mAuthPipe(NULL),
  548. mDirPipe(NULL),
  549. mFactPipe(NULL),
  550. mLanAdPipe(NULL),
  551. mTimerPipe(NULL),
  552. mFirewallPipe(NULL),
  553. mCaptainPipe(NULL),
  554. mClientMap(),
  555. mCloseRequest(false),
  556. mHaveReceivedInitialUserList(false),
  557. mClientCrit(),
  558. mPipeCrit(),
  559. mRoutingCrit(),
  560. mGameKey(),
  561. mVerifierKey(NULL),
  562. mPrivateKey(NULL),
  563. mPublicKeyBlock(NULL),
  564. mCertificate(NULL),
  565. mAuthSessionKey(NULL),
  566. mDirSessionKey(NULL),
  567. mDirClientSecret(NULL),
  568. mFactSessionKey(NULL),
  569. mFactClientSecret(NULL),
  570. mRoutingInfoPipe(NULL),
  571. mEventPipe(NULL),
  572. mNumAuthServersTried(0),
  573. mCurAuthServer(0),
  574. mNumDirServersTried(0),
  575. mCurDirServer(0),
  576. mNumFactServersTried(0),
  577. mCurFactServer(0),
  578. mNumFirewallServersTried(0),
  579. mCurFirewallServer(0),
  580. FACTSERVER_NUM(0),
  581. AUTHSERVER_NUM(0),
  582. FIREWALLSERVER_NUM(0),
  583. EVENTSERVER_NUM(0),
  584. mNeedToAuthenticateAfterGettingAuthDirectory(false),
  585. mUseRoutingServer(true),
  586. mUseOldScheme(false),
  587. mBehindFirewall(false),
  588. mLaunched(false),
  589. mGameCreationState(GAME_NOT_STARTED),
  590. mNumPlayersJoined(0),
  591. mFactPingPipe(NULL),
  592. mCurFactPing(-1),
  593. mMinPingTime(-1),
  594. mNumPingTrials(0),
  595. mSeqNum(0),
  596. mRoutingQueryOffset(0),
  597. mCaptainReconnectNum(0),
  598. mEventTag(0),
  599. mHasLobbyEnterEventBeenSent(false),
  600. mMediaMetrixHWND(NULL),
  601. mRegisterRoutingServerMsg(true /* extended version */),
  602. mNeedToRegisterRoutingServer(false),
  603. mLobbyEnterTime(0),
  604. mGameStartTime(0),
  605. mHaveConnectedToAChatServer(false),
  606. mIsGameServer(false),
  607. mGameDisconnectWasVoluntary(false),
  608. mFailFactOverDirectly(false)
  609. {
  610. // Array initialization
  611. for(int n=0; n<2; n++) {
  612. mRoutePipe[n] = NULL;
  613. mRouteSessionKey[n] = NULL;
  614. mRouteClientSecret[n] = NULL;
  615. mMyClientId[n] = 0;
  616. mRoutingReconnect[n] = false;
  617. mRoutingReconnectNum[n] = 0;
  618. mLoggedInToRoutingServer[n] = false;
  619. }
  620. if ( isIP )
  621. {
  622. mIpType = ip;
  623. mDatagramType = EasySocket::UDP;
  624. mStreamType = EasySocket::TCP;
  625. }
  626. else
  627. {
  628. mIpType = ipx;
  629. mDatagramType = EasySocket::IPX;
  630. mStreamType = EasySocket::SPX;
  631. }
  632. if ( isLan )
  633. {
  634. mUseRoutingServer = false;
  635. mUseOldScheme = true;
  636. mIsLan = true;
  637. mGameKey.Create(GAMEKEY_SIZE, LAN_GAMEKEY);
  638. }
  639. else
  640. {
  641. mIsLan = false;
  642. mGameKey.Create(GAMEKEY_SIZE);
  643. mCurFactServer = time(NULL) % MAX_IPS;
  644. mCurFirewallServer = time(NULL) % MAX_IPS;
  645. mCurAuthServer = time(NULL) % MAX_IPS;
  646. }
  647. CreateMediaMetrixEditControl();
  648. // initialize winsock
  649. EasySocketEngine::startWinsock();
  650. }
  651. ///////////////////////////////////////////////////////////////////////////////////////////
  652. ///////////////////////////////////////////////////////////////////////////////////////////
  653. TitanInterface::~TitanInterface()
  654. {
  655. EasySocketEngine::stopWinsock();
  656. delete mVerifierKey;
  657. delete mPrivateKey;
  658. delete mPublicKeyBlock;
  659. delete mCertificate;
  660. delete mAuthSessionKey;
  661. delete mDirSessionKey;
  662. delete mDirClientSecret;
  663. delete mFactSessionKey;
  664. delete mFactClientSecret;
  665. for(int n=0; n<2; n++) {
  666. delete mRouteSessionKey[n];
  667. delete mRouteClientSecret[n];
  668. }
  669. }
  670. ///////////////////////////////////////////////////////////////////////////////////////////
  671. ///////////////////////////////////////////////////////////////////////////////////////////
  672. void TitanInterface::ChangeAddress(Address *theOldAddress, Address *theNewAddress)
  673. {
  674. int i;
  675. for (i=0;i<tpGameCreated.numPlayers;i++)
  676. {
  677. if (AddressesAreEqual(mOldtpGameCreated.playerInfo[i].address,*theOldAddress))
  678. {
  679. tpGameCreated.playerInfo[i].address = *theNewAddress;
  680. return;
  681. }
  682. }
  683. }
  684. ///////////////////////////////////////////////////////////////////////////////////////////
  685. ///////////////////////////////////////////////////////////////////////////////////////////
  686. unsigned long TitanInterface::CanNetwork(void)
  687. {
  688. SOCKET aSocket;
  689. bool success = false;
  690. int bindSuccess = false;
  691. if ( mIpType == ip )
  692. {
  693. aSocket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
  694. if ( aSocket != INVALID_SOCKET )
  695. {
  696. SOCKADDR_IN aSockAddrIn;
  697. memset((char *)&aSockAddrIn, 0, sizeof(aSockAddrIn));
  698. aSockAddrIn.sin_family = AF_INET;
  699. aSockAddrIn.sin_addr.s_addr = htonl(INADDR_ANY);
  700. aSockAddrIn.sin_port = htons(0);
  701. bindSuccess = bind( aSocket, (SOCKADDR*)(&aSockAddrIn), sizeof(SOCKADDR_IN) );
  702. if ( bindSuccess == 0 )
  703. success = true;
  704. closesocket(aSocket);
  705. }
  706. }
  707. else
  708. {
  709. aSocket = socket( AF_IPX, SOCK_STREAM, NSPROTO_SPX);
  710. if ( aSocket != INVALID_SOCKET )
  711. {
  712. SOCKADDR_IPX aSockAddrIpx;
  713. memset((char *)&aSockAddrIpx, 0, sizeof(aSockAddrIpx));
  714. aSockAddrIpx.sa_family = AF_IPX;
  715. aSockAddrIpx.sa_socket = htons(0); // sa_socket is the IPX equivalent of port
  716. bindSuccess = bind( aSocket, (SOCKADDR*)(&aSockAddrIpx), sizeof(aSockAddrIpx) );
  717. if ( bindSuccess == 0 )
  718. success = true;
  719. closesocket(aSocket);
  720. }
  721. }
  722. if ( success == true )
  723. return 1;
  724. else
  725. return 0;
  726. }
  727. ///////////////////////////////////////////////////////////////////////////////////////////
  728. ///////////////////////////////////////////////////////////////////////////////////////////
  729. int TitanInterface::GetPatch(const char *theFilename,const char *saveFileName) {
  730. string *anArgP;
  731. anArgP = new string[2];
  732. anArgP[0] = theFilename;
  733. anArgP[1] = saveFileName;
  734. int aHandle;
  735. aHandle = _beginthread(GetPatch,0,anArgP);
  736. if(aHandle==-1)
  737. titanGetPatchFailedCB(PATCHFAIL_UNABLE_TO_START_DOWNLOAD_THREAD);
  738. return 0;
  739. }
  740. ///////////////////////////////////////////////////////////////////////////////////////////
  741. ///////////////////////////////////////////////////////////////////////////////////////////
  742. void TitanInterface::GetPatch(void *theArgs)
  743. {
  744. EasySocket aSocket(EasySocket::TCP);
  745. ES_ErrorType anError;
  746. // Read in the Parameters
  747. string theFilename = ((string*)theArgs)[0];
  748. string saveFileName = ((string*)theArgs)[1];
  749. delete [] (string*)theArgs;
  750. // Construct the HTTP request
  751. string aRequest;
  752. aRequest += string("GET /") + theFilename + string(" HTTP/1.1\r\n");
  753. aRequest += "Host: " + string(PATCHSERVER_IPSTRINGS[0]) + "\r\n";
  754. char aBuf[1000];
  755. struct _stat anInfo;
  756. // Check for old file and when it was last modified
  757. char anOldDate[255], aNewDate[255];
  758. anOldDate[0] = aNewDate[0] = aNewDate[254] = '\0';
  759. FILE *aModFile = fopen("modified.txt","r");
  760. if(aModFile!=NULL) {
  761. fread(anOldDate,1,255,aModFile);
  762. fclose(aModFile);
  763. int aResult;
  764. aResult = _stat(saveFileName.c_str(),&anInfo);
  765. // If an old file exists and we know when it was last modified then
  766. // do a conditional range get
  767. if(aResult==0) {
  768. aRequest+= "If-Range: " + string(anOldDate) + "\r\n";
  769. aRequest+= "Range: bytes="+string(ltoa(anInfo.st_size,aBuf,10))+"-\r\n";
  770. }
  771. else {
  772. anInfo.st_size = 0;
  773. anOldDate[0] = '\0';
  774. }
  775. }
  776. aRequest+="\r\n";
  777. // Connect to Web Server
  778. anError = aSocket.connect(string(PATCHSERVER_IPSTRINGS[0]),PATCHSERVER_PORTS[0],0);
  779. if(anError!=WONMisc::ES_NO_ERROR) {
  780. titanGetPatchFailedCB(PATCHFAIL_UNABLE_TO_CONNECT);
  781. titanDebug("FAIL TitanInterface::GetPatch PATCHFAIL_UNABLE_TO_CONNECT (1) Error: %d", anError);
  782. return;
  783. }
  784. do {
  785. anError = aSocket.checkAsynchConnect(1000);
  786. if (anError == WONMisc::ES_NO_ERROR)
  787. break;
  788. else if (anError != WONMisc::ES_TIMED_OUT)
  789. {
  790. titanGetPatchFailedCB(PATCHFAIL_UNABLE_TO_CONNECT);
  791. titanDebug("FAIL TitanInterface::GetPatch PATCHFAIL_UNABLE_TO_CONNECT (2) Error: %d", anError);
  792. return;
  793. }
  794. if (patchAbortRequest)
  795. {
  796. titanGetPatchFailedCB(PATCHFAIL_USERABORT);
  797. titanDebug("FAIL TitanInterface::GetPatch PATCHFAIL_USERABORT");
  798. return;
  799. }
  800. } while (anError == WONMisc::ES_TIMED_OUT);
  801. // Send the HTTP request
  802. do {
  803. anError = aSocket.sendBuffer((void*)aRequest.c_str(),aRequest.length());
  804. if (patchAbortRequest)
  805. {
  806. titanGetPatchFailedCB(PATCHFAIL_USERABORT);
  807. titanDebug("FAIL TitanInterface::GetPatch PATCHFAIL_USERABORT");
  808. return;
  809. }
  810. } while(anError==WONMisc::ES_TIMED_OUT);
  811. if(anError!=WONMisc::ES_NO_ERROR) {
  812. titanGetPatchFailedCB(PATCHFAIL_ERROR_SENDING_REQUEST);
  813. titanDebug("FAIL TitanInterface::GetPatch PATCHFAIL_ERROR_SENDING_REQUEST Error: %d", anError);
  814. return;
  815. }
  816. char ch = ' ';
  817. string aLine;
  818. int aFileLen = -1;
  819. bool append = false;
  820. bool readFirstLine = false;
  821. // Read HTTP header
  822. while(true)
  823. {
  824. aLine.erase();
  825. // Read a line of the Header
  826. while(true)
  827. {
  828. if (patchAbortRequest)
  829. {
  830. titanGetPatchFailedCB(PATCHFAIL_USERABORT);
  831. titanDebug("FAIL TitanInterface::GetPatch PATCHFAIL_USERABORT");
  832. return;
  833. }
  834. anError = aSocket.recvBuffer(&ch,1);
  835. if(anError!=WONMisc::ES_NO_ERROR) {
  836. if(anError==WONMisc::ES_TIMED_OUT)
  837. continue;
  838. titanGetPatchFailedCB(PATCHFAIL_ERROR_RECEIVING_HTTP_HEADER);
  839. titanDebug("FAIL TitanInterface::GetPatch PATCHFAIL_ERROR_RECEIVING_HTTP_HEADER (1) Error: %d", anError);
  840. return;
  841. }
  842. if(ch!='\r')
  843. aLine+=ch;
  844. else {
  845. do {
  846. anError = aSocket.recvBuffer(&ch,1);
  847. if (patchAbortRequest)
  848. {
  849. titanGetPatchFailedCB(PATCHFAIL_USERABORT);
  850. titanDebug("FAIL TitanInterface::GetPatch PATCHFAIL_USERABORT");
  851. return;
  852. }
  853. } while(anError==WONMisc::ES_TIMED_OUT);
  854. if(anError!=WONMisc::ES_NO_ERROR) {
  855. titanGetPatchFailedCB(PATCHFAIL_ERROR_RECEIVING_HTTP_HEADER);
  856. titanDebug("FAIL TitanInterface::GetPatch PATCHFAIL_ERROR_RECEIVING_HTTP_HEADER (2) Error: %d", anError);
  857. return;
  858. }
  859. if(ch!='\n') {
  860. aLine+='\r';
  861. aLine+=ch;
  862. }
  863. else
  864. break;
  865. }
  866. }
  867. // Inspect the line
  868. if(aLine.length()==0) // Nothing -> finished reading header
  869. break;
  870. if(readFirstLine==false) {
  871. readFirstLine = true;
  872. if(strstr(aLine.c_str(),"200")!=NULL) // 200 -> Get entire body
  873. append = false; // Full get
  874. else if(strstr(aLine.c_str(),"206")!=NULL) // 206 -> Get partial body
  875. append = true; // Partial get
  876. else
  877. {
  878. titanGetPatchFailedCB(PATCHFAIL_INVALID_STATUS_REPLY);
  879. titanDebug("FAIL TitanInterface::GetPatch PATCHFAIL_INVALID_STATUS_REPLY HTTP status line = \"%s\"", aLine.c_str());
  880. return;
  881. }
  882. }
  883. if(aFileLen==-1) // Check for Content-Length
  884. sscanf(aLine.c_str(),"Content-Length: %d",&aFileLen);
  885. if(aNewDate[0]=='\0') { // Check for Last-Modified
  886. const char *aPtr = strstr(aLine.c_str(),"Last-Modified: ");
  887. if(aPtr!=NULL) {
  888. aPtr+=strlen("Last-Modified: ");
  889. strncpy(aNewDate, aPtr, 254);
  890. aModFile = fopen("modified.txt","w");
  891. if(aModFile!=NULL) {
  892. fwrite(aNewDate,1,strlen(aNewDate)+1,aModFile);
  893. fclose(aModFile);
  894. }
  895. }
  896. }
  897. }
  898. if(!append && !strcmp(anOldDate, aNewDate)) {
  899. // The web server returns 200 (Full Get) if you request zero bytes of the file
  900. titanGetPatchCompleteCB();
  901. return;
  902. }
  903. if(aFileLen<=0) {
  904. titanGetPatchFailedCB(PATCHFAIL_INVALID_FILE_LENGTH);
  905. titanDebug("FAIL TitanInterface::GetPatch PATCHFAIL_INVALID_FILE_LENGTH File-length = %d", aFileLen);
  906. return;
  907. }
  908. int aLen, aTotalLen = 0;
  909. if(append) {
  910. aTotalLen = anInfo.st_size;
  911. aFileLen+=aTotalLen;
  912. }
  913. FILE *aFile;
  914. if(append) // Continue download
  915. aFile = fopen(saveFileName.c_str(),"a+b");
  916. else // start download
  917. aFile = fopen(saveFileName.c_str(),"wb");
  918. if(aFile==NULL) {
  919. titanGetPatchFailedCB(PATCHFAIL_UNABLE_TO_CREATE_FILE);
  920. titanDebug("FAIL TitanInterface::GetPatch PATCHFAIL_UNABLE_TO_CREATE_FILE errno = %d", errno);
  921. return;
  922. }
  923. while(true) {
  924. aLen = 0;
  925. anError = aSocket.recvBuffer(aBuf,1000,&aLen);
  926. aTotalLen+=aLen;
  927. if(anError==WONMisc::ES_NO_ERROR || anError==WONMisc::ES_INCOMPLETE_RECV)
  928. {
  929. if(fwrite(aBuf,1,aLen,aFile)!=aLen) {
  930. titanGetPatchFailedCB(PATCHFAIL_UNABLE_TO_WRITE_FILE);
  931. titanDebug("FAIL TitanInterface::GetPatch PATCHFAIL_UNABLE_TO_WRITE_FILE (1) ferror = %d, errno = %d", ferror(aFile), errno);
  932. fclose(aFile);
  933. return;
  934. }
  935. }
  936. else if(anError!=WONMisc::ES_TIMED_OUT) {
  937. titanGetPatchFailedCB(PATCHFAIL_ERROR_RECEIVING_PATCH);
  938. titanDebug("FAIL TitanInterface::GetPatch PATCHFAIL_ERROR_RECEIVING_PATCH Error: %d", anError);
  939. fclose(aFile);
  940. return;
  941. }
  942. titanPatchProgressCB(aTotalLen,aFileLen);
  943. if(aTotalLen>=aFileLen)
  944. break;
  945. if (patchAbortRequest)
  946. {
  947. titanGetPatchFailedCB(PATCHFAIL_USERABORT);
  948. titanDebug("FAIL TitanInterface::GetPatch PATCHFAIL_USERABORT");
  949. fclose(aFile);
  950. return;
  951. }
  952. }
  953. if(fclose(aFile)==EOF) {
  954. titanGetPatchFailedCB(PATCHFAIL_UNABLE_TO_WRITE_FILE);
  955. titanDebug("FAIL TitanInterface::GetPatch PATCHFAIL_UNABLE_TO_WRITE_FILE (2) ferror = %d, errno = %d", ferror(aFile), errno);
  956. return;
  957. }
  958. titanGetPatchCompleteCB();
  959. }
  960. ///////////////////////////////////////////////////////////////////////////////////////////
  961. ///////////////////////////////////////////////////////////////////////////////////////////
  962. void TitanInterface::SetGameKey(unsigned char *key)
  963. {
  964. mGameKey.Create(GAMEKEY_SIZE,key);
  965. }
  966. const unsigned char *TitanInterface::GetGameKey(void)
  967. {
  968. return mGameKey.GetKey();
  969. }
  970. void TitanInterface::loadVerifierKey()
  971. {
  972. unsigned char* aBuf = NULL; // buffer is allocated by titanLoadPublicKey
  973. unsigned short aLen;
  974. aLen = titanLoadPublicKey(VERIFIER_KEY_FILE_NAME,&aBuf);
  975. if(aLen==0) {
  976. titanDebug("FAIL: Unable to read verifier key.");
  977. return;
  978. }
  979. try {
  980. mVerifierKey = new EGPublicKey(aLen,aBuf);
  981. }
  982. catch(WONException&) {
  983. titanDebug("EXCEPTION: Failed to create verifier key.");
  984. mVerifierKey = NULL;
  985. }
  986. free(aBuf);
  987. }
  988. void
  989. TitanInterface::PumpEngine()
  990. {
  991. EasySocketEngine::Pump(mEngine);
  992. }
  993. void
  994. TitanInterface::startThread()
  995. {
  996. // Create engine and start (launches the engine thread)
  997. mEngine = new EasySocketEngine(3, 0, false);
  998. // Add the timer pipe to the engine for certificate refreshes
  999. mTimerPipe = new SocketPipe;
  1000. mEngine->AddPipe(mTimerPipe);
  1001. // Start up the message receive thread
  1002. ThreadBase::startThread();
  1003. }
  1004. ///////////////////////////////////////////////////////////////////////////////////////////
  1005. ///////////////////////////////////////////////////////////////////////////////////////////
  1006. void
  1007. TitanInterface::stopThread()
  1008. {
  1009. if (!mIsLan)
  1010. OnFinalLobbyExit();
  1011. // Stop the message receive thread
  1012. SetEvent(getStopEvent());
  1013. if (mEngine)
  1014. mEngine->AbortGetCompletedPipe();
  1015. ThreadBase::stopThread();
  1016. // Shutdown the engine if needed
  1017. if (mEngine)
  1018. {
  1019. delete mEngine; mEngine = NULL;
  1020. }
  1021. }
  1022. ///////////////////////////////////////////////////////////////////////////////////////////
  1023. ///////////////////////////////////////////////////////////////////////////////////////////
  1024. void TitanInterface::BuildAddress(SOCKADDR_IN& theAddrR, long theIP, unsigned short thePort)
  1025. {
  1026. theAddrR.sin_family = AF_INET;
  1027. theAddrR.sin_addr.s_addr = theIP;
  1028. theAddrR.sin_port = htons(thePort);
  1029. }
  1030. void TitanInterface::BuildAddress(SOCKADDR_IN& theAddrR, const WONCommon::RawBuffer& theSixBytes)
  1031. {
  1032. theAddrR.sin_family = AF_INET;
  1033. memcpy(&theAddrR.sin_port, theSixBytes.data(), 6);
  1034. }
  1035. void TitanInterface::BuildAddress(SOCKADDR_IN& theAddrR, unsigned char buffer[])
  1036. {
  1037. theAddrR.sin_family = AF_INET;
  1038. memcpy(&theAddrR.sin_port, buffer, 6);
  1039. }
  1040. const char* TitanInterface::PrintAddress(SOCKADDR_IN& theAddrR)
  1041. {
  1042. static char aAddrString[22];
  1043. sprintf(aAddrString, "%d.%d.%d.%d:%d", theAddrR.sin_addr.S_un.S_un_b.s_b1, theAddrR.sin_addr.S_un.S_un_b.s_b2, theAddrR.sin_addr.S_un.S_un_b.s_b3, theAddrR.sin_addr.S_un.S_un_b.s_b4, ntohs(theAddrR.sin_port));
  1044. return aAddrString;
  1045. }
  1046. const char* TitanInterface::PrintAddress(const WONCommon::RawBuffer& theSixBytes)
  1047. {
  1048. SOCKADDR_IN aSockAddrIn;
  1049. BuildAddress(aSockAddrIn, theSixBytes);
  1050. return PrintAddress(aSockAddrIn);
  1051. }
  1052. ///////////////////////////////////////////////////////////////////////////////////////////
  1053. ///////////////////////////////////////////////////////////////////////////////////////////
  1054. unsigned long
  1055. TitanInterface::GetLocalIPAddress(void)
  1056. {
  1057. SOCKET aSocket;
  1058. long aLong;
  1059. long anotherLong;
  1060. int aRetValue;
  1061. int anAddrSize;
  1062. BOOL aBool = 1;
  1063. DWORD SectorsPerCluster;
  1064. DWORD BytesPerSector;
  1065. DWORD NumberOfFreeClusters;
  1066. DWORD NumberOfClusters;
  1067. BOOL success;
  1068. success = GetDiskFreeSpace(NULL,&SectorsPerCluster,&BytesPerSector,&NumberOfFreeClusters,&NumberOfClusters);
  1069. if ( success == FALSE )
  1070. return 0;
  1071. aLong = GetTickCount();
  1072. aLong += (SectorsPerCluster * BytesPerSector * NumberOfFreeClusters );
  1073. anotherLong = aLong;
  1074. aSocket = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
  1075. if ( aSocket == INVALID_SOCKET )
  1076. return 0;
  1077. aRetValue = setsockopt(aSocket,SOL_SOCKET,SO_BROADCAST, (char*)(&aBool), sizeof(BOOL) );
  1078. if ( aRetValue != 0 )
  1079. {
  1080. closesocket(aSocket);
  1081. return 0;
  1082. }
  1083. SOCKADDR_IN aSockAddrIn;
  1084. memset((char *)&aSockAddrIn, 0, sizeof(aSockAddrIn));
  1085. aSockAddrIn.sin_family = AF_INET;
  1086. aSockAddrIn.sin_addr.s_addr = htonl(INADDR_ANY);
  1087. aSockAddrIn.sin_port = htons(48357);
  1088. aRetValue = bind( aSocket, (SOCKADDR*)(&aSockAddrIn), sizeof(SOCKADDR_IN) );
  1089. if ( aRetValue != 0 )
  1090. {
  1091. closesocket(aSocket);
  1092. return 0;
  1093. }
  1094. aSockAddrIn.sin_addr.s_addr = htonl(INADDR_BROADCAST);
  1095. aRetValue = sendto(aSocket,(char*)&aLong,sizeof(long),0,(SOCKADDR*)(&aSockAddrIn), sizeof(SOCKADDR_IN) );
  1096. if ( aRetValue != sizeof(long) )
  1097. {
  1098. closesocket(aSocket);
  1099. return 0;
  1100. }
  1101. do {
  1102. anAddrSize = sizeof(SOCKADDR_IN);
  1103. aRetValue = recvfrom(aSocket,(char*)&aLong,sizeof(long),0,(SOCKADDR*)(&aSockAddrIn), &anAddrSize );
  1104. } while (aRetValue == sizeof(long) && anotherLong != aLong );
  1105. closesocket(aSocket);
  1106. if ( aRetValue != sizeof(long) )
  1107. return 0;
  1108. return aSockAddrIn.sin_addr.s_addr;
  1109. // return ntohl(aSockAddrIn.sin_addr.s_addr);
  1110. }
  1111. ///////////////////////////////////////////////////////////////////////////////////////////
  1112. ///////////////////////////////////////////////////////////////////////////////////////////
  1113. unsigned long TitanInterface::GetLengthFieldSize(const BaseMessage& theMsgR)
  1114. {
  1115. switch (theMsgR.GetMessageClass())
  1116. {
  1117. case WONMsg::eTMessage:
  1118. case WONMsg::eSmallMessage:
  1119. return 4;
  1120. case WONMsg::eMiniMessage:
  1121. return 2;
  1122. default:
  1123. return 0;
  1124. }
  1125. }
  1126. ///////////////////////////////////////////////////////////////////////////////////////////
  1127. ///////////////////////////////////////////////////////////////////////////////////////////
  1128. bool
  1129. TitanInterface::SendMsg(SocketPipe* thePipeP, const BaseMessage& theMsgR, unsigned char theLengthFieldSize)
  1130. {
  1131. if(thePipeP==NULL)
  1132. return false;
  1133. // Build send buffer
  1134. unsigned long aMsgLen = theMsgR.GetDataLen();
  1135. if (theLengthFieldSize==0)
  1136. theLengthFieldSize = GetLengthFieldSize(theMsgR);
  1137. if (theLengthFieldSize==0)
  1138. {
  1139. titanDebug("TitanInterface::SendMsg Invalid message class type.");
  1140. return false;
  1141. }
  1142. aMsgLen+=theLengthFieldSize;
  1143. char *aBuf = new char[aMsgLen];
  1144. if(theLengthFieldSize==2) *(unsigned short*)aBuf = aMsgLen;
  1145. else if(theLengthFieldSize==4) *(unsigned long*)aBuf = aMsgLen;
  1146. else _ASSERT(0);
  1147. #ifdef LOG_MESSAGE_SIZE
  1148. titanDebug("TitanInterface::SendMsg Sending %d bytes", aMsgLen + theLengthFieldSize);
  1149. #endif // LOG_MESSAGE_SIZE
  1150. memcpy(aBuf+theLengthFieldSize,theMsgR.GetDataPtr(),theMsgR.GetDataLen());
  1151. // Send the buffer
  1152. thePipeP->AddOutgoingCmd(new SendCmd(aBuf, aMsgLen, true, true));
  1153. return true;
  1154. }
  1155. ///////////////////////////////////////////////////////////////////////////////////////////
  1156. ///////////////////////////////////////////////////////////////////////////////////////////
  1157. SocketPipe* TitanInterface::ConnectTo(const Address& theDest, EasySocket::SocketType theType, WONMisc::RecvLengthPrefixType thePrefixType)
  1158. {
  1159. SOCKADDR anAddr;
  1160. if ( mIpType == ip )
  1161. BuildAddress(reinterpret_cast<SOCKADDR_IN&>(anAddr), theDest.AddrPart.IP, theDest.Port);
  1162. else
  1163. EasySocket::getSockAddrIpx(reinterpret_cast<SOCKADDR_IPX&>(anAddr), theDest.AddrPart.etherAddr, theDest.Port);
  1164. return ConnectTo(anAddr, theType, thePrefixType);
  1165. }
  1166. SocketPipe* TitanInterface::ConnectTo(const SOCKADDR& theDest, EasySocket::SocketType theType, WONMisc::RecvLengthPrefixType thePrefixType)
  1167. {
  1168. // Create a TCP pipe
  1169. SocketPipe* aPipeP = new SocketPipe;
  1170. aPipeP->AddOutgoingCmd(new OpenCmd(theType));
  1171. // Connect to destination, set event when done
  1172. HANDLE anEvent = CreateEvent(NULL, false, false, NULL);
  1173. aPipeP->AddOutgoingCmd(new SmartConnectCmd(theDest, CONNECT_TIMEOUT, 1, true));
  1174. aPipeP->AddOutgoingCmd(new SetEventCmd(anEvent));
  1175. // Add a bunch of RecvCmds
  1176. aPipeP->AddIncomingCmd(new WaitForEventCmd(anEvent, true, false));
  1177. for (int i=0; i < PREPOST_MAX; i++)
  1178. aPipeP->AddIncomingCmd(new RecvPrefCmd(false, thePrefixType, false));
  1179. return aPipeP;
  1180. }
  1181. ///////////////////////////////////////////////////////////////////////////////////////////
  1182. ///////////////////////////////////////////////////////////////////////////////////////////
  1183. SocketPipe* TitanInterface::ConnectAndSend(const Address& theDest, const BaseMessage& theMsgR, EasySocket::SocketType theType, WONMisc::RecvLengthPrefixType thePrefixType)
  1184. {
  1185. SOCKADDR anAddr;
  1186. if ( mIpType == ip )
  1187. BuildAddress(reinterpret_cast<SOCKADDR_IN&>(anAddr), theDest.AddrPart.IP, theDest.Port);
  1188. else
  1189. EasySocket::getSockAddrIpx(reinterpret_cast<SOCKADDR_IPX&>(anAddr), theDest.AddrPart.etherAddr, theDest.Port);
  1190. return ConnectAndSend(anAddr, theMsgR, theType, thePrefixType);
  1191. }
  1192. SocketPipe* TitanInterface::ConnectAndSend(const SOCKADDR_IN& theDest, const BaseMessage& theMsgR, EasySocket::SocketType theType, WONMisc::RecvLengthPrefixType thePrefixType)
  1193. { return ConnectAndSend(reinterpret_cast<const SOCKADDR&>(theDest), theMsgR, theType, thePrefixType); }
  1194. SocketPipe* TitanInterface::ConnectAndSend(const SOCKADDR& theDest, const BaseMessage& theMsgR, EasySocket::SocketType theType, WONMisc::RecvLengthPrefixType thePrefixType)
  1195. {
  1196. // Create a TCP pipe
  1197. SocketPipe* aPipeP = ConnectTo(theDest, theType, thePrefixType);
  1198. if (aPipeP)
  1199. {
  1200. int aLengthFieldSize = 4;
  1201. switch(thePrefixType) {
  1202. case WONMisc::ptByte:
  1203. case WONMisc::ptUnsignedByte: aLengthFieldSize = 1; break;
  1204. case WONMisc::ptShort:
  1205. case WONMisc::ptUnsignedShort: aLengthFieldSize = 2; break;
  1206. case WONMisc::ptLong:
  1207. case WONMisc::ptUnsignedLong: aLengthFieldSize = 4; break;
  1208. }
  1209. // Send message
  1210. if (! SendMsg(aPipeP, theMsgR, aLengthFieldSize))
  1211. {
  1212. titanDebug("FAIL: TitanInterface::SendMsg!");
  1213. delete aPipeP; aPipeP = NULL;
  1214. }
  1215. // Hand off pipe to the engine
  1216. else
  1217. mEngine->AddPipe(aPipeP);
  1218. }
  1219. return aPipeP;
  1220. }
  1221. ///////////////////////////////////////////////////////////////////////////////////////////
  1222. ///////////////////////////////////////////////////////////////////////////////////////////
  1223. void TitanInterface::AuthFailOver(void)
  1224. {
  1225. titanDebug("TitanInterface::AuthFailOver");
  1226. mNumAuthServersTried++; // Trying another auth server
  1227. if(mNumAuthServersTried>=AUTHSERVER_NUM)
  1228. {
  1229. titanDebug("TitanInterface::AuthFailOver FAILED all %d authservers.", AUTHSERVER_NUM);
  1230. mgNotifyAuthRequestFailed();
  1231. ResetAuthFailOver();
  1232. return;
  1233. }
  1234. mCurAuthServer = (mCurAuthServer + 1) % AUTHSERVER_NUM;
  1235. titanDebug("TitanInterface::AuthFailOver Trying %s", PrintAddress(AUTHSERVER_ADDRESSES[mCurAuthServer]));
  1236. Authenticate(mLoginName,mPassword,"",false);
  1237. }
  1238. ///////////////////////////////////////////////////////////////////////////////////////////
  1239. ///////////////////////////////////////////////////////////////////////////////////////////
  1240. void TitanInterface::ResetAuthFailOver(void)
  1241. {
  1242. titanDebug("TitanInterface::ResetAuthFailOver");
  1243. mNumAuthServersTried = 0;
  1244. }
  1245. ///////////////////////////////////////////////////////////////////////////////////////////
  1246. ///////////////////////////////////////////////////////////////////////////////////////////
  1247. void TitanInterface::DirFailOver(void)
  1248. {
  1249. titanDebug("TitanInterface::DirFailOver");
  1250. delete mDirSessionKey;
  1251. mDirSessionKey = NULL;
  1252. mNumDirServersTried++; // Trying another auth server
  1253. if(mNumDirServersTried>=DIRSERVER_NUM)
  1254. {
  1255. titanDebug("TitanInterface::DirFailOver FAILED all %d dir servers.", DIRSERVER_NUM);
  1256. mgNotifyDirRequestFailed();
  1257. ResetDirFailOver();
  1258. return;
  1259. }
  1260. mCurDirServer = (mCurDirServer + 1) % DIRSERVER_NUM;
  1261. titanDebug("TitanInterface::DirFailOver Trying %s:%d", DIRSERVER_IPSTRINGS[mCurDirServer], DIRSERVER_PORTS[mCurDirServer]);
  1262. RequestDirectory();
  1263. }
  1264. ///////////////////////////////////////////////////////////////////////////////////////////
  1265. ///////////////////////////////////////////////////////////////////////////////////////////
  1266. void TitanInterface::ResetDirFailOver(void)
  1267. {
  1268. titanDebug("TitanInterface::ResetDirFailOver");
  1269. mNumDirServersTried = 0;
  1270. }
  1271. ///////////////////////////////////////////////////////////////////////////////////////////
  1272. ///////////////////////////////////////////////////////////////////////////////////////////
  1273. void TitanInterface::FactFailOver(void)
  1274. {
  1275. titanDebug("TitanInterface::FactFailOver");
  1276. delete mFactSessionKey;
  1277. mFactSessionKey = NULL;
  1278. if (mFailFactOverDirectly)
  1279. {
  1280. mgStartSpecificFactServerFailedCB();
  1281. ResetFactFailOver();
  1282. return;
  1283. }
  1284. mNumFactServersTried++; // Trying another factory server
  1285. if(mNumFactServersTried >= FACTSERVER_NUM) {
  1286. titanDebug("TitanInterface::FactFailOver FactFailOver FAILED all %d factory servers.", FACTSERVER_NUM);
  1287. if (mGameCreationState == GAME_NOT_STARTED)
  1288. titanStartChatReplyReceivedCB(WONMsg::StatusCommon_Failure);
  1289. else
  1290. {
  1291. mgDisplayMessage(strGetString(strServerDown));
  1292. mgDisplayMessage(strGetString(strHitCancelAgain));
  1293. }
  1294. ResetFactFailOver();
  1295. return;
  1296. }
  1297. mCurFactServer = (mCurFactServer + 1) % FACTSERVER_NUM;
  1298. titanDebug("TitanInterface::FactFailOver Trying %s", PrintAddress(FACTSERVER_ADDRESSES[mCurFactServer]));
  1299. AutoCrit aCrit(mStartRoutingCrit);
  1300. if(mRoomPassword.length()!=0)
  1301. StartRoutingServer(mChannelName.c_str(),mChannelDescription.c_str(),mRoomPassword.c_str(),mIsGameServer,NULL);
  1302. else
  1303. StartRoutingServer(mChannelName.c_str(),mChannelDescription.c_str(),NULL,mIsGameServer,NULL);
  1304. }
  1305. ///////////////////////////////////////////////////////////////////////////////////////////
  1306. ///////////////////////////////////////////////////////////////////////////////////////////
  1307. void TitanInterface::ResetFactFailOver(void)
  1308. {
  1309. titanDebug("TitanInterface::ResetFactFailOver");
  1310. mNumFactServersTried = 0;
  1311. }
  1312. ///////////////////////////////////////////////////////////////////////////////////////////
  1313. ///////////////////////////////////////////////////////////////////////////////////////////
  1314. void TitanInterface::FirewallFailOver(void)
  1315. {
  1316. titanDebug("TitanInterface::FirewallFailOver");
  1317. mNumFirewallServersTried++; // Trying another auth server
  1318. if(mNumFirewallServersTried>=FIREWALLSERVER_NUM)
  1319. {
  1320. titanDebug("TitanInterface::FirewallFailOver FAILED all %d firewall servers.", FIREWALLSERVER_NUM);
  1321. return;
  1322. }
  1323. mCurFirewallServer = (mCurFirewallServer + 1) % FIREWALLSERVER_NUM;
  1324. titanDebug("TitanInterface::FirewallFailOver Trying %s", PrintAddress(FIREWALLSERVER_ADDRESSES[mCurFirewallServer]));
  1325. FirewallDetect();
  1326. }
  1327. ///////////////////////////////////////////////////////////////////////////////////////////
  1328. ///////////////////////////////////////////////////////////////////////////////////////////
  1329. void TitanInterface::FirewallDetect(void)
  1330. {
  1331. titanDebug("TitanInterface::FirewallDetect");
  1332. AutoCrit aCrit(mPipeCrit);
  1333. // Toss old connection if needed
  1334. if (mFirewallPipe)
  1335. {
  1336. titanDebug("NOTE: TitanInterface::FirewallDetect Close existing FirewallPipe");
  1337. mFirewallPipe->AddOutgoingCmd(new CloseNowCmd(false, false, 0, false));
  1338. mFirewallPipe = NULL;
  1339. }
  1340. aCrit.Leave();
  1341. WONMsg::SMsgFirewallDetect aMsg;
  1342. aMsg.SetListenPort(GAME_PORT);
  1343. if(mCurFirewallServer>=FIREWALLSERVER_NUM) {
  1344. if(FIREWALLSERVER_NUM>0)
  1345. mCurFirewallServer%=FIREWALLSERVER_NUM;
  1346. else
  1347. return;
  1348. }
  1349. try
  1350. {
  1351. aMsg.Pack();
  1352. }
  1353. catch (WONException& anEx)
  1354. {
  1355. titanDebug("EXCEPTION: TitanInterface::FirewallDetect: %s", (char*)anEx.what());
  1356. return;
  1357. }
  1358. mFirewallPipe = ConnectAndSend(FIREWALLSERVER_ADDRESSES[mCurFirewallServer], aMsg, EasySocket::TCP, WONMisc::ptUnsignedShort);
  1359. if (!mFirewallPipe)
  1360. {
  1361. titanDebug("FAIL: TitanInterface::FirewallDetect!");
  1362. return;
  1363. }
  1364. }
  1365. ///////////////////////////////////////////////////////////////////////////////////////////
  1366. ///////////////////////////////////////////////////////////////////////////////////////////
  1367. void TitanInterface::HandleFirewallResponse(SocketPipe *thePipeP, const WONMsg::SmallMessage& theMsgR)
  1368. {
  1369. titanDebug("TitanInterface::HandleFirewallResponse");
  1370. try {
  1371. WONMsg::SMsgFirewallStatusReply aReply(theMsgR);
  1372. if(thePipeP==mFirewallPipe) {
  1373. if(aReply.GetStatus()==WONMsg::StatusCommon_Success) {
  1374. mFirewallPipe = NULL;
  1375. return; // Success, now just wait for the connect
  1376. }
  1377. else {
  1378. titanDebug("TitanInterface::HandleFirewallResponse Status = %d", aReply.GetStatus());
  1379. FirewallFailOver();
  1380. return;
  1381. }
  1382. }
  1383. else { // The firewall server must have successfully connected
  1384. mBehindFirewall = false;
  1385. }
  1386. }
  1387. catch(WONException&) {
  1388. if(thePipeP==mFirewallPipe)
  1389. FirewallFailOver();
  1390. }
  1391. }
  1392. //////////////////////////////////////////////////////////////////////////////////////////////////////
  1393. //////////////////////////////////////////////////////////////////////////////////////////////////////
  1394. void
  1395. TitanInterface::PingFactServer() {
  1396. titanDebug("TitanInterface::PingFactServer");
  1397. AutoCrit aCrit(mPipeCrit);
  1398. // Toss old connection if needed
  1399. if (mFactPingPipe)
  1400. {
  1401. mFactPingPipe->AddOutgoingCmd(new CloseNowCmd(false, false, 0, false));
  1402. mFactPingPipe = NULL;
  1403. }
  1404. aCrit.Leave();
  1405. mCurFactPing++;
  1406. if(mCurFactPing>=FACTSERVER_NUM) {
  1407. mCurFactPing = 0;
  1408. mNumPingTrials++;
  1409. if(mNumPingTrials>=3)
  1410. return;
  1411. }
  1412. WONMsg::MMsgCommPing aMsg;
  1413. try
  1414. {
  1415. aMsg.Pack();
  1416. }
  1417. catch (WONException& anEx)
  1418. {
  1419. titanDebug("EXCEPTION: TitanInterface::PingFactServer: %s", (char*)anEx.what());
  1420. return;
  1421. }
  1422. mFactPingPipe = ConnectAndSend(FACTSERVER_ADDRESSES[mCurFactPing], aMsg);
  1423. }
  1424. ///////////////////////////////////////////////////////////////////////////////////////////
  1425. ///////////////////////////////////////////////////////////////////////////////////////////
  1426. void TitanInterface::PingHandleReply(const WONMsg::MiniMessage& theMsgR) {
  1427. titanDebug("TitanInterface::PingHandleReply");
  1428. // Toss ping pipe
  1429. mPipeCrit.Enter();
  1430. mFactPingPipe = NULL;
  1431. mPipeCrit.Leave();
  1432. try
  1433. {
  1434. WONMsg::MMsgCommPingReply aMsg(theMsgR);
  1435. if(aMsg.GetLag() < mMinPingTime) {
  1436. mCurFactServer = mCurFactPing;
  1437. mMinPingTime = aMsg.GetLag();
  1438. }
  1439. }
  1440. catch (WONException& anEx)
  1441. {
  1442. titanDebug("EXCEPTION: TitanInterface::PingHandleReply: %s", (char*)anEx.what());
  1443. }
  1444. PingFactServer();
  1445. }
  1446. ///////////////////////////////////////////////////////////////////////////////////////////
  1447. ///////////////////////////////////////////////////////////////////////////////////////////
  1448. void TitanInterface::AuthGetPubKeyBlock(void) {
  1449. titanDebug("TitanInterface::AuthGetPubKeyBlock");
  1450. AutoCrit aCrit(mPipeCrit);
  1451. // Toss old connection if needed
  1452. if (mAuthPipe)
  1453. {
  1454. titanDebug("NOTE: TitanInterface::AuthGetPubKeyBlock Close existing AuthPipe!");
  1455. mAuthPipe->AddOutgoingCmd(new CloseNowCmd(false, false, 0, false));
  1456. mAuthPipe = NULL;
  1457. }
  1458. aCrit.Leave();
  1459. WONMsg::TMsgAuth1GetPubKeys aMsg(WONMsg::Auth1Login);
  1460. if(AUTHSERVER_NUM==0) {
  1461. titanDebug("FAIL: No auth server to talk to.");
  1462. return;
  1463. }
  1464. else if(mCurAuthServer>=AUTHSERVER_NUM)
  1465. mCurAuthServer%=AUTHSERVER_NUM;
  1466. // Connect and send request
  1467. delete mPublicKeyBlock;
  1468. mPublicKeyBlock = NULL;
  1469. try
  1470. {
  1471. aMsg.Pack();
  1472. }
  1473. catch (WONException& anEx)
  1474. {
  1475. titanDebug("EXCEPTION: TitanInterface::AuthGetPubKeyBlock: %s", (char*)anEx.what());
  1476. return;
  1477. }
  1478. mAuthPipe = ConnectAndSend(AUTHSERVER_ADDRESSES[mCurAuthServer], aMsg);
  1479. }
  1480. ///////////////////////////////////////////////////////////////////////////////////////////
  1481. ///////////////////////////////////////////////////////////////////////////////////////////
  1482. void TitanInterface::AuthHandleGetPubKeysReply(const WONMsg::TMessage& theMsgR)
  1483. {
  1484. titanDebug("TitanInterface::AuthHandleGetPubKeysReply Got PubKeysReply message");
  1485. // Toss auth pipe
  1486. mPipeCrit.Enter();
  1487. mAuthPipe = NULL;
  1488. mPipeCrit.Leave();
  1489. if(mVerifierKey==NULL) {
  1490. titanDebug("TitanInterface::AuthHandleGetPubKeysReply FAIL: Don't have verifier key.");
  1491. return;
  1492. }
  1493. try
  1494. {
  1495. WONMsg::TMsgAuth1GetPubKeysReply msg(theMsgR);
  1496. short status = msg.GetStatus();
  1497. if(status<0) {
  1498. titanDebug("TitanInterface::AuthHandleGetPubKeysReply Status = %d", msg.GetStatus());
  1499. if (!authReceiveReply(status))
  1500. AuthFailOver();
  1501. else
  1502. ResetAuthFailOver();
  1503. return;
  1504. }
  1505. mPublicKeyBlock = new Auth1PublicKeyBlock(msg.GetRawBuf(),msg.GetRawBufLen());
  1506. if(!mPublicKeyBlock->Verify(*mVerifierKey)) {
  1507. delete mPublicKeyBlock;
  1508. mPublicKeyBlock = NULL;
  1509. AuthFailOver();
  1510. return;
  1511. }
  1512. ResetAuthFailOver();
  1513. AuthHandleLogin();
  1514. }
  1515. catch (WONException& anEx)
  1516. {
  1517. AuthFailOver();
  1518. titanDebug("EXCEPTION: TitanInterface::AuthHandleGetPubKeysReply: %s", (char*)anEx.what());
  1519. }
  1520. }
  1521. ///////////////////////////////////////////////////////////////////////////////////////////
  1522. ///////////////////////////////////////////////////////////////////////////////////////////
  1523. bool TitanInterface::ReadLoginKey(char *theKey) {
  1524. FILE *aFile = fopen(LOGIN_KEY_FILE_NAME,"rb");
  1525. if(aFile==NULL)
  1526. return false;
  1527. unsigned char aNum = fgetc(aFile);
  1528. LoginKeyStruct *aKeyStruct = new LoginKeyStruct[aNum];
  1529. aNum = fread(aKeyStruct,sizeof(LoginKeyStruct),aNum,aFile);
  1530. fclose(aFile);
  1531. for(int n=0; n<aNum; n++) {
  1532. if((AUTHSERVER_ADDRESSES[mCurAuthServer].sin_addr.s_addr == aKeyStruct[n].authAddr) && (AUTHSERVER_ADDRESSES[mCurAuthServer].sin_port == aKeyStruct[n].authPort))
  1533. {
  1534. memcpy(theKey, aKeyStruct[n].loginKey, 8);
  1535. break;
  1536. }
  1537. }
  1538. delete [] aKeyStruct;
  1539. return n<aNum;
  1540. }
  1541. ///////////////////////////////////////////////////////////////////////////////////////////
  1542. ///////////////////////////////////////////////////////////////////////////////////////////
  1543. void TitanInterface::WriteLoginKey(char *theKey, bool useOldNewLoginKey) {
  1544. if(AUTHSERVER_NUM==0)
  1545. return;
  1546. FILE *aFile = fopen(LOGIN_KEY_FILE_NAME,"rb");
  1547. unsigned char aNum = 0;
  1548. int n;
  1549. LoginKeyStruct *aKeyStruct = NULL;
  1550. LoginKeyStruct *aNewKeyStruct = new LoginKeyStruct[AUTHSERVER_NUM];
  1551. map<ClientNetAddr,unsigned char> anAddrMap;
  1552. map<ClientNetAddr,unsigned char>::iterator anItr;
  1553. if(aFile!=NULL) {
  1554. aNum = fgetc(aFile);
  1555. aKeyStruct = new LoginKeyStruct[aNum];
  1556. aNum = fread(aKeyStruct,sizeof(LoginKeyStruct),aNum,aFile);
  1557. for(n=0; n<aNum; n++)
  1558. anAddrMap[ClientNetAddr(aKeyStruct[n].authAddr,aKeyStruct[n].authPort)] = n;
  1559. fclose(aFile);
  1560. }
  1561. for(n=0; n<AUTHSERVER_NUM; n++) {
  1562. anItr = anAddrMap.find(ClientNetAddr(AUTHSERVER_ADDRESSES[n].sin_addr.s_addr, AUTHSERVER_ADDRESSES[n].sin_port));
  1563. if(anItr!=anAddrMap.end())
  1564. memcpy(&aNewKeyStruct[n], &aKeyStruct[anItr->second], sizeof(LoginKeyStruct));
  1565. else {
  1566. aNewKeyStruct[n].authAddr = AUTHSERVER_ADDRESSES[n].sin_addr.s_addr;
  1567. aNewKeyStruct[n].authPort = AUTHSERVER_ADDRESSES[n].sin_port;
  1568. }
  1569. if(n==mCurAuthServer) {
  1570. if(theKey!=NULL) {
  1571. memcpy(mOldNewLoginKey, aNewKeyStruct[n].newLoginKey, 8);
  1572. memcpy(aNewKeyStruct[n].newLoginKey,theKey,8);
  1573. }
  1574. else {
  1575. if(useOldNewLoginKey)
  1576. memcpy(aNewKeyStruct[n].newLoginKey, mOldNewLoginKey, 8);
  1577. memcpy(aNewKeyStruct[n].loginKey,aNewKeyStruct[n].newLoginKey,8);
  1578. }
  1579. }
  1580. }
  1581. aFile = fopen(LOGIN_KEY_FILE_NAME,"wb");
  1582. if(aFile!=NULL) {
  1583. fwrite(&AUTHSERVER_NUM,1,1,aFile);
  1584. fwrite(aNewKeyStruct,sizeof(LoginKeyStruct),AUTHSERVER_NUM,aFile);
  1585. fclose(aFile);
  1586. }
  1587. delete [] aKeyStruct;
  1588. delete [] aNewKeyStruct;
  1589. }
  1590. ///////////////////////////////////////////////////////////////////////////////////////////
  1591. ///////////////////////////////////////////////////////////////////////////////////////////
  1592. void TitanInterface::AuthHandleLogin(void) {
  1593. titanDebug("TitanInterface::AuthHandleLogin");
  1594. if(AUTHSERVER_NUM==0) {
  1595. titanDebug("FAIL: No auth server to talk to.");
  1596. return;
  1597. }
  1598. else if(mCurAuthServer>=AUTHSERVER_NUM)
  1599. mCurAuthServer%=AUTHSERVER_NUM;
  1600. AutoCrit aCrit(mPipeCrit);
  1601. // Toss old connection if needed
  1602. if (mAuthPipe)
  1603. {
  1604. titanDebug("NOTE: TitanInterface::AuthHandleLogin Close existing AuthPipe!");
  1605. mAuthPipe->AddOutgoingCmd(new CloseNowCmd(false, false, 0, false));
  1606. mAuthPipe = NULL;
  1607. }
  1608. aCrit.Leave();
  1609. if(mPublicKeyBlock==NULL) {
  1610. titanDebug("FAIL: AuthHandleLogin - Don't have public key block.");
  1611. return;
  1612. }
  1613. WONMsg::TMsgAuth1LoginRequestHW aMsg;
  1614. aMsg.SetKeyBlockId(mPublicKeyBlock->GetBlockId());
  1615. aMsg.SetNeedKeyFlg(mPrivateKey==NULL);
  1616. aMsg.SetCreateAcctFlg(mCreateAccount);
  1617. aMsg.SetUserName(StringToWString(mLoginName));
  1618. #if defined(CGW) || defined(Downloadable)
  1619. aMsg.SetCommunityName(StringToWString("HomeworldDemo"));
  1620. #else // Normal release/beta
  1621. aMsg.SetCommunityName(StringToWString("Homeworld"));
  1622. #endif
  1623. aMsg.SetPassword(StringToWString(mPassword));
  1624. aMsg.SetNewPassword(StringToWString(mNewPassword));
  1625. #if !defined(CGW) && !defined(Downloadable)
  1626. WONCDKey::ClientCDKey aCDKey("Homeworld");
  1627. if (!aCDKey.Load()) {
  1628. titanDebug("FAIL: AuthHandleLogin - Failed to load CD key from registry.");
  1629. mgDisplayMessage(strGetString(strNoCDKey));
  1630. return;
  1631. }
  1632. if (!aCDKey.IsValid()) {
  1633. titanDebug("FAIL: AuthHandleLogin - CD key failed lightweight check.");
  1634. mgDisplayMessage(strGetString(strLightweightBadKey));
  1635. return;
  1636. }
  1637. #ifdef HW_Release
  1638. // If this is a beta version, only beta keys are allowed. If it's a release
  1639. // version (not beta, not demo), only non-beta keys are allowed.
  1640. #ifdef DLPublicBeta
  1641. if (!aCDKey.IsBeta()) {
  1642. titanDebug("FAIL: AuthHandleLogin - CD key is NOT a beta key.");
  1643. mgDisplayMessage(strGetString(strBadKeyBetaKeyRequired));
  1644. return;
  1645. }
  1646. #else
  1647. if (aCDKey.IsBeta()) {
  1648. titanDebug("FAIL: AuthHandleLogin - CD key IS a beta key.");
  1649. mgDisplayMessage(strGetString(strBadKeyBetaKeyNotAllowed));
  1650. return;
  1651. }
  1652. #endif // DLPublicBeta
  1653. #endif // HW_Release
  1654. __int64 aRawCDKey = aCDKey.AsRaw(); // message is encrypted, so key doesn't need to be
  1655. aMsg.SetCDKey((const unsigned char*)&aRawCDKey,sizeof(aRawCDKey));
  1656. #endif // Not a CGW or Downloadable demo
  1657. char aBuf[8];
  1658. ReadLoginKey(aBuf);
  1659. aMsg.SetLoginKey((const unsigned char*)aBuf,8); // This is the secret
  1660. delete mAuthSessionKey; mAuthSessionKey = NULL;
  1661. try {
  1662. // mAuthSessionKey = new BFSymmetricKey(8,(const unsigned char*)aBuf);
  1663. mAuthSessionKey = new BFSymmetricKey(8);
  1664. }
  1665. catch(WONException&) {
  1666. titanDebug("EXCEPTION: AuthHandleLogin unable to create session key.");
  1667. return;
  1668. }
  1669. try {
  1670. aMsg.BuildBuffer(*mPublicKeyBlock, *mAuthSessionKey);
  1671. }
  1672. catch(WONException&) {
  1673. titanDebug("EXCEPTION: Unable to build AuthLogin message.");
  1674. delete mAuthSessionKey; mAuthSessionKey = NULL;
  1675. }
  1676. try
  1677. {
  1678. aMsg.Pack();
  1679. }
  1680. catch (WONException& anEx)
  1681. {
  1682. titanDebug("EXCEPTION: TitanInterface::AuthHanleLogin: %s", (char*)anEx.what());
  1683. return;
  1684. }
  1685. mAuthPipe = ConnectAndSend(AUTHSERVER_ADDRESSES[mCurAuthServer], aMsg);
  1686. }
  1687. ///////////////////////////////////////////////////////////////////////////////////////////
  1688. ///////////////////////////////////////////////////////////////////////////////////////////
  1689. void TitanInterface::AuthHandleChallenge(const WONMsg::TMessage &theMsgR) {
  1690. titanDebug("TitanInterface::AuthHandleChallenge");
  1691. AutoCrit aCrit(mPipeCrit);
  1692. if(mAuthSessionKey==NULL) {
  1693. titanDebug("FAIL: Don't have auth session key.");
  1694. return;
  1695. }
  1696. try {
  1697. WONMsg::TMsgAuth1ChallengeHW aMsg(theMsgR);
  1698. CryptKeyBase::CryptReturn aCryptRet(NULL,0);
  1699. aCryptRet = mAuthSessionKey->Decrypt(aMsg.GetRawBuf(),aMsg.GetRawBufLen());
  1700. if(aCryptRet.first==NULL) {
  1701. titanDebug("FAIL: Unable to decrypt challenge seed.");
  1702. AuthFailOver();
  1703. return;
  1704. }
  1705. auto_ptr<unsigned char> aDeleteCryptRet(aCryptRet.first);
  1706. if(aCryptRet.second!=16) {
  1707. titanDebug("FAIL: Challenge seed length != 16 bytes.");
  1708. AuthFailOver();
  1709. return;
  1710. }
  1711. WriteLoginKey((char*)(aCryptRet.first));
  1712. // respond to challenge from Auth Server
  1713. unsigned int aChallengeResponse[8];
  1714. if (ShortCircuitWON)
  1715. ShortCircuitChallengeResponse((BYTE*)aCryptRet.first, reinterpret_cast<unsigned char*>(aChallengeResponse));
  1716. else
  1717. {
  1718. struct MD5Context ContextEntireFile; // hash without seed
  1719. struct MD5Context ContextKeyedHash; // hash with seed
  1720. MD5Init2(&ContextEntireFile); MD5Init2(&ContextKeyedHash);
  1721. MD5Update2(&ContextKeyedHash, (BYTE*)aCryptRet.first, aCryptRet.second);
  1722. bool firsttime = true;
  1723. unsigned long aBytesRead = 0;
  1724. unsigned char* aUnhashedBuf = NULL;
  1725. while ((aBytesRead = GetHashSection(firsttime, &aUnhashedBuf, reinterpret_cast<unsigned char*>(aChallengeResponse) + MD5_HASH_SIZE)) != 0)
  1726. {
  1727. MD5Update2(&ContextEntireFile, aUnhashedBuf, aBytesRead);
  1728. MD5Update2(&ContextKeyedHash, reinterpret_cast<unsigned char*>(aChallengeResponse) + MD5_HASH_SIZE, MD5_HASH_SIZE);
  1729. firsttime = false;
  1730. }
  1731. MD5Final2(reinterpret_cast<unsigned char*>(aChallengeResponse), &ContextEntireFile);
  1732. MD5Final2(reinterpret_cast<unsigned char*>(aChallengeResponse) + MD5_HASH_SIZE, &ContextKeyedHash);
  1733. delete aUnhashedBuf; aUnhashedBuf = NULL;
  1734. }
  1735. CryptKeyBase::CryptReturn aReplyCrypt(NULL,0);
  1736. aReplyCrypt = mAuthSessionKey->Encrypt((const unsigned char*)aChallengeResponse, MD5_HASH_SIZE*2);
  1737. if(aReplyCrypt.first==NULL) {
  1738. titanDebug("FAIL: Unable to encrypt challenge reply.");
  1739. return;
  1740. }
  1741. auto_ptr<unsigned char> aDeleteReplyCrypt(aReplyCrypt.first);
  1742. WONMsg::TMsgAuth1ConfirmHW aReply;
  1743. aReply.SetRawBuf(aReplyCrypt.first,aReplyCrypt.second,true);
  1744. aReply.Pack();
  1745. if(!SendMsg(mAuthPipe,aReply)) {
  1746. titanDebug("FAIL: Unable to send Auth1LoginConfirm message.");
  1747. return;
  1748. }
  1749. }
  1750. catch(WONException &anEx) {
  1751. titanDebug("EXCEPTION: TitanInterface::AuthHandleChallenge: %s", (char*)anEx.what());
  1752. AuthFailOver();
  1753. return;
  1754. }
  1755. }
  1756. ///////////////////////////////////////////////////////////////////////////////////////////
  1757. ///////////////////////////////////////////////////////////////////////////////////////////
  1758. void TitanInterface::AuthHandleLoginReply(const WONMsg::TMessage &theMsg)
  1759. {
  1760. titanDebug("TitanInterface::AuthHandleLoginReply.");
  1761. // Toss auth pipe
  1762. mPipeCrit.Enter();
  1763. mAuthPipe = NULL;
  1764. mPipeCrit.Leave();
  1765. if(mPublicKeyBlock==NULL) {
  1766. titanDebug("FAIL: AuthHandleLogin - Don't have public key block.");
  1767. return;
  1768. }
  1769. if(mAuthSessionKey==NULL) {
  1770. titanDebug("FAIL: Don't have auth session key.");
  1771. return;
  1772. }
  1773. try {
  1774. WONMsg::TMsgAuth1LoginReply aMsg(theMsg,mAuthSessionKey);
  1775. WONMsg::TMsgAuth1LoginReply::RawBlock aRawBlock;
  1776. if(aMsg.GetStatus()<0) {
  1777. titanDebug("TitanInterface::AuthHandleLoginReply Status = %d", aMsg.GetStatus());
  1778. if(aMsg.GetStatus()==WONMsg::StatusAuth_KeyInUse) {
  1779. // Perhaps we succeeded previously but never got the reply
  1780. // If this is the case, then trying to authenticate again
  1781. // will succeed.
  1782. WriteLoginKey(NULL, true);
  1783. }
  1784. if (!authReceiveReply(aMsg.GetStatus()))
  1785. AuthFailOver();
  1786. else
  1787. ResetAuthFailOver();
  1788. return;
  1789. }
  1790. // Check for new public key block
  1791. aRawBlock = aMsg.GetRawBlock(WONMsg::TMsgAuth1LoginReply::ALPublicKeyBlock);
  1792. if(aRawBlock.first!=NULL) {
  1793. delete mPublicKeyBlock; mPublicKeyBlock = NULL;
  1794. mPublicKeyBlock = new Auth1PublicKeyBlock(aRawBlock.first,aRawBlock.second);
  1795. if(!mPublicKeyBlock->Verify(*mVerifierKey)) {
  1796. titanDebug("FAIL: Failed to verify new public key block.");
  1797. delete mPublicKeyBlock; mPublicKeyBlock = NULL;
  1798. AuthFailOver();
  1799. return;
  1800. }
  1801. }
  1802. // Check for certificate
  1803. delete mCertificate; mCertificate = NULL;
  1804. aRawBlock = aMsg.GetRawBlock(WONMsg::TMsgAuth1LoginReply::ALCertificate);
  1805. if(aRawBlock.first==NULL) {
  1806. titanDebug("FAIL: Didn't get certificate.");
  1807. AuthFailOver();
  1808. return;
  1809. }
  1810. mCertificate = new Auth1Certificate(aRawBlock.first,aRawBlock.second);
  1811. if(!mPublicKeyBlock->VerifyFamilyBuffer(*mCertificate)) {
  1812. titanDebug("FAIL: Couldn't verify certificate from auth server.");
  1813. delete mCertificate; mCertificate = NULL;
  1814. AuthFailOver();
  1815. return;
  1816. }
  1817. mAuthDeltaTime = mCertificate->GetIssueTime() - time(NULL);
  1818. // Check for private key
  1819. aRawBlock = aMsg.GetRawBlock(WONMsg::TMsgAuth1LoginReply::ALClientPrivateKey);
  1820. if(aRawBlock.first!=NULL) {
  1821. delete mPrivateKey; mPrivateKey = NULL;
  1822. mPrivateKey = new EGPrivateKey(aRawBlock.second, aRawBlock.first);
  1823. }
  1824. else if(mPrivateKey==NULL) {
  1825. titanDebug("FAIL: Didn't get private key from auth server.");
  1826. delete mCertificate; mCertificate = NULL;
  1827. AuthFailOver();
  1828. return;
  1829. }
  1830. ResetAuthFailOver();
  1831. time_t aRefreshWaitTime = 1000*(mCertificate->GetExpireTime() - mCertificate->GetIssueTime() - 120);
  1832. mTimerPipe->AddIncomingCmd(new TimerCmd(aRefreshWaitTime,false));
  1833. if(mNewPassword!="") {
  1834. mPassword = mNewPassword;
  1835. mNewPassword = "";
  1836. }
  1837. mCreateAccount = false;
  1838. WriteLoginKey(NULL);
  1839. authReceiveReply(aMsg.GetStatus());
  1840. }
  1841. catch(WONException &anEx) {
  1842. titanDebug("EXCEPTION: TitanInterface::AuthHandleLoginReply: %s", (char*)anEx.what());
  1843. AuthFailOver();
  1844. return;
  1845. }
  1846. }
  1847. ///////////////////////////////////////////////////////////////////////////////////////////
  1848. ///////////////////////////////////////////////////////////////////////////////////////////
  1849. void TitanInterface::AuthHandleRefresh(void)
  1850. {
  1851. titanDebug("TitanInterface::AuthHandleRefresh");
  1852. if(mPublicKeyBlock==NULL) {
  1853. titanDebug("FAIL: Don't have public key block,");
  1854. return;
  1855. }
  1856. char aBuf[8];
  1857. if(!ReadLoginKey(aBuf)) {
  1858. titanDebug("AuthHandleRefresh: Login key not found.");
  1859. return;
  1860. }
  1861. WONMsg::TRawMsg anEncryptBuf;
  1862. anEncryptBuf.AppendShort((short)time(NULL));
  1863. anEncryptBuf.AppendBytes(8, aBuf);
  1864. CryptKeyBase::CryptReturn aCryptRet(NULL,0);
  1865. aCryptRet = mPublicKeyBlock->EncryptRawBuffer((const unsigned char*)anEncryptBuf.GetDataPtr(),anEncryptBuf.GetDataLen());
  1866. auto_ptr<unsigned char> aDeleteCryptRet(aCryptRet.first);
  1867. if(aCryptRet.first==NULL) {
  1868. titanDebug("FAIL: Couldn't encrypt block with auth public key.");
  1869. return;
  1870. }
  1871. WONMsg::TMsgAuth1RefreshHW aMsg;
  1872. aMsg.SetKeyBlockId(mPublicKeyBlock->GetBlockId());
  1873. aMsg.SetRawKeyBuf(aCryptRet.first,aCryptRet.second,true);
  1874. aMsg.SetRawDataBuf(NULL,0,false);
  1875. try
  1876. {
  1877. aMsg.Pack();
  1878. }
  1879. catch (WONException& anEx)
  1880. {
  1881. titanDebug("EXCEPTION: TitanInterface::AuthHanleRefresh: %s", (char*)anEx.what());
  1882. return;
  1883. }
  1884. mAuthPipe = ConnectAndSend(AUTHSERVER_ADDRESSES[mCurAuthServer], aMsg);
  1885. }
  1886. ///////////////////////////////////////////////////////////////////////////////////////////
  1887. ///////////////////////////////////////////////////////////////////////////////////////////
  1888. void TitanInterface::Authenticate(const string &loginName, const string &password, const string &theNewPassword,bool CreateAccount)
  1889. {
  1890. titanDebug("TitanInterface::Authenticate");
  1891. AutoCrit aCrit(mPipeCrit);
  1892. // Toss old connection if needed
  1893. if (mAuthPipe)
  1894. {
  1895. titanDebug("NOTE: TitanInterface::Authenticate Close existing AuthPipe!");
  1896. mAuthPipe->AddOutgoingCmd(new CloseNowCmd(false, false, 0, false));
  1897. mAuthPipe = NULL;
  1898. }
  1899. aCrit.Leave();
  1900. if(mVerifierKey==NULL) {
  1901. titanDebug("FAIL: Can't authenticate without verifier key.");
  1902. return;
  1903. }
  1904. mLoginName = loginName;
  1905. mPassword = password;
  1906. mNewPassword = theNewPassword;
  1907. mCreateAccount = CreateAccount;
  1908. if(!mLaunched) {
  1909. if(firewallButton==FIREWALL_NOTBEHIND) {
  1910. mBehindFirewall = false;
  1911. mUseRoutingServer = true;
  1912. }
  1913. else if(firewallButton==FIREWALL_BEHIND) {
  1914. mBehindFirewall = true;
  1915. mUseRoutingServer = true;
  1916. }
  1917. else { // auto-detect
  1918. mBehindFirewall = true;
  1919. mUseRoutingServer = true;
  1920. FirewallDetect();
  1921. }
  1922. mLaunched = true;
  1923. }
  1924. if(AUTHSERVER_NUM==0) {
  1925. mNeedToAuthenticateAfterGettingAuthDirectory = true;
  1926. RequestDirectory();
  1927. return;
  1928. }
  1929. if(mPublicKeyBlock==NULL)
  1930. AuthGetPubKeyBlock();
  1931. else
  1932. AuthHandleLogin();
  1933. }
  1934. ///////////////////////////////////////////////////////////////////////////////////////////
  1935. ///////////////////////////////////////////////////////////////////////////////////////////
  1936. void TitanInterface::PeerHandleChallenge(SocketPipe** thePipeP, const TMessage& theMsgR)
  1937. {
  1938. titanDebug("TitanInterface::PeerHandleChallenge");
  1939. AutoCrit aCrit(mPipeCrit);
  1940. bool dirStuff = false, factStuff = false, routeStuff = false;
  1941. if(*thePipeP==mDirPipe)
  1942. dirStuff = true;
  1943. else if(*thePipeP==mFactPipe)
  1944. factStuff = true;
  1945. else {
  1946. for(int n=0; n<2; n++)
  1947. if(*thePipeP==mRoutePipe[n])
  1948. routeStuff = true;
  1949. }
  1950. if(mCertificate==NULL) {
  1951. titanDebug("FAIL: Don't have certificate.");
  1952. *thePipeP = NULL;
  1953. return;
  1954. }
  1955. try {
  1956. WONMsg::TMsgAuth1Challenge1 aMsg(theMsgR);
  1957. CryptKeyBase::CryptReturn aCryptRet(NULL,0);
  1958. BFSymmetricKey *aSessionKey;
  1959. BFSymmetricKey *aClientSecret;
  1960. aCryptRet = mPrivateKey->Decrypt(aMsg.GetSecretB(),aMsg.GetSecretBLen());
  1961. auto_ptr<unsigned char> aDeleteCryptRet(aCryptRet.first);
  1962. if(aCryptRet.second < 2 ||
  1963. (*(unsigned short*)aCryptRet.first)!=aCryptRet.second - 2)
  1964. {
  1965. titanDebug("Invalid SecretB received.");
  1966. *thePipeP = NULL;
  1967. if(dirStuff)
  1968. DirFailOver();
  1969. else if(factStuff)
  1970. FactFailOver();
  1971. return;
  1972. }
  1973. if(*thePipeP==mDirPipe) {
  1974. delete mDirSessionKey; delete mDirClientSecret;
  1975. mDirSessionKey = new BFSymmetricKey(aCryptRet.second-2,aCryptRet.first+2);
  1976. mDirClientSecret = new BFSymmetricKey(8);
  1977. aSessionKey = mDirSessionKey;
  1978. aClientSecret = mDirClientSecret;
  1979. }
  1980. else if(*thePipeP==mFactPipe) {
  1981. delete mFactSessionKey; delete mFactClientSecret;
  1982. mFactSessionKey = new BFSymmetricKey(aCryptRet.second-2,aCryptRet.first+2);
  1983. mFactClientSecret = new BFSymmetricKey(8);
  1984. aSessionKey = mFactSessionKey;
  1985. aClientSecret = mFactClientSecret;
  1986. }
  1987. else {
  1988. for(int n=0; n<2; n++) {
  1989. if(*thePipeP==mRoutePipe[n]) {
  1990. delete mRouteSessionKey[n]; delete mRouteClientSecret[n];
  1991. mRouteSessionKey[n] = new BFSymmetricKey(aCryptRet.second-2,aCryptRet.first+2);
  1992. mRouteClientSecret[n] = new BFSymmetricKey(8);
  1993. aSessionKey = mRouteSessionKey[n];
  1994. aClientSecret = mRouteClientSecret[n];
  1995. break;
  1996. }
  1997. }
  1998. if(n==2) {
  1999. titanDebug("FAIL: Pipe is neither dir nor fact nor route pipe.");
  2000. return;
  2001. }
  2002. }
  2003. Auth1Certificate aCertificate;
  2004. if(!aCertificate.Unpack(aMsg.GetRawBuf(), aMsg.GetRawBufLen()) ||
  2005. !mPublicKeyBlock->VerifyFamilyBuffer(aCertificate))
  2006. {
  2007. titanDebug("FAIL: Server certificate is invalid.");
  2008. if(dirStuff)
  2009. DirFailOver();
  2010. else if(factStuff)
  2011. FactFailOver();
  2012. return;
  2013. }
  2014. TRawMsg aBuf;
  2015. aBuf.AppendShort(aSessionKey->GetKeyLen());
  2016. aBuf.AppendBytes(aSessionKey->GetKeyLen(),aSessionKey->GetKey());
  2017. aBuf.AppendBytes(aClientSecret->GetKeyLen(), aClientSecret->GetKey());
  2018. CryptKeyBase::CryptReturn aSecretCrypt(NULL, 0);
  2019. aSecretCrypt = aCertificate.GetPubKey().Encrypt(aBuf.GetDataPtr(), aBuf.GetDataLen());
  2020. auto_ptr<unsigned char> aDeleteSecretCrypt(aSecretCrypt.first);
  2021. if(aSecretCrypt.first==NULL) {
  2022. titanDebug("FAIL: Unable to encrypt challenge2.");
  2023. if(dirStuff)
  2024. DirFailOver();
  2025. else if(factStuff)
  2026. FactFailOver();
  2027. return;
  2028. }
  2029. WONMsg::TMsgAuth1Challenge2 aChallenge2;
  2030. aChallenge2.SetRawBuf(aSecretCrypt.first,aSecretCrypt.second,true);
  2031. aChallenge2.Pack();
  2032. if(!SendMsg(*thePipeP,aChallenge2, routeStuff?2:4)) {
  2033. titanDebug("FAIL: Unable to send Challenge2.");
  2034. if(dirStuff)
  2035. DirFailOver();
  2036. else if(factStuff)
  2037. FactFailOver();
  2038. return;
  2039. }
  2040. }
  2041. catch(WONException &anEx) {
  2042. titanDebug("EXCEPTION: TitanInterface::PeerHandleChallenge: %s", (char*)anEx.what());
  2043. return;
  2044. }
  2045. }
  2046. ///////////////////////////////////////////////////////////////////////////////////////////
  2047. ///////////////////////////////////////////////////////////////////////////////////////////
  2048. void TitanInterface::PeerHandleComplete(SocketPipe** thePipeP, const TMessage& theMsgR)
  2049. {
  2050. titanDebug("TitanInterface::PeerHandleComplete");
  2051. AutoCrit aCrit(mPipeCrit);
  2052. bool dirStuff = false, factStuff = false, routeStuff = false;
  2053. if(*thePipeP==mDirPipe)
  2054. dirStuff = true;
  2055. else if(*thePipeP==mFactPipe)
  2056. factStuff = true;
  2057. int aRouteNum;
  2058. if(mPrivateKey==NULL) {
  2059. titanDebug("FAIL: Don't have private key.");
  2060. return;
  2061. }
  2062. try {
  2063. WONMsg::TMsgAuth1Complete aMsg(theMsgR);
  2064. BFSymmetricKey **aClientSecret, **aSessionKey;
  2065. if(*thePipeP==mDirPipe) {
  2066. aClientSecret = &mDirClientSecret;
  2067. aSessionKey = &mDirSessionKey;
  2068. }
  2069. else if(*thePipeP==mFactPipe) {
  2070. aClientSecret = &mFactClientSecret;
  2071. aSessionKey = &mFactSessionKey;
  2072. }
  2073. else {
  2074. for(int n=0; n<2; n++) {
  2075. if(*thePipeP==mRoutePipe[n]) {
  2076. aClientSecret = &(mRouteClientSecret[n]);
  2077. aSessionKey = &(mRouteSessionKey[n]);
  2078. routeStuff = true;
  2079. aRouteNum = n;
  2080. break;
  2081. }
  2082. }
  2083. if(!routeStuff) {
  2084. titanDebug("FAIL: Invalid pipe received in PeerHandleComplete.");
  2085. return;
  2086. }
  2087. }
  2088. if(aMsg.GetStatus() < 0) {
  2089. titanDebug("FAIL: Failure status on Auth1Complete. %d", aMsg.GetStatus());
  2090. delete *aClientSecret; *aClientSecret=NULL;
  2091. delete *aSessionKey; *aSessionKey=NULL;
  2092. return;
  2093. }
  2094. if(*aClientSecret==NULL) {
  2095. titanDebug("FAIL: Don't have ClientSecret.");
  2096. delete *aSessionKey; *aSessionKey = NULL;
  2097. return;
  2098. }
  2099. if(*aSessionKey==NULL) {
  2100. titanDebug("FAIL: Don't have session key.");
  2101. delete *aClientSecret; *aClientSecret = NULL;
  2102. return;
  2103. }
  2104. CryptKeyBase::CryptReturn aCryptRet(NULL,0);
  2105. aCryptRet = mPrivateKey->Decrypt(aMsg.GetRawBuf(),aMsg.GetRawBufLen());
  2106. auto_ptr<unsigned char> aDeleteCryptRet(aCryptRet.first);
  2107. if(aCryptRet.second<2 ||
  2108. (*(unsigned short*)aCryptRet.first != aCryptRet.second-2) ||
  2109. aCryptRet.second-2 != (*aClientSecret)->GetKeyLen() ||
  2110. !memcmp(aCryptRet.first,(*aClientSecret)->GetKey(),aCryptRet.second-2))
  2111. {
  2112. titanDebug("FAIL: Invalid client secret received.");
  2113. delete *aClientSecret; *aClientSecret = NULL;
  2114. delete *aSessionKey; *aSessionKey = NULL;
  2115. if(dirStuff)
  2116. DirFailOver();
  2117. else if(factStuff)
  2118. FactFailOver();
  2119. return;
  2120. }
  2121. delete *aClientSecret; *aClientSecret = NULL;
  2122. if(*thePipeP==mDirPipe) {
  2123. mDirInSeqNum = 1;
  2124. mDirOutSeqNum = 1;
  2125. mDirSessionId = aMsg.GetSessionId();
  2126. DirHandleGetHWDirectory();
  2127. }
  2128. else if(*thePipeP==mFactPipe)
  2129. {
  2130. mFactSessionId = aMsg.GetSessionId();
  2131. FactHandleStartProcess();
  2132. }
  2133. else if(routeStuff)
  2134. {
  2135. if (mNeedToRegisterRoutingServer)
  2136. RegisterRoutingServer();
  2137. else
  2138. HandleRoutingRegister(aRouteNum);
  2139. }
  2140. }
  2141. catch(WONException &anEx) {
  2142. titanDebug("EXCEPTION: TitanInterface::PeerHandleComplete: %s", (char*)anEx.what());
  2143. return;
  2144. }
  2145. }
  2146. ///////////////////////////////////////////////////////////////////////////////////////////
  2147. ///////////////////////////////////////////////////////////////////////////////////////////
  2148. bool TitanInterface::EncryptAndSendRoutingMsg(const WONMsg::BaseMessage &theMsgR, int theServer)
  2149. {
  2150. titanDebug("TitanInterface::EncryptAndSendRoutingMsg");
  2151. if(mRouteSessionKey[theServer]==NULL) {
  2152. titanDebug("FAIL: Don't have routing server session key");
  2153. return false;
  2154. }
  2155. // Use a MiniMessage to hold the encrypted output. This has the added benefit of
  2156. // signalling SendMsg to use a 2-byte length...
  2157. MiniMessage anEncryptMsg;
  2158. if(!EncryptMessage(theMsgR,anEncryptMsg,*(mRouteSessionKey[theServer]),0,NULL)) {
  2159. titanDebug("FAIL: Failed to encrypt routing message.");
  2160. return false;
  2161. }
  2162. if(!SendMsg(mRoutePipe[theServer], anEncryptMsg)) {
  2163. titanDebug("Couldn't send msg even though this is impossible.");
  2164. return false;
  2165. }
  2166. return true;
  2167. }
  2168. ///////////////////////////////////////////////////////////////////////////////////////////
  2169. ///////////////////////////////////////////////////////////////////////////////////////////
  2170. bool TitanInterface::EncryptMessage(const BaseMessage &theInMsg, BaseMessage &theOutMsg,
  2171. const BFSymmetricKey &theKey, unsigned short theSessionId,
  2172. unsigned short *theSeqNum)
  2173. {
  2174. //titanDebug("TitanInterface::EncryptMessage.");
  2175. if (theInMsg.GetMessageClass() == WONMsg::eTMessage)
  2176. {
  2177. titanDebug("EncryptTMessage FAIL: We no longer use encrypted TMessages!");
  2178. return false;
  2179. }
  2180. else
  2181. return EncryptNonTMessage(theInMsg, theOutMsg, theKey, theSessionId, theSeqNum);
  2182. }
  2183. ///////////////////////////////////////////////////////////////////////////////////////////
  2184. ///////////////////////////////////////////////////////////////////////////////////////////
  2185. /*
  2186. bool TitanInterface::EncryptTMessage(const BaseMessage &theInMsg, BaseMessage &theOutMsg,
  2187. const BFSymmetricKey &theKey, unsigned short theSessionId,
  2188. unsigned short *theSeqNum)
  2189. {
  2190. titanDebug("TitanInterface::EncryptTMessage.");
  2191. if(theInMsg.GetDataLen() < theInMsg.GetHeaderLength())
  2192. return false;
  2193. const char *aDataPtr = (const char*)theInMsg.GetDataPtr();
  2194. char *aBuffer = NULL;
  2195. unsigned long anEncryptSize = theInMsg.GetDataLen();
  2196. if(theSeqNum!=NULL) {
  2197. aBuffer = new char[theInMsg.GetDataLen() + 2];
  2198. memcpy(aBuffer+2,theInMsg.GetDataPtr(),theInMsg.GetDataLen());
  2199. aDataPtr = aBuffer;
  2200. *(unsigned short*)aDataPtr = *theSeqNum;
  2201. anEncryptSize+=2;
  2202. }
  2203. auto_ptr<char> aDelBuf(aBuffer);
  2204. theOutMsg.ResetBuffer();
  2205. theOutMsg.AppendByte(WONMsg::EncryptedService); // Encrypt Flag
  2206. if(theSessionId!=0)
  2207. theOutMsg.AppendShort(theSessionId);
  2208. CryptKeyBase::CryptReturn aCryptRet(NULL,0);
  2209. aCryptRet = theKey.Encrypt(aDataPtr,anEncryptSize);
  2210. auto_ptr<unsigned char> aDeleteCryptRet(aCryptRet.first);
  2211. if(aCryptRet.first==NULL)
  2212. return false;
  2213. theOutMsg.AppendBytes(aCryptRet.second, aCryptRet.first);
  2214. if(theSeqNum!=NULL)
  2215. (*theSeqNum)++;
  2216. return true;
  2217. }
  2218. */
  2219. ///////////////////////////////////////////////////////////////////////////////////////////
  2220. ///////////////////////////////////////////////////////////////////////////////////////////
  2221. bool TitanInterface::EncryptNonTMessage(const BaseMessage &theInMsg, BaseMessage &theOutMsg,
  2222. const BFSymmetricKey &theKey, unsigned short theSessionId,
  2223. unsigned short *theSeqNum)
  2224. {
  2225. //titanDebug("TitanInterface::EncryptNonTMessage.");
  2226. if(theInMsg.GetDataLen() < theInMsg.GetHeaderLength())
  2227. return false;
  2228. const char *aDataPtr = ((const char*)theInMsg.GetDataPtr()) + 1;
  2229. char *aBuffer = NULL;
  2230. unsigned long anEncryptSize = theInMsg.GetDataLen() - 1;
  2231. if(theSeqNum!=NULL) {
  2232. aBuffer = new char[theInMsg.GetDataLen() + 1];
  2233. memcpy(aBuffer+2,((char*)theInMsg.GetDataPtr())+1,theInMsg.GetDataLen()-1);
  2234. aDataPtr = aBuffer;
  2235. *(unsigned short*)aDataPtr = *theSeqNum;
  2236. anEncryptSize+=2;
  2237. }
  2238. auto_ptr<char> aDelBuf(aBuffer);
  2239. theOutMsg.ResetBuffer();
  2240. // Encrypt Flag
  2241. switch (theInMsg.GetMessageClass())
  2242. {
  2243. case WONMsg::eMiniMessage:
  2244. theOutMsg.AppendByte(WONMsg::MiniEncryptedService); break;
  2245. case WONMsg::eSmallMessage:
  2246. theOutMsg.AppendByte(WONMsg::SmallEncryptedService); break;
  2247. case WONMsg::eLargeMessage:
  2248. theOutMsg.AppendByte(WONMsg::LargeEncryptedService); break;
  2249. }
  2250. if(theSessionId!=0)
  2251. theOutMsg.AppendShort(theSessionId);
  2252. CryptKeyBase::CryptReturn aCryptRet(NULL,0);
  2253. aCryptRet = theKey.Encrypt(aDataPtr,anEncryptSize);
  2254. auto_ptr<unsigned char> aDeleteCryptRet(aCryptRet.first);
  2255. if(aCryptRet.first==NULL)
  2256. return false;
  2257. theOutMsg.AppendBytes(aCryptRet.second, aCryptRet.first);
  2258. if(theSeqNum!=NULL)
  2259. (*theSeqNum)++;
  2260. return true;
  2261. }
  2262. ///////////////////////////////////////////////////////////////////////////////////////////
  2263. ///////////////////////////////////////////////////////////////////////////////////////////
  2264. bool TitanInterface::DecryptMessage(const char *theBuf, unsigned long theLen, BaseMessage &theOutMsg, SocketPipe **thePipePP)
  2265. {
  2266. //titanDebug("TitanInterface::DecryptMessage");
  2267. if (theOutMsg.GetMessageClass() == WONMsg::eTMessage)
  2268. {
  2269. titanDebug("DecryptTMessage FAIL: We no longer use encrypted TMessages!");
  2270. return false;
  2271. }
  2272. else
  2273. return DecryptNonTMessage(theBuf, theLen, theOutMsg, thePipePP);
  2274. }
  2275. ///////////////////////////////////////////////////////////////////////////////////////////
  2276. ///////////////////////////////////////////////////////////////////////////////////////////
  2277. /*
  2278. bool TitanInterface::DecryptTMessage(const char *theBuf, unsigned long theLen, BaseMessage &theOutMsg, SocketPipe **thePipePP)
  2279. {
  2280. titanDebug("TitanInterface::DecryptTMessage");
  2281. BFSymmetricKey **aSessionKey;
  2282. unsigned short aSessionId = 0, *aSeqNum = NULL;
  2283. const char *aDataPtr = theBuf + 1;
  2284. if(aSessionId!=0) {
  2285. if(*(unsigned short*)aDataPtr!=aSessionId) {
  2286. titanDebug("DecryptTMessage FAIL: Incorrect session id.");
  2287. *thePipePP = NULL;
  2288. delete *aSessionKey; *aSessionKey = NULL;
  2289. FactFailOver();
  2290. return false;
  2291. }
  2292. aDataPtr+=2;
  2293. }
  2294. CryptKeyBase::CryptReturn aCryptRet(NULL,0);
  2295. aCryptRet = (*aSessionKey)->Decrypt((const unsigned char*)aDataPtr,theLen - (aDataPtr - theBuf));
  2296. auto_ptr<unsigned char> aDeleteCryptRet(aCryptRet.first);
  2297. if(aCryptRet.first==NULL) {
  2298. titanDebug("DecryptTMessage FAIL: Unable to decrypt message.");
  2299. *thePipePP = NULL;
  2300. delete *aSessionKey; *aSessionKey = NULL;
  2301. FactFailOver();
  2302. return false;
  2303. }
  2304. aDataPtr = (const char *)aCryptRet.first;
  2305. if(aSeqNum!=NULL) {
  2306. if(aCryptRet.second<2 || *aSeqNum!=*(unsigned short*)aDataPtr) {
  2307. titanDebug("DecryptTMessage FAIL: Invalid sequence number received.");
  2308. *thePipePP = NULL;
  2309. delete *aSessionKey; *aSessionKey = NULL;
  2310. FactFailOver();
  2311. return false;
  2312. }
  2313. (*aSeqNum)++;
  2314. aDataPtr+=2;
  2315. }
  2316. theOutMsg.ResetBuffer();
  2317. theOutMsg.AppendBytes(aCryptRet.second - (aDataPtr - (const char*)aCryptRet.first), aDataPtr);
  2318. if(theOutMsg.GetDataLen() < theOutMsg.GetHeaderLength()) {
  2319. titanDebug("DecryptTMessage FAIL: Message too small.");
  2320. FactFailOver();
  2321. return false;
  2322. }
  2323. return true;
  2324. }
  2325. */
  2326. ///////////////////////////////////////////////////////////////////////////////////////////
  2327. ///////////////////////////////////////////////////////////////////////////////////////////
  2328. bool TitanInterface::DecryptNonTMessage(const char *theBuf, unsigned long theLen, BaseMessage &theOutMsg, SocketPipe **thePipePP)
  2329. {
  2330. //titanDebug("TitanInterface::DecryptNonTMessage");
  2331. BFSymmetricKey **aSessionKey;
  2332. BFSymmetricKey *aDummyKeyPtr = NULL;
  2333. unsigned short aSessionId = 0, *aSeqNum = NULL;
  2334. const char *aDataPtr = theBuf + 1;
  2335. if (*thePipePP == mRoutePipe[0])
  2336. aSessionKey = &(mRouteSessionKey[0]);
  2337. else if (*thePipePP == mRoutePipe[1])
  2338. aSessionKey = &(mRouteSessionKey[1]);
  2339. else if (*thePipePP == mDirPipe)
  2340. {
  2341. aSessionKey = &mDirSessionKey;
  2342. aSessionId = mDirSessionId;
  2343. aSeqNum = &mDirInSeqNum;
  2344. }
  2345. else if(*thePipePP==mFactPipe)
  2346. {
  2347. aSessionKey = &mFactSessionKey;
  2348. aSessionId = mFactSessionId;
  2349. }
  2350. else
  2351. aSessionKey = &aDummyKeyPtr; // if it's not a server pipe, we assume that it is a game connection (i.e. use mGameKey)
  2352. if(aSessionId!=0) {
  2353. if(*(unsigned short*)aDataPtr!=aSessionId) {
  2354. titanDebug("FAIL: Incorrect session id in non-Tmessage.");
  2355. *thePipePP = NULL;
  2356. delete *aSessionKey; *aSessionKey = NULL;
  2357. return false;
  2358. }
  2359. aDataPtr+=2;
  2360. }
  2361. CryptKeyBase::CryptReturn aCryptRet(NULL,0);
  2362. if (*aSessionKey)
  2363. aCryptRet = (*aSessionKey)->Decrypt((const unsigned char*)aDataPtr,theLen - (aDataPtr - theBuf));
  2364. else
  2365. aCryptRet = mGameKey.Decrypt((const unsigned char*)aDataPtr,theLen - (aDataPtr - theBuf));
  2366. auto_ptr<unsigned char> aDeleteCryptRet(aCryptRet.first);
  2367. if(aCryptRet.first==NULL) {
  2368. titanDebug("FAIL: Unable to decrypt non-Tmessage.");
  2369. *thePipePP = NULL;
  2370. delete *aSessionKey; *aSessionKey = NULL;
  2371. return false;
  2372. }
  2373. aDataPtr = (const char *)aCryptRet.first;
  2374. if(aSeqNum!=NULL) {
  2375. if(aCryptRet.second<2 || *aSeqNum!=*(unsigned short*)aDataPtr) {
  2376. titanDebug("FAIL: Invalid sequence number received on non-Tmessage.");
  2377. *thePipePP = NULL;
  2378. delete *aSessionKey; *aSessionKey = NULL;
  2379. return false;
  2380. }
  2381. (*aSeqNum)++;
  2382. aDataPtr+=2;
  2383. }
  2384. theOutMsg.ResetBuffer();
  2385. theOutMsg.AppendByte(WONMsg::HeaderService1Message1);
  2386. theOutMsg.AppendBytes(aCryptRet.second - (aDataPtr - (const char*)aCryptRet.first), aDataPtr);
  2387. if(theOutMsg.GetDataLen() < theOutMsg.GetHeaderLength()) {
  2388. titanDebug("FAIL: non-Tmessage too small.");
  2389. return false;
  2390. }
  2391. return true;
  2392. }
  2393. ///////////////////////////////////////////////////////////////////////////////////////////
  2394. ///////////////////////////////////////////////////////////////////////////////////////////
  2395. void TitanInterface::FactHandleStartProcess(void)
  2396. {
  2397. titanDebug("TitanInterface::FactHandleStartProcess");
  2398. AutoCrit aCrit(mPipeCrit);
  2399. if(mFactSessionKey==NULL) {
  2400. titanDebug("FAIL: Don't have session key.");
  2401. return;
  2402. }
  2403. TMessage anEncryptMsg;
  2404. if(!EncryptMessage(mStartProcessMsg,anEncryptMsg,*mFactSessionKey,mFactSessionId,NULL)) {
  2405. titanDebug("FAIL: Failed to encrypt start process message.");
  2406. return;
  2407. }
  2408. if(!SendMsg(mFactPipe, anEncryptMsg))
  2409. {
  2410. titanDebug("FAIL: TitanInterface::FactHandleStartProcess!");
  2411. FactFailOver();
  2412. return;
  2413. }
  2414. }
  2415. ///////////////////////////////////////////////////////////////////////////////////////////
  2416. ///////////////////////////////////////////////////////////////////////////////////////////
  2417. void TitanInterface::RecordEvent(unsigned short theEventType)
  2418. {
  2419. titanDebug("TitanInterface::RecordEvent");
  2420. // Don't log events for LAN games. Can't log events if no Event Servers.
  2421. if (mIsLan || EVENTSERVER_NUM == 0)
  2422. return;
  2423. // If we don't have a certificate, we don't have a user-id...
  2424. if (!mCertificate)
  2425. {
  2426. titanDebug("TitanInterface::RecordEvent mCertificate is NULL!");
  2427. return;
  2428. }
  2429. WONMsg::SMsgEventTaggedRecordEvent aRecordEventMsg;
  2430. try
  2431. {
  2432. aRecordEventMsg.SetHasDateTime(false);
  2433. aRecordEventMsg.SetHasRelatedServer(false);
  2434. aRecordEventMsg.SetHasRelatedClient(false);
  2435. aRecordEventMsg.SetHasRelatedUser(true);
  2436. aRecordEventMsg.SetUserAuthenticationMethod(USERAUTHENTICATIONMETHOD_AUTH1);
  2437. aRecordEventMsg.SetUserId(mCertificate->GetUserId());
  2438. aRecordEventMsg.SetActivityType(theEventType);
  2439. aRecordEventMsg.SetTag(mEventTag++);
  2440. // Add data that is specific to this particular type of event.
  2441. // LOBBY_ENTER (WON user ID, date/time, time zone, client type (version & language))
  2442. // LOBBY_EXIT (WON user ID, date/time, duration of stay, behind firewall or not)
  2443. // GAME_CREATE (WON user ID, date/time, num players, routing-server or peer-to-peer)
  2444. // GAME_ENTER (WON user ID, date/time)
  2445. // GAME_EXIT (WON user ID, date/time, duration of game session)
  2446. // SYNC_ERROR (WON user ID, date/time)
  2447. // CHEAT_DETECT(WON user ID, date/time)
  2448. switch (theEventType)
  2449. {
  2450. case ACTIVITYTYPE_HOMEWORLD_LOBBY_ENTER:
  2451. {
  2452. // add timezone detail
  2453. long aRealTimezone = _timezone;
  2454. if (_daylight != 0)
  2455. aRealTimezone += 3600;
  2456. aRecordEventMsg.AddDetail(ACTIVITYHISTORYDETAILTYPE_TIMEZONE, aRealTimezone);
  2457. // add version detail
  2458. aRecordEventMsg.AddDetail(ACTIVITYHISTORYDETAILTYPE_VERSION_STRING, StringToWString(versionString));
  2459. // add language detail
  2460. aRecordEventMsg.AddDetail(ACTIVITYHISTORYDETAILTYPE_HOMEWORLD_LANGUAGE, strCurLanguage);
  2461. break;
  2462. }
  2463. case ACTIVITYTYPE_HOMEWORLD_LOBBY_EXIT:
  2464. // add duration of stay detail
  2465. aRecordEventMsg.AddDetail(ACTIVITYHISTORYDETAILTYPE_SESSION_LENGTH, time(NULL) - mLobbyEnterTime);
  2466. // add firewall-presence detail
  2467. aRecordEventMsg.AddDetail(ACTIVITYHISTORYDETAILTYPE_BEHIND_FIREWALL, mBehindFirewall);
  2468. break;
  2469. case ACTIVITYTYPE_HOMEWORLD_GAME_CREATE:
  2470. {
  2471. // add player count detail
  2472. aRecordEventMsg.AddDetail(ACTIVITYHISTORYDETAILTYPE_PLAYER_COUNT, tpGameCreated.numPlayers);
  2473. // add Internet game type detail (Routing Server or peer-to-peer)
  2474. aRecordEventMsg.AddDetail(ACTIVITYHISTORYDETAILTYPE_USING_ROUTING_SERVER, tpGameCreated.userBehindFirewall);
  2475. break;
  2476. }
  2477. case ACTIVITYTYPE_HOMEWORLD_GAME_EXIT:
  2478. // add duration of game session detail
  2479. aRecordEventMsg.AddDetail(ACTIVITYHISTORYDETAILTYPE_SESSION_LENGTH, time(NULL) - mGameStartTime);
  2480. // add the disconnect code (voluntary/involuntary)
  2481. aRecordEventMsg.AddDetail(ACTIVITYHISTORYDETAILTYPE_DISCONNECT_CODE, mGameDisconnectWasVoluntary);
  2482. break;
  2483. }
  2484. // set/reset time variables
  2485. switch (theEventType)
  2486. {
  2487. case ACTIVITYTYPE_HOMEWORLD_LOBBY_ENTER:
  2488. mLobbyEnterTime = time(NULL); break;
  2489. case ACTIVITYTYPE_HOMEWORLD_LOBBY_EXIT:
  2490. mLobbyEnterTime = 0; // not really necessary, but what the heck...
  2491. case ACTIVITYTYPE_HOMEWORLD_GAME_ENTER:
  2492. mGameStartTime = time(NULL); break;
  2493. case ACTIVITYTYPE_HOMEWORLD_GAME_EXIT:
  2494. mGameStartTime = 0; break;
  2495. }
  2496. aRecordEventMsg.Pack();
  2497. char *aBuf = new char[aRecordEventMsg.GetDataLen()];
  2498. memcpy(aBuf,aRecordEventMsg.GetDataPtr(),aRecordEventMsg.GetDataLen());
  2499. // Send request
  2500. mEventPipe = new SocketPipe;
  2501. mEventPipe->AddOutgoingCmd(new OpenCmd(EasySocket::UDP));
  2502. for (int i = 0; i < NUM_EVENTS_TO_SEND; ++i)
  2503. {
  2504. mEventPipe->AddOutgoingCmd(new SendToCmd(reinterpret_cast<SOCKADDR&>(EVENTSERVER_ADDRESSES[0]), aBuf, aRecordEventMsg.GetDataLen(), (i == NUM_EVENTS_TO_SEND - 1), true));
  2505. mEventPipe->AddOutgoingCmd(new TimerCmd(TIME_BETWEEN_EVENTS, true));
  2506. }
  2507. mEngine->AddPipe(mEventPipe);
  2508. }
  2509. catch (WONException& anEx)
  2510. {
  2511. titanDebug("EXCEPTION: TitanInterface::RecordEvent: %s", (char*)anEx.what());
  2512. return;
  2513. }
  2514. }
  2515. ///////////////////////////////////////////////////////////////////////////////////////////
  2516. ///////////////////////////////////////////////////////////////////////////////////////////
  2517. void TitanInterface::DirHandleGetTitanServers(void)
  2518. {
  2519. titanDebug("TitanInterface::DirHandleGetTitanServers");
  2520. AutoCrit aCrit(mPipeCrit);
  2521. // Build get dir msg
  2522. WONMsg::SMsgDirG2GetEntity aMsg(WONMsg::SMsgDirG2KeyedBase::KT_DIRECTORY, true /* Ex version*/);
  2523. try
  2524. {
  2525. aMsg.SetPath(TITANSERVER_DIR);
  2526. aMsg.SetFlags(WONMsg::GF_DECOMPROOT | WONMsg::GF_DECOMPRECURSIVE | WONMsg::GF_DECOMPSERVICES | WONMsg::GF_ADDTYPE | WONMsg::GF_SERVADDNAME | WONMsg::GF_SERVADDNETADDR | WONMsg::GF_ADDDOTYPE | WONMsg::GF_ADDDODATA);
  2527. aMsg.AddGetType(VALIDVERSIONS_OBJ.c_str(), VALIDVERSIONS_OBJ.size());
  2528. aMsg.Pack();
  2529. }
  2530. catch (WONException& anEx)
  2531. {
  2532. titanDebug("EXCEPTION: TitanInterface::DirHandleGetTitanServers: %s", (char*)anEx.what());
  2533. return;
  2534. }
  2535. // Connect and send request
  2536. SOCKADDR_IN aDirAddr;
  2537. EasySocket::getSockAddrIn(aDirAddr, DIRSERVER_IPSTRINGS[mCurDirServer], DIRSERVER_PORTS[mCurDirServer]);
  2538. mDirPipe = ConnectAndSend(reinterpret_cast<SOCKADDR&>(aDirAddr), aMsg);
  2539. }
  2540. ///////////////////////////////////////////////////////////////////////////////////////////
  2541. ///////////////////////////////////////////////////////////////////////////////////////////
  2542. void TitanInterface::DirHandleGetHWDirectory(void)
  2543. {
  2544. titanDebug("TitanInterface::DirHandleGetHWDirectory");
  2545. AutoCrit aCrit(mPipeCrit);
  2546. // Build get dir msg
  2547. WONMsg::SMsgDirG2GetEntity aMsg(WONMsg::SMsgDirG2KeyedBase::KT_DIRECTORY, true /* Ex version*/);
  2548. try
  2549. {
  2550. aMsg.SetPath(HOMEWORLD_DIR);
  2551. aMsg.SetFlags(WONMsg::GF_DECOMPRECURSIVE | WONMsg::GF_DECOMPSERVICES | WONMsg::GF_DECOMPSUBDIRS | WONMsg::GF_ADDTYPE | WONMsg::GF_ADDDISPLAYNAME | WONMsg::GF_SERVADDNAME | WONMsg::GF_SERVADDNETADDR | WONMsg::GF_DIRADDNAME | WONMsg::GF_ADDDOTYPE | WONMsg::GF_ADDDODATA);
  2552. aMsg.AddGetType(DESCRIPTION_OBJ.c_str(), DESCRIPTION_OBJ.size());
  2553. aMsg.AddGetType(ROOM_FLAGS_OBJ.c_str(), ROOM_FLAGS_OBJ.size());
  2554. aMsg.AddGetType(ROOM_CLIENTCOUNT_OBJ.c_str(), ROOM_CLIENTCOUNT_OBJ.size());
  2555. aMsg.AddGetType(FACT_CUR_SERVER_COUNT_OBJ.c_str(), FACT_CUR_SERVER_COUNT_OBJ.size());
  2556. aMsg.AddGetType(FACT_TOTAL_SERVER_COUNT_OBJ.c_str(), FACT_TOTAL_SERVER_COUNT_OBJ.size());
  2557. aMsg.AddGetType(SERVER_UPTIME_OBJ.c_str(), SERVER_UPTIME_OBJ.size());
  2558. aMsg.Pack();
  2559. }
  2560. catch (WONException& anEx)
  2561. {
  2562. titanDebug("EXCEPTION: TitanInterface::DirHandleGetHWDirectory: %s", (char*)anEx.what());
  2563. return;
  2564. }
  2565. // Connect and send request
  2566. SOCKADDR_IN aDirAddr;
  2567. EasySocket::getSockAddrIn(aDirAddr, DIRSERVER_IPSTRINGS[mCurDirServer], DIRSERVER_PORTS[mCurDirServer]);
  2568. TMessage anEncryptMsg;
  2569. if(mDirSessionKey==NULL) {
  2570. titanDebug("FAIL: Don't have session key.");
  2571. return;
  2572. }
  2573. if(!EncryptMessage(aMsg,anEncryptMsg,*mDirSessionKey,mDirSessionId,&mDirOutSeqNum)) {
  2574. titanDebug("FAIL: Failed to encrypt get dir message.");
  2575. return;
  2576. }
  2577. if(mDirPipe!=NULL)
  2578. {
  2579. if(!SendMsg(mDirPipe, anEncryptMsg))
  2580. {
  2581. titanDebug("FAIL: TitanInterface::DirHandleGetHWDirectory!");
  2582. return;
  2583. }
  2584. }
  2585. else
  2586. mDirPipe = ConnectAndSend(reinterpret_cast<SOCKADDR&>(aDirAddr), anEncryptMsg);
  2587. }
  2588. ///////////////////////////////////////////////////////////////////////////////////////////
  2589. ///////////////////////////////////////////////////////////////////////////////////////////
  2590. void TitanInterface::DirStartPeerLogin(void)
  2591. {
  2592. titanDebug("TitanInterface::StartPeerLogin");
  2593. if(mCertificate==NULL) {
  2594. titanDebug("FAIL: Don't have certificate.");
  2595. return;
  2596. }
  2597. WONMsg::TMsgAuth1Request aMsg;
  2598. try
  2599. {
  2600. aMsg.SetAuthMode(WONAuth::AUTH_SESSION);
  2601. aMsg.SetEncryptMode(WONAuth::ENCRYPT_BLOWFISH);
  2602. aMsg.SetEncryptFlags(WONAuth::EFLAGS_NONE);
  2603. aMsg.SetRawBuf(mCertificate->GetRaw(),mCertificate->GetRawLen());
  2604. aMsg.Pack();
  2605. }
  2606. catch (WONException& anEx)
  2607. {
  2608. titanDebug("EXCEPTION: TitanInterface::DirStartPeerLogin: %s", (char*)anEx.what());
  2609. return;
  2610. }
  2611. // Connect and send request
  2612. SOCKADDR_IN aDirAddr;
  2613. EasySocket::getSockAddrIn(aDirAddr, DIRSERVER_IPSTRINGS[mCurDirServer], DIRSERVER_PORTS[mCurDirServer]);
  2614. mDirPipe = ConnectAndSend(reinterpret_cast<SOCKADDR&>(aDirAddr), aMsg);
  2615. }
  2616. ///////////////////////////////////////////////////////////////////////////////////////////
  2617. ///////////////////////////////////////////////////////////////////////////////////////////
  2618. void
  2619. TitanInterface::RequestDirectory()
  2620. {
  2621. // Toss old connection if needed
  2622. titanDebug("TitanInterface::RequestDirectory");
  2623. AutoCrit aCrit(mPipeCrit);
  2624. if (mDirPipe)
  2625. {
  2626. titanDebug("NOTE: TitanInterface::RequestDirectory already in progress.");
  2627. return;
  2628. }
  2629. aCrit.Leave();
  2630. if (AUTHSERVER_NUM==0)
  2631. DirHandleGetTitanServers();
  2632. else if(mDirSessionKey!=NULL)
  2633. DirHandleGetHWDirectory();
  2634. else
  2635. DirStartPeerLogin();
  2636. }
  2637. ///////////////////////////////////////////////////////////////////////////////////////////
  2638. ///////////////////////////////////////////////////////////////////////////////////////////
  2639. void
  2640. TitanInterface::RequestCreateGame(const wchar_t* theGame, DirectoryCustomInfo* myInfo)
  2641. {
  2642. titanDebug("TitanInterface::RequestCreateGame");
  2643. if (! mRoutePipe[0])
  2644. {
  2645. titanDebug("FAIL: TitanInterface::RequestCreateGame, no RoutingPipe!");
  2646. return;
  2647. }
  2648. mGameKey.Create(GAMEKEY_SIZE);
  2649. memcpy(myInfo->sessionKey,mGameKey.GetKey(),GAMEKEY_SIZE);
  2650. AutoCrit aCrit(mRoutingCrit);
  2651. WONMsg::MMsgRoutingCreateDataObject aCreateDataObjectMsg;
  2652. try
  2653. {
  2654. aCreateDataObjectMsg.SetLinkId(0 /* ALL_USERS */);
  2655. aCreateDataObjectMsg.SetOwnerId(mMyClientId[0]);
  2656. aCreateDataObjectMsg.SetLifespan(0);
  2657. aCreateDataObjectMsg.SetDataType(gameTag);
  2658. aCreateDataObjectMsg.AppendToDataType(WONCommon::RawBuffer((unsigned char*)theGame, wcslen(theGame)*2));
  2659. aCreateDataObjectMsg.SetData(WONCommon::RawBuffer((unsigned char*)myInfo, sizeof(*myInfo) + myInfo->stringdatalength - 1));
  2660. aCreateDataObjectMsg.Pack();
  2661. }
  2662. catch (WONException& anEx)
  2663. {
  2664. titanDebug("EXCEPTION: TitanInterface::RequestCreateGame: %s", (char*)anEx.what());
  2665. return;
  2666. }
  2667. if (! EncryptAndSendRoutingMsg(aCreateDataObjectMsg,0))
  2668. {
  2669. titanDebug("FAIL: TitanInterface::SendMsg, send CreateGame");
  2670. }
  2671. else
  2672. {
  2673. mWaitingRequestQueue[0].push_back(WONMsg::RoutingCreateDataObject);
  2674. }
  2675. }
  2676. ///////////////////////////////////////////////////////////////////////////////////////////
  2677. ///////////////////////////////////////////////////////////////////////////////////////////
  2678. void TitanInterface::RequestDeleteGame(const wchar_t* theGame)
  2679. {
  2680. titanDebug("TitanInterface::RequestDeleteGame");
  2681. if (! mRoutePipe[0])
  2682. {
  2683. titanDebug("FAIL: TitanInterface::RequestDeleteGame, no RoutingPipe!");
  2684. return;
  2685. }
  2686. AutoCrit aCrit(mRoutingCrit);
  2687. WONMsg::MMsgRoutingDeleteDataObject aDeleteDataObjectMsg;
  2688. try
  2689. {
  2690. aDeleteDataObjectMsg.SetLinkId(0 /* ALL_USERS */);
  2691. aDeleteDataObjectMsg.SetDataType(gameTag);
  2692. aDeleteDataObjectMsg.AppendToDataType(WONCommon::RawBuffer((unsigned char*)theGame, wcslen(theGame)*2));
  2693. aDeleteDataObjectMsg.Pack();
  2694. }
  2695. catch (WONException& anEx)
  2696. {
  2697. titanDebug("EXCEPTION: TitanInterface::RequestDeleteGame: %s", (char*)anEx.what());
  2698. return;
  2699. }
  2700. if (! EncryptAndSendRoutingMsg(aDeleteDataObjectMsg,0))
  2701. {
  2702. titanDebug("FAIL: TitanInterface::SendMsg, send DeleteGame");
  2703. }
  2704. mWaitingRequestQueue[0].push_back(WONMsg::RoutingDeleteDataObject);
  2705. }
  2706. ///////////////////////////////////////////////////////////////////////////////////////////
  2707. ///////////////////////////////////////////////////////////////////////////////////////////
  2708. void
  2709. TitanInterface::RequestReplaceGame(const wchar_t* theGame, DirectoryCustomInfo* myInfo, unsigned long replaceTimeout)
  2710. {
  2711. titanDebug("TitanInterface::RequestReplaceGame");
  2712. if (! mRoutePipe[0])
  2713. {
  2714. titanDebug("FAIL: TitanInterface::RequestReplaceGame, no RoutingPipe!");
  2715. return;
  2716. }
  2717. AutoCrit aCrit(mRoutingCrit);
  2718. WONMsg::MMsgRoutingReplaceDataObject aReplaceDataObjectMsg;
  2719. try
  2720. {
  2721. aReplaceDataObjectMsg.SetLinkId(0 /* ALL_USERS */);
  2722. aReplaceDataObjectMsg.SetDataType(gameTag);
  2723. aReplaceDataObjectMsg.AppendToDataType(WONCommon::RawBuffer((unsigned char*)theGame, wcslen(theGame)*2));
  2724. aReplaceDataObjectMsg.SetData(WONCommon::RawBuffer((unsigned char*)myInfo, sizeof(*myInfo) + myInfo->stringdatalength - 1));
  2725. aReplaceDataObjectMsg.Pack();
  2726. }
  2727. catch (WONException& anEx)
  2728. {
  2729. titanDebug("EXCEPTION: TitanInterface::RequestReplaceGame: %s", (char*)anEx.what());
  2730. return;
  2731. }
  2732. // send the replace request
  2733. if (! EncryptAndSendRoutingMsg(aReplaceDataObjectMsg,0))
  2734. {
  2735. titanDebug("FAIL: TitanInterface::SendMsg, send ReplaceGame");
  2736. }
  2737. mWaitingRequestQueue[0].push_back(WONMsg::RoutingReplaceDataObject);
  2738. // send a renew request if needed
  2739. if (replaceTimeout != 0)
  2740. RequestRenewGameLifespan(theGame, TITAN_GAME_EXPIRE_TIME);
  2741. }
  2742. //////////////////////////////////////////////////////////////////////////////////////////////////////
  2743. //////////////////////////////////////////////////////////////////////////////////////////////////////
  2744. void
  2745. TitanInterface::RequestRenewGameLifespan(const wchar_t* theGame, unsigned long newLifespan)
  2746. {
  2747. titanDebug("TitanInterface::RequestRenewGameLifespan");
  2748. if (! mRoutePipe[0])
  2749. {
  2750. titanDebug("FAIL: TitanInterface::RequestRenewGameLifespan, no RoutingPipe!");
  2751. return;
  2752. }
  2753. AutoCrit aCrit(mRoutingCrit);
  2754. WONMsg::MMsgRoutingRenewDataObject aRenewDataObjectMsg;
  2755. try
  2756. {
  2757. aRenewDataObjectMsg.SetLinkId(0 /* ALL_USERS */);
  2758. aRenewDataObjectMsg.SetDataType(gameTag);
  2759. aRenewDataObjectMsg.AppendToDataType(WONCommon::RawBuffer((unsigned char*)theGame, wcslen(theGame)*2));
  2760. aRenewDataObjectMsg.SetNewLifespan(newLifespan);
  2761. aRenewDataObjectMsg.Pack();
  2762. }
  2763. catch (WONException& anEx)
  2764. {
  2765. titanDebug("EXCEPTION: TitanInterface::RequestReplaceGame: %s", (char*)anEx.what());
  2766. return;
  2767. }
  2768. // send the renew request
  2769. if (! EncryptAndSendRoutingMsg(aRenewDataObjectMsg,0))
  2770. {
  2771. titanDebug("FAIL: TitanInterface::SendMsg, send Renew(lifespan)");
  2772. }
  2773. mWaitingRequestQueue[0].push_back(WONMsg::RoutingRenewDataObject);
  2774. }
  2775. //////////////////////////////////////////////////////////////////////////////////////////////////////
  2776. //////////////////////////////////////////////////////////////////////////////////////////////////////
  2777. void TitanInterface::ConnectToClient(Address* theAddressP)
  2778. {
  2779. if(mUseRoutingServer)
  2780. return;
  2781. ClientNetAddr aCAddr = MakeClientNetAddr(theAddressP);
  2782. AutoCrit aCrit(mClientCrit);
  2783. ClientToPipe::iterator anItr = mClientMap.find(aCAddr);
  2784. // If no existing connection...
  2785. if (anItr == mClientMap.end())
  2786. {
  2787. SocketPipe* aPipeP = ConnectTo(*theAddressP, mStreamType, WONMisc::ptUnsignedShort);
  2788. if (! aPipeP)
  2789. {
  2790. titanDebug("FAIL: TitanInterface::ConnectToClient, fail ConnectTo");
  2791. return;
  2792. }
  2793. // Add pipe to engine and update client map
  2794. mEngine->AddPipe(aPipeP);
  2795. mClientMap[aCAddr].pipe = aPipeP;
  2796. aCrit.Leave();
  2797. if(mGameCreationState==GAME_STARTED && AddressesAndPortsAreEqual(*theAddressP,mCaptainAddress))
  2798. mCaptainPipe = aPipeP;
  2799. }
  2800. else if(mGameCreationState==GAME_STARTED && AddressesAndPortsAreEqual(*theAddressP,mCaptainAddress))
  2801. mCaptainPipe = anItr->second.pipe;
  2802. }
  2803. //////////////////////////////////////////////////////////////////////////////////////////////////////
  2804. //////////////////////////////////////////////////////////////////////////////////////////////////////
  2805. ClientNetAddr
  2806. TitanInterface::MakeClientNetAddr(Address* theAddressP)
  2807. {
  2808. ClientNetAddr aCAddr;
  2809. if ( mIpType == ip )
  2810. {
  2811. aCAddr.first = theAddressP->AddrPart.IP;
  2812. aCAddr.second = theAddressP->Port;
  2813. }
  2814. else
  2815. {
  2816. unsigned long aFirstLong;
  2817. unsigned long aSecondLong;
  2818. memcpy( &aFirstLong, theAddressP->AddrPart.etherAddr, 4 );
  2819. ((char*)(&aSecondLong))[0] = theAddressP->AddrPart.etherAddr[4];
  2820. ((char*)(&aSecondLong))[1] = theAddressP->AddrPart.etherAddr[5];
  2821. ((char*)(&aSecondLong))[2] = ((char*)(&(theAddressP->Port)))[0];
  2822. ((char*)(&aSecondLong))[3] = ((char*)(&(theAddressP->Port)))[1];
  2823. aCAddr.first = aFirstLong;
  2824. aCAddr.second = aSecondLong;
  2825. }
  2826. return aCAddr;
  2827. }
  2828. //////////////////////////////////////////////////////////////////////////////////////////////////////
  2829. //////////////////////////////////////////////////////////////////////////////////////////////////////
  2830. void
  2831. TitanInterface::SendPing(Address* theAddressP,unsigned int pingsizebytes)
  2832. {
  2833. // Build change user msg
  2834. WONMsg::MMsgCommPing aMsg;
  2835. try
  2836. {
  2837. aMsg.Pack();
  2838. }
  2839. catch (WONException& anEx)
  2840. {
  2841. titanDebug("EXCEPTION: TitanInterface::SendPing: %s", (char*)anEx.what());
  2842. return;
  2843. }
  2844. // Connect and send request
  2845. ConnectAndSend(*theAddressP, aMsg, mStreamType, (pingsizebytes == 4) ? WONMisc::ptUnsignedLong : WONMisc::ptUnsignedShort);
  2846. }
  2847. //////////////////////////////////////////////////////////////////////////////////////////////////////
  2848. //////////////////////////////////////////////////////////////////////////////////////////////////////
  2849. unsigned long
  2850. TitanInterface::StartRoutingServer(const wchar_t* theChannelName, const wchar_t* theChannelDescription, const wchar_t* thePassword, bool isGameServer,unsigned char *routingaddress)
  2851. {
  2852. titanDebug("TitanInterface::StartRoutingServer");
  2853. AutoCrit aPipeCrit(mPipeCrit);
  2854. unsigned int roomflags = 0;
  2855. if(mCertificate==NULL) {
  2856. titanDebug("FAIL: Don't have certificate.");
  2857. return 0;
  2858. }
  2859. // Toss old connection if needed
  2860. if (mFactPipe)
  2861. {
  2862. titanDebug("NOTE: TitanInterface::StartRoutingServer Close existing FactPipe!");
  2863. mFactPipe->AddOutgoingCmd(new CloseNowCmd(false, false, 0, false));
  2864. mFactPipe = NULL;
  2865. }
  2866. aPipeCrit.Leave();
  2867. try
  2868. {
  2869. // Build the command line
  2870. wstring aCmdLine;
  2871. if (thePassword && thePassword[0] != '\0')
  2872. {
  2873. aCmdLine += L" -Password ";
  2874. aCmdLine += thePassword;
  2875. roomflags |= ROOMFLAGS_PASSWORDPROTECTED;
  2876. }
  2877. mStartProcessMsg.SetAddCmdLine(true);
  2878. mStartProcessMsg.SetCmdLine(aCmdLine);
  2879. // Build start process msg
  2880. if(isGameServer)
  2881. mStartProcessMsg.SetProcessName(ROUTINGSERV_GAME);
  2882. else
  2883. mStartProcessMsg.SetProcessName(ROUTINGSERV_CHAT);
  2884. if(theChannelName[0]!='\0') {
  2885. WONCommon::DataObjectTypeSet aDOSet;
  2886. aDOSet.insert(WONCommon::DataObject(DESCRIPTION_OBJ, WONCommon::RawBuffer(reinterpret_cast<const unsigned char*>(theChannelDescription),wcslen(theChannelDescription) * 2)));
  2887. aDOSet.insert(WONCommon::DataObject(ROOM_FLAGS_OBJ, WONCommon::RawBuffer((unsigned char*)&roomflags,4)));
  2888. mRegisterRoutingServerMsg.SetDataObjects(aDOSet);
  2889. mRegisterRoutingServerMsg.SetDisplayName(theChannelName);
  2890. }
  2891. mStartProcessMsg.SetTotalPorts(1);
  2892. mStartProcessMsg.Pack();
  2893. }
  2894. catch (WONException& anEx)
  2895. {
  2896. titanDebug("EXCEPTION: TitanInterface::StartRoutingServer: %s", (char*)anEx.what());
  2897. return 0;
  2898. }
  2899. WONMsg::TMsgAuth1Request aMsg;
  2900. try
  2901. {
  2902. aMsg.SetAuthMode(WONAuth::AUTH_SESSION);
  2903. aMsg.SetEncryptMode(WONAuth::ENCRYPT_BLOWFISH);
  2904. aMsg.SetEncryptFlags(WONAuth::EFLAGS_NOTSEQUENCED);
  2905. aMsg.SetRawBuf(mCertificate->GetRaw(),mCertificate->GetRawLen());
  2906. aMsg.Pack();
  2907. }
  2908. catch (WONException& anEx)
  2909. {
  2910. titanDebug("EXCEPTION: TitanInterface::StartRoutingServer: %s", (char*)anEx.what());
  2911. return 0;
  2912. }
  2913. if (!routingaddress)
  2914. {
  2915. if(FACTSERVER_NUM==0) {
  2916. return 0;
  2917. }
  2918. if(mCurFactServer>=FACTSERVER_NUM)
  2919. mCurFactServer%=FACTSERVER_NUM;
  2920. mFailFactOverDirectly = false;
  2921. }
  2922. else
  2923. {
  2924. mFailFactOverDirectly = true;
  2925. }
  2926. // Connect and send request
  2927. AutoCrit aStartRoutingCrit(mStartRoutingCrit);
  2928. mChannelName = theChannelName;
  2929. mChannelDescription = theChannelDescription;
  2930. mRoomPassword = (thePassword==NULL) ? L"" : thePassword;
  2931. mIsGameServer = isGameServer;
  2932. if (!routingaddress)
  2933. {
  2934. mFactPipe = ConnectAndSend(FACTSERVER_ADDRESSES[mCurFactServer], aMsg);
  2935. }
  2936. else
  2937. {
  2938. SOCKADDR_IN buildaddr;
  2939. BuildAddress(buildaddr, routingaddress);
  2940. mFactPipe = ConnectAndSend(buildaddr, aMsg);
  2941. }
  2942. return 1;
  2943. }
  2944. //////////////////////////////////////////////////////////////////////////////////////////////////////
  2945. //////////////////////////////////////////////////////////////////////////////////////////////////////
  2946. void
  2947. TitanInterface::SendLanBroadcast(const void* thePacket, unsigned short theLen)
  2948. {
  2949. if ( mLanAdPipe != NULL )
  2950. {
  2951. char* aBufferP = new char[theLen];
  2952. memcpy(aBufferP,thePacket,theLen);
  2953. mLanAdPipe->AddOutgoingCmd(new BroadcastCmd(AD_PORT,aBufferP,theLen,true,true));
  2954. }
  2955. else
  2956. {
  2957. titanDebug("TitanInterface::SendLanBroadcast called when mLadAdSocket == NULL");
  2958. }
  2959. }
  2960. //////////////////////////////////////////////////////////////////////////////////////////////////////
  2961. //////////////////////////////////////////////////////////////////////////////////////////////////////
  2962. void
  2963. TitanInterface::SendPacketTo(Address* theAddressP, unsigned char titanMsgType,
  2964. const void* thePacket, unsigned short theLen,
  2965. bool addSeqNum, int theSeqNum)
  2966. {
  2967. TitanPacketMsg aMsg(titanMsgType, !mUseRoutingServer);
  2968. try
  2969. {
  2970. // insert the data into the packet
  2971. if (theLen > 0)
  2972. aMsg.SetBlob(thePacket, theLen);
  2973. // insert the game name into the packet
  2974. LockMutex(GameWereInterestedInMutex);
  2975. aMsg.SetGameName(GameWereInterestedIn);
  2976. UnLockMutex(GameWereInterestedInMutex);
  2977. aMsg.Pack();
  2978. }
  2979. catch (WONException& anEx)
  2980. {
  2981. titanDebug("EXCEPTION: TitanInterface::SendPacketTo: %s", (char*)anEx.what());
  2982. return;
  2983. }
  2984. if(mUseRoutingServer)
  2985. {
  2986. int aRouteNum = 0;
  2987. if(mGameCreationState==GAME_STARTED) aRouteNum = 1;
  2988. if(theAddressP!=NULL)
  2989. RoutingSendData(theAddressP->Port, aMsg.GetDataLen(), (const unsigned char*)aMsg.GetDataPtr(),aRouteNum,addSeqNum,theSeqNum);
  2990. else
  2991. RoutingSendDataBroadcast(aMsg.GetDataLen(), (const unsigned char*)aMsg.GetDataPtr(),aRouteNum,addSeqNum,theSeqNum);
  2992. }
  2993. else
  2994. {
  2995. AutoCrit aCrit(mClientCrit); // Enter client crit sec
  2996. ClientToPipe::iterator anItr = mClientMap.find(MakeClientNetAddr(theAddressP));
  2997. // ClientToPipe::iterator anItr = mClientMap.find(ClientNetAddr(theIP, thePort));
  2998. if (anItr != mClientMap.end())
  2999. {
  3000. #if DEBUG_DISCONNECT
  3001. string aStr((const char*)thePacket,theLen);
  3002. if(aStr.find("briandis")!=string::npos)
  3003. {
  3004. anItr->second.pipe->AddOutgoingCmd(new CloseCmd(false, false, 0, false));
  3005. return;
  3006. }
  3007. #endif // DEBUG_DISCONNECT
  3008. MiniMessage anEncryptMsg;
  3009. if(!EncryptMessage(aMsg, anEncryptMsg, mGameKey, 0, NULL)) {
  3010. titanDebug("FAIL: Failed to encrypt packet message.");
  3011. return;
  3012. }
  3013. if (! SendMsg(anItr->second.pipe, anEncryptMsg))
  3014. {
  3015. titanDebug("FAILED: TitanInterface:SendPacketTo, send packet to client!");
  3016. return;
  3017. }
  3018. #ifdef CLOCK_COMMANDS_THRU_ENGINE
  3019. anItr->second.pipe->AddOutgoingCmd(new NoOpPayloadCmd(GetTickCount(), false));
  3020. #endif // CLOCK_COMMANDS_THRU_ENGINE
  3021. }
  3022. else
  3023. {
  3024. char addressstring[50];
  3025. PrintAddressToString(addressstring,theAddressP);
  3026. titanDebug("TitanInterface::SendPacketTo unknown client %s",addressstring);
  3027. }
  3028. }
  3029. }
  3030. //////////////////////////////////////////////////////////////////////////////////////////////////////
  3031. //////////////////////////////////////////////////////////////////////////////////////////////////////
  3032. TitanInterface::threadProcess()
  3033. {
  3034. titanDebug("TitanInterface::threadProcess Starting up.");
  3035. // Listen for connections
  3036. SocketPipe* aListenP = new SocketPipe;
  3037. aListenP->AddOutgoingCmd(new OpenCmd(mStreamType));
  3038. aListenP->AddOutgoingCmd(new BindCmd(GAME_PORT));
  3039. aListenP->AddIncomingCmd(new ListenCmd);
  3040. // Stuff in a bunch of accept commands
  3041. for (int i=0; i < PREPOST_MAX; i++)
  3042. aListenP->AddIncomingCmd(new AcceptCmd(mEngine, true, false));
  3043. // Add listen pipe to engine
  3044. mEngine->AddPipe(aListenP);
  3045. // if ( mIpType == ipx )
  3046. if ( mIsLan == true )
  3047. {
  3048. // LAN Ad Pipe
  3049. mLanAdPipe = new WONMisc::SocketPipe;
  3050. mLanAdPipe->AddOutgoingCmd(new OpenCmd(mDatagramType));
  3051. mLanAdPipe->AddOutgoingCmd(new BindCmd(AD_PORT, true));
  3052. #if 0
  3053. // make LAN Ad Pipe socket linger
  3054. linger aLingerStruct;
  3055. aLingerStruct.l_onoff = 1;
  3056. aLingerStruct.l_linger = 120;
  3057. mLanAdPipe->mEasySocketP->setOption(SOL_SOCKET, SO_LINGER, reinterpret_cast<const char*>(&aLingerStruct), sizeof(aLingerStruct));
  3058. #endif
  3059. // Stuff in a bunch of recvfrom commands
  3060. for (int i=0; i < PREPOST_MAX; i++)
  3061. mLanAdPipe->AddIncomingCmd(new RecvFromCmd(new char[MAX_LAN_ADVERT_LEN],MAX_LAN_ADVERT_LEN,true,false));
  3062. // Add listen pipe to engine
  3063. mEngine->AddPipe(mLanAdPipe);
  3064. // get the local MAC address
  3065. if ( mIpType == ipx )
  3066. mLanAdPipe->mEasySocketP->getLocalAddr(myAddress.AddrPart.etherAddr);
  3067. else
  3068. myAddress.AddrPart.IP = GetLocalIPAddress();
  3069. myAddress.Port = GAME_PORT;
  3070. char addrstr[100];
  3071. PrintAddressToString(addrstr,&myAddress);
  3072. titanDebug("TitanInterface::LAN myAddress %s",addrstr);
  3073. }
  3074. // Main loop
  3075. titanDebug("TitanInterface::threadProcess Staring Main Loop.");
  3076. for (;;)
  3077. {
  3078. if (WaitForSingleObject(getStopEvent(), 0) == WAIT_OBJECT_0)
  3079. {
  3080. titanDebug("TitanInterface::threadProcess Stop requested, shutting down.");
  3081. break;
  3082. }
  3083. SocketPipe* aPipeP = mEngine->GetCompletedPipe(INFINITE);
  3084. if (aPipeP)
  3085. {
  3086. if (aPipeP->mInErrorState)
  3087. {
  3088. titanDebug("TitanInterface::threadProcess Pipe in ERROR state, closing!");
  3089. HandleCloseCmd(aPipeP);
  3090. }
  3091. else
  3092. {
  3093. numPendingIn = aPipeP->GetNumPendingIncomingCmds();
  3094. if (numPendingIn > 20)
  3095. {
  3096. titanDebug("TitanInterface::In Queue too high at %d",numPendingIn);
  3097. }
  3098. numPendingOut = aPipeP->GetNumPendingOutgoingCmds();
  3099. if (numPendingOut > 20)
  3100. {
  3101. titanDebug("TitanInterface::Out Queue too high at %d",numPendingOut);
  3102. }
  3103. auto_ptr<PipeCmd> aCmdP(aPipeP->RemoveCompletedCmd());
  3104. if (aCmdP.get())
  3105. {
  3106. switch (aCmdP->GetType())
  3107. {
  3108. case WONMisc::pctWaitForEvent:
  3109. HandleWaitCmd(aCmdP.get());
  3110. break;
  3111. case WONMisc::pctAccept:
  3112. HandleAcceptCmd(aPipeP, aCmdP.get());
  3113. break;
  3114. case WONMisc::pctClose:
  3115. case WONMisc::pctCloseNow:
  3116. HandleCloseCmd(aPipeP);
  3117. break;
  3118. case WONMisc::pctRecvPrefixed:
  3119. if(aPipeP==mCaptainPipe)
  3120. mCaptainReconnectNum = 0;
  3121. HandleRecvCmd(aPipeP, aCmdP.get(), false);
  3122. break;
  3123. case WONMisc::pctRecvFrom:
  3124. {
  3125. if(aPipeP==mCaptainPipe)
  3126. mCaptainReconnectNum = 0;
  3127. RecvFromCmd* aRecvFromCmdP = dynamic_cast<RecvFromCmd*>(aCmdP.get());
  3128. if(aPipeP==mRoutingInfoPipe) {
  3129. aPipeP->AddIncomingCmd(new RecvFromCmd(new char[32],32,true,false));
  3130. HandleMiniMsg(aPipeP, aRecvFromCmdP->mBufferP, aRecvFromCmdP->mBytesReceived);
  3131. }
  3132. else
  3133. HandleLanBroadcastMsg(aPipeP, aRecvFromCmdP->mBufferP, aRecvFromCmdP->mBytesReceived );
  3134. }
  3135. break;
  3136. case WONMisc::pctTimer:
  3137. if(aPipeP==mTimerPipe)
  3138. AuthHandleRefresh();
  3139. break;
  3140. #ifdef CLOCK_COMMANDS_THRU_ENGINE
  3141. case WONMisc::pctNoOpPayload:
  3142. {
  3143. NoOpPayloadCmd* aPayloadCmdP = reinterpret_cast<NoOpPayloadCmd*>(aCmdP.get());
  3144. titanDebug("TitanInterface::threadProcess Payload delay = %d ms", GetTickCount() - aPayloadCmdP->GetPayload());
  3145. break;
  3146. }
  3147. #endif // CLOCK_COMMANDS_THRU_ENGINE
  3148. default:
  3149. titanDebug("TitanInterface::threadProcess Got unknown command type.");
  3150. break;
  3151. }
  3152. }
  3153. }
  3154. }
  3155. }
  3156. titanDebug("TitanInterface::threadProcess Shutting down.");
  3157. return 0;
  3158. }
  3159. //////////////////////////////////////////////////////////////////////////////////////////////////////
  3160. //////////////////////////////////////////////////////////////////////////////////////////////////////
  3161. void
  3162. TitanInterface::HandleWaitCmd(PipeCmd* theCmdP)
  3163. {
  3164. titanDebug("TitanInterface::HandleWaitCommand Got wait command");
  3165. WaitForEventCmd* aWaitCmdP = dynamic_cast<WaitForEventCmd*>(theCmdP);
  3166. if (aWaitCmdP)
  3167. CloseHandle(aWaitCmdP->mEvent);
  3168. }
  3169. //////////////////////////////////////////////////////////////////////////////////////////////////////
  3170. //////////////////////////////////////////////////////////////////////////////////////////////////////
  3171. void
  3172. TitanInterface::HandleAcceptCmd(SocketPipe* thePipeP, PipeCmd* theCmdP)
  3173. {
  3174. titanDebug("TitanInterface::HandleAcceptCmd Got accept command");
  3175. AcceptCmd* anAcceptCmdP = dynamic_cast<AcceptCmd*>(theCmdP);
  3176. // Add recv commands to new pipe
  3177. if (anAcceptCmdP)
  3178. {
  3179. for (int i=0; i < PREPOST_MAX; i++)
  3180. anAcceptCmdP->mAcceptedPipeP->AddIncomingCmd(new RecvPrefCmd(false, WONMisc::ptUnsignedShort, false));
  3181. }
  3182. // Add another accept command to pipe
  3183. thePipeP->AddIncomingCmd(new AcceptCmd(mEngine, true, false));
  3184. }
  3185. //////////////////////////////////////////////////////////////////////////////////////////////////////
  3186. //////////////////////////////////////////////////////////////////////////////////////////////////////
  3187. void
  3188. TitanInterface::HandleCloseCmd(SocketPipe* thePipeP)
  3189. {
  3190. titanDebug("TitanInterface::HandleCloseCmd Got closed pipe with error %s (%s:%d)", WONMisc::ES_ErrorTypeToString(thePipeP->mError).c_str(), thePipeP->mEasySocketP->getDestAddrString().c_str(), thePipeP->mEasySocketP->getDestPort());
  3191. // Flush the pipe of any incoming recv commands
  3192. while (thePipeP->HasCompletedIncomingCmds())
  3193. {
  3194. auto_ptr<PipeCmd> aCmdP(thePipeP->RemoveCompletedIncomingCmd());
  3195. if (aCmdP->GetType() == WONMisc::pctRecvPrefixed)
  3196. HandleRecvCmd(thePipeP, aCmdP.get(), true);
  3197. }
  3198. // Check unpected closes on pipes we're waiting on
  3199. AutoCrit aPipeCrit(mPipeCrit);
  3200. if (thePipeP == mAuthPipe)
  3201. {
  3202. titanDebug("TitanInterface::HandleCloseCmd AuthPipe closed unexpectedly!");
  3203. mAuthPipe = NULL;
  3204. aPipeCrit.Leave();
  3205. AuthFailOver();
  3206. }
  3207. else if (thePipeP == mDirPipe)
  3208. {
  3209. titanDebug("TitanInterface::HandleCloseCmd DirPipe closed unexpectedly!");
  3210. mDirPipe = NULL;
  3211. aPipeCrit.Leave();
  3212. DirFailOver();
  3213. }
  3214. else if (thePipeP == mEventPipe)
  3215. {
  3216. titanDebug("TitanInterface::HandleCloseCmd EventPipe closed unexpectedly!");
  3217. mEventPipe = NULL;
  3218. aPipeCrit.Leave();
  3219. }
  3220. else if (thePipeP == mFactPipe)
  3221. {
  3222. titanDebug("TitanInterface::HandleCloseCmd FactPipe closed unexpectedly!");
  3223. mFactPipe = NULL;
  3224. aPipeCrit.Leave();
  3225. FactFailOver();
  3226. }
  3227. else if (thePipeP == mRoutePipe[0])
  3228. {
  3229. titanDebug("TitanInterface::HandleCloseCmd RoutePipe closed unexpectedly!");
  3230. mRoutePipe[0] = NULL;
  3231. mNeedToRegisterRoutingServer = false;
  3232. mWaitingRequestQueue[0].clear();
  3233. aPipeCrit.Leave();
  3234. cNotifyChatConnectFailed();
  3235. }
  3236. else if (thePipeP == mRoutePipe[1])
  3237. {
  3238. titanDebug("TitanInterface::HandleCloseCmd Game RoutePipe closed unexpectedly!");
  3239. clCommandMessage("Lost connection...reconnecting");
  3240. mRoutePipe[1] = NULL;
  3241. mWaitingRequestQueue[1].clear();
  3242. aPipeCrit.Leave();
  3243. if(mRoutingReconnectNum[1]++ < 3)
  3244. ConnectToRoutingServer(L"SuckMe",L"MoFo",1,true);
  3245. else
  3246. {
  3247. mGameDisconnectWasVoluntary = false;
  3248. RecordEvent(ACTIVITYTYPE_HOMEWORLD_GAME_EXIT);
  3249. }
  3250. }
  3251. else if(thePipeP == mFirewallPipe)
  3252. {
  3253. titanDebug("TitanInterface::HandleCloseCmd FirewallPipe closed unexpectedly!");
  3254. mFirewallPipe = NULL;
  3255. aPipeCrit.Leave();
  3256. FirewallFailOver();
  3257. }
  3258. else if(thePipeP == mFactPingPipe)
  3259. {
  3260. titanDebug("TitanInterface::HandleCloseCmd FactPingPipe closed unexpectedly!");
  3261. aPipeCrit.Leave();
  3262. PingFactServer();
  3263. }
  3264. else if(thePipeP == mRoutingInfoPipe || thePipeP == mLanAdPipe)
  3265. {
  3266. if(thePipeP->mInErrorState && thePipeP->mError==WONMisc::ES_WSAEMSGSIZE)
  3267. {
  3268. thePipeP->mInErrorState = false;
  3269. thePipeP->mError = WONMisc::ES_NO_ERROR;
  3270. return;
  3271. }
  3272. else
  3273. {
  3274. titanDebug("TitanInterface::HandleCloseCmd RoutingInfoPipe closed! (Error: %d)", thePipeP->mError);
  3275. if (thePipeP == mRoutingInfoPipe)
  3276. mRoutingInfoPipe = NULL;
  3277. else
  3278. mLanAdPipe = NULL;
  3279. aPipeCrit.Leave();
  3280. }
  3281. }
  3282. else
  3283. {
  3284. aPipeCrit.Leave();
  3285. // Check for offline clients
  3286. AutoCrit aCrit(mClientCrit); // Enter client crit sec
  3287. ClientToPipe::iterator anItr = mClientMap.begin();
  3288. for (; anItr != mClientMap.end(); anItr++)
  3289. if (anItr->second.pipe == thePipeP)
  3290. break;
  3291. if (anItr != mClientMap.end())
  3292. {
  3293. titanDebug("TitanInterface::HandleCloseCmd Client pipe closed!");
  3294. if(IAmCaptain && mGameCreationState!=GAME_STARTED)
  3295. {
  3296. Address anAddr;
  3297. if(!mIsLan)
  3298. {
  3299. anAddr.AddrPart.IP = anItr->first.first;
  3300. anAddr.Port = anItr->first.second;
  3301. }
  3302. else
  3303. {
  3304. memcpy(anAddr.AddrPart.etherAddr,&(anItr->first.first),4);
  3305. memcpy(anAddr.AddrPart.etherAddr + 4, &(anItr->first.second),2);
  3306. memcpy(&anAddr.Port,((char*)(&(anItr->first.second)))+2,2);
  3307. }
  3308. titanLeaveGameReceivedCB(&anAddr, NULL, 0);
  3309. }
  3310. mClientMap.erase(anItr);
  3311. if(thePipeP == mCaptainPipe && mGameCreationState==GAME_STARTED)
  3312. {
  3313. if (mCaptainReconnectNum < 3)
  3314. {
  3315. clCommandMessage("Lost captain conn...reconnecting");
  3316. mCaptainPipe = NULL;
  3317. mCaptainReconnectNum++;
  3318. ConnectToClient(&mCaptainAddress);
  3319. SendPacketTo(&mCaptainAddress,TITANMSGTYPE_RECONNECT,NULL,0);
  3320. }
  3321. else
  3322. {
  3323. mGameDisconnectWasVoluntary = false;
  3324. RecordEvent(ACTIVITYTYPE_HOMEWORLD_GAME_EXIT);
  3325. }
  3326. }
  3327. if (mClientMap.empty() && mCloseRequest)
  3328. {
  3329. titanNoClientsCB();
  3330. mCloseRequest = false;
  3331. }
  3332. }
  3333. }
  3334. // Kill the Pipe
  3335. mEngine->KillPipe(thePipeP);
  3336. }
  3337. //////////////////////////////////////////////////////////////////////////////////////////////////////
  3338. //////////////////////////////////////////////////////////////////////////////////////////////////////
  3339. void
  3340. TitanInterface::HandleRecvCmd(SocketPipe* thePipeP, PipeCmd* theCmdP, bool pipeClosed)
  3341. {
  3342. // Cast to real command type
  3343. RecvPrefCmd* aRecvCmdP = dynamic_cast<RecvPrefCmd*>(theCmdP);
  3344. if (! aRecvCmdP)
  3345. {
  3346. titanDebug("TitanInterface::HandleRecvCmd Corrupt command discarded, bad conversion!");
  3347. return;
  3348. }
  3349. // Check for closed connection (empty buffer)
  3350. if (aRecvCmdP->mBytesReceived == 0)
  3351. {
  3352. titanDebug("TitanInterface::HandleRecvCmd Empty buffer, pipe closed!");
  3353. if (! pipeClosed)
  3354. HandleCloseCmd(thePipeP);
  3355. return;
  3356. }
  3357. // Post a new recv command
  3358. if (! pipeClosed)
  3359. thePipeP->AddIncomingCmd(new RecvPrefCmd(false, aRecvCmdP->mPrefixType, false));
  3360. // Dispatch message
  3361. switch (aRecvCmdP->mBufferP[0])
  3362. {
  3363. case WONMsg::HeaderService2Message2:
  3364. case WONMsg::SmallEncryptedService:
  3365. HandleSmallMsg(thePipeP, aRecvCmdP->mBufferP, aRecvCmdP->mBytesReceived); break;
  3366. case WONMsg::HeaderService1Message1:
  3367. case WONMsg::MiniEncryptedService:
  3368. HandleMiniMsg(thePipeP, aRecvCmdP->mBufferP, aRecvCmdP->mBytesReceived); break;
  3369. case WONMsg::HeaderService4Message4:
  3370. case WONMsg::LargeEncryptedService:
  3371. titanDebug("TitanInterface::HandleRecvCmd Command discarded. Message received with unused header type."); break;
  3372. // NOTE: The default case handles some messages that you might not expect. For example,
  3373. // the Routing pipes are set up to use 2-byte prefixed recv commands, but peer-to-
  3374. // peer authentication ALWAYS uses 4-byte lengths. Since the peer-to-peer messages
  3375. // are expected to be less than 2^16 bytes long and the lengths are little endian,
  3376. // we can receive them on a 2-byte prefixed pipe. Then when we look at the first
  3377. // byte (normally the header type byte), it will be 0 and fall into the default
  3378. // case:
  3379. default:
  3380. HandleTitanMsg(thePipeP, aRecvCmdP->mBufferP, aRecvCmdP->mBytesReceived); break;
  3381. }
  3382. }
  3383. //////////////////////////////////////////////////////////////////////////////////////////////////////
  3384. //////////////////////////////////////////////////////////////////////////////////////////////////////
  3385. void
  3386. TitanInterface::HandleLanBroadcastMsg(WONMisc::SocketPipe* thePipeP, const char* theBufP, unsigned long theLen)
  3387. {
  3388. // put a new recvfrom on the pipe
  3389. thePipeP->AddIncomingCmd(new RecvFromCmd(new char[MAX_LAN_ADVERT_LEN],MAX_LAN_ADVERT_LEN,true,false));
  3390. // do the callback
  3391. titanReceivedLanBroadcastCB(theBufP,theLen);
  3392. }
  3393. //////////////////////////////////////////////////////////////////////////////////////////////////////
  3394. //////////////////////////////////////////////////////////////////////////////////////////////////////
  3395. void
  3396. TitanInterface::HandleTitanMsg(SocketPipe* thePipeP, const char* theBufP, unsigned long theLen)
  3397. {
  3398. TMessage aMsg;
  3399. if (theLen < aMsg.GetHeaderLength())
  3400. {
  3401. titanDebug("TitanInterface::HandleTitanMsg Corrupt Titan Message discarded, bad length!");
  3402. return;
  3403. }
  3404. if(theBufP[0]==WONMsg::EncryptedService) { // Encrypted Message
  3405. if(!DecryptMessage(theBufP,theLen,aMsg,&thePipeP))
  3406. return; // Failed to decrypt
  3407. }
  3408. else {
  3409. // Fill in TMsg header
  3410. aMsg.ResetBuffer();
  3411. aMsg.AllocateHeaderBuffer();
  3412. aMsg.SetServiceType(*(reinterpret_cast<const unsigned long*>(theBufP)));
  3413. theBufP += sizeof(unsigned long);
  3414. aMsg.SetMessageType(*(reinterpret_cast<const unsigned long*>(theBufP)));
  3415. theBufP += sizeof(unsigned long);
  3416. aMsg.Pack();
  3417. // Add msg data if any
  3418. unsigned long aDataLen = theLen - aMsg.GetHeaderLength();
  3419. if (aDataLen > 0)
  3420. aMsg.AppendBytes(aDataLen, theBufP);
  3421. }
  3422. AutoCrit aCrit(mPipeCrit);
  3423. // Dispatch message
  3424. switch (aMsg.GetServiceType())
  3425. {
  3426. case WONMsg::CommonService:
  3427. if (aMsg.GetMessageType() != WONMsg::MiniCommPing && aMsg.GetMessageType() != WONMsg::MiniCommPingReply && thePipeP != mDirPipe && thePipeP !=mFactPingPipe)
  3428. {
  3429. titanDebug("Titaninterface::HandleTitanMsg unexpected CommonService message discarded.");
  3430. }
  3431. else
  3432. {
  3433. switch(aMsg.GetMessageType())
  3434. {
  3435. case WONMsg::CommStatusReply:
  3436. //Dir Server Session has expired
  3437. delete mDirSessionKey;
  3438. mDirSessionKey = NULL;
  3439. mDirPipe = NULL;
  3440. RequestDirectory();
  3441. break;
  3442. default:
  3443. titanDebug("TitanInterface::HandleTitanMsg Got Unknown titan message, bad CommonService message type %d!", aMsg.GetMessageType());
  3444. break;
  3445. }
  3446. }
  3447. break;
  3448. case WONMsg::Auth1Login:
  3449. if (thePipeP != mAuthPipe)
  3450. {
  3451. titanDebug("TitanInterface::HandleTitanMsg AuthServer msg on non-auth pipe discared!");
  3452. }
  3453. else
  3454. {
  3455. switch (aMsg.GetMessageType())
  3456. {
  3457. case WONMsg::Auth1GetPubKeysReply:
  3458. AuthHandleGetPubKeysReply(aMsg); break;
  3459. case WONMsg::Auth1LoginReply:
  3460. AuthHandleLoginReply(aMsg); break;
  3461. case WONMsg::Auth1LoginChallengeHW:
  3462. AuthHandleChallenge(aMsg); break;
  3463. default:
  3464. titanDebug("TitanInterface::HandleTitanMsg Got Unknown titan message, bad Auth message type %d!", aMsg.GetMessageType());
  3465. break;
  3466. }
  3467. }
  3468. break;
  3469. case WONMsg::Auth1PeerToPeer:
  3470. if(thePipeP!=mDirPipe && thePipeP!=mFactPipe && thePipeP!=mRoutePipe[0] && thePipeP!=mRoutePipe[1])
  3471. {
  3472. titanDebug("TitanInterface::HandleTitanMsg Auth1PeerToPeer msg on non dir/fact/route pipe discarded.");
  3473. }
  3474. else
  3475. {
  3476. switch(aMsg.GetMessageType())
  3477. {
  3478. case WONMsg::Auth1Challenge1:
  3479. PeerHandleChallenge(&thePipeP, aMsg); break;
  3480. case WONMsg::Auth1Complete:
  3481. PeerHandleComplete(&thePipeP, aMsg); break;
  3482. default:
  3483. titanDebug("TitanInterface::HandleTitanMsg got unkonw Auth1PeerToPeer message.");
  3484. break;
  3485. }
  3486. }
  3487. break;
  3488. default:
  3489. titanDebug("TitanInterface::HandleTitanMsg Got Unknown titan message, bad service type!");
  3490. }
  3491. }
  3492. //////////////////////////////////////////////////////////////////////////////////////////////////////
  3493. //////////////////////////////////////////////////////////////////////////////////////////////////////
  3494. void
  3495. TitanInterface::HandleSmallMsg(SocketPipe* thePipeP, const char* theBufP, unsigned long theLen)
  3496. {
  3497. SmallMessage aMsg;
  3498. if (theLen < aMsg.GetHeaderLength())
  3499. {
  3500. titanDebug("TitanInterface::HandleSmallMsg Corrupt MiniMessage discarded, bad length!");
  3501. return;
  3502. }
  3503. if(theBufP[0]==WONMsg::SmallEncryptedService) {
  3504. if(!DecryptMessage(theBufP,theLen,aMsg,&thePipeP))
  3505. return; // Failed to decrypt
  3506. }
  3507. else {
  3508. // Fill in SMsg header
  3509. aMsg.ResetBuffer();
  3510. aMsg.AllocateHeaderBuffer();
  3511. theBufP += sizeof(unsigned char); // skip header type
  3512. aMsg.SetServiceType(*(reinterpret_cast<const unsigned short*>(theBufP)));
  3513. theBufP += sizeof(unsigned short);
  3514. aMsg.SetMessageType(*(reinterpret_cast<const unsigned short*>(theBufP)));
  3515. theBufP += sizeof(unsigned short);
  3516. aMsg.Pack();
  3517. unsigned long aDataLen = theLen - aMsg.GetHeaderLength();
  3518. if (aDataLen > 0)
  3519. aMsg.AppendBytes(aDataLen, theBufP);
  3520. }
  3521. switch (aMsg.GetServiceType())
  3522. {
  3523. case WONMsg::SmallCommonService:
  3524. switch (aMsg.GetMessageType())
  3525. {
  3526. case WONMsg::SmallCommStatusReply:
  3527. HandleRoutingRegisterReply(thePipeP, aMsg); break;
  3528. default:
  3529. titanDebug("TitanInterface::HandleSmallMsg Got Unknown small message, bad Common message type %d!", aMsg.GetMessageType());
  3530. break;
  3531. }
  3532. break;
  3533. case WONMsg::SmallDirServerG2:
  3534. if (thePipeP != mDirPipe)
  3535. {
  3536. titanDebug("TitanInterface::HandleSmallMsg DirServer msg on non-dir pipe discarded!");
  3537. }
  3538. else
  3539. {
  3540. switch (aMsg.GetMessageType())
  3541. {
  3542. case WONMsg::DirG2MultiEntityReply:
  3543. HandleDirMultiEntityReply(aMsg); break;
  3544. default:
  3545. titanDebug("TitanInterface::HandleSmallMsg Got Unknown small message, bad DirServer message type %d!", aMsg.GetMessageType());
  3546. break;
  3547. }
  3548. }
  3549. break;
  3550. case WONMsg::SmallFactoryServer:
  3551. if (thePipeP != mFactPipe)
  3552. {
  3553. titanDebug("TitanInterface::HandleSmallMsg FactoryServer msg on non-fact pipe discarded!");
  3554. }
  3555. else
  3556. {
  3557. switch (aMsg.GetMessageType())
  3558. {
  3559. case WONMsg::SmallFactStatusReply:
  3560. HandleStartRoutingReply(thePipeP, aMsg); break;
  3561. default:
  3562. titanDebug("TitanInterface::HandleSmallMsg Got Unknown small message, bad FactoryServer message type %d!", aMsg.GetMessageType());
  3563. break;
  3564. }
  3565. }
  3566. break;
  3567. case WONMsg::SmallFirewallDetector:
  3568. switch (aMsg.GetMessageType())
  3569. {
  3570. case WONMsg::FirewallStatusReply:
  3571. HandleFirewallResponse(thePipeP, aMsg); break;
  3572. default:
  3573. titanDebug("TitanInterface::HandleSmallMsg Got Unknown small message, bad Firewall message type %d!", aMsg.GetMessageType());
  3574. break;
  3575. }
  3576. break;
  3577. default:
  3578. titanDebug("TitanInterface::HandleSmallMsg Got Unknown small message! Service type %d, Message type %d", aMsg.GetServiceType(), aMsg.GetMessageType());
  3579. }
  3580. }
  3581. //////////////////////////////////////////////////////////////////////////////////////////////////////
  3582. //////////////////////////////////////////////////////////////////////////////////////////////////////
  3583. void
  3584. TitanInterface::HandleMiniMsg(SocketPipe* thePipeP, const char* theBufP, unsigned long theLen)
  3585. {
  3586. MiniMessage aMsg;
  3587. int aRouteNum;
  3588. if (theLen < aMsg.GetHeaderLength())
  3589. {
  3590. titanDebug("TitanInterface::HandleMiniMsg Corrupt MiniMessage discarded, bad length!");
  3591. return;
  3592. }
  3593. if(theBufP[0]==WONMsg::MiniEncryptedService) {
  3594. if(!DecryptMessage(theBufP,theLen,aMsg,&thePipeP))
  3595. return; // Failed to decrypt
  3596. }
  3597. else {
  3598. // Fill in MMsg header
  3599. const char* p = theBufP;
  3600. aMsg.ResetBuffer();
  3601. aMsg.AllocateHeaderBuffer();
  3602. p += sizeof(unsigned char); // skip header type
  3603. aMsg.SetServiceType(*(reinterpret_cast<const unsigned char*>(p)));
  3604. p += sizeof(unsigned char);
  3605. aMsg.SetMessageType(*(reinterpret_cast<const unsigned char*>(p)));
  3606. p += sizeof(unsigned char);
  3607. aMsg.Pack();
  3608. // Discard non-encrypted game msgs other than pings
  3609. if ((aMsg.GetServiceType() == TitanPacketMsg::MyServiceType) &&
  3610. (aMsg.GetMessageType() != TITANMSGTYPE_PING) &&
  3611. (aMsg.GetMessageType() != TITANMSGTYPE_PINGREPLY))
  3612. {
  3613. titanDebug("TitanInterface::HandleMiniMsg Unencrypted game msg dropped!");
  3614. // Could add a callback here if game wants to know
  3615. return;
  3616. }
  3617. unsigned long aDataLen = theLen - aMsg.GetHeaderLength();
  3618. if (aDataLen > 0)
  3619. aMsg.AppendBytes(aDataLen, p);
  3620. }
  3621. switch (aMsg.GetServiceType())
  3622. {
  3623. case WONMsg::MiniRoutingServer:
  3624. if(thePipeP==mRoutePipe[0]) aRouteNum = 0;
  3625. else if(thePipeP==mRoutePipe[1]) aRouteNum = 1;
  3626. else
  3627. {
  3628. titanDebug("TitanInterface::HandleMiniMsg RoutingServer msg on non-route pipe discarded!");
  3629. return;
  3630. }
  3631. switch (aMsg.GetMessageType())
  3632. {
  3633. case WONMsg::RoutingCreateDataObject:
  3634. HandleRoutingCreateDataObject(thePipeP, aMsg); break;
  3635. case WONMsg::RoutingDeleteDataObject:
  3636. HandleRoutingDeleteDataObject(thePipeP, aMsg); break;
  3637. case WONMsg::RoutingGetClientListReply:
  3638. HandleRoutingGetClientListReply(thePipeP, aMsg, aRouteNum); break;
  3639. case WONMsg::RoutingClientChange:
  3640. case WONMsg::RoutingClientChangeEx:
  3641. break; // we expect these messages, but don't process them at all
  3642. case WONMsg::RoutingGroupChange:
  3643. HandleRoutingGroupChange(thePipeP, aMsg, aRouteNum); break;
  3644. case WONMsg::RoutingGroupChangeEx:
  3645. HandleRoutingGroupChangeEx(thePipeP, aMsg, aRouteNum); break;
  3646. case WONMsg::RoutingPeerChat:
  3647. HandleRoutingPeerChat(thePipeP, aMsg, aRouteNum); break;
  3648. case WONMsg::RoutingPeerData:
  3649. HandleRoutingPeerData(thePipeP, aMsg, aRouteNum); break;
  3650. case WONMsg::RoutingPeerDataMultiple:
  3651. HandleRoutingPeerDataMultiple(thePipeP, aMsg, aRouteNum); break;
  3652. case WONMsg::RoutingReadDataObjectReply:
  3653. HandleRoutingReadDataObjectReply(thePipeP, aMsg); break;
  3654. case WONMsg::RoutingReplaceDataObject:
  3655. HandleRoutingReplaceDataObject(thePipeP, aMsg); break;
  3656. case WONMsg::RoutingRegisterClientReply:
  3657. HandleRoutingRegisterClientReply(thePipeP, aMsg, aRouteNum); break;
  3658. case WONMsg::RoutingStatusReply:
  3659. HandleRoutingStatusReply(thePipeP, aMsg, aRouteNum); break;
  3660. default:
  3661. titanDebug("TitanInterface::HandleMiniMsg Got Unknown mini message, bad RoutingServer message type %d!", aMsg.GetMessageType());
  3662. break;
  3663. }
  3664. break;
  3665. case TitanPacketMsg::MyServiceType:
  3666. case TitanPacketMsg::MyEncryptServiceType:
  3667. HandlePeerMsg(thePipeP, aMsg);
  3668. break;
  3669. case WONMsg::MiniCommonService:
  3670. switch(aMsg.GetMessageType())
  3671. {
  3672. case WONMsg::MiniCommPing:
  3673. HandlePing(thePipeP, aMsg); break;
  3674. case WONMsg::MiniCommPingReply:
  3675. if(thePipeP==mFactPingPipe)
  3676. PingHandleReply(aMsg);
  3677. else
  3678. HandlePingReply(thePipeP, aMsg);
  3679. break;
  3680. // case WONMsg::MiniCommGetNumUsersReply:
  3681. // HandleGetNumUsersReply(thePipeP, aMsg); break;
  3682. default:
  3683. titanDebug("TitanInterface::HandleMiniMsg Got Unknown mini message, bad Common message type %d!", aMsg.GetMessageType());
  3684. break;
  3685. }
  3686. break;
  3687. default:
  3688. titanDebug("TitanInterface::HandleMiniMsg Got Unknown mini message! (service %d, message %d)", aMsg.GetServiceType(), aMsg.GetMessageType());
  3689. }
  3690. }
  3691. //////////////////////////////////////////////////////////////////////////////////////////////////////
  3692. //////////////////////////////////////////////////////////////////////////////////////////////////////
  3693. void TitanInterface::HandlePeerMsg(WONMisc::SocketPipe* thePipeP, const WONMsg::MiniMessage& theMsgR)
  3694. {
  3695. // All packets other than game data packets are prefaced with the game name
  3696. // so unwanted messages can be ignored. Game data packets are the exception
  3697. // because we don't want to waste bandwidth during the game...
  3698. TitanPacketMsg aTitanPacketMsg(theMsgR);
  3699. if (theMsgR.GetMessageType() == TITANMSGTYPE_GAME)
  3700. HandleGameMsg(aTitanPacketMsg);
  3701. else
  3702. {
  3703. LockMutex(GameWereInterestedInMutex);
  3704. bool ignore = (aTitanPacketMsg.GetGameName() != GameWereInterestedIn);
  3705. UnLockMutex(GameWereInterestedInMutex);
  3706. if (!ignore)
  3707. {
  3708. titanDebug("TitanInterface::HandlePeerMsg Got message type %d",theMsgR.GetMessageType());
  3709. switch (theMsgR.GetMessageType())
  3710. {
  3711. case TITANMSGTYPE_JOINGAMEREQUEST:
  3712. HandleJoinGame(thePipeP, aTitanPacketMsg); break;
  3713. case TITANMSGTYPE_JOINGAMECONFIRM:
  3714. HandleJoinConfirm(thePipeP, aTitanPacketMsg); break;
  3715. case TITANMSGTYPE_JOINGAMEREJECT:
  3716. HandleJoinReject(thePipeP, aTitanPacketMsg); break;
  3717. case TITANMSGTYPE_LEAVEGAMEREQUEST:
  3718. HandleLeaveGame(thePipeP, aTitanPacketMsg); break;
  3719. case TITANMSGTYPE_UPDATEGAMEDATA:
  3720. HandleGameData(aTitanPacketMsg); break;
  3721. case TITANMSGTYPE_GAMEISSTARTING:
  3722. HandleGameStart(aTitanPacketMsg); break;
  3723. case TITANMSGTYPE_GAMEDISOLVED:
  3724. HandleGameDisolved(aTitanPacketMsg); break;
  3725. case TITANMSGTYPE_UPDATEPLAYER:
  3726. HandleUpdatePlayer(thePipeP, aTitanPacketMsg); break;
  3727. case TITANMSGTYPE_BEGINSTARTGAME:
  3728. HandleBeginStartGame(thePipeP, aTitanPacketMsg); break;
  3729. case TITANMSGTYPE_CHANGEADDRESS:
  3730. HandleChangeAddress(thePipeP, aTitanPacketMsg); break;
  3731. case TITANMSGTYPE_REQUESTPACKETS:
  3732. HandleRequestPackets(thePipeP, aTitanPacketMsg); break;
  3733. case TITANMSGTYPE_RECONNECT:
  3734. HandleClientReconnect(thePipeP, aTitanPacketMsg); break;
  3735. case TITANMSGTYPE_KICKPLAYER:
  3736. HandleKickedOutOfGame(aTitanPacketMsg); break;
  3737. default:
  3738. titanDebug("TitanInterface::HandlePeerMsg Got Unknown titan message, bad Homeworld message type!");
  3739. break;
  3740. }
  3741. }
  3742. }
  3743. }
  3744. //////////////////////////////////////////////////////////////////////////////////////////////////////
  3745. //////////////////////////////////////////////////////////////////////////////////////////////////////
  3746. void
  3747. TitanInterface::HandleStartRoutingReply(SocketPipe* thePipeP, const SmallMessage& theMsgR)
  3748. {
  3749. titanDebug("TitanInterface::HandleStartRoutingReply Got FactoryStatusReply message");
  3750. // Toss dir pipe
  3751. mPipeCrit.Enter();
  3752. mFactPipe = NULL;
  3753. mPipeCrit.Leave();
  3754. try
  3755. {
  3756. WONMsg::SMsgFactStatusReply aReply(theMsgR);
  3757. titanDebug("TitanInterface::HandleStartRoutingReply StartProcess returned status %d", aReply.GetProcessStatus());
  3758. if(aReply.GetProcessStatus()<0) {
  3759. FactFailOver();
  3760. return;
  3761. }
  3762. int aRouteNum = 0;
  3763. if(mGameCreationState==GAME_STARTING) aRouteNum = 1;
  3764. thePipeP->mEasySocketP->getDestAddr(reinterpret_cast<SOCKADDR*>(&(mRoutingAddress[aRouteNum])));
  3765. WONMsg::FACT_SERV_PORT_RANGE_SET::iterator anItr = aReply.GetProcessPortIDSet().begin();
  3766. mRoutingAddress[aRouteNum].sin_port = htons((anItr != aReply.GetProcessPortIDSet().end() ? *anItr : 0));
  3767. if(mGameCreationState==GAME_NOT_STARTED)
  3768. {
  3769. mNeedToRegisterRoutingServer = true;
  3770. ConnectToRoutingServer(StringToWString(utyName),mRoomPassword.c_str(),0);
  3771. }
  3772. else {
  3773. mgDisplayMessage(strGetString(strConnectingToRoutingServer));
  3774. ConnectToRoutingServer(StringToWString(utyName),L"",1);
  3775. }
  3776. ResetFactFailOver();
  3777. }
  3778. catch (WONException& anEx)
  3779. {
  3780. titanDebug("EXCEPTION: TitanInterface::FactoryStatusReply: %s", (char*)anEx.what());
  3781. FactFailOver();
  3782. }
  3783. }
  3784. //////////////////////////////////////////////////////////////////////////////////////////////////////
  3785. //////////////////////////////////////////////////////////////////////////////////////////////////////
  3786. void TitanInterface::HandleRoutingRegisterReply(SocketPipe* thePipeP, const WONMsg::SmallMessage& theMsgR)
  3787. {
  3788. titanDebug("TitanInterface::HandleRoutingRegisterReply");
  3789. short aStatus;
  3790. try
  3791. {
  3792. WONMsg::SMsgCommStatusReply aReply(theMsgR);
  3793. aStatus = aReply.GetStatus();
  3794. if (aStatus < 0)
  3795. titanDebug("TitanInterface::HandleRoutingRegisterReply Status = %d", aReply.GetStatus());
  3796. }
  3797. catch(WONException&)
  3798. {
  3799. titanDebug("TitanInterface::HandleRoutingRegisterReply EXCEPTION: Invalid SMsgCommStatusReply received.");
  3800. return;
  3801. }
  3802. // tell Homeworld whether chat startup succeeded
  3803. titanStartChatReplyReceivedCB(aStatus);
  3804. // shutdown server if necessary
  3805. if (aStatus != WONMsg::StatusCommon_Success)
  3806. titanDebug("TitanInterface::HandleRoutingRegisterReply Failed to register chat server with error %d. Server will shutdown on its own.", aStatus);
  3807. }
  3808. //////////////////////////////////////////////////////////////////////////////////////////////////////
  3809. //////////////////////////////////////////////////////////////////////////////////////////////////////
  3810. /*
  3811. void
  3812. TitanInterface::HandleGetNumUsersReply(WONMisc::SocketPipe *thePipeP, const WONMsg::MiniMessage& theMsgR)
  3813. {
  3814. if(thePipeP!=mRoutingInfoPipe)
  3815. return;
  3816. tpLockChannelList();
  3817. try
  3818. {
  3819. WONMsg::MMsgCommGetNumUsersReply aMsg(theMsgR);
  3820. unsigned short anOffset = aMsg.GetTag() - mRoutingQueryOffset;
  3821. if(anOffset<mRoutingQueryMap.size()) {
  3822. titanGotNumUsersInRoomCB(mRoutingQueryMap[anOffset].c_str(),aMsg.GetNumActiveUsers());
  3823. }
  3824. }
  3825. catch(WONException&)
  3826. {
  3827. titanDebug("Invalid get num users reply received.");
  3828. }
  3829. tpUnLockChannelList();
  3830. }
  3831. */
  3832. //////////////////////////////////////////////////////////////////////////////////////////////////////
  3833. //////////////////////////////////////////////////////////////////////////////////////////////////////
  3834. /*
  3835. void
  3836. TitanInterface::QueryRoutingServers(void)
  3837. {
  3838. AutoCrit aPipeCrit(mPipeCrit);
  3839. if(mRoutingInfoPipe==NULL) {
  3840. mRoutingInfoPipe=new SocketPipe;
  3841. mRoutingInfoPipe->AddOutgoingCmd(new OpenCmd(EasySocket::UDP));
  3842. for (int i=0; i < PREPOST_MAX; i++)
  3843. mRoutingInfoPipe->AddIncomingCmd(new RecvFromCmd(new char[32],32,true,false));
  3844. mEngine->AddPipe(mRoutingInfoPipe);
  3845. }
  3846. aPipeCrit.Leave();
  3847. int n;
  3848. tpLockChannelList();
  3849. int numChannels = tpChannelList.numChannels;
  3850. mRoutingQueryMap.resize(numChannels);
  3851. for(n=0; n<numChannels; n++)
  3852. mRoutingQueryMap[n] = tpChannelList.tpChannels[n].ChannelName;
  3853. tpUnLockChannelList();
  3854. mRoutingQueryOffset+=1000;
  3855. if(mRoutingQueryOffset>60000) mRoutingQueryOffset = 0;
  3856. WONMsg::MMsgCommGetNumUsers aMsg;
  3857. aPipeCrit.Enter(); // QueryRoutingServers is called from Homeworld's thread, so it's possible (improbable) that the pipe is in an error state now.
  3858. if (mRoutingInfoPipe == NULL)
  3859. return;
  3860. try {
  3861. for(n=0; n<numChannels; n++) {
  3862. aMsg.SetTag(mRoutingQueryOffset+n);
  3863. aMsg.Pack();
  3864. char *aBuf = new char[aMsg.GetDataLen()];
  3865. memcpy(aBuf,aMsg.GetDataPtr(),aMsg.GetDataLen());
  3866. if(n<mRoutingAddrMap.size())
  3867. mRoutingInfoPipe->AddOutgoingCmd(new SendToCmd(*(SOCKADDR*)&(mRoutingAddrMap[n]), aBuf, aMsg.GetDataLen(), true, true));
  3868. }
  3869. }
  3870. catch(WONException&) {
  3871. titanDebug("Threw fucking exception while packing nothing message in TitanInterface::PingChatServers!");
  3872. }
  3873. }
  3874. */
  3875. //////////////////////////////////////////////////////////////////////////////////////////////////////
  3876. //////////////////////////////////////////////////////////////////////////////////////////////////////
  3877. void TitanInterface::HandleChannelList(WONMsg::DirEntityList& dirEntities)
  3878. {
  3879. tpLockChannelList();
  3880. bool readFactServers = (FACTSERVER_NUM==0);
  3881. int foundCurrentChannel = false;
  3882. bool isHWDS = false;
  3883. // mRoutingAddrMap.clear();
  3884. WONMsg::DirEntityList::iterator aEntityItr = dirEntities.begin();
  3885. for (int i=0; aEntityItr != dirEntities.end(); ++aEntityItr)
  3886. {
  3887. if (aEntityItr->mType == WONMsg::DirEntity::ET_SERVICE)
  3888. {
  3889. if (!isHWDS)
  3890. {
  3891. if (readFactServers && aEntityItr->mName == FACTORY_SERV)
  3892. {
  3893. if (FACTSERVER_NUM < MAX_IPS)
  3894. BuildAddress(FACTSERVER_ADDRESSES[FACTSERVER_NUM++], aEntityItr->mNetAddress);
  3895. else
  3896. titanDebug("Too many factory servers.");
  3897. }
  3898. else if (i < TP_ChannelListLength && aEntityItr->mName == CHATROOM_SERV)
  3899. {
  3900. // save room name
  3901. wcsncpy(tpChannelList.tpChannels[i].ChannelName, aEntityItr->mDisplayName.c_str(), MAX_CHANNEL_NAME_LEN-1);
  3902. tpChannelList.tpChannels[i].ChannelName[MAX_CHANNEL_NAME_LEN-1] = L'\0';
  3903. // unpack data objects (room flags & description)
  3904. tpChannelList.tpChannels[i].roomflags = 0;
  3905. tpChannelList.tpChannels[i].roomfullness = 0;
  3906. WONCommon::DataObjectTypeSet::iterator aObjItr = aEntityItr->mDataObjects.begin();
  3907. for (; aObjItr != aEntityItr->mDataObjects.end(); ++aObjItr)
  3908. {
  3909. if (aObjItr->GetDataType() == ROOM_FLAGS_OBJ && aObjItr->GetData().size() == sizeof(unsigned int))
  3910. tpChannelList.tpChannels[i].roomflags = *(unsigned int*)aObjItr->GetData().c_str();
  3911. else if (aObjItr->GetDataType() == DESCRIPTION_OBJ)
  3912. {
  3913. wcsncpy(tpChannelList.tpChannels[i].ChannelDescription, reinterpret_cast<const wchar_t*>(aObjItr->GetData().data()), MAX_CHANNEL_DESCRIPTION_LEN-1);
  3914. unsigned int aStringEnd = aObjItr->GetData().size() / 2;
  3915. if (aStringEnd > MAX_CHANNEL_DESCRIPTION_LEN-1)
  3916. aStringEnd = MAX_CHANNEL_DESCRIPTION_LEN-1;
  3917. tpChannelList.tpChannels[i].ChannelDescription[aStringEnd] = L'\0';
  3918. }
  3919. else if (aObjItr->GetDataType() == ROOM_CLIENTCOUNT_OBJ)
  3920. tpChannelList.tpChannels[i].roomfullness = *(unsigned long*)aObjItr->GetData().data();
  3921. }
  3922. memcpy(tpChannelList.tpChannels[i].addressstore,aEntityItr->mNetAddress.data(),6);
  3923. i++;
  3924. }
  3925. }
  3926. else if (aEntityItr->mName == FACTORY_SERV)
  3927. {
  3928. // save server name
  3929. wcsncpy(tpServerList.tpServers[i].ServerName, aEntityItr->mDisplayName.c_str(), MAX_SERVER_NAME_LEN-1);
  3930. tpServerList.tpServers[i].ServerName[MAX_SERVER_NAME_LEN-1] = L'\0';
  3931. // unpack data objects (flags & description)
  3932. tpServerList.tpServers[i].flags = 0;
  3933. tpServerList.tpServers[i].reliability = 0;
  3934. tpServerList.tpServers[i].ping = 0;
  3935. WONCommon::DataObjectTypeSet::iterator aObjItr = aEntityItr->mDataObjects.begin();
  3936. for (; aObjItr != aEntityItr->mDataObjects.end(); ++aObjItr)
  3937. {
  3938. if (aObjItr->GetDataType() == DESCRIPTION_OBJ)
  3939. {
  3940. wcsncpy(tpServerList.tpServers[i].ServerDescription, reinterpret_cast<const wchar_t*>(aObjItr->GetData().data()), MAX_SERVER_DESCRIPTION_LEN-1);
  3941. unsigned int aStringEnd = aObjItr->GetData().size() / 2;
  3942. if (aStringEnd > MAX_SERVER_DESCRIPTION_LEN-1)
  3943. aStringEnd = MAX_SERVER_DESCRIPTION_LEN-1;
  3944. tpServerList.tpServers[i].ServerDescription[aStringEnd] = L'\0';
  3945. }
  3946. else if (aObjItr->GetDataType() == SERVER_UPTIME_OBJ)
  3947. tpServerList.tpServers[i].reliability = *(unsigned long*)aObjItr->GetData().data();
  3948. else if (aObjItr->GetDataType() == FACT_CUR_SERVER_COUNT_OBJ)
  3949. tpServerList.tpServers[i].flags += *(unsigned long*)aObjItr->GetData().data();
  3950. //else if (aObjItr->GetDataType() == FACT_TOTAL_SERVER_COUNT_OBJ)
  3951. //tpServerList.tpServers[i].flags += *(unsigned long*)aObjItr->GetData().data();
  3952. }
  3953. memcpy(tpServerList.tpServers[i].addressstore,aEntityItr->mNetAddress.data(),6);
  3954. i++;
  3955. }
  3956. titanDebug(" Ser: %s - %s", WStringToString(aEntityItr->mName).c_str(), PrintAddress(aEntityItr->mNetAddress));
  3957. }
  3958. else if (aEntityItr->mType == WONMsg::DirEntity::ET_DIRECTORY)
  3959. {
  3960. if (aEntityItr->mName == HWDS_DIR)
  3961. {
  3962. // switch from expecting WON Factory Servers and Chat Rooms to expecting HWDS Factory Servers.
  3963. // (aka switch from ChannelList to ServerList)
  3964. tpChannelList.numChannels = i;
  3965. tpChannelList.newDataArrived = TRUE;
  3966. tpUnLockChannelList();
  3967. i = 0;
  3968. isHWDS = true;
  3969. tpLockServerList();
  3970. }
  3971. titanDebug(" Dir: %s", WStringToString(aEntityItr->mName).c_str());
  3972. }
  3973. }
  3974. if (isHWDS)
  3975. {
  3976. tpServerList.numServers = i;
  3977. tpServerList.newDataArrived = TRUE;
  3978. tpUnLockServerList();
  3979. }
  3980. else
  3981. {
  3982. tpChannelList.numChannels = i;
  3983. tpChannelList.newDataArrived = TRUE;
  3984. tpUnLockChannelList();
  3985. }
  3986. cNotifyRoomListPresent();
  3987. tpLockChannelList();
  3988. for (i=0;i<tpChannelList.numChannels;i++)
  3989. {
  3990. if (wcscmp(tpChannelList.tpChannels[i].ChannelName, GetCurrentChannel()) == 0)
  3991. {
  3992. foundCurrentChannel = true;
  3993. SOCKADDR_IN aSockAddr;
  3994. BuildAddress(aSockAddr, tpChannelList.tpChannels[i].addressstore);
  3995. mRoutingAddress[0] = aSockAddr;
  3996. break;
  3997. }
  3998. }
  3999. tpUnLockChannelList();
  4000. cNotifyCurrentRoomPresent(foundCurrentChannel);
  4001. if(mCurFactPing==-1)
  4002. PingFactServer();
  4003. }
  4004. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4005. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4006. void TitanInterface::HandleTitanServerList(WONMsg::DirEntityList& dirEntities)
  4007. {
  4008. WONMsg::DirEntityList::iterator aEntityItr = dirEntities.begin();
  4009. for ( ; aEntityItr != dirEntities.end(); ++aEntityItr)
  4010. {
  4011. if (aEntityItr->mType == WONMsg::DirEntity::ET_SERVICE)
  4012. {
  4013. if (aEntityItr->mName == AUTH_SERV)
  4014. {
  4015. if (AUTHSERVER_NUM < MAX_IPS)
  4016. BuildAddress(AUTHSERVER_ADDRESSES[AUTHSERVER_NUM++], aEntityItr->mNetAddress);
  4017. else
  4018. titanDebug("Too many auth servers.");
  4019. }
  4020. else if (aEntityItr->mName == EVENT_SERV)
  4021. {
  4022. if (EVENTSERVER_NUM < MAX_IPS)
  4023. BuildAddress(EVENTSERVER_ADDRESSES[EVENTSERVER_NUM++], aEntityItr->mNetAddress);
  4024. else
  4025. titanDebug("Too many event servers.");
  4026. }
  4027. else if (aEntityItr->mName == FIREWALL_SERV)
  4028. {
  4029. if (FIREWALLSERVER_NUM < MAX_IPS)
  4030. BuildAddress(FIREWALLSERVER_ADDRESSES[FIREWALLSERVER_NUM++], aEntityItr->mNetAddress);
  4031. else
  4032. titanDebug("Too many firewall servers.");
  4033. }
  4034. titanDebug(" Ser: %s - %s", WStringToString(aEntityItr->mName).c_str(), PrintAddress(aEntityItr->mNetAddress));
  4035. }
  4036. else
  4037. titanDebug(" Dir: %s", WStringToString(aEntityItr->mName).c_str());
  4038. }
  4039. }
  4040. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4041. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4042. void TitanInterface::HandleDirMultiEntityReply(const SmallMessage& theMsgR)
  4043. {
  4044. titanDebug("TitanInterface::HandleDirMultiEntityReply");
  4045. // Toss dir pipe
  4046. mPipeCrit.Enter();
  4047. mDirPipe = NULL;
  4048. mPipeCrit.Leave();
  4049. try
  4050. {
  4051. WONMsg::SMsgDirG2MultiEntityReply aReply(theMsgR);
  4052. WONMsg::DirEntityList& dirEntities = aReply.Entities();
  4053. if (aReply.GetStatus() >= 0)
  4054. {
  4055. titanDebug("TitanInterface::HandleDirMultiEntityReply DirG2MultiEntityReply message - Request OK.");
  4056. // If we haven't gotten the Auth Server list yet, this reply should be
  4057. // in response to our request for the ValidVersions object. Otherwise,
  4058. // it should be in response to a general query of the Homeworld directory.
  4059. if (AUTHSERVER_NUM == 0)
  4060. {
  4061. if (dirEntities.size() > 0)
  4062. {
  4063. titanDebug("TitanInterface::HandleDirMultiEntityReply Got auth server list and valid version info.");
  4064. // find directory entity and grab valid versions object from it
  4065. WONMsg::DirEntityList::iterator aEntityItr = dirEntities.begin();
  4066. for ( ; aEntityItr != dirEntities.end(); ++aEntityItr)
  4067. {
  4068. if (aEntityItr->mType == WONMsg::DirEntity::ET_DIRECTORY)
  4069. {
  4070. WONCommon::DataObjectTypeSet::iterator aObjItr = aEntityItr->mDataObjects.find(WONCommon::DataObject(VALIDVERSIONS_OBJ));
  4071. if (aObjItr != aEntityItr->mDataObjects.end())
  4072. {
  4073. titanGotValidVersionStrings(const_cast<char*>(reinterpret_cast<const char*>(aObjItr->GetData().c_str())));
  4074. break;
  4075. }
  4076. }
  4077. }
  4078. // handle the auth server services
  4079. HandleTitanServerList(dirEntities);
  4080. if(mNeedToAuthenticateAfterGettingAuthDirectory && AUTHSERVER_NUM>0) {
  4081. mNeedToAuthenticateAfterGettingAuthDirectory = false;
  4082. Authenticate(mLoginName,mPassword,mNewPassword,mCreateAccount);
  4083. }
  4084. }
  4085. }
  4086. else
  4087. {
  4088. titanDebug("TitanInterface::HandleDirMultiEntityReply Dumping Channel Reply: %d Entities",dirEntities.size());
  4089. HandleChannelList(dirEntities);
  4090. }
  4091. }
  4092. else
  4093. {
  4094. titanDebug("TitanInterface::HandleDirMultiEntityReply message - Request FAILED! Status = %d", aReply.GetStatus());
  4095. }
  4096. ResetDirFailOver();
  4097. }
  4098. catch (WONException& anEx)
  4099. {
  4100. titanDebug("EXCEPTION: TitanInterface::HandleDirMultiEntityReply: %s", (char*)anEx.what());
  4101. DirFailOver();
  4102. }
  4103. }
  4104. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4105. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4106. void
  4107. TitanInterface::HandleJoinGame(SocketPipe* thePipeP, const TitanPacketMsg& theMsgR)
  4108. {
  4109. titanDebug("TitanInterface::HandleJoinGame");
  4110. try
  4111. {
  4112. Address anAddress;
  4113. InitDestAddress(&anAddress, thePipeP);
  4114. long requestResult;
  4115. if(mGameCreationState==GAME_NOT_STARTED)
  4116. requestResult = titanRequestReceivedCB(&anAddress,theMsgR.GetBlob(), theMsgR.GetBlobLen());
  4117. else
  4118. requestResult = REQUEST_RECV_CB_JUSTDENY;
  4119. if (requestResult == REQUEST_RECV_CB_ACCEPT)
  4120. {
  4121. if(!mUseRoutingServer) {
  4122. ClientNetAddr anAddr = MakeClientNetAddr(&anAddress);
  4123. AutoCrit aCrit(mClientCrit);
  4124. mClientMap[anAddr].pipe = thePipeP;
  4125. aCrit.Leave();
  4126. }
  4127. titanDebug("TitanInterface::HandleJoinGame Sent join confirm");
  4128. titanSendPacketTo(&anAddress, TITANMSGTYPE_JOINGAMECONFIRM, NULL, 0);
  4129. titanBroadcastPacket(TITANMSGTYPE_UPDATEGAMEDATA, &tpGameCreated, sizeof(tpGameCreated));
  4130. }
  4131. else
  4132. {
  4133. // send reject message
  4134. titanDebug("TitanInterface::HandleJoinGame Sent join reject");
  4135. if(!mUseRoutingServer) {
  4136. ClientNetAddr anAddr = MakeClientNetAddr(&anAddress);
  4137. AutoCrit aCrit(mClientCrit);
  4138. mClientMap[anAddr].pipe = thePipeP;
  4139. aCrit.Leave();
  4140. }
  4141. titanSendPacketTo(&anAddress, TITANMSGTYPE_JOINGAMEREJECT, NULL, 0);
  4142. }
  4143. }
  4144. catch (WONException& anEx)
  4145. {
  4146. titanDebug("EXCEPTION: TitanInterface::HandleJoinGame: %s", (char*)anEx.what());
  4147. }
  4148. }
  4149. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4150. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4151. void
  4152. TitanInterface::HandleClientReconnect(SocketPipe* thePipeP, const MiniMessage& theMsgR)
  4153. {
  4154. titanDebug("TitanInterface::HandleClientReconnect");
  4155. try
  4156. {
  4157. Address anAddress;
  4158. InitDestAddress(&anAddress, thePipeP);
  4159. ClientNetAddr anAddr = MakeClientNetAddr(&anAddress);
  4160. AutoCrit aCrit(mClientCrit);
  4161. mClientMap[anAddr].pipe = thePipeP;
  4162. aCrit.Leave();
  4163. }
  4164. catch (WONException& anEx)
  4165. {
  4166. titanDebug("EXCEPTION: TitanInterface::HandleClientReconnect: %s", (char*)anEx.what());
  4167. }
  4168. }
  4169. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4170. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4171. void
  4172. TitanInterface::InitDestAddress(Address* theAddressP, SocketPipe* thePipeP)
  4173. {
  4174. if(mUseRoutingServer) {
  4175. theAddressP->AddrPart.IP = thePipeP->GetLabel();
  4176. theAddressP->Port = thePipeP->GetLabel();
  4177. return;
  4178. }
  4179. else
  4180. theAddressP->Port = GAME_PORT;
  4181. if ( mIpType == ip )
  4182. {
  4183. SOCKADDR_IN aClientAddr;
  4184. thePipeP->mEasySocketP->getDestAddr(reinterpret_cast<SOCKADDR*>(&aClientAddr));
  4185. theAddressP->AddrPart.IP = aClientAddr.sin_addr.s_addr;
  4186. }
  4187. else
  4188. {
  4189. SOCKADDR_IPX aClientAddr;
  4190. thePipeP->mEasySocketP->getDestAddr(reinterpret_cast<SOCKADDR*>(&aClientAddr));
  4191. memcpy( theAddressP->AddrPart.etherAddr, aClientAddr.sa_nodenum, 6 );
  4192. }
  4193. }
  4194. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4195. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4196. void
  4197. TitanInterface::HandleJoinConfirm(SocketPipe* thePipeP, const TitanPacketMsg& theMsgR)
  4198. {
  4199. titanDebug("TitanInterface::HandleJoinConfirm");
  4200. try
  4201. {
  4202. Address anAddress;
  4203. InitDestAddress(&anAddress, thePipeP);
  4204. if(!mUseRoutingServer) {
  4205. ClientNetAddr anAddr = MakeClientNetAddr(&anAddress);
  4206. AutoCrit aCrit(mClientCrit);
  4207. mClientMap[anAddr].pipe = thePipeP;
  4208. aCrit.Leave();
  4209. }
  4210. titanConfirmReceivedCB(&anAddress, theMsgR.GetBlob(), theMsgR.GetBlobLen());
  4211. }
  4212. catch (WONException& anEx)
  4213. {
  4214. titanDebug("EXCEPTION: TitanInterface::HandleJoinConfirm: %s", (char*)anEx.what());
  4215. }
  4216. }
  4217. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4218. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4219. void
  4220. TitanInterface::HandleJoinReject(SocketPipe* thePipeP, const TitanPacketMsg& theMsgR)
  4221. {
  4222. titanDebug("TitanInterface::HandleJoinReject");
  4223. try
  4224. {
  4225. Address anAddress;
  4226. InitDestAddress(&anAddress, thePipeP);
  4227. if(!mUseRoutingServer) {
  4228. ClientNetAddr anAddr = MakeClientNetAddr(&anAddress);
  4229. AutoCrit aCrit(mClientCrit);
  4230. mClientMap[anAddr].pipe = thePipeP;
  4231. aCrit.Leave();
  4232. }
  4233. titanRejectReceivedCB(&anAddress, theMsgR.GetBlob(), theMsgR.GetBlobLen());
  4234. }
  4235. catch (WONException& anEx)
  4236. {
  4237. titanDebug("EXCEPTION: TitanInterface::HandleJoinReject: %s", (char*)anEx.what());
  4238. }
  4239. }
  4240. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4241. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4242. void
  4243. TitanInterface::HandleLeaveGame(SocketPipe* thePipeP, const TitanPacketMsg& theMsgR)
  4244. {
  4245. titanDebug("TitanInterface::HandleLeaveGame");
  4246. try
  4247. {
  4248. Address anAddress;
  4249. InitDestAddress(&anAddress, thePipeP);
  4250. ClientNetAddr anAddr = MakeClientNetAddr(&anAddress);
  4251. AutoCrit aCrit(mClientCrit);
  4252. if (IPGame) // don't close old client connections if IPX Lan
  4253. {
  4254. ClientToPipe::iterator anItr = mClientMap.find(anAddr);
  4255. if(anItr!=mClientMap.end())
  4256. {
  4257. if(anItr->second.pipe!=NULL)
  4258. anItr->second.pipe->AddOutgoingCmd(new CloseCmd(false, false, 0, false));
  4259. mClientMap.erase(anItr);
  4260. }
  4261. }
  4262. aCrit.Leave();
  4263. titanLeaveGameReceivedCB(&anAddress, theMsgR.GetBlob(), theMsgR.GetBlobLen());
  4264. }
  4265. catch (WONException& anEx)
  4266. {
  4267. titanDebug("EXCEPTION: TitanInterface::HandleLeaveGame: %s", (char*)anEx.what());
  4268. }
  4269. }
  4270. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4271. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4272. void
  4273. TitanInterface::HandlePing(SocketPipe* thePipeP, const MiniMessage& theMsgR)
  4274. {
  4275. titanDebug("TitanInterface::HandlePing");
  4276. try
  4277. {
  4278. WONMsg::MMsgCommPing aMsg(theMsgR);
  4279. WONMsg::MMsgCommPingReply aReply;
  4280. aReply.SetStartTick(aMsg.GetStartTick());
  4281. aReply.Pack();
  4282. if (! SendMsg(thePipeP, aReply, 2))
  4283. {
  4284. titanDebug("FAIL: TitanInterface::HandlePing to send ping reply.");
  4285. }
  4286. }
  4287. catch (WONException& anEx)
  4288. {
  4289. titanDebug("EXCEPTION: TitanInterface::HandlePing: %s", (char*)anEx.what());
  4290. }
  4291. }
  4292. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4293. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4294. void
  4295. TitanInterface::HandlePingReply(SocketPipe* thePipeP, const MiniMessage& theMsgR)
  4296. {
  4297. titanDebug("TitanInterface::HandlePingReply");
  4298. try
  4299. {
  4300. WONMsg::MMsgCommPingReply aMsg(theMsgR);
  4301. SOCKADDR_IN aClientAddr;
  4302. thePipeP->mEasySocketP->getDestAddr(reinterpret_cast<SOCKADDR*>(&aClientAddr));
  4303. Address anAddress;
  4304. anAddress.AddrPart.IP = aClientAddr.sin_addr.s_addr;
  4305. anAddress.Port = ntohs(aClientAddr.sin_port);
  4306. unsigned long aLag = aMsg.GetLag() / 5;
  4307. titanPingReplyReceivedCB(&anAddress, aLag < 50 ? 50 : aLag);
  4308. }
  4309. catch (WONException& anEx)
  4310. {
  4311. titanDebug("EXCEPTION: TitanInterface::HandlePingReply: %s", (char*)anEx.what());
  4312. }
  4313. }
  4314. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4315. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4316. void
  4317. TitanInterface::HandleGameStart(const TitanPacketMsg& theMsgR)
  4318. {
  4319. titanDebug("TitanInterface::HandleGameStart");
  4320. try
  4321. {
  4322. //CloseRoutingServerConnection(0);
  4323. mgGameStartReceivedCB(theMsgR.GetBlob(), theMsgR.GetBlobLen());
  4324. // Record an event indicating that the player has joined the game
  4325. RecordEvent(ACTIVITYTYPE_HOMEWORLD_GAME_ENTER);
  4326. }
  4327. catch (WONException& anEx)
  4328. {
  4329. titanDebug("EXCEPTION: TitanInterface::HandleGameStart: %s", (char*)anEx.what());
  4330. }
  4331. }
  4332. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4333. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4334. void
  4335. TitanInterface::HandleGameData(const TitanPacketMsg& theMsgR)
  4336. {
  4337. titanDebug("TitanInterface::HandleGameData");
  4338. try
  4339. {
  4340. titanUpdateGameDataCB(theMsgR.GetBlob(), theMsgR.GetBlobLen());
  4341. }
  4342. catch (WONException& anEx)
  4343. {
  4344. titanDebug("EXCEPTION: TitanInterface::HandleGameData: %s", (char*)anEx.what());
  4345. }
  4346. }
  4347. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4348. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4349. void
  4350. TitanInterface::HandleGameMsg(const TitanPacketMsg& theMsgR)
  4351. {
  4352. try
  4353. {
  4354. titanGameMsgReceivedCB(theMsgR.GetBlob(), theMsgR.GetBlobLen());
  4355. }
  4356. catch (WONException& anEx)
  4357. {
  4358. titanDebug("EXCEPTION: TitanInterface::HandleGameMsg: %s", (char*)anEx.what());
  4359. }
  4360. }
  4361. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4362. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4363. void
  4364. TitanInterface::HandleGameDisolved(const TitanPacketMsg& theMsgR)
  4365. {
  4366. titanDebug("TitanInterface::HandleGameDisolved");
  4367. try
  4368. {
  4369. mgNotifyGameDisolved();
  4370. }
  4371. catch (WONException& anEx)
  4372. {
  4373. titanDebug("EXCEPTION: TitanInterface::HandleGameDisolved: %s", (char*)anEx.what());
  4374. }
  4375. }
  4376. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4377. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4378. void
  4379. TitanInterface::HandleKickedOutOfGame(const TitanPacketMsg& theMsgR)
  4380. {
  4381. titanDebug("TitanInterface::HandleKickedOutOfGame");
  4382. try
  4383. {
  4384. mgNotifyKickedOut();
  4385. }
  4386. catch (WONException& anEx)
  4387. {
  4388. titanDebug("EXCEPTION: TitanInterface::HandleKickedOutOfGame: %s", (char*)anEx.what());
  4389. }
  4390. }
  4391. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4392. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4393. void
  4394. TitanInterface::HandleUpdatePlayer(SocketPipe* thePipeP, const TitanPacketMsg& theMsgR)
  4395. {
  4396. titanDebug("TitanInterface::HandleUpdatePlayer");
  4397. try
  4398. {
  4399. Address anAddress;
  4400. InitDestAddress(&anAddress, thePipeP);
  4401. titanUpdatePlayerCB(&anAddress, theMsgR.GetBlob(), theMsgR.GetBlobLen());
  4402. }
  4403. catch (WONException& anEx)
  4404. {
  4405. titanDebug("EXCEPTION: TitanInterface::HandleUpdatePlayer: %s", (char*)anEx.what());
  4406. }
  4407. }
  4408. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4409. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4410. void
  4411. TitanInterface::HandleChangeAddress(SocketPipe* thePipeP, const TitanPacketMsg& theMsgR)
  4412. {
  4413. titanDebug("TitanInterface::HandleChangeAddress");
  4414. try
  4415. {
  4416. Address anAddress;
  4417. if(theMsgR.GetBlobLen()!=sizeof(ChangeAddressPacket))
  4418. return;
  4419. ChangeAddressPacket *aPacket = (ChangeAddressPacket*)theMsgR.GetBlob();
  4420. ChangeAddress(&(aPacket->oldAddress),&(aPacket->newAddress));
  4421. if(!mUseRoutingServer) {
  4422. ClientNetAddr anAddr = MakeClientNetAddr(&(aPacket->newAddress));
  4423. AutoCrit aCrit(mClientCrit);
  4424. mClientMap[anAddr].pipe = thePipeP;
  4425. aCrit.Leave();
  4426. }
  4427. if(mGameCreationState == GAME_STARTING && IAmCaptain) {
  4428. mgDisplayMessage(strGetString(strPlayerJoined));
  4429. mNumPlayersJoined++;
  4430. if(mNumPlayersJoined==tpGameCreated.numPlayers) {
  4431. mGameCreationState = GAME_STARTED;
  4432. InitPacketList();
  4433. titanBroadcastPacket(TITANMSGTYPE_UPDATEGAMEDATA, &tpGameCreated, sizeof(tpGameCreated));
  4434. mgStartGameCB();
  4435. //CloseRoutingServerConnection(0);
  4436. return;
  4437. }
  4438. }
  4439. }
  4440. catch (WONException& anEx)
  4441. {
  4442. titanDebug("EXCEPTION: TitanInterface::HandleUpdatePlayer: %s", (char*)anEx.what());
  4443. }
  4444. }
  4445. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4446. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4447. void
  4448. TitanInterface::HandleRequestPackets(SocketPipe* thePipeP, const TitanPacketMsg& theMsgR)
  4449. {
  4450. titanDebug("TitanInterface::HandleRequestPackets");
  4451. try
  4452. {
  4453. Address anAddress;
  4454. if(theMsgR.GetBlobLen()!=sizeof(RequestPacketsPacket))
  4455. return;
  4456. RequestPacketsPacket *aPacket = (RequestPacketsPacket*)theMsgR.GetBlob();
  4457. InitDestAddress(&anAddress, thePipeP);
  4458. AutoCrit aCrit(mPacketCrit);
  4459. if(mPacketList.size()==0)
  4460. return;
  4461. unsigned long aBeginPacket = mSeqNum - mPacketList.size();
  4462. if(mSeqNum<=aPacket->lastPacket || aBeginPacket>aPacket->firstPacket)
  4463. return;
  4464. std::list<basic_string<unsigned char> >::iterator anItr = mPacketList.begin();
  4465. std::list<unsigned char>::iterator aTypeItr = mPacketTypeList.begin();
  4466. while(aBeginPacket!=aPacket->firstPacket) {
  4467. anItr++;
  4468. aTypeItr++;
  4469. aBeginPacket++;
  4470. }
  4471. while(aBeginPacket<=aPacket->lastPacket) {
  4472. SendPacketTo(&anAddress,*aTypeItr,anItr->data(),anItr->size(),true,aBeginPacket);
  4473. anItr++;
  4474. aTypeItr++;
  4475. aBeginPacket++;
  4476. }
  4477. }
  4478. catch (WONException& anEx)
  4479. {
  4480. titanDebug("EXCEPTION: TitanInterface::HandleUpdatePlayer: %s", (char*)anEx.what());
  4481. }
  4482. }
  4483. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4484. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4485. void
  4486. TitanInterface::HandleBeginStartGame(SocketPipe* thePipeP, const TitanPacketMsg& theMsgR) {
  4487. titanDebug("TitanInterface::HandleBeginStartGame");
  4488. try
  4489. {
  4490. mgDisplayMsgBox();
  4491. mgDisplayMessage(strGetString(strStartingGame));
  4492. if(theMsgR.GetBlobLen()!=sizeof(BeginStartGamePacket))
  4493. return;
  4494. BeginStartGamePacket *aPacket = (BeginStartGamePacket*)theMsgR.GetBlob();
  4495. mGameCreationState = GAME_STARTING;
  4496. ChangeAddress(&(aPacket->oldCaptainAddress),&(aPacket->newCaptainAddress));
  4497. mCaptainAddress = aPacket->newCaptainAddress;
  4498. if(tpGameCreated.userBehindFirewall) {
  4499. mgDisplayMessage(strGetString(strDetectedUserBehindFirewall));
  4500. mgDisplayMessage(strGetString(strConnectingToRoutingServer));
  4501. mUseRoutingServer = true;
  4502. BuildAddress(mRoutingAddress[1], aPacket->routingAddress.AddrPart.IP, aPacket->routingAddress.Port);
  4503. ConnectToRoutingServer(StringToWString(utyName),L"",1);
  4504. return;
  4505. }
  4506. else {
  4507. mgDisplayMessage(strGetString(strConnectingToCaptain));
  4508. mUseRoutingServer = false;
  4509. ChangeAddressPacket aChangePacket;
  4510. aChangePacket.oldAddress = myAddress;
  4511. aChangePacket.newAddress = mMyIPAddress;
  4512. myAddress = mMyIPAddress;
  4513. mGameCreationState = GAME_STARTED;
  4514. InitPacketList();
  4515. titanConnectToClient(&(aPacket->newCaptainAddress));
  4516. titanSendPacketTo(&(aPacket->newCaptainAddress),TITANMSGTYPE_CHANGEADDRESS, &aChangePacket, sizeof(aChangePacket));
  4517. }
  4518. }
  4519. catch (WONException& anEx)
  4520. {
  4521. titanDebug("EXCEPTION: TitanInterface::HandleBeginStartGame: %s", (char*)anEx.what());
  4522. }
  4523. }
  4524. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4525. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4526. //--MikeN
  4527. // Adding StartShutdown method
  4528. void
  4529. TitanInterface::StartShutdown(unsigned char titanMsgType, const void* thePacket,
  4530. unsigned short theLen)
  4531. {
  4532. if(tpGameCreated.numPlayers>0) { // Send final message
  4533. if(IAmCaptain) BroadcastPacket(titanMsgType, thePacket, theLen);
  4534. else SendPacketTo(&tpGameCreated.playerInfo[0].address, titanMsgType, thePacket, theLen);
  4535. }
  4536. if(!mUseRoutingServer) {
  4537. if (IPGame) // don't close old client connections if IPX Lan
  4538. {
  4539. AutoCrit aCrit(mClientCrit); // Enter client crit sec
  4540. ClientToPipe::iterator anItr = mClientMap.begin();
  4541. for (; anItr != mClientMap.end(); anItr++)
  4542. {
  4543. SocketPipe* aPipeP = anItr->second.pipe;
  4544. aPipeP->AddOutgoingCmd(new CloseCmd(false, false, 0, false));
  4545. }
  4546. }
  4547. }
  4548. // Close connection to routing server if needed
  4549. CloseRoutingServerConnection(0);
  4550. CloseRoutingServerConnection(1);
  4551. // Mark as closing
  4552. mCloseRequest = true;
  4553. }
  4554. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4555. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4556. // Routing Server stuff
  4557. void TitanInterface::ConnectToRoutingServer(wstring theUserName, const wchar_t* thePassword, int theServer, bool reconnect)
  4558. {
  4559. titanDebug("TitanInterface::ConnectToRoutingServer");
  4560. AutoCrit aPipeCrit(mPipeCrit);
  4561. if (mRoutePipe[theServer])
  4562. {
  4563. titanDebug("NOTE: TitanInterface::ConnectToRoutingServer Close existing RoutePipe!");
  4564. mRoutePipe[theServer]->AddOutgoingCmd(new CloseNowCmd(false, false, 0, false));
  4565. mRoutePipe[theServer] = NULL;
  4566. }
  4567. aPipeCrit.Leave();
  4568. mLoggedInToRoutingServer[theServer] = false;
  4569. AutoCrit aCrit(mRoutingCrit);
  4570. // Prepare for the connection
  4571. mHaveReceivedInitialUserList = false;
  4572. mWaitingRequestQueue[theServer].clear();
  4573. mRoutingReconnect[theServer] = reconnect;
  4574. WONMsg::TMsgAuth1Request aMsg;
  4575. try
  4576. {
  4577. if (mNeedToRegisterRoutingServer) // Register server with Directory Server
  4578. {
  4579. static char aPortStr[17];
  4580. for (int iDirServer = 0; iDirServer < DIRSERVER_NUM; ++iDirServer)
  4581. {
  4582. string aDirServerAddress(DIRSERVER_IPSTRINGS[iDirServer]);
  4583. aDirServerAddress += ":";
  4584. aDirServerAddress += itoa(DIRSERVER_PORTS[iDirServer], aPortStr, 10);
  4585. mRegisterRoutingServerMsg.AddDirServerAddress(aDirServerAddress);
  4586. }
  4587. mRegisterRoutingServerMsg.SetPath(HOMEWORLD_DIR);
  4588. mRegisterRoutingServerMsg.SetRequireUniqueDisplayName(true);
  4589. mRegisterRoutingServerMsg.Pack();
  4590. }
  4591. else // Login to the Routing Server
  4592. {
  4593. mRouteRegisterMsg.SetClientName(WONCommon::RawBuffer((unsigned char*)theUserName.c_str(), theUserName.size() * 2));
  4594. if (theServer == 0)
  4595. mRouteRegisterMsg.SetSetupChat(true); // join chat group
  4596. if (thePassword && thePassword[0] != '\0')
  4597. mRouteRegisterMsg.SetPassword(thePassword);
  4598. else
  4599. mRouteRegisterMsg.SetPassword(wstring());
  4600. mRouteRegisterMsg.Pack();
  4601. }
  4602. aMsg.SetAuthMode(WONAuth::AUTH_PERSISTENT);
  4603. aMsg.SetEncryptMode(WONAuth::ENCRYPT_BLOWFISH);
  4604. aMsg.SetEncryptFlags(WONAuth::EFLAGS_NOTSEQUENCED);
  4605. aMsg.SetRawBuf(mCertificate->GetRaw(),mCertificate->GetRawLen());
  4606. aMsg.Pack();
  4607. }
  4608. catch (WONException& anEx)
  4609. {
  4610. titanDebug("EXCEPTION: TitanInterface::ConnectToRoutingServer: %s", (char*)anEx.what());
  4611. return;
  4612. }
  4613. titanDebug("TitanInterface::ConnectToRoutingServer Connecting to %s.", PrintAddress(mRoutingAddress[theServer]));
  4614. mRoutePipe[theServer] = ConnectAndSend(reinterpret_cast<SOCKADDR&>(mRoutingAddress[theServer]), aMsg, mStreamType, WONMisc::ptUnsignedShort);
  4615. }
  4616. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4617. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4618. void TitanInterface::RegisterRoutingServer()
  4619. {
  4620. titanDebug("TitanInterface::RegisterRoutingServer");
  4621. if(!mRoutePipe[0]) {
  4622. titanDebug("FAIL: No routing pipe with which to register. ;)");
  4623. return;
  4624. }
  4625. // If we just started a chat server, tell it to register with a directory server
  4626. mNeedToRegisterRoutingServer = false;
  4627. if(!EncryptAndSendRoutingMsg(mRegisterRoutingServerMsg, 0)) {
  4628. titanDebug("Couldn't send RegisterRequest msg even though this is improbable.");
  4629. return;
  4630. }
  4631. }
  4632. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4633. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4634. void TitanInterface::HandleRoutingRegister(int theServer)
  4635. {
  4636. titanDebug("TitanInterface::HandleRoutingRegister");
  4637. if(!mRoutePipe[theServer]) {
  4638. titanDebug("FAIL: No routing pipe with which to register. ;)");
  4639. return;
  4640. }
  4641. if(mRoutingReconnect[theServer]) {
  4642. WONMsg::MMsgRoutingReconnectClient aReconnectMsg;
  4643. aReconnectMsg.SetClientId(mMyClientId[theServer]);
  4644. aReconnectMsg.SetWantMissedMessages(true);
  4645. try {
  4646. aReconnectMsg.Pack();
  4647. }
  4648. catch(WONException&) {
  4649. titanDebug("Error packing reconnect msg.");
  4650. return;
  4651. }
  4652. mRoutingReconnect[theServer] = false;
  4653. AutoCrit aCrit(mRoutingCrit);
  4654. mWaitingRequestQueue[theServer].push_back(WONMsg::RoutingReconnectClient);
  4655. aCrit.Leave();
  4656. if(!EncryptAndSendRoutingMsg(aReconnectMsg, theServer)) {
  4657. titanDebug("Couldn't send reconnect msg even though this is improbable.");
  4658. return;
  4659. }
  4660. }
  4661. else
  4662. {
  4663. // Login to the Routing Server
  4664. if(!EncryptAndSendRoutingMsg(mRouteRegisterMsg, theServer)) {
  4665. titanDebug("Couldn't send RegisterClient msg even though this is improbable.");
  4666. return;
  4667. }
  4668. }
  4669. }
  4670. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4671. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4672. void TitanInterface::CloseRoutingServerConnection(int theServer)
  4673. {
  4674. titanDebug("TitanInterface::CloseRoutingServerConnection");
  4675. AutoCrit aCrit(mRoutingCrit);
  4676. if (! mRoutePipe[theServer])
  4677. {
  4678. titanDebug("TitanInterface::CloseRoutingServerConnection No connection.");
  4679. return;
  4680. }
  4681. WONMsg::MMsgRoutingDisconnectClient aDisconnectClientMsg;
  4682. try
  4683. {
  4684. aDisconnectClientMsg.SetIsPermanent(true);
  4685. aDisconnectClientMsg.Pack();
  4686. }
  4687. catch (WONException& anEx)
  4688. {
  4689. titanDebug("EXCEPTION: TitanInterface::CloseRoutingServerConnection: %s", (char*)anEx.what());
  4690. return;
  4691. }
  4692. // Send disconnect and close connection
  4693. aCrit.Leave();
  4694. mPipeCrit.Enter();
  4695. EncryptAndSendRoutingMsg(aDisconnectClientMsg, theServer);
  4696. mRoutePipe[theServer]->AddOutgoingCmd(new CloseCmd(false, false, 0, false));
  4697. mRoutePipe[theServer] = NULL;
  4698. mPipeCrit.Leave();
  4699. }
  4700. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4701. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4702. void TitanInterface::InitPacketList(void) {
  4703. mPacketList.clear();
  4704. mPacketTypeList.clear();
  4705. mSeqNum = 0;
  4706. }
  4707. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4708. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4709. void TitanInterface::AddPacketToList(const std::basic_string<unsigned char>&thePacket, unsigned char theType)
  4710. {
  4711. AutoCrit aCrit(mPacketCrit);
  4712. if(mPacketList.size()>5000) {
  4713. mPacketList.pop_front();
  4714. mPacketTypeList.pop_front();
  4715. }
  4716. mPacketList.push_back(thePacket);
  4717. mPacketTypeList.push_back(theType);
  4718. mSeqNum++;
  4719. }
  4720. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4721. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4722. void
  4723. TitanInterface::BroadcastPacket(unsigned char titanMsgType, const void* thePacket, unsigned short theLen) {
  4724. int i;
  4725. if(mGameCreationState==GAME_NOT_STARTED) {
  4726. for (i=0;i<tpGameCreated.numPlayers;i++)
  4727. {
  4728. if (!AddressesAreEqual(tpGameCreated.playerInfo[i].address,myAddress))
  4729. {
  4730. SendPacketTo(&(tpGameCreated.playerInfo[i].address), titanMsgType, thePacket, theLen);
  4731. }
  4732. }
  4733. }
  4734. else if(mGameCreationState==GAME_STARTING) {
  4735. for (i=0;i<mOldtpGameCreated.numPlayers;i++)
  4736. {
  4737. if (!AddressesAreEqual(mOldtpGameCreated.playerInfo[i].address,myAddress))
  4738. {
  4739. SendPacketTo(&(tpGameCreated.playerInfo[i].address), titanMsgType, thePacket, theLen);
  4740. }
  4741. }
  4742. }
  4743. else {
  4744. AutoCrit aCrit(mPacketCrit);
  4745. if(!mUseRoutingServer) {
  4746. for (i=0;i<tpGameCreated.numPlayers;i++)
  4747. {
  4748. if (!AddressesAreEqual(tpGameCreated.playerInfo[i].address,myAddress))
  4749. {
  4750. // SendPacketTo(&(tpGameCreated.playerInfo[i].address), titanMsgType,(const unsigned char*)thePacket,theLen,IAmCaptain,mSeqNum);
  4751. SendPacketTo(&(tpGameCreated.playerInfo[i].address), titanMsgType,(const unsigned char*)thePacket,theLen);
  4752. }
  4753. }
  4754. }
  4755. else
  4756. // SendPacketTo(NULL, titanMsgType,(const unsigned char*)thePacket,theLen,IAmCaptain,mSeqNum);
  4757. SendPacketTo(NULL, titanMsgType,(const unsigned char*)thePacket,theLen);
  4758. /*
  4759. if(IAmCaptain) {
  4760. WONCommon::RawBuffer aPacket((const unsigned char*)thePacket,theLen);
  4761. AddPacketToList(aPacket,titanMsgType);
  4762. }*/
  4763. }
  4764. }
  4765. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4766. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4767. void TitanInterface::RoutingSendChatBroadcast(unsigned short theSize, const unsigned char* theDataP, int theServer, bool addSeqNum, int theSeqNum)
  4768. {
  4769. titanDebug("TitanInterface::RoutingSendChatBroadcast");
  4770. AutoCrit aCrit(mRoutingCrit);
  4771. #if DEBUG_DISCONNECT
  4772. string aStr((const char*)theDataP,theSize);
  4773. if(aStr.find("briandis")!=string::npos) {
  4774. mRoutePipe[theServer]->AddOutgoingCmd(new CloseCmd(false, false, 0, false));
  4775. return;
  4776. }
  4777. #endif // DEBUG_DISCONNECT
  4778. if (! mRoutePipe[theServer])
  4779. {
  4780. titanDebug("TitanInterface::RoutingSendChatBroadcast No connection.");
  4781. return;
  4782. }
  4783. if (! mLoggedInToRoutingServer[theServer])
  4784. {
  4785. titanDebug("TitanInterface::RoutingSendChatBroadcast Not logged in yet.");
  4786. return;
  4787. }
  4788. WONMsg::MMsgRoutingSendChat aSendChatMsg;
  4789. try
  4790. {
  4791. if(addSeqNum) {
  4792. aSendChatMsg.AppendToData(WONCommon::RawBuffer((unsigned char*)&theSeqNum,4));
  4793. }
  4794. aSendChatMsg.AppendToData(WONCommon::RawBuffer(theDataP,theSize));
  4795. aSendChatMsg.SetChatType(WONMsg::CHATTYPE_UNICODE);
  4796. aSendChatMsg.SetShouldSendReply(false);
  4797. aSendChatMsg.SetIncludeExcludeFlag(false); // exclude no-one (aka broadcast)
  4798. aSendChatMsg.Pack();
  4799. }
  4800. catch (WONException& anEx)
  4801. {
  4802. titanDebug("EXCEPTION: TitanInterface::RoutingSendChatBroadcast: %s", (char*)anEx.what());
  4803. return;
  4804. }
  4805. if (!EncryptAndSendRoutingMsg(aSendChatMsg, theServer))
  4806. {
  4807. titanDebug("FAIL: TitanInterface::RoutingSendChatBroadcast fail send!");
  4808. return;
  4809. }
  4810. }
  4811. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4812. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4813. void TitanInterface::RoutingSendDataBroadcast(unsigned short theSize, const unsigned char* theDataP, int theServer, bool addSeqNum, int theSeqNum)
  4814. {
  4815. titanDebug("TitanInterface::RoutingSendDataBroadcast");
  4816. AutoCrit aCrit(mRoutingCrit);
  4817. #if DEBUG_DISCONNECT
  4818. string aStr((const char*)theDataP,theSize);
  4819. if(aStr.find("briandis")!=string::npos) {
  4820. mRoutePipe[theServer]->AddOutgoingCmd(new CloseCmd(false, false, 0, false));
  4821. return;
  4822. }
  4823. #endif // DEBUG_DISCONNECT
  4824. if (! mRoutePipe[theServer])
  4825. {
  4826. titanDebug("TitanInterface::RoutingSendDataBroadcast No connection.");
  4827. return;
  4828. }
  4829. if (! mLoggedInToRoutingServer[theServer])
  4830. {
  4831. titanDebug("TitanInterface::RoutingSendDataBroadcast Not logged in yet.");
  4832. return;
  4833. }
  4834. WONMsg::MMsgRoutingSendDataBroadcast aSendDataBroadcastMsg;
  4835. try
  4836. {
  4837. if(addSeqNum) {
  4838. aSendDataBroadcastMsg.AppendToData(WONCommon::RawBuffer((unsigned char*)&theSeqNum,4));
  4839. }
  4840. aSendDataBroadcastMsg.AppendToData(WONCommon::RawBuffer(theDataP,theSize));
  4841. aSendDataBroadcastMsg.SetShouldSendReply(false);
  4842. aSendDataBroadcastMsg.Pack();
  4843. }
  4844. catch (WONException& anEx)
  4845. {
  4846. titanDebug("EXCEPTION: TitanInterface::RoutingSendDataBroadcast: %s", (char*)anEx.what());
  4847. return;
  4848. }
  4849. if (!EncryptAndSendRoutingMsg(aSendDataBroadcastMsg, theServer))
  4850. {
  4851. titanDebug("FAIL: TitanInterface::RoutingSendDataBroadcast fail send!");
  4852. return;
  4853. }
  4854. }
  4855. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4856. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4857. void TitanInterface::RoutingSendChatWhisper(unsigned long* theIds, unsigned short theNumIds, unsigned short theSize, const unsigned char* theDataP, bool addSeqNum, int theSeqNum)
  4858. {
  4859. titanDebug("TitanInterface::RoutingSendChatWhisper");
  4860. AutoCrit aCrit(mRoutingCrit);
  4861. #if DEBUG_DISCONNECT
  4862. string aStr((const char*)theDataP,theSize);
  4863. if(aStr.find("dis")!=string::npos) {
  4864. mRoutePipe[theServer]->AddOutgoingCmd(new CloseCmd(false, false, 0, false));
  4865. return;
  4866. }
  4867. #endif // DEBUG_DISCONNECT
  4868. if (! mRoutePipe[0])
  4869. {
  4870. titanDebug("TitanInterface::RoutingSendChatWhisper No connection.");
  4871. return;
  4872. }
  4873. if (! mLoggedInToRoutingServer[0])
  4874. {
  4875. titanDebug("TitanInterface::RoutingSendChatWhisper Not logged in yet.");
  4876. return;
  4877. }
  4878. WONMsg::MMsgRoutingSendChat aSendChatMsg;
  4879. try
  4880. {
  4881. aSendChatMsg.SetIncludeExcludeFlag(true);
  4882. if(addSeqNum) {
  4883. aSendChatMsg.AppendToData(WONCommon::RawBuffer((unsigned char*)&theSeqNum,4));
  4884. }
  4885. for (int iId = 0; iId < theNumIds; ++iId)
  4886. aSendChatMsg.AddAddressee(theIds[iId]);
  4887. aSendChatMsg.AppendToData(WONCommon::RawBuffer(theDataP, theSize));
  4888. aSendChatMsg.SetChatType(WONMsg::CHATTYPE_UNICODE);
  4889. aSendChatMsg.SetShouldSendReply(false);
  4890. aSendChatMsg.Pack();
  4891. }
  4892. catch (WONException& anEx)
  4893. {
  4894. titanDebug("EXCEPTION: TitanInterface::RoutingSendChatWhisper: %s", (char*)anEx.what());
  4895. return;
  4896. }
  4897. if (!EncryptAndSendRoutingMsg(aSendChatMsg, 0))
  4898. {
  4899. titanDebug("FAIL: TitanInterface::RoutingSendChatWhisper fail send!");
  4900. return;
  4901. }
  4902. }
  4903. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4904. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4905. void TitanInterface::RoutingSendData(WONMsg::ClientId theId, unsigned short theSize, const unsigned char* theDataP, int theServer, bool addSeqNum, int theSeqNum)
  4906. {
  4907. titanDebug("TitanInterface::RoutingSendData");
  4908. AutoCrit aCrit(mRoutingCrit);
  4909. #if DEBUG_DISCONNECT
  4910. string aStr((const char*)theDataP,theSize);
  4911. if(aStr.find("dis")!=string::npos) {
  4912. mRoutePipe[theServer]->AddOutgoingCmd(new CloseCmd(false, false, 0, false));
  4913. return;
  4914. }
  4915. #endif // DEBUG_DISCONNECT
  4916. if (! mRoutePipe[theServer])
  4917. {
  4918. titanDebug("TitanInterface::RoutingSendData No connection.");
  4919. return;
  4920. }
  4921. if (! mLoggedInToRoutingServer[theServer])
  4922. {
  4923. titanDebug("TitanInterface::RoutingSendData Not logged in yet.");
  4924. return;
  4925. }
  4926. WONMsg::MMsgRoutingSendData aSendDataMsg;
  4927. try
  4928. {
  4929. aSendDataMsg.SetIncludeExcludeFlag(true);
  4930. if(addSeqNum) {
  4931. aSendDataMsg.AppendToData(WONCommon::RawBuffer((unsigned char*)&theSeqNum,4));
  4932. }
  4933. aSendDataMsg.AddAddressee(theId);
  4934. aSendDataMsg.AppendToData(WONCommon::RawBuffer(theDataP, theSize));
  4935. aSendDataMsg.SetShouldSendReply(false);
  4936. aSendDataMsg.Pack();
  4937. }
  4938. catch (WONException& anEx)
  4939. {
  4940. titanDebug("EXCEPTION: TitanInterface::RoutingSendData: %s", (char*)anEx.what());
  4941. return;
  4942. }
  4943. if (!EncryptAndSendRoutingMsg(aSendDataMsg, theServer))
  4944. {
  4945. titanDebug("FAIL: TitanInterface::RoutingSendData fail send!");
  4946. return;
  4947. }
  4948. }
  4949. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4950. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4951. void TitanInterface::HandleRoutingGroupChange(SocketPipe* thePipeP, const MiniMessage& theMsgR, int theServer)
  4952. {
  4953. titanDebug("TitanInterface::HandleRoutingGroupChange");
  4954. AutoCrit aCrit(mRoutingCrit);
  4955. if(theServer!=0) // captain figures out when people are gone (want to allow reconnects)
  4956. return;
  4957. try
  4958. {
  4959. WONMsg::MMsgRoutingGroupChange aGroupChangeMsg(theMsgR);
  4960. // only care about chat group
  4961. if (aGroupChangeMsg.GetGroupId() != CHAT_GROUP)
  4962. return;
  4963. // Check if user joined, request user info if so
  4964. if (aGroupChangeMsg.GetReason() & 0x80)
  4965. {
  4966. // ask the server for more info on the client
  4967. WONMsg::MMsgRoutingGetClientInfo aGetClientInfoMsg;
  4968. aGetClientInfoMsg.SetClientId(aGroupChangeMsg.GetClientId());
  4969. aGetClientInfoMsg.SetAuthInfoRequested(false);
  4970. aGetClientInfoMsg.Pack();
  4971. if (!EncryptAndSendRoutingMsg(aGetClientInfoMsg, theServer))
  4972. {
  4973. titanDebug("FAIL: TitanInterface::HandleRoutingGroupChange fail send!");
  4974. return;
  4975. }
  4976. }
  4977. else {
  4978. if(mUseRoutingServer && IAmCaptain && mGameCreationState!=GAME_STARTED) {
  4979. Address anAddr;
  4980. anAddr.AddrPart.IP = aGroupChangeMsg.GetClientId();
  4981. anAddr.Port = aGroupChangeMsg.GetClientId();
  4982. titanLeaveGameReceivedCB(&anAddr, NULL, 0);
  4983. }
  4984. chatReceiveUserLeft(aGroupChangeMsg.GetClientId());
  4985. }
  4986. }
  4987. catch (WONException& anEx)
  4988. {
  4989. titanDebug("EXCEPTION: TitanInterface::HandleRoutingGroupChange: %s", (char*)anEx.what());
  4990. return;
  4991. }
  4992. }
  4993. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4994. //////////////////////////////////////////////////////////////////////////////////////////////////////
  4995. void TitanInterface::HandleRoutingGroupChangeEx(SocketPipe* thePipeP, const MiniMessage& theMsgR, int theServer)
  4996. {
  4997. titanDebug("TitanInterface::HandleRoutingGroupChangeEx");
  4998. AutoCrit aCrit(mRoutingCrit);
  4999. if(theServer!=0) // captain figures out when people are gone (want to allow reconnects)
  5000. return;
  5001. try
  5002. {
  5003. WONMsg::MMsgRoutingGroupChangeEx aGroupChangeExMsg(theMsgR);
  5004. // only care about chat group
  5005. if (aGroupChangeExMsg.GetGroupId() != CHAT_GROUP)
  5006. return;
  5007. // Check if user joined, request user info if so
  5008. if (aGroupChangeExMsg.GetReason() & 0x80)
  5009. {
  5010. OnNewRoutingServerClient(aGroupChangeExMsg.GetClientId(),
  5011. wstring(reinterpret_cast<const wchar_t*>(aGroupChangeExMsg.GetClientName().data()), aGroupChangeExMsg.GetClientName().size() / 2),
  5012. aGroupChangeExMsg.GetIPAddress(),
  5013. theServer);
  5014. }
  5015. else
  5016. {
  5017. WONMsg::MMsgRoutingGroupChange aDummyGroupChangeMsg;
  5018. aDummyGroupChangeMsg.SetClientId(aGroupChangeExMsg.GetClientId());
  5019. aDummyGroupChangeMsg.SetReason(aGroupChangeExMsg.GetReason());
  5020. aDummyGroupChangeMsg.Pack();
  5021. HandleRoutingGroupChange(thePipeP, aDummyGroupChangeMsg, theServer);
  5022. }
  5023. }
  5024. catch (WONException& anEx)
  5025. {
  5026. titanDebug("EXCEPTION: TitanInterface::HandleRoutingGroupChangeEx: %s", (char*)anEx.what());
  5027. return;
  5028. }
  5029. }
  5030. //////////////////////////////////////////////////////////////////////////////////////////////////////
  5031. //////////////////////////////////////////////////////////////////////////////////////////////////////
  5032. void TitanInterface::HandleRoutingCreateDataObject(SocketPipe* thePipeP, const MiniMessage& theMsgR)
  5033. {
  5034. titanDebug("TitanInterface::HandleRoutingCreateDataObject.");
  5035. try
  5036. {
  5037. WONMsg::MMsgRoutingCreateDataObject aCreateDataObjectMsg(theMsgR);
  5038. tpscenario aGame;
  5039. memcpy(aGame.Name,
  5040. aCreateDataObjectMsg.GetDataType().c_str() + strlen((char*)gameTag),
  5041. aCreateDataObjectMsg.GetDataType().size() - strlen((char*)gameTag));
  5042. aGame.Name[(aCreateDataObjectMsg.GetDataType().size() - strlen((char*)gameTag))/2] = '\0';
  5043. memcpy(&aGame.directoryCustomInfo,
  5044. aCreateDataObjectMsg.GetData().c_str(),
  5045. aCreateDataObjectMsg.GetData().size());
  5046. mgGameListGameAdded(&aGame);
  5047. }
  5048. catch (WONException& anEx)
  5049. {
  5050. titanDebug("EXCEPTION: TitanInterface::HandleRoutingCreateDataObject: %s", (char*)anEx.what());
  5051. return;
  5052. }
  5053. }
  5054. //////////////////////////////////////////////////////////////////////////////////////////////////////
  5055. //////////////////////////////////////////////////////////////////////////////////////////////////////
  5056. void TitanInterface::HandleRoutingDeleteDataObject(SocketPipe* thePipeP, const MiniMessage& theMsgR)
  5057. {
  5058. titanDebug("TitanInterface::HandleRoutingDeleteDataObject.");
  5059. try
  5060. {
  5061. WONMsg::MMsgRoutingDeleteDataObject aDeleteDataObjectMsg(theMsgR);
  5062. tpscenario aGame;
  5063. memcpy(aGame.Name,
  5064. aDeleteDataObjectMsg.GetDataType().c_str() + strlen((char*)gameTag),
  5065. aDeleteDataObjectMsg.GetDataType().size() - strlen((char*)gameTag));
  5066. aGame.Name[(aDeleteDataObjectMsg.GetDataType().size() - strlen((char*)gameTag))/2] = '\0';
  5067. memset(&aGame.directoryCustomInfo, 0, sizeof(aGame.directoryCustomInfo));
  5068. mgGameListGameRemoved(&aGame);
  5069. }
  5070. catch (WONException& anEx)
  5071. {
  5072. titanDebug("EXCEPTION: TitanInterface::HandleRoutingDeleteDataObject: %s", (char*)anEx.what());
  5073. return;
  5074. }
  5075. }
  5076. //////////////////////////////////////////////////////////////////////////////////////////////////////
  5077. //////////////////////////////////////////////////////////////////////////////////////////////////////
  5078. void TitanInterface::HandleRoutingGetClientListReply(SocketPipe* thePipeP, const MiniMessage& theMsgR, int theServer)
  5079. {
  5080. titanDebug("TitanInterface::HandleRoutingGetClientListReply.");
  5081. try
  5082. {
  5083. WONMsg::MMsgRoutingGetClientListReply aGetClientListReply(theMsgR);
  5084. std::list<WONMsg::MMsgRoutingGetClientListReply::ClientData>::iterator itr = aGetClientListReply.GetClientList().begin();
  5085. for (; itr != aGetClientListReply.GetClientList().end(); itr++)
  5086. OnNewRoutingServerClient(itr->mClientId, wstring(reinterpret_cast<const wchar_t*>(itr->mClientName.data()), itr->mClientName.size() / 2), itr->mIPAddress, theServer);
  5087. if(theServer==0)
  5088. mHaveReceivedInitialUserList = true;
  5089. }
  5090. catch (WONException& anEx)
  5091. {
  5092. titanDebug("EXCEPTION: TitanInterface::HandleRoutingGetClientListReply: %s", (char*)anEx.what());
  5093. return;
  5094. }
  5095. }
  5096. //////////////////////////////////////////////////////////////////////////////////////////////////////
  5097. //////////////////////////////////////////////////////////////////////////////////////////////////////
  5098. void TitanInterface::OnNewRoutingServerClient(WONMsg::ClientId theClientId, const wstring& theUserNameR, unsigned long theIPAddress, int theServer)
  5099. {
  5100. if (theClientId == mMyClientId[theServer])
  5101. {
  5102. mMyIPAddress.AddrPart.IP = theIPAddress;
  5103. mMyIPAddress.Port = GAME_PORT;
  5104. if(!mUseRoutingServer) {
  5105. myAddress.AddrPart.IP = theIPAddress;
  5106. myAddress.Port = GAME_PORT;
  5107. }
  5108. }
  5109. else if(theServer==0)
  5110. {
  5111. if (mHaveReceivedInitialUserList)
  5112. chatReceiveUsersJoined(WStringToString(theUserNameR).c_str(), theClientId);
  5113. else
  5114. chatReceiveUsersHere(WStringToString(theUserNameR).c_str(), theClientId);
  5115. }
  5116. }
  5117. //////////////////////////////////////////////////////////////////////////////////////////////////////
  5118. //////////////////////////////////////////////////////////////////////////////////////////////////////
  5119. void TitanInterface::HandleRoutingPeerChat(SocketPipe* thePipeP, const MiniMessage& theMsgR, int theServer)
  5120. {
  5121. titanDebug("TitanInterface::HandleRoutingPeerChat");
  5122. try
  5123. {
  5124. WONMsg::MMsgRoutingPeerChat aPeerChatMsg(theMsgR);
  5125. if(aPeerChatMsg.GetData().size()<=0)
  5126. return;
  5127. if(aPeerChatMsg.GetClientId() != mMyClientId[0])
  5128. chatReceiveMessage(aPeerChatMsg.GetClientId(), (aPeerChatMsg.GetAddresseeList().size() > 0), 0, aPeerChatMsg.GetData().size(), aPeerChatMsg.GetData().c_str());
  5129. }
  5130. catch (WONException& anEx)
  5131. {
  5132. titanDebug("EXCEPTION: TitanInterface::HandleRoutingPeerData: %s", (char*)anEx.what());
  5133. return;
  5134. }
  5135. }
  5136. //////////////////////////////////////////////////////////////////////////////////////////////////////
  5137. //////////////////////////////////////////////////////////////////////////////////////////////////////
  5138. void TitanInterface::HandleRoutingPeerData(SocketPipe* thePipeP, const WONCommon::RawBuffer &theData, WONMsg::ClientId theId, int theServer)
  5139. {
  5140. titanDebug("TitanInterface::HandleRoutingPeerData");
  5141. MiniMessage aMsg(theData.size(), theData.c_str());
  5142. thePipeP->SetLabel(theId);
  5143. HandlePeerMsg(thePipeP, aMsg);
  5144. return;
  5145. }
  5146. //////////////////////////////////////////////////////////////////////////////////////////////////////
  5147. //////////////////////////////////////////////////////////////////////////////////////////////////////
  5148. void TitanInterface::HandleRoutingPeerData(SocketPipe* thePipeP, const MiniMessage& theMsgR, int theServer)
  5149. {
  5150. titanDebug("TitanInterface::HandleRoutingPeerData1.");
  5151. try
  5152. {
  5153. WONMsg::MMsgRoutingPeerData aPeerDataMsg(theMsgR);
  5154. HandleRoutingPeerData(thePipeP, aPeerDataMsg.GetData(), aPeerDataMsg.GetClientId(), theServer);
  5155. }
  5156. catch (WONException& anEx)
  5157. {
  5158. titanDebug("EXCEPTION: TitanInterface::HandleRoutingPeerData: %s", (char*)anEx.what());
  5159. return;
  5160. }
  5161. }
  5162. //////////////////////////////////////////////////////////////////////////////////////////////////////
  5163. //////////////////////////////////////////////////////////////////////////////////////////////////////
  5164. void TitanInterface::HandleRoutingPeerDataMultiple(SocketPipe* thePipeP, const MiniMessage& theMsgR, int theServer)
  5165. {
  5166. titanDebug("TitanInterface::HandleRoutingPeerDataMultiple.");
  5167. try
  5168. {
  5169. WONMsg::MMsgRoutingPeerDataMultiple aPeerDataMultipleMsg(theMsgR);
  5170. std::list<PeerDataMessage>::iterator itr = aPeerDataMultipleMsg.GetMessageList().begin();
  5171. for (; itr != aPeerDataMultipleMsg.GetMessageList().end(); itr++)
  5172. HandleRoutingPeerData(thePipeP, itr->mData, itr->mClientId, theServer);
  5173. }
  5174. catch (WONException& anEx)
  5175. {
  5176. titanDebug("EXCEPTION: TitanInterface::HandleRoutingPeerDataMultiple: %s", (char*)anEx.what());
  5177. return;
  5178. }
  5179. }
  5180. //////////////////////////////////////////////////////////////////////////////////////////////////////
  5181. //////////////////////////////////////////////////////////////////////////////////////////////////////
  5182. void TitanInterface::HandleRoutingRegisterClientReply(SocketPipe* thePipeP, const MiniMessage& theMsgR, int theServer)
  5183. {
  5184. titanDebug("TitanInterface::HandleRoutingRegisterClientReply.");
  5185. AutoCrit aCrit(mRoutingCrit);
  5186. try
  5187. {
  5188. WONMsg::MMsgRoutingRegisterClientReply aRegisterClientReply(theMsgR);
  5189. mMyClientId[theServer] = aRegisterClientReply.GetClientId();
  5190. mLoggedInToRoutingServer[theServer] = true;
  5191. mHaveConnectedToAChatServer = true;
  5192. if (theServer == 0)
  5193. chatReceiveUserJoinReply(aRegisterClientReply.GetStatus(), mMyClientId[theServer]);
  5194. if (aRegisterClientReply.GetStatus() != WONMsg::StatusCommon_Success)
  5195. {
  5196. titanDebug("TitanInterface::HandleRoutingRegisterClientReply Failed! Status = %d", aRegisterClientReply.GetStatus());
  5197. return;
  5198. }
  5199. if (theServer == 1) // we registered with a game server
  5200. {
  5201. if(IAmCaptain) {
  5202. mgDisplayMessage(strGetString(strTellingPlayersConnectRoutServ));
  5203. BeginStartGamePacket aPacket;
  5204. aPacket.routingAddress.AddrPart.IP = mRoutingAddress[1].sin_addr.S_un.S_addr;
  5205. aPacket.routingAddress.Port = ntohs(mRoutingAddress[1].sin_port);
  5206. aPacket.oldCaptainAddress.AddrPart.IP = mMyClientId[0];
  5207. aPacket.oldCaptainAddress.Port = mMyClientId[0];
  5208. aPacket.newCaptainAddress.AddrPart.IP = mMyClientId[1];
  5209. aPacket.newCaptainAddress.Port = mMyClientId[1];
  5210. titanBroadcastPacket(TITANMSGTYPE_BEGINSTARTGAME, &aPacket, sizeof(aPacket));
  5211. ChangeAddress(&(aPacket.oldCaptainAddress), &(aPacket.newCaptainAddress));
  5212. OnCaptainStartedGame();
  5213. }
  5214. else {
  5215. mgDisplayMessage(strGetString(strConnectingToRoutingServer));
  5216. mGameCreationState = GAME_STARTED;
  5217. InitPacketList();
  5218. ChangeAddressPacket aChangePacket;
  5219. aChangePacket.oldAddress.AddrPart.IP = mMyClientId[0];
  5220. aChangePacket.oldAddress.Port = mMyClientId[0];
  5221. aChangePacket.newAddress.AddrPart.IP = mMyClientId[1];
  5222. aChangePacket.newAddress.Port = mMyClientId[1];
  5223. titanSendPacketTo(&mCaptainAddress,TITANMSGTYPE_CHANGEADDRESS, &aChangePacket, sizeof(aChangePacket));
  5224. }
  5225. myAddress.AddrPart.IP = mMyClientId[theServer];
  5226. myAddress.Port = mMyClientId[theServer];
  5227. }
  5228. else // we registered with a chat server
  5229. {
  5230. if(mUseRoutingServer) {
  5231. myAddress.AddrPart.IP = mMyClientId[0];
  5232. myAddress.Port = mMyClientId[0];
  5233. }
  5234. // now that we're registered, there are a few things to do
  5235. if (mRoutePipe[0])
  5236. {
  5237. // if we've just entered the lobby for the first time (during this session), record the event
  5238. if (!mHasLobbyEnterEventBeenSent)
  5239. OnInitialLobbyEnter();
  5240. // get the user list
  5241. WONMsg::MMsgRoutingGetClientList aGetClientListMsg;
  5242. aGetClientListMsg.SetAuthInfoRequested(false);
  5243. aGetClientListMsg.Pack();
  5244. if (!EncryptAndSendRoutingMsg(aGetClientListMsg, theServer))
  5245. {
  5246. titanDebug("FAIL: TitanInterface::HandleRoutingRegisterClientReply fail send RoutingGetClientList!");
  5247. return;
  5248. }
  5249. // subscribe to the Homeworld game data
  5250. WONMsg::MMsgRoutingSubscribeDataObject aSubscribeDataObjectMsg;
  5251. aSubscribeDataObjectMsg.SetLinkId(0 /* ALL_USERS */);
  5252. aSubscribeDataObjectMsg.SetDataType(gameTag);
  5253. aSubscribeDataObjectMsg.SetExactOrRecursiveFlag(false);
  5254. aSubscribeDataObjectMsg.SetGroupOrMembersFlag(true);
  5255. aSubscribeDataObjectMsg.Pack();
  5256. if (!EncryptAndSendRoutingMsg(aSubscribeDataObjectMsg, theServer))
  5257. {
  5258. titanDebug("FAIL: TitanInterface::HandleRoutingRegisterClientReply fail send RoutingSubscribeDataObject!");
  5259. return;
  5260. }
  5261. }
  5262. }
  5263. }
  5264. catch (WONException& anEx)
  5265. {
  5266. titanDebug("EXCEPTION: TitanInterface::HandleRoutingRegisterClientReply: %s", (char*)anEx.what());
  5267. return;
  5268. }
  5269. }
  5270. //////////////////////////////////////////////////////////////////////////////////////////////////////
  5271. //////////////////////////////////////////////////////////////////////////////////////////////////////
  5272. void TitanInterface::HandleRoutingReadDataObjectReply(SocketPipe* thePipeP, const MiniMessage& theMsgR)
  5273. {
  5274. titanDebug("TitanInterface::HandleRoutingReadDataObjectReply.");
  5275. try
  5276. {
  5277. WONMsg::MMsgRoutingReadDataObjectReply aReadDataObjectReplyMsg(theMsgR);
  5278. tpscenario aGame;
  5279. WONMsg::MMsgRoutingReadDataObjectReply::DataObjectSet::iterator itr = aReadDataObjectReplyMsg.GetDataObjects().begin();
  5280. for (; itr != aReadDataObjectReplyMsg.GetDataObjects().end(); itr++)
  5281. {
  5282. memcpy(aGame.Name,
  5283. itr->GetDataType().c_str() + strlen((char*)gameTag),
  5284. itr->GetDataType().size() - strlen((char*)gameTag));
  5285. aGame.Name[(itr->GetDataType().size() - strlen((char*)gameTag))/2] = '\0';
  5286. memcpy(&aGame.directoryCustomInfo, itr->GetData().c_str(), itr->GetData().size());
  5287. mgGameListGameAdded(&aGame);
  5288. }
  5289. }
  5290. catch (WONException& anEx)
  5291. {
  5292. titanDebug("EXCEPTION: TitanInterface::HandleRoutingReadDataObjectReply: %s", (char*)anEx.what());
  5293. return;
  5294. }
  5295. }
  5296. //////////////////////////////////////////////////////////////////////////////////////////////////////
  5297. //////////////////////////////////////////////////////////////////////////////////////////////////////
  5298. void TitanInterface::HandleRoutingReplaceDataObject(SocketPipe* thePipeP, const MiniMessage& theMsgR)
  5299. {
  5300. titanDebug("TitanInterface::HandleRoutingReplaceDataObject.");
  5301. try
  5302. {
  5303. WONMsg::MMsgRoutingReplaceDataObject aReplaceDataObjectMsg(theMsgR);
  5304. tpscenario aGame;
  5305. memcpy(aGame.Name,
  5306. aReplaceDataObjectMsg.GetDataType().c_str() + strlen((char*)gameTag),
  5307. aReplaceDataObjectMsg.GetDataType().size() - strlen((char*)gameTag));
  5308. aGame.Name[(aReplaceDataObjectMsg.GetDataType().size() - strlen((char*)gameTag))/2] = '\0';
  5309. memcpy(&aGame.directoryCustomInfo,
  5310. aReplaceDataObjectMsg.GetData().c_str(),
  5311. aReplaceDataObjectMsg.GetData().size());
  5312. mgGameListGameChanged(&aGame);
  5313. }
  5314. catch (WONException& anEx)
  5315. {
  5316. titanDebug("EXCEPTION: TitanInterface::HandleRoutingReplaceDataObject: %s", (char*)anEx.what());
  5317. return;
  5318. }
  5319. }
  5320. //////////////////////////////////////////////////////////////////////////////////////////////////////
  5321. //////////////////////////////////////////////////////////////////////////////////////////////////////
  5322. void TitanInterface::HandleRoutingStatusReply(SocketPipe* thePipeP, const MiniMessage& theMsgR, int theServer)
  5323. {
  5324. titanDebug("TitanInterface::HandleRoutingStatusReply.");
  5325. try
  5326. {
  5327. WONMsg::MMsgRoutingStatusReply aStatusReplyMsg(theMsgR);
  5328. short aStatus = aStatusReplyMsg.GetStatus();
  5329. // were we expecting a StatusReply (can't really tell unless queue is empty)
  5330. if (mWaitingRequestQueue[theServer].size() == 0)
  5331. {
  5332. titanDebug("TitanInterface::HandleRoutingStatusReply: **SOFTWARE ERROR** Received unexpected StatusReply with status %d.", aStatus);
  5333. _ASSERT(mWaitingRequestQueue[theServer].size() != 0); // we're slightly hosed...requests and replies out of sync
  5334. }
  5335. // what type of request elicited this RoutingStatusReply?
  5336. unsigned char aRequestType = mWaitingRequestQueue[theServer].front();
  5337. mWaitingRequestQueue[theServer].pop_front();
  5338. // take action based on the reply
  5339. if (aRequestType == WONMsg::RoutingCreateDataObject)
  5340. {
  5341. titanDebug("TitanInterface::HandleRoutingStatusReply: Got status (%d) when creating game object", aStatus);
  5342. cNotifyGameCreationStatus(aStatus);
  5343. }
  5344. else if(aRequestType == WONMsg::RoutingReconnectClient)
  5345. {
  5346. if(aStatus!=WONMsg::StatusCommon_Success) {
  5347. // What now? mgNotifyReconnectFailed();
  5348. CloseRoutingServerConnection(theServer);
  5349. return;
  5350. }
  5351. clCommandMessage("Reconnected.");
  5352. mLoggedInToRoutingServer[theServer] = true;
  5353. mRoutingReconnectNum[theServer] = 0;
  5354. }
  5355. }
  5356. catch (WONException& anEx)
  5357. {
  5358. titanDebug("EXCEPTION: TitanInterface::HandleRoutingStatusReply: %s", (char*)anEx.what());
  5359. return;
  5360. }
  5361. }
  5362. //////////////////////////////////////////////////////////////////////////////////////////////////////
  5363. //////////////////////////////////////////////////////////////////////////////////////////////////////
  5364. void TitanInterface::OnInitialLobbyEnter()
  5365. {
  5366. RecordEvent(ACTIVITYTYPE_HOMEWORLD_LOBBY_ENTER);
  5367. mHasLobbyEnterEventBeenSent = true;
  5368. // enter the Homeworld URL into the MediaMetrix edit box
  5369. if (mMediaMetrixHWND) SendMessage(mMediaMetrixHWND, WM_SETTEXT, 0, (LPARAM)MEDIAMETRIX_URL);
  5370. }
  5371. //////////////////////////////////////////////////////////////////////////////////////////////////////
  5372. //////////////////////////////////////////////////////////////////////////////////////////////////////
  5373. void TitanInterface::OnFinalLobbyExit()
  5374. {
  5375. RecordEvent(ACTIVITYTYPE_HOMEWORLD_LOBBY_EXIT);
  5376. // clear the Homeworld URL from the MediaMetrix edit box
  5377. if (mMediaMetrixHWND) SendMessage(mMediaMetrixHWND, WM_SETTEXT, 0, (LPARAM) "");
  5378. }
  5379. //////////////////////////////////////////////////////////////////////////////////////////////////////
  5380. //////////////////////////////////////////////////////////////////////////////////////////////////////
  5381. void TitanInterface::OnCaptainStartedGame()
  5382. {
  5383. // Record an event indicating that a new game has been created and that we joined it
  5384. RecordEvent(ACTIVITYTYPE_HOMEWORLD_GAME_CREATE);
  5385. RecordEvent(ACTIVITYTYPE_HOMEWORLD_GAME_ENTER);
  5386. }
  5387. //////////////////////////////////////////////////////////////////////////////////////////////////////
  5388. //////////////////////////////////////////////////////////////////////////////////////////////////////
  5389. void TitanInterface::CreateMediaMetrixEditControl()
  5390. {
  5391. if (!mIsLan)
  5392. mMediaMetrixHWND = CreateWindow("EDIT", // predefined class
  5393. NULL, // no window title
  5394. WS_CHILD, // not visible. not tabstop
  5395. 0, 0, 100, 50, // arbitrary size
  5396. ghMainWindow, // parent window
  5397. (HMENU) NULL, // edit control ID
  5398. (HINSTANCE) GetWindowLong(ghMainWindow, GWL_HINSTANCE),
  5399. NULL); // pointer not needed
  5400. }
  5401. unsigned long TitanInterface::GetHashSection(bool restart, unsigned char** theUnhashedBufP, unsigned char digest[MD5_HASH_SIZE])
  5402. {
  5403. const unsigned int HASH_CHUNK_SIZE = 16384; // number of writes read from the exe per GetHashSection call
  5404. static HANDLE aFileH = INVALID_HANDLE_VALUE;
  5405. if (restart)
  5406. {
  5407. char aFileName[MAX_PATH];
  5408. if (GetModuleFileName(GetModuleHandle(NULL), aFileName, MAX_PATH) == 0)
  5409. return 0;
  5410. aFileH = CreateFile(aFileName,
  5411. GENERIC_READ,
  5412. FILE_SHARE_READ,
  5413. NULL,
  5414. OPEN_EXISTING,
  5415. FILE_FLAG_SEQUENTIAL_SCAN,
  5416. NULL);
  5417. if (*theUnhashedBufP == NULL)
  5418. *theUnhashedBufP = new unsigned char[HASH_CHUNK_SIZE];
  5419. }
  5420. DWORD dwBytesRead;
  5421. if (ReadFile(aFileH, *theUnhashedBufP, HASH_CHUNK_SIZE, &dwBytesRead, NULL) == 0 || dwBytesRead == 0)
  5422. return 0;
  5423. struct MD5Context Context;
  5424. MD5Init2(&Context);
  5425. MD5Update2(&Context, *theUnhashedBufP, dwBytesRead);
  5426. MD5Final2(digest, &Context);
  5427. return dwBytesRead;
  5428. }
  5429. void TitanInterface::ShortCircuitChallengeResponse(unsigned char* theSeed, unsigned char* theChallengeResponseP)
  5430. {
  5431. ReadFromWonstuff(true, theChallengeResponseP);
  5432. struct MD5Context Context;
  5433. MD5Init2(&Context);
  5434. MD5Update2(&Context, theSeed, MD5_HASH_SIZE);
  5435. while (ReadFromWonstuff(false, theChallengeResponseP + MD5_HASH_SIZE))
  5436. MD5Update2(&Context, theChallengeResponseP + MD5_HASH_SIZE, MD5_HASH_SIZE);
  5437. MD5Final2(theChallengeResponseP + MD5_HASH_SIZE, &Context);
  5438. }
  5439. bool TitanInterface::SaveWonstuff()
  5440. {
  5441. unsigned char digest[MD5_HASH_SIZE];
  5442. DWORD dwBytesWritten;
  5443. char readfile[500];
  5444. strcpy(readfile,filePrependPath);
  5445. strcat(readfile,"WONstuff.txt");
  5446. // open the wonstuff.txt file
  5447. HANDLE aFileH = CreateFile(readfile,
  5448. GENERIC_WRITE,
  5449. 0,
  5450. NULL,
  5451. CREATE_ALWAYS,
  5452. 0,
  5453. NULL);
  5454. if (aFileH == INVALID_HANDLE_VALUE)
  5455. {
  5456. DWORD a = GetLastError();
  5457. return false;
  5458. }
  5459. // save space for the whole-file hash
  5460. SetFilePointer(aFileH, MD5_HASH_SIZE, NULL, FILE_BEGIN);
  5461. struct MD5Context Context;
  5462. MD5Init2(&Context);
  5463. // write out the partial-file digests
  5464. bool firsttime = true;
  5465. DWORD dwBytesRead;
  5466. unsigned char* aUnhashedBuf = NULL;
  5467. while ((dwBytesRead = GetHashSection(firsttime, &aUnhashedBuf, digest)) != 0)
  5468. {
  5469. firsttime = false;
  5470. // keep track of the whole-file hash
  5471. MD5Update2(&Context, aUnhashedBuf, dwBytesRead);
  5472. // write out the partial-file hash
  5473. if (WriteFile(aFileH, digest, MD5_HASH_SIZE, &dwBytesWritten, NULL) == 0 || dwBytesWritten != MD5_HASH_SIZE)
  5474. return false;
  5475. }
  5476. // write out the whole-file hash
  5477. SetFilePointer(aFileH, 0, NULL, FILE_BEGIN);
  5478. MD5Final2(digest, &Context);
  5479. if (WriteFile(aFileH, digest, MD5_HASH_SIZE, &dwBytesWritten, NULL) == 0 || dwBytesWritten != MD5_HASH_SIZE)
  5480. return false;
  5481. CloseHandle(aFileH);
  5482. return true;
  5483. }
  5484. int titanSaveWonstuff()
  5485. {
  5486. return TitanInterface::SaveWonstuff();
  5487. }
  5488. bool TitanInterface::ReadFromWonstuff(bool restart, unsigned char* theBufferP)
  5489. {
  5490. static HANDLE aFileH = INVALID_HANDLE_VALUE;
  5491. char readfile[500];
  5492. strcpy(readfile,filePrependPath);
  5493. strcat(readfile,"WONstuff.txt");
  5494. if (restart)
  5495. {
  5496. aFileH = CreateFile(readfile,
  5497. GENERIC_READ,
  5498. FILE_SHARE_READ,
  5499. NULL,
  5500. OPEN_EXISTING,
  5501. FILE_FLAG_SEQUENTIAL_SCAN,
  5502. NULL);
  5503. if (aFileH == INVALID_HANDLE_VALUE)
  5504. return false;
  5505. }
  5506. DWORD dwBytesRead;
  5507. if (ReadFile(aFileH, theBufferP, MD5_HASH_SIZE, &dwBytesRead, NULL) == 0 || dwBytesRead == 0)
  5508. {
  5509. CloseHandle(aFileH);
  5510. aFileH = INVALID_HANDLE_VALUE;
  5511. return false;
  5512. }
  5513. return true;
  5514. }