net.dv8tion.jda.core.managers.GuildManagerUpdatable.java Source code

Java tutorial

Introduction

Here is the source code for net.dv8tion.jda.core.managers.GuildManagerUpdatable.java

Source

/*
 *     Copyright 2015-2017 Austin Keener & Michael Ritter & Florian Spie
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package net.dv8tion.jda.core.managers;

import net.dv8tion.jda.core.JDA;
import net.dv8tion.jda.core.Permission;
import net.dv8tion.jda.core.Region;
import net.dv8tion.jda.core.entities.Guild;
import net.dv8tion.jda.core.entities.Icon;
import net.dv8tion.jda.core.entities.VoiceChannel;
import net.dv8tion.jda.core.exceptions.GuildUnavailableException;
import net.dv8tion.jda.core.exceptions.PermissionException;
import net.dv8tion.jda.core.managers.fields.GuildField;
import net.dv8tion.jda.core.requests.Request;
import net.dv8tion.jda.core.requests.Response;
import net.dv8tion.jda.core.requests.Route;
import net.dv8tion.jda.core.requests.restaction.AuditableRestAction;
import net.dv8tion.jda.core.utils.Checks;
import org.json.JSONObject;

import javax.annotation.CheckReturnValue;

/**
 * An {@link #update() updatable} manager that allows
 * to modify guild settings like the {@link #getNameField() name} or the {@link #getSplashField() splash}.
 *
 * <p>This manager allows to modify multiple fields at once
 * by getting the {@link net.dv8tion.jda.core.managers.fields.GuildField GuildField} for specific
 * properties and setting or resetting their values; followed by a call of {@link #update()}!
 *
 * <p>The {@link net.dv8tion.jda.core.managers.GuildManager GuildManager} implementation
 * simplifies this process by giving simple setters that return the {@link #update() update} {@link net.dv8tion.jda.core.requests.RestAction RestAction}
 *
 * <p><b>Note</b>: To {@link #update() update} this manager
 * the currently logged in account requires the Permission {@link net.dv8tion.jda.core.Permission#MANAGE_SERVER MANAGE_SERVER}
 *
 * <p><b>To use moderation abilities like creating Roles or banning Members use {@link net.dv8tion.jda.core.managers.GuildController GuildController}</b>
 */
public class GuildManagerUpdatable {
    protected final Guild guild;

    protected GuildField<String> name;
    protected GuildField<Icon> icon;
    protected GuildField<Icon> splash;
    protected GuildField<Region> region;
    protected GuildField<VoiceChannel> afkChannel;
    protected GuildField<Guild.VerificationLevel> verificationLevel;
    protected GuildField<Guild.NotificationLevel> defaultNotificationLevel;
    protected GuildField<Guild.MFALevel> mfaLevel;
    protected GuildField<Guild.ExplicitContentLevel> explicitContentLevel;
    protected GuildField<Guild.Timeout> timeout;

    /**
     * Creates a new GuildManagerUpdatable instance
     *
     * @param guild
     *        The {@link net.dv8tion.jda.core.entities.Guild Guild} that should be modified
     */
    public GuildManagerUpdatable(Guild guild) {
        this.guild = guild;
        setupFields();
    }

    /**
     * The {@link net.dv8tion.jda.core.JDA JDA} instance of this Manager
     *
     * @return the corresponding JDA instance
     */
    public JDA getJDA() {
        return guild.getJDA();
    }

    /**
     * The {@link net.dv8tion.jda.core.entities.Guild Guild} object of this Manager.
     * Useful if this Manager was returned via a create function
     *
     * @return The {@link net.dv8tion.jda.core.entities.Guild Guild} of this Manager
     */
    public Guild getGuild() {
        return guild;
    }

    /**
     * An {@link net.dv8tion.jda.core.managers.fields.GuildField GuildField}
     * for the <b><u>name</u></b> of the selected {@link net.dv8tion.jda.core.entities.Guild Guild}.
     *
     * <p>To set the value use {@link net.dv8tion.jda.core.managers.fields.Field#setValue(Object) setValue(String)}
     * on the returned {@link net.dv8tion.jda.core.managers.fields.GuildField GuildField} instance.
     *
     * <p>A guild name <b>must not</b> be {@code null} nor less than 2 characters or more than 100 characters long!
     * <br>Otherwise {@link net.dv8tion.jda.core.managers.fields.Field#setValue(Object) Field.setValue(...)} will
     * throw an {@link IllegalArgumentException IllegalArgumentException}.
     *
     * @throws net.dv8tion.jda.core.exceptions.GuildUnavailableException
     *         If the Guild is temporarily not {@link net.dv8tion.jda.core.entities.Guild#isAvailable() available}
     *
     * @return {@link net.dv8tion.jda.core.managers.fields.GuildField GuildField} - Type: {@code String}
     */
    public GuildField<String> getNameField() {
        checkAvailable();

        return name;
    }

    /**
     * An {@link net.dv8tion.jda.core.managers.fields.GuildField GuildField}
     * for the {@link net.dv8tion.jda.core.Region Region} of the selected {@link net.dv8tion.jda.core.entities.Guild Guild}.
     *
     * <p>To set the value use {@link net.dv8tion.jda.core.managers.fields.Field#setValue(Object) setValue(Region)}
     * on the returned {@link net.dv8tion.jda.core.managers.fields.GuildField GuildField} instance.
     *
     * <p>A guild region <b>must not</b> be {@code null} nor {@link net.dv8tion.jda.core.Region#UNKNOWN Region.UNKNOWN}!
     * <br>Otherwise {@link net.dv8tion.jda.core.managers.fields.Field#setValue(Object) Field.setValue(...)} will
     * throw an {@link IllegalArgumentException IllegalArgumentException}.
     *
     * @throws net.dv8tion.jda.core.exceptions.GuildUnavailableException
     *         If the Guild is temporarily not {@link net.dv8tion.jda.core.entities.Guild#isAvailable() available}
     *
     * @return {@link net.dv8tion.jda.core.managers.fields.GuildField GuildField} - Type: {@link net.dv8tion.jda.core.Region Region}
     */
    public GuildField<Region> getRegionField() {
        checkAvailable();

        return region;
    }

    /**
     * An {@link net.dv8tion.jda.core.managers.fields.GuildField GuildField}
     * for the {@link net.dv8tion.jda.core.entities.Icon Icon} of the selected {@link net.dv8tion.jda.core.entities.Guild Guild}.
     * <br>To reset the Icon of a Guild provide {@code null} to {@link net.dv8tion.jda.core.managers.fields.Field#setValue(Object) setValue(Icon)}.
     *
     * <p>To set the value use {@link net.dv8tion.jda.core.managers.fields.Field#setValue(Object) setValue(Icon)}
     * on the returned {@link net.dv8tion.jda.core.managers.fields.GuildField GuildField} instance.
     *
     * @throws net.dv8tion.jda.core.exceptions.GuildUnavailableException
     *         If the Guild is temporarily not {@link net.dv8tion.jda.core.entities.Guild#isAvailable() available}
     *
     * @return {@link net.dv8tion.jda.core.managers.fields.GuildField GuildField} - Type: {@link net.dv8tion.jda.core.entities.Icon Icon}
     */
    public GuildField<Icon> getIconField() {
        checkAvailable();

        return icon;
    }

    /**
     * An {@link net.dv8tion.jda.core.managers.fields.GuildField GuildField}
     * for the <b><u>splash {@link net.dv8tion.jda.core.entities.Icon Icon}</u></b> of the selected {@link net.dv8tion.jda.core.entities.Guild Guild}.
     * <br>To reset the splash of a Guild provide {@code null} to {@link net.dv8tion.jda.core.managers.fields.Field#setValue(Object) setValue(Icon)}.
     *
     * <p>To set the value use {@link net.dv8tion.jda.core.managers.fields.Field#setValue(Object) setValue(Icon)}
     * on the returned {@link net.dv8tion.jda.core.managers.fields.GuildField GuildField} instance.
     *
     * @throws net.dv8tion.jda.core.exceptions.GuildUnavailableException
     *         If the Guild is temporarily not {@link net.dv8tion.jda.core.entities.Guild#isAvailable() available}
     *
     * @return {@link net.dv8tion.jda.core.managers.fields.GuildField GuildField} - Type: {@link net.dv8tion.jda.core.entities.Icon Icon}
     */
    public GuildField<Icon> getSplashField() {
        checkAvailable();

        return splash;
    }

