Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

willkroboth
Copy link
Collaborator

@willkroboth willkroboth commented Dec 27, 2022

The inspiration for this PR started in discord (see here).

This PR does two things:

  • allows platform-specific configuration options
    ...which is necessary for...
  • hook-paper-reload config option

First, CommandAPIConfig is now abstract and implements ChainableBuilder. Each platform should have a subclass of CommandAPIConfig, for example, CommandAPIBukkitConfig. Any information needed for configuring the platform specifically can be added to the platform implementation, such as shouldHookPaperReload.

public abstract class CommandAPIConfig<Impl extends CommandAPIConfig<Impl>> implements ChainableBuilder<Impl> {
	// The default configuration. This should mirror the commandapi-plugin config.yml file.
	boolean verboseOutput = false;
        ...

	public Impl verboseOutput(boolean value) {
		this.verboseOutput = value;
		return instance();
	}

        ...
}

public class CommandAPIBukkitConfig extends CommandAPIConfig<CommandAPIBukkitConfig> {
	JavaPlugin plugin;
	// Default configuration
	boolean shouldHookPaperReload = true;

	public CommandAPIBukkitConfig(JavaPlugin plugin) {
		this.plugin = plugin;
	}

	public CommandAPIBukkitConfig shouldHookPaperReload(boolean hooked) {
		this.shouldHookPaperReload = hooked;

		return this;
	}

	@Override
	public CommandAPIBukkitConfig instance() {
		return this;
	}
}

When a platform is loaded, it will now be passed the config object, which is packaged into an appropriate subclass of InternalConfig, which can be accessed later.

public abstract class CommandAPIBukkit<Source> ... {
	private static InternalBukkitConfig config;

	public static InternalBukkitConfig getConfiguration() {
		return config;
	}

	@Override
	public void onLoad(CommandAPIConfig<?> config) {
		if(config instanceof CommandAPIBukkitConfig bukkitConfig) {
			CommandAPIBukkit.config = new InternalBukkitConfig(bukkitConfig);
		} else {
			CommandAPI.logError("CommandAPIBukkit was loaded with non-Bukkit config!");
			CommandAPI.logError("Attempts to access Bukkit-specific config variables will fail!");
		}

		checkDependencies();
	}

	@Override
	public void onEnable() {
		JavaPlugin plugin = config.getPlugin();
		...
	}

        ...
}

public class InternalBukkitConfig extends InternalConfig {
	private final JavaPlugin plugin;
	private final boolean shouldHookPaperReload;

	public InternalBukkitConfig(CommandAPIBukkitConfig config) {
		super(config);
		this.plugin = config.plugin;
		this.shouldHookPaperReload = config.shouldHookPaperReload;
	}

	public JavaPlugin getPlugin() {
		return plugin;
	}

	public boolean shouldHookPaperReload() {
		return shouldHookPaperReload;
	}
}

Moving to the second point, when registering the event handler on the ServerResourcesReloadedEvent, the Bukkit-specific, hook-paper-reload config option is now considered.

public class PaperImplementations {
	public void registerReloadHandler(Plugin plugin) {
		if (isPaperPresent && CommandAPIBukkit.getConfiguration().shouldHookPaperReload()) {
			Bukkit.getServer().getPluginManager().registerEvents(new Listener() {

				@EventHandler
				public void onServerReloadResources(ServerResourcesReloadedEvent event) {
					CommandAPI.logNormal("/minecraft:reload detected. Reloading CommandAPI commands!");
					nmsInstance.reloadDataPacks();
				}

			}, plugin);
			CommandAPI.logNormal("Hooked into Paper ServerResourcesReloadedEvent");
		} else {
			CommandAPI.logNormal("Did not hook into Paper ServerResourcesReloadedEvent");
		}
	}
}

IMPORTANT: CommandAPI#onLoad and CommandAPI#onEnable method usage has changed

Previously, CommandAPI#onEnable received an Object that represented the 'plugin' responsible for loading it. This was done in an attempt to be as backward-compatible as possible. CommandAPI#onEnable used to take JavaPlugin, but that class is not accessible in a platform-free context, so Object was the best bet for that to work.

Now, however, the JavaPlugin variable was moved to the CommandAPIBukkitConfig. It was put in the constructor to make it required to create a Bukkit config object, reflecting how it is required for the CommandAPI to work.

Altogether, here's how shaders need to change their code (taken from maven-shaded example)
From:

public class Main extends JavaPlugin {
	@Override
	public void onLoad() {
		CommandAPI.setLogger(new CommandAPIJavaLogger(getLogger()));

		CommandAPI.onLoad(
			new CommandAPIConfig()
				.verboseOutput(true)
				.dispatcherFile(new File(getDataFolder(), "command_registration.json"))
				.initializeNBTAPI(NBTContainer.class, NBTContainer::new)
		);
	}

	@Override
	public void onEnable() {
		CommandAPI.onEnable(this);

		// Register commands
		...
	}
}

To:

public class Main extends JavaPlugin {
	@Override
	public void onLoad() {
		CommandAPI.setLogger(new CommandAPIJavaLogger(getLogger()));

		CommandAPI.onLoad(
			new CommandAPIBukkitConfig(this) // Creating a CommandAPIBukkitConfig now
				.verboseOutput(true)
				.dispatcherFile(new File(getDataFolder(), "command_registration.json"))
				.initializeNBTAPI(NBTContainer.class, NBTContainer::new)
		);
	}

	@Override
	public void onEnable() {
		CommandAPI.onEnable(); // Removed parameter

		// Register commands
		...
	}
}

Planned TODO before merge:

  • Add Javadocs
  • Update relevant documentation
  • Adress code review

@willkroboth willkroboth marked this pull request as ready for review December 30, 2022 14:37
Copy link
Member

@JorelAli JorelAli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've pointed out a few minor changes to do with wording of some end-user-facing documentation and an assertion that I'd like added to check if users try to use the paper-specific configuration option on a non-paper server.

I've not done any manual testing, but just by static analysis of the current implementation, everything looks fairly clean and robust. I'm not going to let manual testing prevent this PR from merging, but it's something I'd like to do before 9.0.0's release.

@JorelAli JorelAli merged commit d98f4bb into CommandAPI:dev/dev Dec 30, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants