|
1 |
| -# ProtocolLib |
2 |
| - |
3 |
| -Certain tasks are impossible to perform with the standard Bukkit API, and may require |
4 |
| -working with and even modifying Minecraft directly. A common technique is to modify incoming |
5 |
| -and outgoing [packets](https://www.wiki.vg/Protocol), or inject custom packets into the |
6 |
| -stream. This is quite cumbersome to do, however, and most implementations will break |
7 |
| -as soon as a new version of Minecraft has been released, mostly due to obfuscation. |
8 |
| - |
9 |
| -Critically, different plugins that use this approach may _hook_ into the same classes, |
10 |
| -with unpredictable outcomes. More than often this causes plugins to crash, but it may also |
11 |
| -lead to more subtle bugs. |
12 |
| - |
13 |
| -Currently maintained by dmulloy2 on behalf of [Spigot](https://www.spigotmc.org/). |
14 |
| - |
15 |
| -### Resources |
16 |
| - |
17 |
| -* [Resource Page](https://www.spigotmc.org/resources/protocollib.1997/) |
18 |
| -* [Dev Builds](https://ci.dmulloy2.net/job/ProtocolLib) |
19 |
| -* [JavaDoc](https://ci.dmulloy2.net/job/ProtocolLib/javadoc/index.html) |
20 |
| - |
21 |
| -### Compilation |
22 |
| - |
23 |
| -ProtocolLib is built with [Maven](https://maven.apache.org/). If you have it installed, just run |
24 |
| -`mvn package` in the root project folder. |
25 |
| - |
26 |
| -### A new API |
27 |
| - |
28 |
| -__ProtocolLib__ attempts to solve this problem by providing an event API, much like Bukkit, |
29 |
| -that allows plugins to monitor, modify, or cancel packets sent and received. But, more importantly, |
30 |
| -the API also hides all the gritty, obfuscated classes with a simple index based read/write system. |
31 |
| -You no longer have to reference CraftBukkit! |
32 |
| - |
33 |
| -### Using ProtocolLib |
34 |
| - |
35 |
| -To use this library, first add ProtocolLib.jar to your Java build path. Then, add ProtocolLib |
36 |
| -as a dependency or soft dependency to your plugin.yml file like any other plugin: |
37 |
| - |
38 |
| -````yml |
39 |
| -depend: [ ProtocolLib ] |
40 |
| -```` |
41 |
| - |
42 |
| -You can also add ProtocolLib as a Maven dependency: |
43 |
| - |
44 |
| -````xml |
45 |
| -<repositories> |
46 |
| - <repository> |
47 |
| - <id>dmulloy2-repo</id> |
48 |
| - <url>https://repo.dmulloy2.net/repository/public/</url> |
49 |
| - </repository> |
50 |
| -</repositories> |
51 |
| - |
52 |
| -<dependencies> |
53 |
| - <dependency> |
54 |
| - <groupId>com.comphenix.protocol</groupId> |
55 |
| - <artifactId>ProtocolLib</artifactId> |
56 |
| - <version>4.7.0</version> |
57 |
| - <scope>provided</scope> |
58 |
| - </dependency> |
59 |
| -</dependencies> |
60 |
| -```` |
61 |
| - |
62 |
| -Or use the maven dependency with gradle: |
63 |
| - |
64 |
| -```gradle |
65 |
| -repositories { |
66 |
| - maven { url "https://repo.dmulloy2.net/repository/public/" } |
67 |
| -} |
68 |
| -
|
69 |
| -dependencies { |
70 |
| - compileOnly group: "com.comphenix.protocol", name: "ProtocolLib", version: "4.7.0"; |
71 |
| -} |
72 |
| -``` |
73 |
| - |
74 |
| -Then get a reference to ProtocolManager in onLoad() or onEnable() and you're good to go. |
75 |
| - |
76 |
| -````java |
77 |
| -private ProtocolManager protocolManager; |
78 |
| - |
79 |
| -public void onLoad() { |
80 |
| - protocolManager = ProtocolLibrary.getProtocolManager(); |
81 |
| -} |
82 |
| -```` |
83 |
| - |
84 |
| -To listen for packets sent by the server to a client, add a server-side listener: |
85 |
| - |
86 |
| -````java |
87 |
| -// Disable all sound effects |
88 |
| -protocolManager.addPacketListener(new PacketAdapter( |
89 |
| - this, |
90 |
| - ListenerPriority.NORMAL, |
91 |
| - PacketType.Play.Server.NAMED_SOUND_EFFECT |
92 |
| -) { |
93 |
| - @Override |
94 |
| - public void onPacketSending(PacketEvent event) { |
95 |
| - event.setCancelled(true); |
96 |
| - } |
97 |
| -}); |
98 |
| -```` |
99 |
| - |
100 |
| -It's also possible to read and modify the content of these packets. For instance, you can create a global |
101 |
| -censor by listening for Packet3Chat events: |
102 |
| - |
103 |
| -````java |
104 |
| -// Censor |
105 |
| -protocolManager.addPacketListener(new PacketAdapter( |
106 |
| - this, |
107 |
| - ListenerPriority.NORMAL, |
108 |
| - PacketType.Play.Client.CHAT |
109 |
| -) { |
110 |
| - @Override |
111 |
| - public void onPacketReceiving(PacketEvent event) { |
112 |
| - PacketContainer packet = event.getPacket(); |
113 |
| - String message = packet.getStrings().read(0); |
114 |
| - |
115 |
| - if (message.contains("shit") || message.contains("damn")) { |
116 |
| - event.setCancelled(true); |
117 |
| - event.getPlayer().sendMessage("Bad manners!"); |
118 |
| - } |
119 |
| - } |
120 |
| -}); |
121 |
| -```` |
122 |
| - |
123 |
| -### Sending packets |
124 |
| - |
125 |
| -Normally, you might have to do something ugly like the following: |
126 |
| - |
127 |
| -````java |
128 |
| -PacketPlayOutExplosion fakeExplosion = new PacketPlayOutExplosion( |
129 |
| - player.getLocation().getX(), |
130 |
| - player.getLocation().getY(), |
131 |
| - player.getLocation().getZ(), |
132 |
| - 3.0F, |
133 |
| - new ArrayList<>(), |
134 |
| - new Vec3D( |
135 |
| - player.getVelocity().getX() + 1, |
136 |
| - player.getVelocity().getY() + 1, |
137 |
| - player.getVelocity().getZ() + 1 |
138 |
| - ) |
139 |
| -); |
140 |
| - |
141 |
| -((CraftPlayer) player).getHandle().b.a(fakeExplosion); |
142 |
| -```` |
143 |
| - |
144 |
| -But with ProtocolLib, you can turn that into something more manageable: |
145 |
| - |
146 |
| -````java |
147 |
| -PacketContainer fakeExplosion = new PacketContainer(PacketType.Play.Server.EXPLOSION); |
148 |
| -fakeExplosion.getDoubles() |
149 |
| - .write(0, player.getLocation().getX()) |
150 |
| - .write(1, player.getLocation().getY()) |
151 |
| - .write(2, player.getLocation().getZ()); |
152 |
| -fakeExplosion.getFloat().write(0, 3.0F); |
153 |
| -fakeExplosion.getBlockPositionCollectionModifier().write(0, new ArrayList<>()); |
154 |
| -fakeExplosion.getVectors().write(0, player.getVelocity().add(new Vector(1, 1, 1))); |
155 |
| - |
156 |
| -protocolManager.sendServerPacket(player, fakeExplosion); |
157 |
| -```` |
158 |
| - |
159 |
| -### Compatibility |
160 |
| - |
161 |
| -One of the main goals of this project was to achieve maximum compatibility with CraftBukkit. And the end |
162 |
| -result is quite flexible. It's likely that I won't have to update ProtocolLib for anything but bug fixes |
163 |
| -and new features. |
164 |
| - |
165 |
| -How is this possible? It all comes down to reflection in the end. Essentially, no name is hard coded - |
166 |
| -every field, method and class is deduced by looking at field types, package names or parameter |
167 |
| -types. It's remarkably consistent across different versions. |
| 1 | +# ProtocolLib |
| 2 | + |
| 3 | +Certain tasks are impossible to perform with the standard Bukkit API, and may require |
| 4 | +working with and even modifying Minecraft directly. A common technique is to modify incoming |
| 5 | +and outgoing [packets](https://www.wiki.vg/Protocol), or inject custom packets into the |
| 6 | +stream. This is quite cumbersome to do, however, and most implementations will break |
| 7 | +as soon as a new version of Minecraft has been released, mostly due to obfuscation. |
| 8 | + |
| 9 | +Critically, different plugins that use this approach may _hook_ into the same classes, |
| 10 | +with unpredictable outcomes. More than often this causes plugins to crash, but it may also |
| 11 | +lead to more subtle bugs. |
| 12 | + |
| 13 | +Currently maintained by dmulloy2 on behalf of [Spigot](https://www.spigotmc.org/). |
| 14 | + |
| 15 | +### Resources |
| 16 | + |
| 17 | +* [Resource Page](https://www.spigotmc.org/resources/protocollib.1997/) |
| 18 | +* [Dev Builds](https://ci.dmulloy2.net/job/ProtocolLib) |
| 19 | +* [JavaDoc](https://ci.dmulloy2.net/job/ProtocolLib/javadoc/index.html) |
| 20 | + |
| 21 | +### Compilation |
| 22 | + |
| 23 | +ProtocolLib is built with [Maven](https://maven.apache.org/). If you have it installed, just run |
| 24 | +`mvn package` in the root project folder. |
| 25 | + |
| 26 | +### A new API |
| 27 | + |
| 28 | +__ProtocolLib__ attempts to solve this problem by providing an event API, much like Bukkit, |
| 29 | +that allows plugins to monitor, modify, or cancel packets sent and received. But, more importantly, |
| 30 | +the API also hides all the gritty, obfuscated classes with a simple index based read/write system. |
| 31 | +You no longer have to reference CraftBukkit! |
| 32 | + |
| 33 | +### Using ProtocolLib |
| 34 | + |
| 35 | +To use this library, first add ProtocolLib.jar to your Java build path. Then, add ProtocolLib |
| 36 | +as a dependency or soft dependency to your plugin.yml file like any other plugin: |
| 37 | + |
| 38 | +````yml |
| 39 | +depend: [ ProtocolLib ] |
| 40 | +```` |
| 41 | + |
| 42 | +You can also add ProtocolLib as a Maven dependency: |
| 43 | + |
| 44 | +````xml |
| 45 | +<repositories> |
| 46 | + <repository> |
| 47 | + <id>dmulloy2-repo</id> |
| 48 | + <url>https://repo.dmulloy2.net/repository/public/</url> |
| 49 | + </repository> |
| 50 | +</repositories> |
| 51 | + |
| 52 | +<dependencies> |
| 53 | + <dependency> |
| 54 | + <groupId>com.comphenix.protocol</groupId> |
| 55 | + <artifactId>ProtocolLib</artifactId> |
| 56 | + <version>4.7.0</version> |
| 57 | + <scope>provided</scope> |
| 58 | + </dependency> |
| 59 | +</dependencies> |
| 60 | +```` |
| 61 | + |
| 62 | +Or use the maven dependency with gradle: |
| 63 | + |
| 64 | +```gradle |
| 65 | +repositories { |
| 66 | + maven { url "https://repo.dmulloy2.net/repository/public/" } |
| 67 | +} |
| 68 | +
|
| 69 | +dependencies { |
| 70 | + compileOnly group: "com.comphenix.protocol", name: "ProtocolLib", version: "4.7.0"; |
| 71 | +} |
| 72 | +``` |
| 73 | + |
| 74 | +Then get a reference to ProtocolManager in onLoad() or onEnable() and you're good to go. |
| 75 | + |
| 76 | +````java |
| 77 | +private ProtocolManager protocolManager; |
| 78 | + |
| 79 | +public void onLoad() { |
| 80 | + protocolManager = ProtocolLibrary.getProtocolManager(); |
| 81 | +} |
| 82 | +```` |
| 83 | + |
| 84 | +To listen for packets sent by the server to a client, add a server-side listener: |
| 85 | + |
| 86 | +````java |
| 87 | +// Disable all sound effects |
| 88 | +protocolManager.addPacketListener(new PacketAdapter( |
| 89 | + this, |
| 90 | + ListenerPriority.NORMAL, |
| 91 | + PacketType.Play.Server.NAMED_SOUND_EFFECT |
| 92 | +) { |
| 93 | + @Override |
| 94 | + public void onPacketSending(PacketEvent event) { |
| 95 | + event.setCancelled(true); |
| 96 | + } |
| 97 | +}); |
| 98 | +```` |
| 99 | + |
| 100 | +It's also possible to read and modify the content of these packets. For instance, you can create a global |
| 101 | +censor by listening for Packet3Chat events: |
| 102 | + |
| 103 | +````java |
| 104 | +// Censor |
| 105 | +protocolManager.addPacketListener(new PacketAdapter( |
| 106 | + this, |
| 107 | + ListenerPriority.NORMAL, |
| 108 | + PacketType.Play.Client.CHAT |
| 109 | +) { |
| 110 | + @Override |
| 111 | + public void onPacketReceiving(PacketEvent event) { |
| 112 | + PacketContainer packet = event.getPacket(); |
| 113 | + String message = packet.getStrings().read(0); |
| 114 | + |
| 115 | + if (message.contains("shit") || message.contains("damn")) { |
| 116 | + event.setCancelled(true); |
| 117 | + event.getPlayer().sendMessage("Bad manners!"); |
| 118 | + } |
| 119 | + } |
| 120 | +}); |
| 121 | +```` |
| 122 | + |
| 123 | +### Sending packets |
| 124 | + |
| 125 | +Normally, you might have to do something ugly like the following: |
| 126 | + |
| 127 | +````java |
| 128 | +PacketPlayOutExplosion fakeExplosion = new PacketPlayOutExplosion( |
| 129 | + player.getLocation().getX(), |
| 130 | + player.getLocation().getY(), |
| 131 | + player.getLocation().getZ(), |
| 132 | + 3.0F, |
| 133 | + new ArrayList<>(), |
| 134 | + new Vec3D( |
| 135 | + player.getVelocity().getX() + 1, |
| 136 | + player.getVelocity().getY() + 1, |
| 137 | + player.getVelocity().getZ() + 1 |
| 138 | + ) |
| 139 | +); |
| 140 | + |
| 141 | +((CraftPlayer) player).getHandle().b.a(fakeExplosion); |
| 142 | +```` |
| 143 | + |
| 144 | +But with ProtocolLib, you can turn that into something more manageable: |
| 145 | + |
| 146 | +````java |
| 147 | +PacketContainer fakeExplosion = new PacketContainer(PacketType.Play.Server.EXPLOSION); |
| 148 | +fakeExplosion.getDoubles() |
| 149 | + .write(0, player.getLocation().getX()) |
| 150 | + .write(1, player.getLocation().getY()) |
| 151 | + .write(2, player.getLocation().getZ()); |
| 152 | +fakeExplosion.getFloat().write(0, 3.0F); |
| 153 | +fakeExplosion.getBlockPositionCollectionModifier().write(0, new ArrayList<>()); |
| 154 | +fakeExplosion.getVectors().write(0, player.getVelocity().add(new Vector(1, 1, 1))); |
| 155 | + |
| 156 | +protocolManager.sendServerPacket(player, fakeExplosion); |
| 157 | +```` |
| 158 | + |
| 159 | +### Compatibility |
| 160 | + |
| 161 | +One of the main goals of this project was to achieve maximum compatibility with CraftBukkit. And the end |
| 162 | +result is quite flexible. It's likely that I won't have to update ProtocolLib for anything but bug fixes |
| 163 | +and new features. |
| 164 | + |
| 165 | +How is this possible? It all comes down to reflection in the end. Essentially, no name is hard coded - |
| 166 | +every field, method and class is deduced by looking at field types, package names or parameter |
| 167 | +types. It's remarkably consistent across different versions. |
0 commit comments