Skip to content

Commit

Permalink
Added a system property 'shopkeepers.skip-wg-allow-shop-flag' which can
Browse files Browse the repository at this point in the history
be used to disable the registration of the 'allow-shop' WorldGuard flag.

This should usually not be required though.

Also moved some initialization and config loading into the onLoad phase,
so that it is available for any code running there.
  • Loading branch information
blablubbabc committed Aug 19, 2019
1 parent 2a197e4 commit 1939c02
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 36 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ Date format: (YYYY-MM-DD)
* Changed: Some entity attributes are setup prior to entity spawning now (such as metadata, non-persist flag and name (if it has/uses one)). This should help other plugins to identify Shopkeeper entities during spawning.
* Changed: Added setting 'increment-villager-statistics' (default: false) which controls whether opening the trading menu and trading with shopkeepers increment minecraft's 'talked-to-villager' and 'traded-with-villager' statistics. Previously the talked-to-villager statistics would always get incremented and the traded-with-villager statistic was not used.
* Added: The previous, current and next page items inside the editor view will now use their stack size to visualize the previous, current and next page number. This even works for items which are usually not stackable.
* Added: Added a system property 'shopkeepers.skip-wg-allow-shop-flag' which can be used to disable the registration of the 'allow-shop' WorldGuard flag. This should usually not be required though.

API:
* API: Added interfaces for the different shopkeeper types and their offers to the API. They allow modifying the shopkeepers' trades. Factory methods for the different types of offers are provided via ShopkeepersPlugin and ShopkeepersAPI. The internal shopkeeper classes got renamed.
Expand All @@ -44,6 +45,7 @@ API:
* API/Fixed: ShopkeepersAPI was missing getDefaultUITypes.