    /**
     * An {@link net.dv8tion.jda.core.managers.fields.GuildField GuildField}
     * for the <b><u>AFK {@link net.dv8tion.jda.core.entities.VoiceChannel VoiceChannel}</u></b> of the selected {@link net.dv8tion.jda.core.entities.Guild Guild}.
     * <br>To reset the channel of a Guild provide {@code null} to {@link net.dv8tion.jda.core.managers.fields.Field#setValue(Object) setValue(VoiceChannel)}.
     *
     * <p>To set the value use {@link net.dv8tion.jda.core.managers.fields.Field#setValue(Object) setValue(VoiceChannel)}
     * on the returned {@link net.dv8tion.jda.core.managers.fields.GuildField GuildField} instance.
     *
     * <p>A guild afk channel <b>must</b> be from this Guild!
     * <br>Otherwise {@link net.dv8tion.jda.core.managers.fields.Field#setValue(Object) Field.setValue(...)} will
     * throw an {@link IllegalArgumentException IllegalArgumentException}.
     *
     * @throws net.dv8tion.jda.core.exceptions.GuildUnavailableException
     *         If the Guild is temporarily not {@link net.dv8tion.jda.core.entities.Guild#isAvailable() available}
     *
     * @return {@link net.dv8tion.jda.core.managers.fields.GuildField GuildField} - Type: {@link net.dv8tion.jda.core.entities.VoiceChannel VoiceChannel}
     */
    public GuildField<VoiceChannel> getAfkChannelField() {
        checkAvailable();

        return afkChannel;
    }

    /**
     * An {@link net.dv8tion.jda.core.managers.fields.GuildField GuildField}
     * for the <b><u>AFK {@link net.dv8tion.jda.core.entities.Guild.Timeout Timeout}</u></b> of the selected {@link net.dv8tion.jda.core.entities.Guild Guild}.
     * <br>Valid timeouts (in seconds) are 60, 300, 900, 1800, 3600. Default value is {@code 300} (5 minutes)
     *
     * <p>To set the value use {@link net.dv8tion.jda.core.managers.fields.Field#setValue(Object) setValue(Guild.Timeout)}
     * on the returned {@link net.dv8tion.jda.core.managers.fields.GuildField GuildField} instance.
     *
     * <p>A guild afk timeout <b>must not</b> be {@code null}!
     * <br>Otherwise {@link net.dv8tion.jda.core.managers.fields.Field#setValue(Object) Field.setValue(...)} will
     * throw an {@link IllegalArgumentException IllegalArgumentException}.
     *
     * @throws net.dv8tion.jda.core.exceptions.GuildUnavailableException
     *         If the Guild is temporarily not {@link net.dv8tion.jda.core.entities.Guild#isAvailable() available}
     *
     * @return {@link net.dv8tion.jda.core.managers.fields.GuildField GuildField} - Type: {@link net.dv8tion.jda.core.entities.Guild.Timeout Guild.Timeout}
     */
    public GuildField<Guild.Timeout> getAfkTimeoutField() {
        checkAvailable();

        return timeout;
    }

    /**
     * An {@link net.dv8tion.jda.core.managers.fields.GuildField GuildField}
     * for the <b><u>{@link net.dv8tion.jda.core.entities.Guild.VerificationLevel Verification Level}</u></b> of the selected {@link net.dv8tion.jda.core.entities.Guild Guild}.
     * <br>The default value is {@link net.dv8tion.jda.core.entities.Guild.VerificationLevel#NONE NONE}
     *
     * <p>To set the value use {@link net.dv8tion.jda.core.managers.fields.Field#setValue(Object) setValue(Guild.VerificationLevel)}
     * on the returned {@link net.dv8tion.jda.core.managers.fields.GuildField GuildField} instance.
     *
     * <p>A guild verification level <b>must not</b> be {@code null} or {@link net.dv8tion.jda.core.entities.Guild.VerificationLevel#UNKNOWN UNKNOWN}!
     * <br>Otherwise {@link net.dv8tion.jda.core.managers.fields.Field#setValue(Object) Field.setValue(...)} will
     * throw an {@link IllegalArgumentException IllegalArgumentException}.
     *
     * @throws net.dv8tion.jda.core.exceptions.GuildUnavailableException
     *         If the Guild is temporarily not {@link net.dv8tion.jda.core.entities.Guild#isAvailable() available}
     *
     * @return {@link net.dv8tion.jda.core.managers.fields.GuildField GuildField} - Type: {@link net.dv8tion.jda.core.entities.Guild.VerificationLevel Guild.VerificationLevel}
     */
    public GuildField<Guild.VerificationLevel> getVerificationLevelField() {
        checkAvailable();

        return verificationLevel;
    }

