Skip to content

Commit 703a3cc

Browse files
committed
Let external plugins register combat tag implementations
Remove static 'CombatTagHelper', and add a CombatTagPlugin getter to the SpawnShield class.
1 parent 5e70797 commit 703a3cc

File tree

13 files changed

+182
-173
lines changed

13 files changed

+182
-173
lines changed

api/src/main/java/net/techcable/spawnshield/combattag/CombatTagPlugin.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
/**
22
* The MIT License
33
* Copyright (c) 2015 Techcable
4-
*
4+
* <p>
55
* Permission is hereby granted, free of charge, to any person obtaining a copy
66
* of this software and associated documentation files (the "Software"), to deal
77
* in the Software without restriction, including without limitation the rights
88
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
99
* copies of the Software, and to permit persons to whom the Software is
1010
* furnished to do so, subject to the following conditions:
11-
*
11+
* <p>
1212
* The above copyright notice and this permission notice shall be included in
1313
* all copies or substantial portions of the Software.
14-
*
14+
* <p>
1515
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1616
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1717
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -24,6 +24,7 @@
2424

2525
import org.bukkit.entity.Entity;
2626
import org.bukkit.entity.Player;
27+
import org.bukkit.plugin.Plugin;
2728

2829
public interface CombatTagPlugin {
2930

@@ -79,4 +80,11 @@ public interface CombatTagPlugin {
7980
*/
8081
public boolean isInstalled();
8182

83+
/**
84+
* Return the plugin who owns this combat tagging instance
85+
*
86+
*
87+
* @return the plugin
88+
*/
89+
public Plugin getPlugin();
8290
}

base/src/main/java/net/techcable/spawnshield/SpawnShield.java

Lines changed: 92 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,34 @@
2222
*/
2323
package net.techcable.spawnshield;
2424

25-
import lombok.Getter;
26-
import net.techcable.spawnshield.combattag.CombatTagHelper;
25+
import lombok.*;
26+
27+
import java.io.IOException;
28+
import java.lang.reflect.Constructor;
29+
import java.lang.reflect.InvocationTargetException;
30+
import java.util.Set;
31+
import java.util.UUID;
32+
import java.util.logging.Level;
33+
import java.util.stream.Collector;
34+
35+
import com.google.common.collect.ImmutableList;
36+
37+
import net.techcable.spawnshield.combattag.CombatTagPlugin;
38+
import net.techcable.spawnshield.combattag.MultiPluginCombatTagPlugin;
2739
import net.techcable.spawnshield.compat.worldguard6.WorldGuard6Plugin;
2840
import net.techcable.spawnshield.config.SpawnShieldConfig;
2941
import net.techcable.spawnshield.config.SpawnShieldMessages;
3042
import net.techcable.spawnshield.forcefield.ForceFieldListener;
31-
import net.techcable.spawnshield.tasks.ForceFieldUpdateTask;
3243
import net.techcable.spawnshield.tasks.KnockbackTask;
3344
import net.techcable.spawnshield.tasks.TeleportSafezoningTask;
3445
import net.techcable.techutils.TechPlugin;
46+
3547
import org.bukkit.Bukkit;
48+
import org.bukkit.plugin.Plugin;
49+
import org.bukkit.plugin.RegisteredServiceProvider;
50+
import org.bukkit.plugin.ServicePriority;
3651
import org.bukkit.plugin.java.JavaPlugin;
37-
38-
import java.io.IOException;
39-
import java.util.UUID;
52+
import org.reflections.Reflections;
4053

