public static string SharedGetAreaOwnerFactionClanTag(ILogicObject area) { var areasGroup = SharedGetLandClaimAreasGroup(area); var areasGroupPublicState = LandClaimAreasGroup.GetPublicState(areasGroup); return(areasGroupPublicState.FactionClanTag); }
private static void ServerTransferAreasGroupToFactionOwnership( ILogicObject faction, ICharacter byCharacter, ILogicObject areasGroup) { var areas = LandClaimAreasGroup.GetPrivateState(areasGroup).ServerLandClaimsAreas; foreach (var area in areas) { ServerUnregisterArea(area); } var publicState = LandClaimAreasGroup.GetPublicState(areasGroup); publicState.ServerSetFaction(faction); var centerTilePosition = new Vector2Ushort( (ushort)areas.Average(a => LandClaimArea.GetPublicState(a).LandClaimCenterTilePosition.X), (ushort)areas.Average(a => LandClaimArea.GetPublicState(a).LandClaimCenterTilePosition.Y)); Logger.Important( $"Transferred land claim areas group to the faction ownership: {areasGroup} at {centerTilePosition}"); FactionSystem.ServerOnLandClaimExpanded(faction, centerTilePosition, byCharacter); foreach (var area in areas) { ServerRegisterArea(area); } }
public static string ServerSetOwner(ushort x, ushort y, string newOwnerName) { using var tempList = Api.Shared.GetTempList <ILogicObject>(); LandClaimSystem.SharedGetAreasInBounds(new RectangleInt(x, y, 1, 1), tempList, addGracePadding: false); var landClaimsModified = 0; foreach (var area in tempList.AsList()) { var areasGroup = LandClaimSystem.SharedGetLandClaimAreasGroup(area); if (LandClaimAreasGroup.GetPublicState(areasGroup).ServerFaction is not null) { // cannot change an owner of the faction land claim continue; } var privateState = LandClaimArea.GetPrivateState(area); privateState.LandClaimFounder = newOwnerName; privateState.DirectLandOwners.Clear(); privateState.DirectLandOwners.Add(newOwnerName); landClaimsModified++; } return($"Modified {landClaimsModified} land claims"); }
private static ILogicObject ServerGetOwningFaction(IWorldObject worldObject) { ILogicObject faction = null; if (worldObject is IStaticWorldObject staticWorldObject) { var areasGroup = LandClaimSystem.SharedGetLandClaimAreasGroup(staticWorldObject); if (areasGroup is null) { throw new Exception( "Cannot modify faction access mode for an object without a faction land claim area"); } faction = LandClaimAreasGroup.GetPublicState(areasGroup).ServerFaction; } else if (worldObject.ProtoGameObject is IProtoVehicle) { var clanTag = worldObject.GetPublicState <VehiclePublicState>().ClanTag; if (string.IsNullOrEmpty(clanTag)) { throw new Exception("The vehicle doesn't belong to a faction: " + worldObject); } faction = FactionSystem.ServerGetFactionByClanTag(clanTag); } if (faction is null) { throw new Exception( "Cannot modify faction access mode for an object without a faction land claim area"); } return(faction); }
private static void ServerResetDecayTimerForLandClaimAreasGroup(ILogicObject areasGroup) { var areasGroupPrivateState = LandClaimAreasGroup.GetPrivateState(areasGroup); var areasGroupPublicState = LandClaimAreasGroup.GetPublicState(areasGroup); var areas = areasGroupPrivateState.ServerLandClaimsAreas; // TODO: it's better to move this code to another place as this property is used in several other places areasGroupPublicState.IsFounderDemoPlayer = ServerGetIsFounderDemoPlayer(areas); // reset the decay timer for all land claim buildings inside this areas group var decayDelayDuration = LandClaimSystem.ServerGetDecayDelayDurationForLandClaimAreas( areas, areasGroupPublicState.IsFounderDemoPlayer, out _); foreach (var area in areas) { var worldObject = LandClaimArea.GetPrivateState(area) .ServerLandClaimWorldObject; StructureDecaySystem.ServerResetDecayTimer( worldObject.GetPrivateState <StructurePrivateState>(), decayDelayDuration); } }
private void ServerRemote_TransferLandClaimToFactionOwnership(ILogicObject area) { var character = ServerRemoteContext.Character; var areasGroup = SharedGetLandClaimAreasGroup(area); if (LandClaimAreasGroup.GetPublicState(areasGroup).ServerFaction is not null) { // already has a faction (and it's not possible to change the faction) Logger.Warning("The land claim areas group is already transferred to a faction."); return; } FactionSystem.ServerValidateHasAccessRights(character, FactionMemberAccessRights.LandClaimManagement, out var faction); var factionOwnedAreas = SharedEnumerateAllFactionAreas(FactionSystem.SharedGetClanTag(faction)); var claimLimitRemains = FactionConstants.SharedGetFactionLandClaimsLimit( Faction.GetPublicState(faction).Level) - factionOwnedAreas.Count(); claimLimitRemains -= LandClaimAreasGroup.GetPrivateState(areasGroup).ServerLandClaimsAreas.Count; if (claimLimitRemains < 0) { Logger.Warning( "Cannot transfer land claims to the faction as it will exceed the land claims number limit"); return; } Logger.Important("Will transfer land claims to the faction: after upgrade the remaining limit will be " + claimLimitRemains); // verify user has access to the land claim var owner = ServerRemoteContext.Character; if (!Server.World.IsInPrivateScope(area, owner)) { throw new Exception( "Cannot interact with the land claim object as the area is not in private scope: " + area); } if (!LandClaimArea.GetPrivateState(area).ServerGetLandOwners() .Contains(owner.Name)) { throw new Exception("Player is not an owner of the land claim area"); } ServerTransferAreasGroupToFactionOwnership(faction, character, areasGroup); var worldObject = InteractionCheckerSystem.SharedGetCurrentInteraction(character); InteractableWorldObjectHelper.ServerTryAbortInteraction(character, worldObject); }
public static void ClientDeactivateShield(ILogicObject areasGroup) { var status = SharedGetShieldPublicStatus(areasGroup); if (status == ShieldProtectionStatus.Inactive) { Logger.Important("The shield is already inactive"); return; } var stackPanel = new StackPanel(); stackPanel.Children.Add( DialogWindow.CreateTextElement( string.Format(CoreStrings.ShieldProtection_DeactivationNotes_Format, ClientTimeFormatHelper.FormatTimeDuration( SharedCooldownDuration, appendSeconds: false)), TextAlignment.Left)); var accessRight = FactionMemberAccessRights.BaseShieldManagement; var areasGroupPublicState = LandClaimAreasGroup.GetPublicState(areasGroup); var hasNoFactionPermission = !string.IsNullOrEmpty(areasGroupPublicState.FactionClanTag) && !FactionSystem.ClientHasAccessRight(accessRight); if (hasNoFactionPermission) { var message = FactionSystem.ClientHasFaction ? string.Format( CoreStrings.Faction_Permission_Required_Format, accessRight.GetDescription()) : CoreStrings.Faction_ErrorDontHaveFaction; var textElement = DialogWindow.CreateTextElement("[br]" + message, TextAlignment.Left); textElement.Foreground = Client.UI.GetApplicationResource <Brush>("BrushColorRed6"); textElement.FontWeight = FontWeights.Bold; stackPanel.Children.Add(textElement); } var dialog = DialogWindow.ShowDialog( CoreStrings.ShieldProtection_Dialog_ConfirmDeactivation, stackPanel, okText: CoreStrings.ShieldProtection_Button_DeactivateShield, okAction: () => Instance.CallServer(_ => _.ServerRemote_DeactivateShield(areasGroup)), cancelAction: () => { }, focusOnCancelButton: true); if (hasNoFactionPermission) { dialog.ButtonOk.IsEnabled = false; } }
public ViewModelShieldProtectionControl(ILogicObject areasGroup) { this.areasGroup = areasGroup; this.privateState = LandClaimAreasGroup.GetPrivateState(areasGroup); this.publicState = LandClaimAreasGroup.GetPublicState(areasGroup); this.privateState.ClientSubscribe( _ => _.ShieldProtectionCurrentChargeElectricity, _ => { this.NotifyPropertyChanged(nameof(this.ElectricityAmount)); this.NotifyPropertyChanged(nameof(this.CanActivateShield)); this.NotifyPropertyChanged(nameof(this.HasFullCharge)); this.UpdateCurrentDurations(); }, this); this.privateState.ClientSubscribe( _ => _.ShieldProtectionCooldownExpirationTime, _ => this.RefreshState(), this); this.publicState.ClientSubscribe( _ => _.ShieldActivationTime, _ => this.RefreshState(), this); this.publicState.ClientSubscribe( _ => _.Status, _ => this.RefreshState(), this); this.RefreshState(); this.IsLandClaimInsideAnotherBase = LandClaimShieldProtectionHelper.SharedIsLandClaimInsideAnotherBase( areasGroup); FactionSystem.ClientCurrentFactionAccessRightsChanged += this.CurrentFactionAccessRightsChangedHandler; UpdateCurrentDurationsEverySecond(); void UpdateCurrentDurationsEverySecond() { if (this.IsDisposed) { return; } this.UpdateCurrentDurations(); ClientTimersSystem.AddAction(1, UpdateCurrentDurationsEverySecond); } }
private void ServerRemote_SetDirectAccessMode(IStaticWorldObject worldObject, WorldObjectDirectAccessMode mode) { var character = ServerRemoteContext.Character; if (!(worldObject.ProtoGameObject is IProtoObjectWithAccessMode protoObjectWithAccessMode)) { throw new Exception("This world object doesn't have an access mode"); } if (!protoObjectWithAccessMode.SharedCanInteract(character, worldObject, writeToLog: true)) { return; } var areasGroup = LandClaimSystem.SharedGetLandClaimAreasGroup(worldObject); if (areasGroup is not null && LandClaimAreasGroup.GetPublicState(areasGroup).ServerFaction is not null) { throw new Exception( "Cannot modify direct access mode for an object within a faction land claim area"); } if (!WorldObjectOwnersSystem.SharedIsOwner(character, worldObject) && !CreativeModeSystem.SharedIsInCreativeMode(character)) { throw new Exception("The player character is not an owner of " + worldObject); } if (mode == WorldObjectDirectAccessMode.Closed && !protoObjectWithAccessMode.IsClosedAccessModeAvailable) { throw new Exception("Closed access mode is not supported for " + protoObjectWithAccessMode); } if (mode == WorldObjectDirectAccessMode.OpensToEveryone && !protoObjectWithAccessMode.IsEveryoneAccessModeAvailable) { throw new Exception("Everyone access mode is not supported for " + protoObjectWithAccessMode); } var privateState = worldObject.GetPrivateState <IObjectWithAccessModePrivateState>(); if (privateState.DirectAccessMode == mode) { return; } privateState.DirectAccessMode = mode; Logger.Info($"Direct access mode changed: {mode}; {worldObject}", character); }
private static void ServerAreasGroupChangedHandler( ILogicObject area, [CanBeNull] ILogicObject areasGroupFrom, [CanBeNull] ILogicObject areasGroupTo) { var byMember = ServerPlayerCharacterCurrentActionStateContext.CurrentCharacter ?? (ServerRemoteContext.IsRemoteCall ? ServerRemoteContext.Character : null); if (areasGroupTo is not null) { var clanTag = LandClaimAreasGroup.GetPublicState(areasGroupTo).FactionClanTag; if (string.IsNullOrEmpty(clanTag)) { return; } var faction = FactionSystem.ServerGetFactionByClanTag(clanTag); var centerTilePosition = LandClaimArea.GetPublicState(area).LandClaimCenterTilePosition; Logger.Important( string.Format("Faction-owned land claim areas group expanded with a new claim area: {0} at {1}", areasGroupTo, centerTilePosition)); FactionSystem.ServerOnLandClaimExpanded(faction, centerTilePosition, byMember: byMember); } else if (areasGroupFrom is not null) { var clanTag = LandClaimAreasGroup.GetPublicState(areasGroupFrom).FactionClanTag; if (string.IsNullOrEmpty(clanTag)) { return; } var faction = FactionSystem.ServerGetFactionByClanTag(clanTag); var centerTilePosition = LandClaimArea.GetPublicState(area).LandClaimCenterTilePosition; Logger.Important( string.Format("Faction-owned land claim areas group removed: {0} at {1}", areasGroupFrom, centerTilePosition)); FactionSystem.ServerOnLandClaimRemoved(faction, centerTilePosition, byMember: byMember); } }
public void ReInitialize() { this.Reset(); this.stateSubscriptionStorage = new StateSubscriptionStorage(); var groupPublicState = LandClaimAreasGroup.GetPublicState(this.areasGroup); groupPublicState.ClientSubscribe( o => o.LastRaidTime, this.RefreshRaidedState, this.stateSubscriptionStorage); this.RefreshRaidedState(); }
public static IEnumerable <ILogicObject> SharedEnumerateAllFactionAreas(string clanTag) { if (string.IsNullOrEmpty(clanTag)) { throw new ArgumentNullException(); } return(SharedEnumerateAllAreas() .Where(a => { var areasGroup = SharedGetLandClaimAreasGroup(a); var areasGroupPublicState = LandClaimAreasGroup.GetPublicState(areasGroup); return areasGroupPublicState.FactionClanTag == clanTag; })); }
private static void ServerBaseBrokenHandler(ILogicObject areasGroup, List <ILogicObject> newAreaGroups) { var faction = LandClaimAreasGroup.GetPublicState(areasGroup).ServerFaction; if (faction is null) { return; } foreach (var newAreasGroup in newAreaGroups) { LandClaimAreasGroup.GetPublicState(newAreasGroup).ServerSetFaction(faction); } ServerRefreshFactionClaimAccess(faction); }
public Controller( ILogicObject areasGroup, WorldMapController worldMapController) { this.areasGroup = areasGroup; this.worldMapController = worldMapController; this.stateSubscriptionStorage = new StateSubscriptionStorage(); var groupPublicState = LandClaimAreasGroup.GetPublicState(areasGroup); groupPublicState.ClientSubscribe( o => o.LastRaidTime, this.RefreshRaidedState, this.stateSubscriptionStorage); this.RefreshRaidedState(); }
private SetOwnersResult ServerRemote_SetOwners(IWorldObject worldObject, List <string> newOwners) { var maxOwners = worldObject.ProtoGameObject is IProtoObjectDoor ? RateDoorOwnersMax.SharedValue : byte.MaxValue; if (newOwners.Count > maxOwners) { return(SetOwnersResult.ErrorAccessListSizeLimitExceeded); } var character = ServerRemoteContext.Character; if (worldObject is IStaticWorldObject staticWorldObject) { if (!staticWorldObject.ProtoStaticWorldObject .SharedCanInteract(character, worldObject, writeToLog: true)) { throw new Exception("Cannot interact with " + worldObject); } if (!SharedIsOwner(character, worldObject)) { throw new Exception("Not an owner"); } var areasGroup = LandClaimSystem.SharedGetLandClaimAreasGroup(staticWorldObject); if (areasGroup is not null && LandClaimAreasGroup.GetPublicState(areasGroup).ServerFaction is not null) { throw new Exception( "Cannot modify owners list for an object within a faction land claim area"); } } else // dynamic world object (a vehicle, etc) { if (!worldObject.ProtoWorldObject.SharedCanInteract(character, worldObject, writeToLog: false)) { throw new Exception("Cannot interact with " + worldObject); } } return(ServerSetOwners(worldObject, newOwners, byOwner: character)); }
public string Execute( ShieldProtectionStatus status, [CurrentCharacterIfNull] ICharacter character = null) { if (!LandClaimShieldProtectionConstants.SharedIsEnabled) { return("S.H.I.E.L.D. protection is not available"); } if (status == ShieldProtectionStatus.Active) { status = ShieldProtectionStatus.Activating; } using var tempAreas = Api.Shared.GetTempList <ILogicObject>(); LandClaimSystem.SharedGetAreasInBounds( new RectangleInt(character.TilePosition, (1, 1)), tempAreas, addGracePadding: false); var area = tempAreas.AsList().FirstOrDefault(); if (area is null) { return("No base exist near " + character.Name); } var areasGroup = LandClaimSystem.SharedGetLandClaimAreasGroup(area); LandClaimShieldProtectionSystem.SharedGetShieldProtectionMaxStatsForBase(areasGroup, out _, out _); var privateState = LandClaimAreasGroup.GetPrivateState(areasGroup); privateState.ShieldProtectionCooldownExpirationTime = 0; var publicState = LandClaimAreasGroup.GetPublicState(areasGroup); publicState.Status = status; publicState.ShieldActivationTime = Server.Game.FrameTime; return($"Status of the S.H.I.E.L.D. changed to {status}."); }
public static bool SharedIsOwner(ICharacter who, IWorldObject worldObject, out bool isFactionAccess) { isFactionAccess = false; switch (worldObject) { case IStaticWorldObject staticWorldObject: { var areasGroup = LandClaimSystem.SharedGetLandClaimAreasGroup(staticWorldObject); if (areasGroup is null || LandClaimAreasGroup.GetPublicState(areasGroup).FactionClanTag is not { } clanTag || string.IsNullOrEmpty(clanTag)) { break; } // the static object is inside the faction-owned land claim, // verify permission isFactionAccess = true; return(SharedHasFactionAccessRights(who, FactionMemberAccessRights.LandClaimManagement, clanTag)); } case IDynamicWorldObject when worldObject.ProtoGameObject is IProtoVehicle: { var clanTag = worldObject.GetPublicState <VehiclePublicState>().ClanTag; if (string.IsNullOrEmpty(clanTag)) { break; } // the vehicle is owned by faction // verify whether the character has the access right isFactionAccess = true; return(WorldObjectAccessModeSystem.SharedHasAccess(who, worldObject, writeToLog: true)); } } return(SharedGetDirectOwners(worldObject).Contains(who.Name)); }
private static void Refresh() { var position = ClientCurrentCharacterHelper.Character?.TilePosition ?? Vector2Ushort.Zero; var areasGroup = LandClaimSystem.SharedGetLandClaimAreasGroup(position, addGracePadding: false) ?? LandClaimSystem.SharedGetLandClaimAreasGroup(position, addGracePadding: true); var lastRaidTime = areasGroup is not null ? LandClaimAreasGroup.GetPublicState(areasGroup).LastRaidTime ?? double.MinValue : double.MinValue; var time = Api.Client.CurrentGame.ServerFrameTimeRounded; var timeSinceRaidStart = time - lastRaidTime; var timeRemainsToRaidEnd = LandClaimSystemConstants.SharedRaidBlockDurationSeconds - timeSinceRaidStart; timeRemainsToRaidEnd = Math.Max(timeRemainsToRaidEnd, 0); if (timeRemainsToRaidEnd <= 0) { // no raid here - hide notification currentNotification?.Hide(quick: true); currentNotification = null; return; } // raid here, display/update notification var text = GetNotificationText(timeRemainsToRaidEnd); if (currentNotification is not null && !currentNotification.IsHiding) { currentNotification.Message = text; return; } currentNotification = NotificationSystem.ClientShowNotification( title: Notification_Title, message: text, autoHide: false, // TODO: add custom icon here, currently we're using a placeholder icon icon: Api.GetProtoEntity <ItemBombModern>().Icon, playSound: false); }
public static bool SharedIsWorldObjectOwnedByFaction(IStaticWorldObject worldObject, out string clanTag) { var areasGroup = SharedGetLandClaimAreasGroup(worldObject); if (areasGroup is null) { clanTag = null; return(false); } var areasGroupPublicState = LandClaimAreasGroup.GetPublicState(areasGroup); clanTag = areasGroupPublicState.FactionClanTag; if (string.IsNullOrEmpty(clanTag)) { clanTag = null; return(false); } return(true); }
public static IReadOnlyList <string> SharedGetOwners(IWorldObject worldObject, out bool isFactionAccess) { isFactionAccess = false; switch (worldObject) { case IStaticWorldObject staticWorldObject: { var areasGroup = LandClaimSystem.SharedGetLandClaimAreasGroup(staticWorldObject); if (areasGroup is null || LandClaimAreasGroup.GetPublicState(areasGroup).FactionClanTag is not { } clanTag || string.IsNullOrEmpty(clanTag)) { break; } // the static object is inside the faction-owned land claim, var faction = FactionSystem.ServerGetFactionByClanTag(clanTag); return(FactionSystem.ServerGetFactionMemberNames(faction).ToList()); } case IDynamicWorldObject when worldObject.ProtoGameObject is IProtoVehicle: { var clanTag = worldObject.GetPublicState <VehiclePublicState>().ClanTag; if (string.IsNullOrEmpty(clanTag)) { break; } // the vehicle is owned by faction var faction = FactionSystem.ServerGetFactionByClanTag(clanTag); return(FactionSystem.ServerGetFactionMemberNames(faction).ToList()); } } return(SharedGetDirectOwners(worldObject)); }
private static void ServerRefreshFactionClaimAccess(ILogicObject faction) { using var tempList = Api.Shared.GetTempList <ILogicObject>(); Api.GetProtoEntity <LandClaimAreasGroup>() .GetAllGameObjects(tempList.AsList()); foreach (var areasGroup in tempList.AsList()) { if (!ReferenceEquals(LandClaimAreasGroup.GetPublicState(areasGroup).ServerFaction, faction)) { continue; } var areas = LandClaimAreasGroup.GetPrivateState(areasGroup) .ServerLandClaimsAreas; foreach (var area in areas) { ServerUnregisterArea(area); ServerRegisterArea(area); } } }
private static void Refresh() { var areasGroup = GetAreasGroupNearPlayerCharacter(); if (areasGroup is null) { currentNotification?.Hide(quick: true); currentNotification = null; return; } var publicState = LandClaimAreasGroup.GetPublicState(areasGroup); if (publicState.Status == ShieldProtectionStatus.Inactive) { currentNotification?.Hide(quick: true); currentNotification = null; return; } var isOwner = IsOwner(areasGroup); if (currentNotification is null || currentNotification.IsHiding) { currentNotification = CreateNotification(); } GetText(publicState, canDeactivate: isOwner, out var message, out var title); currentNotification.Title = title; currentNotification.Message = message; }
private static void ServerRefreshLandClaimAreasGroup(ILogicObject areasGroup) { if (areasGroup.IsDestroyed) { return; } var areasGroupPrivateState = LandClaimAreasGroup.GetPrivateState(areasGroup); var areasGroupPublicState = LandClaimAreasGroup.GetPublicState(areasGroup); var areas = areasGroupPrivateState.ServerLandClaimsAreas; // TODO: it's better to move this code to another place as this property is used in several other places areasGroupPublicState.IsFounderDemoPlayer = ServerGetIsFounderDemoPlayer(areas); // check every area in the group // if any of them has an online owner, reset the decay timer foreach (var area in areas) { var areaBounds = LandClaimSystem.SharedGetLandClaimAreaBounds(area, addGracePadding: true); var areaPrivateState = LandClaimArea.GetPrivateState(area); var owners = areaPrivateState.LandOwners; foreach (var owner in owners) { var character = ServerCharacters.GetPlayerCharacter(owner); if (character is null || !character.ServerIsOnline) { continue; } if (!areaBounds.Contains(character.TilePosition)) { continue; } // the land claim area contains an online owner character ServerResetDecayTimer(); return; } } // helper method to reset the decay timer for all land claim buildings inside this areas group void ServerResetDecayTimer() { var decayDelayDuration = LandClaimSystem.ServerGetDecayDelayDurationForLandClaimAreas( areas, areasGroupPublicState.IsFounderDemoPlayer, out _); foreach (var area in areas) { var worldObject = LandClaimArea.GetPrivateState(area) .ServerLandClaimWorldObject; StructureDecaySystem.ServerResetDecayTimer( worldObject.GetPrivateState <StructurePrivateState>(), decayDelayDuration); } } }
private static void Refresh() { var areasGroup = GetAreasGroupNearPlayerCharacter(); if (areasGroup is null) { currentNotification?.Hide(quick: true); currentNotification = null; return; } var status = LandClaimAreasGroup.GetPublicState(areasGroup).Status; if (status == ShieldProtectionStatus.Inactive) { currentNotification?.Hide(quick: true); currentNotification = null; return; } var isOwner = IsOwner(areasGroup); if (currentNotification is null || currentNotification.IsHiding) { currentNotification = CreateNotification(); } var publicState = LandClaimAreasGroup.GetPublicState(areasGroup); var time = Api.Client.CurrentGame.ServerFrameTimeApproximated; string message, title; if (status == ShieldProtectionStatus.Active) { var timeRemains = publicState.ShieldEstimatedExpirationTime - time; title = CoreStrings.ShieldProtection_NotificationBaseUnderShield_Title; message = string.Format(CoreStrings.ShieldProtection_NotificationBaseUnderShield_Message_Format, ClientTimeFormatHelper.FormatTimeDuration(timeRemains, appendSeconds: false)); if (isOwner) { message += "[br][br]" + CoreStrings.ShieldProtection_NotificationBaseUnderShield_MessageOwner; } message += "[br][br]" + CoreStrings.ShieldProtection_Description_2 + "[br]" + CoreStrings.ShieldProtection_Description_3; } else // activating { var timeRemains = publicState.ShieldActivationTime - time; timeRemains = Math.Max(0, timeRemains); title = CoreStrings.ShieldProtection_NotificationBaseActivatingShield_Title; message = string.Format(CoreStrings.ShieldProtection_NotificationBaseActivatingShield_Message_Format, ClientTimeFormatHelper.FormatTimeDuration(timeRemains)); if (isOwner) { message += "[br][br]" + CoreStrings.ShieldProtection_NotificationBaseUnderShield_MessageOwner; } } currentNotification.Title = title; currentNotification.Message = message; }