-
Notifications
You must be signed in to change notification settings - Fork 61
Expand file tree
/
Copy pathNMSHandler.java
More file actions
296 lines (259 loc) · 11.3 KB
/
NMSHandler.java
File metadata and controls
296 lines (259 loc) · 11.3 KB
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
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
package dev.rosewood.rosestacker.nms;
import dev.rosewood.rosestacker.nms.hologram.Hologram;
import dev.rosewood.rosestacker.nms.spawner.StackedSpawnerTile;
import dev.rosewood.rosestacker.nms.storage.EntityDataEntry;
import dev.rosewood.rosestacker.nms.storage.StackedEntityDataStorage;
import dev.rosewood.rosestacker.nms.storage.StackedEntityDataStorageType;
import java.util.List;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Creeper;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Item;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
/**
* Allows performing certain actions that are only possible through the use of NMS.
* For internal use only. Subject to change extremely frequently.
*/
@ApiStatus.Internal
public interface NMSHandler {
List<String> REMOVABLE_NBT_KEYS = List.of(
"UUID", "Pos", "Rotation", "WorldUUIDMost", "WorldUUIDLeast",
"Motion", "OnGround", "FallDistance", "Leash", "Spigot.ticksLived",
"Paper.OriginWorld", "Paper.Origin", "Patrolling", "PatrolTarget",
"RaidId", "Wave", "AngryAt", "AngerTime", "Pose", "LastPoseTick",
"uuid", "pos", "rotation", "world_uuid_most", "world_uuid_least",
"motion", "on_ground", "fall_distance", "leash", "patrolling",
"patrol_target", "raid_id", "wave", "angry_at", "anger_time", "pose",
"last_pose_tick"
);
List<String> UNSAFE_NBT_KEYS = List.of(
"ArmorItems", "HandItems", "Items", "ChestedHorse", "Saddle",
"DecorItem", "Inventory", "carriedBlockState", "DeathTime", "Health",
"Attributes", "ActiveEffects", "ArmorDropChances", "HandDropChances", "Brain",
"LeftHanded", "Team", "SaddleItem",
"armor_items", "hand_items", "items", "chested_horse", "saddle",
"decor_item", "inventory", "carried_block_state", "death_time", "health",
"attributes", "active_effects", "armor_drop_chances", "hand_drop_chances", "brain",
"left_handed", "team", "saddle_item"
);
/**
* Creates a LivingEntity instance where the actual entity has not been added to the world.
* To be used in conjunction with {@link #spawnExistingEntity(LivingEntity, SpawnReason, boolean)}
*
* @param entityType The type of the entity to spawn
* @param location The location the entity would have spawned at
* @param spawnReason The reason the entity would have been spawned
* @return The newly created LivingEntity instance
*/
LivingEntity createNewEntityUnspawned(EntityType entityType, Location location, SpawnReason spawnReason);
/**
* Adds an unspawned entity to the world.
* To be used in conjunction with {@link #createNewEntityUnspawned(EntityType, Location, SpawnReason)}
*
* @param entity The entity to add
* @param spawnReason The reason the entity is spawning
* @param bypassSpawnEvent Should an EntitySpawnEvent be called for this entity?
*/
void spawnExistingEntity(LivingEntity entity, SpawnReason spawnReason, boolean bypassSpawnEvent);
/**
* Spawns an entity with a certain SpawnReason
*
* @param entityType The type of entity to spawn
* @param spawnReason The reason the entity is spawning
*/
default LivingEntity spawnEntityWithReason(EntityType entityType, Location location, SpawnReason spawnReason, boolean bypassSpawnEvent) {
LivingEntity entity = this.createNewEntityUnspawned(entityType, location, spawnReason);
this.spawnExistingEntity(entity, spawnReason, bypassSpawnEvent);
return entity;
}
/**
* Updates the name and visibility of an Entity's nametag for a Player
*
* @param player The Player to send the packet to
* @param entity The Entity to toggle
* @param customName The name to display for the entity, nullable
* @param customNameVisible true to make the nametag visible, otherwise false
*/
void updateEntityNameTagForPlayer(Player player, Entity entity, String customName, boolean customNameVisible);
/**
* Updates the visibility of an Entity's nametag for a Player
*
* @param player The Player to send the packet to
* @param entity The Entity to toggle
* @param customNameVisible true to make the nametag visible, otherwise false
*/
void updateEntityNameTagVisibilityForPlayer(Player player, Entity entity, boolean customNameVisible);
/**
* Unignites a creeper
*
* @param creeper The creeper to unignite
*/
void unigniteCreeper(Creeper creeper);
/**
* Removes entity goals and movement
*
* @param livingEntity The entity to remove goals and movement from
*/
void removeEntityGoals(LivingEntity livingEntity);
/**
* Sets a String value into an ItemStack's NBT
*
* @param itemStack The ItemStack
* @param key The key to store the value at
* @param value The value to store
* @return A copy of the ItemStack with the applied NBT value
*/
ItemStack setItemStackNBT(ItemStack itemStack, String key, String value);
/**
* Sets an int value into an ItemStack's NBT
*
* @param itemStack The ItemStack
* @param key The key to store the value at
* @param value The value to store
* @return A copy of the ItemStack with the applied NBT value
*/
ItemStack setItemStackNBT(ItemStack itemStack, String key, int value);
/**
* Gets a String value from an ItemStack's NBT
*
* @param itemStack The ItemStack
* @param key The key the value is stored at
* @return The value stored on the ItemStack, or an empty String if none found
*/
String getItemStackNBTString(ItemStack itemStack, String key);
/**
* Gets an int value from an ItemStack's NBT
*
* @param itemStack The ItemStack
* @param key The key the value is stored at
* @return The value stored on the ItemStack, or 0 if none found
*/
int getItemStackNBTInt(ItemStack itemStack, String key);
/**
* Gets a String value from an ItemStack's NBT compound
*
* @param itemStack The ItemStack
* @param compoundKey The key the compound is stored at on the item
* @param valueKey The key the value is stored at in the compound
* @return The value stored on the ItemStack, or an empty String if none found
*/
String getItemStackNBTStringFromCompound(ItemStack itemStack, String compoundKey, String valueKey);
/**
* Sets the LivingEntity's lastHurtByPlayer value to the given Player
*
* @param livingEntity The LivingEntity
* @param player The Player
*/
void setLastHurtBy(LivingEntity livingEntity, Player player);
/**
* Checks if a LivingEntity can see a specific Location point
*
* @param entity1 The LivingEntity
* @param location The Location point
* @return true if the LivingEntity can see the Location point, false otherwise
*/
boolean hasLineOfSight(LivingEntity entity1, Location location);
/**
* Checks if a LivingEntity can see a specific Entity
*
* @param entity1 The LivingEntity
* @param entity2 The Entity
* @return true if the LivingEntity can see the Entity, false otherwise
*/
default boolean hasLineOfSight(LivingEntity entity1, Entity entity2) {
Location location;
if (entity2 instanceof LivingEntity) {
location = ((LivingEntity) entity2).getEyeLocation();
} else {
location = entity2.getLocation().add(0, entity2.getHeight() * 0.85, 0);
}
return this.hasLineOfSight(entity1, location);
}
/**
* Checks if an entity is an actively participating in a raid
*
* @param entity The entity to check
* @return true if the entity is an active raider, false otherwise
*/
boolean isActiveRaider(LivingEntity entity);
/**
* Creates a new EntityDataEntry from a LivingEntity
*
* @param livingEntity The LivingEntity
* @return The EntityDataEntry
*/
EntityDataEntry createEntityDataEntry(LivingEntity livingEntity);
/**
* Creates a new StackedEntityDataStorage instance for storing large amounts of entities of the same type in a small data footprint
*
* @param livingEntity The base entity
* @param storageType The type of storage to create
* @return a new StackedEntityDataStorage instance
*/
StackedEntityDataStorage createEntityDataStorage(LivingEntity livingEntity, StackedEntityDataStorageType storageType);
/**
* Creates a new StackedEntityDataStorage instance from existing serialized data
*
* @param livingEntity The base entity
* @param data The StackedEntityDataStorage data, should be acquired from {@link StackedEntityDataStorage#serialize()}
* @param storageType The type of storage to deserialize
* @return a new StackedEntityDataStorage instance
*/
StackedEntityDataStorage deserializeEntityDataStorage(LivingEntity livingEntity, byte[] data, StackedEntityDataStorageType storageType);
/**
* Injects the custom stacked spawner logic into the tile entity of the given spawner
*
* @param stackedSpawner The StackedSpawner instance to inject the custom stacked spawner logic into
* @return A StackedSpawnerTile instance that was injected or null if the object given was not a valid StackedSpawner
*/
StackedSpawnerTile injectStackedSpawnerTile(Object stackedSpawner);
/**
* Creates a hologram at the given location with the given text
*
* @param location The location to create the hologram at
* @param text The text to display on the hologram
* @return The hologram created
*/
Hologram createHologram(Location location, List<String> text);
/**
* @return true if empty spawners are supported, false otherwise
*/
default boolean supportsEmptySpawners() {
return false;
}
/**
* 1.19 uses a new RandomSource system which causes a server crash when accessed async.
* Try to hijack this RandomSource and inject our own into the world which allows "thread-safe" access.
* This is likely a very bad idea, sorry to whoever is reading this.
*
* @param world The World to hijack the RandomSource of
*/
default void hijackRandomSource(World world) {
}
/**
* Sets the entity's fromMobSpawner property on paper servers
*
* @param entity The entity
*/
default void setPaperFromMobSpawner(Entity entity) {
}
/**
* Sets the entity custom name bypassing the 256 character limit set by Bukkit.
* Why is this character limit still a thing? Names have supported it for ages.
*
* @param entity The entity to change the custom name of
* @param customName The custom name to set
*/
void setCustomNameUncapped(Entity entity, String customName);
int getItemDespawnRate(Item item);
EntityDeathEvent createAsyncEntityDeathEvent(@NotNull LivingEntity what, @NotNull List<ItemStack> drops, int droppedExp);
List<ItemStack> getBoxContents(Item item);
}