Fork of Poseidon providing Bukkit #1060 to older Beta versions (b1.0-b1.7.3)
1package org.bukkit.craftbukkit.entity;
2
3import com.legacyminecraft.poseidon.util.CrackedAllowlist;
4import com.projectposeidon.ConnectionType;
5import net.minecraft.server.*;
6
7import org.bukkit.Achievement;
8import org.bukkit.Material;
9import org.bukkit.Statistic;
10import org.bukkit.*;
11import org.bukkit.craftbukkit.CraftServer;
12import org.bukkit.craftbukkit.CraftWorld;
13import org.bukkit.craftbukkit.map.CraftMapView;
14import org.bukkit.craftbukkit.map.RenderData;
15import org.bukkit.entity.Player;
16import org.bukkit.event.player.PlayerTeleportEvent;
17import org.bukkit.map.MapView;
18
19import java.net.InetSocketAddress;
20import java.net.SocketAddress;
21import java.util.HashSet;
22import java.util.Set;
23import java.util.UUID;
24
25public class CraftPlayer extends CraftHumanEntity implements Player {
26 private Set<UUID> hiddenPlayers = new HashSet<UUID>();
27
28 public CraftPlayer(CraftServer server, EntityPlayer entity) {
29 super(server, entity);
30 }
31
32 @Override
33 public boolean isOp() {
34 return server.getHandle().isOp(getName());
35 }
36
37 @Override
38 public void setOp(boolean value) {
39 if (value == isOp()) return;
40
41 if (value) {
42 server.getHandle().e(getName());
43 } else {
44 server.getHandle().f(getName());
45 }
46
47 perm.recalculatePermissions();
48 }
49
50 public boolean isPlayer() {
51 return true;
52 }
53
54 public boolean isOnline() {
55 for (Object obj : server.getHandle().players) {
56 EntityPlayer player = (EntityPlayer) obj;
57 if (player.name.equalsIgnoreCase(getName())) {
58 return true;
59 }
60 }
61 return false;
62 }
63
64 public InetSocketAddress getAddress() {
65 SocketAddress addr = getHandle().netServerHandler.networkManager.getSocketAddress();
66 if (addr instanceof InetSocketAddress) {
67 return (InetSocketAddress) addr;
68 } else {
69 return null;
70 }
71 }
72
73 @Override
74 public EntityPlayer getHandle() {
75 return (EntityPlayer) entity;
76 }
77
78 public double getEyeHeight() {
79 return getEyeHeight(false);
80 }
81
82 public double getEyeHeight(boolean ignoreSneaking) {
83 if (ignoreSneaking) {
84 return 1.62D;
85 } else {
86 if (isSneaking()) {
87 return 1.42D;
88 } else {
89 return 1.62D;
90 }
91 }
92 }
93
94 public void setHandle(final EntityPlayer entity) {
95 super.setHandle((EntityHuman) entity);
96 this.entity = entity;
97 }
98
99 public void sendRawMessage(String message) {
100 // uberbukkit
101 int pvn = getHandle().netServerHandler.networkManager.pvn;
102
103 // The WorldEdit plugin greets the client with this character sequence
104 // to establish communication with WorldEditCUI (client-side mod).
105 // However, this char sequence crashes clients before b1.5, so this filter is needed
106 if (pvn < 11 && message.equals("\u00A75\u00A76\u00A74\u00A75")) return;
107
108 try {
109 getHandle().netServerHandler.sendPacket(new Packet3Chat(message));
110 } catch (NullPointerException exception) {
111 System.out.println("[Poseidon] Exception thrown when attempting to send packet to " + getName() + ". Does this player exist, or are they a phantom?????");
112 exception.printStackTrace();
113 }
114 }
115
116 public void sendMessage(String message) {
117 this.sendRawMessage(message);
118 }
119
120 public String getDisplayName() {
121 return getHandle().displayName;
122 }
123
124 public void setDisplayName(final String name) {
125 getHandle().displayName = name;
126 }
127
128 @Override
129 public String toString() {
130 return "CraftPlayer{" + "name=" + getName() + '}';
131 }
132
133 @Override
134 public boolean equals(Object obj) {
135 if (obj == null) {
136 return false;
137 }
138 if (getClass() != obj.getClass()) {
139 return false;
140 }
141 final CraftPlayer other = (CraftPlayer) obj;
142 if ((this.getName() == null) ? (other.getName() != null) : !this.getName().equals(other.getName())) {
143 return false;
144 }
145 return true;
146 }
147
148 @Override
149 public int hashCode() {
150 int hash = 5;
151 hash = 97 * hash + (this.getName() != null ? this.getName().hashCode() : 0);
152 return hash;
153 }
154
155 public void kickPlayer(String message) {
156 if (this.isOnline() && !getHandle().netServerHandler.disconnected) // Poseidon: Kick/Disconnect spam fix
157 getHandle().netServerHandler.disconnect(message == null ? "" : message);
158 }
159
160 public void setCompassTarget(Location loc) {
161 // Do not directly assign here, from the packethandler we'll assign it.
162 getHandle().netServerHandler.sendPacket(new Packet6SpawnPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
163 }
164
165 //Project Poseidon Start
166 public UUID getUniqueId() {
167 //return UUIDPlayerStorage.getInstance().getPlayerUUID(getName());
168 return getHandle().playerUUID;
169 }
170 //Project Poseidon End
171
172 public UUID getPlayerUUID() {
173 return getUniqueId();
174 }
175
176 public Location getCompassTarget() {
177 return getHandle().compassTarget;
178 }
179
180 public void chat(String msg) {
181 getHandle().netServerHandler.chat(msg);
182 }
183
184 public boolean performCommand(String command) {
185 return server.dispatchCommand(this, command);
186 }
187
188 public void playNote(Location loc, byte instrument, byte note) {
189 getHandle().netServerHandler.sendPacket(new Packet54PlayNoteBlock(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), instrument, note));
190 }
191
192 public void playNote(Location loc, Instrument instrument, Note note) {
193 getHandle().netServerHandler.sendPacket(new Packet54PlayNoteBlock(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), instrument.getType(), note.getId()));
194 }
195
196 public void playEffect(Location loc, Effect effect, int data) {
197
198 int packetData = effect.getId();
199 Packet61 packet = new Packet61(packetData, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), data);
200 getHandle().netServerHandler.sendPacket(packet);
201 }
202
203 public void sendBlockChange(Location loc, Material material, byte data) {
204 sendBlockChange(loc, material.getId(), data);
205 }
206
207 public void sendBlockChange(Location loc, int material, byte data) {
208 Packet53BlockChange packet = new Packet53BlockChange(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), ((CraftWorld) loc.getWorld()).getHandle());
209
210 packet.material = material;
211 packet.data = data;
212 getHandle().netServerHandler.sendPacket(packet);
213 }
214
215 public boolean sendChunkChange(Location loc, int sx, int sy, int sz, byte[] data) {
216 int x = loc.getBlockX();
217 int y = loc.getBlockY();
218 int z = loc.getBlockZ();
219
220 int cx = x >> 4;
221 int cz = z >> 4;
222
223 if (sx <= 0 || sy <= 0 || sz <= 0) {
224 return false;
225 }
226
227 if ((x + sx - 1) >> 4 != cx || (z + sz - 1) >> 4 != cz || y < 0 || y + sy > 128) {
228 return false;
229 }
230
231 if (data.length != (sx * sy * sz * 5) / 2) {
232 return false;
233 }
234
235 Packet51MapChunk packet = new Packet51MapChunk(x, y, z, sx, sy, sz, data);
236
237 getHandle().netServerHandler.sendPacket(packet);
238
239 return true;
240 }
241
242 public void sendMap(MapView map) {
243 RenderData data = ((CraftMapView) map).render(this);
244 for (int x = 0; x < 128; ++x) {
245 byte[] bytes = new byte[131];
246 bytes[1] = (byte) x;
247 for (int y = 0; y < 128; ++y) {
248 bytes[y + 3] = data.buffer[y * 128 + x];
249 }
250 Packet131 packet = new Packet131((short) Material.MAP.getId(), map.getId(), bytes);
251 getHandle().netServerHandler.sendPacket(packet);
252 }
253 }
254
255 @Override
256 public boolean teleport(Location location) {
257 // From = Players current Location
258 Location from = this.getLocation();
259 // To = Players new Location if Teleport is Successful
260 Location to = location;
261 // Create & Call the Teleport Event.
262 PlayerTeleportEvent event = new PlayerTeleportEvent((Player) this, from, to);
263 server.getPluginManager().callEvent(event);
264 // Return False to inform the Plugin that the Teleport was unsuccessful/cancelled.
265 if (event.isCancelled() == true) {
266 return false;
267 }
268 // Update the From Location
269 from = event.getFrom();
270 // Grab the new To Location dependent on whether the event was cancelled.
271 to = event.getTo();
272 // Grab the To and From World Handles.
273 WorldServer fromWorld = ((CraftWorld) from.getWorld()).getHandle();
274 WorldServer toWorld = ((CraftWorld) to.getWorld()).getHandle();
275 // Grab the EntityPlayer
276 EntityPlayer entity = getHandle();
277
278 // Check if the fromWorld and toWorld are the same.
279 if (fromWorld == toWorld) {
280 entity.netServerHandler.teleport(to);
281 } else {
282 server.getHandle().moveToWorld(entity, toWorld.dimension, to);
283 }
284 return true;
285 }
286
287 public void setSneaking(boolean sneak) {
288 getHandle().setSneak(sneak);
289 }
290
291 public boolean isSneaking() {
292 return getHandle().isSneaking();
293 }
294
295 public void loadData() {
296 server.getHandle().playerFileData.b(getHandle());
297 }
298
299 public void saveData() {
300 server.getHandle().playerFileData.a(getHandle());
301 }
302
303 public void updateInventory() {
304 getHandle().updateInventory(getHandle().activeContainer);
305 }
306
307 public void setSleepingIgnored(boolean isSleeping) {
308 getHandle().fauxSleeping = isSleeping;
309 ((CraftWorld) getWorld()).getHandle().checkSleepStatus();
310 }
311
312 public boolean isSleepingIgnored() {
313 return getHandle().fauxSleeping;
314 }
315
316 public void awardAchievement(Achievement achievement) {
317 sendStatistic(achievement.getId(), 1);
318 }
319
320 public void incrementStatistic(Statistic statistic) {
321 incrementStatistic(statistic, 1);
322 }
323
324 public void incrementStatistic(Statistic statistic, int amount) {
325 sendStatistic(statistic.getId(), amount);
326 }
327
328 public void incrementStatistic(Statistic statistic, Material material) {
329 incrementStatistic(statistic, material, 1);
330 }
331
332 public void incrementStatistic(Statistic statistic, Material material, int amount) {
333 if (!statistic.isSubstatistic()) {
334 throw new IllegalArgumentException("Given statistic is not a substatistic");
335 }
336 if (statistic.isBlock() != material.isBlock()) {
337 throw new IllegalArgumentException("Given material is not valid for this substatistic");
338 }
339
340 int mat = material.getId();
341
342 if (!material.isBlock()) {
343 mat -= 255;
344 }
345
346 sendStatistic(statistic.getId() + mat, amount);
347 }
348
349 private void sendStatistic(int id, int amount) {
350
351 while (amount > Byte.MAX_VALUE) {
352 sendStatistic(id, Byte.MAX_VALUE);
353 amount -= Byte.MAX_VALUE;
354 }
355
356 getHandle().netServerHandler.sendPacket(new Packet200Statistic(id, amount));
357 }
358
359 public void setPlayerTime(long time, boolean relative) {
360 getHandle().timeOffset = time;
361 getHandle().relativeTime = relative;
362 }
363
364 public long getPlayerTimeOffset() {
365 return getHandle().timeOffset;
366 }
367
368 public long getPlayerTime() {
369 return getHandle().getPlayerTime();
370 }
371
372 public boolean isPlayerTimeRelative() {
373 return getHandle().relativeTime;
374 }
375
376 public ConnectionType getConnectionType() {
377 return getHandle().netServerHandler.getConnectionType();
378 }
379
380 public boolean hasReceivedPacket0() {
381 return getHandle().netServerHandler.isReceivedKeepAlive();
382 }
383
384 public boolean isUsingReleaseToBeta() {
385 return getHandle().netServerHandler.isUsingReleaseToBeta();
386 }
387
388 public void resetPlayerTime() {
389 setPlayerTime(0, true);
390 }
391
392 public boolean isBanned() {
393 return server.getHandle().banByName.contains(getName().toLowerCase());
394 }
395
396 public void setBanned(boolean value) {
397 if (value) {
398 server.getHandle().a(getName().toLowerCase());
399 } else {
400 server.getHandle().b(getName().toLowerCase());
401 }
402 }
403
404 public boolean isWhitelisted() {
405 return server.getHandle().e().contains(getName().toLowerCase());
406 }
407
408 public void setWhitelisted(boolean value) {
409 if (value) {
410 server.getHandle().k(getName().toLowerCase());
411 } else {
412 server.getHandle().l(getName().toLowerCase());
413 }
414 }
415
416 public void hidePlayer(Player player) {
417
418 hiddenPlayers.add(player.getUniqueId());
419
420 //remove this player from the hidden player's EntityTrackerEntry
421 EntityTracker tracker = ((WorldServer) entity.world).tracker;
422 EntityPlayer other = ((CraftPlayer) player).getHandle();
423 EntityTrackerEntry entry = (EntityTrackerEntry) tracker.b.a(other.id);
424 if (entry != null) {
425 entry.c(getHandle());
426 }
427
428 }
429
430 public void showPlayer(Player player) {
431 hiddenPlayers.remove(player.getUniqueId());
432
433 EntityTracker tracker = ((WorldServer) entity.world).tracker;
434 EntityPlayer other = ((CraftPlayer) player).getHandle();
435 EntityTrackerEntry entry = (EntityTrackerEntry) tracker.b.a(other.id);
436 if (entry != null && !entry.trackedPlayers.contains(getHandle())) {
437 entry.b(getHandle());
438 }
439
440 }
441
442 public boolean canSee(Player player) {
443 return !hiddenPlayers.contains(player.getUniqueId());
444 }
445
446 public void sendPacket(final Player player, final Packet packet) {
447 if (player.isOnline()) {
448 NetServerHandler nsh = getHandle().netServerHandler;
449 nsh.sendPacket(packet);
450 }
451 }
452
453 // uberbukkit start
454
455 public boolean isCracked() {
456 return CrackedAllowlist.get().contains(getName());
457 }
458
459 public boolean hasBed() {
460 return ((EntityHuman) getHandle()).b != null;
461 }
462
463 public Location getBedLocation() {
464 ChunkCoordinates coords = ((EntityHuman) getHandle()).b;
465 String worldname = getHandle().spawnWorld;
466
467 org.bukkit.World world = getServer().getWorld(worldname);
468
469 return new Location(world, coords.x, coords.y, coords.z);
470 }
471
472 public void setBedLocation(Location location) {
473 ChunkCoordinates coords = new ChunkCoordinates(location.getBlockX(), location.getBlockY(), location.getBlockZ());
474
475 ((EntityHuman) getHandle()).b = coords;
476
477 String worldname = "";
478 if (location.getWorld() != null) worldname = location.getWorld().getName();
479
480 getHandle().spawnWorld = worldname;
481 }
482
483 // uberbukkit end
484}