forked from lishid/OpenInv
-
Notifications
You must be signed in to change notification settings - Fork 41
/
InternalAccessor.java
221 lines (200 loc) · 8.96 KB
/
InternalAccessor.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
/*
* Copyright (C) 2011-2021 lishid. All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.lishid.openinv.util;
import com.lishid.openinv.internal.IAnySilentContainer;
import com.lishid.openinv.internal.IPlayerDataManager;
import com.lishid.openinv.internal.ISpecialEnderChest;
import com.lishid.openinv.internal.ISpecialPlayerInventory;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
public class InternalAccessor {
private final Plugin plugin;
private final String version;
private boolean supported = false;
private IPlayerDataManager playerDataManager;
private IAnySilentContainer anySilentContainer;
public InternalAccessor(final Plugin plugin) {
this.plugin = plugin;
String packageName = plugin.getServer().getClass().getPackage().getName();
this.version = packageName.substring(packageName.lastIndexOf('.') + 1);
try {
Class.forName("com.lishid.openinv.internal." + this.version + ".SpecialPlayerInventory");
Class.forName("com.lishid.openinv.internal." + this.version + ".SpecialEnderChest");
this.playerDataManager = this.createObject(IPlayerDataManager.class, "PlayerDataManager");
this.anySilentContainer = this.createObject(IAnySilentContainer.class, "AnySilentContainer");
this.supported = InventoryAccess.isUsable();
} catch (Exception ignored) {}
}
public String getReleasesLink() {
switch (version) {
case "1_4_5":
case "1_4_6":
case "v1_4_R1":
case "v1_5_R2":
case "v1_5_R3":
case "v1_6_R1":
case "v1_6_R2":
case "v1_6_R3":
case "v1_7_R1":
case "v1_7_R2":
case "v1_7_R3":
case "v1_7_R4":
case "v1_8_R1":
case "v1_8_R2":
case "v1_9_R1":
case "v1_9_R2":
case "v1_10_R1":
case "v1_11_R1":
case "v1_12_R1":
return "https://github.com/lishid/OpenInv/releases/tag/4.0.0 (OpenInv-legacy)";
case "v1_13_R1":
return "https://github.com/lishid/OpenInv/releases/tag/4.0.0";
case "v1_13_R2":
return "https://github.com/lishid/OpenInv/releases/tag/4.0.7";
case "v1_14_R1":
return "https://github.com/lishid/OpenInv/releases/tag/4.1.1";
case "v1_16_R1":
return "https://github.com/lishid/OpenInv/releases/tag/4.1.4";
case "v1_8_R3":
case "v1_15_R1":
case "v1_16_R2":
return "https://github.com/lishid/OpenInv/releases/tag/4.1.5";
case "v1_16_R3":
return "https://github.com/Jikoo/OpenInv/releases/tag/4.1.8";
case "v1_17_R1":
default:
return "https://github.com/Jikoo/OpenInv/releases";
}
}
private <T> T createObject(final Class<? extends T> assignableClass, final String className,
final Object... params) throws ClassCastException, ClassNotFoundException,
InstantiationException, IllegalAccessException, IllegalArgumentException,
InvocationTargetException, NoSuchMethodException, SecurityException {
// Fetch internal class if it exists.
Class<?> internalClass = Class.forName("com.lishid.openinv.internal." + this.version + "." + className);
if (!assignableClass.isAssignableFrom(internalClass)) {
String message = String.format("Found class %s but cannot cast to %s!", internalClass.getName(), assignableClass.getName());
this.plugin.getLogger().warning(message);
throw new IllegalStateException(message);
}
// Quick return: no parameters, no need to fiddle about finding the correct constructor.
if (params.length == 0) {
return assignableClass.cast(internalClass.getConstructor().newInstance());
}
// Search constructors for one matching the given parameters
nextConstructor: for (Constructor<?> constructor : internalClass.getConstructors()) {
Class<?>[] requiredClasses = constructor.getParameterTypes();
if (requiredClasses.length != params.length) {
continue;
}
for (int i = 0; i < params.length; ++i) {
if (!requiredClasses[i].isAssignableFrom(params[i].getClass())) {
continue nextConstructor;
}
}
return assignableClass.cast(constructor.newInstance(params));
}
StringBuilder builder = new StringBuilder("Found class ").append(internalClass.getName())
.append(" but cannot find any matching constructors for [");
for (Object object : params) {
builder.append(object.getClass().getName()).append(", ");
}
builder.delete(builder.length() - 2, builder.length());
String message = builder.append(']').toString();
this.plugin.getLogger().warning(message);
throw new IllegalArgumentException(message);
}
/**
* Creates an instance of the IAnySilentContainer implementation for the current server version.
*
* @return the IAnySilentContainer
* @throws IllegalStateException if server version is unsupported
*/
public IAnySilentContainer getAnySilentContainer() {
if (!this.supported) {
throw new IllegalStateException(String.format("Unsupported server version %s!", this.version));
}
return this.anySilentContainer;
}
/**
* Creates an instance of the IPlayerDataManager implementation for the current server version.
*
* @return the IPlayerDataManager
* @throws IllegalStateException if server version is unsupported
*/
public IPlayerDataManager getPlayerDataManager() {
if (!this.supported) {
throw new IllegalStateException(String.format("Unsupported server version %s!", this.version));
}
return this.playerDataManager;
}
/**
* Gets the server implementation version. If not initialized, returns the string "null"
* instead.
*
* @return the version, or "null"
*/
public String getVersion() {
return this.version != null ? this.version : "null";
}
/**
* Checks if the server implementation is supported.
*
* @return true if initialized for a supported server version
*/
public boolean isSupported() {
return this.supported;
}
/**
* Creates an instance of the ISpecialEnderChest implementation for the given Player, or
* null if the current version is unsupported.
*
* @param player the Player
* @param online true if the Player is online
* @return the ISpecialEnderChest created
* @throws InstantiationException if the ISpecialEnderChest could not be instantiated
*/
public ISpecialEnderChest newSpecialEnderChest(final Player player, final boolean online) throws InstantiationException {
if (!this.supported) {
throw new IllegalStateException(String.format("Unsupported server version %s!", this.version));
}
try {
return this.createObject(ISpecialEnderChest.class, "SpecialEnderChest", player, online);
} catch (Exception e) {
throw new InstantiationException(String.format("Unable to create a new ISpecialEnderChest: %s", e.getMessage()));
}
}
/**
* Creates an instance of the ISpecialPlayerInventory implementation for the given Player..
*
* @param player the Player
* @param online true if the Player is online
* @return the ISpecialPlayerInventory created
* @throws InstantiationException if the ISpecialPlayerInventory could not be instantiated
*/
public ISpecialPlayerInventory newSpecialPlayerInventory(final Player player, final boolean online) throws InstantiationException {
if (!this.supported) {
throw new IllegalStateException(String.format("Unsupported server version %s!", this.version));
}
try {
return this.createObject(ISpecialPlayerInventory.class, "SpecialPlayerInventory", player, online);
} catch (Exception e) {
throw new InstantiationException(String.format("Unable to create a new ISpecialPlayerInventory: %s", e.getMessage()));
}
}
}