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); } } }
public static void ClientSetFactionAccessMode( IWorldObject worldObject, WorldObjectFactionAccessModes modes) { Instance.CallServer(_ => _.ServerRemote_SetFactionAccessMode(worldObject, modes)); }
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); }
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); }