Skip to content

Commit 4327cd6

Browse files
committed
Fixed scoreboard support for older minecraft versions. (Fixes #4)
1 parent 94da6dd commit 4327cd6

File tree

6 files changed

+196
-23
lines changed

6 files changed

+196
-23
lines changed

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,5 @@ McCombatLevel
33

44
Bukkit plugin that creates and displays a combat level for mcMMO.
55

6-
See http://dev.bukkit.org/bukkit-plugins/mccombatlevel/
7-
6+
See http://dev.bukkit.org/bukkit-plugins/mccombatlevel/ \\
87
http://www.curse.com/bukkit-plugins/minecraft/mccombatlevel

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<name>McCombatLevel</name>
1010
<inceptionYear>2014</inceptionYear>
1111
<description>Displays a combat level above users heads and in chat based on their mcMMO stats that affect combat</description>
12-
<version>1.7</version>
12+
<version>1.7.2</version>
1313
<url>http://dev.bukkit.org/bukkit-plugins/mccombatlevel/</url>
1414

1515
<properties>
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
package com.gmail.mrphpfan.mccombatlevel;
2+
3+
import com.google.common.base.Charsets;
4+
import com.google.common.base.Objects;
5+
import com.google.common.collect.Maps;
6+
7+
import java.util.Map;
8+
import java.util.UUID;
9+
10+
import org.bukkit.Bukkit;
11+
import org.bukkit.Location;
12+
import org.bukkit.OfflinePlayer;
13+
import org.bukkit.entity.Player;
14+
15+
/**
16+
* Since 1.7 Bukkit introduced CraftServer.getOfflinePlayer(String name).
17+
*
18+
* This method is blocking as it looks up the cache. So it could cause lags
19+
* on big servers. Because we only need the name this class is made.
20+
*
21+
* Bukkit already implemented methods to get around this problem, but the
22+
* scoreboard team isn't yet modified for methods, which can be called just
23+
* with a string.
24+
*
25+
* Servers <b>below 1.7</b> with use of this class doesn't need to search for the
26+
* player.
27+
*
28+
* @see org.bukkit.Bukkit#getOfflinePlayer(java.lang.String)
29+
*/
30+
public class FastOfflinePlayer implements OfflinePlayer {
31+
32+
private final String playerName;
33+
34+
/**
35+
* Creates a new instance based of this name
36+
*
37+
* @param playerName the player name
38+
*/
39+
public FastOfflinePlayer(String playerName) {
40+
this.playerName = playerName;
41+
}
42+
43+
@Override
44+
public boolean isOnline() {
45+
//it's a fake player, so it won't be online
46+
return false;
47+
}
48+
49+
@Override
50+
public String getName() {
51+
return playerName;
52+
}
53+
54+
@Override
55+
public UUID getUniqueId() {
56+
return UUID.nameUUIDFromBytes(playerName.getBytes(Charsets.UTF_8));
57+
}
58+
59+
@Override
60+
public boolean isBanned() {
61+
return false;
62+
}
63+
64+
@Override
65+
@SuppressWarnings("deprecation")
66+
public void setBanned(boolean banned) {
67+
//ignore
68+
}
69+
70+
@Override
71+
public boolean isWhitelisted() {
72+
return false;
73+
}
74+
75+
@Override
76+
public void setWhitelisted(boolean value) {
77+
//ignore
78+
}
79+
80+
@Override
81+
public Player getPlayer() {
82+
return null;
83+
}
84+
85+
@Override
86+
public long getFirstPlayed() {
87+
return System.currentTimeMillis();
88+
}
89+
90+
@Override
91+
public long getLastPlayed() {
92+
return System.currentTimeMillis();
93+
}
94+
95+
@Override
96+
public boolean hasPlayedBefore() {
97+
return false;
98+
}
99+
100+
@Override
101+
public Location getBedSpawnLocation() {
102+
return new Location(Bukkit.getWorlds().get(0), 0, 0, 0);
103+
}
104+
105+
@Override
106+
public boolean isOp() {
107+
return false;
108+
}
109+
110+
@Override
111+
public void setOp(boolean value) {
112+
//ignore
113+
}
114+
115+
@Override
116+
public Map<String, Object> serialize() {
117+
final Map<String, Object> result = Maps.newLinkedHashMap();
118+
119+
result.put("UUID", getUniqueId().toString());
120+
result.put("name", playerName);
121+
122+
return result;
123+
}
124+
125+
@Override
126+
public int hashCode() {
127+
return Objects.hashCode(playerName);
128+
}
129+
130+
@Override
131+
public boolean equals(Object obj) {
132+
//check for null too
133+
if (!(obj instanceof FastOfflinePlayer)) {
134+
return false;
135+
}
136+
137+
final FastOfflinePlayer other = (FastOfflinePlayer) obj;
138+
return Objects.equal(playerName, other.playerName);
139+
}
140+
141+
@Override
142+
public String toString() {
143+
return Objects.toStringHelper(this)
144+
.add("playerName", playerName)
145+
.toString();
146+
}
147+
}

src/main/java/com/gmail/mrphpfan/mccombatlevel/McCombatLevel.java

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ public class McCombatLevel extends JavaPlugin {
2828
private final Map<String, Integer> playerLevels = Maps.newConcurrentMap();
2929

3030
private LevelCalculator levelCalculator;
31+
private boolean oldScoreboardAPI;
3132

3233
private Scoreboard board;
3334
private Objective objective;
@@ -55,12 +56,17 @@ public ChatColor getPrefixColor() {
5556
return prefixLevel;
5657
}
5758

59+
public void setLevelCalculator(LevelCalculator newCalculator) {
60+
levelCalculator = newCalculator;
61+
}
62+
5863
@Override
5964
public void onEnable() {
6065
loadConfiguration();
6166

62-
6367
if (enableTag) {
68+
oldScoreboardAPI = isOldScoreboardAPI();
69+
6470
//Choose the main scoreboard in order to be compatible with for example ColoredTags
6571
board = getServer().getScoreboardManager().getMainScoreboard();
6672

@@ -117,20 +123,28 @@ public void setLevel(Player player, int level) {
117123

118124
if (enableTag && player.hasPermission(getName().toLowerCase() + ".showLevelTag")) {
119125
//set the score on the scoreboard
120-
objective.getScore(playerName).setScore(level);
126+
if (oldScoreboardAPI) {
127+
objective.getScore(new FastOfflinePlayer(playerName)).setScore(level);
128+
} else {
129+
objective.getScore(playerName).setScore(level);
130+
}
121131
}
122132
}
123133

124134
public void removeCachedLevels(Player player) {
125135
final String playerName = player.getName();
126136
playerLevels.remove(playerName);
127137
//prevent that objective will be too big
128-
board.resetScores(playerName);
138+
if (oldScoreboardAPI) {
139+
board.resetScores(new FastOfflinePlayer(playerName));
140+
} else {
141+
board.resetScores(playerName);
142+
}
129143
}
130144

131145
public void updateLevel(Player player) {
132-
//Check if the player is loaded without exceptions, but with backwards compatibility
133146
if (UserManager.hasPlayerDataKey(player)) {
147+
//Check if the player is loaded without exceptions, but with backwards compatibility
134148
int newLevel = calculateLevel(UserManager.getPlayer(player));
135149
setLevel(player, newLevel);
136150
}
@@ -201,4 +215,17 @@ private void removeObjective() {
201215
toRemove.unregister();
202216
}
203217
}
218+
219+
private boolean isOldScoreboardAPI() {
220+
try {
221+
Objective.class.getDeclaredMethod("getScore", String.class);
222+
} catch (NoSuchMethodException noSuchMethodEx) {
223+
//since we have an extra class for it (FastOfflinePlayer)
224+
//we can fail silently
225+
return true;
226+
}
227+
228+
//We have access to the new method
229+
return false;
230+
}
204231
}

src/main/java/com/gmail/mrphpfan/mccombatlevel/PlayerListener.java

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ public PlayerListener(McCombatLevel plugin) {
2424
}
2525

2626
@EventHandler(ignoreCancelled = true)
27-
public void onPlayerJoinEvent(PlayerJoinEvent event) {
28-
final Player player = event.getPlayer();
27+
public void onPlayerJoinEvent(PlayerJoinEvent joinEvent) {
28+
final Player player = joinEvent.getPlayer();
2929

3030
Bukkit.getScheduler().runTaskLater(plugin, new Runnable() {
3131

@@ -36,7 +36,7 @@ public void run() {
3636
plugin.updateLevel(player);
3737
}
3838
}
39-
}, 3 * 20L);
39+
}, 5 * 20L);
4040

4141
//send them the scoreboard
4242
if (plugin.isTagEnabled()) {
@@ -45,42 +45,42 @@ public void run() {
4545
}
4646

4747
@EventHandler
48-
public void onPlayerLogout(PlayerQuitEvent event) {
48+
public void onPlayerLogout(PlayerQuitEvent quitEvent) {
4949
//remove the player from the cache
50-
plugin.removeCachedLevels(event.getPlayer());
50+
plugin.removeCachedLevels(quitEvent.getPlayer());
5151
}
5252

5353
//set it to low in order to update the level before other plugins want to get that value
5454
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOW)
55-
public void onPlayerLevelUp(McMMOPlayerLevelUpEvent event) {
56-
SkillType skill = event.getSkill();
55+
public void onPlayerLevelUp(McMMOPlayerLevelUpEvent levelUpEvent) {
56+
SkillType skill = levelUpEvent.getSkill();
5757

5858
//only level up combat if one of the following was leveled
5959
if (skill.equals(SkillType.SWORDS) || skill.equals(SkillType.ARCHERY)
6060
|| skill.equals(SkillType.AXES) || skill.equals(SkillType.UNARMED)
6161
|| skill.equals(SkillType.TAMING) || skill.equals(SkillType.ACROBATICS)) {
62-
plugin.updateLevel(event.getPlayer());
62+
plugin.updateLevel(levelUpEvent.getPlayer());
6363
}
6464
}
6565

6666
//some chat plugins listen and change stuff on the default priority. In order
6767
//to see these changes we need an higher priority.
6868
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOW)
69-
public void onChat(AsyncPlayerChatEvent event) {
69+
public void onChat(AsyncPlayerChatEvent chatEvent) {
7070
if (!plugin.isPrefixEnabled()) {
7171
//check if prefix is enabled
7272
return;
7373
}
7474

75-
Integer combatLevel = plugin.getCombatLevel(event.getPlayer());
76-
String format = event.getFormat();
75+
Integer combatLevel = plugin.getCombatLevel(chatEvent.getPlayer());
76+
String format = chatEvent.getFormat();
7777
if (format.contains(CHAT_VARIABLE)) {
7878
String level = "";
7979
if (combatLevel != null) {
8080
level = combatLevel.toString();
8181
}
8282

83-
event.setFormat(format.replace(CHAT_VARIABLE, level));
83+
chatEvent.setFormat(format.replace(CHAT_VARIABLE, level));
8484
//variable found - do not append the tag manually
8585
return;
8686
}
@@ -89,8 +89,8 @@ public void onChat(AsyncPlayerChatEvent event) {
8989
if (combatLevel != null) {
9090
ChatColor prefixColor = plugin.getPrefixColor();
9191
ChatColor prefixBracket = plugin.getPrefixBracket();
92-
event.setFormat(prefixBracket + "[" + prefixColor + combatLevel + prefixBracket + "]"
93-
+ ChatColor.RESET + event.getFormat());
92+
chatEvent.setFormat(prefixBracket + "[" + prefixColor + combatLevel + prefixBracket + "]"
93+
+ ChatColor.RESET + chatEvent.getFormat());
9494
}
9595
}
9696
}

src/main/resources/plugin.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ depend: [mcMMO]
1616

1717
commands:
1818
# choose a possible unique name
19-
combatlevel:
19+
${project.artifactId}:
2020
description: 'See the combat level'
2121
usage: /<command> [player]
22-
aliases: [level]
22+
aliases: [level, combatlevel]
2323

2424
permissions:
2525
mccombatlevel.*:

0 commit comments

Comments
 (0)