Skip to content

Commit 1a0ff69

Browse files
committed
Merge branch 'base' into mc/1.13
2 parents 5b32ade + e60d60f commit 1a0ff69

File tree

49 files changed

+2298
-174
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+2298
-174
lines changed
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
/*
2+
* This file is part of BlueMap, licensed under the MIT License (MIT).
3+
*
4+
* Copyright (c) Blue (Lukas Rieger) <https://bluecolored.de>
5+
* Copyright (c) contributors
6+
*
7+
* Permission is hereby granted, free of charge, to any person obtaining a copy
8+
* of this software and associated documentation files (the "Software"), to deal
9+
* in the Software without restriction, including without limitation the rights
10+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
* copies of the Software, and to permit persons to whom the Software is
12+
* furnished to do so, subject to the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be included in
15+
* all copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
* THE SOFTWARE.
24+
*/
25+
package de.bluecolored.bluemap.bukkit;
26+
27+
import java.lang.ref.WeakReference;
28+
import java.util.EnumMap;
29+
import java.util.Map;
30+
import java.util.UUID;
31+
32+
import org.bukkit.Bukkit;
33+
import org.bukkit.GameMode;
34+
import org.bukkit.Location;
35+
import org.bukkit.potion.PotionEffectType;
36+
37+
import com.flowpowered.math.vector.Vector3d;
38+
39+
import de.bluecolored.bluemap.common.plugin.serverinterface.Gamemode;
40+
import de.bluecolored.bluemap.common.plugin.serverinterface.Player;
41+
import de.bluecolored.bluemap.common.plugin.text.Text;
42+
43+
public class BukkitPlayer implements Player {
44+
45+
private static final Map<GameMode, Gamemode> GAMEMODE_MAP = new EnumMap<>(GameMode.class);
46+
static {
47+
GAMEMODE_MAP.put(GameMode.ADVENTURE, Gamemode.ADVENTURE);
48+
GAMEMODE_MAP.put(GameMode.SURVIVAL, Gamemode.SURVIVAL);
49+
GAMEMODE_MAP.put(GameMode.CREATIVE, Gamemode.CREATIVE);
50+
GAMEMODE_MAP.put(GameMode.SPECTATOR, Gamemode.SPECTATOR);
51+
}
52+
53+
private UUID uuid;
54+
private Text name;
55+
private UUID world;
56+
private Vector3d position;
57+
private boolean online;
58+
private boolean sneaking;
59+
private boolean invisible;
60+
private Gamemode gamemode;
61+
62+
private WeakReference<org.bukkit.entity.Player> delegate;
63+
64+
public BukkitPlayer(org.bukkit.entity.Player delegate) {
65+
this.uuid = delegate.getUniqueId();
66+
this.delegate = new WeakReference<>(delegate);
67+
update();
68+
}
69+
70+
@Override
71+
public UUID getUuid() {
72+
return this.uuid;
73+
}
74+
75+
@Override
76+
public Text getName() {
77+
return this.name;
78+
}
79+
80+
@Override
81+
public UUID getWorld() {
82+
return this.world;
83+
}
84+
85+
@Override
86+
public Vector3d getPosition() {
87+
return this.position;
88+
}
89+
90+
@Override
91+
public boolean isOnline() {
92+
return this.online;
93+
}
94+
95+
@Override
96+
public boolean isSneaking() {
97+
return this.sneaking;
98+
}
99+
100+
@Override
101+
public boolean isInvisible() {
102+
return this.invisible;
103+
}
104+
105+
@Override
106+
public Gamemode getGamemode() {
107+
return this.gamemode;
108+
}
109+
110+
/**
111+
* API access, only call on server thread!
112+
*/
113+
public void update() {
114+
org.bukkit.entity.Player player = delegate.get();
115+
if (player == null) {
116+
player = Bukkit.getPlayer(uuid);
117+
if (player == null) {
118+
this.online = false;
119+
return;
120+
}
121+
122+
delegate = new WeakReference<>(player);
123+
}
124+
125+
this.gamemode = GAMEMODE_MAP.get(player.getGameMode());
126+
127+
this.invisible = player.hasPotionEffect(PotionEffectType.INVISIBILITY);
128+
129+
this.name = Text.of(player.getName());
130+
this.online = player.isOnline();
131+
132+
Location location = player.getLocation();
133+
this.position = new Vector3d(location.getX(), location.getY(), location.getZ());
134+
this.sneaking = player.isSneaking();
135+
this.world = player.getWorld().getUID();
136+
}
137+
138+
}