    /**
     * An {@link net.dv8tion.jda.core.managers.fields.GuildField GuildField}
     * for the <b><u>{@link net.dv8tion.jda.core.entities.Guild.NotificationLevel Notification Level}</u></b> of the selected {@link net.dv8tion.jda.core.entities.Guild Guild}.
     * <br>The default value is {@link net.dv8tion.jda.core.entities.Guild.NotificationLevel#ALL_MESSAGES ALL_MESSAGES}
     *
     * <p>To set the value use {@link net.dv8tion.jda.core.managers.fields.Field#setValue(Object) setValue(Guild.NotificationLevel)}
     * on the returned {@link net.dv8tion.jda.core.managers.fields.GuildField GuildField} instance.
     *
     * <p>A guild notification level <b>must not</b> be {@code null} or {@link net.dv8tion.jda.core.entities.Guild.NotificationLevel#UNKNOWN UNKNOWN}!
     * <br>Otherwise {@link net.dv8tion.jda.core.managers.fields.Field#setValue(Object) Field.setValue(...)} will
     * throw an {@link IllegalArgumentException IllegalArgumentException}.
     *
     * @throws net.dv8tion.jda.core.exceptions.GuildUnavailableException
     *         If the Guild is temporarily not {@link net.dv8tion.jda.core.entities.Guild#isAvailable() available}
     *
     * @return {@link net.dv8tion.jda.core.managers.fields.GuildField GuildField} - Type: {@link net.dv8tion.jda.core.entities.Guild.NotificationLevel Guild.NotificationLevel}
     */
    public GuildField<Guild.NotificationLevel> getDefaultNotificationLevelField() {
        checkAvailable();

        return defaultNotificationLevel;
    }

    /**
     * An {@link net.dv8tion.jda.core.managers.fields.GuildField GuildField}
     * for the <b><u>{@link net.dv8tion.jda.core.entities.Guild.MFALevel MFA Level}</u></b> of the selected {@link net.dv8tion.jda.core.entities.Guild Guild}.
     * <br>The default value is {@link net.dv8tion.jda.core.entities.Guild.MFALevel#NONE NONE}
     *
     * <p>To set the value use {@link net.dv8tion.jda.core.managers.fields.Field#setValue(Object) setValue(Guild.MFALevel)}
     * on the returned {@link net.dv8tion.jda.core.managers.fields.GuildField GuildField} instance.
     *
     * <p>A guild mfa level <b>must not</b> be {@code null} or {@link net.dv8tion.jda.core.entities.Guild.MFALevel#UNKNOWN UNKNOWN}!
     * <br>Otherwise {@link net.dv8tion.jda.core.managers.fields.Field#setValue(Object) Field.setValue(...)} will
     * throw an {@link IllegalArgumentException IllegalArgumentException}.
     *
     * @throws net.dv8tion.jda.core.exceptions.GuildUnavailableException
     *         If the Guild is temporarily not {@link net.dv8tion.jda.core.entities.Guild#isAvailable() available}
     *
     * @return {@link net.dv8tion.jda.core.managers.fields.GuildField GuildField} - Type: {@link net.dv8tion.jda.core.entities.Guild.MFALevel Guild.MFALevel}
     */
    public GuildField<Guild.MFALevel> getRequiredMFALevelField() {
        checkAvailable();
        return mfaLevel;
    }

    /**
     * An {@link net.dv8tion.jda.core.managers.fields.GuildField GuildField}
     * for the <b><u>{@link net.dv8tion.jda.core.entities.Guild.ExplicitContentLevel Explicit Content Level}</u></b> of the selected {@link net.dv8tion.jda.core.entities.Guild Guild}.
     * <br>The default value is {@link net.dv8tion.jda.core.entities.Guild.ExplicitContentLevel#OFF OFF}
     *
     * <p>To set the value use {@link net.dv8tion.jda.core.managers.fields.Field#setValue(Object) setValue(Guild.ExplicitContentLevel)}
     * on the returned {@link net.dv8tion.jda.core.managers.fields.GuildField GuildField} instance.
     *
     * <p>A guild explicit content level <b>must not</b> be {@code null} or {@link net.dv8tion.jda.core.entities.Guild.ExplicitContentLevel#UNKNOWN UNKNOWN}!
     * <br>Otherwise {@link net.dv8tion.jda.core.managers.fields.Field#setValue(Object) Field.setValue(...)} will
     * throw an {@link IllegalArgumentException IllegalArgumentException}.
     *
     * @throws net.dv8tion.jda.core.exceptions.GuildUnavailableException
     *         If the Guild is temporarily not {@link net.dv8tion.jda.core.entities.Guild#isAvailable() available}
     *
     * @return {@link net.dv8tion.jda.core.managers.fields.GuildField GuildField} - Type: {@link net.dv8tion.jda.core.entities.Guild.ExplicitContentLevel Guild.ExplicitContentLevel}
     */
    public GuildField<Guild.ExplicitContentLevel> getExplicitContentLevelField() {
        checkAvailable();
        return explicitContentLevel;
    }

