From 44565396638325f8fbc9687d2bcad1a5c7430669 Mon Sep 17 00:00:00 2001 From: Wanne Date: Mon, 29 Apr 2013 19:45:32 +0000 Subject: [PATCH] - MP: Put the interrupt fix code in a define "INTERRUPT_MP_DEADLOCK_FIX o It seems the fix does not work 100% and if the fix code is enabled the ALT + E feature does not work correctly (for now, disabled the fix) git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@6036 3b4a5df2-a311-0410-b5c6-a8a6f20db521 --- Multiplayer/client.cpp | 167 +++++++++++++++++++++++++++++------------ Multiplayer/connect.h | 5 ++ Tactical/TeamTurns.cpp | 37 ++++++--- 3 files changed, 150 insertions(+), 59 deletions(-) diff --git a/Multiplayer/client.cpp b/Multiplayer/client.cpp index 2fbe51db..7b6a81e1 100644 --- a/Multiplayer/client.cpp +++ b/Multiplayer/client.cpp @@ -1936,69 +1936,136 @@ void send_interrupt (SOLDIERTYPE *pSoldier) } // WANNE - MP: Here we have to add AddTopMessage() on the clients -void recieveINTERRUPT (RPCParameters *rpcParameters) -{ - INT_STRUCT* INT = (INT_STRUCT*)rpcParameters->input; - SOLDIERTYPE* pOpponent = MercPtrs[ INT->Interrupted]; - - if(INT->bTeam == netbTeam || (is_server && INT->bTeam == 1))//its for us or we are server and its for AI which we control +#ifdef INTERRUPT_MP_DEADLOCK_FIX + + void recieveINTERRUPT (RPCParameters *rpcParameters) { + INT_STRUCT* INT = (INT_STRUCT*)rpcParameters->input; + SOLDIERTYPE* pOpponent = MercPtrs[ INT->Interrupted]; + + if(INT->bTeam == netbTeam || (is_server && INT->bTeam == 1))//its for us or we are server and its for AI which we control + { + + if(INT->bTeam == netbTeam){//for me + INT->bTeam=0; + INT->ubID=INT->ubID - ubID_prefix; + AddTopMessage( PLAYER_INTERRUPT_MESSAGE, TeamTurnString[ INT->bTeam ] ); + }else{//for ai + //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"starting ai" ); + AddTopMessage( COMPUTER_INTERRUPT_MESSAGE, TeamTurnString[ INT->bTeam ] ); + } + + + for(int i=0; i <= INT->gubOutOfTurnPersons; i++)//this loop translates soldier id's from what they are in someone else's game to what they are locally + { + if((INT->gubOutOfTurnOrder[i] >= ubID_prefix) && (INT->gubOutOfTurnOrder[i] < (ubID_prefix+6))) + { + INT->gubOutOfTurnOrder[i]=INT->gubOutOfTurnOrder[i]-ubID_prefix; + } + } + memcpy(gubOutOfTurnOrder,INT->gubOutOfTurnOrder, sizeof(UINT8) * MAXMERCS); + gubOutOfTurnPersons = INT->gubOutOfTurnPersons; + + + //AddTopMessage( PLAYER_INTERRUPT_MESSAGE, TeamTurnString[ INT->bTeam ] ); + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Recieved interrupt between %s and %s.", TeamNameStrings[pOpponent->bTeam], TeamNameStrings[INT->bTeam] ); + + - if(INT->bTeam == netbTeam){//for me + //start interrupt turn //real interrupt code + SOLDIERTYPE* pSoldier = MercPtrs[ INT->ubID ]; + ManSeesMan(pSoldier,pOpponent,pOpponent->sGridNo,pOpponent->pathing.bLevel,2,1); + StartInterrupt(); + + + } + else//its not for us, make faux interrupt look while it happens + { + //this following section starts the interrupt, either with faux interrupt look, or real interrupt code, or nothing if already there + + //if( INT->bTeam != 0)//not for our team - hayden + //{ + + //stop moving merc who was interrupted and init UI bar + SOLDIERTYPE* pMerc = MercPtrs[ INT->ubID ]; + pMerc->HaultSoldierFromSighting(TRUE); + FreezeInterfaceForEnemyTurn(); + InitEnemyUIBar( 0, 0 ); + fInterfacePanelDirty = DIRTYLEVEL2; + gTacticalStatus.fInterruptOccurred = TRUE; + + AddTopMessage( COMPUTER_INTERRUPT_MESSAGE, TeamTurnString[ INT->bTeam ] ); + //this needed to add details of who's interrupt it is - hayden + + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Recieved interrupt with %s and %s.", TeamNameStrings[pOpponent->bTeam], TeamNameStrings[INT->bTeam] );//was MPClientMessage[17], can be reconnected if text updated and translated + } + + } + +#else + + void recieveINTERRUPT (RPCParameters *rpcParameters) + { + INT_STRUCT* INT = (INT_STRUCT*)rpcParameters->input; + SOLDIERTYPE* pOpponent = MercPtrs[ INT->Interrupted]; + + if(INT->bTeam==netbTeam)//for us + { INT->bTeam=0; INT->ubID=INT->ubID - ubID_prefix; + + for(int i=0; i <= INT->gubOutOfTurnPersons; i++)//this loop translates soldier id's from what they are in someone else's game to what they are locally + { + if((INT->gubOutOfTurnOrder[i] >= ubID_prefix) && (INT->gubOutOfTurnOrder[i] < (ubID_prefix+6))) + { + INT->gubOutOfTurnOrder[i]=INT->gubOutOfTurnOrder[i]-ubID_prefix; + } + } + memcpy(gubOutOfTurnOrder,INT->gubOutOfTurnOrder, sizeof(UINT8) * MAXMERCS); + gubOutOfTurnPersons = INT->gubOutOfTurnPersons; + + AddTopMessage( PLAYER_INTERRUPT_MESSAGE, TeamTurnString[ INT->bTeam ] ); - }else{//for ai - //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"starting ai" ); - AddTopMessage( COMPUTER_INTERRUPT_MESSAGE, TeamTurnString[ INT->bTeam ] ); + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Interrupt of %s awarded to %s.", TeamNameStrings[pOpponent->bTeam], TeamNameStrings[INT->bTeam] ); + } - - for(int i=0; i <= INT->gubOutOfTurnPersons; i++)//this loop translates soldier id's from what they are in someone else's game to what they are locally + // WANNE - MP: This seems to cause the HANG on AI interrupt where we have to press ALT + E on the server! + if( INT->bTeam != 0)//not for our team - hayden { - if((INT->gubOutOfTurnOrder[i] >= ubID_prefix) && (INT->gubOutOfTurnOrder[i] < (ubID_prefix+6))) + + //stop moving merc who was interrupted and init UI bar + SOLDIERTYPE* pMerc = MercPtrs[ INT->ubID ]; + pMerc->HaultSoldierFromSighting(TRUE); + FreezeInterfaceForEnemyTurn(); + InitEnemyUIBar( 0, 0 ); + fInterfacePanelDirty = DIRTYLEVEL2; + gTacticalStatus.fInterruptOccurred = TRUE; + + AddTopMessage( COMPUTER_INTERRUPT_MESSAGE, TeamTurnString[ INT->bTeam ] ); + //this needed to add details of who's interrupt it is - hayden + + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Interrupt with %s awarded to %s.", TeamNameStrings[pOpponent->bTeam], TeamNameStrings[INT->bTeam] );//was MPClientMessage[17], can be reconnected if text updated and translated + } + else + { + //it for us ! :) + if(INT->gubOutOfTurnPersons==0)//indicates finished interrupt maybe can just call end interrupt { - INT->gubOutOfTurnOrder[i]=INT->gubOutOfTurnOrder[i]-ubID_prefix; + //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"old int finish" ); + } + else //start our interrupt turn + { + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Interrupt of %s awarded to you.", TeamNameStrings[pOpponent->bTeam] );//was MPClientMessage[37], can be reconnected if text updated and translated + + SOLDIERTYPE* pSoldier = MercPtrs[ INT->ubID ]; + ManSeesMan(pSoldier,pOpponent,pOpponent->sGridNo,pOpponent->pathing.bLevel,2,1); + StartInterrupt(); } } - memcpy(gubOutOfTurnOrder,INT->gubOutOfTurnOrder, sizeof(UINT8) * MAXMERCS); - gubOutOfTurnPersons = INT->gubOutOfTurnPersons; - - - //AddTopMessage( PLAYER_INTERRUPT_MESSAGE, TeamTurnString[ INT->bTeam ] ); - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Recieved interrupt between %s and %s.", TeamNameStrings[pOpponent->bTeam], TeamNameStrings[INT->bTeam] ); - - - - //start interrupt turn //real interrupt code - SOLDIERTYPE* pSoldier = MercPtrs[ INT->ubID ]; - ManSeesMan(pSoldier,pOpponent,pOpponent->sGridNo,pOpponent->pathing.bLevel,2,1); - StartInterrupt(); - - - } - else//its not for us, make faux interrupt look while it happens - { - //this following section starts the interrupt, either with faux interrupt look, or real interrupt code, or nothing if already there - - //if( INT->bTeam != 0)//not for our team - hayden - //{ - - //stop moving merc who was interrupted and init UI bar - SOLDIERTYPE* pMerc = MercPtrs[ INT->ubID ]; - pMerc->HaultSoldierFromSighting(TRUE); - FreezeInterfaceForEnemyTurn(); - InitEnemyUIBar( 0, 0 ); - fInterfacePanelDirty = DIRTYLEVEL2; - gTacticalStatus.fInterruptOccurred = TRUE; - - AddTopMessage( COMPUTER_INTERRUPT_MESSAGE, TeamTurnString[ INT->bTeam ] ); - //this needed to add details of who's interrupt it is - hayden - - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Recieved interrupt with %s and %s.", TeamNameStrings[pOpponent->bTeam], TeamNameStrings[INT->bTeam] );//was MPClientMessage[17], can be reconnected if text updated and translated } -} +#endif void intAI (SOLDIERTYPE *pSoldier ) { diff --git a/Multiplayer/connect.h b/Multiplayer/connect.h index a756bcd4..166be798 100644 --- a/Multiplayer/connect.h +++ b/Multiplayer/connect.h @@ -147,6 +147,11 @@ extern char cServerName[30]; //OJW - 20081224 #define MAX_CONNECT_RETRIES 5 + +// WANNE: If this define is enabled, it hopefully fixes the "enemy AI got stuck on pure client interrupt". (this "fix" was added in revision 5623) +// After some MP-Tests: It seems there are still problems with enemy interupt and if this define is enabled the ALT + E (give turn to client) does not work correctly. So I disabled this define for now ... +//#define INTERRUPT_MP_DEADLOCK_FIX + #define ENABLE_COLLISION (is_server && pBullet->pFirer->ubID<120) || (!is_server && is_client && pBullet->pFirer->ubID<20) || (!is_server && !is_client) extern bool auto_retry; extern int giNumTries; diff --git a/Tactical/TeamTurns.cpp b/Tactical/TeamTurns.cpp index aefc784c..18e1990a 100644 --- a/Tactical/TeamTurns.cpp +++ b/Tactical/TeamTurns.cpp @@ -1176,8 +1176,14 @@ void EndInterrupt( BOOLEAN fMarkInterruptOccurred ) #ifdef BETAVERSION ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"unchecked interrupt call area:(resume interrupted interrupt)..."); #endif + + +#ifdef INTERRUPT_MP_DEADLOCK_FIX // INTERRUPT is calculated on the server who controls AI - if (0)//(nbTeam > 0) && (nbTeam <6 ) && is_server) //the AI had interrupted someone //experiment with 0 as with doneaddindtointlist func + if (0) //the AI had interrupted someone //experiment with 0 as with doneaddindtointlist func +#else + if ((nbTeam > 0) && (nbTeam <6 ) && is_server) // AI interrupt resume and im server +#endif { send_interrupt( npSoldier ); StartInterrupt(); @@ -1196,11 +1202,16 @@ void EndInterrupt( BOOLEAN fMarkInterruptOccurred ) StartInterrupt(); ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Continuing interrupt of AI by %s", TeamNameStrings[npSoldier->bTeam]); - } - else if(gTacticalStatus.ubCurrentTeam == 0)//its our turn//else// pure client awarding interrupt resume //its our turn + +#ifdef INTERRUPT_MP_DEADLOCK_FIX + //its our turn//else// pure client awarding interrupt resume //its our turn + else if(gTacticalStatus.ubCurrentTeam == 0) +#else + // pure client awarding interrupt resume + else +#endif { - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Continuing interrupt with %s", TeamNameStrings[npSoldier->bTeam]);//this can be simplified if above comment is implemented //ClearIntList(); //hayden//may need more work. @@ -1208,7 +1219,6 @@ void EndInterrupt( BOOLEAN fMarkInterruptOccurred ) send_interrupt( npSoldier ); // } } - } else { @@ -2272,11 +2282,16 @@ void DoneAddingToIntList( SOLDIERTYPE * pSoldier, BOOLEAN fChange, UINT8 ubInter //npSoldier is interruptor //hayden +#ifdef INTERRUPT_MP_DEADLOCK_FIX // INTERRUPT is calculated on the server who controls AI - if (0)//((nbTeam > 0) && (nbTeam <6 ) && is_server) //the AI has interrupted someone//made this 0 as interrupt should only be calculated by person whos turn it is - { + if (0) //the AI has interrupted someone//made this 0 as interrupt should only be calculated by person whos turn it is +#else + if ((nbTeam > 0) && (nbTeam <6 ) && is_server) //is for AI and are server +#endif + { ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Interrupt calculated between %s and AI", TeamNameStrings[pSoldier->bTeam]); - + + // Only display the top message if we (the server) got interrupted if (pSoldier->bTeam == 0) AddTopMessage( COMPUTER_INTERRUPT_MESSAGE, TeamTurnString[ nbTeam ] ); @@ -2300,7 +2315,11 @@ void DoneAddingToIntList( SOLDIERTYPE * pSoldier, BOOLEAN fChange, UINT8 ubInter // INTERRUPT is calculated on the pure client or server else if(gTacticalStatus.ubCurrentTeam == 0)//its our turn { - //ScreenMsg( FONT_MCOLOR_LTRED, MSG_INTERFACE, MPClientMessage[79]); +#ifdef INTERRUPT_MP_DEADLOCK_FIX + // Do nothing +#else + ScreenMsg( FONT_MCOLOR_LTRED, MSG_INTERFACE, MPClientMessage[79]); +#endif send_interrupt( npSoldier );