BlueMapBukkit/src/main/java/de/bluecolored/bluemap/bukkit/BukkitPlugin.java

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,15 @@
2727
import java.io.File;
2828
import java.io.IOException;
2929
import java.lang.reflect.Field;
30+
import java.util.ArrayList;
31+
import java.util.Collection;
32+
import java.util.Collections;
33+
import java.util.List;
34+
import java.util.Map;
35+
import java.util.Optional;
3036
import java.util.UUID;
3137
import java.util.concurrent.CompletableFuture;
38+
import java.util.concurrent.ConcurrentHashMap;
3239
import java.util.concurrent.ExecutionException;
3340
import java.util.concurrent.Future;
3441

@@ -37,23 +44,36 @@
3744
import org.bukkit.World;
3845
import org.bukkit.command.CommandMap;
3946
import org.bukkit.command.defaults.BukkitCommand;
47+
import org.bukkit.event.EventHandler;
48+
import org.bukkit.event.EventPriority;
49+
import org.bukkit.event.Listener;
50+
import org.bukkit.event.player.PlayerJoinEvent;
51+
import org.bukkit.event.player.PlayerQuitEvent;
4052
import org.bukkit.plugin.java.JavaPlugin;
4153

4254
import de.bluecolored.bluemap.common.plugin.Plugin;
55+
import de.bluecolored.bluemap.common.plugin.serverinterface.Player;
4356
import de.bluecolored.bluemap.common.plugin.serverinterface.ServerEventListener;
4457
import de.bluecolored.bluemap.common.plugin.serverinterface.ServerInterface;
4558
import de.bluecolored.bluemap.core.logger.Logger;
4659

47-
public class BukkitPlugin extends JavaPlugin implements ServerInterface {
60+
public class BukkitPlugin extends JavaPlugin implements ServerInterface, Listener {
4861

4962
private static BukkitPlugin instance;
5063

5164
private Plugin bluemap;
5265
private EventForwarder eventForwarder;
5366
private BukkitCommands commands;
5467

68+
private int playerUpdateIndex = 0;
69+
private Map<UUID, Player> onlinePlayerMap;
70+
private List<BukkitPlayer> onlinePlayerList;
71+
5572
public BukkitPlugin() {
5673
Logger.global = new JavaLogger(getLogger());
74+
75+
this.onlinePlayerMap = new ConcurrentHashMap<>();
76+
this.onlinePlayerList = Collections.synchronizedList(new ArrayList<>());
5777

5878
this.eventForwarder = new EventForwarder();
5979
this.bluemap = new Plugin("bukkit", this);
@@ -73,6 +93,7 @@ public void onEnable() {
7393
}
7494

7595
//register events
96+
getServer().getPluginManager().registerEvents(this, this);
7697
getServer().getPluginManager().registerEvents(eventForwarder, this);
7798

7899
//register commands
@@ -92,6 +113,9 @@ public void onEnable() {
92113
//tab completions
93114
getServer().getPluginManager().registerEvents(commands, this);
94115

116+
//start updating players
117+
getServer().getScheduler().runTaskTimer(this, this::updateSomePlayers, 1, 1);
118+
95119
//load bluemap
96120
getServer().getScheduler().runTaskAsynchronously(this, () -> {
97121
try {
@@ -107,6 +131,7 @@ public void onEnable() {
107131
@Override
108132
public void onDisable() {
109133
Logger.global.logInfo("Stopping...");
134+
getServer().getScheduler().cancelTasks(this);
110135
bluemap.unload();
111136
Logger.global.logInfo("Saved and stopped!");
112137
}
@@ -179,4 +204,51 @@ public static BukkitPlugin getInstance() {
179204
return instance;
180205
}
181206

207+
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
208+
public void onPlayerJoin(PlayerJoinEvent evt) {
209+
BukkitPlayer player = new BukkitPlayer(evt.getPlayer());
210+
onlinePlayerMap.put(evt.getPlayer().getUniqueId(), player);
211+
onlinePlayerList.add(player);
212+
}
213+
214+
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
215+
public void onPlayerLeave(PlayerQuitEvent evt) {
216+
UUID playerUUID = evt.getPlayer().getUniqueId();
217+
onlinePlayerMap.remove(playerUUID);
218+
synchronized (onlinePlayerList) {
219+
onlinePlayerList.removeIf(p -> p.getUuid().equals(playerUUID));
220+
}
221+
}
222+
223+
@Override
224+
public Collection<Player> getOnlinePlayers() {
225+
return onlinePlayerMap.values();
226+
}
227+
228+
@Override
229+
public Optional<Player> getPlayer(UUID uuid) {
230+
return Optional.ofNullable(onlinePlayerMap.get(uuid));
231+
}
232+
233+
/**
234+
* Only update some of the online players each tick to minimize performance impact on the server-thread.
235+
* Only call this method on the server-thread.
236+
*/
237+
private void updateSomePlayers() {
238+
int onlinePlayerCount = onlinePlayerList.size();
239+
if (onlinePlayerCount == 0) return;
240+
241+
int playersToBeUpdated = onlinePlayerCount / 20; //with 20 tps, each player is updated once a second
242+
if (playersToBeUpdated == 0) playersToBeUpdated = 1;
243+
244+
for (int i = 0; i < playersToBeUpdated; i++) {
245+
playerUpdateIndex++;
246+
if (playerUpdateIndex >= 20 && playerUpdateIndex >= onlinePlayerCount) playerUpdateIndex = 0;
247+
248+
if (playerUpdateIndex < onlinePlayerCount) {
249+
onlinePlayerList.get(i).update();
250+
}
251+
}
252+
}
253+
182254
}

BlueMapBukkit/src/main/java/de/bluecolored/bluemap/bukkit/EventForwarder.java

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,17 @@
4242
import org.bukkit.event.block.BlockGrowEvent;
4343
import org.bukkit.event.block.BlockPlaceEvent;
4444
import org.bukkit.event.block.BlockSpreadEvent;
45+
import org.bukkit.event.player.AsyncPlayerChatEvent;
46+
import org.bukkit.event.player.PlayerJoinEvent;
47+
import org.bukkit.event.player.PlayerQuitEvent;
4548
import org.bukkit.event.world.ChunkPopulateEvent;
4649
import org.bukkit.event.world.WorldSaveEvent;
4750

4851
import com.flowpowered.math.vector.Vector2i;
4952
import com.flowpowered.math.vector.Vector3i;
5053

5154
import de.bluecolored.bluemap.common.plugin.serverinterface.ServerEventListener;
55+
import de.bluecolored.bluemap.common.plugin.text.Text;
5256

5357
public class EventForwarder implements Listener {
5458

@@ -68,7 +72,7 @@ public synchronized void removeAllListeners() {
6872

6973
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
7074
public synchronized void onWorldSaveToDisk(WorldSaveEvent evt) {
71-
listeners.forEach(l -> l.onWorldSaveToDisk(evt.getWorld().getUID()));
75+
for (ServerEventListener listener : listeners) listener.onWorldSaveToDisk(evt.getWorld().getUID());
7276
}
7377

7478
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
@@ -119,15 +123,31 @@ public void onBlockChange(BlockFertilizeEvent evt) {
119123
private synchronized void onBlockChange(Location loc) {
120124
UUID world = loc.getWorld().getUID();
121125
Vector3i pos = new Vector3i(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
122-
listeners.forEach(l -> l.onBlockChange(world, pos));
126+
for (ServerEventListener listener : listeners) listener.onBlockChange(world, pos);
123127
}
124128

125129
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
126130
public synchronized void onChunkFinishedGeneration(ChunkPopulateEvent evt) {
127131
Chunk chunk = evt.getChunk();
128132
UUID world = chunk.getWorld().getUID();
129133
Vector2i chunkPos = new Vector2i(chunk.getX(), chunk.getZ());
130-
listeners.forEach(l -> l.onChunkFinishedGeneration(world, chunkPos));
134+
for (ServerEventListener listener : listeners) listener.onChunkFinishedGeneration(world, chunkPos);
135+
}
136+
137+
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
138+
public synchronized void onPlayerJoin(PlayerJoinEvent evt) {
139+
for (ServerEventListener listener : listeners) listener.onPlayerJoin(evt.getPlayer().getUniqueId());
140+
}
141+
142+
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
143+
public synchronized void onPlayerLeave(PlayerQuitEvent evt) {
144+
for (ServerEventListener listener : listeners) listener.onPlayerJoin(evt.getPlayer().getUniqueId());
145+
}
146+
147+
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
148+
public synchronized void onPlayerChat(AsyncPlayerChatEvent evt) {
149+
String message = String.format(evt.getFormat(), evt.getPlayer().getDisplayName(), evt.getMessage());
150+
for (ServerEventListener listener : listeners) listener.onChatMessage(Text.of(message));
131151
}
132152

133153
}

BlueMapBukkit/src/main/resources/bluemap-bukkit-defaults.conf

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,9 @@ webserver {
99
port: 8100
1010
maxConnectionCount: 100
1111
}
12+
liveUpdates {
13+
enabled: true
14+
hiddenGameModes: []
15+
hideInvisible: true
16+
hideSneaking: false
17+
}

BlueMapBukkit/src/main/resources/bluemap-bukkit.conf

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ webroot: "bluemap/web"
3838
#webdata: "path/to/data/folder"
3939

4040
# If the web-application should use cookies to save the configurations of a user.
41+
# Default is true
4142
useCookies: true
4243

4344
webserver {
@@ -165,3 +166,23 @@ maps: [
165166
}
166167

167168
]
169+
170+
liveUpdates {
171+
# If the server should send live-updates and player-positions.
172+
# Default is true
173+
enabled: true
174+
175+
# A list of gamemodes that will prevent a player from appearing on the map.
176+
# Possible values are: survival, creative, spectator, adventure
177+
hiddenGameModes: [
178+
"spectator"
179+
]
180+
181+
# If this is true, players that have an invisibility (potion-)effect will be hidden on the map.
182+
# Default is true
183+
hideInvisible: true
184+
185+
# If this is true, players that are sneaking will be hidden on the map.
186+
# Default is false
187+
hideSneaking: false
188+
}

BlueMapCLI/src/main/java/de/bluecolored/bluemap/cli/BlueMapCLI.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
import com.flowpowered.math.vector.Vector2i;
5858
import com.google.common.base.Preconditions;
5959

60+
import de.bluecolored.bluemap.common.BlueMapWebServer;
6061
import de.bluecolored.bluemap.common.MapType;
6162
import de.bluecolored.bluemap.common.RenderManager;
6263
import de.bluecolored.bluemap.common.RenderTask;
@@ -72,7 +73,6 @@
7273
import de.bluecolored.bluemap.core.render.lowres.LowresModelManager;
7374
import de.bluecolored.bluemap.core.resourcepack.ParseResourceException;
7475
import de.bluecolored.bluemap.core.resourcepack.ResourcePack;
75-
import de.bluecolored.bluemap.core.web.BlueMapWebServer;
7676
import de.bluecolored.bluemap.core.web.WebFilesManager;
7777
import de.bluecolored.bluemap.core.web.WebSettings;
7878
import de.bluecolored.bluemap.core.world.SlicedWorld;

0 commit comments

Comments
 (0)