1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069 |
- #include "pch.h"
- ALLOC_MSG_LIST;
- bool g_bCheckFiles = false;
- /////////////////////////////////////////////////////////////////////////////
- // ClientEventSource
- class ClientEventSource : public IClientEventSource
- {
- private:
- TList<TRef<IClientEventSink> > m_listSinks;
- void RemoveDeadSinks()
- {
- // remove all of the NULL elements from the list
- while (m_listSinks.Remove(NULL))
- {
- }
- }
-
- public:
- void AddSink(IClientEventSink* psink)
- {
- m_listSinks.PushFront(psink);
- }
-
- void RemoveSink(IClientEventSink* psink)
- {
- // in order to let us remove the current sync while walking the list of
- // sinks, just set the sink to NULL for the moment.
- m_listSinks.Replace(psink, NULL);
- }
- #define ForEachSink(fnc) \
- TList<TRef<IClientEventSink> >::Iterator iter(m_listSinks); \
- while (!iter.End()) \
- { \
- if (iter.Value() != NULL) \
- iter.Value()->fnc; \
- iter.Next(); \
- } \
- RemoveDeadSinks(); \
- void OnAddMission(MissionInfo* pMissionInfo)
- {
- ForEachSink( OnAddMission(pMissionInfo) )
- }
- void OnMissionCountdown(MissionInfo* pMissionInfo)
- {
- ForEachSink( OnMissionCountdown(pMissionInfo) )
- }
-
- void OnMissionStarted(MissionInfo* pMissionInfo)
- {
- ForEachSink( OnMissionStarted(pMissionInfo) )
- }
-
- void OnMissionEnded(MissionInfo* pMissionInfo)
- {
- ForEachSink( OnMissionEnded(pMissionInfo) )
- }
- void OnLockLobby(bool bLock)
- {
- ForEachSink( OnLockLobby(bLock) )
- }
- void OnLockSides(bool bLock)
- {
- ForEachSink( OnLockSides(bLock) )
- }
- void OnFoundPlayer(MissionInfo* pMissionInfo)
- {
- ForEachSink( OnFoundPlayer(pMissionInfo) )
- }
- void OnEnterMission()
- {
- ForEachSink( OnEnterMission() )
- }
- void OnDelMission(MissionInfo* pMissionInfo)
- {
- ForEachSink( OnDelMission(pMissionInfo) )
- }
-
- void OnAddPlayer(MissionInfo* pMissionInfo, SideID sideID, PlayerInfo* pPlayerInfo)
- {
- ForEachSink( OnAddPlayer(pMissionInfo, sideID, pPlayerInfo) )
- }
- void OnDelPlayer(MissionInfo* pMissionInfo, SideID sideID, PlayerInfo* pPlayerInfo, QuitSideReason reason, const char* szMessageParam)
- {
- ForEachSink( OnDelPlayer(pMissionInfo, sideID, pPlayerInfo, reason, szMessageParam) )
- }
- void OnAddRequest(MissionInfo* pMissionInfo, SideID sideID, PlayerInfo* pPlayerInfo)
- {
- ForEachSink( OnAddRequest(pMissionInfo, sideID, pPlayerInfo) )
- }
- void OnDelRequest(MissionInfo* pMissionInfo, SideID sideID, PlayerInfo* pPlayerInfo, DelPositionReqReason reason)
- {
- ForEachSink( OnDelRequest(pMissionInfo, sideID, pPlayerInfo, reason) )
- }
- void OnTeamInactive(MissionInfo* pMissionInfo, SideID sideID)
- {
- ForEachSink( OnTeamInactive(pMissionInfo, sideID) )
- }
- void OnTeamReadyChange(MissionInfo* pMissionInfo, SideID sideID, bool fTeamReady)
- {
- ForEachSink( OnTeamReadyChange(pMissionInfo, sideID, fTeamReady) )
- }
- void OnTeamForceReadyChange(MissionInfo* pMissionInfo, SideID sideID, bool fTeamForceReady)
- {
- ForEachSink( OnTeamForceReadyChange(pMissionInfo, sideID, fTeamForceReady) )
- }
- void OnTeamAutoAcceptChange(MissionInfo* pMissionInfo, SideID sideID, bool fAutoAccept)
- {
- ForEachSink( OnTeamAutoAcceptChange(pMissionInfo, sideID, fAutoAccept) )
- }
- void OnTeamCivChange(MissionInfo* pMissionInfo, SideID sideID, CivID civID)
- {
- ForEachSink( OnTeamCivChange(pMissionInfo, sideID, civID) )
- }
- void OnTeamNameChange(MissionInfo* pMissionInfo, SideID sideID)
- {
- ForEachSink( OnTeamNameChange(pMissionInfo, sideID) )
- }
- void OnPlayerStatusChange(MissionInfo* pMissionInfo, SideID sideID, PlayerInfo* pPlayerInfo)
- {
- ForEachSink( OnPlayerStatusChange(pMissionInfo, sideID, pPlayerInfo) )
- }
- void OnMoneyChange(PlayerInfo* pPlayerInfo)
- {
- ForEachSink( OnMoneyChange(pPlayerInfo) )
- }
- void OnBucketChange(BucketChange bc, IbucketIGC* b)
- {
- ForEachSink( OnBucketChange(bc, b) )
- }
- void OnTechTreeChanged(SideID sid)
- {
- ForEachSink( OnTechTreeChanged(sid) )
- }
- void OnStationCaptured(StationID stationID, SideID sideID)
- {
- ForEachSink( OnStationCaptured(stationID, sideID) )
- }
- void OnModelTerminated(ImodelIGC* pmodel)
- {
- ForEachSink( OnModelTerminated(pmodel) )
- }
- void OnLoadoutChanged(IpartIGC* ppart, LoadoutChange lc)
- {
- ForEachSink( OnLoadoutChanged(ppart, lc) )
- }
-
- void OnTurretStateChanging(bool bTurret)
- {
- ForEachSink( OnTurretStateChanging(bTurret) )
- }
- void OnPurchaseCompleted(bool bAllPartsBought)
- {
- ForEachSink( OnPurchaseCompleted(bAllPartsBought) )
- }
- void OnShipStatusChange(PlayerInfo* pplayer)
- {
- ForEachSink( OnShipStatusChange(pplayer) )
- }
- void OnBoardShip(IshipIGC* pshipChild, IshipIGC* pshipParent)
- {
- ForEachSink( OnBoardShip(pshipChild, pshipParent) )
- }
- void OnBoardFailed(IshipIGC* pshipParent)
- {
- ForEachSink( OnBoardFailed(pshipParent) )
- }
- void OnDiscoveredStation(IstationIGC* pstation)
- {
- ForEachSink( OnDiscoveredStation(pstation) )
- }
- void OnDiscoveredAsteroid(IasteroidIGC* pasteroid)
- {
- ForEachSink( OnDiscoveredAsteroid(pasteroid) )
- }
- void OnClusterChanged(IclusterIGC* pcluster)
- {
- ForEachSink( OnClusterChanged(pcluster) )
- }
- void OnGameoverStats()
- {
- ForEachSink( OnGameoverStats() )
- }
- void OnGameoverPlayers()
- {
- ForEachSink( OnGameoverPlayers() )
- }
- void OnDeleteChatMessage(ChatInfo* pchatInfo)
- {
- ForEachSink( OnDeleteChatMessage(pchatInfo) )
- }
- void OnNewChatMessage()
- {
- ForEachSink( OnNewChatMessage() )
- }
- void OnClearChat()
- {
- ForEachSink( OnClearChat() )
- }
- void OnChatMessageChange()
- {
- ForEachSink( OnChatMessageChange() )
- }
- void OnLostConnection(const char * szReason)
- {
- ForEachSink( OnLostConnection(szReason) )
- }
- void OnEnterModalState()
- {
- ForEachSink( OnEnterModalState() )
- }
- void OnLeaveModalState()
- {
- ForEachSink( OnLeaveModalState() )
- }
- void OnLogonClub()
- {
- ForEachSink( OnLogonClub() )
- }
- void OnLogonClubFailed(bool bRetry, const char * szReason)
- {
- ForEachSink( OnLogonClubFailed(bRetry, szReason) )
- }
- void OnLogonLobby()
- {
- ForEachSink( OnLogonLobby() )
- }
- void OnLogonLobbyFailed(bool bRetry, const char * szReason)
- {
- ForEachSink( OnLogonLobbyFailed(bRetry, szReason) )
- }
- void OnLogonGameServer()
- {
- ForEachSink( OnLogonGameServer() )
- }
- void OnLogonGameServerFailed(bool bRetry, const char * szReason)
- {
- ForEachSink( OnLogonGameServerFailed(bRetry, szReason) )
- }
- };
- /////////////////////////////////////////////////////////////////////////////
- // IClientEventSink
- class ClientEventSinkDelegate : public IClientEventSink {
- private:
- IClientEventSink* m_psink;
- public:
- ClientEventSinkDelegate(IClientEventSink* psink) :
- m_psink(psink)
- {
- }
- void OnAddMission(MissionInfo* pMissionInfo)
- {
- m_psink->OnAddMission(pMissionInfo);
- }
- void OnMissionCountdown(MissionInfo* pMissionInfo)
- {
- m_psink->OnMissionCountdown(pMissionInfo);
- }
-
- void OnMissionStarted(MissionInfo* pMissionInfo)
- {
- m_psink->OnMissionStarted(pMissionInfo);
- }
-
- void OnMissionEnded(MissionInfo* pMissionInfo)
- {
- m_psink->OnMissionEnded(pMissionInfo);
- }
-
- void OnLockLobby(bool bLock)
- {
- m_psink->OnLockLobby(bLock);
- }
-
- void OnLockSides(bool bLock)
- {
- m_psink->OnLockSides(bLock);
- }
-
- void OnFoundPlayer(MissionInfo* pMissionDef)
- {
- m_psink->OnFoundPlayer(pMissionDef);
- }
- void OnEnterMission()
- {
- m_psink->OnEnterMission();
- }
- void OnDelMission(MissionInfo* pMissionInfo)
- {
- m_psink->OnDelMission(pMissionInfo);
- }
-
- void OnAddPlayer(MissionInfo* pMissionInfo, SideID sideID, PlayerInfo* pPlayerInfo)
- {
- m_psink->OnAddPlayer(pMissionInfo, sideID, pPlayerInfo);
- }
- void OnDelPlayer(MissionInfo* pMissionInfo, SideID sideID, PlayerInfo* pPlayerInfo, QuitSideReason reason, const char* szMessageParam)
- {
- m_psink->OnDelPlayer(pMissionInfo, sideID, pPlayerInfo, reason, szMessageParam);
- }
- void OnAddRequest(MissionInfo* pMissionInfo, SideID sideID, PlayerInfo* pPlayerInfo)
- {
- m_psink->OnAddRequest(pMissionInfo, sideID, pPlayerInfo);
- }
- void OnDelRequest(MissionInfo* pMissionInfo, SideID sideID, PlayerInfo* pPlayerInfo, DelPositionReqReason reason)
- {
- m_psink->OnDelRequest(pMissionInfo, sideID, pPlayerInfo, reason);
- }
- void OnTeamInactive(MissionInfo* pMissionInfo, SideID sideID)
- {
- m_psink->OnTeamInactive(pMissionInfo, sideID);
- }
- void OnTeamReadyChange(MissionInfo* pMissionInfo, SideID sideID, bool fTeamReady)
- {
- m_psink->OnTeamReadyChange(pMissionInfo, sideID, fTeamReady);
- }
- void OnTeamForceReadyChange(MissionInfo* pMissionInfo, SideID sideID, bool fTeamForceReady)
- {
- m_psink->OnTeamForceReadyChange(pMissionInfo, sideID, fTeamForceReady);
- }
- void OnTeamAutoAcceptChange(MissionInfo* pMissionInfo, SideID sideID, bool fAutoAccept)
- {
- m_psink->OnTeamAutoAcceptChange(pMissionInfo, sideID, fAutoAccept);
- }
- void OnTeamCivChange(MissionInfo* pMissionInfo, SideID sideID, CivID civID)
- {
- m_psink->OnTeamCivChange(pMissionInfo, sideID, civID);
- }
- void OnTeamNameChange(MissionInfo* pMissionInfo, SideID sideID)
- {
- m_psink->OnTeamNameChange(pMissionInfo, sideID);
- }
- void OnPlayerStatusChange(MissionInfo* pMissionInfo, SideID sideID, PlayerInfo* pPlayerInfo)
- {
- m_psink->OnPlayerStatusChange(pMissionInfo, sideID, pPlayerInfo);
- }
- void OnMoneyChange(PlayerInfo* pPlayerInfo)
- {
- m_psink->OnMoneyChange(pPlayerInfo);
- }
- void OnBucketChange(BucketChange bc, IbucketIGC* b)
- {
- m_psink->OnBucketChange(bc, b);
- }
- void OnTechTreeChanged(SideID sid)
- {
- m_psink->OnTechTreeChanged(sid);
- }
- void OnStationCaptured(StationID stationID, SideID sideID)
- {
- m_psink->OnStationCaptured(stationID, sideID);
- }
- void OnModelTerminated(ImodelIGC* pmodel)
- {
- m_psink->OnModelTerminated(pmodel);
- }
- void OnLoadoutChanged(IpartIGC* ppart, LoadoutChange lc)
- {
- m_psink->OnLoadoutChanged(ppart, lc);
- }
- void OnTurretStateChanging(bool bTurret)
- {
- m_psink->OnTurretStateChanging(bTurret);
- }
- void OnPurchaseCompleted(bool bAllPartsBought)
- {
- m_psink->OnPurchaseCompleted(bAllPartsBought);
- }
- void OnShipStatusChange(PlayerInfo* pplayer)
- {
- m_psink->OnShipStatusChange(pplayer);
- }
- void OnBoardShip(IshipIGC* pshipChild, IshipIGC* pshipParent)
- {
- m_psink->OnBoardShip(pshipChild, pshipParent);
- }
- void OnBoardFailed(IshipIGC* pshipParent)
- {
- m_psink->OnBoardFailed(pshipParent);
- }
- void OnDiscoveredStation(IstationIGC* pstation)
- {
- m_psink->OnDiscoveredStation(pstation);
- }
- void OnDiscoveredAsteroid(IasteroidIGC* pasteroid)
- {
- m_psink->OnDiscoveredAsteroid(pasteroid);
- }
- void OnClusterChanged(IclusterIGC* pcluster)
- {
- m_psink->OnClusterChanged(pcluster);
- }
- void OnGameoverStats()
- {
- m_psink->OnGameoverStats();
- }
- void OnGameoverPlayers()
- {
- m_psink->OnGameoverPlayers();
- }
- void OnDeleteChatMessage(ChatInfo* pchatInfo)
- {
- m_psink->OnDeleteChatMessage(pchatInfo);
- }
- void OnNewChatMessage()
- {
- m_psink->OnNewChatMessage();
- }
- void OnClearChat()
- {
- m_psink->OnClearChat();
- }
- void OnChatMessageChange()
- {
- m_psink->OnChatMessageChange();
- }
- void OnLostConnection(const char* szReason)
- {
- m_psink->OnLostConnection(szReason);
- }
- void OnEnterModalState()
- {
- m_psink->OnEnterModalState();
- }
- void OnLeaveModalState()
- {
- m_psink->OnLeaveModalState();
- }
- void OnLogonClub()
- {
- m_psink->OnLogonClub();
- }
- void OnLogonClubFailed(bool bRetry, const char * szReason)
- {
- m_psink->OnLogonClubFailed(bRetry, szReason);
- }
- void OnLogonLobby()
- {
- m_psink->OnLogonLobby();
- }
- void OnLogonLobbyFailed(bool bRetry, const char * szReason)
- {
- m_psink->OnLogonLobbyFailed(bRetry, szReason);
- }
- void OnLogonGameServer()
- {
- m_psink->OnLogonGameServer();
- }
- void OnLogonGameServerFailed(bool bRetry, const char * szReason)
- {
- m_psink->OnLogonGameServerFailed(bRetry, szReason);
- }
- };
- TRef<IClientEventSink> IClientEventSink::CreateDelegate(IClientEventSink* psink)
- {
- return new ClientEventSinkDelegate(psink);
- }
- /////////////////////////////////////////////////////////////////////////////
- // ChatInfo
- void ChatInfo::SetChat(ChatTarget ctRecipient,
- const ZString& strText,
- CommandID cid,
- ImodelIGC* pmodelTarget,
- const Color& color,
- bool bFromPlayer,
- bool bFromObjectModel,
- bool bFromLeader)
- {
- m_ctRecipient = ctRecipient;
- m_cidCommand = cid;
- m_pmodelTarget = pmodelTarget;
- m_strMessage = strText;
- m_colorMessage = color;
- m_bFromPlayer = bFromPlayer;
- m_bFromObjectModel = bFromObjectModel;
- m_bFromLeader = bFromLeader;
- }
- void ChatInfo::ClearTarget(void)
- {
- m_cidCommand = c_cidNone;
- if (m_pmodelTarget->GetObjectType() != OT_buoy)
- {
- m_strMessage += " <dead>";
- }
- m_pmodelTarget = NULL;
- }
- /////////////////////////////////////////////////////////////////////////////
- // MissionInfo
- MissionInfo::MissionInfo(DWORD dwCookie) :
- m_sideLobby(SIDE_TEAMLOBBY)
- {
- m_pfmMissionDef = new FMD_S_MISSIONDEF;
- memset(m_pfmMissionDef, 0, sizeof(FMD_S_MISSIONDEF));
- m_pfmMissionDef->dwCookie = dwCookie;
- m_fGuaranteedSlotsAvailable = false;
- m_fAnySlotsAvailable = false;
- m_fCountdownStarted = false;
- m_nNumPlayers = 0;
- }
- MissionInfo::~MissionInfo()
- {
- if (m_pfmMissionDef)
- delete m_pfmMissionDef;
- TMapListWrapper<SideID, SideInfo*>::Iterator iterSideInfo(m_mapSideInfo);
- while (!iterSideInfo.End())
- {
- delete iterSideInfo.Value();
- iterSideInfo.Next();
- }
- }
- void MissionInfo::Update(FMD_S_MISSIONDEF* pfmMissionDef)
- {
- int numSidesOld = NumSides();
- memcpy(m_pfmMissionDef, pfmMissionDef, sizeof(FMD_S_MISSIONDEF));
- // create or destroy sides, as needed.
- if (NumSides() > numSidesOld)
- {
- // create the new sides the easy way
- for(SideID sideID = numSidesOld; sideID < NumSides(); sideID++)
- {
- GetSideInfo(sideID);
- }
- }
- else
- {
- // destroy the old sides
- for (SideID sideID = numSidesOld - 1; sideID >= NumSides(); sideID--)
- {
- m_mapSideInfo.Remove(sideID);
- }
- }
- // signal the sides list in case something has changed.
- m_mapSideInfo.GetSink()();
- }
- void MissionInfo::Update(FMD_LS_LOBBYMISSIONINFO* pfmLobbyMissionInfo)
- {
- int numSidesOld = NumSides();
- Strncpy(m_pfmMissionDef->misparms.strGameName, FM_VAR_REF(pfmLobbyMissionInfo, szGameName), c_cbGameName);
- m_pfmMissionDef->misparms.strGameName[c_cbGameName - 1] = '\0';
- m_strGameDetailsFiles = (FM_VAR_REF(pfmLobbyMissionInfo, szGameDetailsFiles) != NULL)
- ? FM_VAR_REF(pfmLobbyMissionInfo, szGameDetailsFiles) : "";
- m_pfmMissionDef->misparms.nTeams = pfmLobbyMissionInfo->nTeams;
- m_pfmMissionDef->misparms.nMinPlayersPerTeam = pfmLobbyMissionInfo->nMinPlayersPerTeam;
- m_pfmMissionDef->misparms.nMaxPlayersPerTeam = pfmLobbyMissionInfo->nMaxPlayersPerTeam;
- m_pfmMissionDef->misparms.iMinRank = pfmLobbyMissionInfo->nMinRank;
- m_pfmMissionDef->misparms.iMaxRank = pfmLobbyMissionInfo->nMaxRank;
- m_pfmMissionDef->misparms.timeStart = Time(pfmLobbyMissionInfo->dwStartTime);
- m_nNumPlayers = pfmLobbyMissionInfo->nNumPlayers;
- m_fGuaranteedSlotsAvailable = pfmLobbyMissionInfo->fGuaranteedSlotsAvailable;
- m_fAnySlotsAvailable = pfmLobbyMissionInfo->fAnySlotsAvailable;
- m_nNumPlayers = pfmLobbyMissionInfo->nNumPlayers;
- SetInProgress(pfmLobbyMissionInfo->fInProgress);
- SetCountdownStarted(pfmLobbyMissionInfo->fCountdownStarted);
- m_pfmMissionDef->misparms.bScoresCount = pfmLobbyMissionInfo->fScoresCount;
- m_pfmMissionDef->misparms.bAllowDevelopments = pfmLobbyMissionInfo->fAllowDevelopments;
- m_pfmMissionDef->misparms.bInvulnerableStations = pfmLobbyMissionInfo->fInvulnerableStations;
- m_pfmMissionDef->misparms.bObjectModelCreated = pfmLobbyMissionInfo->fMSArena;
- m_pfmMissionDef->misparms.nTotalMaxPlayersPerGame = pfmLobbyMissionInfo->nMaxPlayersPerGame;
- m_pfmMissionDef->misparms.bSquadGame = pfmLobbyMissionInfo->fSquadGame;
- m_pfmMissionDef->misparms.bEjectPods = pfmLobbyMissionInfo->fEjectPods;
- if (pfmLobbyMissionInfo->fLimitedLives && m_pfmMissionDef->misparms.iLives == 0x7fff)
- m_pfmMissionDef->misparms.iLives = 1;
- else if (!pfmLobbyMissionInfo->fLimitedLives && m_pfmMissionDef->misparms.iLives != 0x7fff)
- m_pfmMissionDef->misparms.iLives = 0x7fff;
- if (pfmLobbyMissionInfo->fConquest && !m_pfmMissionDef->misparms.IsConquestGame())
- m_pfmMissionDef->misparms.iGoalConquestPercentage = 100;
- else if (!pfmLobbyMissionInfo->fConquest && m_pfmMissionDef->misparms.IsConquestGame())
- m_pfmMissionDef->misparms.iGoalConquestPercentage = 0;
- if (pfmLobbyMissionInfo->fDeathMatch && !m_pfmMissionDef->misparms.IsDeathMatchGame())
- m_pfmMissionDef->misparms.nGoalTeamKills = 1;
- else if (!pfmLobbyMissionInfo->fDeathMatch && m_pfmMissionDef->misparms.IsDeathMatchGame())
- m_pfmMissionDef->misparms.nGoalTeamKills = 0;
- if (pfmLobbyMissionInfo->fCountdown && !m_pfmMissionDef->misparms.IsCountdownGame())
- m_pfmMissionDef->misparms.dtGameLength = 600;
- else if (!pfmLobbyMissionInfo->fCountdown && m_pfmMissionDef->misparms.IsCountdownGame())
- m_pfmMissionDef->misparms.dtGameLength = 0;
- if (pfmLobbyMissionInfo->fProsperity && !m_pfmMissionDef->misparms.IsProsperityGame())
- m_pfmMissionDef->misparms.fGoalTeamMoney = 100;
- else if (!pfmLobbyMissionInfo->fProsperity && m_pfmMissionDef->misparms.IsProsperityGame())
- m_pfmMissionDef->misparms.fGoalTeamMoney = 0;
- if (pfmLobbyMissionInfo->fArtifacts && !m_pfmMissionDef->misparms.IsArtifactsGame())
- m_pfmMissionDef->misparms.nGoalArtifactsCount = 10;
- else if (!pfmLobbyMissionInfo->fArtifacts && m_pfmMissionDef->misparms.IsArtifactsGame())
- m_pfmMissionDef->misparms.nGoalArtifactsCount = 0;
- if (pfmLobbyMissionInfo->fFlags && !m_pfmMissionDef->misparms.IsFlagsGame())
- m_pfmMissionDef->misparms.nGoalFlagsCount = 10;
- else if (!pfmLobbyMissionInfo->fFlags && m_pfmMissionDef->misparms.IsFlagsGame())
- m_pfmMissionDef->misparms.nGoalFlagsCount = 0;
- if (pfmLobbyMissionInfo->fTerritorial && !m_pfmMissionDef->misparms.IsTerritoryGame())
- m_pfmMissionDef->misparms.iGoalTerritoryPercentage = 70;
- else if (!pfmLobbyMissionInfo->fTerritorial && m_pfmMissionDef->misparms.IsTerritoryGame())
- m_pfmMissionDef->misparms.iGoalTerritoryPercentage = 100;
- // create or destroy sides, as needed.
- if (NumSides() > numSidesOld)
- {
- // create the new sides the easy way
- for(SideID sideID = numSidesOld; sideID < NumSides(); sideID++)
- {
- GetSideInfo(sideID);
- }
- }
- else
- {
- // destroy the old sides
- for (SideID sideID = numSidesOld - 1; sideID >= NumSides(); sideID--)
- {
- m_mapSideInfo.Remove(sideID);
- }
- }
- // copy the squad info
- {
- SideID sideID;
- SquadID* vSquadIDs = (SquadID*)FM_VAR_REF(pfmLobbyMissionInfo, rgSquadIDs);
- int numSquads = pfmLobbyMissionInfo->cbrgSquadIDs / sizeof(SquadID);
- assert(numSquads < c_cSidesMax);
- for (sideID = 0; sideID < numSquads; sideID++)
- squadIDs[sideID] = vSquadIDs[sideID];
- for (; sideID < c_cSidesMax; sideID++)
- squadIDs[sideID] = NA;
- }
- // signal the sides list in case something has changed.
- m_mapSideInfo.GetSink()();
- }
- void MissionInfo::UpdateStartTime(Time timeStart)
- {
- m_pfmMissionDef->misparms.timeStart = timeStart;
- }
- int MissionInfo::GuaranteedPositions()
- {
- SideID sideID;
- int nTotal = 0;
- for(sideID = 0; sideID < NumSides(); sideID++)
- {
- if (SideActive(sideID) && (SideAutoAccept(sideID)
- || (SideNumPlayers(sideID) == 0 && AutoAcceptLeaders())))
- {
- nTotal += SideMaxPlayers(sideID) - SideNumPlayers(sideID);
- }
- }
- return nTotal;
- }
- void MissionInfo::PurgePlayers()
- {
- TMapListWrapper<SideID, SideInfo*>::Iterator iterSideInfo(m_mapSideInfo);
- while (!iterSideInfo.End())
- {
- delete iterSideInfo.Value();
- iterSideInfo.Next();
- }
- m_mapSideInfo.SetEmpty();
- for (SideID id = 0; id < NumSides(); id++)
- {
- m_pfmMissionDef->rgcPlayers[id] = 0;
- }
- }
- bool MissionInfo::HasSquad(SquadID squadID)
- {
- for (SideID id = 0; id < NumSides(); id++)
- {
- if (squadIDs[id] == squadID)
- return true;
- }
- return false;
- }
- void MissionInfo::SetSideLeader(PlayerInfo* pPlayerInfo)
- {
- m_pfmMissionDef->rgShipIDLeaders[pPlayerInfo->SideID()] = pPlayerInfo->ShipID();
- if (pPlayerInfo->IsMissionOwner())
- m_pfmMissionDef->iSideMissionOwner = pPlayerInfo->SideID();
- GetSideInfo(pPlayerInfo->SideID())->GetMembers().GetSink()();
- }
- bool MissionInfo::FindPlayer(SideID sideID, ShipID shipID)
- {
- ZAssert(sideID != NA);
- ZAssert(shipID >= 0);
- return GetSideInfo(sideID)->FindPlayer(shipID);
- }
- void MissionInfo::AddPlayer(PlayerInfo* pPlayerInfo)
- {
- SideID sideID = pPlayerInfo->SideID();
- ShipID shipID = pPlayerInfo->ShipID();
- ZAssert(sideID != NA);
- ZAssert(shipID >= 0);
-
- SideInfo* psideInfo = GetSideInfo(sideID);
- if (!psideInfo->FindPlayer(shipID))
- {
- if ((sideID >= 0) && pPlayerInfo->IsHuman())
- m_pfmMissionDef->rgcPlayers[sideID]++;
- psideInfo->RemoveRequest(shipID);
- psideInfo->AddPlayer(shipID);
- m_mapSideInfo.GetSink()();
- }
- }
- void MissionInfo::RemovePlayer(PlayerInfo* pPlayerInfo)
- {
- SideID sideID = pPlayerInfo->SideID();
- ShipID shipID = pPlayerInfo->ShipID();
- ZAssert(sideID != NA);
- ZAssert(shipID >= 0);
- if (sideID != SIDE_TEAMLOBBY)
- {
- // update the team owner info if the team owner is quiting
- if (m_pfmMissionDef->rgShipIDLeaders[sideID] == pPlayerInfo->ShipID())
- {
- pPlayerInfo->SetTeamLeader(false);
- m_pfmMissionDef->rgShipIDLeaders[sideID] = NA;
- if (m_pfmMissionDef->iSideMissionOwner == sideID)
- {
- m_pfmMissionDef->iSideMissionOwner = NA;
- pPlayerInfo->SetMissionOwner(false);
- }
- }
- }
- SideInfo* psideInfo = GetSideInfo(sideID);
- if (psideInfo->FindPlayer(shipID))
- {
- if ((sideID >= 0) && pPlayerInfo->IsHuman())
- m_pfmMissionDef->rgcPlayers[sideID]--;
- psideInfo->RemovePlayer(shipID);
- m_mapSideInfo.GetSink()();
- }
- }
- bool MissionInfo::FindRequest(SideID sideID, ShipID shipID)
- {
- ZAssert(sideID != NA);
- ZAssert(shipID >= 0);
- if (sideID == SIDE_TEAMLOBBY)
- return false;
- return GetSideInfo(sideID)->FindRequest(shipID);
- }
- void MissionInfo::AddRequest(SideID sideID, ShipID shipID)
- {
- ZAssert(sideID != NA);
- ZAssert(shipID >= 0);
- if (sideID == SIDE_TEAMLOBBY)
- return;
- SideInfo* psideInfo = GetSideInfo(sideID);
- ZAssert(psideInfo);
- if (!psideInfo->FindPlayer(shipID) && !psideInfo->FindRequest(shipID))
- psideInfo->AddRequest(shipID);
- m_mapSideInfo.GetSink()();
- }
- void MissionInfo::RemoveRequest(SideID sideID, ShipID shipID)
- {
- ZAssert(sideID != NA);
- ZAssert(shipID >= 0);
- if (sideID == SIDE_TEAMLOBBY)
- return;
- GetSideInfo(sideID)->RemoveRequest(shipID);
- m_mapSideInfo.GetSink()();
- }
- SideInfo* MissionInfo::GetSideInfo(SideID sideID)
- {
- ZAssert(sideID != NA);
- SideInfo* pSideInfo = NULL;
-
- if (sideID >= m_pfmMissionDef->misparms.nTeams)
- {
- assert(false);
- return NULL;
- }
- else if (!m_mapSideInfo.Find(sideID, pSideInfo) && sideID != SIDE_TEAMLOBBY)
- {
- pSideInfo = new SideInfo(sideID);
- m_mapSideInfo.Set(sideID, pSideInfo);
- }
- else if (sideID == SIDE_TEAMLOBBY)
- {
- return &m_sideLobby;
- }
- return pSideInfo;
- }
- List* MissionInfo::GetSideList()
- {
- // make sure we have a complete sides list
- for (SideID id = 0; id < NumSides(); id++)
- GetSideInfo(id);
- GetSideInfo(SIDE_TEAMLOBBY);
- return new ListDelegate(&m_mapSideInfo);
- }
- /////////////////////////////////////////////////////////////////////////////
- // PlayerInfo
- PlayerInfo::PlayerInfo(void) :
- m_pship(NULL),
- m_vPersistPlayerScores(NULL),
- m_cPersistPlayerScores(0),
- m_bMute(false)
- {
- }
- PlayerInfo::~PlayerInfo()
- {
- if (m_vPersistPlayerScores)
- delete m_vPersistPlayerScores;
- ResetShipStatus();
- }
- void PlayerInfo::Set(FMD_S_PLAYERINFO* pfmPlayerInfo)
- {
- if (m_vPersistPlayerScores)
- delete m_vPersistPlayerScores;
- memcpy(&m_fmPlayerInfo, pfmPlayerInfo, sizeof(m_fmPlayerInfo));
- m_cPersistPlayerScores = pfmPlayerInfo->cbrgPersistPlayerScores / sizeof(PersistPlayerScoreObject);
- if (m_cPersistPlayerScores > 0)
- {
- PersistPlayerScoreObject* vSrcScores
- = (PersistPlayerScoreObject*)FM_VAR_REF(pfmPlayerInfo, rgPersistPlayerScores);
- m_vPersistPlayerScores = new PersistPlayerScoreObject[m_cPersistPlayerScores];
- for (int i = 0; i < m_cPersistPlayerScores; i++)
- m_vPersistPlayerScores[i] = vSrcScores[i];
- }
- else
- {
- m_vPersistPlayerScores = NULL;
- }
- }
- const PersistPlayerScoreObject& PlayerInfo::GetPersistScore(CivID civId) const
- {
- for (int i = 0; i < m_cPersistPlayerScores; i++)
- {
- if (m_vPersistPlayerScores[i].GetCivID() == civId)
- return m_vPersistPlayerScores[i];
- }
- return m_persist;
- }
- void PlayerInfo::UpdateScore(PersistPlayerScoreObject& ppso)
- {
- CivID civId = ppso.GetCivID();
- if (civId != NA)
- {
- int iCivScore;
- // look for the ppso for this civ
- for (iCivScore = 0; iCivScore < m_cPersistPlayerScores; ++iCivScore)
- {
- if (m_vPersistPlayerScores[iCivScore].GetCivID() == civId)
- break;
- }
- // if the given civ was not found, create a new entry for it.
- if (iCivScore >= m_cPersistPlayerScores)
- {
- PersistPlayerScoreObject* vppsoNew
- = new PersistPlayerScoreObject[m_cPersistPlayerScores + 1];
-
- for (int i = 0; i < m_cPersistPlayerScores; ++i)
- vppsoNew[i] = m_vPersistPlayerScores[i];
- if (m_vPersistPlayerScores)
- delete m_vPersistPlayerScores;
- m_vPersistPlayerScores = vppsoNew;
- ++m_cPersistPlayerScores;
- }
- // copy the stats
- m_vPersistPlayerScores[iCivScore] = ppso;
- }
- }
- CivID PlayerInfo::GetCivID() const
- {
- if (SideID() < 0)
- return NA;
- else
- return GetShip()->GetSide()->GetCivilization()->GetObjectID();
- }
- /////////////////////////////////////////////////////////////////////////////
- // BaseClient
- BaseClient::BaseClient(void)
- :
- m_pCoreIGC(CreateMission()),
- m_lastSend(Time::Now()),
- m_lastLagCheck(Time::Now()),
- m_serverOffset(0),
- m_serverOffsetValidF(false),
- m_selectedWeapon(0),
- m_messageType(c_mtNone),
- m_cookie(NA),
- m_plinkSelectedChat(NULL),
- m_pPlayerInfo(NULL),
- m_pMissionInfo(NULL),
- m_fLoggedOn(false),
- m_fLoggedOnToLobby(false),
- m_fLoggedOnToClub(false),
- m_fm(this),
- m_fmLobby(this),
- m_fmClub(this),
- m_ship(NULL),
- m_pshipLastSender(NULL),
- m_moneyLastRequest(0),
- m_sync(1.0f),
- m_viewCluster(NULL),
- m_cUnansweredPings(0),
- m_pAutoDownload(NULL),
- m_fZoneClub(false),
- m_fIsLobbied(false),
- m_dwCookieToJoin(NA),
- m_bInGame(false),
- m_bWaitingForGameRestart(false),
- m_cRankInfo(0),
- m_vRankInfo(NULL),
- m_cStaticMapInfo(0),
- m_vStaticMapInfo(NULL),
- m_lockdownCriteria(0),
- m_lobbyServerOffset(0),
- m_plistFindServerResults(NULL),
- m_strCDKey("")
- {
- CoInitialize(NULL);
- m_timeLastPing = m_lastSend;
- m_plistMissions = new ListDelegate(&m_mapMissions);
- m_pClientEventSource = new ClientEventSource();
- m_szCharName[0] = '\0';
- m_szClubCharName[0] = '\0';
- m_szLobbyCharName[0] = '\0';
- m_szIGCStaticFile[0] = '\0';
- m_pMissionInfo = NULL;
- }
- BaseClient::~BaseClient(void)
- {
- #ifdef USEAUTH
- FreeZoneAuthClient();
- #endif
- CoUninitialize();
- TMapListWrapper<DWORD, MissionInfo*>::Iterator iterMissions(m_mapMissions);
- while (!iterMissions.End())
- {
- delete iterMissions.Value();
- iterMissions.Next();
- }
- if (m_pMissionInfo)
- delete m_pMissionInfo;
- if (m_ci.pZoneTicket)
- HeapFree(GetProcessHeap(), 0, m_ci.pZoneTicket);
- m_fm.Shutdown();
- if (m_pAutoDownload)
- delete m_pAutoDownload;
- if (m_vRankInfo)
- delete [] m_vRankInfo;
- m_vRankInfo = NULL;
- if (m_vStaticMapInfo)
- delete [] m_vStaticMapInfo;
- m_vStaticMapInfo = NULL;
- }
- void BaseClient::Initialize(Time timeNow)
- {
- assert (m_pCoreIGC);
-
- //Now that we have a mission, create a (no-hull) ship for the player
- CreateDummyShip();
- m_pCoreIGC->Initialize(timeNow, this);
- }
- void BaseClient::Reinitialize(Time timeNow)
- {
- BaseClient::Terminate();
- // dont change m_pClientEventSource... too many things in WinTrek are holding on to it
- // and don't get reinitialized
- ZAssert(m_pCoreIGC == NULL);
- m_pCoreIGC = CreateMission();
- m_lastSend = timeNow;
- m_lastLagCheck = timeNow;
- m_timeLastPing = timeNow;
- m_serverOffset = 0;
- m_serverOffsetValidF = false;
- m_selectedWeapon = NULL;
- m_messageType = c_mtNone;
- m_cookie = NA;
- m_plinkSelectedChat = NULL;
- m_pPlayerInfo = NULL;
- if (m_pMissionInfo)
- delete m_pMissionInfo;
- m_pMissionInfo = NULL;
- m_fLoggedOn = false;
- m_pchaffLastCreated = NULL;
- m_pshipLastSender = NULL;
- m_moneyLastRequest = 0;
- m_mapBucketStatusArray.SetEmpty();
- m_listPlayers.purge(true);
- m_chatList.purge(true);
- Initialize(timeNow);
-
- }
- void BaseClient::Terminate(void)
- {
- assert (m_pCoreIGC);
- Disconnect();
- FlushGameState();
- }
- void BaseClient::FlushGameState()
- {
- m_pchaffLastCreated = NULL;
- if (m_ship)
- m_ship->AddRef();
- //Offline, we need to explicitly terminate all of the ships
- {
- const ShipListIGC* ships = m_pCoreIGC->GetShips();
- ShipLinkIGC* l;
- while ((l = ships->first()) != NULL)
- {
- l->data()->Terminate();
- }
- }
- m_listPlayers.purge();
- m_pCoreIGC->Terminate();
- // Destroy the dummy ship
- if (m_ship)
- {
- DestroyDummyShip();
- m_ship->Release();
- m_ship = NULL;
- }
- delete m_pCoreIGC;
- m_pCoreIGC = NULL;
- m_bInGame = false;
- }
- HRESULT BaseClient::ConnectToServer(ConnectInfo & ci, DWORD dwCookie, Time now, const char* szPassword, bool bStandalonePrivate)
- {
- // connect to a particular *game* on this server
- HRESULT hr = S_OK;
-
- // review: in the event of retry logon after logon failure
- // we need to treat this as a reconnect and dump first connection...
- // we should see about reusing the connection
- assert(IFF(ci.cbZoneTicket > 0, ci.pZoneTicket));
- Reinitialize(now);
-
- assert (!m_fm.IsConnected() && !m_fLoggedOn);
- // this does everything up to, and including, creating a new player
- if (ci.guidSession != GUID_NULL)
- {
- assert(ci.strServer.IsEmpty());
- hr = m_fm.JoinSessionInstance(ci.guidSession, ci.szName);
- }
- else
- {
- if (bStandalonePrivate)
- hr = m_fm.JoinSession(FEDSRV_STANDALONE_PRIVATE_GUID, ci.strServer, ci.szName);
- else
- hr = m_fm.JoinSession(FEDSRV_GUID, ci.strServer, ci.szName);
- }
- // TODO: Remove this when we are ready to enforce CD Keys
- if (m_strCDKey.IsEmpty())
- m_strCDKey = ZString(ci.szName).ToUpper();
- if (m_fm.IsConnected())
- {
- ZSucceeded(hr);
- // Let's formally announce ourselves to the server
- SetMessageType(c_mtGuaranteed);
- BEGIN_PFM_CREATE(m_fm, pfmLogon, C, LOGONREQ)
- FM_VAR_PARM(ci.szName, CB_ZTS)
- FM_VAR_PARM(ci.pZoneTicket, ci.cbZoneTicket)
- FM_VAR_PARM((PCC)m_strCDKey.Scramble(bStandalonePrivate ? "corrupt wave file" : ci.szName), CB_ZTS)
- FM_VAR_PARM(szPassword, CB_ZTS)
- END_PFM_CREATE
- pfmLogon->fedsrvVer = MSGVER;
- pfmLogon->dwCookie = dwCookie;
- //pfmLogon->zgs = m_fm.GetEncryptedZoneTicket();
- pfmLogon->time = Time::Now ();
- debugf("Logging on to game server \"%s\"...\n",
- ci.strServer.IsEmpty() ? "" : (LPCSTR)ci.strServer);
- SendMessages();
- }
- retailf("$$MSRGuard:Set:UserName=%s\n", ci.szName);
- m_cUnansweredPings = 0;
- m_serverOffsetValidF = false;
- return hr;
- }
- HRESULT BaseClient::ConnectToLobby(ConnectInfo * pci) // pci is NULL if relogging in
- {
- HRESULT hr = S_OK;
-
- // review: in the event of retry logon after logon failure
- // we need to treat this as a reconnect and dump first connection...
- // we should see about reusing the connection
- if (pci)
- {
- if (m_ci.pZoneTicket)
- HeapFree(GetProcessHeap(), 0, m_ci.pZoneTicket);
- m_ci = *pci;
- }
- // but we always use config-specified lobby server. Is this too restrictive to derived clients?
- m_ci.strServer = GetIsZoneClub() ? GetCfgInfo().strClubLobby : GetCfgInfo().strPublicLobby;
- assert(IFF(m_ci.cbZoneTicket > 0, m_ci.pZoneTicket));
-
- // TODO: Remove this when we are ready to enforce CD Keys
- if (m_strCDKey.IsEmpty())
- m_strCDKey = ZString(m_ci.szName).ToUpper();
- if (m_fmLobby.IsConnected())
- return S_OK;
- assert(m_fLoggedOnToLobby == false);
-
- TMapListWrapper<DWORD, MissionInfo*>::Iterator iterMissions(m_mapMissions);
- while (!iterMissions.End())
- {
- delete iterMissions.Value();
- iterMissions.Next();
- }
- m_mapMissions.SetEmpty();
- hr = m_fmLobby.JoinSession(GetIsZoneClub() ? FEDLOBBYCLIENTS_GUID : FEDFREELOBBYCLIENTS_GUID, m_ci.strServer, m_ci.szName);
- assert(IFF(m_fmLobby.IsConnected(), SUCCEEDED(hr)));
- if (m_fmLobby.IsConnected())
- {
- DWORD dwTime = Time::Now().clock();
- int crcFileList = (g_bCheckFiles ? 0 : FileCRC("FileList.txt", NULL));
- char * szEncryptionKey = (char *)_alloca(strlen(CL_LOGON_KEY) + 30);
- wsprintf(szEncryptionKey, CL_LOGON_KEY, dwTime, m_ci.szName);
- // Let's formally announce ourselves to the server
- BEGIN_PFM_CREATE(m_fmLobby, pfmLogon, C, LOGON_LOBBY)
- FM_VAR_PARM(m_ci.pZoneTicket, m_ci.cbZoneTicket)
- FM_VAR_PARM(PCC(m_strCDKey.Scramble(szEncryptionKey)), CB_ZTS)
- END_PFM_CREATE
- pfmLogon->verLobby = LOBBYVER;
- pfmLogon->crcFileList = crcFileList;
- pfmLogon->dwTime = dwTime;
- lstrcpy(pfmLogon->szName, m_ci.szName);
- // do art update--see ConnectToServer
- debugf("Logging on to lobby \"%s\"...\n",
- m_ci.strServer.IsEmpty() ? "" : (LPCSTR)m_ci.strServer);
- lstrcpy(m_szLobbyCharName, m_ci.szName);
- SendLobbyMessages();
- }
- retailf("$$MSRGuard:Set:UserName=%s\n", m_szLobbyCharName);
- m_cUnansweredPings = 0;
- m_serverOffsetValidF = false;
- return hr;
- }
- HRESULT BaseClient::ConnectToClub(ConnectInfo * pci) // pci is NULL if relogging in
- {
- HRESULT hr = S_OK;
-
- if (m_fmClub.IsConnected())
- return S_OK;
- // review: in the event of retry logon after logon failure
- // we need to treat this as a reconnect and dump first connection...
- // we should see about reusing the connection
- if (pci)
- {
- if (m_ci.pZoneTicket)
- HeapFree(GetProcessHeap(), 0, m_ci.pZoneTicket);
- m_ci = *pci;
- }
- assert(IFF(m_ci.cbZoneTicket > 0, m_ci.pZoneTicket));
-
- if (m_fmClub.IsConnected())
- return S_OK;
- assert(m_fLoggedOnToClub == false);
-
- hr = m_fmClub.JoinSession(FEDCLUB_GUID, m_ci.strServer, m_ci.szName);
- assert(IFF(m_fmClub.IsConnected(), SUCCEEDED(hr)));
- if (m_fmClub.IsConnected())
- {
- // Let's formally announce ourselves to the server
- BEGIN_PFM_CREATE(m_fmClub, pfmLogon, C, LOGON_CLUB)
- FM_VAR_PARM(pci->szName, CB_ZTS)
- FM_VAR_PARM(m_ci.pZoneTicket, m_ci.cbZoneTicket)
- END_PFM_CREATE
- pfmLogon->verClub = ALLCLUBVER;
- debugf("Logging on to Club Server...\n");
- lstrcpy(m_szClubCharName, pci->szName);
- SendClubMessages();
- }
- m_cUnansweredPings = 0;
- m_serverOffsetValidF = false;
- return hr;
- }
- void BaseClient::FindStandaloneServersByName(const char* szName, TList<TRef<LANServerInfo> >& listResults)
- {
- listResults.SetEmpty();
- m_plistFindServerResults = &listResults;
- m_fm.EnumSessions(FEDSRV_STANDALONE_PRIVATE_GUID, szName);
- m_plistFindServerResults = NULL;
- };
- void BaseClient::SetCDKey(const ZString& strCDKey)
- {
- m_strCDKey = strCDKey.ToUpper();
- }
- void BaseClient::HandleAutoDownload(DWORD dwTimeAlloted)
- {
- if (m_pAutoDownload)
- {
- m_pAutoDownload->HandleAutoDownload(dwTimeAlloted);
- }
- }
- IweaponIGC* BaseClient::GetWeapon(void)
- {
- return (IweaponIGC*)m_ship->GetMountedPart(ET_Weapon, m_selectedWeapon);
- }
- void BaseClient::SetAutoPilot(bool autoPilot)
- {
- m_ship->SetAutopilot(autoPilot);
- }
- void BaseClient::DisconnectLobby()
- {
- m_fLoggedOnToLobby = false;
- if (m_fmLobby.IsConnected())
- m_fmLobby.Shutdown();
- }
- void BaseClient::DisconnectClub()
- {
- m_fLoggedOnToClub = false;
- if (m_fmClub.IsConnected())
- m_fmClub.Shutdown();
- m_szClubCharName[0] = '\0';
- }
- void BaseClient::Disconnect(void)
- {
- if (m_fLoggedOn)
- {
- SetMessageType(c_mtGuaranteed);
- BEGIN_PFM_CREATE(m_fm, pfmLogoff, CS, LOGOFF)
- END_PFM_CREATE
- SendMessages();
- // let's just spin for a few seconds handling messages directly from here, and wait until we either see our logoff
- // come back (m_fLoggedOn = false) or until we get sick of waiting. This will ensure that the server cleanly kills
- // this player. Obviously the ui will be hung during this time.
- // Ok, that was a nice idea, but entering the receive loop re-entrantly was not safe, so we're just going to wait,
- // and hope that the message gets out. The only risk here is that if the server doesn't get the logoff, it will think
- // the player was dropped instead of cleanly logged off.
- Sleep(500);
- }
- if (m_fm.IsConnected())
- {
- m_fm.Shutdown();
- m_fLoggedOn = false;
- }
- m_szCharName[0] = '\0';
- m_szIGCStaticFile[0] = '\0';
- }
- void BaseClient::SetPlayerInfo(PlayerInfo* p)
- {
- assert (p);
- m_pPlayerInfo = p;
- //Set the fields that are derived from the player's info
- m_ship->SetObjectID(p->ShipID());
- m_ship->SetName(p->CharacterName());
- assert (p->SideID() == NA);
- assert (m_ship->GetSide() == NULL);
- }
- void BaseClient::SetViewCluster(IclusterIGC* pcluster, const Vector* pposition)
- {
- m_viewCluster = pcluster;
- }
- void BaseClient::ResetShip(void)
- {
- assert (GetSide());
- //Lose all of the parts
- {
- const PartListIGC* plist = m_ship->GetParts();
- PartLinkIGC* plink;
- while (plink = plist->first()) //Not ==
- {
- plink->data()->Terminate();
- }
- }
- m_ship->SetBaseHullType(GetSide()->GetCivilization()->GetLifepod());
- //Do not set these before setting the hull (since we might not have has a hull and that would
- //trigger the 0 mass assert).
- m_ship->SetAmmo(0);
- m_ship->SetFuel(0.0f);
- m_pmodelServerTarget = NULL;
- }
- void BaseClient::ResetClusterScanners(IsideIGC* pside)
- {
- SideID sid = pside->GetObjectID();
- //Because the player joined a side the scanner information for each "our" side is not correct
- //fix that problem
- {
- //Stations ...
- for (StationLinkIGC* l = pside->GetStations()->first();
- (l != NULL);
- l = l->next())
- {
- IstationIGC* pstation = l->data();
- pstation->GetCluster()->GetClusterSite()->AddScanner(sid, pstation);
- }
- }
- {
- //Probes ...
- }
- }
- void BaseClient::BuyLoadout(IshipIGC* pshipLoadout, bool bLaunch)
- {
- assert(pshipLoadout);
- if (m_fm.IsConnected ())
- {
- SetMessageType(c_mtGuaranteed);
- BEGIN_PFM_CREATE(m_fm, pfmBuyLoadout, C, BUY_LOADOUT)
- FM_VAR_PARM(NULL, pshipLoadout->ExportShipLoadout(NULL))
- END_PFM_CREATE
- assert (pshipLoadout->GetBaseHullType());
- pshipLoadout->ExportShipLoadout((ShipLoadout*)(FM_VAR_REF(pfmBuyLoadout, loadout)));
- pfmBuyLoadout->fLaunch = bLaunch;
- if (bLaunch)
- StartLockDown("Preparing ship for launch....", lockdownLoadout);
- else
- StartLockDown("Loading out ship....", lockdownLoadout);
- }
- else
- {
- // I'm training here
- short size = pshipLoadout->ExportShipLoadout(NULL);
- void* ptr = new char[size];
- pshipLoadout->ExportShipLoadout (static_cast <ShipLoadout*> (ptr));
- m_ship->PurchaseShipLoadout (size, static_cast <ShipLoadout*> (ptr));
- m_pClientEventSource->OnPurchaseCompleted (true);
- delete ptr;
- }
- }
- IshipIGC* BaseClient::CopyCurrentShip(void)
- {
- assert (m_ship);
- TRef<IshipIGC> pshipLoadout = CreateEmptyShip();
- //Copy the hull
- pshipLoadout->SetBaseHullType(m_ship->GetBaseHullType());
- //Copy the parts
- for (PartLinkIGC* ppl = m_ship->GetParts()->first(); (ppl != NULL); ppl = ppl->next())
- {
- IpartIGC* ppart = ppl->data();
- pshipLoadout->CreateAndAddPart(ppart->GetPartType(), ppart->GetMountID(), ppart->GetAmount());
- }
- return pshipLoadout;
- }
- IshipIGC* BaseClient::CreateEmptyShip(ShipID sid)
- {
- DataShipIGC ds;
- ds.hullID = NA;
- ds.shipID = sid;
- ds.nParts = 0;
- ds.sideID = SIDE_TEAMLOBBY;
- ds.name[0] = '\0';
- //ds.wingID = 0;
- ds.pilotType = c_ptCheatPlayer;
- ds.abmOrders = 0;
- ds.nDeaths = 0;
- ds.nEjections = 0;
- ds.nKills = 0;
- ds.baseObjectID = NA;
- IshipIGC* pship = (IshipIGC*)(m_pCoreIGC->CreateObject(m_lastSend, OT_ship, &ds, sizeof(ds)));
- //pship->SetSide(GetCore()->GetSide(SIDE_TEAMLOBBY));
- return pship;
- }
- void BaseClient::SetMoney(Money m)
- {
- assert(m >= 0);
- // XXX still a hack until I work out exactly how to get the player info set up
- if (m_pPlayerInfo)
- {
- m_pPlayerInfo->SetMoney(m);
- m_pClientEventSource->OnMoneyChange(m_pPlayerInfo);
- }
- if (m_pMissionInfo)
- {
- SideInfo* psideinfo = m_pMissionInfo->GetSideInfo(GetSideID());
- if (psideinfo)
- {
- psideinfo->GetMembers().GetSink()();
- }
- }
- }
- bool BaseClient::SendUpdate(Time now)
- {
- bool fSent = false;
- if (flyingF() && m_fm.IsConnected())
- {
- if (m_ship->GetParentShip() == NULL)
- {
- static const int smSendUpdateNow = weaponsMaskIGC | selectedWeaponMaskIGC |
- coastButtonIGC |
- backwardButtonIGC | forwardButtonIGC |
- leftButtonIGC | rightButtonIGC |
- upButtonIGC | downButtonIGC |
- afterburnerButtonIGC;
- //int stateM = m_ship->GetStateM();
- if ((now >= m_lastSend + c_dsecUpdateClient) /* || ((m_oldStateM ^ stateM) & smSendUpdateNow) */)
- {
- ZAssert(m_ship->GetPosition().LengthSquared());
- m_lastSend = now;
- /*
- ** We only "own" one object which needs to be updated -- the player's ship --
- ** so just send an update for it.
- */
- SetMessageType(c_mtNonGuaranteed);
- BEGIN_PFM_CREATE(m_fm, pfmShip, C, SHIP_UPDATE)
- END_PFM_CREATE
- m_ship->ExportShipUpdate(&(pfmShip->shipupdate));
- pfmShip->cookie = m_cookie;
- pfmShip->timeUpdate = ServerTimeFromClientTime(m_ship->GetLastUpdate());
- //m_oldStateM = stateM;
- fSent = true;
- }
- }
- else
- {
- static const int smSendUpdateNow = weaponsMaskIGC;
- //int stateM = m_ship->GetStateM();
- if ((now >= m_lastSend + c_dsecUpdateClient) /* || ((m_oldStateM ^ stateM) & smSendUpdateNow)*/)
- {
- m_lastSend = now;
- /*
- ** We only "own" one object which needs to be updated -- the player's ship --
- ** so just send an update for it.
- */
- SetMessageType(c_mtNonGuaranteed);
- int stateM = m_ship->GetStateM();
- if (stateM & weaponsMaskIGC)
- {
- //Turret is shooting ... facing matters
- BEGIN_PFM_CREATE(m_fm, pfmTurret, C, ACTIVE_TURRET_UPDATE)
- END_PFM_CREATE
- m_ship->ExportShipUpdate(&(pfmTurret->atu));
- pfmTurret->timeUpdate = ServerTimeFromClientTime(m_ship->GetLastUpdate());
- }
- else
- {
- //Turret is not shooting ... facing doesn't matter so don't bother to send it
- BEGIN_PFM_CREATE(m_fm, pfmTurret, C, INACTIVE_TURRET_UPDATE)
- END_PFM_CREATE
- }
- //m_oldStateM = stateM;
- fSent = true;
- }
- }
- }
- return(fSent);
- }
- void BaseClient::SetMessageType(MessageType messageType)
- {
- // If the message type was None, there shldn't be anything in the message outbox
- // CURTC: I didn't write this, and I don't like it :-)
- assert(IMPLIES(m_messageType == c_mtNone, m_fm.CbUsedSpaceInOutbox() == 0));
- if (messageType != m_messageType)
- {
- SendMessages();
- m_messageType = messageType;
- }
- }
- void BaseClient::SendMessages(void)
- {
- // Message type should be none iff there is nothing in the outbox
- assert (IMPLIES((m_messageType == c_mtNone), (m_fm.CbUsedSpaceInOutbox() == 0)));
- if (m_messageType != c_mtNone)
- {
- ZSucceeded(m_fm.SendMessages(m_fm.GetServerConnection(),
- m_messageType == c_mtGuaranteed ? FM_GUARANTEED : FM_NOT_GUARANTEED,
- FM_FLUSH));
- m_messageType = c_mtNone;
- }
- }
- void BaseClient::NextWeapon(void)
- {
- assert (m_ship);
- if (m_ship->GetParentShip() == NULL)
- {
- Mount nHardpoints = m_ship->GetHullType()->GetMaxFixedWeapons();
- if (nHardpoints > 0)
- {
- Mount startWeapon = m_selectedWeapon;
- IpartIGC* p;
- do
- {
- m_selectedWeapon = (m_selectedWeapon + 1) % nHardpoints;
- p = m_ship->GetMountedPart(ET_Weapon, m_selectedWeapon);
- }
- while ((p == NULL) && (m_selectedWeapon != startWeapon));
- }
- }
- }
- void BaseClient::PreviousWeapon(void)
- {
- assert (m_ship);
- if (m_ship->GetParentShip() == NULL)
- {
- Mount nHardpoints = m_ship->GetHullType()->GetMaxFixedWeapons();
- if (nHardpoints > 0)
- {
- Mount startWeapon = m_selectedWeapon;
- IpartIGC* p;
- do
- {
- m_selectedWeapon =
- m_selectedWeapon ? (m_selectedWeapon - 1) : nHardpoints - 1;
- p = m_ship->GetMountedPart(ET_Weapon, m_selectedWeapon);
- }
- while ((p == NULL) && (m_selectedWeapon != startWeapon));
- }
- }
- }
- void BaseClient::SetSelectedWeapon(Mount id)
- {
- assert (m_ship);
- if (m_ship->GetParentShip() == NULL)
- {
- Mount nHardpoints = m_ship->GetHullType()->GetMaxFixedWeapons();
- if (id < nHardpoints && m_ship->GetMountedPart(ET_Weapon, id))
- {
- m_selectedWeapon = id;
- }
- }
- }
- void BaseClient::JoinMission(MissionInfo * pMission, const char* szMissionPassword)
- {
- assert (pMission);
- BEGIN_PFM_CREATE(m_fmLobby, pfmJoinGameReq, C, JOIN_GAME_REQ)
- END_PFM_CREATE
- pfmJoinGameReq->dwCookie = pMission->GetCookie();
- SendLobbyMessages();
- m_dwCookieToJoin = pMission->GetCookie();
- assert(strlen(szMissionPassword) < c_cbGamePassword);
- strncpy(m_strPasswordToJoin, szMissionPassword, c_cbGamePassword);
- m_strPasswordToJoin[c_cbGamePassword - 1] = '\0';
- // waiting for FM_L_JOIN_GAME_ACK. When we get that we can join it
- }
- void BaseClient::CreateMissionReq()
- {
- //No need to set message type for non m_fm messages
- BEGIN_PFM_CREATE(m_fmLobby, pfmCreateMission, C, CREATE_MISSION_REQ)
- END_PFM_CREATE
- SendLobbyMessages();
- // now we wait for FM_L_CREATE_MISSION_ACK
- }
- #ifdef markcu
- const int g_cPingsTimeout = int(unsigned(1<<31)-1); // close to infinity as possible for int
- #else
- const int g_cPingsTimeout = 5;
- #endif
- const DWORD g_sDeadTime = 30; // 30 seconds
- void BaseClient::CheckServerLag(Time now)
- {
- const float maxLagCheck = 6.0f;
- const float minLagCheck = 1.0f;
- if (m_fm.IsConnected())
- {
- //if (0 == m_timeLastPing.clock()) // start the ping clock once we get a ship
- //m_timeLastPing = now;
- if (m_lastLagCheck + maxLagCheck <= now)
- {
- // debugf("DPlay latency=%dms\n", m_fm.GetLatency(m_fm.GetServerConnection())); -- this doesn't report accurate values
- // if we haven't received x pings in a row and it's been at least g_sDeadTime since the last message, we're a goner
- if (m_cUnansweredPings > g_cPingsTimeout && (now - m_timeLastServerMessage) >= g_sDeadTime)
- {
- // what should that number be?
- OnSessionLost("Pings aren't coming back.", &m_fm);
- }
- else
- {
- m_lastLagCheck = now;
- // make sure we get an update on the server offset even if the
- // connection is poor.
- bool bGuaranteed = m_cUnansweredPings > g_cPingsTimeout;
- SetMessageType(bGuaranteed ? c_mtGuaranteed : c_mtNonGuaranteed);
- BEGIN_PFM_CREATE(m_fm, pfmPing, CS, PING)
- END_PFM_CREATE
- pfmPing->fmg = bGuaranteed ? FM_GUARANTEED : FM_NOT_GUARANTEED;
- pfmPing->timeClient = Time::Now();
- SendMessages();
- m_cUnansweredPings++;
- }
- }
- }
- }
- HRESULT BaseClient::ReceiveMessages(void)
- {
- HRESULT hr;
- if (m_fm.IsConnected())
- hr = m_fm.ReceiveMessages();
- else
- hr = S_OK;
- if (m_fmLobby.IsConnected())
- {
- if (FAILED(hr)) // preserve fail sign
- m_fmLobby.ReceiveMessages();
- else
- hr = m_fmLobby.ReceiveMessages();
- }
- if (m_fmClub.IsConnected())
- {
- if (FAILED(hr)) // preserve fail sign
- m_fmClub.ReceiveMessages();
- else
- hr = m_fmClub.ReceiveMessages();
- }
- return(hr);
- }
- HRESULT BaseClient::OnSessionLost(char * szReason, FedMessaging * pthis)
- {
- debugf("OnSessionLost. %s. lastUpdate=%d now=%d Time::Now()=%d\n",
- szReason, m_lastUpdate.clock(), m_now.clock(), Time::Now().clock());
- m_fLoggedOn = false; // we don't want to try and log off, cause the link is dead
- if (pthis == &m_fm)
- Disconnect();
- else if (pthis == &m_fmClub)
- DisconnectClub();
- else if (pthis == &m_fmLobby)
- DisconnectLobby();
- else
- assert(false);
- return(S_OK);
- }
- void BaseClient::OnMessageNAK(FedMessaging * pthis, DWORD dwTime, CFMRecipient * prcp)
- {
- // we can't recover from this, so...
- OnSessionLost("guaranteed message couldn't be delivered", pthis);
- }
- HRESULT BaseClient::OnSessionLost(FedMessaging * pthis)
- {
- return OnSessionLost("DPlay session terminated", pthis);
- }
- void BaseClient::OnSessionFound(FedMessaging * pthis, FMSessionDesc * pSessionDesc)
- {
- m_plistFindServerResults->PushEnd(
- new LANServerInfo(pSessionDesc->GetInstance(), pSessionDesc->GetGameName(),
- pSessionDesc->GetNumPlayers(), pSessionDesc->GetMaxPlayers())
- );
- }
- void BaseClient::ReceiveChat(IshipIGC* pshipSender,
- ChatTarget ctRecipient,
- ObjectID oidRecipient,
- SoundID voiceOver,
- const char* pszText,
- CommandID cid,
- ObjectType otTarget,
- ObjectID oidTarget,
- ImodelIGC* pmodelTarget,
- bool bObjectModel)
- {
- m_pClientEventSource->OnNewChatMessage();
- }
- /*
- void BaseClient::OfflineCommandToDrone (const ChatData* pcd, const DataBuoyIGC* pdb, CFSShip* pfsSender, IshipIGC* pshipTo, ImodelIGC** ppmodelTarget)
- {
- assert (pfsSender);
- IsideIGC* pside = pshipTo->GetSide();
- if ((pcd->commandID != c_cidNone) &&
- (pfsSender->GetIGCShip()->GetSide() == pside))
- {
- if (*ppmodelTarget == NULL)
- {
- if (pdb)
- {
- //Create a buoy for this chat message
- *ppmodelTarget = (ImodelIGC*)(pfsMission->GetIGCMission()->CreateObject(g.timeNow, OT_buoy, pdb, sizeof(*pdb)));
- assert (*ppmodelTarget);
- ((IbuoyIGC*)*ppmodelTarget)->AddConsumer();
- }
- else
- {
- *ppmodelTarget = pfsMission->GetIGCMission()->GetModel(otTarget, oidTarget);
- }
- }
- CommandID cid = pcd->commandID;
- if ((cid == c_cidDefault) && (*ppmodelTarget != NULL))
- {
- cid = c_cidGoto;
- PilotType pt = pshipTo->GetPilotType();
- switch (pt)
- {
- case c_ptMiner:
- case c_ptBuilder:
- {
- if (((*ppmodelTarget)->GetObjectType() == OT_asteroid) &&
- ((IasteroidIGC*)(*ppmodelTarget))->HasCapability(pshipTo->GetOrdersABM()))
- {
- cid = (pt == c_ptMiner) ? c_cidMine : c_cidBuild;
- }
- }
- break;
- case c_ptLayer:
- {
- if ((*ppmodelTarget)->GetObjectType() == OT_buoy)
- {
- cid = c_cidBuild;
- }
- }
- break;
- case c_ptWingman:
- {
- IsideIGC* psideTarget = (*ppmodelTarget)->GetSide();
- if (psideTarget == pside)
- cid = c_cidDefend;
- else
- cid = c_cidAttack;
- }
- }
- }
- if (pshipTo->LegalCommand(cid, *ppmodelTarget))
- {
- pfsMission->GetSite()->SendChat(pshipTo, CHAT_INDIVIDUAL, pfsSender->GetIGCShip()->GetObjectID(),
- voAffirmativeSound, "Affirmative.");
- if (cid == c_cidJoin)
- {
- //Join the targets wing
- assert ((*ppmodelTarget)->GetObjectType() == OT_ship);
- WingID wid = ((IshipIGC*)*ppmodelTarget)->GetWingID();
- pshipTo->SetWingID(wid);
- BEGIN_PFM_CREATE(g.fm, pfmWingChange, CS, SET_WINGID)
- END_PFM_CREATE
- pfmWingChange->shipID = pshipTo->GetObjectID();
- pfmWingChange->wingID = wid;
- g.fm.SendMessages(CFSSide::FromIGC(pside)->GetGroup(), FM_GUARANTEED, FM_FLUSH);
- }
- else
- {
- //Set both current and accepted commands
- pshipTo->SetCommand(c_cmdCurrent,
- *ppmodelTarget,
- cid);
- pshipTo->SetCommand(c_cmdAccepted,
- *ppmodelTarget,
- cid);
- }
- }
- else
- {
- pfsMission->GetSite()->SendChat(pshipTo, CHAT_INDIVIDUAL, pfsSender->GetIGCShip()->GetObjectID(),
- voNegativeSound, "Negative.");
- }
- }
- }
- */
- bool BaseClient::ParseShellCommand(const char* pszCommand)
- {
- bool bCommand = false;
- if (_strnicmp(pszCommand, "!mute ", 6) == 0)
- {
- PlayerInfo* ppi = FindPlayer(pszCommand + 6);
- if (ppi)
- ppi->SetMute(true);
- bCommand = true;
- }
- else if (_strnicmp(pszCommand, "!unmute ", 8) == 0)
- {
- PlayerInfo* ppi = FindPlayer(pszCommand + 8);
- if (ppi)
- ppi->SetMute(false);
- bCommand = true;
- }
- #ifdef _DEBUG
- else if (_strnicmp(pszCommand, "!chatcountdown ", 8) == 0)
- {
- int i = atoi(pszCommand + strlen("!chatcountdown "));
- char cbTemp[20];
- for (; i > 0; i--)
- {
- SendChat(m_ship, CHAT_EVERYONE, NA, NA, _itoa(i, cbTemp, 10));
- // send the messages every so often so that we don't overflow the
- // send buffer
- if (i % 16 == 0)
- SendMessages();
- }
- bCommand = true;
- }
- #endif
- return bCommand;
- }
- void BaseClient::SendChat(IshipIGC* pshipSender,
- ChatTarget ctRecipient,
- ObjectID oidRecipient,
- SoundID soundID,
- const char* pszText,
- CommandID cid,
- ObjectType otTarget,
- ObjectID oidTarget,
- ImodelIGC* pmodelTarget,
- bool bObjectModel)
- {
- if (oidRecipient == NA)
- {
- //Convert from NA to an actual ID based on the player's ship
- switch (ctRecipient)
- {
- case CHAT_INDIVIDUAL:
- oidRecipient = m_ship->GetObjectID();
- break;
- case CHAT_WING:
- oidRecipient = m_ship->GetWingID();
- break;
- case CHAT_TEAM:
- oidRecipient = m_ship->GetSide()->GetObjectID();
- break;
- case CHAT_ALL_SECTOR:
- case CHAT_FRIENDLY_SECTOR:
- {
- IclusterIGC* pcluster = GetChatCluster();
- if (pcluster)
- oidRecipient = pcluster->GetObjectID();
- else
- {
- oidRecipient = m_ship->GetSide()->GetObjectID();
- ctRecipient = CHAT_TEAM;
- }
- }
- break;
- }
- }
- if ((ctRecipient == CHAT_INDIVIDUAL) || (ctRecipient == CHAT_GROUP) || (ctRecipient == CHAT_GROUP_NOECHO))
- {
- IshipIGC* pship = m_pCoreIGC->GetShip(oidRecipient);
- if ((pship == NULL) || (pship->GetMission() == NULL))
- return; //Don't bother to send to the dead
- // do the right thing for training missions
- PilotType pilotType = pship->GetPilotType();
- if ((!m_fm.IsConnected ()) && (pilotType < c_ptPlayer) && (cid != c_cidNone))
- {
- if ((cid == c_cidDefault) && (pmodelTarget != NULL))
- {
- cid = c_cidGoto;
- if (ctRecipient == CHAT_INDIVIDUAL)
- {
- switch (pilotType)
- {
- case c_ptMiner:
- case c_ptBuilder:
- {
- if ((pmodelTarget->GetObjectType() == OT_asteroid) && ((IasteroidIGC*) pmodelTarget)->HasCapability(pship->GetOrdersABM()))
- {
- cid = (pilotType == c_ptMiner) ? c_cidMine : c_cidBuild;
- }
- }
- break;
- case c_ptLayer:
- {
- if (pmodelTarget->GetObjectType() == OT_buoy)
- {
- cid = c_cidBuild;
- }
- }
- break;
- case c_ptWingman:
- {
- if (pmodelTarget->GetSide() == pship->GetSide ())
- cid = c_cidDefend;
- else
- cid = c_cidAttack;
- }
- }
- }
- }
- pship->SetCommand (c_cmdCurrent, pmodelTarget, cid);
- pship->SetCommand (c_cmdAccepted, pmodelTarget, cid);
- //ReceiveChat (m_ship, ctRecipient, oidRecipient, soundID, pszText, cid, otTarget, oidTarget, pmodelTarget);
- }
- }
- //Don't bother sending messages to the server if there is no server or the message it to ourself
- if (m_fm.IsConnected() &&
- (ctRecipient != CHAT_NOSELECTION) &&
- ((ctRecipient != CHAT_INDIVIDUAL) ||
- (oidRecipient != m_ship->GetObjectID())))
- {
- SetMessageType(BaseClient::c_mtGuaranteed);
- ChatData* pcd;
- if (otTarget == OT_buoy)
- {
- BEGIN_PFM_CREATE(m_fm, pfmChatBuoy, CS, CHATBUOY)
- FM_VAR_PARM(pszText, CB_ZTS)
- END_PFM_CREATE
- pcd = &(pfmChatBuoy->cd);
- assert (pmodelTarget);
- pmodelTarget->Export(&(pfmChatBuoy->db));
- }
- else
- {
- BEGIN_PFM_CREATE(m_fm, pfmChatMessage, CS, CHATMESSAGE)
- FM_VAR_PARM(pszText, CB_ZTS)
- END_PFM_CREATE
- pcd = &(pfmChatMessage->cd);
- pfmChatMessage->otTarget = otTarget;
- pfmChatMessage->oidTarget = oidTarget;
- }
- //Don't bother to set the sender
- pcd->chatTarget = ctRecipient;
- pcd->oidRecipient = oidRecipient;
- pcd->commandID = cid;
- pcd->voiceOver = soundID;
- pcd->bObjectModel = bObjectModel;
- }
- //We always get chats we send
- if (ctRecipient != CHAT_GROUP_NOECHO)
- {
- ReceiveChat(pshipSender,
- ctRecipient, oidRecipient,
- soundID, pszText,
- cid, otTarget, oidTarget, pmodelTarget, bObjectModel);
- }
- }
- void BaseClient::ScrollChatUp(void)
- {
- if (m_plinkSelectedChat == NULL)
- m_plinkSelectedChat = m_chatList.last();
- else if (m_plinkSelectedChat != m_chatList.first())
- m_plinkSelectedChat = m_plinkSelectedChat->txen();
- }
- void BaseClient::ScrollChatDown(void)
- {
- if (m_plinkSelectedChat != NULL)
- m_plinkSelectedChat = m_plinkSelectedChat->next();
- }
- ChatInfo* BaseClient::GetCurrentMessage(void)
- {
- ChatLink* l = (m_plinkSelectedChat != NULL)
- ? m_plinkSelectedChat
- : m_chatList.last();
- return l ? &(l->data()) : NULL;
- }
- BallotInfo* BaseClient::GetCurrentBallot()
- {
- Time now = Time::Now();
- // remove any expired ballots before the first valid ballot
- while (!m_listBallots.IsEmpty() && m_listBallots.GetFront().GetBallotExpirationTime() < now)
- m_listBallots.PopFront();
- if (m_listBallots.IsEmpty())
- return NULL;
- else
- return &(m_listBallots.GetFront());
- }
- void BaseClient::Vote(bool bAgree)
- {
- if (!m_listBallots.IsEmpty())
- {
- // compose a vote message
- SetMessageType(c_mtGuaranteed);
- BEGIN_PFM_CREATE(m_fm, pfmVote, C, VOTE)
- END_PFM_CREATE
- pfmVote->ballotID = m_listBallots.GetFront().GetBallotID();
- pfmVote->bAgree = bAgree;
- m_listBallots.PopFront();
- }
- }
- void BaseClient::SkipCurrentBallot()
- {
- if (!m_listBallots.IsEmpty())
- {
- m_listBallots.PopFront();
- }
- }
- Money BaseClient::GetBucketStatus(StationID stationID, short iBucket)
- {
- TRef<BucketStatusArray> prgStatus;
- if (m_mapBucketStatusArray.Find(stationID, prgStatus))
- return (*prgStatus)[iBucket];
- else
- return 0;
- }
- Money BaseClient::AddMoneyToBucket(IbucketIGC* b,
- Money m)
- {
- assert (b);
- Money spent = b->AddMoney(m);
- SetMoney(GetMoney() - spent);
- if (m_fm.IsConnected())
- {
- SetMessageType(c_mtGuaranteed);
- BEGIN_PFM_CREATE(m_fm, pfmBD, C, BUCKET_DONATE)
- END_PFM_CREATE
- pfmBD->moneyGiven = spent;
- pfmBD->iBucket = b->GetObjectID();
- }
- return spent;
- }
- void BaseClient::DonateMoney(PlayerInfo* pPlayerInfo, Money money)
- {
- if (m_fm.IsConnected())
- {
- SetMessageType(c_mtGuaranteed);
- BEGIN_PFM_CREATE(m_fm, pfmDonate, C, PLAYER_DONATE)
- END_PFM_CREATE
- pfmDonate->moneyGiven = money;
- pfmDonate->shipID = pPlayerInfo->ShipID();
- }
- // the recipients money changes
- pPlayerInfo->SetMoney(pPlayerInfo->GetMoney() + money);
- m_pClientEventSource->OnMoneyChange(pPlayerInfo);
- // and my money changes
- SetMoney(GetMoney() - money);
- }
- MissionInfo* BaseClient::GetLobbyMission(DWORD dwCookie)
- {
- MissionInfo* pMissionInfo = NULL;
- if (!m_mapMissions.Find(dwCookie, pMissionInfo))
- {
- pMissionInfo = new MissionInfo(dwCookie);
- m_mapMissions.Set(dwCookie, pMissionInfo);
- }
- return pMissionInfo;
- }
- PlayerLink* BaseClient::FindPlayerLink(ShipID shipID)
- {
- PlayerLink* l = m_listPlayers.first();
- while ((l != NULL) && (l->data().ShipID() != shipID))
- l = l->next();
- return l;
- }
- PlayerInfo* BaseClient::FindAndCreatePlayerLink(ShipID shipID)
- {
- PlayerLink* l = FindPlayerLink(shipID);
- if (l == NULL)
- {
- l = new PlayerLink;
- m_listPlayers.last(l);
- }
- return &(l->data ());
- }
- PlayerInfo* BaseClient::FindPlayer(ShipID shipID)
- {
- PlayerLink* l = FindPlayerLink(shipID);
- return l ? &(l->data()) : NULL;
- }
- PlayerInfo* BaseClient::FindPlayer(const char* szName)
- {
- PlayerInfo* p = NULL;
- for (PlayerLink* l = m_listPlayers.first(); (l != NULL); l = l->next())
- {
- if (_stricmp(l->data().CharacterName(), szName) == 0)
- {
- p = &(l->data());
- break;
- }
- }
- return p;
- }
- PlayerInfo* BaseClient::FindPlayerByPrefix(const char* szNamePrefix)
- {
- PlayerInfo* p = NULL;
- int lenNamePrefix = strlen(szNamePrefix);
- for (PlayerLink* l = m_listPlayers.first(); (l != NULL); l = l->next())
- {
- PlayerInfo& player = l->data();
- if (_strnicmp(player.CharacterName(), szNamePrefix, lenNamePrefix) == 0)
- {
- p = &player;
- break;
- }
- }
- return p;
- }
- namespace {
- // remove trailing whitespaces from a string
- void RemoveTrailingSpaces(char* sz)
- {
- for (int nIndex = strlen(sz); nIndex > 0 && sz[nIndex - 1] == ' '; --nIndex)
- {
- sz[nIndex - 1] = '\0';
- }
- };
- }
- ZString BaseClient::LookupRankName(RankID rank, CivID civ)
- {
- const char* szRankNameTemplate = "Unknown (%d)";
- int nClosestRank = -1;
- if (m_cRankInfo <= 0 || !GetIsZoneClub())
- {
- assert(!m_fm.IsConnected() || !GetIsZoneClub());
- szRankNameTemplate = "";
- }
- else
- {
- // 'slow', but probably still fast enough
- for (int iEntry = 0; iEntry < m_cRankInfo; iEntry++)
- {
- if (m_vRankInfo[iEntry].civ == civ
- && m_vRankInfo[iEntry].rank <= rank
- && m_vRankInfo[iEntry].rank >= nClosestRank)
- {
- szRankNameTemplate = m_vRankInfo[iEntry].RankName;
- nClosestRank = m_vRankInfo[iEntry].rank;
- }
- }
- assert(nClosestRank >= 0);
- }
- char cbTemp[c_cbName + 8];
- wsprintf(cbTemp, szRankNameTemplate, rank - nClosestRank + 1);
- RemoveTrailingSpaces(cbTemp);
- return cbTemp;
- }
- List* BaseClient::GetMissionList()
- {
- return m_plistMissions;
- }
- void BaseClient::QuitMission()
- {
- // Create and queue the message to the server
- BaseClient::SetMessageType(c_mtGuaranteed);
- BEGIN_PFM_CREATE(*GetNetwork(), pfmQuitMission, CS, QUIT_MISSION)
- END_PFM_CREATE
- pfmQuitMission->shipID = GetShipID();
- pfmQuitMission->reason = QSR_Quit;
- }
- bool BaseClient::MyMissionInProgress()
- {
- if (m_pMissionInfo)
- return m_pMissionInfo->InProgress();
- else
- return false;
- }
- void BaseClient::SaveSquadMemberships(const char* szCharacterName)
- {
- }
- void BaseClient::RestoreSquadMemberships(const char* szCharacterName)
- {
- }
- bool BaseClient::HasPlayerSquad(MissionInfo* pMission)
- {
- for (TList<SquadMembership>::Iterator iterSquad(m_squadmemberships);
- !iterSquad.End(); iterSquad.Next())
- {
- if (pMission->HasSquad(iterSquad.Value().GetID()))
- return true;
- }
- return false;
- }
- void BaseClient::SendAllMissions(IClientEventSink* pSink)
- {
- TMapListWrapper<DWORD, MissionInfo*>::Iterator iterMissions(m_mapMissions);
- MissionInfo* pMissionInfo;
- while (!iterMissions.End())
- {
- pMissionInfo = iterMissions.Value();
- pSink->OnAddMission(pMissionInfo);
- iterMissions.Next();
- }
- }
- void BaseClient::SendAllPlayers(IClientEventSink* pSink, MissionInfo* pMissionInfo, SideID sideID)
- {
- if (pMissionInfo)
- {
- ShipList::Iterator iterPlayers(pMissionInfo->GetSideInfo(sideID)->GetMembers());
- PlayerInfo* pPlayerInfo;
- ShipID shipID;
- while (!iterPlayers.End())
- {
- shipID = iterPlayers.Value();
- if (pPlayerInfo = FindPlayer(shipID))
- pSink->OnAddPlayer(pMissionInfo, sideID, pPlayerInfo);
- iterPlayers.Next();
- }
- }
- }
- void BaseClient::SendAllRequests(IClientEventSink* pSink, MissionInfo* pMissionInfo, SideID sideID)
- {
- ShipList::Iterator iterRequests(pMissionInfo->GetSideInfo(sideID)->GetRequests());
- PlayerInfo* pPlayerInfo;
- ShipID shipID;
- while (!iterRequests.End())
- {
- shipID = iterRequests.Value();
- if (pPlayerInfo = FindPlayer(shipID))
- pSink->OnAddRequest(pMissionInfo, sideID, pPlayerInfo);
- iterRequests.Next();
- }
- }
- //
- // IgcSite implementation.
- //
- void BaseClient::TerminateModelEvent(ImodelIGC* pModel)
- {
- ObjectType type = pModel->GetObjectType();
- if (type != OT_projectile) //can never target projectiles
- {
- //Clean up any references to the model
- {
- bool fChanges = false;
- for (ChatLink* l = m_chatList.first();
- (l != NULL);
- l = l->next())
- {
- ChatInfo& cw = l->data();
- if (cw.GetTarget() == pModel)
- {
- cw.ClearTarget();
- fChanges = true;
- }
- }
- if (fChanges)
- m_pClientEventSource->OnChatMessageChange();
- }
- for (Command i = 0; (i < c_cmdMax); i++)
- {
- if (m_ship->GetCommandTarget(i) == pModel)
- m_ship->SetCommand(i, NULL, c_cidNone);
- }
- if (pModel == m_pmodelServerTarget)
- m_pmodelServerTarget = NULL;
- }
- m_pClientEventSource->OnModelTerminated(pModel);
- }
- void BaseClient::LoadoutChangeEvent(IshipIGC* pship, IpartIGC* ppart, LoadoutChange lc)
- {
- if (m_ship->GetSourceShip() == pship)
- m_pClientEventSource->OnLoadoutChanged(ppart, lc);
- }
- void BaseClient::BucketChangeEvent(BucketChange bc, IbucketIGC* b)
- {
- m_pClientEventSource->OnBucketChange(bc, b);
- }
- void BaseClient::SideBuildingTechChange(IsideIGC* s)
- {
- SideID sid = s->GetObjectID();
- m_pClientEventSource->OnTechTreeChanged(sid);
- }
- void BaseClient::SideDevelopmentTechChange(IsideIGC* s)
- {
- SideID sid = s->GetObjectID();
- m_pClientEventSource->OnTechTreeChanged(sid);
- }
- void BaseClient::StationTypeChange(IstationIGC* s)
- {
- SideID sid = s->GetSide()->GetObjectID();
- m_pClientEventSource->OnTechTreeChanged(sid);
- }
- static ItreasureIGC* CreateTreasure(BaseClient* pClient, Time now, IshipIGC* pship, IpartIGC* p, IpartTypeIGC* ppt, const Vector& position, float dv)
- {
- assert (ppt);
- assert (dv > 1.0f);
- assert (pship);
- DataTreasureIGC dt;
- dt.treasureCode = c_tcPart;
- dt.treasureID = ppt->GetObjectID();
- dt.objectID = pClient->m_pCoreIGC->GenerateNewTreasureID();
- dt.p0 = position;
- Vector direction;
- {
- //Get a nice random 3D direction
- direction.z = random(-1.0f, 1.0f);
- float yaw = random(0.0f, pi);
- float cosPitch = (float)sqrt(1.0f - direction.z * direction.z);
- direction.x = cos(yaw) * cosPitch;
- direction.y = sin(yaw) * cosPitch;
- }
- float radius = pship->GetRadius() + 10.0f;
- dt.p0 += radius * direction;
- dt.v0 = direction * dv + pship->GetVelocity();
- switch (ppt->GetEquipmentType())
- {
- case ET_Magazine:
- case ET_Dispenser:
- {
- assert (p);
- dt.amount = ((IlauncherIGC*)p)->GetAmount();
- }
- break;
- case ET_Pack:
- {
- DataPackTypeIGC* pdp = (DataPackTypeIGC*)(ppt->GetData());
- dt.amount = pdp->amount;
- }
- break;
- default:
- dt.amount = 0;
- }
- dt.lifespan = 600.0f;
- IclusterIGC* pcluster = pship->GetCluster();
- dt.clusterID = pcluster->GetObjectID();
- dt.createNow = false;
- dt.time0 = pClient->ServerTimeFromClientTime(now);
- ItreasureIGC* t = (ItreasureIGC *)
- pClient->m_pCoreIGC->CreateObject(now, OT_treasure,
- &dt, sizeof(dt));
- //Note: bad form releasing a pointer before we return it but we know it will
- //stick around since it is in a cluster.
- assert (t);
- t->Release();
- return t;
- }
- void BaseClient::KillAsteroidEvent(IasteroidIGC* pasteroid, bool explodeF)
- {
- if (!m_fm.IsConnected())
- {
- if (explodeF)
- pasteroid->GetCluster()->GetClusterSite()->AddExplosion(pasteroid, c_etAsteroid);
- pasteroid->Terminate();
- }
- }
- void BaseClient::KillProbeEvent(IprobeIGC* pprobe)
- {
- if (!m_fm.IsConnected())
- pprobe->Terminate();
- }
- void BaseClient::KillMineEvent(ImineIGC* pmine)
- {
- if (!m_fm.IsConnected())
- pmine->Terminate();
- }
- void BaseClient::KillMissileEvent(ImissileIGC* pmissile, const Vector& position)
- {
- if (!m_fm.IsConnected())
- {
- pmissile->Explode(position);
- pmissile->Terminate();
- }
- else
- pmissile->Disarm();
- }
- void BaseClient::KillShipEvent(Time now, IshipIGC* pShip, ImodelIGC* pLauncher, float flAmount, const Vector& p1, const Vector& p2)
- {
- if (!m_fm.IsConnected())
- {
- // commented because these are causing performance problems after a while BSW 10/27/1999
- /*
- //Blow the parts into space
- {
- const PartListIGC* plist = pShip->GetParts();
- PartLinkIGC* plink;
- while (plink = plist->first()) //Not ==
- {
- IpartIGC* p = plink->data();
- CreateTreasure(this, now, pShip, p, p->GetPartType(),
- p1, 100.0f);
- p->Terminate();
- }
- //Treasures for ammo
- {
- int ammo = pShip->GetAmmo();
- if (ammo > 0)
- {
- IpartTypeIGC* pptAmmo = m_pCoreIGC->GetAmmoPack();
- assert (pptAmmo);
- ItreasureIGC* t = CreateTreasure(this, now, pShip, NULL, pptAmmo, p1, 100.0f);
- assert (t);
- int a = t->GetAmount();
- assert (a > 0);
- if (ammo <= a)
- {
- t->SetAmount((short)ammo);
- }
- pShip->SetAmmo(0);
- }
- }
- //Ditto for fuel
- {
- int fuel = int(pShip->GetFuel());
- if (fuel > 0)
- {
- IpartTypeIGC* pptFuel = m_pCoreIGC->GetFuelPack();
- assert (pptFuel);
- ItreasureIGC* t = CreateTreasure(this, now, pShip, NULL, pptFuel, p1, 100.0f);
- assert (t);
- int f = t->GetAmount();
- assert (f > 0);
- if (fuel <= f)
- {
- t->SetAmount((short)fuel);
- }
- }
- pShip->SetFuel(0.0f);
- }
- }
- */
- if (pShip == m_ship->GetSourceShip())
- {
- //Eject the player
- Vector v = pShip->GetVelocity();
- pShip->SetBaseHullType(pShip->GetSide()->GetCivilization()->GetLifepod());
- Vector f = Vector::RandomDirection();
- Orientation o;
- if (pLauncher)
- {
- if (pLauncher->GetCluster() == pShip->GetCluster())
- {
- Vector dp = (pLauncher->GetPosition() - p1).Normalize();
- o.Set(dp);
- f = (f + dp * 8.0f).Normalize();
- }
- else
- {
- o.Set(f);
- }
- }
- else
- {
- Vector dp = (p2 - p1).Normalize();
- o.Set(dp);
- f = (f + dp * 8.0f).Normalize();
- }
- v -= f * 100.0f;
- //Put a spin on the ship as it leaves the bad guys.
- pShip->SetCurrentTurnRate(c_axisRoll, pi * 2.0f);
- pShip->SetPosition(p1);
- pShip->SetVelocity(v);
- pShip->SetOrientation(o);
- pShip->SetBB(now, now, 0.0f);
- EjectPlayer(pLauncher);
- }
- else
- {
- PlayerInfo* pPlayerInfo = reinterpret_cast<PlayerInfo*> (pShip->GetPrivateData ());
- RemovePlayerFromSide (pPlayerInfo, QSR_Quit);
- RemovePlayerFromMission (pPlayerInfo, QSR_Quit);
- }
- }
- }
- void BaseClient::DamageStationEvent(IstationIGC* pStation,
- ImodelIGC* pLauncher,
- DamageTypeID type,
- float flAmount,
- float flLeakage)
- {
- if ((NULL != pStation->GetCluster()) &&
- (pStation->GetCluster() == GetCluster()))
- {
- if (pStation->GetShieldFraction() < 0.0f)
- this->PlaySoundEffect(otherHullHitSound, pStation);
- else
- this->PlaySoundEffect(otherShieldHitSound, pStation);
- }
- }
- void BaseClient::KillStationEvent(IstationIGC* pStation,
- ImodelIGC* pLauncher,
- float flAmount,
- float flLeakage)
- {
- if (!m_fm.IsConnected())
- {
- pStation->GetCluster()->GetClusterSite()->AddExplosion(pStation, c_etLargeStation);
- pStation->Terminate();
- }
- }
- void BaseClient::FireMissile(IshipIGC* pShip,
- ImagazineIGC* pMagazine,
- Time timeFired,
- ImodelIGC* pTarget,
- float flLock)
- {
- assert (pShip == m_ship);
- if (pTarget &&
- ((pTarget->GetCluster() != m_ship->GetCluster()) ||
- !m_ship->CanSee(pTarget)))
- pTarget = NULL;
- this->PlaySoundEffect(pMagazine->GetMissileType()->GetLaunchSound(), pShip);
- this->PlayFFEffect(effectFire);
- IclusterIGC* pCluster = pShip->GetCluster();
- assert (pCluster);
- const Vector& myVelocity = pShip->GetVelocity();
- const Orientation& myOrientation = pShip->GetOrientation();
- Vector myPosition = pShip->GetPosition() +
- pMagazine->GetEmissionPt() * myOrientation;
- int iNumMissiles = pMagazine->GetLaunchCount ();
- int iNumRemainingMissiles = pMagazine->GetAmount ();
- Time lastUpdate = pShip->GetLastUpdate();
- if (iNumRemainingMissiles < iNumMissiles)
- iNumMissiles = iNumRemainingMissiles;
- iNumRemainingMissiles -= iNumMissiles;
- DataMissileIGC dataMissile;
- dataMissile.pmissiletype = pMagazine->GetMissileType();
- dataMissile.pLauncher = pShip;
- dataMissile.pTarget = pTarget;
- dataMissile.pCluster = pCluster;
- dataMissile.lock = flLock;
- Vector vecLaunchPosition = myPosition + (myVelocity * (timeFired - lastUpdate));
- Vector vecLaunchForward = myOrientation.GetForward();
- Vector vecLaunchVelocity = myVelocity;
- MissileLaunchData* missileLaunchData = new MissileLaunchData[iNumMissiles];
- // disperse the missiles over the launch region
- float fDispersion = dataMissile.pmissiletype->GetDispersion();
- float fDispersionBase = -fDispersion;
- float fUniformDispersion = (2.0f * fDispersion) / (float) iNumMissiles;
- float fHalfUniformDispersion = fUniformDispersion * 0.5f;
- for (int i = 0; i < iNumMissiles; i++)
- {
- missileLaunchData[i].vecForward = vecLaunchForward;
- if (fDispersion != 0.0f)
- {
- float fRandomDispersion = (random (-0.75f, 0.75f) * fHalfUniformDispersion) + (fDispersionBase + fHalfUniformDispersion);
- fDispersionBase += fUniformDispersion;
- missileLaunchData[i].vecForward += fRandomDispersion * myOrientation.GetRight();
- missileLaunchData[i].vecForward += (random (-0.1f, 0.1f) * fDispersion) * myOrientation.GetUp();
- missileLaunchData[i].vecForward.SetNormalize();
- }
- ZRetailAssert(missileLaunchData[i].vecForward * missileLaunchData[i].vecForward >= 0.95f);
- ZRetailAssert(missileLaunchData[i].vecForward * missileLaunchData[i].vecForward <= 1.05f);
- missileLaunchData[i].vecPosition = vecLaunchPosition + (missileLaunchData[i].vecForward * (dataMissile.pmissiletype->GetInitialSpeed() * random (0.1f, 0.2f)));
- ZRetailAssert(missileLaunchData[i].vecPosition * missileLaunchData[i].vecPosition >= 0.0f);
- ZRetailAssert(missileLaunchData[i].vecPosition * missileLaunchData[i].vecPosition <= 4.0e10f);
- missileLaunchData[i].vecVelocity = vecLaunchVelocity + (dataMissile.pmissiletype->GetInitialSpeed() * missileLaunchData[i].vecForward);
- ZRetailAssert(missileLaunchData[i].vecVelocity * missileLaunchData[i].vecVelocity >= 0.0f);
- ZRetailAssert(missileLaunchData[i].vecVelocity * missileLaunchData[i].vecVelocity <= 1.0e6);
- }
- if (!m_fm.IsConnected())
- {
- for (i = 0; i < iNumMissiles; i++)
- {
- dataMissile.position = missileLaunchData[i].vecPosition;
- dataMissile.forward = missileLaunchData[i].vecForward;
- dataMissile.velocity = missileLaunchData[i].vecVelocity;
- dataMissile.missileID = m_pCoreIGC->GenerateNewMissileID ();
- dataMissile.bDud = false;
- ImissileIGC* m = (ImissileIGC*)(m_pCoreIGC->CreateObject(timeFired, OT_missile, &dataMissile, sizeof(dataMissile)));
- assert (m != NULL);
- m->Release();
- }
- }
- else
- {
- //Tell the server (& everyone else) to fire a missile
- SetMessageType(c_mtGuaranteed);
- BEGIN_PFM_CREATE(m_fm, pfmFM, CS, FIRE_MISSILE)
- FM_VAR_PARM(missileLaunchData, sizeof(MissileLaunchData) * iNumMissiles)
- END_PFM_CREATE
- if (NULL != pTarget)
- {
- pfmFM->targetType = pTarget->GetObjectType();
- pfmFM->targetID = pTarget->GetObjectID();
- }
- else
- {
- pfmFM->targetType = OT_invalid;
- pfmFM->targetID = NA;
- }
- pfmFM->clusterID = pCluster->GetObjectID();
- pfmFM->lock = flLock;
- pfmFM->timeFired = ServerTimeFromClientTime(timeFired);
- //Don't bother to set the ship, missile or missile type ID ... the server will set them
- }
- delete missileLaunchData;
- pMagazine->SetAmount (iNumRemainingMissiles);
- if (0 == iNumRemainingMissiles)
- {
- //
- // Nothing left ... nuke it (which may also cause it to be
- // released & deleted).
- //
- if (Reload(pShip, pMagazine, ET_Magazine))
- {
- PlayNotificationSound(salReloadingMissilesSound, GetShip());
- PlaySoundEffect(startReloadSound, GetShip());
- PostText(false, "Reloading missiles...");
- }
- else
- {
- PlayNotificationSound(salMissilesDepletedSound, GetShip());
- PostText(false, "Missiles depleted.");
- }
- }
- }
- void BaseClient::FireExpendable(IshipIGC* pShip,
- IdispenserIGC* pDispenser,
- Time timeFired)
- {
- assert (pShip == m_ship);
- this->PlayFFEffect(effectFire, pShip);
- IclusterIGC* pCluster = pShip->GetCluster();
- assert (pCluster);
- IexpendableTypeIGC* pet = pDispenser->GetExpendableType();
- ObjectType type = pet->GetObjectType();
- switch (type)
- {
- case OT_chaffType:
- this->PlaySoundEffect(deployChaffSound, pShip);
- break;
- case OT_mineType:
- this->PlaySoundEffect(deployMineSound, pShip);
- break;
- case OT_probeType:
- this->PlaySoundEffect(deployProbeSound, pShip);
- break;
- }
- if (!m_fm.IsConnected())
- {
- const Vector& myPosition = pShip->GetPosition();
- const Vector& myVelocity = pShip->GetVelocity();
- if (type == OT_chaffType)
- {
- assert (type == OT_chaffType);
- //Drop the chaff "behind" the player's ship
- DataChaffIGC dataChaff;
- dataChaff.time0 = timeFired;
- dataChaff.p0 = myPosition;
- dataChaff.v0 = myVelocity + pShip->GetOrientation().GetUp() * 25.0f;
- dataChaff.pcluster = pCluster;
- dataChaff.pchafftype = (IchaffTypeIGC*)pet;
- IchaffIGC* c = (IchaffIGC*)(m_pCoreIGC->CreateObject(timeFired,
- OT_chaff,
- &dataChaff,
- sizeof(dataChaff)));
- assert (c != NULL);
- c->Release();
- }
- else
- {
- float speed2 = myVelocity.LengthSquared();
- float offset = (pet->GetRadius() + pShip->GetRadius()) + 5.0f;
- Vector displace = (speed2 < 1.0f)
- ? (pShip->GetOrientation().GetBackward() * offset)
- : (myVelocity * (-offset / float(sqrt(speed2))));
- Vector launchPosition = myPosition + displace;
- if (type == OT_mineType)
- {
- DataMineIGC dataMine;
- dataMine.pminetype = (ImineTypeIGC*)pet;
- dataMine.time0 = timeFired + 3.0f; //And the count shall be 3.
- dataMine.p0 = launchPosition;
- dataMine.exportF = false;
- dataMine.pshipLauncher = pShip;
- dataMine.pcluster = pCluster;
- dataMine.mineID = m_pCoreIGC->GenerateNewMineID();
- ImineIGC* m = (ImineIGC*)(m_pCoreIGC->CreateObject(timeFired,
- OT_mine,
- &dataMine,
- sizeof(dataMine)));
- assert (m != NULL);
- m->Release();
- }
- else if (type == OT_probeType)
- {
- //Drop the probe "behind" the player's ship
- DataProbeIGC dataProbe;
- dataProbe.pprobetype = (IprobeTypeIGC*)pet;
- dataProbe.time0 = timeFired;
- dataProbe.p0 = launchPosition;
- dataProbe.exportF = false;
- dataProbe.pcluster = pCluster;
- dataProbe.pside = pShip->GetSide();
- dataProbe.pship = pShip;
- dataProbe.pmodelTarget = pShip->GetCommandTarget(c_cmdCurrent);
- dataProbe.probeID = m_pCoreIGC->GenerateNewProbeID();
- IprobeIGC* p = (IprobeIGC*)(m_pCoreIGC->CreateObject(timeFired,
- OT_probe,
- &dataProbe,
- sizeof(dataProbe)));
- assert (p != NULL);
- p->Release();
- }
- }
- }
- else
- {
- //Tell the server to fire an expendable
- SetMessageType(c_mtGuaranteed);
- BEGIN_PFM_CREATE(m_fm, pfmFE, C, FIRE_EXPENDABLE)
- END_PFM_CREATE
- pfmFE->et = pet->GetEquipmentType();
- }
- short amount = pDispenser->GetAmount() - 1;
- pDispenser->SetAmount(amount);
- if (0 == amount)
- {
- //
- // Nothing left ... nuke it (which may also cause it to be
- // released & deleted).
- //
- if (Reload(pShip, pDispenser, pet->GetEquipmentType()))
- {
- switch (pet->GetObjectType())
- {
- case OT_chaffType:
- PlayNotificationSound(salReloadingChaffSound, GetShip());
- PostText(false, "Reloading chaff...");
- break;
- default:
- PlayNotificationSound(salReloadingDispenserSound, GetShip());
- PostText(false, "Reloading dispenser...");
- break;
- }
- PlaySoundEffect(startReloadSound, GetShip());
- }
- else
- {
- switch (pet->GetObjectType())
- {
- case OT_chaffType:
- PlayNotificationSound(salChaffDepletedSound, GetShip());
- PostText(false, "Chaff depleted.");
- break;
- default:
- PlayNotificationSound(salDispenserEmptySound, GetShip());
- PostText(false, "Dispenser empty.");
- break;
- }
- }
- }
- }
- bool BaseClient::Reload(IshipIGC* pship, IlauncherIGC* plauncher, EquipmentType type)
- {
- int nReloads = 0;
- if (pship == m_ship)
- {
- const int c_MaxReloads = 8;
- ReloadData reloads[c_MaxReloads];
- const IhullTypeIGC* pht = pship->GetHullType();
- switch (type)
- {
- case ET_Weapon:
- case ET_Afterburner:
- {
- PackType ptDesired;
- short ammo;
- short maxAmmo;
- if (type == ET_Weapon)
- {
- ptDesired = c_packAmmo;
- ammo = pship->GetAmmo();
- maxAmmo = pht->GetMaxAmmo();
- }
- else
- {
- ptDesired = c_packFuel;
- ammo = short(pship->GetFuel());
- maxAmmo = short(pht->GetMaxFuel());
- }
- while (ammo < maxAmmo)
- {
- /*
- //Find the ammo/fuel pack with the least amount of ammo/fuel in it (first if all the same)
- IpackIGC* ppack = NULL;
- short amount = 0x7fff;
- {
- for (Mount i = -1; (i >= -c_maxCargo); i--)
- {
- IpartIGC* ppart = pship->GetMountedPart(NA, i);
- if (ppart && (ppart->GetObjectType() == OT_pack))
- {
- IpackIGC* p = (IpackIGC*)ppart;
- if (p->GetPackType() == ptDesired)
- {
- short a = p->GetAmount();
- if (a < amount)
- {
- ppack = p;
- amount = a;
- }
- }
- }
- }
- }
- */
- // Find the last ammo/fuel pack (avoids mysterious behavior in inventory pane)
- IpackIGC* ppack = NULL;
- short amount = 0x7fff;
- {
- for (Mount i = -1; (i >= -c_maxCargo); i--)
- {
- IpartIGC* ppart = pship->GetMountedPart(NA, i);
- if (ppart && (ppart->GetObjectType() == OT_pack))
- {
- IpackIGC* p = (IpackIGC*)ppart;
- if (p->GetPackType() == ptDesired)
- {
- ppack = p;
- amount = p->GetAmount();
- }
- }
- }
- }
- if (ppack)
- {
- reloads[nReloads].mount = ppack->GetMountID();
- short transfer;
- if (ammo + amount > maxAmmo)
- {
- //There will be stuff left in the pack
- transfer = maxAmmo - ammo;
- ammo = maxAmmo;
- ppack->SetAmount(amount - transfer);
- }
- else
- {
- //Entire pack gets trasnfered
- transfer = NA;
- ammo += amount;
- ppack->Terminate();
- }
- reloads[nReloads++].amountTransfered = transfer;
- }
- else
- break;
- }
- if (nReloads != 0)
- {
- if (type == ET_Weapon)
- {
- pship->SetAmmo(ammo);
- //disable all mounted weapons that use ammo
- Mount maxWeapons = pht->GetMaxWeapons();
- for (Mount i = 0; (i < maxWeapons); i++)
- {
- IweaponIGC* pw = (IweaponIGC*)(pship->GetMountedPart(ET_Weapon, i));
- if (pw && (pw->GetAmmoPerShot() != 0))
- pw->SetMountedFraction(0.0f);
- }
- }
- else
- {
- pship->SetFuel(float(ammo));
- //disable the afterburner
- IpartIGC* p = pship->GetMountedPart(ET_Afterburner, 0);
- if (p)
- p->SetMountedFraction(0.0f);
- }
- }
- }
- break;
- case ET_Magazine:
- case ET_Dispenser:
- case ET_ChaffLauncher:
- {
- IpartTypeIGC* pparttype;
- short ammo;
- short maxAmmo;
- if (plauncher)
- {
- pparttype = plauncher->GetPartType();
- ammo = plauncher->GetAmount();
- maxAmmo = ((IlauncherTypeIGC*)pparttype)->GetAmount(pship);
- }
- else
- {
- pparttype = NULL;
- ammo = 0;
- maxAmmo = 0x7fff;
- }
- while (ammo < maxAmmo)
- {
- IlauncherIGC* plauncherReload = NULL;
- IpartTypeIGC* pptReload;
- short amount = 0x7fff;
- {
- for (Mount mount = -1; (mount >= -c_maxCargo); mount--)
- {
- IpartIGC* p = pship->GetMountedPart(NA, mount);
- if (p && (p->GetEquipmentType() == type))
- {
- IpartTypeIGC* ppt = p->GetPartType();
- if (pht->CanMount(ppt, 0))
- {
- short a = ((IlauncherIGC*)p)->GetAmount();
- assert (a > 0);
- if (pparttype == NULL)
- {
- //when one has nothing ... one will pick anything
- reloads[nReloads].amountTransfered = NA;
- reloads[nReloads++].mount = mount;
- if (plauncher)
- plauncher->Terminate();
- p->SetMountID(0);
- plauncher = (IlauncherIGC*)p;
- pparttype = plauncher->GetPartType();
- ammo = plauncher->GetAmount();
- assert (ammo > 0);
- maxAmmo = ((IlauncherTypeIGC*)pparttype)->GetAmount(pship);
- assert (plauncherReload == NULL);
- if (ammo == maxAmmo)
- break; //No point in continuing if we are full up
- }
- else if ((ppt == pparttype) /*&& (a < amount)*/)
- {
- plauncherReload = (IlauncherIGC*)p;
- pptReload = ppt;
- amount = a;
- }
- }
- }
- }
- }
- if (plauncherReload)
- {
- reloads[nReloads].mount = plauncherReload->GetMountID();
- short transfer;
- if (ammo + amount <= maxAmmo)
- {
- transfer = amount;
- plauncherReload->Terminate();
- }
- else
- {
- transfer = maxAmmo - ammo;
- plauncherReload->SetAmount(amount - transfer);
- }
- ammo += transfer;
- plauncher->SetAmount(ammo);
- plauncher->SetMountedFraction(0.0f);
- plauncher->ResetTimeLoaded();
- reloads[nReloads++].amountTransfered = transfer;
- }
- else if (pparttype && (ammo == 0))
- {
- //Couldn't find a way to reload the existing launcher
- //try again being less picky
- assert (plauncher);
- pparttype = NULL;
- maxAmmo = 0x7fff;
- }
- else
- break;
- }
- }
- break;
- }
- if (m_fm.IsConnected())
- {
- if (nReloads > 0)
- {
- int size = sizeof(ReloadData) * nReloads;
- SetMessageType(c_mtGuaranteed);
- BEGIN_PFM_CREATE(m_fm, pfmReload, CS, RELOAD)
- FM_VAR_PARM(NULL, size)
- END_PFM_CREATE
- memcpy(FM_VAR_REF(pfmReload, rgReloads), reloads, size);
- }
- else if (plauncher && (plauncher->GetAmount() == 0))
- {
- SetMessageType(c_mtGuaranteed);
- BEGIN_PFM_CREATE(m_fm, pfmDrop, CS, DROP_PART)
- END_PFM_CREATE
- pfmDrop->et = plauncher->GetEquipmentType();
- pfmDrop->mount = plauncher->GetMountID();
- plauncher->Terminate();
- }
- }
- }
- return nReloads > 0;
- }
- void BaseClient::OnQuitSide()
- {
- m_bInGame = false;
- m_bWaitingForGameRestart = false;
- if (IsLockedDown())
- EndLockDown(lockdownDonating | lockdownLoadout | lockdownTeleporting);
- // clear any team chats, in case they join another team
- ChatLink* lChat = m_chatList.first();
- while (lChat != NULL)
- {
- ChatLink* lChatPrev = lChat;
- lChat = lChat->next();
- if (lChatPrev->data().GetChatTarget() != CHAT_EVERYONE)
- delete lChatPrev;
- }
- // nuke any saved player status information
- // (in case they rejoin this game on a different side)
- PlayerLink* l = m_listPlayers.first();
- while (l != NULL)
- {
- PlayerInfo& playerCurrent = l->data();
- playerCurrent.ResetShipStatus();
- l = l->next();
- }
- assert (m_ship->GetStation() == NULL);
- assert (m_ship->GetCluster() == NULL);
- {
- // set all ships to the null sector
- ShipLinkIGC* plinkShip = m_pCoreIGC->GetShips()->first();
- while (plinkShip)
- {
- plinkShip->data()->SetCluster(NULL);
- plinkShip = plinkShip->next();
- }
- }
- // nuke all clusters
- SetViewCluster(NULL);
- m_pCoreIGC->ResetMission();
- // nuke any pending votes
- m_listBallots.SetEmpty();
- };
- void BaseClient::OnJoinSide()
- {
- ResetShip();
- m_strBriefingText.SetEmpty();
- m_bGenerateCivBriefing = false;
- if (m_pPlayerInfo->SideID() != SIDE_TEAMLOBBY)
- SetMoney(m_pPlayerInfo->GetMoney());
- if (m_pMissionInfo->InProgress())
- {
- m_pCoreIGC->SetMissionStage(STAGE_STARTED);
- }
- m_pClientEventSource->OnChatMessageChange();
- m_plinkSelectedChat = NULL;
- // if this is the lobby side, we need to manually send the OnAddPlayer message
- if (m_pPlayerInfo->SideID() == SIDE_TEAMLOBBY)
- m_pClientEventSource->OnAddPlayer(m_pMissionInfo, m_pPlayerInfo->SideID(), m_pPlayerInfo);
- };
- void BaseClient::OnQuitMission(QuitSideReason reason, const char* szMessageParam)
- {
- Disconnect();
- // clear chat messages
- m_chatList.purge(true);
- m_pClientEventSource->OnClearChat();
- m_ship->AddRef();
- {
- // destroy all ships
- ShipLinkIGC* plinkShip = m_pCoreIGC->GetShips()->first();
- while (plinkShip)
- {
- ShipLinkIGC* lNext = plinkShip->next();
- IshipIGC* s = plinkShip->data();
- plinkShip->data()->Terminate();
- plinkShip = lNext;
- }
- }
- m_ship->Release();
- CreateDummyShip();
- {
- // and sides
- const SideListIGC * pSides = m_pCoreIGC->GetSides();
- SideLinkIGC * pSidelink = NULL;
- while (pSidelink = pSides->first())
- pSidelink->data()->Terminate();
- }
- {
- // and players...
- m_listPlayers.purge(true);
- m_pPlayerInfo = NULL;
- }
- delete m_pMissionInfo;
- m_pMissionInfo = NULL;
- };
- void BaseClient::OnEnterGame()
- {
- m_pCoreIGC->EnterGame();
- m_bInGame = true;
- m_pClientEventSource->OnEnterMission();
- };
- void BaseClient::CreateDummyShip()
- {
- // create a (no-hull) ship for the player
- DataShipIGC ds;
- ds.hullID = NA;
- ds.shipID = NA;
- ds.nParts = 0;
- ds.sideID = NA;
- ds.name[0] = '\0';
- //ds.wingID = 0;
- ds.pilotType = c_ptCheatPlayer;
- ds.abmOrders = 0;
- ds.nDeaths = 0;
- ds.nEjections = 0;
- ds.nKills = 0;
- ds.baseObjectID = NA;
- // Allow the ship data to be modified by derived classes
- ModifyShipData(&ds);
- m_ship = (IshipIGC*)(m_pCoreIGC->CreateObject(m_lastSend, OT_ship, &ds, sizeof(ds)));
- assert (m_ship);
- m_ship->Release();
- };
- void BaseClient::DestroyDummyShip()
- {
- // Base class does nothing
- }
- void BaseClient::RemovePlayerFromSide(PlayerInfo* pPlayerInfo, QuitSideReason reason, const char* szMessageParam)
- {
- if (!pPlayerInfo)
- {
- assert(false);
- return;
- }
- ZAssert(pPlayerInfo->SideID() != SIDE_TEAMLOBBY && pPlayerInfo->SideID() != NA);
- SideID sideOld = pPlayerInfo->SideID();
- ZAssert(pPlayerInfo->SideID() != NA);
- pPlayerInfo->SetReady(true);
- pPlayerInfo->SetTeamLeader(false);
- pPlayerInfo->SetMissionOwner(false);
- pPlayerInfo->Reset(false);
- if (STAGE_STARTED != m_pMissionInfo->GetStage())
- pPlayerInfo->GetShip()->SetExperience(1.0f);
- m_pClientEventSource->OnMoneyChange(pPlayerInfo);
- m_pMissionInfo->RemovePlayer(pPlayerInfo);
- m_pClientEventSource->OnDelPlayer(m_pMissionInfo, pPlayerInfo->SideID(), pPlayerInfo, reason);
- IshipIGC* pship = m_pCoreIGC->GetShip(pPlayerInfo->ShipID());
- pship->SetSide(NULL);
- if (pPlayerInfo == m_pPlayerInfo)
- {
- OnQuitSide();
- }
- else
- {
- if (pPlayerInfo->IsHuman() && (m_pMissionInfo->GetStage() == STAGE_STARTED) && (m_fm.IsConnected ()))
- {
- ZString msg;
- // tell the player that someone has just quit their team
- if (m_pPlayerInfo->SideID() == sideOld)
- {
- switch (reason)
- {
- case QSR_LeaderBooted:
- msg = pPlayerInfo->CharacterName() + ZString(" was booted from the team by the team leader.");
- ReceiveChat(NULL, CHAT_TEAM, NA, salQuitSound, msg, c_cidNone, NA, NA);
- break;
- case QSR_OwnerBooted:
- msg = pPlayerInfo->CharacterName() + ZString(" was booted from the game by the mission owner.");
- ReceiveChat(NULL, CHAT_TEAM, NA, salQuitSound, msg, c_cidNone, NA, NA);
- break;
- case QSR_AdminBooted:
- msg = pPlayerInfo->CharacterName() + ZString(" was booted from the team by an admin.");
- ReceiveChat(NULL, CHAT_TEAM, NA, salQuitSound, msg, c_cidNone, NA, NA);
- break;
- case QSR_ServerShutdown:
- break;
- case QSR_SquadChange:
- msg = pPlayerInfo->CharacterName() + ZString(" was booted because of a squad change.");
- ReceiveChat(NULL, CHAT_TEAM, NA, salQuitSound, msg, c_cidNone, NA, NA);
- break;
- case QSR_SideDestroyed:
- break;
- case QSR_RankLimits:
- msg = pPlayerInfo->CharacterName() + ZString(" was booted because he/she did not meet the new rank limits.");
- ReceiveChat(NULL, CHAT_TEAM, NA, salQuitSound, msg, c_cidNone, NA, NA);
- break;
- case QSR_TeamSizeLimits:
- msg = pPlayerInfo->CharacterName() + ZString(" was booted to reduce the team size within it's new limits.");
- ReceiveChat(NULL, CHAT_TEAM, NA, salQuitSound, msg, c_cidNone, NA, NA);
- break;
- case QSR_Quit:
- msg = pPlayerInfo->CharacterName() + ZString(" has quit.");
- ReceiveChat(NULL, CHAT_TEAM, NA, salQuitSound, msg, c_cidNone, NA, NA);
- break;
- case QSR_SwitchingSides:
- msg = pPlayerInfo->CharacterName() + ZString(" is switching sides.");
- ReceiveChat(NULL, CHAT_TEAM, NA, salChangeSidesSound, msg, c_cidNone, NA, NA);
- break;
- case QSR_DuplicateLocalLogon:
- case QSR_DuplicateCDKey:
- // don't send a chat in case they were dropped.
- //msg = pPlayerInfo->CharacterName() + ZString(" has been booted due to a duplicate logon.");
- //ReceiveChat(NULL, CHAT_TEAM, NA, salQuitSound, msg, c_cidNone, NA, NA);
- break;
- case QSR_RandomizeSides:
- break;
- case QSR_DuplicateRemoteLogon:
- msg = pPlayerInfo->CharacterName() + ZString(" has been booted due to a duplicate logon.");
- ReceiveChat(NULL, CHAT_TEAM, NA, salQuitSound, msg, c_cidNone, NA, NA);
- break;
- default:
- ZAssert(false);
- // intentional fallthrough
- case QSR_LinkDead:
- msg = pPlayerInfo->CharacterName() + ZString(" is MIA.");
- ReceiveChat(NULL, CHAT_TEAM, NA, salMIASound, msg, c_cidNone, NA, NA);
- break;
- };
- }
- else
- {
- msg = pPlayerInfo->CharacterName() + ZString(" has left ")
- + GetCore()->GetSide(sideOld)->GetName() + ZString(".");
- ReceiveChat(NULL, CHAT_TEAM, NA, salEnemyLeavesSound, msg, c_cidNone, NA, NA);
- }
- }
- }
- pPlayerInfo->SetTeamLeader(false);
- pPlayerInfo->SetMissionOwner(false);
- pPlayerInfo->SetSideID(SIDE_TEAMLOBBY);
- pPlayerInfo->SetMoney(0);
- IsideIGC* pside = m_pCoreIGC->GetSide(SIDE_TEAMLOBBY);
- pship->SetSide(pside);
-
- if (pPlayerInfo == m_pPlayerInfo)
- {
- ResetShip();
- m_pClientEventSource->OnChatMessageChange();
- m_plinkSelectedChat = NULL;
- }
- m_pMissionInfo->AddPlayer(pPlayerInfo);
- // if this is the lobby side, we need to manually send the OnAddPlayer message
- if (m_pPlayerInfo->SideID() == SIDE_TEAMLOBBY)
- m_pClientEventSource->OnAddPlayer(m_pMissionInfo, pPlayerInfo->SideID(), pPlayerInfo);
- }
- void BaseClient::RemovePlayerFromMission(PlayerInfo* pPlayerInfo, QuitSideReason reason, const char* szMessageParam)
- {
- if (!pPlayerInfo)
- {
- assert(false);
- return;
- }
- // must call RemovePlayerFromSide first if the player is not on the team lobby
- ZAssert(pPlayerInfo->SideID() == SIDE_TEAMLOBBY);
- assert(pPlayerInfo);
-
- m_pMissionInfo->RemovePlayer(pPlayerInfo);
- pPlayerInfo->SetReady(true);
- if (pPlayerInfo == m_pPlayerInfo)
- {
- // we need to manually send the DelPlayerMessage
- m_pClientEventSource->OnDelPlayer(m_pMissionInfo, pPlayerInfo->SideID(), pPlayerInfo, reason);
- }
- pPlayerInfo->SetSideID(NA);
- IshipIGC* pship = pPlayerInfo->GetShip();
-
- pship->SetSide(NULL);
- if (pPlayerInfo != m_pPlayerInfo)
- {
- // destroy their ship and player info
- pship->Terminate();
- PlayerLink* l = FindPlayerLink(pPlayerInfo->ShipID());
- delete l;
- }
- else
- {
- // we are quitting the mission...
- OnQuitMission(reason, szMessageParam);
- }
- }
- void BaseClient::AddPlayerToMission(PlayerInfo* pPlayerInfo)
- {
- assert(pPlayerInfo);
- pPlayerInfo->SetSideID(SIDE_TEAMLOBBY);
- IshipIGC* pship = pPlayerInfo->GetShip();
- IsideIGC* pside = m_pCoreIGC->GetSide(SIDE_TEAMLOBBY);
- pship->SetSide(pside);
- if (pPlayerInfo == m_pPlayerInfo)
- {
- m_pCoreIGC->SetMissionParams(&(m_pMissionInfo->GetMissionParams()));
- m_pCoreIGC->UpdateSides(Time::Now(), &(m_pMissionInfo->GetMissionParams()), m_pMissionInfo->GetMissionDef().rgszName);
- OnJoinSide();
- }
- m_pMissionInfo->AddPlayer(pPlayerInfo);
- }
- void BaseClient::AddPlayerToSide(PlayerInfo* pPlayerInfo, SideID sideID)
- {
- assert(pPlayerInfo);
- assert(pPlayerInfo->SideID() == SIDE_TEAMLOBBY);
- SideID sideOld = pPlayerInfo->SideID();
- m_pMissionInfo->RemovePlayer(pPlayerInfo);
- assert(pPlayerInfo->GetMoney() == 0);
- pPlayerInfo->SetReady(true);
- if (pPlayerInfo == m_pPlayerInfo)
- {
- OnQuitSide();
- }
- pPlayerInfo->SetSideID(sideID);
- IshipIGC* pship = pPlayerInfo->GetShip();
- IsideIGC* pside = m_pCoreIGC->GetSide(sideID);
- pship->SetSide(pside);
- if (pPlayerInfo == m_pPlayerInfo)
- {
- OnJoinSide();
- }
- m_pMissionInfo->AddPlayer(pPlayerInfo);
- if (pPlayerInfo->IsTeamLeader())
- m_pMissionInfo->SetSideLeader(pPlayerInfo);
- // now officially on team so remove any requests to this mission
- if (m_pMissionInfo->FindRequest(pPlayerInfo->SideID(), pPlayerInfo->ShipID()))
- m_pMissionInfo->RemoveRequest(pPlayerInfo->SideID(), pPlayerInfo->ShipID());
- // don't notify... notification assumed in OnAddPlayer
- // update the last seen info
- pPlayerInfo->ResetShipStatus();
- m_pClientEventSource->OnAddPlayer(m_pMissionInfo, pPlayerInfo->SideID(), pPlayerInfo);
- if (pPlayerInfo->IsHuman() && m_pMissionInfo->GetStage() == STAGE_STARTED && m_fm.IsConnected())
- {
- // tell the players that someone has just joined their team
- if ((m_pPlayerInfo != pPlayerInfo) && (m_pPlayerInfo->SideID() == pPlayerInfo->SideID()))
- {
- ZString msg = pPlayerInfo->CharacterName() + ZString(" has joined your team.");
- ReceiveChat(NULL, CHAT_TEAM, NA, salRecruitsArrivedSound, msg, c_cidNone, NA, NA);
- }
- else if (m_pPlayerInfo && GetSide() && GetSideID() != SIDE_TEAMLOBBY)
- {
- ZString msg = pPlayerInfo->CharacterName() + ZString(" has joined ")
- + pside->GetName() + ZString(".");
- ReceiveChat(NULL, CHAT_TEAM, NA, salEnemyJoinersSound, msg, c_cidNone, NA, NA);
- }
- }
- }
- /*-------------------------------------------------------------------------
- * ResetStaticData
- *-------------------------------------------------------------------------
- Purpose:
- Out with the old IGC data, in with the new
- Parameters:
- IGC staic file to load
- Returns:
- whether data set was successfully loaded
- Side Effects:
- Old data set is nuked (better not have any references to IGC stuff when calling this)
- */
- static void DoDecrypt(int size, char* pdata)
- {
- DWORD encrypt = 0;
- //Do a rolling XOR to demunge the data
- for (int i = 0; (i < size); i += 4)
- {
- DWORD* p = (DWORD*)(pdata + size);
- encrypt = *p = *p ^ encrypt;
- }
- }
- bool BaseClient::ResetStaticData(const char * szIGCStaticFile, ImissionIGC** ppStaticIGC, Time tNow, bool bEncrypt)
- {
- assert(ppStaticIGC);
- if (&m_pCoreIGC == ppStaticIGC)
- {
- FlushGameState();
- *ppStaticIGC = CreateMission();
- Initialize(tNow);
- }
- else
- {
- // In this special case, the static mission must have already been created and initialized
- assert(*ppStaticIGC);
- }
- // copy the core name
- lstrcpy(m_szIGCStaticFile, szIGCStaticFile);
- // here we load the static core data
- int iStaticCoreVersion = LoadIGCStaticCore (szIGCStaticFile, *ppStaticIGC, true); // first just check version
- // only reload the static igc core if this game uses a different one
- if (iStaticCoreVersion != m_pMissionInfo->GetIGCStaticVer())
- {
- return false;
- }
- // actually load the data
- LoadIGCStaticCore (szIGCStaticFile, *ppStaticIGC, false, bEncrypt ? DoDecrypt : NULL); // then actually load the data
- return true;
- }
- void BaseClient::StartLockDown(const ZString& strReason, LockdownCriteria criteria)
- {
- ZAssert((m_lockdownCriteria & criteria) == 0);
-
- m_lockdownCriteria |= criteria;
- m_strLockDownReason = strReason;
- }
- void BaseClient::EndLockDown(LockdownCriteria criteria)
- {
- ZAssert(m_lockdownCriteria != 0);
- m_lockdownCriteria &= ~criteria;
- }
- void BaseClient::BoardShip(IshipIGC* pship)
- {
- SetMessageType(BaseClient::c_mtGuaranteed);
- BEGIN_PFM_CREATE(m_fm, pfmBoardShip, C, BOARD_SHIP)
- END_PFM_CREATE
- pfmBoardShip->sidParent = pship ? pship->GetObjectID() : NA;
- if (pship)
- {
- assert(GetShip()->GetParentShip() == NULL);
- StartLockDown("Boarding " + ZString(pship->GetName()) + "'s ship....", lockdownTeleporting);
- }
- else
- {
- IshipIGC* pshipParent = GetShip()->GetParentShip();
- assert(pshipParent);
- StartLockDown("Disembarking from " + ZString(pshipParent->GetName()) + "'s ship....", lockdownTeleporting);
- }
- }
- void CfgInfo::Load(const char * szConfig)
- {
- const char * c_szCfgApp = "Allegiance";
- char szStr[128]; // random number;
-
- GetPrivateProfileString(c_szCfgApp, "ZAuth", "auth.zone.com",
- szStr, sizeof(szStr), szConfig);
- strZAuth = szStr;
- GetPrivateProfileString(c_szCfgApp, "ClubLobby", "",
- szStr, sizeof(szStr), szConfig);
- strClubLobby = szStr;
- GetPrivateProfileString(c_szCfgApp, "PublicLobby", "",
- szStr, sizeof(szStr), szConfig);
- strPublicLobby = szStr;
- GetPrivateProfileString(c_szCfgApp, "Club", "",
- szStr, sizeof(szStr), szConfig);
- strClub = szStr;
- GetPrivateProfileString(c_szCfgApp, "ClubMessageURL", "http://fdl.msn.com/zone/allegiance/messageoftheday.mdl", // http://a-markcu1/test/messageoftheday.mdl
- szStr, sizeof(szStr), szConfig);
- strClubMessageURL = szStr;
- GetPrivateProfileString(c_szCfgApp, "PublicMessageURL", "http://fdl.msn.com/zone/allegiance/messageoftheday.mdl", // http://a-markcu1/test/messageoftheday.mdl
- szStr, sizeof(szStr), szConfig);
- strPublicMessageURL = szStr;
- GetPrivateProfileString(c_szCfgApp, "ZoneEventsURL", "", szStr, sizeof(szStr), szConfig);
- strZoneEventsURL = szStr;
- GetPrivateProfileString(c_szCfgApp, "ZoneEventDetailsURL", "http://fdl.msn.com/zone/allegiance/zoneevents.mdl",
- szStr, sizeof(szStr), szConfig);
- strZoneEventDetailsURL = szStr;
- GetPrivateProfileString(c_szCfgApp, "TrainingURL", "http://www.zone.com/allegiance/downloads.asp",
- szStr, sizeof(szStr), szConfig);
- strTrainingURL = szStr;
- GetPrivateProfileString(c_szCfgApp, "PassportUpdateURL", "http://www.zone.com/allegiance/passportupdate.html",
- szStr, sizeof(szStr), szConfig);
- strPassportUpdateURL = szStr;
- GetPrivateProfileString(c_szCfgApp, "ZoneAuthGUID", "{00000000-0000-0000-C000-000000000046}",
- szStr, sizeof(szStr), szConfig);
- int cbStr = strlen(szStr) + 1;
- LPOLESTR wszStr = (LPOLESTR)_alloca(sizeof(OLECHAR) * cbStr);
- MultiByteToWideChar(CP_ACP, 0, PCC(szStr), cbStr, wszStr, cbStr);
- if (cbStr == 1 || !ZSucceeded(IIDFromString(wszStr, &guidZoneAuth)))
- {
- guidZoneAuth = GUID_NULL;
- }
- GetPrivateProfileString(c_szCfgApp, "FilelistCRC", "0",
- szStr, sizeof(szStr), szConfig);
- _strupr(szStr);
- crcFileList = UTL::hextoi(szStr);
- if (crcFileList == 0)
- debugf("FilelistCRC is missing or invalid from %s.\n", szConfig);
- GetPrivateProfileString(c_szCfgApp, "FilelistSize", "0",
- szStr, sizeof(szStr), szConfig);
- nFilelistSize = atoi(szStr);
- if (nFilelistSize == 0)
- debugf("FilelistSize is missing or invalid from %s.\n", szConfig);
- GetPrivateProfileString(c_szCfgApp, "FilelistSite", "",
- szStr, sizeof(szStr), szConfig);
- strFilelistSite = szStr;
-
- GetPrivateProfileString(c_szCfgApp, "FilelistDirectory", "",
- szStr, sizeof(szStr), szConfig);
- strFilelistDirectory = szStr;
- GetPrivateProfileString(c_szCfgApp, "ClubMessageCRC", "0",
- szStr, sizeof(szStr), szConfig);
- _strupr(szStr);
- crcClubMessageFile = UTL::hextoi(szStr);
- GetPrivateProfileString(c_szCfgApp, "PublicMessageCRC", "0",
- szStr, sizeof(szStr), szConfig);
- _strupr(szStr);
- crcPublicMessageFile = UTL::hextoi(szStr);
- GetPrivateProfileString(c_szCfgApp, "UsePassport", "0",
- szStr, sizeof(szStr), szConfig);
- bUsePassport = atoi(szStr) != 0;
- }
- void _debugf(const char* format, ...)
- {
- const size_t size = 512;
- char bfr[size];
- va_list vl;
- va_start(vl, format);
- _vsnprintf(bfr, size, format, vl);
- va_end(vl);
- debugf(bfr);
- }
|