    /**
     * Resets all queued updates. So the next call to {@link #update()} will change nothing.
     * <br>This is automatically called by {@link #update()}
     */
    public void reset() {
        this.name.reset();
        this.region.reset();
        this.timeout.reset();
        this.icon.reset();
        this.splash.reset();
        this.afkChannel.reset();
        this.verificationLevel.reset();
        this.defaultNotificationLevel.reset();
        this.mfaLevel.reset();
    }

    /**
     * Creates a new {@link net.dv8tion.jda.core.requests.RestAction RestAction} instance
     * that will apply <b>all</b> changes that have been made to this manager instance.
     * <br>If no changes have been made this will simply return {@link net.dv8tion.jda.core.requests.RestAction.EmptyRestAction EmptyRestAction}.
     *
     * <p>Before applying new changes it is recommended to call {@link #reset()} to reset previous changes.
     * <br>This is automatically called if this method returns successfully.
     *
     * <p>Possible {@link net.dv8tion.jda.core.requests.ErrorResponse ErrorResponses} for this
     * update include the following:
     * <ul>
     *      <li>{@link net.dv8tion.jda.core.requests.ErrorResponse#UNKNOWN_GUILD UNKNOWN_GUILD}
     *      <br>If the Guild was deleted before finishing the task</li>
     *
     *      <li>{@link net.dv8tion.jda.core.requests.ErrorResponse#MISSING_PERMISSIONS MISSING_PERMISSIONS}
     *      <br>If the currently logged in account loses the {@link net.dv8tion.jda.core.Permission#MANAGE_SERVER MANAGE_SERVER Permission}
     *          before finishing the task</li>
     * </ul>
     *
     * @throws net.dv8tion.jda.core.exceptions.PermissionException
     *         If the currently logged in account does not have the Permission {@link net.dv8tion.jda.core.Permission#MANAGE_SERVER MANAGE_SERVER}
     *         in the underlying {@link net.dv8tion.jda.core.entities.Guild Guild}
     * @throws net.dv8tion.jda.core.exceptions.GuildUnavailableException
     *         If the Guild is temporarily not {@link net.dv8tion.jda.core.entities.Guild#isAvailable() available}
     *
     * @return {@link net.dv8tion.jda.core.requests.restaction.AuditableRestAction AuditableRestAction}
     *         <br>Applies all changes that have been made in a single api-call.
     */
    @CheckReturnValue
    public AuditableRestAction<Void> update() {
        checkAvailable();
        checkPermission(Permission.MANAGE_SERVER);

        if (!needToUpdate())
            return new AuditableRestAction.EmptyRestAction<>(getJDA(), null);

        JSONObject body = new JSONObject().put("name", guild.getName());
        if (name.shouldUpdate())
            body.put("name", name.getValue());
        if (region.shouldUpdate())
            body.put("region", region.getValue().getKey());
        if (timeout.shouldUpdate())
            body.put("afk_timeout", timeout.getValue().getSeconds());
        if (icon.shouldUpdate())
            body.put("icon", icon.getValue() == null ? JSONObject.NULL : icon.getValue().getEncoding());
        if (splash.shouldUpdate())
            body.put("splash", splash.getValue() == null ? JSONObject.NULL : splash.getValue().getEncoding());
        if (afkChannel.shouldUpdate())
            body.put("afk_channel_id",
                    afkChannel.getValue() == null ? JSONObject.NULL : afkChannel.getValue().getId());
        if (verificationLevel.shouldUpdate())
            body.put("verification_level", verificationLevel.getValue().getKey());
        if (defaultNotificationLevel.shouldUpdate())
            body.put("default_notification_level", defaultNotificationLevel.getValue().getKey());
        if (mfaLevel.shouldUpdate())
            body.put("mfa_level", mfaLevel.getValue().getKey());
        if (explicitContentLevel.shouldUpdate())
            body.put("explicit_content_filter", explicitContentLevel.getValue().getKey());

        reset(); //now that we've built our JSON object, reset the manager back to the non-modified state
        Route.CompiledRoute route = Route.Guilds.MODIFY_GUILD.compile(guild.getId());
        return new AuditableRestAction<Void>(guild.getJDA(), route, body) {
            @Override
            protected void handleResponse(Response response, Request<Void> request) {
                if (response.isOk())
                    request.onSuccess(null);
                else
                    request.onFailure(response);
            }
        };
    }

