package engine.net.client.handlers ;
import engine.Enum ;
import engine.Enum.GameObjectType ;
import engine.exception.MsgSendException ;
import engine.gameManager.BuildingManager ;
import engine.gameManager.DbManager ;
import engine.gameManager.SessionManager ;
import engine.net.Dispatch ;
import engine.net.DispatchMessage ;
import engine.net.client.ClientConnection ;
import engine.net.client.msg.* ;
import engine.objects.Building ;
import engine.objects.PlayerCharacter ;
import org.pmw.tinylog.Logger ;
import java.time.LocalDateTime ;
import static engine.net.client.msg.ErrorPopupMsg.sendErrorPopup ;
/ *
*
* @Summary : Processes application protocol message where a
* client requests that a building be upgraded .
* /
public class UpgradeAssetMsgHandler extends AbstractClientMsgHandler {
// Constructor
public UpgradeAssetMsgHandler ( ) {
super ( UpgradeAssetMessage . class ) ;
}
@Override
protected boolean _handleNetMsg ( ClientNetMsg baseMsg , ClientConnection origin ) throws MsgSendException {
// Member variable declaration
UpgradeAssetMessage msg ;
ManageCityAssetsMsg outMsg ;
PlayerCharacter player ;
int buildingUUID ;
Building buildingToRank ;
LocalDateTime dateToUpgrade ;
int nextRank ;
int rankCost ;
Dispatch dispatch ;
// Assign member variables
msg = ( UpgradeAssetMessage ) baseMsg ;
// Grab pointer to the requesting player
player = SessionManager . getPlayerCharacter ( origin ) ;
// Grab pointer to the building from the cache
buildingUUID = msg . getBuildingUUID ( ) ;
buildingToRank = ( Building ) DbManager . getObject ( GameObjectType . Building , buildingUUID ) ;
// Early exit if building not in cache.
if ( buildingToRank = = null ) {
Logger . error ( "Attempt to upgrade null building by " + player . getName ( ) ) ;
return true ;
}
// Early exit for building that is already ranking
if ( buildingToRank . isRanking ( ) ) {
Logger . error ( "Attempt to upgrade a building already ranking by " + player . getName ( ) ) ;
return true ;
}
// Calculate and set time/cost to upgrade
nextRank = ( buildingToRank . getRank ( ) + 1 ) ;
if ( buildingToRank . getBlueprint ( ) = = null )
return true ;
if ( buildingToRank . getBlueprint ( ) . getMaxRank ( ) < nextRank | | nextRank = = 8 ) {
ErrorPopupMsg . sendErrorMsg ( player , "Building is already at it's Max rank." ) ;
return true ;
}
rankCost = buildingToRank . getBlueprint ( ) . getRankCost ( nextRank ) ;
// SEND NOT ENOUGH GOLD ERROR
if ( ! buildingToRank . hasFunds ( rankCost ) ) {
ErrorPopupMsg . sendErrorPopup ( player , 127 ) ; // Not enough gold in strongbox
return true ;
}
if ( rankCost > buildingToRank . getStrongboxValue ( ) ) {
sendErrorPopup ( player , 127 ) ;
return true ;
}
// Validation appears good. Let's now process the upgrade
try {
if ( buildingToRank . getCity ( ) ! = null ) {
buildingToRank . getCity ( ) . transactionLock . writeLock ( ) . lock ( ) ;
try {
if ( ! buildingToRank . transferGold ( - rankCost , false ) ) {
sendErrorPopup ( player , 127 ) ;
return true ;
}
} catch ( Exception e ) {
Logger . error ( e ) ;
} finally {
buildingToRank . getCity ( ) . transactionLock . writeLock ( ) . unlock ( ) ;
}
} else if ( ! buildingToRank . transferGold ( - rankCost , false ) ) {
sendErrorPopup ( player , 127 ) ;
return true ;
}
//dateToUpgrade = LocalDateTime.now().plusHours(buildingToRank.getBlueprint().getRankTime(nextRank));
dateToUpgrade = LocalDateTime . now ( ) . plusMinutes ( 5 ) ;
BuildingManager . setUpgradeDateTime ( buildingToRank , dateToUpgrade , 0 ) ;
// Schedule upgrade job
BuildingManager . submitUpgradeJob ( buildingToRank ) ;
// Refresh the client's manage asset window
// *** Refactor : We have some of these unknowns
outMsg = new ManageCityAssetsMsg ( player , buildingToRank ) ;
// Action TYPE
outMsg . actionType = 3 ;
outMsg . setTargetType ( buildingToRank . getObjectType ( ) . ordinal ( ) ) ;
outMsg . setTargetID ( buildingToRank . getObjectUUID ( ) ) ;
outMsg . setTargetType3 ( buildingToRank . getObjectType ( ) . ordinal ( ) ) ;
outMsg . setTargetID3 ( buildingToRank . getObjectUUID ( ) ) ;
outMsg . setAssetName1 ( buildingToRank . getName ( ) ) ;
outMsg . setUnknown54 ( 1 ) ;
dispatch = Dispatch . borrow ( player , outMsg ) ;
DispatchMessage . dispatchMsgDispatch ( dispatch , Enum . DispatchChannel . SECONDARY ) ;
} catch ( Exception e ) {
PlaceAssetMsg . sendPlaceAssetError ( player . getClientConnection ( ) , 1 , "A Serious error has occurred. Please post details for to ensure transaction integrity" ) ;
}
return true ;
}
}