コード例 #1
0
        public static bool ServerHasAccess(
            IWorldObject worldObject,
            ICharacter character,
            WorldObjectDirectAccessMode directAccessMode,
            WorldObjectFactionAccessModes factionAccessModes,
            bool writeToLog)
        {
            if (worldObject is IStaticWorldObject staticWorldObject)
            {
                if (LandClaimSystem.SharedIsWorldObjectOwnedByFaction(staticWorldObject, out var clanTag))
                {
                    if (ServerHasFactionAccess(character, clanTag, factionAccessModes))
                    {
                        return(true);
                    }

                    if (writeToLog)
                    {
                        Logger.Warning(
                            $"Character cannot interact with {worldObject} - no access.",
                            character);

                        Instance.CallClient(
                            character,
                            _ => _.ClientRemote_OnCannotInteractNoAccess(worldObject));
                    }

                    return(false);
                }
            }
            else if (worldObject.ProtoGameObject is IProtoVehicle)
            {
                var clanTag = worldObject.GetPublicState <VehiclePublicState>().ClanTag;
                if (string.IsNullOrEmpty(clanTag))
                {
                    // the vehicles don't have direct access mode, any owner has access
                    return(false);
                }

                return(ServerHasFactionAccess(character, clanTag, factionAccessModes));
            }

            switch (directAccessMode)
            {
            case WorldObjectDirectAccessMode.Closed:
            default:
                if (writeToLog)
                {
                    Logger.Warning(
                        $"Character cannot interact with {worldObject} - no access.",
                        character);

                    Instance.CallClient(
                        character,
                        _ => _.ClientRemote_OnCannotInteractNoAccess(worldObject));
                }

                return(false);

            case WorldObjectDirectAccessMode.OpensToEveryone:
                return(true);

            case WorldObjectDirectAccessMode.OpensToObjectOwners:
            case WorldObjectDirectAccessMode.OpensToObjectOwnersOrAreaOwners:
            {
                if (WorldObjectOwnersSystem.SharedIsOwner(character, worldObject))
                {
                    // an object owner
                    return(true);
                }

                // not an object owner
                if (directAccessMode == WorldObjectDirectAccessMode.OpensToObjectOwnersOrAreaOwners)
                {
                    if (LandClaimSystem.SharedIsOwnedLand(worldObject.TilePosition,
                                                          character,
                                                          requireFactionPermission: false,
                                                          out _))
                    {
                        // an area owner
                        return(true);
                    }
                }

                if (CreativeModeSystem.SharedIsInCreativeMode(character))
                {
                    return(true);
                }

                // not an object owner and not an area owner
                if (writeToLog)
                {
                    WorldObjectOwnersSystem.ServerNotifyNotOwner(character,
                                                                 worldObject,
                                                                 isFactionAccess: false);
                }

                return(false);
            }
            }
        }
コード例 #2
0
 public static void ClientSetFactionAccessMode(
     IWorldObject worldObject,
     WorldObjectFactionAccessModes modes)
 {
     Instance.CallServer(_ => _.ServerRemote_SetFactionAccessMode(worldObject, modes));
 }
コード例 #3
0
        private void ServerRemote_SetFactionAccessMode(
            IWorldObject worldObject,
            WorldObjectFactionAccessModes modes)
        {
            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 faction = ServerGetOwningFaction(worldObject);

            if (faction is null)
            {
                throw new Exception("No faction");
            }

            if (!CreativeModeSystem.SharedIsInCreativeMode(character))
            {
                // verify permission to access object
                FactionSystem.ServerValidateHasAccessRights(
                    character,
                    SharedGetFactionAccessRightRequirementForObject(worldObject),
                    out var characterFaction);

                if (!ReferenceEquals(faction, characterFaction))
                {
                    throw new Exception(worldObject + " belongs to another faction - cannot modify its access");
                }
            }

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

            if ((modes == WorldObjectFactionAccessModes.Everyone ||
                 modes == WorldObjectFactionAccessModes.AllyFactionMembers) &&
                !protoObjectWithAccessMode.IsEveryoneAccessModeAvailable)
            {
                throw new Exception("Everyone and Ally access modes are not supported for "
                                    + protoObjectWithAccessMode);
            }

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

            if (!protoObjectWithAccessMode.CanChangeFactionRoleAccessForSelfRole)
            {
                var role = FactionSystem.ServerGetRole(character);
                switch (role)
                {
                case FactionMemberRole.Officer1
                    when previousModes.HasFlag(WorldObjectFactionAccessModes.Officer1)
                    ^ modes.HasFlag(WorldObjectFactionAccessModes.Officer1):

                case FactionMemberRole.Officer2
                    when previousModes.HasFlag(WorldObjectFactionAccessModes.Officer2)
                    ^ modes.HasFlag(WorldObjectFactionAccessModes.Officer2):

                case FactionMemberRole.Officer3
                    when previousModes.HasFlag(WorldObjectFactionAccessModes.Officer3)
                    ^ modes.HasFlag(WorldObjectFactionAccessModes.Officer3):
                    throw new Exception("Cannot change access setting for self role " + protoObjectWithAccessMode);
                }
            }

            if (previousModes == modes)
            {
                return;
            }

            privateState.FactionAccessMode = modes;
            Logger.Info($"Faction access mode changed: {modes}; {worldObject}", character);
        }
コード例 #4
0
        private static bool ServerHasFactionAccess(
            ICharacter character,
            string objectClanTag,
            WorldObjectFactionAccessModes factionAccessModes)
        {
            if (factionAccessModes == WorldObjectFactionAccessModes.Closed)
            {
                // always closed
                return(false);
            }

            if (factionAccessModes == WorldObjectFactionAccessModes.Everyone)
            {
                // always opened
                return(true);
            }

            var playerClanTag = FactionSystem.SharedGetClanTag(character);

            if (string.IsNullOrEmpty(playerClanTag))
            {
                // player don't have a faction
                return(false);
            }

            if (factionAccessModes.HasFlag(WorldObjectFactionAccessModes.AllyFactionMembers))
            {
                if (objectClanTag == playerClanTag)
                {
                    // current faction also allowed
                    return(true);
                }

                var objectFaction = FactionSystem.ServerGetFactionByClanTag(objectClanTag);
                return(FactionSystem.SharedGetFactionDiplomacyStatus(objectFaction, playerClanTag)
                       == FactionDiplomacyStatus.Ally);
            }

            // all further checks are only for the current faction
            if (objectClanTag != playerClanTag)
            {
                return(false);
            }

            if (factionAccessModes.HasFlag(WorldObjectFactionAccessModes.AllFactionMembers))
            {
                // all current faction members allowed
                return(true);
            }

            // only a specific role or roles are allowed
            var characterRole = FactionSystem.ServerGetRole(character);

            return(CheckAccessRights(WorldObjectFactionAccessModes.Leader, FactionMemberRole.Leader) ||
                   CheckAccessRights(WorldObjectFactionAccessModes.Officer1, FactionMemberRole.Officer1) ||
                   CheckAccessRights(WorldObjectFactionAccessModes.Officer2, FactionMemberRole.Officer2) ||
                   CheckAccessRights(WorldObjectFactionAccessModes.Officer3, FactionMemberRole.Officer3));

            bool CheckAccessRights(WorldObjectFactionAccessModes flag, FactionMemberRole role)
            => characterRole == role &&
            factionAccessModes.HasFlag(flag);
        }