| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853 |
- /*
- * Copyright (c) 2014, Oculus VR, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
- #include "NativeFeatureIncludes.h"
- #if _RAKNET_SUPPORT_TeamManager==1
- #include "TeamManager.h"
- #include "BitStream.h"
- #include "MessageIdentifiers.h"
- #include "GetTime.h"
- using namespace RakNet;
- enum TeamManagerOperations
- {
- ID_RUN_UpdateListsToNoTeam,
- ID_RUN_UpdateTeamsRequestedToAny,
- ID_RUN_JoinAnyTeam,
- ID_RUN_JoinRequestedTeam,
- ID_RUN_UpdateTeamsRequestedToNoneAndAddTeam,
- ID_RUN_RemoveFromTeamsRequestedAndAddTeam,
- ID_RUN_AddToRequestedTeams,
- ID_RUN_LeaveTeam,
- ID_RUN_SetMemberLimit,
- ID_RUN_SetJoinPermissions,
- ID_RUN_SetBalanceTeams,
- ID_RUN_SetBalanceTeamsInitial,
- ID_RUN_SerializeWorld,
- };
- STATIC_FACTORY_DEFINITIONS(TM_TeamMember,TM_TeamMember);
- STATIC_FACTORY_DEFINITIONS(TM_Team,TM_Team);
- STATIC_FACTORY_DEFINITIONS(TeamManager,TeamManager);
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- int TM_World::JoinRequestHelperComp(const TM_World::JoinRequestHelper &key, const TM_World::JoinRequestHelper &data)
- {
- if (key.whenRequestMade < data.whenRequestMade)
- return -1;
- if (key.whenRequestMade > data.whenRequestMade)
- return 1;
- if (key.requestIndex < data.requestIndex)
- return -1;
- if (key.requestIndex > data.requestIndex)
- return 1;
- return 0;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- TeamSelection::TeamSelection() {}
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- TeamSelection::TeamSelection(JoinTeamType itt) : joinTeamType(itt) {}
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- TeamSelection::TeamSelection(JoinTeamType itt, TM_Team *param) : joinTeamType(itt) {teamParameter.specificTeamToJoin=param;}
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- TeamSelection::TeamSelection(JoinTeamType itt, NoTeamId param) : joinTeamType(itt) {teamParameter.noTeamSubcategory=param;}
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- TeamSelection TeamSelection::AnyAvailable(void) {return TeamSelection(JOIN_ANY_AVAILABLE_TEAM);}
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- TeamSelection TeamSelection::SpecificTeam(TM_Team *specificTeamToJoin) {return TeamSelection(JOIN_SPECIFIC_TEAM, specificTeamToJoin);}
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- TeamSelection TeamSelection::NoTeam(NoTeamId noTeamSubcategory) {return TeamSelection(JOIN_NO_TEAM, noTeamSubcategory);}
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- TM_TeamMember::TM_TeamMember()
- {
- networkId=0;
- world=0;
- joinTeamType=JOIN_NO_TEAM;
- noTeamSubcategory=0;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- TM_TeamMember::~TM_TeamMember()
- {
- if (world)
- {
- world->DereferenceTeamMember(this);
- }
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- bool TM_TeamMember::RequestTeam(TeamSelection teamSelection)
- {
- if (teamSelection.joinTeamType==JOIN_NO_TEAM)
- {
- // If joining no team:
- // - If already no team, and no team category is the same, return false.
- // - Execute JoinNoTeam() locally. Return ID_TEAM_BALANCER_TEAM_ASSIGNED locally.
- // - If we are host, broadcast event. Done.
- // - Send to remote host event to call JoinNoTeam()
- // - remote Host executes JoinNoTeam() and broadcasts event. This may cause may cause rebalance if team balancing is on.
- // - - JoinNoTeam(): Remove from all current and requested teams. Set no-team category.
- if (teams.Size()==0 && noTeamSubcategory==teamSelection.teamParameter.noTeamSubcategory)
- {
- // No change
- return false;
- }
- BitStream bsOut;
- bsOut.WriteCasted<MessageID>(ID_TEAM_BALANCER_INTERNAL);
- bsOut.WriteCasted<MessageID>(ID_RUN_UpdateListsToNoTeam);
- bsOut.Write(world->GetWorldId());
- bsOut.Write(networkId);
- bsOut.Write(teamSelection.teamParameter.noTeamSubcategory);
- world->BroadcastToParticipants(&bsOut, UNASSIGNED_RAKNET_GUID);
- StoreLastTeams();
- UpdateListsToNoTeam(teamSelection.teamParameter.noTeamSubcategory);
- world->GetTeamManager()->PushTeamAssigned(this);
- if (world->GetHost()==world->GetTeamManager()->GetMyGUIDUnified())
- {
- world->FillRequestedSlots();
- world->EnforceTeamBalance(teamSelection.teamParameter.noTeamSubcategory);
- }
- }
- else if (teamSelection.joinTeamType==JOIN_ANY_AVAILABLE_TEAM)
- {
- // If joining any team
- // Execute JoinAnyTeamCheck()
- // - JoinAnyTeamCheck():
- // - - If already on a team, return false
- // - - If any team is already in requested teams, return false.
- // On local, call UpdateTeamsRequestedToAny(). Send event to also execute this to remote host
- // If we are host, execute JoinAnyTeam(myguid).
- // - JoinAnyTeam(requesterGuid): Attempt to join any team immediately. If fails, send to all except requestGuid UpdateTeamsRequestedToAny(). Else sends out new team, including to caller.
- // On remote host, execute JoinAnyTeamCheck(). If fails, this was because you were added to a team simultaneously on host. This is OK, just ignore the call.
- // Assuming JoinAnyTeamCheck() passed on remote host, call UpdateTeamsRequestedToAny() for this player. execute JoinAnyTeam(packet->guid).
- if (JoinAnyTeamCheck()==false)
- return false;
- UpdateTeamsRequestedToAny();
- // Send request to host to execute JoinAnyTeam()
- BitStream bsOut;
- bsOut.WriteCasted<MessageID>(ID_TEAM_BALANCER_INTERNAL);
- bsOut.WriteCasted<MessageID>(ID_RUN_JoinAnyTeam);
- bsOut.Write(world->GetWorldId());
- bsOut.Write(networkId);
- world->GetTeamManager()->SendUnified(&bsOut,HIGH_PRIORITY, RELIABLE_ORDERED, 0, world->GetHost(), false);
- }
- else
- {
- RakAssert(teamSelection.joinTeamType==JOIN_SPECIFIC_TEAM);
- // If joining specific team
- // Execute JoinSpecificTeamCheck()
- // JoinSpecificTeamCheck():
- // - If already on specific team, return false
- // - If specific team is in requested list, return false
- // On local, call AddToRequestedTeams(). Send event to also execute this to remote host
- // If we are host, execute JoinSpecificTeam(myguid)
- // - JoinSpecificTeam(requesterGuid): Attempt to join specific team immediately. If fails, send to all except requesterGuid to execute AddSpecificToRequested(). Else sends out new team, including to caller.
- // On remote host, execute JoinSpecificTeamCheck(). If fails, just ignore.
- // Assuming JoinSpecificTeamCheck() passed on host, call AddSpecificToRequestedList(). Execute JoinSpecificTeam(packet->guid)
- if (JoinSpecificTeamCheck(teamSelection.teamParameter.specificTeamToJoin,false)==false)
- return false;
- AddToRequestedTeams(teamSelection.teamParameter.specificTeamToJoin);
- // Send request to host to execute JoinRequestedTeam()
- BitStream bsOut;
- bsOut.WriteCasted<MessageID>(ID_TEAM_BALANCER_INTERNAL);
- bsOut.WriteCasted<MessageID>(ID_RUN_JoinRequestedTeam);
- bsOut.Write(world->GetWorldId());
- bsOut.Write(networkId);
- bsOut.Write(teamSelection.teamParameter.specificTeamToJoin->GetNetworkID());
- bsOut.Write(false);
- world->GetTeamManager()->SendUnified(&bsOut,HIGH_PRIORITY, RELIABLE_ORDERED, 0, world->GetHost(), false);
- }
- return true;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- bool TM_TeamMember::RequestTeamSwitch(TM_Team *teamToJoin, TM_Team *teamToLeave)
- {
- if (SwitchSpecificTeamCheck(teamToJoin,teamToLeave,false)==false)
- return false;
- AddToRequestedTeams(teamToJoin, teamToLeave);
- // Send request to host to execute JoinRequestedTeam()
- BitStream bsOut;
- bsOut.WriteCasted<MessageID>(ID_TEAM_BALANCER_INTERNAL);
- bsOut.WriteCasted<MessageID>(ID_RUN_JoinRequestedTeam);
- bsOut.Write(world->GetWorldId());
- bsOut.Write(networkId);
- bsOut.Write(teamToJoin->GetNetworkID());
- bsOut.Write(true);
- if (teamToLeave)
- {
- bsOut.Write(true);
- bsOut.Write(teamToLeave->GetNetworkID());
- }
- else
- {
- bsOut.Write(false);
- }
- world->GetTeamManager()->SendUnified(&bsOut,HIGH_PRIORITY, RELIABLE_ORDERED, 0, world->GetHost(), false);
- return true;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- TeamSelection TM_TeamMember::GetRequestedTeam(void) const
- {
- if (teamsRequested.Size()>0)
- return TeamSelection::SpecificTeam(teamsRequested[0].requested);
- else if (joinTeamType==JOIN_NO_TEAM)
- return TeamSelection::NoTeam(noTeamSubcategory);
- else
- return TeamSelection::AnyAvailable();
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TM_TeamMember::GetRequestedSpecificTeams(DataStructures::List<TM_Team*> &requestedTeams) const
- {
- requestedTeams.Clear(true, _FILE_AND_LINE_);
- for (unsigned int i=0; i < teamsRequested.Size(); i++)
- requestedTeams.Push(teamsRequested[i].requested, _FILE_AND_LINE_);
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- bool TM_TeamMember::HasRequestedTeam(TM_Team *team) const
- {
- unsigned int i = GetRequestedTeamIndex(team);
- if (i==(unsigned int)-1)
- return false;
- return true;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- unsigned int TM_TeamMember::GetRequestedTeamIndex(TM_Team *team) const
- {
- unsigned int i;
- for (i=0; i < teamsRequested.Size(); i++)
- {
- if (teamsRequested[i].requested==team)
- return i;
- }
- return (unsigned int) -1;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- unsigned int TM_TeamMember::GetRequestedTeamCount(void) const
- {
- return teamsRequested.Size();
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- bool TM_TeamMember::CancelTeamRequest(TM_Team *specificTeamToCancel)
- {
- if (RemoveFromRequestedTeams(specificTeamToCancel)==false)
- return false;
- // Send request to host to execute JoinRequestedTeam()
- BitStream bsOut;
- bsOut.WriteCasted<MessageID>(ID_TEAM_BALANCER_TEAM_REQUESTED_CANCELLED);
- bsOut.Write(world->GetWorldId());
- bsOut.Write(networkId);
- if (specificTeamToCancel)
- {
- bsOut.Write(true);
- bsOut.Write(specificTeamToCancel->GetNetworkID());
- }
- else
- {
- bsOut.Write(false);
- }
- world->BroadcastToParticipants(&bsOut, UNASSIGNED_RAKNET_GUID);
- world->GetTeamManager()->PushBitStream(&bsOut);
- return true;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- bool TM_TeamMember::LeaveTeam(TM_Team* team, NoTeamId _noTeamSubcategory)
- {
- if (LeaveTeamCheck(team)==false)
- return false;
- RemoveFromSpecificTeamInternal(team);
- if (teams.Size()==0)
- {
- noTeamSubcategory=_noTeamSubcategory;
- joinTeamType=JOIN_NO_TEAM;
- }
- // Execute LeaveTeamCheck()
- // - LeaveTeamCheck():
- // - - If not on this team, return false
- // On local, call RemoteFromTeamsList(). Send event to also execute this to remote host
- // If we are host, execute OnLeaveTeamEvent(myGuid)
- // - OnLeaveTeamEvent(requesterGuid):
- // - - If rebalancing is active, rebalance
- // - - If someone else wants to join this team, let them.
- // - - Send leave team event notification to all except requesterGuid-
- // On remote host, execute LeaveTeamCheck(). If fails, ignore.
- // On remote host, execute RemoteFromTeamsList() followed by OnLeaveTeamEvent(packet->guid)
- // Pattern:
- // Execute local check, if fails return false
- // Locally execute non-host guaranteed changes
- // If local system is also host, execute host changes. Relay to all but local
- // On remote host, execute check. If check passes, execute non-host changes, followed by host changes. Relay to all but sender.
- BitStream bsOut;
- bsOut.WriteCasted<MessageID>(ID_TEAM_BALANCER_INTERNAL);
- bsOut.WriteCasted<MessageID>(ID_RUN_LeaveTeam);
- bsOut.Write(world->GetWorldId());
- bsOut.Write(networkId);
- bsOut.Write(team->GetNetworkID());
- bsOut.Write(noTeamSubcategory);
- world->BroadcastToParticipants(&bsOut, UNASSIGNED_RAKNET_GUID);
- if (world->GetHost()==world->GetTeamManager()->GetMyGUIDUnified())
- {
- // Rebalance teams
- world->FillRequestedSlots();
- world->EnforceTeamBalance(noTeamSubcategory);
- }
- return true;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- bool TM_TeamMember::LeaveAllTeams(NoTeamId noTeamSubcategory)
- {
- return RequestTeam(TeamSelection::NoTeam(noTeamSubcategory));
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- TM_Team* TM_TeamMember::GetCurrentTeam(void) const
- {
- if (teams.Size()>0)
- return teams[0];
- return 0;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- unsigned int TM_TeamMember::GetCurrentTeamCount(void) const
- {
- return teams.Size();
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- TM_Team* TM_TeamMember::GetCurrentTeamByIndex(unsigned int index)
- {
- return teams[index];
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TM_TeamMember::GetCurrentTeams(DataStructures::List<TM_Team*> &_teams) const
- {
- _teams=teams;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TM_TeamMember::GetLastTeams(DataStructures::List<TM_Team*> &_teams) const
- {
- _teams=lastTeams;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- bool TM_TeamMember::IsOnTeam(TM_Team *team) const
- {
- unsigned int i;
- for (i=0; i < teams.Size(); i++)
- {
- if (teams[i]==team)
- return true;
- }
- return false;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- NetworkID TM_TeamMember::GetNetworkID(void) const
- {
- return networkId;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- TM_World* TM_TeamMember::GetTM_World(void) const
- {
- return world;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TM_TeamMember::SerializeConstruction(BitStream *constructionBitstream)
- {
- // Write requested teams
- constructionBitstream->Write(world->GetWorldId());
- constructionBitstream->Write(networkId);
- constructionBitstream->WriteCasted<uint16_t>(teamsRequested.Size());
- for (unsigned int i=0; i < teamsRequested.Size(); i++)
- {
- constructionBitstream->Write(teamsRequested[i].isTeamSwitch);
- if (teamsRequested[i].teamToLeave)
- {
- constructionBitstream->Write(true);
- constructionBitstream->Write(teamsRequested[i].teamToLeave->GetNetworkID());
- }
- else
- {
- constructionBitstream->Write(false);
- }
- if (teamsRequested[i].requested)
- {
- constructionBitstream->Write(true);
- constructionBitstream->Write(teamsRequested[i].requested->GetNetworkID());
- }
- else
- {
- constructionBitstream->Write(false);
- }
- }
- world->teamManager->EncodeTeamAssigned(constructionBitstream, this);
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- bool TM_TeamMember::DeserializeConstruction(TeamManager *teamManager, BitStream *constructionBitstream)
- {
- // Read requested teams
- bool success;
- uint16_t teamsRequestedSize;
- WorldId worldId;
- constructionBitstream->Read(worldId);
- TM_World *world = teamManager->GetWorldWithId(worldId);
- RakAssert(world);
- constructionBitstream->Read(networkId);
- world->ReferenceTeamMember(this,networkId);
- success=constructionBitstream->Read(teamsRequestedSize);
- for (unsigned int i=0; i < teamsRequestedSize; i++)
- {
- RequestedTeam rt;
- rt.isTeamSwitch=false;
- rt.requested=0;
- rt.whenRequested=0;
- constructionBitstream->Read(rt.isTeamSwitch);
- bool hasTeamToLeave=false;
- constructionBitstream->Read(hasTeamToLeave);
- NetworkID teamToLeaveId;
- if (hasTeamToLeave)
- {
- constructionBitstream->Read(teamToLeaveId);
- rt.teamToLeave = world->GetTeamByNetworkID(teamToLeaveId);
- RakAssert(rt.teamToLeave);
- }
- else
- rt.teamToLeave=0;
- bool hasTeamRequested=false;
- success=constructionBitstream->Read(hasTeamRequested);
- NetworkID teamRequestedId;
- if (hasTeamRequested)
- {
- success=constructionBitstream->Read(teamRequestedId);
- rt.requested = world->GetTeamByNetworkID(teamRequestedId);
- RakAssert(rt.requested);
- }
- rt.whenRequested=RakNet::GetTime();
- rt.requestIndex=world->teamRequestIndex++; // In case whenRequested is the same between two teams when sorting team requests
- if (
- (hasTeamToLeave==false || (hasTeamToLeave==true && rt.teamToLeave!=0)) &&
- (hasTeamRequested==false || (hasTeamRequested==true && rt.requested!=0))
- )
- {
- teamsRequested.Push(rt, _FILE_AND_LINE_);
- }
- }
- if (success)
- world->teamManager->ProcessTeamAssigned(constructionBitstream);
- return success;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void *TM_TeamMember::GetOwner(void) const
- {
- return owner;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TM_TeamMember::SetOwner(void *o)
- {
- owner=o;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- NoTeamId TM_TeamMember::GetNoTeamId(void) const
- {
- return noTeamSubcategory;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- unsigned int TM_TeamMember::GetWorldIndex(void) const
- {
- return world->GetTeamMemberIndex(this);
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- unsigned long TM_TeamMember::ToUint32( const NetworkID &g )
- {
- return g & 0xFFFFFFFF;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TM_TeamMember::UpdateListsToNoTeam(NoTeamId nti)
- {
- teamsRequested.Clear(true, _FILE_AND_LINE_ );
- for (unsigned int i=0; i < teams.Size(); i++)
- {
- teams[i]->RemoveFromTeamMemberList(this);
- }
- teams.Clear(true, _FILE_AND_LINE_ );
- noTeamSubcategory=nti;
- joinTeamType=JOIN_NO_TEAM;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- bool TM_TeamMember::JoinAnyTeamCheck(void) const
- {
- // - - If already on a team, return false
- if (teams.Size() > 0)
- return false;
- // - - If any team is already in requested teams, return false.
- if (teamsRequested.Size()==0 && joinTeamType==JOIN_ANY_AVAILABLE_TEAM)
- return false;
- return true;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- bool TM_TeamMember::JoinSpecificTeamCheck(TM_Team *specificTeamToJoin, bool ignoreRequested) const
- {
- // - If already on specific team, return false
- if (IsOnTeam(specificTeamToJoin))
- return false;
- if (ignoreRequested)
- return true;
- unsigned int i;
- for (i=0; i < teamsRequested.Size(); i++)
- {
- if (teamsRequested[i].requested==specificTeamToJoin)
- {
- if (teamsRequested[i].isTeamSwitch==true)
- return true; // Turn off team switch
- // Same thing
- return false;
- }
- }
- // Not in teams requested
- return true;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- bool TM_TeamMember::SwitchSpecificTeamCheck(TM_Team *teamToJoin, TM_Team *teamToLeave, bool ignoreRequested) const
- {
- RakAssert(teamToJoin!=0);
- // - If already on specific team, return false
- if (IsOnTeam(teamToJoin))
- return false;
- if (teamToLeave!=0 && IsOnTeam(teamToLeave)==false)
- return false;
- if (teamToJoin==teamToLeave)
- return false;
- if (ignoreRequested)
- return true;
- unsigned int i;
- for (i=0; i < teamsRequested.Size(); i++)
- {
- if (teamsRequested[i].requested==teamToJoin)
- {
- if (teamsRequested[i].isTeamSwitch==false)
- return true; // Different - leave team was off, turn on
-
- if (teamsRequested[i].teamToLeave==teamToLeave)
- return false; // Same thing - leave all or a specific team
- // Change leave team
- return true;
- }
- }
- // Not in teams requested
- return true;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- bool TM_TeamMember::LeaveTeamCheck(TM_Team *team) const
- {
- if (IsOnTeam(team)==false)
- return false;
- return true;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TM_TeamMember::UpdateTeamsRequestedToAny(void)
- {
- teamsRequested.Clear(true, _FILE_AND_LINE_);
- joinTeamType=JOIN_ANY_AVAILABLE_TEAM;
- whenJoinAnyRequested=RakNet::GetTime();
- joinAnyRequestIndex=world->teamRequestIndex++; // In case whenRequested is the same between two teams when sorting team requests
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TM_TeamMember::UpdateTeamsRequestedToNone(void)
- {
- teamsRequested.Clear(true, _FILE_AND_LINE_);
- joinTeamType=JOIN_NO_TEAM;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TM_TeamMember::AddToRequestedTeams(TM_Team *teamToJoin)
- {
- RemoveFromRequestedTeams(teamToJoin);
- RequestedTeam rt;
- rt.isTeamSwitch=false;
- rt.requested=teamToJoin;
- rt.teamToLeave=0;
- rt.whenRequested=RakNet::GetTime();
- rt.requestIndex=world->teamRequestIndex++; // In case whenRequested is the same between two teams when sorting team requests
- teamsRequested.Push(rt, _FILE_AND_LINE_ );
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TM_TeamMember::AddToRequestedTeams(TM_Team *teamToJoin, TM_Team *teamToLeave)
- {
- RemoveFromRequestedTeams(teamToJoin);
- RequestedTeam rt;
- rt.isTeamSwitch=true;
- rt.requested=teamToJoin;
- rt.teamToLeave=teamToLeave;
- rt.whenRequested=RakNet::GetTime();
- rt.requestIndex=world->teamRequestIndex++; // In case whenRequested is the same between two teams when sorting team requests
- teamsRequested.Push(rt, _FILE_AND_LINE_ );
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- bool TM_TeamMember::RemoveFromRequestedTeams(TM_Team *team)
- {
- if (team==0)
- {
- teamsRequested.Clear(true, _FILE_AND_LINE_);
- joinTeamType=JOIN_NO_TEAM;
- return true;
- }
- else
- {
- unsigned int i;
- for (i=0; i < teamsRequested.Size(); i++)
- {
- if (teamsRequested[i].requested==team)
- {
- teamsRequested.RemoveAtIndex(i);
- if (teamsRequested.Size()==0)
- {
- joinTeamType=JOIN_NO_TEAM;
- }
- return true;
- }
- }
- }
- return false;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TM_TeamMember::AddToTeamList(TM_Team *team)
- {
- team->teamMembers.Push(this, _FILE_AND_LINE_ );
- teams.Push(team, _FILE_AND_LINE_ );
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TM_TeamMember::RemoveFromSpecificTeamInternal(TM_Team *team)
- {
- unsigned int i,j;
- for (i=0; i < teams.Size(); i++)
- {
- if (teams[i]==team)
- {
- for (j=0; j < team->teamMembers.Size(); j++)
- {
- if (team->teamMembers[j]==this)
- {
- team->teamMembers.RemoveAtIndex(j);
- break;
- }
- }
- teams.RemoveAtIndex(i);
- break;
- }
- }
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TM_TeamMember::RemoveFromAllTeamsInternal(void)
- {
- TM_Team *team;
- unsigned int i,j;
- for (i=0; i < teams.Size(); i++)
- {
- team = teams[i];
- for (j=0; j < team->teamMembers.Size(); j++)
- {
- if (team->teamMembers[j]==this)
- {
- team->teamMembers.RemoveAtIndex(j);
- break;
- }
- }
- }
- teams.Clear(true, _FILE_AND_LINE_);
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TM_TeamMember::StoreLastTeams(void)
- {
- lastTeams=teams;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- TM_Team::TM_Team()
- {
- ID=0;
- world=0;
- joinPermissions=ALLOW_JOIN_ANY_AVAILABLE_TEAM|ALLOW_JOIN_SPECIFIC_TEAM|ALLOW_JOIN_REBALANCING;
- balancingApplies=true;
- teamMemberLimit=65535;
- owner=0;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- TM_Team::~TM_Team()
- {
- if (world)
- world->DereferenceTeam(this, 0);
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- bool TM_Team::SetMemberLimit(TeamMemberLimit _teamMemberLimit, NoTeamId noTeamId)
- {
- if (teamMemberLimit==_teamMemberLimit)
- return false;
- teamMemberLimit=_teamMemberLimit;
- // Network this as request to host
- BitStream bsOut;
- bsOut.WriteCasted<MessageID>(ID_TEAM_BALANCER_INTERNAL);
- bsOut.WriteCasted<MessageID>(ID_RUN_SetMemberLimit);
- bsOut.Write(world->GetWorldId());
- bsOut.Write(GetNetworkID());
- bsOut.Write(teamMemberLimit);
- bsOut.Write(noTeamId);
- world->GetTeamManager()->Send(&bsOut, world->GetHost(), false);
- return true;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- TeamMemberLimit TM_Team::GetMemberLimit(void) const
- {
- if (world->GetBalanceTeams()==false)
- {
- return teamMemberLimit;
- }
- else
- {
- TeamMemberLimit limitWithBalancing=world->GetBalancedTeamLimit();
- if (limitWithBalancing < teamMemberLimit)
- return limitWithBalancing;
- return teamMemberLimit;
- }
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- TeamMemberLimit TM_Team::GetMemberLimitSetting(void) const
- {
- return teamMemberLimit;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- bool TM_Team::SetJoinPermissions(JoinPermissions _joinPermissions)
- {
- if (joinPermissions==_joinPermissions)
- return false;
- joinPermissions=_joinPermissions;
- // Network this as request to host
- BitStream bsOut;
- bsOut.WriteCasted<MessageID>(ID_TEAM_BALANCER_INTERNAL);
- bsOut.WriteCasted<MessageID>(ID_RUN_SetJoinPermissions);
- bsOut.Write(world->GetWorldId());
- bsOut.Write(GetNetworkID());
- bsOut.Write(_joinPermissions);
- world->GetTeamManager()->Send(&bsOut,world->GetHost(), false);
- return true;
-
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- JoinPermissions TM_Team::GetJoinPermissions(void) const
- {
- return joinPermissions;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TM_Team::LeaveTeam(TM_TeamMember* teamMember, NoTeamId noTeamSubcategory)
- {
- teamMember->LeaveTeam(this, noTeamSubcategory);
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- bool TM_Team::GetBalancingApplies(void) const
- {
- return balancingApplies;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TM_Team::GetTeamMembers(DataStructures::List<TM_TeamMember*> &_teamMembers) const
- {
- _teamMembers=teamMembers;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- unsigned int TM_Team::GetTeamMembersCount(void) const
- {
- return teamMembers.Size();
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- TM_TeamMember *TM_Team::GetTeamMemberByIndex(unsigned int index) const
- {
- return teamMembers[index];
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- NetworkID TM_Team::GetNetworkID(void) const
- {
- return ID;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- TM_World* TM_Team::GetTM_World(void) const
- {
- return world;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TM_Team::SerializeConstruction(BitStream *constructionBitstream)
- {
- // Do not need to serialize member lists, the team members do this
- constructionBitstream->Write(world->GetWorldId());
- constructionBitstream->Write(ID);
- constructionBitstream->Write(joinPermissions);
- constructionBitstream->Write(balancingApplies);
- constructionBitstream->Write(teamMemberLimit);
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- bool TM_Team::DeserializeConstruction(TeamManager *teamManager, BitStream *constructionBitstream)
- {
- WorldId worldId;
- constructionBitstream->Read(worldId);
- TM_World *world = teamManager->GetWorldWithId(worldId);
- RakAssert(world);
- constructionBitstream->Read(ID);
- constructionBitstream->Read(joinPermissions);
- constructionBitstream->Read(balancingApplies);
- bool b = constructionBitstream->Read(teamMemberLimit);
- RakAssert(b);
- if (b)
- {
- world->ReferenceTeam(this,ID,balancingApplies);
- }
- return b;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- unsigned long TM_Team::ToUint32( const NetworkID &g )
- {
- return g & 0xFFFFFFFF;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void *TM_Team::GetOwner(void) const
- {
- return owner;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- unsigned int TM_Team::GetWorldIndex(void) const
- {
- return world->GetTeamIndex(this);
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TM_Team::SetOwner(void *o)
- {
- owner=o;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TM_Team::RemoveFromTeamMemberList(TM_TeamMember *teamMember)
- {
- unsigned int index = teamMembers.GetIndexOf(teamMember);
- RakAssert(index != (unsigned int) -1);
- teamMembers.RemoveAtIndex(index);
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- unsigned int TM_Team::GetMemberWithRequestedSingleTeamSwitch(TM_Team *team)
- {
- unsigned int i;
- for (i=0; i < teamMembers.Size(); i++)
- {
- if (teamMembers[i]->GetCurrentTeamCount()==1)
- {
- unsigned int j = teamMembers[i]->GetRequestedTeamIndex(team);
- if (j!=(unsigned int)-1)
- {
- if (teamMembers[i]->teamsRequested[j].isTeamSwitch &&
- (teamMembers[i]->teamsRequested[j].teamToLeave==0 ||
- teamMembers[i]->teamsRequested[j].teamToLeave==teamMembers[i]->teams[0])
- )
- return i;
- }
- }
- }
- return (unsigned int) -1;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- TM_World::TM_World()
- {
- teamManager=0;
- balanceTeamsIsActive=false;
- hostGuid=UNASSIGNED_RAKNET_GUID;
- worldId=0;
- autoAddParticipants=true;
- teamRequestIndex=0;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- TM_World::~TM_World()
- {
- Clear();
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- TeamManager *TM_World::GetTeamManager(void) const
- {
- return teamManager;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TM_World::AddParticipant(RakNetGUID rakNetGUID)
- {
- participants.Push(rakNetGUID, _FILE_AND_LINE_ );
- // Send to remote system status of balanceTeamsIsActive
- if (GetTeamManager()->GetMyGUIDUnified()==GetHost())
- {
- // Actually just transmitting initial value of balanceTeamsIsActive
- BitStream bsOut;
- bsOut.WriteCasted<MessageID>(ID_TEAM_BALANCER_INTERNAL);
- bsOut.WriteCasted<MessageID>(ID_RUN_SetBalanceTeamsInitial);
- bsOut.Write(GetWorldId());
- bsOut.Write(balanceTeamsIsActive);
- teamManager->SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0,rakNetGUID, false);
- }
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TM_World::RemoveParticipant(RakNetGUID rakNetGUID)
- {
- unsigned int i;
- i = participants.GetIndexOf(rakNetGUID);
- if (i!=(unsigned int)-1)
- participants.RemoveAtIndex(i);
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TM_World::SetAutoManageConnections(bool autoAdd)
- {
- autoAddParticipants=autoAdd;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TM_World::GetParticipantList(DataStructures::List<RakNetGUID> &participantList)
- {
- participantList = participants;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TM_World::ReferenceTeam(TM_Team *team, NetworkID networkId, bool applyBalancing)
- {
- unsigned int i;
- for (i=0; i < teams.Size(); i++)
- {
- if (teams[i]==team)
- return;
- }
- team->ID=networkId;
- team->balancingApplies=applyBalancing;
- team->world=this;
- // Add this team to the list of teams
- teams.Push(team, _FILE_AND_LINE_);
- teamsHash.Push(networkId,team,_FILE_AND_LINE_);
- // If autobalancing is on, and the team lock state supports it, then call EnforceTeamBalancing()
- if (applyBalancing && balanceTeamsIsActive)
- {
- EnforceTeamBalance(0);
- }
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TM_World::DereferenceTeam(TM_Team *team, NoTeamId noTeamSubcategory)
- {
- unsigned int i;
- for (i=0; i < teams.Size(); i++)
- {
- if (teams[i]==team)
- {
- TM_Team *team = teams[i];
- while (team->teamMembers.Size())
- {
- team->teamMembers[team->teamMembers.Size()-1]->LeaveTeam(team, noTeamSubcategory);
- }
- teams.RemoveAtIndex(i);
- teamsHash.Remove(team->GetNetworkID(),_FILE_AND_LINE_);
- break;
- }
- }
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- unsigned int TM_World::GetTeamCount(void) const
- {
- return teams.Size();
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- TM_Team *TM_World::GetTeamByIndex(unsigned int index) const
- {
- return teams[index];
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- TM_Team *TM_World::GetTeamByNetworkID(NetworkID teamId)
- {
- DataStructures::HashIndex hi = teamsHash.GetIndexOf(teamId);
- if (hi.IsInvalid())
- return 0;
- return teamsHash.ItemAtIndex(hi);
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- unsigned int TM_World::GetTeamIndex(const TM_Team *team) const
- {
- unsigned int i;
- for (i=0; i < teams.Size(); i++)
- {
- if (teams[i]==team)
- return i;
- }
- return (unsigned int) -1;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TM_World::ReferenceTeamMember(TM_TeamMember *teamMember, NetworkID networkId)
- {
- unsigned int i;
- for (i=0; i < teamMembers.Size(); i++)
- {
- if (teamMembers[i]==teamMember)
- return;
- }
- teamMember->world=this;
- teamMember->networkId=networkId;
- teamMembers.Push(teamMember, _FILE_AND_LINE_);
- teamMembersHash.Push(networkId,teamMember,_FILE_AND_LINE_);
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TM_World::DereferenceTeamMember(TM_TeamMember *teamMember)
- {
- unsigned int i;
- for (i=0; i < teamMembers.Size(); i++)
- {
- if (teamMembers[i]==teamMember)
- {
- teamMembers[i]->UpdateListsToNoTeam(0);
- teamMembersHash.Remove(teamMembers[i]->GetNetworkID(),_FILE_AND_LINE_);
- teamMembers.RemoveAtIndex(i);
- break;
- }
- }
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- unsigned int TM_World::GetTeamMemberCount(void) const
- {
- return teamMembers.Size();
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- TM_TeamMember *TM_World::GetTeamMemberByIndex(unsigned int index) const
- {
- return teamMembers[index];
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- NetworkID TM_World::GetTeamMemberIDByIndex(unsigned int index) const
- {
- return teamMembers[index]->GetNetworkID();
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- TM_TeamMember *TM_World::GetTeamMemberByNetworkID(NetworkID teamMemberId)
- {
- DataStructures::HashIndex hi = teamMembersHash.GetIndexOf(teamMemberId);
- if (hi.IsInvalid())
- return 0;
- return teamMembersHash.ItemAtIndex(hi);
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- unsigned int TM_World::GetTeamMemberIndex(const TM_TeamMember *teamMember) const
- {
- unsigned int i;
- for (i=0; i < teamMembers.Size(); i++)
- {
- if (teamMembers[i]==teamMember)
- return i;
- }
- return (unsigned int) -1;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- bool TM_World::SetBalanceTeams(bool balanceTeams, NoTeamId noTeamId)
- {
- if (balanceTeams==balanceTeamsIsActive)
- return false;
- balanceTeamsIsActive=balanceTeams;
- // Network this as request to host
- BitStream bsOut;
- bsOut.WriteCasted<MessageID>(ID_TEAM_BALANCER_INTERNAL);
- bsOut.WriteCasted<MessageID>(ID_RUN_SetBalanceTeams);
- bsOut.Write(GetWorldId());
- bsOut.Write(balanceTeams);
- bsOut.Write(noTeamId);
- GetTeamManager()->SendUnified(&bsOut,HIGH_PRIORITY, RELIABLE_ORDERED, 0, GetHost(), false);
- return true;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- bool TM_World::GetBalanceTeams(void) const
- {
- return balanceTeamsIsActive;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TM_World::SetHost(RakNetGUID _hostGuid)
- {
- if (hostGuid==_hostGuid)
- return;
- RakAssert(_hostGuid!=UNASSIGNED_RAKNET_GUID);
- hostGuid=_hostGuid;
- if (GetHost()==GetTeamManager()->GetMyGUIDUnified())
- FillRequestedSlots();
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- RakNetGUID TM_World::GetHost(void) const
- {
- return hostGuid;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- WorldId TM_World::GetWorldId(void) const
- {
- return worldId;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TM_World::Clear(void)
- {
- for (unsigned int i=0; i < teams.Size(); i++)
- {
- teams[i]->world=0;
- }
- for (unsigned int i=0; i < teamMembers.Size(); i++)
- {
- teamMembers[i]->world=0;
- }
- participants.Clear(true, _FILE_AND_LINE_);
- teams.Clear(true, _FILE_AND_LINE_);
- teamMembers.Clear(true, _FILE_AND_LINE_);
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TM_World::OnClosedConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason )
- {
- (void) lostConnectionReason;
- (void) systemAddress;
- RemoveParticipant(rakNetGUID);
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TM_World::OnNewConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, bool isIncoming)
- {
- (void) isIncoming;
- (void) systemAddress;
- if (autoAddParticipants)
- AddParticipant(rakNetGUID);
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TM_World::EnforceTeamBalance(NoTeamId noTeamId)
- {
- // Host only function
- RakAssert(GetHost()==GetTeamManager()->GetMyGUIDUnified());
- KickExcessMembers(noTeamId);
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TM_World::KickExcessMembers(NoTeamId noTeamId)
- {
- // Host only function
- RakAssert(GetHost()==GetTeamManager()->GetMyGUIDUnified());
- // For each team that applies balancing, if the team is overfull, put on a team that is not overfull if the team has ALLOW_JOIN_REBALANCING set
- // If cannot move the player to another team, just take the player off the team and set to noTeamId if they have no team at that point
-
- TeamMemberLimit balancedTeamLimit;
- if (balanceTeamsIsActive)
- balancedTeamLimit = GetBalancedTeamLimit();
- else
- balancedTeamLimit = (TeamMemberLimit) -1;
- TM_Team *team, *teamToJoin;
- unsigned int i, teamIndex;
- for (i=0; i < teams.Size(); i++)
- {
- team = teams[i];
- while (team->GetMemberLimitSetting() < team->GetTeamMembersCount() ||
- (balancedTeamLimit < team->GetTeamMembersCount() && team->GetBalancingApplies()) )
- {
- TM_TeamMember *teamMember = team->teamMembers[team->teamMembers.Size()-1];
- teamIndex = GetAvailableTeamIndexWithFewestMembers(balancedTeamLimit, ALLOW_JOIN_REBALANCING);
- if (teamIndex == (unsigned int)-1)
- {
- // Move this member to no team
- teamMember->LeaveTeam(team, noTeamId);
- teamManager->PushTeamAssigned(teamMember);
- }
- else
- {
- teamToJoin = teams[teamIndex];
- // Move this member
- teamMember->StoreLastTeams();
- teamManager->RemoveFromTeamsRequestedAndAddTeam(teamMember, teamToJoin, true, team);
- BitStream bsOut;
- bsOut.WriteCasted<MessageID>(ID_TEAM_BALANCER_INTERNAL);
- bsOut.WriteCasted<MessageID>(ID_RUN_RemoveFromTeamsRequestedAndAddTeam);
- bsOut.Write(GetWorldId());
- bsOut.Write(teamMember->GetNetworkID());
- bsOut.Write(teamToJoin->GetNetworkID());
- bsOut.Write(true);
- bsOut.Write(true);
- bsOut.Write(team->GetNetworkID());
- BroadcastToParticipants(&bsOut, UNASSIGNED_RAKNET_GUID);
- }
- }
- }
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TM_World::FillRequestedSlots(void)
- {
- // Host only function
- RakAssert(GetHost()==GetTeamManager()->GetMyGUIDUnified());
- TeamMemberLimit balancedTeamLimit;
- if (balanceTeamsIsActive)
- balancedTeamLimit = GetBalancedTeamLimit();
- else
- balancedTeamLimit = (TeamMemberLimit) -1;
- unsigned int teamIndex, indexIntoTeamsRequested = (unsigned int)-1;
- TM_Team *team;
- TM_TeamMember *teamMember;
- DataStructures::OrderedList<TM_World::JoinRequestHelper, TM_World::JoinRequestHelper, JoinRequestHelperComp> joinRequests;
- GetSortedJoinRequests(joinRequests);
- unsigned int joinRequestIndex;
- for (joinRequestIndex=0; joinRequestIndex < joinRequests.Size(); joinRequestIndex++)
- {
- teamMember = teamMembers[joinRequests[joinRequestIndex].teamMemberIndex];
- if (teamMember->teamsRequested.Size()==0)
- {
- if (teamMember->joinTeamType==JOIN_ANY_AVAILABLE_TEAM)
- teamIndex = GetAvailableTeamIndexWithFewestMembers(balancedTeamLimit, ALLOW_JOIN_ANY_AVAILABLE_TEAM);
- else
- teamIndex=(unsigned int)-1;
- }
- else
- {
- indexIntoTeamsRequested = joinRequests[joinRequestIndex].indexIntoTeamsRequested;
- team = teamMember->teamsRequested[indexIntoTeamsRequested].requested;
- if (team->GetTeamMembersCount() < balancedTeamLimit &&
- team->GetTeamMembersCount() < team->GetMemberLimitSetting() &&
- (ALLOW_JOIN_SPECIFIC_TEAM & team->GetJoinPermissions())!=0)
- {
- teamIndex=teams.GetIndexOf(team);
- }
- else
- {
- teamIndex=(unsigned int)-1;
- }
- }
- if (teamIndex != (unsigned int)-1)
- {
- team = teams[teamIndex];
- if (teamMember->teamsRequested.Size()==0)
- {
- if (teamMember->joinTeamType==JOIN_ANY_AVAILABLE_TEAM)
- {
- // Join any
- teamMember->StoreLastTeams();
- teamMember->UpdateTeamsRequestedToNone();
- teamMember->AddToTeamList(teams[teamIndex]);
- teamManager->PushTeamAssigned(teamMember);
- BitStream bsOut;
- bsOut.WriteCasted<MessageID>(ID_TEAM_BALANCER_INTERNAL);
- bsOut.WriteCasted<MessageID>(ID_RUN_UpdateTeamsRequestedToNoneAndAddTeam);
- bsOut.Write(GetWorldId());
- bsOut.Write(teamMember->GetNetworkID());
- bsOut.Write(team->GetNetworkID());
- BroadcastToParticipants(&bsOut, UNASSIGNED_RAKNET_GUID);
- }
- }
- else
- {
- // Switch or join specific
- DataStructures::List<TM_Team*> teamsWeAreLeaving;
- bool isSwitch = teamMember->teamsRequested[indexIntoTeamsRequested].isTeamSwitch;
- TM_Team *teamToLeave;
- if (isSwitch)
- {
- teamToLeave=teamMember->teamsRequested[indexIntoTeamsRequested].teamToLeave;
- if (teamToLeave)
- {
- if (teamMember->IsOnTeam(teamToLeave))
- {
- teamsWeAreLeaving.Push(teamToLeave, _FILE_AND_LINE_);
- }
- else
- {
- teamToLeave=0;
- isSwitch=false;
- }
- }
- else
- {
- teamsWeAreLeaving=teamMember->teams;
- }
- }
- else
- teamToLeave=0;
- int teamJoined = JoinSpecificTeam(teamMember, team, isSwitch, teamToLeave, teamsWeAreLeaving);
- if (teamJoined==1)
- {
- BitStream bsOut;
- bsOut.WriteCasted<MessageID>(ID_TEAM_BALANCER_INTERNAL);
- bsOut.WriteCasted<MessageID>(ID_RUN_RemoveFromTeamsRequestedAndAddTeam);
- bsOut.Write(GetWorldId());
- bsOut.Write(teamMember->GetNetworkID());
- bsOut.Write(team->GetNetworkID());
- bsOut.Write(isSwitch);
- if (teamToLeave!=0)
- {
- bsOut.Write(true);
- bsOut.Write(teamToLeave->GetNetworkID());
- }
- else
- bsOut.Write(false);
- BroadcastToParticipants(&bsOut, UNASSIGNED_RAKNET_GUID);
- }
- }
- }
- }
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- unsigned int TM_World::GetAvailableTeamIndexWithFewestMembers(TeamMemberLimit secondaryLimit, JoinPermissions joinPermissions)
- {
- unsigned int teamIndex;
- unsigned int lowestTeamMembers = (unsigned int) -1;
- unsigned int lowestIndex = (unsigned int) -1;
- for (teamIndex=0; teamIndex < teams.Size(); teamIndex++)
- {
- if (teams[teamIndex]->GetTeamMembersCount() < secondaryLimit &&
- teams[teamIndex]->GetTeamMembersCount() < teams[teamIndex]->GetMemberLimitSetting() &&
- teams[teamIndex]->GetTeamMembersCount() < lowestTeamMembers &&
- (joinPermissions & teams[teamIndex]->GetJoinPermissions())!=0)
- {
- lowestTeamMembers = teams[teamIndex]->GetTeamMembersCount();
- lowestIndex = teamIndex;
- }
- }
- return lowestIndex;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TM_World::GetSortedJoinRequests(DataStructures::OrderedList<TM_World::JoinRequestHelper, TM_World::JoinRequestHelper, JoinRequestHelperComp> &joinRequests)
- {
- unsigned int i;
- for (i=0; i < teamMembers.Size(); i++)
- {
- TM_TeamMember *teamMember = teamMembers[i];
- if (teamMember->teamsRequested.Size()==0)
- {
- if (teamMember->joinTeamType==JOIN_ANY_AVAILABLE_TEAM)
- {
- TM_World::JoinRequestHelper jrh;
- jrh.whenRequestMade=teamMember->whenJoinAnyRequested;
- jrh.teamMemberIndex=i;
- jrh.requestIndex=teamMember->joinAnyRequestIndex;
- joinRequests.Insert(jrh, jrh, true, _FILE_AND_LINE_);
- }
- }
- else
- {
- unsigned int j;
- for (j=0; j < teamMember->teamsRequested.Size(); j++)
- {
- TM_World::JoinRequestHelper jrh;
- jrh.whenRequestMade=teamMember->teamsRequested[j].whenRequested;
- jrh.teamMemberIndex=i;
- jrh.indexIntoTeamsRequested=j;
- jrh.requestIndex=teamMember->teamsRequested[j].requestIndex;
- joinRequests.Insert(jrh, jrh, true, _FILE_AND_LINE_);
- }
- }
- }
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TM_World::BroadcastToParticipants(RakNet::BitStream *bsOut, RakNetGUID exclusionGuid)
- {
- for (unsigned int i=0; i < participants.Size(); i++)
- {
- if (participants[i]==exclusionGuid)
- continue;
- teamManager->SendUnified(bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, participants[i], false);
- }
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TM_World::BroadcastToParticipants(unsigned char *data, const int length, RakNetGUID exclusionGuid)
- {
- for (unsigned int i=0; i < participants.Size(); i++)
- {
- if (participants[i]==exclusionGuid)
- continue;
- teamManager->SendUnified((const char*) data, length, HIGH_PRIORITY, RELIABLE_ORDERED, 0, participants[i], false);
- }
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- TM_Team* TM_World::JoinAnyTeam(TM_TeamMember *teamMember, int *resultCode)
- {
- TeamMemberLimit balancedLimit = GetBalancedTeamLimit();
- unsigned int idx = GetAvailableTeamIndexWithFewestMembers(balancedLimit, ALLOW_JOIN_ANY_AVAILABLE_TEAM);
- if (idx == (unsigned int ) -1)
- {
- // If any team is joinable but full, return full. Otherwise return locked
- for (idx=0; idx < teams.Size(); idx++)
- {
- if ((teams[idx]->GetTeamMembersCount() >= balancedLimit ||
- teams[idx]->GetTeamMembersCount() >= teams[idx]->GetMemberLimitSetting()) &&
- teams[idx]->GetMemberLimitSetting() != 0 &&
- (ALLOW_JOIN_ANY_AVAILABLE_TEAM & teams[idx]->GetJoinPermissions())!=0)
- {
- // Full
- *resultCode=-2;
- return teams[idx];
- }
- }
- // Locked
- *resultCode=-1;
- return 0;
- }
- TM_Team* lowestMemberTeam = teams[idx];
- teamMember->StoreLastTeams();
- teamMember->UpdateTeamsRequestedToNone();
- teamMember->AddToTeamList(lowestMemberTeam);
- teamManager->PushTeamAssigned(teamMember);
- *resultCode=1;
- return lowestMemberTeam;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- int TM_World::JoinSpecificTeam(TM_TeamMember *teamMember, TM_Team *team, bool isTeamSwitch, TM_Team *teamToLeave, DataStructures::List<TM_Team*> &teamsWeAreLeaving)
- {
- if (team->GetJoinPermissions() & ALLOW_JOIN_SPECIFIC_TEAM)
- {
- if (balanceTeamsIsActive==false || teamsWeAreLeaving.Size()==0)
- {
- if (team->GetMemberLimit() > team->GetTeamMembersCount())
- {
- // Can join normally
- teamMember->StoreLastTeams();
- teamManager->RemoveFromTeamsRequestedAndAddTeam(teamMember, team, isTeamSwitch, teamToLeave);
- return 1;
- }
- else
- {
- // Full
- return -2;
- }
- }
- else
- {
- // Note: balanceTeamsIsActive==true && isTeamSwitch==true
- // Do limited team swap
- // We must be on one team, target must be on one team, and we want to exchange teams
- if (teamsWeAreLeaving.Size()==1)
- {
- unsigned int j = team->GetMemberWithRequestedSingleTeamSwitch(teamsWeAreLeaving[0]);
- if (j!=(unsigned int)-1)
- {
- TM_TeamMember *swappingMember = team->teamMembers[j];
- teamMember->StoreLastTeams();
- swappingMember->StoreLastTeams();
- teamManager->RemoveFromTeamsRequestedAndAddTeam(teamMember, team, true, 0);
- teamManager->RemoveFromTeamsRequestedAndAddTeam(swappingMember, teamsWeAreLeaving[0], true, 0);
- // Send ID_TEAM_BALANCER_TEAM_ASSIGNED to all, for swapped member
- // Calling function sends ID_RUN_RemoveFromTeamsRequestedAndAddTeam which pushes ID_TEAM_BALANCER_TEAM_ASSIGNED for teamMember
- RakNet::BitStream bitStream;
- bitStream.WriteCasted<MessageID>(ID_TEAM_BALANCER_TEAM_ASSIGNED);
- teamManager->EncodeTeamAssigned(&bitStream, swappingMember);
- BroadcastToParticipants(&bitStream, UNASSIGNED_RAKNET_GUID);
- return 1;
- }
- }
- // Full
- return -2;
- }
- }
- else
- {
- // Locked
- return -1;
- }
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- TeamMemberLimit TM_World::GetBalancedTeamLimit(void) const
- {
- if (teams.Size()==0)
- return 0;
- if (balanceTeamsIsActive==false)
- return (TeamMemberLimit) -1;
- unsigned int i;
- bool additionalTeamsExcluded;
- TeamMemberLimit balancedLimit;
- unsigned int teamsCount=teams.Size();
- unsigned int membersCount=teamMembers.Size();
- DataStructures::List<TM_Team*> consideredTeams = teams;
- do
- {
- additionalTeamsExcluded=false;
- balancedLimit = (TeamMemberLimit) ((membersCount+(teamsCount-1))/(teamsCount));
- i=0;
- while (i < consideredTeams.Size())
- {
- if (consideredTeams[i]->GetMemberLimitSetting() < balancedLimit)
- {
- additionalTeamsExcluded=true;
- membersCount-=consideredTeams[i]->GetMemberLimitSetting();
- teamsCount--;
- consideredTeams.RemoveAtIndexFast(i);
- }
- else
- {
- i++;
- }
- }
- } while (additionalTeamsExcluded==true && teamsCount>0);
-
- return balancedLimit;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- TeamManager::TeamManager()
- {
- for (unsigned int i=0; i < 255; i++)
- worldsArray[i]=0;
- autoAddParticipants=true;
- topology=TM_PEER_TO_PEER;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- TeamManager::~TeamManager()
- {
- Clear();
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- TM_World* TeamManager::AddWorld(WorldId worldId)
- {
- RakAssert(worldsArray[worldId]==0 && "World already in use");
- TM_World *newWorld = RakNet::OP_NEW<TM_World>(_FILE_AND_LINE_);
- newWorld->worldId=worldId;
- newWorld->teamManager=this;
- newWorld->hostGuid=GetMyGUIDUnified();
- worldsArray[worldId]=newWorld;
- worldsList.Push(newWorld,_FILE_AND_LINE_);
- return newWorld;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TeamManager::RemoveWorld(WorldId worldId)
- {
- RakAssert(worldsArray[worldId]!=0 && "World not in use");
- for (unsigned int i=0; i < worldsList.Size(); i++)
- {
- if (worldsList[i]==worldsArray[worldId])
- {
- RakNet::OP_DELETE(worldsList[i],_FILE_AND_LINE_);
- worldsList.RemoveAtIndexFast(i);
- break;
- }
- }
- worldsArray[worldId]=0;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- unsigned int TeamManager::GetWorldCount(void) const
- {
- return worldsList.Size();
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- TM_World* TeamManager::GetWorldAtIndex(unsigned int index) const
- {
- return worldsList[index];
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- TM_World* TeamManager::GetWorldWithId(WorldId worldId) const
- {
- return worldsArray[worldId];
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TeamManager::SetAutoManageConnections(bool autoAdd)
- {
- autoAddParticipants=autoAdd;
- for (unsigned int i=0; i < worldsList.Size(); i++)
- {
- worldsList[i]->SetAutoManageConnections(autoAdd);
- }
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TeamManager::SetTopology(TMTopology _topology)
- {
- topology=_topology;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TeamManager::EncodeTeamFull(RakNet::BitStream *bitStream, TM_TeamMember *teamMember, TM_Team *team)
- {
- bitStream->WriteCasted<MessageID>(ID_TEAM_BALANCER_REQUESTED_TEAM_FULL);
- EncodeTeamFullOrLocked(bitStream, teamMember, team);
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TeamManager::DecomposeTeamFull(Packet *packet,
- TM_World **world, TM_TeamMember **teamMember, TM_Team **team,
- uint16_t ¤tMembers, uint16_t &memberLimitIncludingBalancing, bool &balancingIsActive, JoinPermissions &joinPermissions)
- {
- BitStream bsIn(packet->data,packet->length,false);
- bsIn.IgnoreBytes(sizeof(MessageID));
- DecomposeTeamFullOrLocked(&bsIn, world, teamMember, team, currentMembers, memberLimitIncludingBalancing, balancingIsActive, joinPermissions);
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TeamManager::EncodeTeamLocked(RakNet::BitStream *bitStream, TM_TeamMember *teamMember, TM_Team *team)
- {
- bitStream->WriteCasted<MessageID>(ID_TEAM_BALANCER_REQUESTED_TEAM_LOCKED);
- EncodeTeamFullOrLocked(bitStream, teamMember, team);
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TeamManager::EncodeTeamFullOrLocked(RakNet::BitStream *bitStream, TM_TeamMember *teamMember, TM_Team *team)
- {
- bitStream->Write(teamMember->world->GetWorldId());
- bitStream->Write(teamMember->GetNetworkID());
- bitStream->Write(team->GetNetworkID());
- bitStream->WriteCasted<uint16_t>(team->GetTeamMembersCount());
- bitStream->Write(team->GetMemberLimit());
- bitStream->Write(team->GetBalancingApplies());
- bitStream->Write(team->GetJoinPermissions());
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TeamManager::DecomposeTeamFullOrLocked(RakNet::BitStream *bsIn, TM_World **world, TM_TeamMember **teamMember, TM_Team **team,
- uint16_t ¤tMembers, uint16_t &memberLimitIncludingBalancing, bool &balancingIsActive, JoinPermissions &joinPermissions)
- {
- WorldId worldId;
- NetworkID teamMemberId;
- NetworkID teamId;
- *teamMember=0;
- *team=0;
- *world=0;
- bsIn->Read(worldId);
- bsIn->Read(teamMemberId);
- bsIn->Read(teamId);
- bsIn->Read(currentMembers);
- bsIn->Read(memberLimitIncludingBalancing);
- bsIn->Read(balancingIsActive);
- bsIn->Read(joinPermissions);
- *world = GetWorldWithId(worldId);
- if (*world)
- {
- *teamMember = (*world)->GetTeamMemberByNetworkID(teamMemberId);
- *team = (*world)->GetTeamByNetworkID(teamId);
- }
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TeamManager::DecomposeTeamLocked(Packet *packet,
- TM_World **world, TM_TeamMember **teamMember, TM_Team **team,
- uint16_t ¤tMembers, uint16_t &memberLimitIncludingBalancing, bool &balancingIsActive, JoinPermissions &joinPermissions)
- {
- BitStream bsIn(packet->data,packet->length,false);
- bsIn.IgnoreBytes(sizeof(MessageID));
- DecomposeTeamFullOrLocked(&bsIn, world, teamMember, team, currentMembers, memberLimitIncludingBalancing, balancingIsActive, joinPermissions);
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TeamManager::EncodeTeamAssigned(RakNet::BitStream *bitStream, TM_TeamMember *teamMember)
- {
- bitStream->Write(teamMember->world->GetWorldId());
- bitStream->Write(teamMember->GetNetworkID());
- bitStream->WriteCasted<uint16_t>(teamMember->teams.Size());
- for (unsigned int i=0; i < teamMember->teams.Size(); i++)
- {
- bitStream->Write(teamMember->teams[i]->GetNetworkID());
- }
- bitStream->Write(teamMember->noTeamSubcategory);
- bitStream->Write(teamMember->joinTeamType);
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TeamManager::ProcessTeamAssigned(RakNet::BitStream *bsIn)
- {
- TM_World *world;
- TM_TeamMember *teamMember;
- NoTeamId noTeamId;
- JoinTeamType joinTeamType;
- DataStructures::List<TM_Team *> newTeam;
- DataStructures::List<TM_Team *> teamsLeft;
- DataStructures::List<TM_Team *> teamsJoined;
- DecodeTeamAssigned(bsIn, &world, &teamMember, noTeamId, joinTeamType, newTeam, teamsLeft, teamsJoined);
- if (teamMember)
- {
- teamMember->StoreLastTeams();
- for (unsigned int i=0; i < teamsLeft.Size(); i++)
- {
- teamMember->RemoveFromSpecificTeamInternal(teamsLeft[i]);
- }
- for (unsigned int i=0; i < teamsJoined.Size(); i++)
- {
- if (teamMember->IsOnTeam(teamsJoined[i])==false)
- {
- teamMember->RemoveFromRequestedTeams(teamsJoined[i]);
- teamMember->AddToTeamList(teamsJoined[i]);
- }
- }
- teamMember->noTeamSubcategory=noTeamId;
- teamMember->joinTeamType=joinTeamType;
- }
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TeamManager::DecodeTeamAssigned(Packet *packet, TM_World **world, TM_TeamMember **teamMember)
- {
- WorldId worldId;
- NetworkID teamMemberId;
- RakNet::BitStream bsIn(packet->data, packet->length, false);
- bsIn.IgnoreBytes(sizeof(MessageID));
- bsIn.Read(worldId);
- bsIn.Read(teamMemberId);
- *world = GetWorldWithId(worldId);
- if (*world)
- {
- *teamMember = (*world)->GetTeamMemberByNetworkID(teamMemberId);
- }
- else
- {
- *teamMember=0;
- }
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TeamManager::DecodeTeamCancelled(Packet *packet, TM_World **world, TM_TeamMember **teamMember, TM_Team **teamCancelled)
- {
- WorldId worldId;
- NetworkID teamMemberId;
- RakNet::BitStream bsIn(packet->data, packet->length, false);
- bsIn.IgnoreBytes(sizeof(MessageID));
- bsIn.Read(worldId);
- bsIn.Read(teamMemberId);
- bool sp=false;
- *world = GetWorldWithId(worldId);
- if (*world)
- {
- *teamMember = (*world)->GetTeamMemberByNetworkID(teamMemberId);
- }
- else
- {
- *teamMember=0;
- }
- bsIn.Read(sp);
- if (sp)
- {
- NetworkID nid;
- bsIn.Read(nid);
- *teamCancelled = (*world)->GetTeamByNetworkID(nid);
- }
- else
- {
- *teamCancelled = 0;
- }
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TeamManager::DecodeTeamAssigned(BitStream *bsIn, TM_World **world, TM_TeamMember **teamMember, NoTeamId &noTeamId,
- JoinTeamType &joinTeamType, DataStructures::List<TM_Team *> &newTeam,
- DataStructures::List<TM_Team *> &teamsLeft, DataStructures::List<TM_Team *> &teamsJoined
- )
- {
- newTeam.Clear(true, _FILE_AND_LINE_);
- teamsLeft.Clear(true, _FILE_AND_LINE_);
- teamsJoined.Clear(true, _FILE_AND_LINE_);
- WorldId worldId;
- NetworkID teamMemberId;
- NetworkID teamId;
- bsIn->Read(worldId);
- bsIn->Read(teamMemberId);
- *world = GetWorldWithId(worldId);
- if (*world)
- {
- *teamMember = (*world)->GetTeamMemberByNetworkID(teamMemberId);
- uint16_t teamsCount;
- bsIn->Read(teamsCount);
- for (unsigned int i=0; i < teamsCount; i++)
- {
- bsIn->Read(teamId);
- TM_Team * team = (*world)->GetTeamByNetworkID(teamId);
- RakAssert(team);
- if (team)
- newTeam.Push(team, _FILE_AND_LINE_);
- // else probably didn't reference team first
- }
- if (*teamMember)
- {
- for (unsigned int i=0; i < (*teamMember)->teams.Size(); i++)
- {
- TM_Team *team = (*teamMember)->teams[i];
- if (newTeam.GetIndexOf(team)==(unsigned int)-1)
- teamsLeft.Push(team, _FILE_AND_LINE_);
- }
- }
- for (unsigned int i=0; i < newTeam.Size(); i++)
- {
- TM_Team *team = newTeam[i];
- if ((*teamMember)->teams.GetIndexOf(team)==(unsigned int)-1)
- teamsJoined.Push(team, _FILE_AND_LINE_);
- }
- bsIn->Read(noTeamId);
- bsIn->Read(joinTeamType);
- }
- else
- {
- *teamMember=0;
- }
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TeamManager::Clear(void)
- {
- for (unsigned int i=0; i < worldsList.Size(); i++)
- {
- worldsArray[worldsList[i]->worldId]=0;
- worldsList[i]->Clear();
- delete worldsList[i];
- }
- worldsList.Clear(false, _FILE_AND_LINE_);
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TeamManager::Update(void)
- {
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- PluginReceiveResult TeamManager::OnReceive(Packet *packet)
- {
- switch (packet->data[0])
- {
- case ID_FCM2_NEW_HOST:
- {
- unsigned int i;
- for (i=0; i < worldsList.Size(); i++)
- worldsList[i]->SetHost(packet->guid);
- }
- break;
- case ID_TEAM_BALANCER_TEAM_ASSIGNED:
- {
- BitStream bsIn(packet->data,packet->length,false);
- bsIn.IgnoreBytes(sizeof(MessageID));
- ProcessTeamAssigned(&bsIn);
- }
- break;
- case ID_TEAM_BALANCER_TEAM_REQUESTED_CANCELLED:
- {
- BitStream bsIn(packet->data,packet->length,false);
- bsIn.IgnoreBytes(1);
- WorldId worldId;
- bsIn.Read(worldId);
- TM_World *world = GetWorldWithId(worldId);
- if (world==0)
- return RR_STOP_PROCESSING_AND_DEALLOCATE;
- bool validPacket = OnRemoveFromRequestedTeams(packet, world);
- if (validPacket==false)
- return RR_STOP_PROCESSING_AND_DEALLOCATE;
- break;
- }
- case ID_TEAM_BALANCER_INTERNAL:
- {
- if (packet->length>=2)
- {
- BitStream bsIn(packet->data,packet->length,false);
- bsIn.IgnoreBytes(2);
- WorldId worldId;
- bsIn.Read(worldId);
- TM_World *world = GetWorldWithId(worldId);
- if (world==0)
- return RR_STOP_PROCESSING_AND_DEALLOCATE;
- switch (packet->data[1])
- {
- case ID_RUN_UpdateListsToNoTeam:
- OnUpdateListsToNoTeam(packet, world);
- break;
- case ID_RUN_UpdateTeamsRequestedToAny:
- OnUpdateTeamsRequestedToAny(packet, world);
- break;
- case ID_RUN_JoinAnyTeam:
- OnJoinAnyTeam(packet, world);
- break;
- case ID_RUN_JoinRequestedTeam:
- OnJoinRequestedTeam(packet, world);
- break;
- case ID_RUN_UpdateTeamsRequestedToNoneAndAddTeam:
- OnUpdateTeamsRequestedToNoneAndAddTeam(packet, world);
- break;
- case ID_RUN_RemoveFromTeamsRequestedAndAddTeam:
- OnRemoveFromTeamsRequestedAndAddTeam(packet, world);
- break;
- case ID_RUN_AddToRequestedTeams:
- OnAddToRequestedTeams(packet, world);
- break;
- case ID_RUN_LeaveTeam:
- OnLeaveTeam(packet, world);
- break;
- case ID_RUN_SetMemberLimit:
- OnSetMemberLimit(packet, world);
- break;
- case ID_RUN_SetJoinPermissions:
- OnSetJoinPermissions(packet, world);
- break;
- case ID_RUN_SetBalanceTeams:
- OnSetBalanceTeams(packet, world);
- break;
- case ID_RUN_SetBalanceTeamsInitial:
- OnSetBalanceTeamsInitial(packet, world);
- break;
- }
- }
- }
- return RR_STOP_PROCESSING_AND_DEALLOCATE;
- }
- return RR_CONTINUE_PROCESSING;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TeamManager::OnClosedConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason )
- {
- for (unsigned int i=0; i < worldsList.Size(); i++)
- {
- worldsList[i]->OnClosedConnection(systemAddress, rakNetGUID, lostConnectionReason);
- }
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TeamManager::OnNewConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, bool isIncoming)
- {
- for (unsigned int i=0; i < worldsList.Size(); i++)
- {
- worldsList[i]->OnNewConnection(systemAddress, rakNetGUID, isIncoming);
- }
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TeamManager::Send( const RakNet::BitStream * bitStream, const AddressOrGUID systemIdentifier, bool broadcast )
- {
- SendUnified(bitStream,HIGH_PRIORITY, RELIABLE_ORDERED, 0, systemIdentifier, broadcast);
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TeamManager::RemoveFromTeamsRequestedAndAddTeam(TM_TeamMember *teamMember, TM_Team *team, bool isTeamSwitch, TM_Team *teamToLeave)
- {
- teamMember->RemoveFromRequestedTeams(team);
- if (isTeamSwitch)
- {
- if (teamToLeave==0)
- {
- // Leave all teams
- teamMember->RemoveFromAllTeamsInternal();
- }
- else
- {
- // Leave specific team if it exists
- teamMember->RemoveFromSpecificTeamInternal(teamToLeave);
- }
- }
- teamMember->AddToTeamList(team);
- PushTeamAssigned(teamMember);
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TeamManager::PushTeamAssigned(TM_TeamMember *teamMember)
- {
- // Push ID_TEAM_BALANCER_TEAM_ASSIGNED locally
- RakNet::BitStream bitStream;
- bitStream.WriteCasted<MessageID>(ID_TEAM_BALANCER_TEAM_ASSIGNED);
- EncodeTeamAssigned(&bitStream, teamMember);
- PushBitStream(&bitStream);
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TeamManager::PushBitStream(RakNet::BitStream *bitStream)
- {
- Packet *p = AllocatePacketUnified(bitStream->GetNumberOfBytesUsed());
- memcpy(p->data, bitStream->GetData(), bitStream->GetNumberOfBytesUsed());
- p->systemAddress=UNASSIGNED_SYSTEM_ADDRESS;
- p->systemAddress.systemIndex=(SystemIndex)-1;
- p->guid=UNASSIGNED_RAKNET_GUID;
- p->wasGeneratedLocally=true;
- PushBackPacketUnified(p, true);
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TeamManager::OnUpdateListsToNoTeam(Packet *packet, TM_World *world)
- {
- BitStream bsIn(packet->data,packet->length,false);
- bsIn.IgnoreBytes(2+sizeof(WorldId));
- NetworkID networkId;
- bsIn.Read(networkId);
- TM_TeamMember *teamMember = world->GetTeamMemberByNetworkID(networkId);
- NoTeamId noTeamId;
- bsIn.Read(noTeamId);
- if (teamMember)
- {
- teamMember->StoreLastTeams();
- teamMember->UpdateListsToNoTeam(noTeamId);
- PushTeamAssigned(teamMember);
- if (world->GetHost()==world->GetTeamManager()->GetMyGUIDUnified())
- {
- world->FillRequestedSlots();
- world->EnforceTeamBalance(noTeamId);
- if (topology==TM_CLIENT_SERVER)
- {
- // Relay
- world->BroadcastToParticipants(packet->data, packet->length, packet->guid);
- }
- }
- }
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TeamManager::OnUpdateTeamsRequestedToAny(Packet *packet, TM_World *world)
- {
- BitStream bsIn(packet->data,packet->length,false);
- bsIn.IgnoreBytes(2+sizeof(WorldId));
- NetworkID networkId;
- bsIn.Read(networkId);
- TM_TeamMember *teamMember = world->GetTeamMemberByNetworkID(networkId);
- if (teamMember)
- {
- teamMember->UpdateTeamsRequestedToAny();
- }
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TeamManager::OnJoinAnyTeam(Packet *packet, TM_World *world)
- {
- BitStream bsIn(packet->data,packet->length,false);
- bsIn.IgnoreBytes(2+sizeof(WorldId));
- NetworkID networkId;
- bsIn.Read(networkId);
- TM_TeamMember *teamMember = world->GetTeamMemberByNetworkID(networkId);
- if (teamMember)
- {
- // This is a host-only operation
- RakAssert(world->GetHost()==world->GetTeamManager()->GetMyGUIDUnified());
- teamMember->UpdateTeamsRequestedToAny();
- int resultCode;
- TM_Team *newTeam = world->JoinAnyTeam(teamMember, &resultCode);
- if (resultCode==1)
- {
- // Broadcast packet - remote systems should clear requested teams to none, and add the team we joined.
- // Broadcast includes non-host sender (all participants)
- BitStream bsOut;
- bsOut.WriteCasted<MessageID>(ID_TEAM_BALANCER_INTERNAL);
- bsOut.WriteCasted<MessageID>(ID_RUN_UpdateTeamsRequestedToNoneAndAddTeam);
- bsOut.Write(world->GetWorldId());
- bsOut.Write(networkId);
- bsOut.Write(newTeam->GetNetworkID());
- world->BroadcastToParticipants(&bsOut, packet->guid);
- // Send to sender ID_TEAM_BALANCER_TEAM_ASSIGNED
- if (packet->guid!=GetMyGUIDUnified())
- {
- RakNet::BitStream bitStream;
- bitStream.WriteCasted<MessageID>(ID_TEAM_BALANCER_TEAM_ASSIGNED);
- EncodeTeamAssigned(&bitStream, teamMember);
- SendUnified(&bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, packet->guid, false);
- }
- }
- else
- {
- // Relay packet to set requested teams to any
- BitStream bsOut;
- bsOut.WriteCasted<MessageID>(ID_TEAM_BALANCER_INTERNAL);
- bsOut.WriteCasted<MessageID>(ID_RUN_UpdateTeamsRequestedToAny);
- bsOut.Write(world->GetWorldId());
- bsOut.Write(networkId);
- world->BroadcastToParticipants(&bsOut, packet->guid);
- bsOut.Reset();
- if (resultCode==-2)
- {
- EncodeTeamFull(&bsOut, teamMember, newTeam);
- }
- else if (resultCode==-1)
- {
- EncodeTeamLocked(&bsOut, teamMember, newTeam);
- }
- // SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, packet->guid, false);
- world->BroadcastToParticipants(&bsOut, UNASSIGNED_RAKNET_GUID);
- if (packet->guid!=GetMyGUIDUnified())
- PushBitStream(&bsOut);
- }
- }
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TeamManager::OnJoinRequestedTeam(Packet *packet, TM_World *world)
- {
- BitStream bsIn(packet->data,packet->length,false);
- bsIn.IgnoreBytes(2+sizeof(WorldId));
- NetworkID networkId;
- bsIn.Read(networkId);
- TM_TeamMember *teamMember = world->GetTeamMemberByNetworkID(networkId);
- NetworkID teamToJoinNetworkId;
- bsIn.Read(teamToJoinNetworkId);
- TM_Team *teamToJoin = world->GetTeamByNetworkID(teamToJoinNetworkId);
- bool isTeamSwitch=false;
- bool switchSpecificTeam=false;
- NetworkID teamToLeaveNetworkId=UNASSIGNED_NETWORK_ID;
- TM_Team *teamToLeave=0;
- bsIn.Read(isTeamSwitch);
- if (isTeamSwitch)
- {
- bsIn.Read(switchSpecificTeam);
- if (switchSpecificTeam)
- {
- bsIn.Read(teamToLeaveNetworkId);
- teamToLeave = world->GetTeamByNetworkID(teamToLeaveNetworkId);
- if (teamToLeave==0)
- isTeamSwitch=false;
- }
- }
- if (teamToJoin && teamMember)
- {
- if (isTeamSwitch)
- {
- if (teamMember->SwitchSpecificTeamCheck(teamToJoin, teamToLeave, packet->guid==GetMyGUIDUnified())==false)
- return;
- teamMember->AddToRequestedTeams(teamToJoin, teamToLeave);
- }
- else
- {
- if (teamMember->JoinSpecificTeamCheck(teamToJoin, packet->guid==GetMyGUIDUnified())==false)
- return;
- teamMember->AddToRequestedTeams(teamToJoin);
- }
- DataStructures::List<TM_Team*> teamsWeAreLeaving;
- if (isTeamSwitch)
- {
- if (teamToLeave==0)
- {
- teamsWeAreLeaving=teamMember->teams;
- }
- else
- {
- if (teamMember->IsOnTeam(teamToLeave))
- teamsWeAreLeaving.Push(teamToLeave, _FILE_AND_LINE_);
- }
- if (teamsWeAreLeaving.Size()==0)
- isTeamSwitch=false;
- }
- int resultCode = world->JoinSpecificTeam(teamMember, teamToJoin, isTeamSwitch, teamToLeave, teamsWeAreLeaving);
- if (resultCode==1)
- {
- // Broadcast packet - remote systems should remove from requested teams and add the team we joined.
- // Broadcast includes non-host sender (all participants)
- BitStream bsOut;
- bsOut.WriteCasted<MessageID>(ID_TEAM_BALANCER_INTERNAL);
- bsOut.WriteCasted<MessageID>(ID_RUN_RemoveFromTeamsRequestedAndAddTeam);
- bsOut.Write(world->GetWorldId());
- bsOut.Write(networkId);
- bsOut.Write(teamToJoin->GetNetworkID());
- bsOut.Write(isTeamSwitch);
- if (isTeamSwitch)
- {
- bsOut.Write(switchSpecificTeam);
- if (switchSpecificTeam)
- bsOut.Write(teamToLeaveNetworkId);
- }
- world->BroadcastToParticipants(&bsOut, packet->guid);
- // Send to sender ID_TEAM_BALANCER_TEAM_ASSIGNED
- if (packet->guid!=GetMyGUIDUnified())
- {
- RakNet::BitStream bitStream;
- bitStream.WriteCasted<MessageID>(ID_TEAM_BALANCER_TEAM_ASSIGNED);
- EncodeTeamAssigned(&bitStream, teamMember);
- SendUnified(&bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, packet->guid, false);
- }
- }
- else
- {
- // Relay packet to set requested teams to any
- BitStream bsOut;
- bsOut.WriteCasted<MessageID>(ID_TEAM_BALANCER_INTERNAL);
- bsOut.WriteCasted<MessageID>(ID_RUN_AddToRequestedTeams);
- bsOut.Write(world->GetWorldId());
- bsOut.Write(networkId);
- bsOut.Write(teamToJoin->GetNetworkID());
- bsOut.Write(isTeamSwitch);
- if (isTeamSwitch)
- {
- bsOut.Write(switchSpecificTeam);
- if (switchSpecificTeam)
- bsOut.Write(teamToLeaveNetworkId);
- }
- world->BroadcastToParticipants(&bsOut, packet->guid);
- bsOut.Reset();
- if (resultCode==-2)
- {
- EncodeTeamFull(&bsOut, teamMember, teamToJoin);
- }
- else if (resultCode==-1)
- {
- EncodeTeamLocked(&bsOut, teamMember, teamToJoin);
- }
- // SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, packet->guid, false);
- world->BroadcastToParticipants(&bsOut, UNASSIGNED_RAKNET_GUID);
- if (packet->guid!=GetMyGUIDUnified())
- PushBitStream(&bsOut);
- }
- }
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TeamManager::OnUpdateTeamsRequestedToNoneAndAddTeam(Packet *packet, TM_World *world)
- {
- BitStream bsIn(packet->data,packet->length,false);
- bsIn.IgnoreBytes(2+sizeof(WorldId));
- NetworkID networkId;
- bsIn.Read(networkId);
- TM_TeamMember *teamMember = world->GetTeamMemberByNetworkID(networkId);
- NetworkID teamNetworkId;
- bsIn.Read(teamNetworkId);
- TM_Team *team = world->GetTeamByNetworkID(teamNetworkId);
- if (team && teamMember)
- {
- teamMember->StoreLastTeams();
- teamMember->UpdateTeamsRequestedToNone();
- teamMember->AddToTeamList(team);
- world->GetTeamManager()->PushTeamAssigned(teamMember);
- }
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TeamManager::OnRemoveFromTeamsRequestedAndAddTeam(Packet *packet, TM_World *world)
- {
- BitStream bsIn(packet->data,packet->length,false);
- bsIn.IgnoreBytes(2+sizeof(WorldId));
- NetworkID networkId;
- bsIn.Read(networkId);
- TM_TeamMember *teamMember = world->GetTeamMemberByNetworkID(networkId);
- NetworkID teamNetworkId;
- bsIn.Read(teamNetworkId);
- bool isTeamSwitch=false, switchSpecificTeam=false;
- NetworkID teamToLeaveNetworkId;
- TM_Team *teamToLeave=0;
- bsIn.Read(isTeamSwitch);
- if (isTeamSwitch)
- {
- bsIn.Read(switchSpecificTeam);
- if (switchSpecificTeam)
- {
- bsIn.Read(teamToLeaveNetworkId);
- teamToLeave = world->GetTeamByNetworkID(teamToLeaveNetworkId);
- }
- }
- TM_Team *team = world->GetTeamByNetworkID(teamNetworkId);
- if (team && teamMember)
- {
- teamMember->StoreLastTeams();
- if (teamToLeave)
- teamMember->RemoveFromSpecificTeamInternal(teamToLeave);
- else if (isTeamSwitch==true && switchSpecificTeam==false)
- teamMember->RemoveFromAllTeamsInternal();
- RemoveFromTeamsRequestedAndAddTeam(teamMember, team, false, 0);
- }
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TeamManager::OnAddToRequestedTeams(Packet *packet, TM_World *world)
- {
- BitStream bsIn(packet->data,packet->length,false);
- bsIn.IgnoreBytes(2+sizeof(WorldId));
- NetworkID networkId;
- bsIn.Read(networkId);
- TM_TeamMember *teamMember = world->GetTeamMemberByNetworkID(networkId);
- NetworkID teamNetworkId;
- bsIn.Read(teamNetworkId);
- TM_Team *team = world->GetTeamByNetworkID(teamNetworkId);
- bool isTeamSwitch=false;
- bool switchSpecificTeam=false;
- NetworkID teamToLeaveNetworkId=UNASSIGNED_NETWORK_ID;
- TM_Team *teamToLeave=0;
- bsIn.Read(isTeamSwitch);
- if (isTeamSwitch)
- {
- bsIn.Read(switchSpecificTeam);
- if (switchSpecificTeam)
- {
- bsIn.Read(teamToLeaveNetworkId);
- teamToLeave = world->GetTeamByNetworkID(teamToLeaveNetworkId);
- if (teamToLeave==0)
- isTeamSwitch=false;
- }
- }
- if (team && teamMember)
- {
- if (isTeamSwitch)
- teamMember->AddToRequestedTeams(team, teamToLeave);
- else
- teamMember->AddToRequestedTeams(team);
- }
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- bool TeamManager::OnRemoveFromRequestedTeams(Packet *packet, TM_World *world)
- {
- BitStream bsIn(packet->data,packet->length,false);
- bsIn.IgnoreBytes(1+sizeof(WorldId));
- NetworkID networkId;
- bsIn.Read(networkId);
- TM_TeamMember *teamMember = world->GetTeamMemberByNetworkID(networkId);
- bool hasSpecificTeam=false;
- NetworkID teamNetworkId;
- TM_Team *team;
- bsIn.Read(hasSpecificTeam);
- if (hasSpecificTeam)
- {
- bsIn.Read(teamNetworkId);
- team = world->GetTeamByNetworkID(teamNetworkId);
- if (team==0)
- return false;
- }
- else
- {
- team=0;
- }
- if (teamMember)
- {
- teamMember->RemoveFromRequestedTeams(team);
- // Relay as host
- if (world->GetHost()==world->GetTeamManager()->GetMyGUIDUnified() && topology==TM_CLIENT_SERVER)
- {
- world->BroadcastToParticipants(packet->data, packet->length, packet->guid);
- }
- return true;
- }
- else
- {
- return false;
- }
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TeamManager::OnLeaveTeam(Packet *packet, TM_World *world)
- {
- BitStream bsIn(packet->data,packet->length,false);
- bsIn.IgnoreBytes(2+sizeof(WorldId));
- NetworkID networkId;
- bsIn.Read(networkId);
- TM_TeamMember *teamMember = world->GetTeamMemberByNetworkID(networkId);
- NetworkID teamNetworkId;
- bsIn.Read(teamNetworkId);
- TM_Team *team = world->GetTeamByNetworkID(teamNetworkId);
- NoTeamId noTeamId;
- bsIn.Read(noTeamId);
- if (team && teamMember)
- {
- if (teamMember->LeaveTeamCheck(team)==false)
- return;
- teamMember->StoreLastTeams();
- teamMember->RemoveFromSpecificTeamInternal(team);
- if (teamMember->GetCurrentTeamCount()==0)
- {
- teamMember->noTeamSubcategory=noTeamId;
- teamMember->joinTeamType=JOIN_NO_TEAM;
- }
- PushTeamAssigned(teamMember);
- if (world->GetHost()==world->GetTeamManager()->GetMyGUIDUnified())
- {
- // Rebalance teams
- world->FillRequestedSlots();
- world->EnforceTeamBalance(noTeamId);
- // Relay as host
- if (topology==TM_CLIENT_SERVER)
- world->BroadcastToParticipants(packet->data, packet->length, packet->guid);
- }
- }
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TeamManager::OnSetMemberLimit(Packet *packet, TM_World *world)
- {
- BitStream bsIn(packet->data,packet->length,false);
- bsIn.IgnoreBytes(2+sizeof(WorldId));
- NetworkID teamNetworkId;
- bsIn.Read(teamNetworkId);
- TeamMemberLimit teamMemberLimit;
- NoTeamId noTeamId;
- bsIn.Read(teamMemberLimit);
- bsIn.Read(noTeamId);
- TM_Team *team = world->GetTeamByNetworkID(teamNetworkId);
- if (team)
- {
- team->teamMemberLimit=teamMemberLimit;
- if (world->GetHost()==world->GetTeamManager()->GetMyGUIDUnified())
- {
- if (packet->guid==GetMyGUIDUnified())
- world->BroadcastToParticipants(packet->data, packet->length, packet->guid);
- else
- world->BroadcastToParticipants(packet->data, packet->length, UNASSIGNED_RAKNET_GUID);
- world->FillRequestedSlots();
- world->KickExcessMembers(noTeamId);
- }
- }
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TeamManager::OnSetJoinPermissions(Packet *packet, TM_World *world)
- {
- BitStream bsIn(packet->data,packet->length,false);
- bsIn.IgnoreBytes(2+sizeof(WorldId));
- NetworkID teamNetworkId;
- bsIn.Read(teamNetworkId);
- JoinPermissions joinPermissions;
- bsIn.Read(joinPermissions);
- TM_Team *team = world->GetTeamByNetworkID(teamNetworkId);
- if (team)
- {
- team->joinPermissions=joinPermissions;
- if (world->GetHost()==world->GetTeamManager()->GetMyGUIDUnified())
- {
- if (packet->guid==GetMyGUIDUnified())
- world->BroadcastToParticipants(packet->data, packet->length, packet->guid);
- else
- world->BroadcastToParticipants(packet->data, packet->length, UNASSIGNED_RAKNET_GUID);
- world->FillRequestedSlots();
- }
- }
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TeamManager::OnSetBalanceTeams(Packet *packet, TM_World *world)
- {
- BitStream bsIn(packet->data,packet->length,false);
- bsIn.IgnoreBytes(2+sizeof(WorldId));
- bool balanceTeams=false;
- bsIn.Read(balanceTeams);
- NoTeamId noTeamId;
- bsIn.Read(noTeamId);
- world->balanceTeamsIsActive=balanceTeams;
- if (world->GetHost()==world->GetTeamManager()->GetMyGUIDUnified())
- {
- if (packet->guid==GetMyGUIDUnified())
- world->BroadcastToParticipants(packet->data, packet->length, packet->guid);
- else
- world->BroadcastToParticipants(packet->data, packet->length, UNASSIGNED_RAKNET_GUID);
-
- if (balanceTeams)
- world->EnforceTeamBalance(noTeamId);
- else
- world->FillRequestedSlots();
- }
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- void TeamManager::OnSetBalanceTeamsInitial(Packet *packet, TM_World *world)
- {
- BitStream bsIn(packet->data,packet->length,false);
- bsIn.IgnoreBytes(2+sizeof(WorldId));
- bool balanceTeams=false;
- bsIn.Read(balanceTeams);
- world->balanceTeamsIsActive=balanceTeams;
- }
- // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- #endif // _RAKNET_SUPPORT_TeamManager==1
|