Ejemplo n.º 1
0
        private void ServerRemote_SetMode(IStaticWorldObject worldObject, WorldObjectAccessMode mode)
        {
            var character = ServerRemoteContext.Character;

            if (!InteractionCheckerSystem.SharedHasInteraction(character,
                                                               worldObject,
                                                               requirePrivateScope: true))
            {
                throw new Exception("The player character is not interacting with " + worldObject);
            }

            if (!WorldObjectOwnersSystem.SharedIsOwner(character, worldObject) &&
                !CreativeModeSystem.SharedIsInCreativeMode(character))
            {
                throw new Exception("The player character is not the owner of " + worldObject);
            }

            if (!(worldObject.ProtoStaticWorldObject is IProtoObjectWithAccessMode protoObjectWithAccessMode))
            {
                throw new Exception("This world object doesn't have an access mode");
            }

            if (mode == WorldObjectAccessMode.Closed &&
                !protoObjectWithAccessMode.IsClosedAccessModeAvailable)
            {
                throw new Exception("Closed access mode is not supported for " + protoObjectWithAccessMode);
            }

            var privateState = worldObject.GetPrivateState <IObjectWithAccessModePrivateState>();

            privateState.AccessMode = mode;
            Logger.Important($"Access mode changed: {mode}; {worldObject}", character);
        }
Ejemplo n.º 2
0
        private void ServerRemote_SetLightMode(IStaticWorldObject lightObject, ObjectLightMode mode)
        {
            var character = ServerRemoteContext.Character;

            if (!InteractionCheckerSystem.SharedHasInteraction(character, lightObject, requirePrivateScope: true))
            {
                throw new Exception("The player character is not interacting with the light object");
            }

            var privateState = GetPrivateState(lightObject);
            var publicState  = GetPublicState(lightObject);

            privateState.Mode = mode;
            Logger.Important($"Light mode changed: {mode}, light: {lightObject}", character);

            this.ServerUpdateLight(lightObject,
                                   privateState,
                                   publicState,
                                   deltaTime: 0);
        }
        public static string ServerSetOwners(
            IWorldObject worldObject,
            List <string> newOwners,
            NetworkSyncList <string> currentOwners,
            ICharacter byOwner)
        {
            var protoObject = (IProtoObjectWithOwnersList)worldObject.ProtoGameObject;

            if (!protoObject.HasOwnersList)
            {
                throw new Exception("This object doesn't support owners list: " + worldObject);
            }

            if (!InteractionCheckerSystem.SharedHasInteraction(ServerRemoteContext.Character,
                                                               worldObject,
                                                               requirePrivateScope: true))
            {
                throw new Exception("The player character is not interacting with " + worldObject);
            }

            if (!currentOwners.Contains(byOwner.Name) &&
                !CreativeModeSystem.SharedIsInCreativeMode(byOwner))
            {
                return(DialogCannotSetOwners_MessageNotOwner);
            }

            if (!((IProtoObjectWithOwnersList)worldObject.ProtoGameObject)
                .SharedCanEditOwners(worldObject, byOwner))
            {
                return(DialogCannotSetOwners_MessageCannotEdit);
            }

            currentOwners.GetDiff(newOwners, out var ownersToAdd, out var ownersToRemove);
            if (ownersToRemove.Count > 0 &&
                currentOwners.Count == ownersToRemove.Count)
            {
                return(DialogCannotSetOwners_MessageCannotRemoveLastOwner);
            }

            if (ownersToRemove.Contains(byOwner.Name))
            {
                return(DialogCannotSetOwners_MessageCannotRemoveSelf);
            }

            if (ownersToAdd.Count == 0 &&
                ownersToRemove.Count == 0)
            {
                Logger.Warning(
                    "No need to change the owners - the new owners list is the same as the current owners list: "
                    + worldObject,
                    characterRelated: byOwner);
                return(null);
            }

            foreach (var n in ownersToAdd)
            {
                var name        = n;
                var playerToAdd = Api.Server.Characters.GetPlayerCharacter(name);
                if (playerToAdd == null)
                {
                    return(string.Format(DialogCannotSetOwners_MessageFormatPlayerNotFound, name));
                }

                // get proper player name
                name = playerToAdd.Name;
                if (currentOwners.AddIfNotContains(name))
                {
                    Api.Logger.Important($"Added owner: {name}; {worldObject}", characterRelated: byOwner);
                }
            }

            foreach (var name in ownersToRemove)
            {
                if (!currentOwners.Remove(name))
                {
                    continue;
                }

                Api.Logger.Important($"Removed owner: {name}; {worldObject}", characterRelated: byOwner);

                var removedPlayer = Api.Server.Characters.GetPlayerCharacter(name);
                if (removedPlayer == null)
                {
                    continue;
                }

                InteractableWorldObjectHelper.ServerTryAbortInteraction(removedPlayer, worldObject);
            }

            ServerInvokeOwnersChangedEvent(worldObject);
            return(null);
        }