4154
@Getter
4255
public class SpawnShield extends TechPlugin<SpawnShieldPlayer> {
@@ -48,16 +61,26 @@ public class SpawnShield extends TechPlugin<SpawnShieldPlayer> {
4861
private ForceFieldListener forceFieldListener;
4962
private TeleportSafezoningTask teleportSafezoningTask;
5063
private KnockbackTask knockbackTask;
51-
private ForceFieldUpdateTask forceFieldUpdateTask;
5264

5365
@Override
5466
protected void startup() {
55-
Utils.info("Loading SpawnShield by Techcable");
56-
if (!CombatTagHelper.isInstalled()) {
57-
Utils.severe("No Combat Tagging Plugin Installed");
58-
Utils.severe("Shutting down");
67+
getInstance().getLogger().info("Loading SpawnShield by Techcable");
68+
if (getCombatTagPlugins().isEmpty()) {
69+
getInstance().getLogger().severe("No Combat Tagging Plugin Installed");
70+
getInstance().getLogger().severe("Shutting down");
5971
setEnabled(false);
6072
return;
73+
} else {
74+
getLogger().info("Found " + getCombatTagPlugins().size() + " installed CombatTagPlugins:");
75+
int i = 1;
76+
for (CombatTagPlugin plugin : getCombatTagPlugins()) {
77+
Plugin providingPlugin = JavaPlugin.getProvidingPlugin(plugin.getClass());
78+
getLogger().info(i + ") " + plugin.getPlugin().getName());
79+
if (providingPlugin != plugin.getPlugin()) {
80+
getLogger().info("\t- this is provided by " + providingPlugin.getName() + " not implemented in " + plugin.getPlugin().getName() + " itself");;
81+
getLogger().info("\t- therefore report bugs with the integration to " + Utils.getAuthors(providingPlugin) + ", not to " + Utils.getAuthors(plugin.getPlugin()));
82+
}
83+
}
6184
}
6285
settings = new SpawnShieldConfig(this);
6386
messages = new SpawnShieldMessages(this);
@@ -86,46 +109,96 @@ public int getValue() {
86109
});
87110
metrics.start();
88111
} catch (IOException e) {
89-
Utils.warning("Unable to run metrics");
112+
getInstance().getLogger().warning("Unable to run metrics");
113+
}
114+
if (getSettings().isDebug()) {
115+
getLogger().setLevel(Level.FINE);
90116
}
91117
//Add the protection plugins
92118
int numPluginsAdded = 0;
93119
if (Bukkit.getPluginManager().isPluginEnabled("WorldGuard")) {
94120
String version = Bukkit.getPluginManager().getPlugin("WorldGuard").getDescription().getVersion();
95121
if (version.startsWith("6")) {
96-
Utils.info("Worldguard 6 Detected, Activatin support");
122+
getInstance().getLogger().info("Worldguard 6 Detected, Activating support");
97123
WorldGuard6Plugin hook = new WorldGuard6Plugin();
98124
getSettings().addProtectionPlugin(hook);
99125
numPluginsAdded++;
100126
}
101127
}
102128
if (numPluginsAdded == 0) {
103-
Utils.severe("No supported protection plugin found, shutting down");
129+
getInstance().getLogger().severe("No supported protection plugin found, shutting down");
104130
setEnabled(false);
105131
return;
106132
}
107133
getCommand("spawnshield").setExecutor(new SpawnShieldExecutor());
108134
switch (settings.getMode()) {
109135
case FORCEFIELD :
110-
Utils.warning("Force field mode is currently unsupported");
111-
this.forceFieldListener = new ForceFieldListener();
136+
this.forceFieldListener = new ForceFieldListener(this);
112137
registerListener(forceFieldListener);
113138
break;
114139
case TELEPORT :
115-
teleportSafezoningTask = new TeleportSafezoningTask();
140+
teleportSafezoningTask = new TeleportSafezoningTask(this);
116141
teleportSafezoningTask.runTaskTimer(this, 5, 5); //Every 1/4 of a tick
117142
break;
118143
case KNOCKBACK :
119-
knockbackTask = new KnockbackTask();
144+
knockbackTask = new KnockbackTask(this);
120145
knockbackTask.runTaskTimer(this, 5, 5); //Every 1/4 of a tick
121146
break;
122147
default :
123-
Utils.severe("[SpawnShield] Unknown Plugin Mode");
148+
getInstance().getLogger().severe("[SpawnShield] Unknown Plugin Mode");
124149
setEnabled(false);
125150
return;
126151
}
127152
}
128153

154+
public CombatTagPlugin getCombatTagPlugin() {
155+
ImmutableList<CombatTagPlugin> plugins = getCombatTagPlugins();
156+
switch (plugins.size()) {
157+
case 0:
158+
throw new IllegalStateException("No CombatTagPlugin installed!");
159+
case 1:
160+
return plugins.get(0);
161+
default:
162+
return new MultiPluginCombatTagPlugin(plugins);
163+
}
164+
}
165+
166+
167+
public ImmutableList<CombatTagPlugin> getCombatTagPlugins() {
168+
if (getServer().getServicesManager().getRegistrations(this).isEmpty()) {
169+
// Search classpath for our own impls
170+
String className = CombatTagPlugin.class.getName();
171+
String packageName = className.substring(0, className.lastIndexOf('.') - 1);
172+
Set<Class<? extends CombatTagPlugin>> pluginTypes = new Reflections(packageName).getSubTypesOf(CombatTagPlugin.class);
173+
for (Class<? extends CombatTagPlugin> pluginType : pluginTypes) {
174+
if (pluginType == MultiPluginCombatTagPlugin.class) continue;
175+
CombatTagPlugin plugin;
176+
try {
177+
Constructor<? extends CombatTagPlugin> c = pluginType.getConstructor();
178+
c.setAccessible(true);
179+
plugin = c.newInstance();
180+
} catch (NoSuchMethodException | InstantiationException e) {
181+
continue;
182+
} catch (IllegalAccessException e) {
183+
throw new RuntimeException("Unable to call setAccessible() on " + pluginType.getSimpleName());
184+
} catch (InvocationTargetException e) {
185+
Throwable cause = e.getTargetException();
186+
throw new RuntimeException("new " + pluginType.getSimpleName() + "() threw an exception", cause);
187+
}
188+
getServer().getServicesManager().register(CombatTagPlugin.class, plugin, this, ServicePriority.Normal);
189+
}
190+
}
191+
return getServer().getServicesManager().getRegistrations(CombatTagPlugin.class).stream()
192+
.map(RegisteredServiceProvider::getProvider)
193+
.filter(CombatTagPlugin::isInstalled) // Only return installed plugins :)
194+
.collect(Collector.<CombatTagPlugin, ImmutableList.Builder<CombatTagPlugin>, ImmutableList<CombatTagPlugin>>of(
195+
ImmutableList::builder,
196+
ImmutableList.Builder::add,
197+
(builder1, builder2) -> builder1.addAll(builder2.build()),
198+
ImmutableList.Builder::build
199+
));
200+
}
201+
129202
@Override
130203
protected void shutdown() {
131204
if (getSettings() != null) getSettings().save();

base/src/main/java/net/techcable/spawnshield/Utils.java

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,31 +23,38 @@
2323
package net.techcable.spawnshield;
2424

2525
import com.google.common.base.Preconditions;
26+
import com.google.common.collect.ImmutableList;
27+
2628
import lombok.AccessLevel;
2729
import lombok.NoArgsConstructor;
30+
31+
import java.util.List;
32+
2833
import org.bukkit.Bukkit;
34+
import org.bukkit.plugin.Plugin;
2935

3036
@NoArgsConstructor(access = AccessLevel.PRIVATE)
3137
public class Utils {
3238

33-
public static void severe(String error) {
34-
Bukkit.getLogger().severe("[SpawnShield] " + error);
35-
}
36-
37-
public static void warning(String error) {
38-
Bukkit.getLogger().warning("[SpawnShield] " + error);
39-
}
40-
41-
public static void debug(String msg) {
42-
if (SpawnShield.getInstance().getSettings().isDebug()) {
43-
info(msg);
39+
public static String getAuthors(Plugin plugin) {
40+
List<String> authors = plugin.getDescription().getAuthors();
41+
switch (authors.size()) {
42+
case 0:
43+
return "unknown author";
44+
case 1:
45+
return authors.get(0);
46+
default:
47+
StringBuilder builder = new StringBuilder();
48+
for (int i = 0; i < authors.size() - 1; i++) {
49+
if (i != 0) builder.append(", ");
50+
builder.append(authors.get(i));
51+
}
52+
builder.append(", and ");
53+
builder.append(authors.get(authors.size() - 1));
54+
return builder.toString();
4455
}
4556
}
4657

47-
public static void info(String msg) {
48-
Bukkit.getLogger().info("[SpawnShield] " + msg);
49-
}
50-
5158
public static void assertMainThread() {
5259
Preconditions.checkState(Bukkit.isPrimaryThread(), "Should only be called on the primary thread");
5360
}

base/src/main/java/net/techcable/spawnshield/combattag/CombatTagHelper.java

Lines changed: 0 additions & 105 deletions
This file was deleted.

0 commit comments

Comments
 (0)