Internal:
* Internal: Moved some initialization and config loading into the onLoad phase.
* Internal: Avoiding ItemStack#hasItemMeta calls before getting an item's ItemMeta, since this might be heavier than simply getting the ItemMeta directly and performing only the relevant checks on that. Internally ItemStack#hasItemMeta checks emptiness for all item attributes and might (for CraftItemStacks) even first copy all the item's data into a new ItemMeta object. And even if the item actually has no data (Bukkit ItemStack with null ItemMeta), ItemStack#getItemMeta will simply create a new empty ItemMeta object without having to copy any data, so this is still a similarly lightweight operation anyways.
* Internal: Made all priorities and ignoring of cancelled events explicit.
* Internal: Moved code for checking chest access into util package.
Expand Down
132 changes: 98 additions & 34 deletions src/main/java/com/nisovin/shopkeepers/SKShopkeepersPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -113,18 +113,10 @@ public static SKShopkeepersPlugin getInstance() {
private final SignShops signShops = new SignShops(this);
private final CitizensShops citizensShops = new CitizensShops(this);

@Override
public void onLoad() {
// WorldGuard only allows registering flags before it got enabled.
// The config gets loaded later, so we always attempt to register the flag.
WorldGuardHandler.registerAllowShopFlag();
}

@Override
public void onEnable() {
plugin = this;
ShopkeepersAPI.enable(this);
private boolean outdatedServer = false;
private boolean incompatibleServer = false;

private void loadRequiredClasses() {
// making sure that certain classes, that are needed during shutdown, are loaded:
// this helps for hot reloads (when the plugin gets disabled, but the original jar got replaced and is therefore
// no longer available)
Expand All @@ -136,48 +128,52 @@ public void onEnable() {
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}

// validate that this is running a minimum required version of Spigot:
// returns true if server is outdated
private boolean isOutdatedServerVersion() {
// validate that this server is running a minimum required version:
// TODO add proper version parsing
/*String cbVersion = Utils.getServerCBVersion(); // 1_13_R2
String bukkitVersion = Bukkit.getBukkitVersion(); // 1.13.1-R0.1-SNAPSHOT*/
/*String cbVersion = Utils.getServerCBVersion(); // eg. 1_13_R2
String bukkitVersion = Bukkit.getBukkitVersion(); // eg. 1.13.1-R0.1-SNAPSHOT*/
try {
// this has been added with the recent changes to PlayerBedEnterEvent:
// this has been added with the recent changes to PlayerBedEnterEvent: TODO outdated
Class.forName("org.bukkit.event.player.PlayerBedEnterEvent$BedEnterResult");
} catch (ClassNotFoundException e1) {
Log.severe("Outdated server version (" + Bukkit.getVersion()
+ "): Shopkeepers cannot be enabled. Please update your server!");
this.setEnabled(false);
return;
return false;
} catch (ClassNotFoundException e) {
return true;
}
}

// try to load suitable NMS code:
// returns false if no compatible NMS version, nor the fallback handler could be setup
private boolean setupNMS() {
NMSManager.load(this);
if (NMSManager.getProvider() == null) {
Log.severe("Incompatible server version: Shopkeepers cannot be enabled.");
this.setEnabled(false);
return;
}
return (NMSManager.getProvider() != null);
}

private void loadConfig() {
Log.info("Loading config.");
// save default config in case the config file doesn't exist
this.saveDefaultConfig();

// load config:
File configFile = new File(this.getDataFolder(), "config.yml");
if (!configFile.exists()) {
this.saveDefaultConfig();
}
this.reloadConfig();

// load settings from config:
Configuration config = this.getConfig();
boolean configChanged = Settings.loadConfiguration(config);
if (configChanged) {
// if missing settings were added -> save the modified config
// if the config was modified (migrations, adding missing settings, ..), save it:
// TODO persist comments somehow
this.saveConfig();
}

// load language config:
String lang = Settings.language;
File langFile = new File(this.getDataFolder(), "language-" + lang + ".yml");
if (!langFile.exists() && this.getResource("language-" + lang + ".yml") != null) {
this.saveResource("language-" + lang + ".yml", false);
String langFileName = "language-" + lang + ".yml";
File langFile = new File(this.getDataFolder(), langFileName);
if (!langFile.exists() && this.getResource(langFileName) != null) {
this.saveResource(langFileName, false);
}
if (langFile.exists()) {
try {
Expand All @@ -188,6 +184,74 @@ public void onEnable() {
e.printStackTrace();
}
}
}

@Override
public void onLoad() {
// setting plugin reference early, so it is also available for any code running here:
plugin = this;
ShopkeepersAPI.enable(this);

// making sure that certain classes, that are needed during shutdown, are loaded:
// this helps for hot reloads (when the plugin gets disabled, but the original jar got replaced and is therefore
// no longer available)
this.loadRequiredClasses();

// validate that this server is running a minimum required version:
this.outdatedServer = this.isOutdatedServerVersion();
if (this.outdatedServer) {
return;
}

// try to load suitable NMS (or fallback) code:
this.incompatibleServer = !this.setupNMS();
if (this.incompatibleServer) {
return;
}

// load config:
this.loadConfig();

// WorldGuard only allows registering flags before it gets enabled.
// By default, we always attempt to register the flag. There is no config setting for this, because this is not
// expected to be required. And a config setting would also not work for later config reloads.
// Instead, in case this is really required for some reason, a system property can be used to disable the flag
// registration.
if (System.getProperty("shopkeepers.skip-wg-allow-shop-flag", "false").equals("false")) {
WorldGuardHandler.registerAllowShopFlag();
}
}

@Override
public void onEnable() {
// plugin instance and API might already have been set during onLoad:
boolean alreadySetup = true;
if (plugin == null) {
alreadySetup = false;
plugin = this;
ShopkeepersAPI.enable(this);
}

// validate that this server is running a minimum required version:
if (this.outdatedServer) {
Log.severe("Outdated server version (" + Bukkit.getVersion() + "): Shopkeepers cannot be enabled. Please update your server!");
this.setEnabled(false); // also calls onDisable
return;
}

// check if the server version is incompatible:
if (this.incompatibleServer) {
Log.severe("Incompatible server version: Shopkeepers cannot be enabled.");
this.setEnabled(false); // also calls onDisable
return;
}

// load config (if it hasn't just been loaded already during onLoad):
if (!alreadySetup) {
this.loadConfig();
} else {
Log.info("Config already loaded.");
}

// process additional permissions
String[] perms = Settings.maxShopsPermOptions.replace(" ", "").split(",");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,14 @@ public static boolean isShopAllowed(Player player, Location loc) {
private static class Link {

public static void registerAllowShopFlag() {
Log.debug("Registering WorldGuard flag '" + FLAG_ALLOW_SHOP + "'.");
Log.info("Registering WorldGuard flag '" + FLAG_ALLOW_SHOP + "'.");
try {
StateFlag allowShopFlag = new StateFlag(FLAG_ALLOW_SHOP, false);
WorldGuard.getInstance().getFlagRegistry().register(allowShopFlag);
} catch (FlagConflictException | IllegalStateException e) {
// another plugin has probably already registered this flag,
// or this plugin got hard reloaded by some plugin manager plugin
Log.debug("Couldn't register WorldGuard flag '" + FLAG_ALLOW_SHOP + "': " + e.getMessage());
Log.info("Couldn't register WorldGuard flag '" + FLAG_ALLOW_SHOP + "': " + e.getMessage());
}
}

Expand Down

0 comments on commit 1939c02

Please sign in to comment.