Ejemplo n.º 4
0
        protected override void CheckInteractionQueue()
        {
            if (openedLootContainer != null)
            {
                if (InteractionCheckerSystem.SharedHasInteraction(CurrentCharacter, openedLootContainer, true))
                {
                    // We get container private state, now take all items from container.
                    var q      = openedLootContainer.GetPrivateState <LootContainerPrivateState>();
                    var result =
                        CurrentCharacter.ProtoCharacter.ClientTryTakeAllItems(CurrentCharacter, q.ItemsContainer, true);
                    if (result.MovedItems.Count > 0)
                    {
                        NotificationSystem.ClientShowItemsNotification(
                            itemsChangedCount: result.MovedItems
                            .GroupBy(p => p.Key.ProtoItem)
                            .ToDictionary(p => p.Key, p => p.Sum(v => v.Value)));
                    }
                    InteractionCheckerSystem.CancelCurrentInteraction(CurrentCharacter);
                }
                else if (openedLootContainer.ProtoWorldObject
                         .SharedCanInteract(CurrentCharacter, openedLootContainer, false))
                {
                    // Waiting for container private state from server.
                    return;
                }
                openedLootContainer = null;
                readyForInteraction = true;
            }

            if (!readyForInteraction)
            {
                return;
            }

            // Remove from queue while it have object and they in our whitelist if:
            //  - object is destroyed
            //  - if object is container that we already have looted
            //  - if object not IProtoObjectGatherable
            //  - if we can not interact with object right now
            //  - if we can not gather anything from object
            while (interactionQueue.Count != 0 && EnabledEntityList.Contains(interactionQueue[0].ProtoGameObject) &&
                   (interactionQueue[0].IsDestroyed ||
                    (lastActionState != null &&
                     lastActionState.TargetWorldObject == interactionQueue[0] &&
                     lastActionState.IsCompleted &&
                     !lastActionState.IsCancelled &&
                     !lastActionState.IsCancelledByServer) ||
                    !(interactionQueue[0].ProtoGameObject is IProtoObjectGatherable protoGatherable) ||
                    !protoGatherable.SharedCanInteract(CurrentCharacter, interactionQueue[0], false) ||
                    !protoGatherable.SharedIsCanGather(interactionQueue[0])))
            {
                interactionQueue.RemoveAt(0);
            }

            if (interactionQueue.Count == 0)
            {
                return;
            }

            var request = new WorldActionRequest(CurrentCharacter, interactionQueue[0]);

            GatheringSystem.Instance.SharedStartAction(request);
        }
Ejemplo n.º 5
0
        public ObjectLandClaimCanUpgradeCheckResult SharedCanUpgrade(
            IStaticWorldObject worldObjectLandClaim,
            IProtoObjectLandClaim protoUpgradedLandClaim,
            ICharacter character,
            out IConstructionUpgradeEntryReadOnly upgradeEntry,
            bool writeErrors = true)
        {
            if (!this.SharedCanInteract(character,
                                        worldObjectLandClaim,
                                        writeToLog: writeErrors))
            {
                upgradeEntry = null;
                return(ObjectLandClaimCanUpgradeCheckResult.ErrorUnknown);
            }

            upgradeEntry = null;
            foreach (var entry in this.ConfigUpgrade.Entries)
            {
                if (entry.ProtoStructure == protoUpgradedLandClaim)
                {
                    upgradeEntry = entry;
                    break;
                }
            }

            var currentLandClaimArea = GetPublicState(worldObjectLandClaim).LandClaimAreaObject;
            var founderName          = LandClaimArea.GetPrivateState(currentLandClaimArea).LandClaimFounder;

            var result = ObjectLandClaimCanUpgradeCheckResult.Success;

            if (upgradeEntry == null)
            {
                result = ObjectLandClaimCanUpgradeCheckResult.ErrorUnknown;
            }

            if (result == ObjectLandClaimCanUpgradeCheckResult.Success)
            {
                if (character.Name != founderName &&
                    !CreativeModeSystem.SharedIsInCreativeMode(character))
                {
                    result = ObjectLandClaimCanUpgradeCheckResult.ErrorNotFounder;
                }
            }

            if (result == ObjectLandClaimCanUpgradeCheckResult.Success)
            {
                // validate player know the tech, have enough items, etc
                if (!upgradeEntry.CheckRequirementsSatisfied(character))
                {
                    upgradeEntry = null;
                    result       = ObjectLandClaimCanUpgradeCheckResult.ErrorRequirementsNotSatisfied;
                }
            }

            if (result == ObjectLandClaimCanUpgradeCheckResult.Success)
            {
                // check there will be no intersection with other areas
                var landClaimCenterTilePosition =
                    LandClaimSystem.SharedCalculateLandClaimObjectCenterTilePosition(worldObjectLandClaim);
                if (!LandClaimSystem.SharedCheckCanPlaceOrUpgradeLandClaimThere(
                        protoUpgradedLandClaim,
                        landClaimCenterTilePosition,
                        character))
                {
                    result = ObjectLandClaimCanUpgradeCheckResult.ErrorAreaIntersection;
                }
            }

            if (result == ObjectLandClaimCanUpgradeCheckResult.Success)
            {
                if (!InteractionCheckerSystem.SharedHasInteraction(character,
                                                                   worldObjectLandClaim,
                                                                   requirePrivateScope: true))
                {
                    result = ObjectLandClaimCanUpgradeCheckResult.ErrorNoActiveInteraction;
                }
            }

            if (result == ObjectLandClaimCanUpgradeCheckResult.Success)
            {
                if (LandClaimSystem.SharedIsUnderRaidBlock(character, worldObjectLandClaim))
                {
                    // the building is in an area under the raid
                    LandClaimSystem.SharedSendNotificationActionForbiddenUnderRaidblock(character);
                    result = ObjectLandClaimCanUpgradeCheckResult.ErrorUnderRaid;
                }
            }

            if (writeErrors &&
                result != ObjectLandClaimCanUpgradeCheckResult.Success)
            {
                Logger.Warning(
                    $"Can\'t upgrade: {worldObjectLandClaim} to {protoUpgradedLandClaim}: error code - {result}",
                    character);
            }

            return(result);
        }