Skip to content

Commit a8c2bbf

Browse files
committed
Add TpsWatcher, Spilt nms stuff from Util class into ReflectFactory
1 parent cf77564 commit a8c2bbf

File tree

4 files changed

+144
-142
lines changed

4 files changed

+144
-142
lines changed

src/main/java/org/maxgamer/quickshop/QuickShop.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ public class QuickShop extends JavaPlugin implements QuickShopAPI {
111111
private JavaTextManager textManager;
112112
private boolean priceChangeRequiresFee = false;
113113
private final Map<String, Integer> limits = new HashMap<>(15);
114-
private final GameVersion gameVersion = GameVersion.get(Util.getNMSVersion());
114+
private final GameVersion gameVersion = GameVersion.get(ReflectFactory.getNMSVersion());
115115
/* Public QuickShop API End */
116116

117117
/**
@@ -255,6 +255,8 @@ public class QuickShop extends JavaPlugin implements QuickShopAPI {
255255
private WorldEditAdapter worldEditAdapter;
256256
@Getter
257257
private ShopPurger shopPurger;
258+
@Getter
259+
private final TpsWatcher tpsWatcher = new TpsWatcher();
258260

259261
/**
260262
* Use for mock bukkit
@@ -349,7 +351,7 @@ private void load3rdParty() {
349351
}
350352
}
351353
if (getConfig().getBoolean("plugin.WorldEdit")) {
352-
String nmsVersion = Util.getNMSVersion();
354+
String nmsVersion = ReflectFactory.getNMSVersion();
353355
GameVersion gameVersion = GameVersion.get(nmsVersion);
354356
this.worldEditPlugin = Bukkit.getPluginManager().getPlugin("WorldEdit");
355357
if (this.worldEditPlugin != null) {
@@ -637,6 +639,9 @@ public final void onDisable() {
637639
if (calendarWatcher != null) {
638640
calendarWatcher.stop();
639641
}
642+
if (tpsWatcher != null) {
643+
tpsWatcher.cancel();
644+
}
640645
/* Unload UpdateWatcher */
641646
if (this.updateWatcher != null) {
642647
this.updateWatcher.uninit();
@@ -940,6 +945,7 @@ public void run() {
940945
}
941946
calendarWatcher = new CalendarWatcher(this);
942947
calendarWatcher.start();
948+
tpsWatcher.runTaskTimer(this, 1000, 50);
943949
this.shopPurger = new ShopPurger(this, false);
944950
shopPurger.runTaskAsynchronously(this);
945951
Util.debugLog("Now using display-type: " + AbstractDisplayItem.getNowUsing().name());

src/main/java/org/maxgamer/quickshop/util/ReflectFactory.java

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,74 @@ public class ReflectFactory {
4343
private static Method itemStack_saveMethod;
4444
private static Class<?> nbtTagCompoundClass;
4545
private static Class<?> craftServerClass;
46+
private static Class<?> cachedNMSClass;
47+
private static String nmsVersion;
48+
private static Object serverInstance;
49+
private static Field tpsField;
50+
51+
52+
@NotNull
53+
public static String getNMSVersion() {
54+
if (nmsVersion == null) {
55+
String name = Bukkit.getServer().getClass().getPackage().getName();
56+
nmsVersion = name.substring(name.lastIndexOf('.') + 1);
57+
}
58+
return nmsVersion;
59+
}
60+
61+
/**
62+
* Get MinecraftServer's TPS
63+
*
64+
* @return TPS (e.g 19.92)
65+
*/
66+
@NotNull
67+
public static Double getTPS() {
68+
return QuickShop.getInstance().getTpsWatcher().getAverageTPS();
69+
// if (serverInstance == null || tpsField == null) {
70+
// try {
71+
// serverInstance = getNMSClass("MinecraftServer").getMethod("getServer").invoke(null);
72+
// tpsField = serverInstance.getClass().getField("recentTps");
73+
// } catch (NoSuchFieldException
74+
// | SecurityException
75+
// | IllegalAccessException
76+
// | IllegalArgumentException
77+
// | InvocationTargetException
78+
// | NoSuchMethodException e) {
79+
// serverInstance = null;
80+
// tpsField = null;
81+
// Util.debugLog("Failed to get TPS " + e.getMessage());
82+
// try {
83+
//
84+
// }catch (Exception exception){
85+
// return 20.0;
86+
// }
87+
// }
88+
// }
89+
// try {
90+
// double[] tps = ((double[]) tpsField.get(serverInstance));
91+
// return tps[0];
92+
// } catch (IllegalAccessException ignored) {
93+
// return 20.0;
94+
// }
95+
}
96+
97+
@NotNull
98+
public static Class<?> getNMSClass(@Nullable String className) {
99+
if (cachedNMSClass != null) {
100+
return cachedNMSClass;
101+
}
102+
if (className == null) {
103+
className = "MinecraftServer";
104+
}
105+
String name = Bukkit.getServer().getClass().getPackage().getName();
106+
String version = name.substring(name.lastIndexOf('.') + 1);
107+
try {
108+
cachedNMSClass = Class.forName("net.minecraft.server." + version + "." + className);
109+
return cachedNMSClass;
110+
} catch (ClassNotFoundException e) {
111+
throw new RuntimeException(e);
112+
}
113+
}
46114

47115
static {
48116
String name = Bukkit.getServer().getClass().getPackage().getName();

src/main/java/org/maxgamer/quickshop/util/Util.java

Lines changed: 2 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,6 @@
6161

6262
import java.io.*;
6363
import java.lang.management.ManagementFactory;
64-
import java.lang.reflect.Field;
65-
import java.lang.reflect.InvocationTargetException;
6664
import java.nio.charset.StandardCharsets;
6765
import java.nio.file.Files;
6866
import java.text.DecimalFormat;
@@ -84,24 +82,18 @@ public class Util {
8482
private static final List<BlockFace> VERTICAL_FACING = Collections.unmodifiableList(Arrays.asList(BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST));
8583
private static final List<String> DEBUG_LOGS = new ArrayList<>();
8684
private static final ReentrantReadWriteLock LOCK = new ReentrantReadWriteLock();
87-
@Getter
88-
private static final Map<String, String> CURRENCY_SYMBOL_MAPPING = new HashMap<>();
85+
8986
private static final ThreadLocal<MineDown> MINEDOWN = ThreadLocal.withInitial(() -> new MineDown(""));
9087
private static int bypassedCustomStackSize = -1;
9188
private static Yaml yaml = null;
9289
private static Boolean devMode = null;
9390
@Setter
9491
private static QuickShop plugin;
95-
private static Object serverInstance;
96-
private static Field tpsField;
9792
@Getter
9893
private static boolean disableDebugLogger = false;
9994
@Getter
10095
@Nullable
10196
private static DyeColor dyeColor = null;
102-
@Nullable
103-
private static Class<?> cachedNMSClass = null;
104-
private volatile static String nmsVersion;
10597

10698
/**
10799
* Convert strArray to String. E.g "Foo, Bar"
@@ -353,73 +345,7 @@ public static void debugLog(@NotNull String... logs) {
353345
LOCK.writeLock().unlock();
354346
}
355347

356-
/**
357-
* Formats the given number according to how vault would like it. E.g. $50 or 5 dollars.
358-
*
359-
* @param n price
360-
* @param shop shop
361-
* @return The formatted string.
362-
*/
363-
@NotNull
364-
public static String format(double n, @Nullable Shop shop) {
365-
if (shop == null) {
366-
return "Error: Shop null";
367-
}
368-
return format(n, plugin.getConfig().getBoolean("shop.disable-vault-format", false), shop.getLocation().getWorld(), shop);
369-
}
370-
371-
@NotNull
372-
public static String format(double n, boolean internalFormat, @NotNull World world, @Nullable Shop shop) {
373-
if (shop != null) {
374-
return format(n, internalFormat, world, shop.getCurrency());
375-
} else {
376-
return format(n, internalFormat, world, (Shop) null);
377-
}
378-
}
379-
380-
@NotNull
381-
public static String format(double n, boolean internalFormat, @NotNull World world, @Nullable String currency) {
382-
if (internalFormat) {
383-
return getInternalFormat(n, currency);
384-
}
385-
386-
if (plugin == null) {
387-
Util.debugLog("Called format before Plugin booted up, forcing fixing.");
388-
plugin = QuickShop.getInstance();
389-
}
390-
if (plugin.getEconomy() == null) {
391-
Util.debugLog("Called format before Economy booted up, using built-in formatter.");
392-
return getInternalFormat(n, currency);
393-
}
394-
try {
395-
String formatted = plugin.getEconomy().format(n, world, currency);
396-
if (StringUtils.isEmpty(formatted)) {
397-
Util.debugLog(
398-
"Use alternate-currency-symbol to formatting, Cause economy plugin returned null");
399-
return getInternalFormat(n, currency);
400-
} else {
401-
return formatted;
402-
}
403-
} catch (NumberFormatException e) {
404-
Util.debugLog("format", e.getMessage());
405-
Util.debugLog(
406-
"format", "Use alternate-currency-symbol to formatting, Cause NumberFormatException");
407-
return getInternalFormat(n, currency);
408-
}
409-
}
410348

411-
private static String getInternalFormat(double amount, @Nullable String currency) {
412-
if (StringUtils.isEmpty(currency)) {
413-
Util.debugLog("Format: Currency is null");
414-
String formatted = plugin.getConfig().getBoolean("use-decimal-format", false) ? MsgUtil.decimalFormat(amount) : Double.toString(amount);
415-
return plugin.getConfig().getBoolean("shop.currency-symbol-on-right", false) ? formatted + plugin.getConfig().getString("shop.alternate-currency-symbol", "$") : plugin.getConfig().getString("shop.alternate-currency-symbol", "$") + formatted;
416-
} else {
417-
Util.debugLog("Format: Currency is: [" + currency + "]");
418-
String formatted = plugin.getConfig().getBoolean("use-decimal-format", false) ? MsgUtil.decimalFormat(amount) : Double.toString(amount);
419-
String symbol = CURRENCY_SYMBOL_MAPPING.getOrDefault(currency, currency);
420-
return plugin.getConfig().getBoolean("shop.currency-symbol-on-right", false) ? formatted + symbol : symbol + formatted;
421-
}
422-
}
423349

424350
/**
425351
* return the right side for given blockFace
@@ -625,7 +551,6 @@ public static void initialize() {
625551
SHOPABLES.clear();
626552
RESTRICTED_PRICES.clear();
627553
CUSTOM_STACKSIZE.clear();
628-
CURRENCY_SYMBOL_MAPPING.clear();
629554
devMode = plugin.getConfig().getBoolean("dev-mode");
630555

631556
for (String s : plugin.getConfig().getStringList("shop-blocks")) {
@@ -688,14 +613,7 @@ public static void initialize() {
688613
dyeColor = DyeColor.valueOf(plugin.getConfig().getString("shop.sign-dye-color"));
689614
} catch (Exception ignored) {
690615
}
691-
List<String> symbols = plugin.getConfig().getStringList("shop.alternate-currency-symbol-list");
692-
symbols.forEach(entry -> {
693-
String[] splits = entry.split(";", 2);
694-
if (splits.length < 2) {
695-
plugin.getLogger().warning("Invalid entry in alternate-currency-symbol-list: " + entry);
696-
}
697-
CURRENCY_SYMBOL_MAPPING.put(splits[0], splits[1]);
698-
});
616+
699617
InteractUtil.init(plugin.getConfig());
700618
}
701619

@@ -1171,14 +1089,6 @@ public static String getClassPrefix() {
11711089
return "[" + className + "-" + methodName + "] ";
11721090
}
11731091

1174-
@NotNull
1175-
public static String getNMSVersion() {
1176-
if (nmsVersion == null) {
1177-
String name = Bukkit.getServer().getClass().getPackage().getName();
1178-
nmsVersion = name.substring(name.lastIndexOf('.') + 1);
1179-
}
1180-
return nmsVersion;
1181-
}
11821092

11831093
/**
11841094
* Get the sign material using by plugin. With compatiabily process.
@@ -1194,37 +1104,6 @@ public static Material getSignMaterial() {
11941104
return Material.OAK_WALL_SIGN;
11951105
}
11961106

1197-
/**
1198-
* Get MinecraftServer's TPS
1199-
*
1200-
* @return TPS (e.g 19.92)
1201-
*/
1202-
@NotNull
1203-
public static Double getTPS() {
1204-
if (serverInstance == null || tpsField == null) {
1205-
try {
1206-
serverInstance = getNMSClass("MinecraftServer").getMethod("getServer").invoke(null);
1207-
tpsField = serverInstance.getClass().getField("recentTps");
1208-
} catch (NoSuchFieldException
1209-
| SecurityException
1210-
| IllegalAccessException
1211-
| IllegalArgumentException
1212-
| InvocationTargetException
1213-
| NoSuchMethodException e) {
1214-
plugin.getLogger().log(Level.WARNING, "Failed to getting server TPS, please report to QuickShop.", e);
1215-
serverInstance = null;
1216-
tpsField = null;
1217-
Util.debugLog("Failed to get TPS " + e.getMessage());
1218-
return 20.0;
1219-
}
1220-
}
1221-
try {
1222-
double[] tps = ((double[]) tpsField.get(serverInstance));
1223-
return tps[0];
1224-
} catch (IllegalAccessException ignored) {
1225-
return 20.0;
1226-
}
1227-
}
12281107

12291108
@SneakyThrows
12301109
public static void makeExportBackup(@Nullable String backupName) {
@@ -1253,23 +1132,6 @@ public static void makeExportBackup(@Nullable String backupName) {
12531132
});
12541133
}
12551134

1256-
@NotNull
1257-
public static Class<?> getNMSClass(@Nullable String className) {
1258-
if (cachedNMSClass != null) {
1259-
return cachedNMSClass;
1260-
}
1261-
if (className == null) {
1262-
className = "MinecraftServer";
1263-
}
1264-
String name = Bukkit.getServer().getClass().getPackage().getName();
1265-
String version = name.substring(name.lastIndexOf('.') + 1);
1266-
try {
1267-
cachedNMSClass = Class.forName("net.minecraft.server." + version + "." + className);
1268-
return cachedNMSClass;
1269-
} catch (ClassNotFoundException e) {
1270-
throw new RuntimeException(e);
1271-
}
1272-
}
12731135

12741136
/**
12751137
* Check QuickShop is running on dev edition or not.
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* This file is a part of project QuickShop, the name is TpsWatcher.java
3+
* Copyright (C) PotatoCraft Studio and contributors
4+
*
5+
* This program is free software: you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License as published by the
7+
* Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful, but WITHOUT
11+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13+
* for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*
18+
*/
19+
20+
package org.maxgamer.quickshop.watcher;
21+
22+
import org.bukkit.scheduler.BukkitRunnable;
23+
24+
import java.util.LinkedList;
25+
26+
/**
27+
* @author EssentialsX
28+
* https://github.com/EssentialsX/Essentials/blob/90e4845627551a02a5868141544396bf50ac51a9/Essentials/src/main/java/com/earth2me/essentials/EssentialsTimer.java#L13
29+
*/
30+
public class TpsWatcher extends BukkitRunnable {
31+
private final LinkedList<Double> history = new LinkedList<>();
32+
@SuppressWarnings("FieldCanBeLocal")
33+
private final long tickInterval = 50;
34+
private transient long lastPoll = System.nanoTime();
35+
36+
public TpsWatcher() {
37+
history.add(20d);
38+
}
39+
40+
@Override
41+
public void run() {
42+
final long startTime = System.nanoTime();
43+
long timeSpent = (startTime - lastPoll) / 1000;
44+
if (timeSpent == 0) {
45+
timeSpent = 1;
46+
}
47+
if (history.size() > 10) {
48+
history.remove();
49+
}
50+
final double tps = tickInterval * 1000000.0 / timeSpent;
51+
if (tps <= 21) {
52+
history.add(tps);
53+
}
54+
lastPoll = startTime;
55+
}
56+
57+
public double getAverageTPS() {
58+
double avg = 0;
59+
for (final Double f : history) {
60+
if (f != null) {
61+
avg += f;
62+
}
63+
}
64+
return avg / history.size();
65+
}
66+
}

0 commit comments

Comments
 (0)