    protected boolean needToUpdate() {
        return name.shouldUpdate() || region.shouldUpdate() || timeout.shouldUpdate() || icon.shouldUpdate()
                || splash.shouldUpdate() || afkChannel.shouldUpdate() || verificationLevel.shouldUpdate()
                || defaultNotificationLevel.shouldUpdate() || mfaLevel.shouldUpdate()
                || explicitContentLevel.shouldUpdate();
    }

    protected void checkAvailable() {
        if (!guild.isAvailable())
            throw new GuildUnavailableException();
    }

    protected void checkPermission(Permission perm) {
        if (!guild.getSelfMember().hasPermission(perm))
            throw new PermissionException(perm);
    }

    protected void setupFields() {
        this.name = new GuildField<String>(this, guild::getName) {
            @Override
            public void checkValue(String value) {
                Checks.notNull(value, "guild name");
                if (value.length() < 2 || value.length() > 100)
                    throw new IllegalArgumentException("Provided guild name must be 2 to 100 characters in length");
            }
        };

        this.timeout = new GuildField<Guild.Timeout>(this, guild::getAfkTimeout) {
            @Override
            public void checkValue(Guild.Timeout value) {
                Checks.notNull(value, "Timeout");
            }
        };

        this.icon = new GuildField<Icon>(this, null) {
            @Override
            public void checkValue(Icon value) {
            }

            @Override
            public Icon getOriginalValue() {
                throw new UnsupportedOperationException(
                        "Cannot easily provide the original Icon. Use Guild#getIconUrl() and download it yourself.");
            }

            @Override
            public boolean shouldUpdate() {
                return isSet();
            }
        };

        this.splash = new GuildField<Icon>(this, null) {
            @Override
            public void checkValue(Icon value) {
            }

            @Override
            public Icon getOriginalValue() {
                throw new UnsupportedOperationException(
                        "Cannot easily provide the original Splash. Use Guild#getSplashUrl() and download it yourself.");
            }

            @Override
            public boolean shouldUpdate() {
                return isSet();
            }
        };

        this.region = new GuildField<Region>(this, guild::getRegion) {
            @Override
            public void checkValue(Region value) {
                Checks.notNull(value, "Region");
                if (value == Region.UNKNOWN)
                    throw new IllegalArgumentException("Cannot set Guild Region to UNKNOWN!");
            }
        };

        this.afkChannel = new GuildField<VoiceChannel>(this, guild::getAfkChannel) {
            @Override
            public void checkValue(VoiceChannel value) {
                if (value != null && !guild.equals(value.getGuild()))
                    throw new IllegalArgumentException("Provided AFK Channel is not from this Guild!");
            }
        };

        this.verificationLevel = new GuildField<Guild.VerificationLevel>(this, guild::getVerificationLevel) {
            @Override
            public void checkValue(Guild.VerificationLevel value) {
                Checks.notNull(value, "VerificationLevel");
                if (value == Guild.VerificationLevel.UNKNOWN)
                    throw new IllegalArgumentException("Cannot set Guild VerificationLevel to UNKNOWN");
            }
        };

        this.defaultNotificationLevel = new GuildField<Guild.NotificationLevel>(this,
                guild::getDefaultNotificationLevel) {
            @Override
            public void checkValue(Guild.NotificationLevel value) {
                Checks.notNull(value, "NotificationLevel");
                if (value == Guild.NotificationLevel.UNKNOWN)
                    throw new IllegalArgumentException("Cannot set NotificationLevel to UNKNOWN");
            }
        };

        this.mfaLevel = new GuildField<Guild.MFALevel>(this, guild::getRequiredMFALevel) {
            @Override
            public void checkValue(Guild.MFALevel value) {
                Checks.notNull(value, "MFALevel");
                if (value == Guild.MFALevel.UNKNOWN)
                    throw new IllegalArgumentException("Cannot set MFALevel to UNKNOWN");
            }
        };

        this.explicitContentLevel = new GuildField<Guild.ExplicitContentLevel>(this,
                guild::getExplicitContentLevel) {
            @Override
            public void checkValue(Guild.ExplicitContentLevel value) {
                Checks.notNull(value, "ExplicitContentLevel");
                Checks.check(value != Guild.ExplicitContentLevel.UNKNOWN,
                        "Cannot set ExplicitContentLevel to UNKNOWN");
            }
        };
    }
}