Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8c3127dee1 | ||
|
|
5ec87c9d76 | ||
|
|
2205ce639e | ||
|
|
2844d75607 | ||
|
|
a6810ea874 | ||
|
|
aaf1af8e41 | ||
|
|
b8dd43aeed | ||
|
|
e959efc5af | ||
|
|
73ce01bbde | ||
|
|
b30628f6db | ||
|
|
9289825d87 | ||
|
|
57cfbc4f81 | ||
|
|
3ab2026d62 | ||
|
|
e439c778a6 | ||
|
|
98413c917e | ||
|
|
540a5e53c4 | ||
|
|
27047f83a5 | ||
|
|
222b535c15 | ||
|
|
3f31af6b70 | ||
|
|
b6a054b766 | ||
|
|
3b7b692e80 | ||
|
|
c6788addeb | ||
|
|
5b38bc7f38 | ||
|
|
33bb12713d | ||
|
|
d175a7655e | ||
|
|
4afb38aae1 | ||
|
|
36b5670b3d | ||
|
|
7b61796506 | ||
|
|
684b687e42 | ||
|
|
7a9b9afe2e | ||
|
|
7d382279ad | ||
|
|
b4f5f18283 | ||
|
|
17e150393a | ||
|
|
b5ecfb9c5f | ||
|
|
31a0c9b10c | ||
|
|
e4d95e09cf | ||
|
|
d173be0db5 | ||
|
|
051989a396 | ||
|
|
795c77e943 | ||
|
|
1de6bbc9dc | ||
|
|
474c74b1f9 | ||
|
|
caaa57c915 | ||
|
|
588f736348 | ||
|
|
828302150a | ||
|
|
144723af18 | ||
|
|
087913ab3a | ||
|
|
64942cbb5e | ||
|
|
97430a8e42 | ||
|
|
1bdd200794 | ||
|
|
679035c3bf | ||
|
|
bd4352f041 | ||
|
|
05ffeb8e7f | ||
|
|
6c982a83f0 | ||
|
|
9860fbaec6 | ||
|
|
26c29d9c85 | ||
|
|
242b25eb1e | ||
|
|
c13b8d4fc6 | ||
|
|
12e9c08a1a | ||
|
|
98a0528806 | ||
|
|
015a6067fd | ||
|
|
e34105e754 | ||
|
|
a995866d5b | ||
|
|
a88347dfe6 | ||
|
|
4f404a41c6 | ||
|
|
88444dcf74 | ||
|
|
4f5ab9eb8c | ||
|
|
f51427b63c | ||
|
|
cdcb6a6007 | ||
|
|
ac7e17d0a6 | ||
|
|
402390866a | ||
|
|
cc362a1b7f | ||
|
|
1ca7973b77 | ||
|
|
9ecbea68ca | ||
|
|
e5bc602af3 | ||
|
|
a9aa406d29 | ||
|
|
c1ae6f14fc | ||
|
|
411b7a2446 | ||
|
|
869b457810 | ||
|
|
4330bae47f | ||
|
|
1c36c41050 | ||
|
|
bea4356aca | ||
|
|
32f51c612a | ||
|
|
355d00d951 | ||
|
|
bf56f3919f | ||
|
|
d876580ddf | ||
|
|
90f36198d2 | ||
|
|
e542f3c9d3 | ||
|
|
87c56d0248 | ||
|
|
8c928cb237 | ||
|
|
6030992af4 | ||
|
|
688da1a1bb | ||
|
|
ceecd51982 | ||
|
|
c77a700442 | ||
|
|
10ded26d60 | ||
|
|
74adaba8ac | ||
|
|
19c57b0e5e | ||
|
|
f561057311 | ||
|
|
0e6a7a39a0 | ||
|
|
13b905e762 | ||
|
|
b4c0cc5a27 | ||
|
|
a042c8bb3c | ||
|
|
286a642739 | ||
|
|
513a83c4b0 | ||
|
|
9b2c8826b1 | ||
|
|
413a3c27a4 | ||
|
|
c9328d98d7 | ||
|
|
f6c0751ce3 | ||
|
|
16c7ebef73 | ||
|
|
ec38ac7292 | ||
|
|
b8497a91a6 | ||
|
|
5115bcaf98 | ||
|
|
7077037bb7 | ||
|
|
11ba322b5f | ||
|
|
a39a37ec51 | ||
|
|
ec8fa0d1fe | ||
|
|
5efc4ffee3 | ||
|
|
c2d028df4f | ||
|
|
9b838df17d | ||
|
|
a20ff4645d | ||
|
|
850e3431da | ||
|
|
072a60516e | ||
|
|
9b3feb995a | ||
|
|
d359f7455f | ||
|
|
4987cd188a | ||
|
|
019e45572d | ||
|
|
d87e877a27 | ||
|
|
05c7da17b9 | ||
|
|
8c21f75e6d | ||
|
|
615a4e6e37 | ||
|
|
11ca1bf51e | ||
|
|
7fabfad65d | ||
|
|
ce4779f49d | ||
|
|
a88b919e60 | ||
|
|
cc4d035b63 | ||
|
|
12b78eb1d7 | ||
|
|
8a5267ab76 | ||
|
|
a189947617 | ||
|
|
f01b3999ff |
No files matched your search
@@ -0,0 +1,38 @@
|
||||
Contributing to ProtocolLib
|
||||
===========================
|
||||
This page will detail specific things that must be done if you intend to contribute to this project.
|
||||
|
||||
## Updating ProtocolLib to a New Protocol Version
|
||||
#### Before we get started:
|
||||
1. **When do we need to update the protocol version?**
|
||||
_A Minecraft protocol version is a number for each specification of the Minecraft protocol.
|
||||
This means it is incremented when there is a change to the [Protocol Specification](http://wiki.vg/Protocol),
|
||||
but not necessarily for each Minecraft version update. If the latest Minecraft version contains a protocol change,
|
||||
that means ProtocolLib needs to be updated._
|
||||
2. **When do we need to update other parts of ProtocolLib?**
|
||||
_When the package version guard changes. The package version guard is the version string inserted
|
||||
into the package identifier for CraftBukkit and net.minecraft.server (e.g. v1_9_R2). It is incremented
|
||||
by Spigot if there is a major breaking change in the internal server code. This is to encourage plugins
|
||||
that interact directly with CraftBukkit/nms code to update more specifically. However, since most of
|
||||
ProtocolLib uses reflection, and the structure of packet classes is generally static, one will have
|
||||
to go through the code and change imports from nms/CraftBukkit._
|
||||
|
||||
#### Ready? Let's get started!
|
||||
1. Read the [Protocol Changes](http://wiki.vg/Protocol_History). Always make sure the list is both
|
||||
complete and correct. If you're unsure, don't hesitate to ask in #mcdevs (the people who maintain wiki.vg) on [freenode.net](http://freenode.net)
|
||||
or #spigot on [irc.spi.gt](http://irc.spi.gt) ([webchat](https://irc.spi.gt/iris/?channels=spigot)).
|
||||
2. Search for usages of the now-defunct NMS package guard and change them.
|
||||
3. The class `com.comphenix.protocol.PacketType` contains a list of all the packets. If any packets were added or removed
|
||||
(or had their ID changed), make sure to update this list. If a packet was removed
|
||||
in favor of usage of another packet, instead of removing it, move it to the bottom of the list
|
||||
in its section, add a deprecation warning to it, and redirect it to the packet that replaced it.
|
||||
4. `mvn` in the root directory to build the project.
|
||||
5. If tests fail in the maven build, go through the tests to make sure you removed references to any removed packets
|
||||
and changed the NMS version guards.
|
||||
6. Increment the package version in `com.comphenix.protocol.utility.Constants`.
|
||||
7. `com.comphenix.protocol.ProtocolLibrary` contains several constants that must be updated, including the Minecraft version
|
||||
and the release date.
|
||||
8. `com.comphenix.protocol.utility.MinecraftProtocolVersion` contains a map of all the protocol version integers.
|
||||
If the protocol version has been incremented, add a new line to the map.
|
||||
9. `mvn` in root directory again. If it builds successfully, test on the appropriate version of a Spigot server. If
|
||||
the build fails, debug!
|
||||
@@ -0,0 +1,10 @@
|
||||
_Follow this template except for feature requests. Use pastebin when providing /protocol dump and any relevant errors._
|
||||
|
||||
Make sure you've done the following:
|
||||
- [ ] You're using the latest build for your server version
|
||||
- [ ] This isn't an issue caused by another plugin
|
||||
- [ ] You've checked for duplicate issues
|
||||
|
||||
Debug paste link:
|
||||
|
||||
Description and relevant errors:
|
||||
@@ -7,6 +7,10 @@
|
||||
.classpath
|
||||
.settings/
|
||||
bin/
|
||||
.idea/
|
||||
.iml
|
||||
.ipr
|
||||
.iws
|
||||
|
||||
*.pydevproject
|
||||
.metadata
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@ language: java
|
||||
jdk:
|
||||
- oraclejdk8
|
||||
- oraclejdk7
|
||||
script: mvn clean test -U
|
||||
before_install: cd ProtocolLib
|
||||
script: mvn clean test
|
||||
#before_install: cd ProtocolLib
|
||||
install: true
|
||||
notifications:
|
||||
email:
|
||||
|
||||
@@ -1,167 +0,0 @@
|
||||
#################
|
||||
## Eclipse
|
||||
#################
|
||||
|
||||
*.pydevproject
|
||||
.project
|
||||
.metadata
|
||||
bin/
|
||||
tmp/
|
||||
*.tmp
|
||||
*.bak
|
||||
*.swp
|
||||
*~.nib
|
||||
local.properties
|
||||
.classpath
|
||||
.settings/
|
||||
.loadpath
|
||||
target/
|
||||
.gitignore
|
||||
|
||||
# External tool builders
|
||||
.externalToolBuilders/
|
||||
|
||||
# Locally stored "Eclipse launch configurations"
|
||||
*.launch
|
||||
|
||||
# CDT-specific
|
||||
.cproject
|
||||
|
||||
# PDT-specific
|
||||
.buildpath
|
||||
|
||||
|
||||
#################
|
||||
## Visual Studio
|
||||
#################
|
||||
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.sln.docstates
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Rr]elease/
|
||||
*_i.c
|
||||
*_p.c
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.vspscc
|
||||
.builds
|
||||
*.dotCover
|
||||
|
||||
## TODO: If you have NuGet Package Restore enabled, uncomment this
|
||||
#packages/
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish
|
||||
|
||||
# Others
|
||||
[Bb]in
|
||||
[Oo]bj
|
||||
sql
|
||||
TestResults
|
||||
*.Cache
|
||||
ClientBin
|
||||
stylecop.*
|
||||
~$*
|
||||
*.dbmdl
|
||||
Generated_Code #added for RIA/Silverlight projects
|
||||
|
||||
# Backup & report files from converting an old project file to a newer
|
||||
# Visual Studio version. Backup files are not needed, because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
|
||||
|
||||
|
||||
############
|
||||
## Windows
|
||||
############
|
||||
|
||||
# Windows image file caches
|
||||
Thumbs.db
|
||||
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
|
||||
|
||||
#############
|
||||
## Python
|
||||
#############
|
||||
|
||||
*.py[co]
|
||||
|
||||
# Packages
|
||||
*.egg
|
||||
*.egg-info
|
||||
dist
|
||||
build
|
||||
eggs
|
||||
parts
|
||||
bin
|
||||
var
|
||||
sdist
|
||||
develop-eggs
|
||||
.installed.cfg
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
.coverage
|
||||
.tox
|
||||
|
||||
#Translations
|
||||
*.mo
|
||||
|
||||
#Mr Developer
|
||||
.mr.developer.cfg
|
||||
|
||||
# Mac crap
|
||||
.DS_Store
|
||||
/target
|
||||
/target
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2012 Kristian S. Stangeland
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program;
|
||||
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
* 02111-1307 USA
|
||||
*/
|
||||
|
||||
package com.comphenix.protocol;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
/**
|
||||
* Ignore this class.
|
||||
*
|
||||
* @author Kristian
|
||||
*/
|
||||
public class Application {
|
||||
private static Thread mainThread;
|
||||
private static boolean primaryMethod = true;
|
||||
|
||||
public static void main(String[] args) {
|
||||
// For now, though we might consider making a proper application
|
||||
System.out.println("This is a Bukkit library. Place it in the plugin-folder and restart the server!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if we are running on the main thread.
|
||||
* @return TRUE if we are, FALSE otherwise.
|
||||
*/
|
||||
public static boolean isPrimaryThread() {
|
||||
if (primaryMethod) {
|
||||
try {
|
||||
return Bukkit.isPrimaryThread();
|
||||
} catch (LinkageError e) {
|
||||
primaryMethod = false;
|
||||
}
|
||||
}
|
||||
// Fallback method
|
||||
return Thread.currentThread().equals(mainThread);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the calling thread as the primary thread.
|
||||
*/
|
||||
static void registerPrimaryThread() {
|
||||
mainThread = Thread.currentThread();
|
||||
}
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 dmulloy2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program;
|
||||
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
* 02111-1307 USA
|
||||
*/
|
||||
package com.comphenix.protocol.compat.guava;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.google.common.collect.Range;
|
||||
|
||||
/**
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
public class Guava {
|
||||
private static GuavaCompat compat;
|
||||
|
||||
static {
|
||||
try {
|
||||
Range.closed(1, 2);
|
||||
compat = new Guava17();
|
||||
} catch (Throwable ex) {
|
||||
try {
|
||||
Class<?> clazz = Class.forName("com.comphenix.protocol.compat.guava.Guava10");
|
||||
compat = (GuavaCompat) clazz.newInstance();
|
||||
} catch (Throwable ex1) {
|
||||
ProtocolLibrary.log(Level.SEVERE, "Failed to create Guava 10 compat:", ex1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static GuavaCompat getCompat() {
|
||||
return compat;
|
||||
}
|
||||
|
||||
public static <C extends Comparable<C>> Range<C> closedRange(C lower, C upper) {
|
||||
return getCompat().closedRange(lower, upper);
|
||||
}
|
||||
|
||||
public static <C extends Comparable<C>> Range<C> singleton(C singleton) {
|
||||
return getCompat().singletonRange(singleton);
|
||||
}
|
||||
|
||||
public static Set<Integer> toSet(Range<Integer> range) {
|
||||
return getCompat().toSet(range);
|
||||
}
|
||||
|
||||
public static DataInputStream addHeader(DataInputStream input, PacketType type) {
|
||||
return getCompat().addHeader(input, type);
|
||||
}
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 dmulloy2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program;
|
||||
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
* 02111-1307 USA
|
||||
*/
|
||||
package com.comphenix.protocol.compat.guava;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Set;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.google.common.collect.ContiguousSet;
|
||||
import com.google.common.collect.DiscreteDomain;
|
||||
import com.google.common.collect.Range;
|
||||
import com.google.common.io.ByteSource;
|
||||
|
||||
/**
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
public class Guava17 implements GuavaCompat {
|
||||
|
||||
@Override
|
||||
public <C extends Comparable<C>> Range<C> closedRange(C lower, C upper) {
|
||||
return Range.closed(lower, upper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <C extends Comparable<C>> Range<C> singletonRange(C singleton) {
|
||||
return Range.singleton(singleton);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Integer> toSet(Range<Integer> range) {
|
||||
return ContiguousSet.create(range, DiscreteDomain.integers());
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataInputStream addHeader(final DataInputStream input, final PacketType type) {
|
||||
ByteSource header = new ByteSource() {
|
||||
@Override
|
||||
public InputStream openStream() throws IOException {
|
||||
byte[] data = new byte[] { (byte) type.getLegacyId() };
|
||||
return new ByteArrayInputStream(data);
|
||||
}
|
||||
};
|
||||
|
||||
ByteSource data = new ByteSource() {
|
||||
@Override
|
||||
public InputStream openStream() throws IOException {
|
||||
return input;
|
||||
}
|
||||
};
|
||||
|
||||
// Combine them into a single stream
|
||||
try {
|
||||
return new DataInputStream(ByteSource.concat(header, data).openStream());
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Cannot add header.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 dmulloy2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program;
|
||||
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
* 02111-1307 USA
|
||||
*/
|
||||
package com.comphenix.protocol.compat.guava;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.util.Set;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.google.common.collect.Range;
|
||||
|
||||
/**
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
public interface GuavaCompat {
|
||||
|
||||
<C extends Comparable<C>> Range<C> closedRange(C lower, C upper);
|
||||
|
||||
<C extends Comparable<C>> Range<C> singletonRange(C singleton);
|
||||
|
||||
Set<Integer> toSet(Range<Integer> range);
|
||||
|
||||
DataInputStream addHeader(DataInputStream input, PacketType type);
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 dmulloy2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program;
|
||||
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
* 02111-1307 USA
|
||||
*/
|
||||
package com.comphenix.protocol.compat.netty;
|
||||
|
||||
import com.comphenix.protocol.injector.netty.Injector;
|
||||
|
||||
/**
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
public interface ChannelInjector extends Injector {
|
||||
|
||||
WrappedChannel getChannel();
|
||||
}
|
||||
-103
@@ -1,103 +0,0 @@
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 dmulloy2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program;
|
||||
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
* 02111-1307 USA
|
||||
*/
|
||||
package com.comphenix.protocol.compat.netty;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.PacketType.Protocol;
|
||||
import com.comphenix.protocol.PacketType.Sender;
|
||||
import com.comphenix.protocol.injector.netty.ProtocolRegistry;
|
||||
import com.comphenix.protocol.injector.packet.MapContainer;
|
||||
import com.comphenix.protocol.reflect.StructureModifier;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
/**
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
public class LegacyProtocolRegistry extends ProtocolRegistry {
|
||||
|
||||
public LegacyProtocolRegistry() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initialize() {
|
||||
final Object[] protocols = enumProtocol.getEnumConstants();
|
||||
List<Map<Integer, Class<?>>> serverMaps = Lists.newArrayList();
|
||||
List<Map<Integer, Class<?>>> clientMaps = Lists.newArrayList();
|
||||
StructureModifier<Object> modifier = null;
|
||||
|
||||
// Result
|
||||
Register result = new Register();
|
||||
|
||||
for (Object protocol : protocols) {
|
||||
if (modifier == null)
|
||||
modifier = new StructureModifier<Object>(protocol.getClass().getSuperclass(), false);
|
||||
StructureModifier<Map<Integer, Class<?>>> maps = modifier.withTarget(protocol).withType(Map.class);
|
||||
|
||||
serverMaps.add(maps.read(0));
|
||||
clientMaps.add(maps.read(1));
|
||||
}
|
||||
// Maps we have to occationally check have changed
|
||||
for (Map<Integer, Class<?>> map : Iterables.concat(serverMaps, clientMaps)) {
|
||||
result.containers.add(new MapContainer(map));
|
||||
}
|
||||
|
||||
// Heuristic - there are more server packets than client packets
|
||||
if (sum(clientMaps) > sum(serverMaps)) {
|
||||
// Swap if this is violated
|
||||
List<Map<Integer, Class<?>>> temp = serverMaps;
|
||||
serverMaps = clientMaps;
|
||||
clientMaps = temp;
|
||||
}
|
||||
|
||||
for (int i = 0; i < protocols.length; i++) {
|
||||
Enum<?> enumProtocol = (Enum<?>) protocols[i];
|
||||
Protocol equivalent = Protocol.fromVanilla(enumProtocol);
|
||||
|
||||
// Associate known types
|
||||
associatePackets(result, serverMaps.get(i), equivalent, Sender.SERVER);
|
||||
associatePackets(result, clientMaps.get(i), equivalent, Sender.CLIENT);
|
||||
}
|
||||
|
||||
// Exchange (thread safe, as we have only one writer)
|
||||
this.register = result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void associatePackets(Register register, Map<Integer, Class<?>> lookup, Protocol protocol, Sender sender) {
|
||||
for (Entry<Integer, Class<?>> entry : lookup.entrySet()) {
|
||||
PacketType type = PacketType.fromID(protocol, sender, entry.getKey(), entry.getValue());
|
||||
|
||||
try {
|
||||
register.typeToClass.put(type, entry.getValue());
|
||||
|
||||
if (sender == Sender.SERVER)
|
||||
register.serverPackets.add(type);
|
||||
if (sender == Sender.CLIENT)
|
||||
register.clientPackets.add(type);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
// Sometimes this happens with fake packets, just ignore it
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 dmulloy2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program;
|
||||
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
* 02111-1307 USA
|
||||
*/
|
||||
package com.comphenix.protocol.compat.netty;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.compat.netty.independent.IndependentNetty;
|
||||
import com.comphenix.protocol.error.ErrorReporter;
|
||||
import com.comphenix.protocol.injector.PacketFilterManager;
|
||||
import com.comphenix.protocol.wrappers.WrappedServerPing.CompressedImage;
|
||||
|
||||
/**
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
public class Netty {
|
||||
private static NettyCompat compat;
|
||||
|
||||
static {
|
||||
try {
|
||||
Class.forName("io.netty.buffer.ByteBuf");
|
||||
compat = new IndependentNetty();
|
||||
} catch (ClassNotFoundException ex) {
|
||||
try {
|
||||
Class<?> clazz = Class.forName("com.comphenix.protocol.compat.netty.shaded.ShadedNetty");
|
||||
compat = (NettyCompat) clazz.newInstance();
|
||||
} catch (Exception ex1) {
|
||||
ProtocolLibrary.log(Level.SEVERE, "Failed to create legacy netty compat:", ex1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static NettyCompat getCompat() {
|
||||
return compat;
|
||||
}
|
||||
|
||||
public static boolean isIndependent() {
|
||||
return compat instanceof IndependentNetty;
|
||||
}
|
||||
|
||||
public static WrappedByteBuf createPacketBuffer() {
|
||||
return getCompat().createPacketBuffer();
|
||||
}
|
||||
|
||||
public static Class<?> getGenericFutureListenerArray() {
|
||||
return getCompat().getGenericFutureListenerArray();
|
||||
}
|
||||
|
||||
public static Class<?> getChannelHandlerContext() {
|
||||
return getCompat().getChannelHandlerContext();
|
||||
}
|
||||
|
||||
public static String toEncodedText(CompressedImage image) {
|
||||
return getCompat().toEncodedText(image);
|
||||
}
|
||||
|
||||
public static WrappedByteBuf decode(byte[] encoded) {
|
||||
return getCompat().decode(encoded);
|
||||
}
|
||||
|
||||
public static ProtocolInjector getProtocolInjector(Plugin library, PacketFilterManager packetFilterManager, ErrorReporter reporter) {
|
||||
return getCompat().getProtocolInjector(library, packetFilterManager, reporter);
|
||||
}
|
||||
|
||||
public static WrappedByteBuf packetReader(DataInputStream input) {
|
||||
return getCompat().packetReader(input);
|
||||
}
|
||||
|
||||
public static WrappedByteBuf packetWriter(DataOutputStream output) {
|
||||
return getCompat().packetWriter(output);
|
||||
}
|
||||
|
||||
public static WrappedByteBuf copiedBuffer(byte[] array) {
|
||||
return getCompat().copiedBuffer(array);
|
||||
}
|
||||
|
||||
public static WrappedByteBuf buffer() {
|
||||
return getCompat().buffer();
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 dmulloy2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program;
|
||||
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
* 02111-1307 USA
|
||||
*/
|
||||
package com.comphenix.protocol.compat.netty;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import com.comphenix.protocol.error.ErrorReporter;
|
||||
import com.comphenix.protocol.injector.ListenerInvoker;
|
||||
import com.comphenix.protocol.wrappers.WrappedServerPing.CompressedImage;
|
||||
|
||||
|
||||
/**
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
// TODO: Sort out packet readers/writers
|
||||
public interface NettyCompat {
|
||||
|
||||
WrappedByteBuf createPacketBuffer();
|
||||
|
||||
WrappedByteBuf copiedBuffer(byte[] array);
|
||||
|
||||
WrappedByteBuf buffer();
|
||||
|
||||
Class<?> getGenericFutureListenerArray();
|
||||
|
||||
Class<?> getChannelHandlerContext();
|
||||
|
||||
String toEncodedText(CompressedImage image);
|
||||
|
||||
WrappedByteBuf decode(byte[] encoded);
|
||||
|
||||
ProtocolInjector getProtocolInjector(Plugin plugin, ListenerInvoker invoker, ErrorReporter reporter);
|
||||
|
||||
WrappedByteBuf packetReader(DataInputStream input);
|
||||
|
||||
WrappedByteBuf packetWriter(DataOutputStream output);
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 dmulloy2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program;
|
||||
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
* 02111-1307 USA
|
||||
*/
|
||||
package com.comphenix.protocol.compat.netty;
|
||||
|
||||
import com.comphenix.protocol.injector.netty.ChannelListener;
|
||||
import com.comphenix.protocol.injector.packet.PacketInjector;
|
||||
import com.comphenix.protocol.injector.player.PlayerInjectionHandler;
|
||||
|
||||
/**
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
public interface ProtocolInjector extends ChannelListener {
|
||||
|
||||
PlayerInjectionHandler getPlayerInjector();
|
||||
|
||||
PacketInjector getPacketInjector();
|
||||
|
||||
void setDebug(boolean debug);
|
||||
|
||||
void inject();
|
||||
|
||||
void close();
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 dmulloy2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program;
|
||||
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
* 02111-1307 USA
|
||||
*/
|
||||
package com.comphenix.protocol.compat.netty;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
|
||||
/**
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
public interface WrappedByteBuf {
|
||||
|
||||
void writeBytes(ObjectInputStream input, int id) throws IOException;
|
||||
|
||||
Object getHandle();
|
||||
|
||||
int readableBytes();
|
||||
|
||||
void readBytes(ObjectOutputStream output, int readableBytes) throws IOException;
|
||||
|
||||
void readBytes(byte[] data);
|
||||
|
||||
void writeByte(byte b);
|
||||
|
||||
void writeByte(int i);
|
||||
|
||||
void writeBytes(byte[] bytes);
|
||||
|
||||
byte[] array();
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 dmulloy2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program;
|
||||
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
* 02111-1307 USA
|
||||
*/
|
||||
package com.comphenix.protocol.compat.netty;
|
||||
|
||||
/**
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
public interface WrappedChannel {
|
||||
|
||||
void writeAndFlush(Object packet);
|
||||
}
|
||||
-105
@@ -1,105 +0,0 @@
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 dmulloy2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program;
|
||||
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
* 02111-1307 USA
|
||||
*/
|
||||
package com.comphenix.protocol.compat.netty.independent;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.buffer.UnpooledByteBufAllocator;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.base64.Base64;
|
||||
import io.netty.util.concurrent.GenericFutureListener;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import com.comphenix.protocol.compat.netty.NettyCompat;
|
||||
import com.comphenix.protocol.compat.netty.ProtocolInjector;
|
||||
import com.comphenix.protocol.compat.netty.WrappedByteBuf;
|
||||
import com.comphenix.protocol.error.ErrorReporter;
|
||||
import com.comphenix.protocol.injector.ListenerInvoker;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
import com.comphenix.protocol.wrappers.WrappedServerPing.CompressedImage;
|
||||
import com.google.common.base.Charsets;
|
||||
|
||||
/**
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
public class IndependentNetty implements NettyCompat {
|
||||
|
||||
@Override
|
||||
public WrappedByteBuf createPacketBuffer() {
|
||||
ByteBuf buffer = UnpooledByteBufAllocator.DEFAULT.buffer();
|
||||
Class<?> packetSerializer = MinecraftReflection.getPacketDataSerializerClass();
|
||||
|
||||
try {
|
||||
return new NettyByteBuf((ByteBuf) packetSerializer.getConstructor(ByteBuf.class).newInstance(buffer));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Cannot construct packet serializer.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getGenericFutureListenerArray() {
|
||||
return GenericFutureListener[].class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getChannelHandlerContext() {
|
||||
return ChannelHandlerContext.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toEncodedText(CompressedImage image) {
|
||||
final ByteBuf buffer = Unpooled.wrappedBuffer(image.getDataCopy());
|
||||
String computed = "data:" + image.getMime() + ";base64," +
|
||||
Base64.encode(buffer).toString(Charsets.UTF_8);
|
||||
return computed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WrappedByteBuf decode(byte[] encoded) {
|
||||
return new NettyByteBuf(Base64.decode(Unpooled.wrappedBuffer(encoded)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProtocolInjector getProtocolInjector(Plugin plugin, ListenerInvoker invoker, ErrorReporter reporter) {
|
||||
return new NettyProtocolInjector(plugin, invoker, reporter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WrappedByteBuf packetReader(DataInputStream input) {
|
||||
return new NettyByteBuf(NettyByteBufAdapter.packetReader(input));
|
||||
}
|
||||
|
||||
@Override
|
||||
public WrappedByteBuf packetWriter(DataOutputStream output) {
|
||||
return new NettyByteBuf(NettyByteBufAdapter.packetWriter(output));
|
||||
}
|
||||
|
||||
@Override
|
||||
public WrappedByteBuf copiedBuffer(byte[] array) {
|
||||
return new NettyByteBuf(Unpooled.copiedBuffer(array));
|
||||
}
|
||||
|
||||
@Override
|
||||
public WrappedByteBuf buffer() {
|
||||
return new NettyByteBuf(Unpooled.buffer());
|
||||
}
|
||||
}
|
||||
-83
@@ -1,83 +0,0 @@
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 dmulloy2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program;
|
||||
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
* 02111-1307 USA
|
||||
*/
|
||||
package com.comphenix.protocol.compat.netty.independent;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
import com.comphenix.protocol.compat.netty.WrappedByteBuf;
|
||||
|
||||
/**
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
public class NettyByteBuf implements WrappedByteBuf {
|
||||
private WeakReference<ByteBuf> handle;
|
||||
|
||||
public NettyByteBuf(ByteBuf handle) {
|
||||
this.handle = new WeakReference<ByteBuf>(handle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBytes(ObjectInputStream input, int id) throws IOException {
|
||||
handle.get().writeBytes(input, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getHandle() {
|
||||
return handle.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readableBytes() {
|
||||
return handle.get().readableBytes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readBytes(ObjectOutputStream output, int readableBytes) throws IOException {
|
||||
handle.get().readBytes(output, readableBytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readBytes(byte[] data) {
|
||||
handle.get().readBytes(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeByte(byte b) {
|
||||
handle.get().writeByte(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeByte(int i) {
|
||||
handle.get().writeByte(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBytes(byte[] bytes) {
|
||||
handle.get().writeBytes(bytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] array() {
|
||||
return handle.get().array();
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 dmulloy2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program;
|
||||
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
* 02111-1307 USA
|
||||
*/
|
||||
package com.comphenix.protocol.injector.netty;
|
||||
|
||||
import com.comphenix.protocol.compat.netty.WrappedByteBuf;
|
||||
|
||||
/**
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
public class WirePacket {
|
||||
private final int id;
|
||||
private final byte[] bytes;
|
||||
|
||||
public WirePacket(int id, byte[] bytes) {
|
||||
this.id = id;
|
||||
this.bytes = bytes;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public byte[] getBytes() {
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public void writeId(WrappedByteBuf output) {
|
||||
int i = id;
|
||||
while ((i & -128) != 0) {
|
||||
output.writeByte(i & 127 | 128);
|
||||
i >>>= 7;
|
||||
}
|
||||
|
||||
output.writeByte(i);
|
||||
}
|
||||
|
||||
public void writeBytes(WrappedByteBuf output) {
|
||||
output.writeBytes(bytes);
|
||||
}
|
||||
}
|
||||
@@ -1,924 +0,0 @@
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2012 Kristian S. Stangeland
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program;
|
||||
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
* 02111-1307 USA
|
||||
*/
|
||||
package com.comphenix.protocol.wrappers;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import com.comphenix.protocol.injector.BukkitUnwrapper;
|
||||
import com.comphenix.protocol.reflect.FieldAccessException;
|
||||
import com.comphenix.protocol.reflect.FieldUtils;
|
||||
import com.comphenix.protocol.reflect.FuzzyReflection;
|
||||
import com.comphenix.protocol.reflect.accessors.Accessors;
|
||||
import com.comphenix.protocol.reflect.accessors.ConstructorAccessor;
|
||||
import com.comphenix.protocol.reflect.accessors.FieldAccessor;
|
||||
import com.comphenix.protocol.reflect.accessors.ReadOnlyFieldAccessor;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
import com.comphenix.protocol.wrappers.collection.ConvertedMap;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.Iterators;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
/**
|
||||
* Wraps a DataWatcher that is used to transmit arbitrary key-value pairs with a given entity.
|
||||
*
|
||||
* @author Kristian
|
||||
*/
|
||||
public class WrappedDataWatcher extends AbstractWrapper implements Iterable<WrappedWatchableObject> {
|
||||
/**
|
||||
* Every custom watchable type in the Spigot protocol hack.
|
||||
* @author Kristian
|
||||
*/
|
||||
public enum CustomType {
|
||||
BYTE_SHORT("org.spigotmc.ProtocolData$ByteShort", 0, short.class),
|
||||
DUAL_BYTE("org.spigotmc.ProtocolData$DualByte", 0, byte.class, byte.class),
|
||||
HIDDEN_BYTE("org.spigotmc.ProtocolData$HiddenByte", 0, byte.class),
|
||||
INT_BYTE("org.spigotmc.ProtocolData$IntByte", 2, int.class, byte.class),
|
||||
DUAL_INT("org.spigotmc.ProtocolData$DualInt", 2, int.class, int.class);
|
||||
|
||||
private Class<?> spigotClass;
|
||||
private ConstructorAccessor constructor;
|
||||
private FieldAccessor secondaryValue;
|
||||
private int typeId;
|
||||
|
||||
private CustomType(String className, int typeId, Class<?>... parameters) {
|
||||
try {
|
||||
this.spigotClass = Class.forName(className);
|
||||
this.constructor = Accessors.getConstructorAccessor(spigotClass, parameters);
|
||||
this.secondaryValue = parameters.length > 1 ? Accessors.getFieldAccessor(spigotClass, "value2", true) : null;
|
||||
} catch (ClassNotFoundException e) {
|
||||
// ProtocolLibrary.log(Level.WARNING, "Unable to find " + className);
|
||||
this.spigotClass = null;
|
||||
}
|
||||
|
||||
this.typeId = typeId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new instance of this Spigot type.
|
||||
* @param value - the value. Cannot be NULL.
|
||||
* @return The instance to construct.
|
||||
*/
|
||||
Object newInstance(Object value) {
|
||||
return newInstance(value, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new instance of this Spigot type.
|
||||
* <p>
|
||||
* The secondary value may be NULL if this custom type does not contain a secondary value.
|
||||
* @param value - the value.
|
||||
* @param secondary - optional secondary value.
|
||||
* @return
|
||||
*/
|
||||
Object newInstance(Object value, Object secondary) {
|
||||
Preconditions.checkNotNull(value, "value cannot be NULL.");
|
||||
|
||||
if (hasSecondary()) {
|
||||
return constructor.invoke(value, secondary);
|
||||
} else {
|
||||
if (secondary != null) {
|
||||
throw new IllegalArgumentException("Cannot construct " + this + " with a secondary value");
|
||||
}
|
||||
return constructor.invoke(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the secondary value of a given type.
|
||||
* @param instance - the instance.
|
||||
* @param secondary - the secondary value.
|
||||
*/
|
||||
void setSecondary(Object instance, Object secondary) {
|
||||
if (!hasSecondary()) {
|
||||
throw new IllegalArgumentException(this + " does not have a secondary value.");
|
||||
}
|
||||
secondaryValue.set(instance, secondary);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the secondary value of a type.
|
||||
* @param instance - the instance.
|
||||
* @return The secondary value.
|
||||
*/
|
||||
Object getSecondary(Object instance) {
|
||||
if (!hasSecondary()) {
|
||||
throw new IllegalArgumentException(this + " does not have a secondary value.");
|
||||
}
|
||||
return secondaryValue.get(instance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if this type has a secondary value.
|
||||
* @return TRUE if it does, FALSE otherwise.
|
||||
*/
|
||||
public boolean hasSecondary() {
|
||||
return secondaryValue != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Underlying Spigot class.
|
||||
* @return The class.
|
||||
*/
|
||||
public Class<?> getSpigotClass() {
|
||||
return spigotClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* The equivalent type ID.
|
||||
* @return The equivalent ID.
|
||||
*/
|
||||
public int getTypeId() {
|
||||
return typeId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the custom Spigot type of a value.
|
||||
* @param value - the value.
|
||||
* @return The Spigot type, or NULL if not found.
|
||||
*/
|
||||
public static CustomType fromValue(Object value) {
|
||||
for (CustomType type : CustomType.values()) {
|
||||
if (type.getSpigotClass().isInstance(value)) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to assign integer IDs to given types.
|
||||
*/
|
||||
private static Map<Class<?>, Integer> TYPE_MAP;
|
||||
|
||||
/**
|
||||
* Custom types in the bountiful update.
|
||||
*/
|
||||
private static Map<Class<?>, Integer> CUSTOM_MAP;
|
||||
|
||||
// Accessors
|
||||
private static FieldAccessor TYPE_MAP_ACCESSOR;
|
||||
private static FieldAccessor VALUE_MAP_ACCESSOR;
|
||||
|
||||
// Fields
|
||||
private static Field READ_WRITE_LOCK_FIELD;
|
||||
private static Field ENTITY_FIELD;
|
||||
|
||||
// Methods
|
||||
private static Method CREATE_KEY_VALUE_METHOD;
|
||||
private static Method UPDATE_KEY_VALUE_METHOD;
|
||||
private static Method GET_KEY_VALUE_METHOD;
|
||||
|
||||
// Constructors
|
||||
private static Constructor<?> CREATE_DATA_WATCHER_CONSTRUCTOR;
|
||||
|
||||
// Entity methods
|
||||
private volatile static Field ENTITY_DATA_FIELD;
|
||||
|
||||
/**
|
||||
* Whether or not this class has already been initialized.
|
||||
*/
|
||||
private static boolean HAS_INITIALIZED;
|
||||
|
||||
// Lock
|
||||
private ReadWriteLock readWriteLock;
|
||||
|
||||
// Map of watchable objects
|
||||
private Map<Integer, Object> watchableObjects;
|
||||
|
||||
// A map view of all the watchable objects
|
||||
private Map<Integer, WrappedWatchableObject> mapView;
|
||||
|
||||
/**
|
||||
* Initialize a new data watcher.
|
||||
* @throws FieldAccessException If we're unable to wrap a DataWatcher.
|
||||
*/
|
||||
public WrappedDataWatcher() {
|
||||
super(MinecraftReflection.getDataWatcherClass());
|
||||
|
||||
// Just create a new watcher
|
||||
try {
|
||||
if (MinecraftReflection.isUsingNetty()) {
|
||||
setHandle(newEntityHandle(null));
|
||||
} else {
|
||||
setHandle(getHandleType().newInstance());
|
||||
}
|
||||
initialize();
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Unable to construct DataWatcher.", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a wrapper for a given data watcher.
|
||||
* @param handle - the data watcher to wrap.
|
||||
* @throws FieldAccessException If we're unable to wrap a DataWatcher.
|
||||
*/
|
||||
public WrappedDataWatcher(Object handle) {
|
||||
super(MinecraftReflection.getDataWatcherClass());
|
||||
setHandle(handle);
|
||||
initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new data watcher with the given entity.
|
||||
* <p>
|
||||
* In 1.6.4 and ealier, this will fall back to using {@link #WrappedDataWatcher()}.
|
||||
* @param entity - the entity.
|
||||
* @return The wrapped data watcher.
|
||||
*/
|
||||
public static WrappedDataWatcher newWithEntity(Entity entity) {
|
||||
// Use the old constructor
|
||||
if (!MinecraftReflection.isUsingNetty())
|
||||
return new WrappedDataWatcher();
|
||||
return new WrappedDataWatcher(newEntityHandle(entity));
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new native DataWatcher with the given entity.
|
||||
* <p>
|
||||
* Warning: This is only supported in 1.7.2 and above.
|
||||
* @param entity - the entity, or NULL.
|
||||
* @return The data watcher.
|
||||
*/
|
||||
private static Object newEntityHandle(Entity entity) {
|
||||
Class<?> dataWatcher = MinecraftReflection.getDataWatcherClass();
|
||||
|
||||
try {
|
||||
if (CREATE_DATA_WATCHER_CONSTRUCTOR == null)
|
||||
CREATE_DATA_WATCHER_CONSTRUCTOR = dataWatcher.getConstructor(MinecraftReflection.getEntityClass());
|
||||
|
||||
return CREATE_DATA_WATCHER_CONSTRUCTOR.newInstance(
|
||||
BukkitUnwrapper.getInstance().unwrapItem(entity)
|
||||
);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Cannot construct data watcher.", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new data watcher for a list of watchable objects.
|
||||
* <p>
|
||||
* Note that the watchable objects are not cloned, and will be modified in place. Use "deepClone" if
|
||||
* that is not desirable.
|
||||
* <p>
|
||||
* The {@link #removeObject(int)} method will not modify the given list, however.
|
||||
*
|
||||
* @param watchableObjects - list of watchable objects that will be copied.
|
||||
* @throws FieldAccessException Unable to read watchable objects.
|
||||
*/
|
||||
public WrappedDataWatcher(List<WrappedWatchableObject> watchableObjects) throws FieldAccessException {
|
||||
this();
|
||||
|
||||
Lock writeLock = getReadWriteLock().writeLock();
|
||||
Map<Integer, Object> map = getWatchableObjectMap();
|
||||
|
||||
writeLock.lock();
|
||||
|
||||
try {
|
||||
// Add the watchable objects by reference
|
||||
for (WrappedWatchableObject watched : watchableObjects) {
|
||||
map.put(watched.getIndex(), watched.handle);
|
||||
}
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the ID of a given type, if it's allowed to be watched.
|
||||
* @param clazz - Class to check for.
|
||||
* @return The ID, or NULL if it cannot be watched.
|
||||
* @throws FieldAccessException If we cannot initialize the reflection machinery.
|
||||
*/
|
||||
public static Integer getTypeID(Class<?> clazz) throws FieldAccessException {
|
||||
initialize();
|
||||
Integer result = TYPE_MAP.get(WrappedWatchableObject.getUnwrappedType(clazz));
|
||||
|
||||
if (result == null) {
|
||||
result = CUSTOM_MAP.get(clazz);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the type of a given ID, if it's allowed to be watched.
|
||||
* @param id - id to get type for
|
||||
* @return The type using a given ID, or NULL if it cannot be watched.
|
||||
* @throws FieldAccessException If we cannot initialize the reflection machinery.
|
||||
*/
|
||||
public static Class<?> getTypeClass(int id) throws FieldAccessException {
|
||||
initialize();
|
||||
|
||||
for (Map.Entry<Class<?>, Integer> entry : TYPE_MAP.entrySet()) {
|
||||
if (Objects.equal(entry.getValue(), id)) {
|
||||
return entry.getKey();
|
||||
}
|
||||
}
|
||||
|
||||
// Unknown class type
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a watched byte.
|
||||
* @param index - index of the watched byte.
|
||||
* @return The watched byte, or NULL if this value doesn't exist.
|
||||
* @throws FieldAccessException Cannot read underlying field.
|
||||
*/
|
||||
public Byte getByte(int index) throws FieldAccessException {
|
||||
return (Byte) getObject(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a watched short.
|
||||
* @param index - index of the watched short.
|
||||
* @return The watched short, or NULL if this value doesn't exist.
|
||||
* @throws FieldAccessException Cannot read underlying field.
|
||||
*/
|
||||
public Short getShort(int index) throws FieldAccessException {
|
||||
return (Short) getObject(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a watched integer.
|
||||
* @param index - index of the watched integer.
|
||||
* @return The watched integer, or NULL if this value doesn't exist.
|
||||
* @throws FieldAccessException Cannot read underlying field.
|
||||
*/
|
||||
public Integer getInteger(int index) throws FieldAccessException {
|
||||
return (Integer) getObject(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a watched float.
|
||||
* @param index - index of the watched float.
|
||||
* @return The watched float, or NULL if this value doesn't exist.
|
||||
* @throws FieldAccessException Cannot read underlying field.
|
||||
*/
|
||||
public Float getFloat(int index) throws FieldAccessException {
|
||||
return (Float) getObject(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a watched string.
|
||||
* @param index - index of the watched string.
|
||||
* @return The watched string, or NULL if this value doesn't exist.
|
||||
* @throws FieldAccessException Cannot read underlying field.
|
||||
*/
|
||||
public String getString(int index) throws FieldAccessException {
|
||||
return (String) getObject(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a watched string.
|
||||
* @param index - index of the watched string.
|
||||
* @return The watched string, or NULL if this value doesn't exist.
|
||||
* @throws FieldAccessException Cannot read underlying field.
|
||||
*/
|
||||
public ItemStack getItemStack(int index) throws FieldAccessException {
|
||||
return (ItemStack) getObject(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a watched string.
|
||||
* @param index - index of the watched string.
|
||||
* @return The watched string, or NULL if this value doesn't exist.
|
||||
* @throws FieldAccessException Cannot read underlying field.
|
||||
*/
|
||||
public WrappedChunkCoordinate getChunkCoordinate(int index) throws FieldAccessException {
|
||||
return (WrappedChunkCoordinate) getObject(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a watchable object by index.
|
||||
* @param index - index of the object to retrieve.
|
||||
* @return The watched object.
|
||||
* @throws FieldAccessException Cannot read underlying field.
|
||||
*/
|
||||
public Object getObject(int index) throws FieldAccessException {
|
||||
Object watchable = getWatchedObject(index);
|
||||
|
||||
if (watchable != null) {
|
||||
return new WrappedWatchableObject(watchable).getValue();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve every watchable object in this watcher.
|
||||
* @return Every watchable object.
|
||||
* @throws FieldAccessException If reflection failed.
|
||||
*/
|
||||
public List<WrappedWatchableObject> getWatchableObjects() throws FieldAccessException {
|
||||
Lock readLock = getReadWriteLock().readLock();
|
||||
readLock.lock();
|
||||
|
||||
try {
|
||||
List<WrappedWatchableObject> result = new ArrayList<WrappedWatchableObject>();
|
||||
|
||||
// Add each watchable object to the list
|
||||
for (Object watchable : getWatchableObjectMap().values()) {
|
||||
if (watchable != null) {
|
||||
result.add(new WrappedWatchableObject(watchable));
|
||||
} else {
|
||||
result.add(null);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
// Quick checks
|
||||
if (obj == this)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
|
||||
if (obj instanceof WrappedDataWatcher) {
|
||||
WrappedDataWatcher other = (WrappedDataWatcher) obj;
|
||||
Iterator<WrappedWatchableObject> first = iterator(), second = other.iterator();
|
||||
|
||||
// Make sure they're the same size
|
||||
if (size() != other.size())
|
||||
return false;
|
||||
|
||||
for (; first.hasNext() && second.hasNext(); ) {
|
||||
// See if the two elements are equal
|
||||
if (!first.next().equals(second.next()))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return getWatchableObjects().hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a copy of every index associated with a watched object.
|
||||
* @return Every watched object index.
|
||||
* @throws FieldAccessException If we're unable to read the underlying object.
|
||||
*/
|
||||
public Set<Integer> indexSet() throws FieldAccessException {
|
||||
Lock readLock = getReadWriteLock().readLock();
|
||||
readLock.lock();
|
||||
|
||||
try {
|
||||
return new HashSet<Integer>(getWatchableObjectMap().keySet());
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone the content of the current DataWatcher.
|
||||
* @return A cloned data watcher.
|
||||
*/
|
||||
public WrappedDataWatcher deepClone() {
|
||||
WrappedDataWatcher clone = new WrappedDataWatcher();
|
||||
|
||||
// Make a new copy instead
|
||||
for (WrappedWatchableObject watchable : this) {
|
||||
clone.setObject(watchable.getIndex(), watchable.getClonedValue());
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the number of watched objects.
|
||||
* @return Watched object count.
|
||||
* @throws FieldAccessException If we're unable to read the underlying object.
|
||||
*/
|
||||
public int size() throws FieldAccessException {
|
||||
Lock readLock = getReadWriteLock().readLock();
|
||||
readLock.lock();
|
||||
|
||||
try {
|
||||
return getWatchableObjectMap().size();
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a given object from the underlying DataWatcher.
|
||||
* @param index - index of the object to remove.
|
||||
* @return The watchable object that was removed, or NULL If none could be found.
|
||||
*/
|
||||
public WrappedWatchableObject removeObject(int index) {
|
||||
Lock writeLock = getReadWriteLock().writeLock();
|
||||
writeLock.lock();
|
||||
|
||||
try {
|
||||
Object removed = getWatchableObjectMap().remove(index);
|
||||
return removed != null ? new WrappedWatchableObject(removed) : null;
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a watched byte.
|
||||
* @param index - index of the watched byte.
|
||||
* @param newValue - the new watched value.
|
||||
* @throws FieldAccessException Cannot read underlying field.
|
||||
*/
|
||||
public void setObject(int index, Object newValue) throws FieldAccessException {
|
||||
setObject(index, newValue, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a watched byte.
|
||||
* @param index - index of the watched byte.
|
||||
* @param newValue - the new watched value.
|
||||
* @param update - whether or not to refresh every listening client.
|
||||
* @throws FieldAccessException Cannot read underlying field.
|
||||
*/
|
||||
public void setObject(int index, Object newValue, boolean update) throws FieldAccessException {
|
||||
// Aquire write lock
|
||||
Lock writeLock = getReadWriteLock().writeLock();
|
||||
writeLock.lock();
|
||||
|
||||
try {
|
||||
Object watchable = getWatchedObject(index);
|
||||
|
||||
if (watchable != null) {
|
||||
new WrappedWatchableObject(watchable).setValue(newValue, update);
|
||||
} else {
|
||||
CREATE_KEY_VALUE_METHOD.invoke(handle, index, WrappedWatchableObject.getUnwrapped(newValue));
|
||||
}
|
||||
|
||||
// Handle invoking the method
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new FieldAccessException("Cannot convert arguments.", e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new FieldAccessException("Illegal access.", e);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new FieldAccessException("Checked exception in Minecraft.", e);
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a watched byte with an optional secondary value.
|
||||
* @param index - index of the watched byte.
|
||||
* @param newValue - the new watched value.
|
||||
* @param secondary - optional secondary value.
|
||||
* @param update - whether or not to refresh every listening client.
|
||||
* @param type - custom type.
|
||||
* @throws FieldAccessException If we cannot read the underlying field.
|
||||
*/
|
||||
public void setObject(int index, Object newValue, Object secondary, boolean update, CustomType type) throws FieldAccessException {
|
||||
Object created = type.newInstance(newValue, secondary);
|
||||
|
||||
// Now update the watcher
|
||||
setObject(index, created, update);
|
||||
}
|
||||
|
||||
private Object getWatchedObject(int index) throws FieldAccessException {
|
||||
// We use the get-method first and foremost
|
||||
if (GET_KEY_VALUE_METHOD != null) {
|
||||
try {
|
||||
return GET_KEY_VALUE_METHOD.invoke(handle, index);
|
||||
} catch (Exception e) {
|
||||
throw new FieldAccessException("Cannot invoke get key method for index " + index, e);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
getReadWriteLock().readLock().lock();
|
||||
return getWatchableObjectMap().get(index);
|
||||
|
||||
} finally {
|
||||
getReadWriteLock().readLock().unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the current read write lock.
|
||||
* @return Current read write lock.
|
||||
* @throws FieldAccessException If we're unable to read the underlying field.
|
||||
*/
|
||||
protected ReadWriteLock getReadWriteLock() throws FieldAccessException {
|
||||
try {
|
||||
// Cache the read write lock
|
||||
if (readWriteLock != null)
|
||||
return readWriteLock;
|
||||
else if (READ_WRITE_LOCK_FIELD != null)
|
||||
return readWriteLock = (ReadWriteLock) FieldUtils.readField(READ_WRITE_LOCK_FIELD, handle, true);
|
||||
else
|
||||
return readWriteLock = new ReentrantReadWriteLock();
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new FieldAccessException("Unable to read lock field.", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the underlying map of key values that stores watchable objects.
|
||||
* @return A map of watchable objects.
|
||||
* @throws FieldAccessException If we don't have permission to perform reflection.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Map<Integer, Object> getWatchableObjectMap() throws FieldAccessException {
|
||||
if (watchableObjects == null)
|
||||
watchableObjects = (Map<Integer, Object>) VALUE_MAP_ACCESSOR.get(handle);
|
||||
return watchableObjects;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the data watcher associated with an entity.
|
||||
* @param entity - the entity to read from.
|
||||
* @return Associated data watcher.
|
||||
* @throws FieldAccessException Reflection failed.
|
||||
*/
|
||||
public static WrappedDataWatcher getEntityWatcher(Entity entity) throws FieldAccessException {
|
||||
if (ENTITY_DATA_FIELD == null)
|
||||
ENTITY_DATA_FIELD = FuzzyReflection.fromClass(MinecraftReflection.getEntityClass(), true).
|
||||
getFieldByType("datawatcher", MinecraftReflection.getDataWatcherClass());
|
||||
|
||||
BukkitUnwrapper unwrapper = new BukkitUnwrapper();
|
||||
|
||||
try {
|
||||
Object nsmWatcher = FieldUtils.readField(ENTITY_DATA_FIELD, unwrapper.unwrapItem(entity), true);
|
||||
|
||||
if (nsmWatcher != null)
|
||||
return new WrappedDataWatcher(nsmWatcher);
|
||||
else
|
||||
return null;
|
||||
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new FieldAccessException("Cannot access DataWatcher field.", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when a data watcher is first used.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private static void initialize() throws FieldAccessException {
|
||||
// This method should only be run once, even if an exception is thrown
|
||||
if (!HAS_INITIALIZED)
|
||||
HAS_INITIALIZED = true;
|
||||
else
|
||||
return;
|
||||
|
||||
FuzzyReflection fuzzy = FuzzyReflection.fromClass(MinecraftReflection.getDataWatcherClass(), true);
|
||||
|
||||
for (Field lookup : fuzzy.getFieldListByType(Map.class)) {
|
||||
if (Modifier.isStatic(lookup.getModifiers())) {
|
||||
// This must be the type map
|
||||
TYPE_MAP_ACCESSOR = Accessors.getFieldAccessor(lookup, true);
|
||||
} else {
|
||||
// If not, then we're probably dealing with the value map
|
||||
VALUE_MAP_ACCESSOR = Accessors.getFieldAccessor(lookup, true);
|
||||
}
|
||||
}
|
||||
// Spigot workaround (not necessary
|
||||
initializeSpigot(fuzzy);
|
||||
|
||||
// Any custom types
|
||||
CUSTOM_MAP = initializeCustom();
|
||||
|
||||
// Initialize static type type
|
||||
TYPE_MAP = (Map<Class<?>, Integer>) TYPE_MAP_ACCESSOR.get(null);
|
||||
|
||||
try {
|
||||
READ_WRITE_LOCK_FIELD = fuzzy.getFieldByType("readWriteLock", ReadWriteLock.class);
|
||||
} catch (IllegalArgumentException e) {
|
||||
// It's not a big deal
|
||||
}
|
||||
|
||||
// Check for the entity field as well
|
||||
if (MinecraftReflection.isUsingNetty()) {
|
||||
ENTITY_FIELD = fuzzy.getFieldByType("entity", MinecraftReflection.getEntityClass());
|
||||
ENTITY_FIELD.setAccessible(true);
|
||||
}
|
||||
initializeMethods(fuzzy);
|
||||
}
|
||||
|
||||
// For Spigot's bountiful update patch
|
||||
private static Map<Class<?>, Integer> initializeCustom() {
|
||||
Map<Class<?>, Integer> map = Maps.newHashMap();
|
||||
|
||||
for (CustomType type : CustomType.values()) {
|
||||
if (type.getSpigotClass() != null) {
|
||||
map.put(type.getSpigotClass(), type.getTypeId());
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
// TODO: Remove, as this was fixed in build #1189 of Spigot
|
||||
private static void initializeSpigot(FuzzyReflection fuzzy) {
|
||||
// See if the workaround is needed
|
||||
if (TYPE_MAP_ACCESSOR != null && VALUE_MAP_ACCESSOR != null)
|
||||
return;
|
||||
|
||||
for (Field lookup : fuzzy.getFields()) {
|
||||
final Class<?> type = lookup.getType();
|
||||
|
||||
if (TroveWrapper.isTroveClass(type)) {
|
||||
// Create a wrapper accessor
|
||||
final ReadOnlyFieldAccessor accessor = TroveWrapper.wrapMapField(
|
||||
Accessors.getFieldAccessor(lookup, true), new Function<Integer, Integer>() {
|
||||
@Override
|
||||
public Integer apply(@Nullable Integer value) {
|
||||
// Do not use zero for no entry value
|
||||
if (value == 0)
|
||||
return -1;
|
||||
return value;
|
||||
}
|
||||
});
|
||||
|
||||
if (Modifier.isStatic(lookup.getModifiers())) {
|
||||
TYPE_MAP_ACCESSOR = accessor;
|
||||
} else {
|
||||
VALUE_MAP_ACCESSOR = accessor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (TYPE_MAP_ACCESSOR == null)
|
||||
throw new IllegalArgumentException("Unable to find static type map.");
|
||||
if (VALUE_MAP_ACCESSOR == null)
|
||||
throw new IllegalArgumentException("Unable to find static value map.");
|
||||
}
|
||||
|
||||
private static void initializeMethods(FuzzyReflection fuzzy) {
|
||||
List<Method> candidates = fuzzy.getMethodListByParameters(Void.TYPE,
|
||||
new Class<?>[] { int.class, Object.class});
|
||||
|
||||
// Load the get-method
|
||||
try {
|
||||
GET_KEY_VALUE_METHOD = fuzzy.getMethodByParameters(
|
||||
"getWatchableObject", MinecraftReflection.getWatchableObjectClass(), new Class[] { int.class });
|
||||
GET_KEY_VALUE_METHOD.setAccessible(true);
|
||||
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Use the fallback method
|
||||
}
|
||||
|
||||
for (Method method : candidates) {
|
||||
if (!method.getName().startsWith("watch")) {
|
||||
CREATE_KEY_VALUE_METHOD = method;
|
||||
} else {
|
||||
UPDATE_KEY_VALUE_METHOD = method;
|
||||
}
|
||||
}
|
||||
|
||||
// Did we succeed?
|
||||
if (UPDATE_KEY_VALUE_METHOD == null || CREATE_KEY_VALUE_METHOD == null) {
|
||||
// Go by index instead
|
||||
if (candidates.size() > 1) {
|
||||
CREATE_KEY_VALUE_METHOD = candidates.get(0);
|
||||
UPDATE_KEY_VALUE_METHOD = candidates.get(1);
|
||||
} else {
|
||||
throw new IllegalStateException("Unable to find create and update watchable object. Update ProtocolLib.");
|
||||
}
|
||||
|
||||
// Be a little scientist - see if this in fact IS the right way around
|
||||
try {
|
||||
WrappedDataWatcher watcher = new WrappedDataWatcher();
|
||||
watcher.setObject(0, 0);
|
||||
watcher.setObject(0, 1);
|
||||
|
||||
if (watcher.getInteger(0) != 1) {
|
||||
throw new IllegalStateException("This cannot be!");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// Nope
|
||||
UPDATE_KEY_VALUE_METHOD = candidates.get(0);
|
||||
CREATE_KEY_VALUE_METHOD = candidates.get(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<WrappedWatchableObject> iterator() {
|
||||
// We'll wrap the iterator instead of creating a new list every time
|
||||
return Iterators.transform(getWatchableObjectMap().values().iterator(),
|
||||
new Function<Object, WrappedWatchableObject>() {
|
||||
|
||||
@Override
|
||||
public WrappedWatchableObject apply(@Nullable Object item) {
|
||||
if (item != null)
|
||||
return new WrappedWatchableObject(item);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a view of this DataWatcher as a map.
|
||||
* <p>
|
||||
* Any changes to the map will be reflected in this DataWatcher, and vice versa.
|
||||
* @return A view of the data watcher as a map.
|
||||
*/
|
||||
public Map<Integer, WrappedWatchableObject> asMap() {
|
||||
// Construct corresponding map
|
||||
if (mapView == null) {
|
||||
mapView = new ConvertedMap<Integer, Object, WrappedWatchableObject>(getWatchableObjectMap()) {
|
||||
@Override
|
||||
protected Object toInner(WrappedWatchableObject outer) {
|
||||
if (outer == null)
|
||||
return null;
|
||||
return outer.getHandle();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected WrappedWatchableObject toOuter(Object inner) {
|
||||
if (inner == null)
|
||||
return null;
|
||||
return new WrappedWatchableObject(inner);
|
||||
}
|
||||
};
|
||||
}
|
||||
return mapView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return asMap().toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the entity associated with this data watcher.
|
||||
* <p>
|
||||
* <b>Warning:</b> This is only supported on 1.7.2 and above.
|
||||
* @return The entity, or NULL.
|
||||
*/
|
||||
public Entity getEntity() {
|
||||
if (!MinecraftReflection.isUsingNetty())
|
||||
throw new IllegalStateException("This method is only supported on 1.7.2 and above.");
|
||||
|
||||
try {
|
||||
return (Entity) MinecraftReflection.getBukkitEntity(ENTITY_FIELD.get(handle));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Unable to retrieve entity.", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the entity associated with this data watcher.
|
||||
* <p>
|
||||
* <b>Warning:</b> This is only supported on 1.7.2 and above.
|
||||
* @param entity - the new entity.
|
||||
*/
|
||||
public void setEntity(Entity entity) {
|
||||
if (!MinecraftReflection.isUsingNetty())
|
||||
throw new IllegalStateException("This method is only supported on 1.7.2 and above.");
|
||||
|
||||
try {
|
||||
ENTITY_FIELD.set(handle, BukkitUnwrapper.getInstance().unwrapItem(entity));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Unable to set entity.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
-467
@@ -1,467 +0,0 @@
|
||||
/*
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2012 Kristian S. Stangeland
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program;
|
||||
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
* 02111-1307 USA
|
||||
*/
|
||||
|
||||
package com.comphenix.protocol.wrappers;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import com.comphenix.protocol.reflect.EquivalentConverter;
|
||||
import com.comphenix.protocol.reflect.FieldAccessException;
|
||||
import com.comphenix.protocol.reflect.StructureModifier;
|
||||
import com.comphenix.protocol.reflect.instances.DefaultInstances;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
/**
|
||||
* Represents a watchable object.
|
||||
*
|
||||
* @author Kristian
|
||||
*/
|
||||
public class WrappedWatchableObject extends AbstractWrapper {
|
||||
// Whether or not the reflection machinery has been initialized
|
||||
private static boolean hasInitialized;
|
||||
|
||||
// The field containing the value itself
|
||||
private static StructureModifier<Object> baseModifier;
|
||||
|
||||
// Used to create new watchable objects
|
||||
private static Constructor<?> watchableConstructor;
|
||||
|
||||
// The watchable object class type
|
||||
private static Class<?> watchableObjectClass;
|
||||
|
||||
protected StructureModifier<Object> modifier;
|
||||
|
||||
// Type of the stored value
|
||||
private Class<?> typeClass;
|
||||
|
||||
/**
|
||||
* Wrap a given raw Minecraft watchable object.
|
||||
* @param handle - the raw watchable object to wrap.
|
||||
*/
|
||||
public WrappedWatchableObject(Object handle) {
|
||||
super(MinecraftReflection.getWatchableObjectClass());
|
||||
load(handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a watchable object from an index and a given value.
|
||||
* @param index - the index.
|
||||
* @param value - non-null value of specific types.
|
||||
*/
|
||||
public WrappedWatchableObject(int index, Object value) {
|
||||
super(MinecraftReflection.getWatchableObjectClass());
|
||||
|
||||
if (value == null)
|
||||
throw new IllegalArgumentException("Value cannot be NULL.");
|
||||
|
||||
// Get the correct type ID
|
||||
Integer typeID = WrappedDataWatcher.getTypeID(value.getClass());
|
||||
|
||||
if (typeID != null) {
|
||||
if (watchableConstructor == null) {
|
||||
try {
|
||||
watchableConstructor = MinecraftReflection.getWatchableObjectClass().
|
||||
getConstructor(int.class, int.class, Object.class);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Cannot get the WatchableObject(int, int, Object) constructor.", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Create the object
|
||||
try {
|
||||
load(watchableConstructor.newInstance(typeID, index, getUnwrapped(value)));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Cannot construct underlying WatchableObject.", e);
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException("Cannot watch the type " + value.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Construct a custom watchable object from an index, value and custom type.
|
||||
// * @param index - the index.
|
||||
// * @param primary - non-null value of specific types.
|
||||
// * @param secondary - optional secondary value, if the type can store it.
|
||||
// * @param type - the custom Spigot type.
|
||||
// */
|
||||
// public WrappedWatchableObject(int index, Object value, Object secondary, CustomType type) {
|
||||
// this(index, type.newInstance(value, secondary));
|
||||
// }
|
||||
|
||||
// Wrap a NMS object
|
||||
private void load(Object handle) {
|
||||
initialize();
|
||||
this.handle = handle;
|
||||
this.modifier = baseModifier.withTarget(handle);
|
||||
|
||||
// Make sure the type is correct
|
||||
if (!watchableObjectClass.isAssignableFrom(handle.getClass())) {
|
||||
throw new ClassCastException("Cannot cast the class " + handle.getClass().getName() +
|
||||
" to " + watchableObjectClass.getName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize reflection machinery.
|
||||
*/
|
||||
private static void initialize() {
|
||||
if (!hasInitialized) {
|
||||
hasInitialized = true;
|
||||
watchableObjectClass = MinecraftReflection.getWatchableObjectClass();
|
||||
baseModifier = new StructureModifier<Object>(watchableObjectClass, null, false);
|
||||
}
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Retrieve the custom type of this object.
|
||||
// * @return The custom type, or NULL if not applicable.
|
||||
// */
|
||||
// public CustomType getCustomType() {
|
||||
// return CustomType.fromValue(getValue());
|
||||
// }
|
||||
|
||||
/**
|
||||
* Retrieve the correct super type of the current value.
|
||||
* @return Super type.
|
||||
* @throws FieldAccessException Unable to read values.
|
||||
*/
|
||||
public Class<?> getType() throws FieldAccessException {
|
||||
return getWrappedType(getTypeRaw());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the correct super type of the current value, given the raw NMS object.
|
||||
* @return Super type.
|
||||
* @throws FieldAccessException Unable to read values.
|
||||
*/
|
||||
private Class<?> getTypeRaw() throws FieldAccessException {
|
||||
if (typeClass == null) {
|
||||
typeClass = WrappedDataWatcher.getTypeClass(getTypeID());
|
||||
|
||||
if (typeClass == null) {
|
||||
throw new IllegalStateException("Unrecognized data type: " + getTypeID());
|
||||
}
|
||||
}
|
||||
|
||||
return typeClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the index of this watchable object. This is used to identify a value.
|
||||
* @return Object index.
|
||||
* @throws FieldAccessException Reflection failed.
|
||||
*/
|
||||
public int getIndex() throws FieldAccessException {
|
||||
return modifier.<Integer>withType(int.class).read(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the the index of this watchable object.
|
||||
* @param index - the new object index.
|
||||
* @throws FieldAccessException Reflection failed.
|
||||
*/
|
||||
public void setIndex(int index) throws FieldAccessException {
|
||||
modifier.<Integer>withType(int.class).write(1, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the type ID of a watchable object.
|
||||
* <table border=1>
|
||||
* <caption>Type to Value</caption>
|
||||
* <tbody>
|
||||
* <tr>
|
||||
* <th>Type ID</th>
|
||||
* <th>Data Type</th>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>0</td>
|
||||
* <td>Byte</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>1</td>
|
||||
* <td>Short</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>2</td>
|
||||
* <td>Int</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>3</td>
|
||||
* <td>Float</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>4</td>
|
||||
* <td>{@link String}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>5</td>
|
||||
* <td>{@link org.bukkit.inventory.ItemStack ItemStack}</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>6<sup>*</sup></td>
|
||||
* <td>{@link com.comphenix.protocol.wrappers.ChunkPosition ChunkPosition}</td>
|
||||
* </tr>
|
||||
* </tbody>
|
||||
* </table>
|
||||
* @return Type ID that identifies the type of the value.
|
||||
* @throws FieldAccessException Reflection failed.
|
||||
*/
|
||||
public int getTypeID() throws FieldAccessException {
|
||||
return modifier.<Integer>withType(int.class).read(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the type ID of a watchable object.
|
||||
* @param id - the new ID.
|
||||
* @throws FieldAccessException Reflection failed.
|
||||
* @see #getTypeID()
|
||||
*/
|
||||
public void setTypeID(int id) throws FieldAccessException {
|
||||
modifier.<Integer>withType(int.class).write(0, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the value field.
|
||||
* @param newValue - new value.
|
||||
* @throws FieldAccessException Unable to use reflection.
|
||||
*/
|
||||
public void setValue(Object newValue) throws FieldAccessException {
|
||||
setValue(newValue, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the value field.
|
||||
* @param newValue - new value.
|
||||
* @param updateClient - whether or not to update listening clients.
|
||||
* @throws FieldAccessException Unable to use reflection.
|
||||
*/
|
||||
public void setValue(Object newValue, boolean updateClient) throws FieldAccessException {
|
||||
// Verify a few quick things
|
||||
if (newValue == null)
|
||||
throw new IllegalArgumentException("Cannot watch a NULL value.");
|
||||
if (!getType().isAssignableFrom(newValue.getClass()))
|
||||
throw new IllegalArgumentException("Object " + newValue + " must be of type " + getType().getName());
|
||||
|
||||
// See if we should update the client to
|
||||
if (updateClient)
|
||||
setDirtyState(true);
|
||||
|
||||
// Use the modifier to set the value
|
||||
modifier.withType(Object.class).write(0, getUnwrapped(newValue));
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the underlying value field.
|
||||
* @return The underlying value.
|
||||
*/
|
||||
private Object getNMSValue() {
|
||||
return modifier.withType(Object.class).read(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the value field.
|
||||
* @return The watched value.
|
||||
* @throws FieldAccessException Unable to use reflection.
|
||||
*/
|
||||
public Object getValue() throws FieldAccessException {
|
||||
return getWrapped(modifier.withType(Object.class).read(0));
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Retrieve the secondary value associated with this watchable object.
|
||||
// * <p>
|
||||
// * This is only applicable for certain {@link CustomType}.
|
||||
// * @return The secondary value, or NULL if not found.
|
||||
// */
|
||||
// public Object getSecondaryValue() {
|
||||
// CustomType type = getCustomType();
|
||||
// return type != null ? type.getSecondary(getValue()) : null;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Set the secondary value.
|
||||
// * @param secondary - the secondary value.
|
||||
// * @throws IllegalStateException If this watchable object does not have a secondary value.
|
||||
// */
|
||||
// public void setSecondaryValue(Object secondary) {
|
||||
// CustomType type = getCustomType();
|
||||
//
|
||||
// if (type == null) {
|
||||
// throw new IllegalStateException(this + " does not have a custom type.");
|
||||
// }
|
||||
// type.setSecondary(getValue(), secondary);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Set whether or not the value must be synchronized with the client.
|
||||
* @param dirty - TRUE if the value should be synchronized, FALSE otherwise.
|
||||
* @throws FieldAccessException Unable to use reflection.
|
||||
*/
|
||||
public void setDirtyState(boolean dirty) throws FieldAccessException {
|
||||
modifier.<Boolean>withType(boolean.class).write(0, dirty);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve whether or not the value must be synchronized with the client.
|
||||
* @return TRUE if the value should be synchronized, FALSE otherwise.
|
||||
* @throws FieldAccessException Unable to use reflection.
|
||||
*/
|
||||
public boolean getDirtyState() throws FieldAccessException {
|
||||
return modifier.<Boolean>withType(boolean.class).read(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the wrapped object value, if needed.
|
||||
* @param value - the raw NMS object to wrap.
|
||||
* @return The wrapped object.
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
static Object getWrapped(Object value) {
|
||||
// Handle the special cases
|
||||
if (MinecraftReflection.isItemStack(value)) {
|
||||
return BukkitConverters.getItemStackConverter().getSpecific(value);
|
||||
} else if (MinecraftReflection.isChunkCoordinates(value)) {
|
||||
return new WrappedChunkCoordinate((Comparable) value);
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the wrapped type, if needed.
|
||||
* @param wrapped - the wrapped class type.
|
||||
* @return The wrapped class type.
|
||||
*/
|
||||
static Class<?> getWrappedType(Class<?> unwrapped) {
|
||||
if (unwrapped.equals(MinecraftReflection.getChunkPositionClass()))
|
||||
return ChunkPosition.class;
|
||||
else if (unwrapped.equals(MinecraftReflection.getBlockPositionClass()))
|
||||
return BlockPosition.class;
|
||||
else if (unwrapped.equals(MinecraftReflection.getChunkCoordinatesClass()))
|
||||
return WrappedChunkCoordinate.class;
|
||||
else if (unwrapped.equals(MinecraftReflection.getItemStackClass()))
|
||||
return ItemStack.class;
|
||||
else
|
||||
return unwrapped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the raw NMS value.
|
||||
* @param wrapped - the wrapped position.
|
||||
* @return The raw NMS object.
|
||||
*/
|
||||
static Object getUnwrapped(Object wrapped) {
|
||||
// Convert special cases
|
||||
if (wrapped instanceof ChunkPosition)
|
||||
return ChunkPosition.getConverter().getGeneric(MinecraftReflection.getChunkPositionClass(), (ChunkPosition) wrapped);
|
||||
else if (wrapped instanceof BlockPosition)
|
||||
return BlockPosition.getConverter().getGeneric(MinecraftReflection.getBlockPositionClass(), (BlockPosition) wrapped);
|
||||
else if (wrapped instanceof WrappedChunkCoordinate)
|
||||
return ((WrappedChunkCoordinate) wrapped).getHandle();
|
||||
else if (wrapped instanceof ItemStack)
|
||||
return BukkitConverters.getItemStackConverter().getGeneric(MinecraftReflection.getItemStackClass(), (ItemStack) wrapped);
|
||||
else
|
||||
return wrapped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the unwrapped type, if needed.
|
||||
* @param wrapped - the unwrapped class type.
|
||||
* @return The unwrapped class type.
|
||||
*/
|
||||
static Class<?> getUnwrappedType(Class<?> wrapped) {
|
||||
if (wrapped.equals(ChunkPosition.class))
|
||||
return MinecraftReflection.getChunkPositionClass();
|
||||
else if (wrapped.equals(BlockPosition.class))
|
||||
return MinecraftReflection.getBlockPositionClass();
|
||||
else if (wrapped.equals(WrappedChunkCoordinate.class))
|
||||
return MinecraftReflection.getChunkCoordinatesClass();
|
||||
else if (ItemStack.class.isAssignableFrom(wrapped))
|
||||
return MinecraftReflection.getItemStackClass();
|
||||
else
|
||||
return wrapped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone the current wrapped watchable object, along with any contained objects.
|
||||
* @return A deep clone of the current watchable object.
|
||||
* @throws FieldAccessException If we're unable to use reflection.
|
||||
*/
|
||||
public WrappedWatchableObject deepClone() throws FieldAccessException {
|
||||
WrappedWatchableObject clone = new WrappedWatchableObject(
|
||||
DefaultInstances.DEFAULT.getDefault(MinecraftReflection.getWatchableObjectClass()));
|
||||
|
||||
clone.setDirtyState(getDirtyState());
|
||||
clone.setIndex(getIndex());
|
||||
clone.setTypeID(getTypeID());
|
||||
clone.setValue(getClonedValue(), false);
|
||||
return clone;
|
||||
}
|
||||
|
||||
// Helper
|
||||
Object getClonedValue() throws FieldAccessException {
|
||||
Object value = getNMSValue();
|
||||
|
||||
// Only a limited set of references types are supported
|
||||
if (MinecraftReflection.isBlockPosition(value)) {
|
||||
EquivalentConverter<BlockPosition> converter = BlockPosition.getConverter();
|
||||
return converter.getGeneric(MinecraftReflection.getBlockPositionClass(), converter.getSpecific(value));
|
||||
} else if (MinecraftReflection.isChunkPosition(value)) {
|
||||
EquivalentConverter<ChunkPosition> converter = ChunkPosition.getConverter();
|
||||
return converter.getGeneric(MinecraftReflection.getChunkPositionClass(), converter.getSpecific(value));
|
||||
} else if (MinecraftReflection.isItemStack(value)) {
|
||||
return MinecraftReflection.getMinecraftItemStack(MinecraftReflection.getBukkitItemStack(value).clone());
|
||||
} else {
|
||||
// A string or primitive wrapper, which are all immutable.
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
// Quick checks
|
||||
if (obj == this)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
|
||||
if (obj instanceof WrappedWatchableObject) {
|
||||
WrappedWatchableObject other = (WrappedWatchableObject) obj;
|
||||
|
||||
return Objects.equal(getIndex(), other.getIndex()) &&
|
||||
Objects.equal(getTypeID(), other.getTypeID()) &&
|
||||
Objects.equal(getValue(), other.getValue());
|
||||
}
|
||||
|
||||
// No, this is not equivalent
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(getIndex(), getTypeID(), getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("[%s: %s (%s)]", getIndex(), getValue(), getType().getSimpleName());
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
package com.comphenix.protocol;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.comphenix.protocol.PacketType.Protocol;
|
||||
import com.comphenix.protocol.PacketType.Sender;
|
||||
import com.comphenix.protocol.compat.netty.independent.NettyProtocolRegistry;
|
||||
import com.comphenix.protocol.injector.netty.ProtocolRegistry;
|
||||
|
||||
public class PacketTypeTest {
|
||||
|
||||
@BeforeClass
|
||||
public static void initializeReflection() {
|
||||
BukkitInitialization.initializePackage();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindCurrent() {
|
||||
assertEquals(PacketType.Play.Client.STEER_VEHICLE, PacketType.findCurrent(Protocol.PLAY, Sender.CLIENT, "SteerVehicle"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ensureAllExist() {
|
||||
ProtocolRegistry registry = new NettyProtocolRegistry();
|
||||
Map<PacketType, Class<?>> lookup = registry.getPacketTypeLookup();
|
||||
for (Entry<PacketType, Class<?>> entry : lookup.entrySet()) {
|
||||
PacketType type = entry.getKey();
|
||||
Class<?> clazz = entry.getValue();
|
||||
|
||||
assertFalse("Packet " + clazz + " does not have a corresponding PacketType!", type.isDynamic());
|
||||
}
|
||||
}
|
||||
}
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
package com.comphenix.protocol.reflect.cloning;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.comphenix.protocol.BukkitInitialization;
|
||||
|
||||
public class AggregateClonerTest {
|
||||
|
||||
@BeforeClass
|
||||
public static void initializeBukkit() {
|
||||
BukkitInitialization.initializePackage();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArrays() {
|
||||
List<Integer> input = Arrays.asList(1, 2, 3);
|
||||
assertEquals(input, AggregateCloner.DEFAULT.clone(input));
|
||||
}
|
||||
}
|
||||
@@ -15,8 +15,8 @@ Currently maintained by dmulloy2 on behalf of [Spigot](http://www.spigotmc.org/)
|
||||
### Resources
|
||||
|
||||
* [Resource Page](http://www.spigotmc.org/resources/protocollib.1997/)
|
||||
* [Downloads](http://ci.shadowvolt.com/job/ProtocolLib)
|
||||
* [JavaDoc](http://ci.shadowvolt.com/job/ProtocolLib/javadoc)
|
||||
* [Dev Builds](http://ci.dmulloy2.net/job/ProtocolLib)
|
||||
* [JavaDoc](http://ci.dmulloy2.net/job/ProtocolLib/javadoc)
|
||||
|
||||
### Compilation
|
||||
|
||||
@@ -47,13 +47,13 @@ You can also add ProtocolLib as a Maven dependency:
|
||||
<url>http://repo.dmulloy2.net/content/groups/public/</url>
|
||||
</repository>
|
||||
...
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.comphenix.protocol</groupId>
|
||||
<artifactId>ProtocolLib</artifactId>
|
||||
<version>3.6.4</version>
|
||||
<version>3.6.5</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
````
|
||||
@@ -131,6 +131,7 @@ you don't have to create an ArrayList with this version:
|
||||
|
||||
````java
|
||||
|
||||
PacketContainer fakeExplosion = new PacketContainer(PacketType.Play.Server.EXPLOSION);
|
||||
fakeExplosion.getDoubles().
|
||||
write(0, player.getLocation().getX()).
|
||||
write(1, player.getLocation().getY()).
|
||||
@@ -159,4 +160,4 @@ types. It's remarkably consistent across different versions.
|
||||
### Incompatibility
|
||||
|
||||
The following plugins (to be expanded) are not compatible with ProtocolLib:
|
||||
* TagAPI
|
||||
* TagAPI
|
||||
@@ -1,275 +1,252 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>ProtocolLib-v1_7_R4</artifactId>
|
||||
<name>ProtocolLib-v1_7_R4</name>
|
||||
<version>3.6.5</version>
|
||||
|
||||
<description>Provides read/write access to the Minecraft protocol.</description>
|
||||
<url>http://www.spigotmc.org/resources/protocollib.1997/</url>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.comphenix.protocol</groupId>
|
||||
<artifactId>ProtocolLib-Parent</artifactId>
|
||||
<version>v3-SNAPSHOT</version>
|
||||
<relativePath>../../</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.build.number></project.build.number>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>md_5-repo</id>
|
||||
<url>http://repo.md-5.net/content/groups/public/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<build>
|
||||
<defaultGoal>clean install</defaultGoal>
|
||||
<sourceDirectory>src/main/java</sourceDirectory>
|
||||
<testSourceDirectory>src/test/java</testSourceDirectory>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
<excludes>
|
||||
<exclude>**/*.java</exclude>
|
||||
</excludes>
|
||||
</resource>
|
||||
</resources>
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>2.3</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<shadedArtifactAttached>false</shadedArtifactAttached>
|
||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||
|
||||
<relocations>
|
||||
<relocation>
|
||||
<pattern>net.sf</pattern>
|
||||
<shadedPattern>com.comphenix.net.sf</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
|
||||
<artifactSet>
|
||||
<excludes>
|
||||
<exclude>org.spigotmc:spigot</exclude>
|
||||
<exclude>org.spigotmc:spigot-api</exclude>
|
||||
<exclude>junit:junit</exclude>
|
||||
</excludes>
|
||||
</artifactSet>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.2</version>
|
||||
<configuration>
|
||||
<source>1.6</source>
|
||||
<target>1.6</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>2.5</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifestEntries>
|
||||
<Main-Class>com.comphenix.protocol.Application</Main-Class>
|
||||
<Implementation-Title>ProtocolLib</Implementation-Title>
|
||||
<Implementation-Version>${project.version}${project.build.number}</Implementation-Version>
|
||||
<Implementation-Vendor>dmulloy2</Implementation-Vendor>
|
||||
</manifestEntries>
|
||||
</archive>
|
||||
<finalName>ProtocolLib</finalName>
|
||||
<outputDirectory>../../target/</outputDirectory>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>2.7</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<id>attach-javadocs</id>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<reporting>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>findbugs-maven-plugin</artifactId>
|
||||
<version>2.5.2</version>
|
||||
<configuration>
|
||||
<threshold>High</threshold>
|
||||
<effort>Default</effort>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</reporting>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>jenkins</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>env.BUILD_NUMBER</name>
|
||||
</property>
|
||||
</activation>
|
||||
<properties>
|
||||
<project.build.number>-b${env.BUILD_NUMBER}</project.build.number>
|
||||
</properties>
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>release-sign-artifacts</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>performRelease</name>
|
||||
<value>true</value>
|
||||
</property>
|
||||
</activation>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>2.4</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-sources</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>2.10.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-javadocs</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-gpg-plugin</artifactId>
|
||||
<version>1.5</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>sign-artifacts</id>
|
||||
<phase>verify</phase>
|
||||
<goals>
|
||||
<goal>sign</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<scm>
|
||||
<connection>scm:git:git://github.com/dmulloy2/ProtocolLib.git</connection>
|
||||
<developerConnection>scm:git:git@github.com:dmulloy2/ProtocolLib.git</developerConnection>
|
||||
<url>https://github.com/dmulloy2/ProtocolLib</url>
|
||||
</scm>
|
||||
|
||||
<licenses>
|
||||
<license>
|
||||
<name>GNU GENERAL PUBLIC LICENSE - Version 2, June 1991</name>
|
||||
<url>http://www.gnu.org/licenses/gpl-2.0.txt</url>
|
||||
<distribution>repo</distribution>
|
||||
</license>
|
||||
</licenses>
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<id>dmulloy2</id>
|
||||
<name>Dan Mulloy</name>
|
||||
<url>http://dmulloy2.net/</url>
|
||||
<roles>
|
||||
<role>developer</role>
|
||||
<role>maintainer</role>
|
||||
</roles>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>aadnk</id>
|
||||
<name>Kristian S. Stangeland</name>
|
||||
<email>kr_stang@hotmail.com</email>
|
||||
<url>http://comphenix.net/</url>
|
||||
<roles>
|
||||
<role>former author</role>
|
||||
</roles>
|
||||
<timezone>1</timezone>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.7.10-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot</artifactId>
|
||||
<version>1.7.10-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.comphenix.protocol</groupId>
|
||||
<artifactId>ProtocolLib</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cglib</groupId>
|
||||
<artifactId>cglib-nodep</artifactId>
|
||||
<version>2.2.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.comphenix.executors</groupId>
|
||||
<artifactId>BukkitExecutors</artifactId>
|
||||
<version>1.1-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>ProtocolLib-API</artifactId>
|
||||
<name>ProtocolLib-API</name>
|
||||
<version>4.2.1</version>
|
||||
|
||||
<description>Provides read/write access to the Minecraft protocol.</description>
|
||||
<url>http://www.spigotmc.org/resources/protocollib.1997/</url>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.comphenix.protocol</groupId>
|
||||
<artifactId>ProtocolLib-Parent</artifactId>
|
||||
<version>v4-SNAPSHOT</version>
|
||||
<relativePath>../../</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.build.number></project.build.number>
|
||||
<project.fullVersion>${project.version}</project.fullVersion>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<defaultGoal>clean install</defaultGoal>
|
||||
<sourceDirectory>src/main/java</sourceDirectory>
|
||||
<testSourceDirectory>src/test/java</testSourceDirectory>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
<excludes>
|
||||
<exclude>**/*.java</exclude>
|
||||
</excludes>
|
||||
</resource>
|
||||
</resources>
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.5.1</version>
|
||||
<configuration>
|
||||
<source>1.7</source>
|
||||
<target>1.7</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>2.6</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifestEntries>
|
||||
<Main-Class>com.comphenix.protocol.Application</Main-Class>
|
||||
<Implementation-Title>ProtocolLib</Implementation-Title>
|
||||
<Implementation-Version>${project.fullVersion}</Implementation-Version>
|
||||
<Implementation-Vendor>dmulloy2</Implementation-Vendor>
|
||||
</manifestEntries>
|
||||
</archive>
|
||||
<finalName>ProtocolLib</finalName>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.10</version>
|
||||
<configuration>
|
||||
<systemProperties>
|
||||
<property>
|
||||
<name>projectVersion</name>
|
||||
<value>${project.version}</value>
|
||||
</property>
|
||||
</systemProperties>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>jenkins</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>env.BUILD_NUMBER</name>
|
||||
</property>
|
||||
</activation>
|
||||
<properties>
|
||||
<project.build.number>-b${env.BUILD_NUMBER}</project.build.number>
|
||||
<project.fullVersion>${project.version}${project.build.number}</project.fullVersion>
|
||||
</properties>
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>release-sign-artifacts</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>performRelease</name>
|
||||
<value>true</value>
|
||||
</property>
|
||||
</activation>
|
||||
<properties>
|
||||
<project.fullVersion>${project.version}</project.fullVersion>
|
||||
</properties>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-sources</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>2.10.3</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-javadocs</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<!-- TODO: Look into signing releases
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-gpg-plugin</artifactId>
|
||||
<version>1.6</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>sign-artifacts</id>
|
||||
<phase>verify</phase>
|
||||
<goals>
|
||||
<goal>sign</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
-->
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<scm>
|
||||
<connection>scm:git:git://github.com/dmulloy2/ProtocolLib.git</connection>
|
||||
<developerConnection>scm:git:git@github.com:dmulloy2/ProtocolLib.git</developerConnection>
|
||||
<url>https://github.com/dmulloy2/ProtocolLib</url>
|
||||
</scm>
|
||||
|
||||
<licenses>
|
||||
<license>
|
||||
<name>GNU GENERAL PUBLIC LICENSE - Version 2, June 1991</name>
|
||||
<url>http://www.gnu.org/licenses/gpl-2.0.txt</url>
|
||||
<distribution>repo</distribution>
|
||||
</license>
|
||||
</licenses>
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<id>dmulloy2</id>
|
||||
<name>Dan Mulloy</name>
|
||||
<url>http://dmulloy2.net/</url>
|
||||
<roles>
|
||||
<role>developer</role>
|
||||
<role>maintainer</role>
|
||||
</roles>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>aadnk</id>
|
||||
<name>Kristian S. Stangeland</name>
|
||||
<email>kr_stang@hotmail.com</email>
|
||||
<url>http://comphenix.net/</url>
|
||||
<roles>
|
||||
<role>former author</role>
|
||||
</roles>
|
||||
<timezone>1</timezone>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
<dependencies>
|
||||
<!-- Included with Minecraft
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-all</artifactId>
|
||||
<version>4.0.23.Final</version>
|
||||
</dependency>
|
||||
-->
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.11.2-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot</artifactId>
|
||||
<version>1.11.2-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cglib</groupId>
|
||||
<artifactId>cglib-nodep</artifactId>
|
||||
<version>2.2.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.comphenix.executors</groupId>
|
||||
<artifactId>BukkitExecutors</artifactId>
|
||||
<version>1.1-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.10</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<version>1.8.4</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.powermock</groupId>
|
||||
<artifactId>powermock-module-junit4</artifactId>
|
||||
<version>1.5</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.powermock</groupId>
|
||||
<artifactId>powermock-api-mockito</artifactId>
|
||||
<version>1.5</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
+1
-1
@@ -152,4 +152,4 @@ public interface AsynchronousManager {
|
||||
* @return Set of every asynchronous packet listener.
|
||||
*/
|
||||
public abstract Set<PacketListener> getAsyncHandlers();
|
||||
}
|
||||
}
|
||||
File renamed without changes.
+243
-152
@@ -4,6 +4,7 @@ import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Callable;
|
||||
@@ -31,10 +32,10 @@ import com.google.common.util.concurrent.Futures;
|
||||
* Note that vanilla Minecraft reuses packet IDs per protocol (ping, game, login) and IDs are subject to change, so they are not reliable.
|
||||
* @author Kristian
|
||||
*/
|
||||
public class PacketType implements Serializable, Comparable<PacketType> {
|
||||
public class PacketType implements Serializable, Cloneable, Comparable<PacketType> {
|
||||
// Increment whenever the type changes
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
/**
|
||||
* Represents an unknown legacy packet ID.
|
||||
*/
|
||||
@@ -53,10 +54,8 @@ public class PacketType implements Serializable, Comparable<PacketType> {
|
||||
*/
|
||||
public static class Client extends ObjectEnum<PacketType> {
|
||||
private final static Sender SENDER = Sender.CLIENT;
|
||||
/**
|
||||
* Legacy name: HANDSHAKE.
|
||||
*/
|
||||
public static final PacketType SET_PROTOCOL = new PacketType(PROTOCOL, SENDER, 0x00, 2, "SetProtocol");
|
||||
|
||||
public static final PacketType SET_PROTOCOL = new PacketType(PROTOCOL, SENDER, 0x00, 0x00, "SetProtocol");
|
||||
|
||||
private final static Client INSTANCE = new Client();
|
||||
|
||||
@@ -107,94 +106,138 @@ public class PacketType implements Serializable, Comparable<PacketType> {
|
||||
public static class Server extends ObjectEnum<PacketType> {
|
||||
private final static Sender SENDER = Sender.SERVER;
|
||||
|
||||
public static final PacketType KEEP_ALIVE = new PacketType(PROTOCOL, SENDER, 0x00, 0, "KeepAlive");
|
||||
public static final PacketType LOGIN = new PacketType(PROTOCOL, SENDER, 0x01, 1, "Login");
|
||||
public static final PacketType CHAT = new PacketType(PROTOCOL, SENDER, 0x02, 3, "Chat");
|
||||
public static final PacketType UPDATE_TIME = new PacketType(PROTOCOL, SENDER, 0x03, 4, "UpdateTime");
|
||||
public static final PacketType ENTITY_EQUIPMENT = new PacketType(PROTOCOL, SENDER, 0x04, 5, "EntityEquipment");
|
||||
public static final PacketType SPAWN_POSITION = new PacketType(PROTOCOL, SENDER, 0x05, 6, "SpawnPosition");
|
||||
public static final PacketType UPDATE_HEALTH = new PacketType(PROTOCOL, SENDER, 0x06, 8, "UpdateHealth");
|
||||
public static final PacketType RESPAWN = new PacketType(PROTOCOL, SENDER, 0x07, 9, "Respawn");
|
||||
public static final PacketType POSITION = new PacketType(PROTOCOL, SENDER, 0x08, 13, "Position");
|
||||
public static final PacketType HELD_ITEM_SLOT = new PacketType(PROTOCOL, SENDER, 0x09, 16, "HeldItemSlot");
|
||||
/**
|
||||
* Note that this was Packets.Server.ENTITY_LOCATION_ACTION.
|
||||
*/
|
||||
public static final PacketType BED = new PacketType(PROTOCOL, SENDER, 0x0A, 17, "Bed");
|
||||
public static final PacketType ANIMATION = new PacketType(PROTOCOL, SENDER, 0x0B, 18, "Animation");
|
||||
public static final PacketType NAMED_ENTITY_SPAWN = new PacketType(PROTOCOL, SENDER, 0x0C, 20, "NamedEntitySpawn");
|
||||
public static final PacketType COLLECT = new PacketType(PROTOCOL, SENDER, 0x0D, 22, "Collect");
|
||||
public static final PacketType SPAWN_ENTITY = new PacketType(PROTOCOL, SENDER, 0x0E, 23, "SpawnEntity");
|
||||
public static final PacketType SPAWN_ENTITY_LIVING = new PacketType(PROTOCOL, SENDER, 0x0F, 24, "SpawnEntityLiving");
|
||||
public static final PacketType SPAWN_ENTITY_PAINTING = new PacketType(PROTOCOL, SENDER, 0x10, 25, "SpawnEntityPainting");
|
||||
public static final PacketType SPAWN_ENTITY_EXPERIENCE_ORB =
|
||||
new PacketType(PROTOCOL, SENDER, 0x11, 26, "SpawnEntityExperienceOrb");
|
||||
public static final PacketType ENTITY_VELOCITY = new PacketType(PROTOCOL, SENDER, 0x12, 28, "EntityVelocity");
|
||||
public static final PacketType ENTITY_DESTROY = new PacketType(PROTOCOL, SENDER, 0x13, 29, "EntityDestroy");
|
||||
public static final PacketType ENTITY = new PacketType(PROTOCOL, SENDER, 0x14, 30, "Entity");
|
||||
public static final PacketType REL_ENTITY_MOVE = new PacketType(PROTOCOL, SENDER, 0x15, 31, "RelEntityMove");
|
||||
public static final PacketType ENTITY_LOOK = new PacketType(PROTOCOL, SENDER, 0x16, 32, "EntityLook");
|
||||
public static final PacketType ENTITY_MOVE_LOOK = new PacketType(PROTOCOL, SENDER, 0x17, 33, "RelEntityMoveLook");
|
||||
public static final PacketType ENTITY_TELEPORT = new PacketType(PROTOCOL, SENDER, 0x18, 34, "EntityTeleport");
|
||||
public static final PacketType ENTITY_HEAD_ROTATION = new PacketType(PROTOCOL, SENDER, 0x19, 35, "EntityHeadRotation");
|
||||
public static final PacketType ENTITY_STATUS = new PacketType(PROTOCOL, SENDER, 0x1A, 38, "EntityStatus");
|
||||
public static final PacketType ATTACH_ENTITY = new PacketType(PROTOCOL, SENDER, 0x1B, 39, "AttachEntity");
|
||||
public static final PacketType ENTITY_METADATA = new PacketType(PROTOCOL, SENDER, 0x1C, 40, "EntityMetadata");
|
||||
public static final PacketType ENTITY_EFFECT = new PacketType(PROTOCOL, SENDER, 0x1D, 41, "EntityEffect");
|
||||
public static final PacketType REMOVE_ENTITY_EFFECT = new PacketType(PROTOCOL, SENDER, 0x1E, 42, "RemoveEntityEffect");
|
||||
public static final PacketType EXPERIENCE = new PacketType(PROTOCOL, SENDER, 0x1F, 43, "Experience");
|
||||
public static final PacketType UPDATE_ATTRIBUTES = new PacketType(PROTOCOL, SENDER, 0x20, 44, "UpdateAttributes");
|
||||
public static final PacketType MAP_CHUNK = new PacketType(PROTOCOL, SENDER, 0x21, 51, "MapChunk");
|
||||
public static final PacketType MULTI_BLOCK_CHANGE = new PacketType(PROTOCOL, SENDER, 0x22, 52, "MultiBlockChange");
|
||||
public static final PacketType BLOCK_CHANGE = new PacketType(PROTOCOL, SENDER, 0x23, 53, "BlockChange");
|
||||
public static final PacketType BLOCK_ACTION = new PacketType(PROTOCOL, SENDER, 0x24, 54, "BlockAction");
|
||||
public static final PacketType BLOCK_BREAK_ANIMATION = new PacketType(PROTOCOL, SENDER, 0x25, 55, "BlockBreakAnimation");
|
||||
public static final PacketType MAP_CHUNK_BULK = new PacketType(PROTOCOL, SENDER, 0x26, 56, "MapChunkBulk");
|
||||
public static final PacketType EXPLOSION = new PacketType(PROTOCOL, SENDER, 0x27, 60, "Explosion");
|
||||
public static final PacketType WORLD_EVENT = new PacketType(PROTOCOL, SENDER, 0x28, 61, "WorldEvent");
|
||||
public static final PacketType NAMED_SOUND_EFFECT = new PacketType(PROTOCOL, SENDER, 0x29, 62, "NamedSoundEffect");
|
||||
public static final PacketType WORLD_PARTICLES = new PacketType(PROTOCOL, SENDER, 0x2A, 63, "WorldParticles");
|
||||
/**
|
||||
* Note that this was Packets.Server.BED.
|
||||
*/
|
||||
public static final PacketType GAME_STATE_CHANGE = new PacketType(PROTOCOL, SENDER, 0x2B, 70, "GameStateChange");
|
||||
public static final PacketType SPAWN_ENTITY_WEATHER = new PacketType(PROTOCOL, SENDER, 0x2C, 71, "SpawnEntityWeather");
|
||||
public static final PacketType OPEN_WINDOW = new PacketType(PROTOCOL, SENDER, 0x2D, 100, "OpenWindow");
|
||||
public static final PacketType CLOSE_WINDOW = new PacketType(PROTOCOL, SENDER, 0x2E, 101, "CloseWindow");
|
||||
public static final PacketType SET_SLOT = new PacketType(PROTOCOL, SENDER, 0x2F, 103, "SetSlot");
|
||||
public static final PacketType WINDOW_ITEMS = new PacketType(PROTOCOL, SENDER, 0x30, 104, "WindowItems");
|
||||
/**
|
||||
* Should be WINDOW_DATA.
|
||||
*/
|
||||
public static final PacketType CRAFT_PROGRESS_BAR = new PacketType(PROTOCOL, SENDER, 0x31, 105, "WindowData");
|
||||
public static final PacketType TRANSACTION = new PacketType(PROTOCOL, SENDER, 0x32, 106, "Transaction");
|
||||
public static final PacketType UPDATE_SIGN = new PacketType(PROTOCOL, SENDER, 0x33, 130, "UpdateSign");
|
||||
public static final PacketType MAP = new PacketType(PROTOCOL, SENDER, 0x34, 131, "Map");
|
||||
public static final PacketType TILE_ENTITY_DATA = new PacketType(PROTOCOL, SENDER, 0x35, 132, "TileEntityData");
|
||||
public static final PacketType OPEN_SIGN_ENTITY = new PacketType(PROTOCOL, SENDER, 0x36, 133, "OpenSignEditor");
|
||||
public static final PacketType STATISTICS = new PacketType(PROTOCOL, SENDER, 0x37, 200, "Statistic");
|
||||
public static final PacketType PLAYER_INFO = new PacketType(PROTOCOL, SENDER, 0x38, 201, "PlayerInfo");
|
||||
public static final PacketType ABILITIES = new PacketType(PROTOCOL, SENDER, 0x39, 202, "Abilities");
|
||||
public static final PacketType TAB_COMPLETE = new PacketType(PROTOCOL, SENDER, 0x3A, 203, "TabComplete");
|
||||
public static final PacketType SCOREBOARD_OBJECTIVE = new PacketType(PROTOCOL, SENDER, 0x3B, 206, "ScoreboardObjective");
|
||||
public static final PacketType SCOREBOARD_SCORE = new PacketType(PROTOCOL, SENDER, 0x3C, 207, "ScoreboardScore");
|
||||
public static final PacketType SCOREBOARD_DISPLAY_OBJECTIVE =
|
||||
new PacketType(PROTOCOL, SENDER, 0x3D, 208, "ScoreboardDisplayObjective");
|
||||
public static final PacketType SCOREBOARD_TEAM = new PacketType(PROTOCOL, SENDER, 0x3E, 209, "ScoreboardTeam");
|
||||
public static final PacketType CUSTOM_PAYLOAD = new PacketType(PROTOCOL, SENDER, 0x3F, 250, "CustomPayload");
|
||||
public static final PacketType KICK_DISCONNECT = new PacketType(PROTOCOL, SENDER, 0x40, 255, "KickDisconnect");
|
||||
public static final PacketType SERVER_DIFFICULTY = new PacketType(PROTOCOL, SENDER, 0x41, -1, "ServerDifficulty");
|
||||
public static final PacketType COMBAT_EVENT = new PacketType(PROTOCOL, SENDER, 0x42, -1, "CombatEvent");
|
||||
public static final PacketType CAMERA = new PacketType(PROTOCOL, SENDER, 0x43, -1, "Camera");
|
||||
public static final PacketType WORLD_BORDER = new PacketType(PROTOCOL, SENDER, 0x44, -1, "WorldBorder");
|
||||
public static final PacketType TITLE = new PacketType(PROTOCOL, SENDER, 0x45, -1, "Title");
|
||||
public static final PacketType SET_COMPRESSION = new PacketType(PROTOCOL, SENDER, 0x46, -1, "SetCompression");
|
||||
public static final PacketType PLAYER_LIST_HEADER_FOOTER =
|
||||
new PacketType(PROTOCOL, SENDER, 0x47, -1, "PlayerListHeaderFooter");
|
||||
public static final PacketType RESOURCE_PACK_SEND = new PacketType(PROTOCOL, SENDER, 0x48, -1, "ResourcePackSend");
|
||||
public static final PacketType UPDATE_ENTITY_NBT = new PacketType(PROTOCOL, SENDER, 0x49, -1, "UpdateEntityNBT");
|
||||
public static final PacketType SPAWN_ENTITY = new PacketType(PROTOCOL, SENDER, 0x00, 0x0E, "SpawnEntity");
|
||||
public static final PacketType SPAWN_ENTITY_EXPERIENCE_ORB = new PacketType(PROTOCOL, SENDER, 0x01, 0x11, "SpawnEntityExperienceOrb");
|
||||
public static final PacketType SPAWN_ENTITY_WEATHER = new PacketType(PROTOCOL, SENDER, 0x02, 0x2C, "SpawnEntityWeather");
|
||||
public static final PacketType SPAWN_ENTITY_LIVING = new PacketType(PROTOCOL, SENDER, 0x03, 0x0F, "SpawnEntityLiving");
|
||||
public static final PacketType SPAWN_ENTITY_PAINTING = new PacketType(PROTOCOL, SENDER, 0x04, 0x10, "SpawnEntityPainting");
|
||||
public static final PacketType NAMED_ENTITY_SPAWN = new PacketType(PROTOCOL, SENDER, 0x05, 0x0C, "NamedEntitySpawn");
|
||||
public static final PacketType ANIMATION = new PacketType(PROTOCOL, SENDER, 0x06, 0x0B, "Animation");
|
||||
public static final PacketType STATISTIC = new PacketType(PROTOCOL, SENDER, 0x07, 0x37, "Statistic");
|
||||
public static final PacketType BLOCK_BREAK_ANIMATION = new PacketType(PROTOCOL, SENDER, 0x08, 0x25, "BlockBreakAnimation");
|
||||
public static final PacketType TILE_ENTITY_DATA = new PacketType(PROTOCOL, SENDER, 0x09, 0x35, "TileEntityData");
|
||||
public static final PacketType BLOCK_ACTION = new PacketType(PROTOCOL, SENDER, 0x0A, 0x24, "BlockAction");
|
||||
public static final PacketType BLOCK_CHANGE = new PacketType(PROTOCOL, SENDER, 0x0B, 0x23, "BlockChange");
|
||||
public static final PacketType BOSS = new PacketType(PROTOCOL, SENDER, 0x0C, 0xFF, "Boss");
|
||||
public static final PacketType SERVER_DIFFICULTY = new PacketType(PROTOCOL, SENDER, 0x0D, 0x41, "ServerDifficulty");
|
||||
public static final PacketType TAB_COMPLETE = new PacketType(PROTOCOL, SENDER, 0x0E, 0x3A, "TabComplete");
|
||||
public static final PacketType CHAT = new PacketType(PROTOCOL, SENDER, 0x0F, 0x02, "Chat");
|
||||
public static final PacketType MULTI_BLOCK_CHANGE = new PacketType(PROTOCOL, SENDER, 0x10, 0x22, "MultiBlockChange");
|
||||
public static final PacketType TRANSACTION = new PacketType(PROTOCOL, SENDER, 0x11, 0x32, "Transaction");
|
||||
public static final PacketType CLOSE_WINDOW = new PacketType(PROTOCOL, SENDER, 0x12, 0x2E, "CloseWindow");
|
||||
public static final PacketType OPEN_WINDOW = new PacketType(PROTOCOL, SENDER, 0x13, 0x2D, "OpenWindow");
|
||||
public static final PacketType WINDOW_ITEMS = new PacketType(PROTOCOL, SENDER, 0x14, 0x30, "WindowItems");
|
||||
public static final PacketType WINDOW_DATA = new PacketType(PROTOCOL, SENDER, 0x15, 0x31, "WindowData");
|
||||
public static final PacketType SET_SLOT = new PacketType(PROTOCOL, SENDER, 0x16, 0x2F, "SetSlot");
|
||||
public static final PacketType SET_COOLDOWN = new PacketType(PROTOCOL, SENDER, 0x17, 0xFC, "SetCooldown");
|
||||
public static final PacketType CUSTOM_PAYLOAD = new PacketType(PROTOCOL, SENDER, 0x18, 0x3F, "CustomPayload");
|
||||
public static final PacketType CUSTOM_SOUND_EFFECT = new PacketType(PROTOCOL, SENDER, 0x19, 0xFD, "CustomSoundEffect");
|
||||
public static final PacketType KICK_DISCONNECT = new PacketType(PROTOCOL, SENDER, 0x1A, 0x40, "KickDisconnect");
|
||||
public static final PacketType ENTITY_STATUS = new PacketType(PROTOCOL, SENDER, 0x1B, 0x1A, "EntityStatus");
|
||||
public static final PacketType EXPLOSION = new PacketType(PROTOCOL, SENDER, 0x1C, 0x27, "Explosion");
|
||||
public static final PacketType UNLOAD_CHUNK = new PacketType(PROTOCOL, SENDER, 0x1D, 0xFA, "UnloadChunk");
|
||||
public static final PacketType GAME_STATE_CHANGE = new PacketType(PROTOCOL, SENDER, 0x1E, 0x2B, "GameStateChange");
|
||||
public static final PacketType KEEP_ALIVE = new PacketType(PROTOCOL, SENDER, 0x1F, 0x00, "KeepAlive");
|
||||
public static final PacketType MAP_CHUNK = new PacketType(PROTOCOL, SENDER, 0x20, 0x21, "MapChunk");
|
||||
public static final PacketType WORLD_EVENT = new PacketType(PROTOCOL, SENDER, 0x21, 0x28, "WorldEvent");
|
||||
public static final PacketType WORLD_PARTICLES = new PacketType(PROTOCOL, SENDER, 0x22, 0x2A, "WorldParticles");
|
||||
public static final PacketType LOGIN = new PacketType(PROTOCOL, SENDER, 0x23, 0x01, "Login");
|
||||
public static final PacketType MAP = new PacketType(PROTOCOL, SENDER, 0x24, 0x34, "Map");
|
||||
public static final PacketType REL_ENTITY_MOVE = new PacketType(PROTOCOL, SENDER, 0x25, 0x15, "RelEntityMove");
|
||||
public static final PacketType REL_ENTITY_MOVE_LOOK = new PacketType(PROTOCOL, SENDER, 0x26, 0x17, "RelEntityMoveLook");
|
||||
public static final PacketType ENTITY_LOOK = new PacketType(PROTOCOL, SENDER, 0x27, 0x16, "EntityLook");
|
||||
public static final PacketType ENTITY = new PacketType(PROTOCOL, SENDER, 0x28, 0x14, "Entity");
|
||||
public static final PacketType VEHICLE_MOVE = new PacketType(PROTOCOL, SENDER, 0x29, 0xFE, "VehicleMove");
|
||||
public static final PacketType OPEN_SIGN_EDITOR = new PacketType(PROTOCOL, SENDER, 0x2A, 0x36, "OpenSignEditor");
|
||||
public static final PacketType ABILITIES = new PacketType(PROTOCOL, SENDER, 0x2B, 0x39, "Abilities");
|
||||
public static final PacketType COMBAT_EVENT = new PacketType(PROTOCOL, SENDER, 0x2C, 0x42, "CombatEvent");
|
||||
public static final PacketType PLAYER_INFO = new PacketType(PROTOCOL, SENDER, 0x2D, 0x38, "PlayerInfo");
|
||||
public static final PacketType POSITION = new PacketType(PROTOCOL, SENDER, 0x2E, 0x08, "Position");
|
||||
public static final PacketType BED = new PacketType(PROTOCOL, SENDER, 0x2F, 0x0A, "Bed");
|
||||
public static final PacketType ENTITY_DESTROY = new PacketType(PROTOCOL, SENDER, 0x30, 0x13, "EntityDestroy");
|
||||
public static final PacketType REMOVE_ENTITY_EFFECT = new PacketType(PROTOCOL, SENDER, 0x31, 0x1E, "RemoveEntityEffect");
|
||||
public static final PacketType RESOURCE_PACK_SEND = new PacketType(PROTOCOL, SENDER, 0x32, 0x48, "ResourcePackSend");
|
||||
public static final PacketType RESPAWN = new PacketType(PROTOCOL, SENDER, 0x33, 0x07, "Respawn");
|
||||
public static final PacketType ENTITY_HEAD_ROTATION = new PacketType(PROTOCOL, SENDER, 0x34, 0x19, "EntityHeadRotation");
|
||||
public static final PacketType WORLD_BORDER = new PacketType(PROTOCOL, SENDER, 0x35, 0x44, "WorldBorder");
|
||||
public static final PacketType CAMERA = new PacketType(PROTOCOL, SENDER, 0x36, 0x43, "Camera");
|
||||
public static final PacketType HELD_ITEM_SLOT = new PacketType(PROTOCOL, SENDER, 0x37, 0x09, "HeldItemSlot");
|
||||
public static final PacketType SCOREBOARD_DISPLAY_OBJECTIVE = new PacketType(PROTOCOL, SENDER, 0x38, 0x3D, "ScoreboardDisplayObjective");
|
||||
public static final PacketType ENTITY_METADATA = new PacketType(PROTOCOL, SENDER, 0x39, 0x1C, "EntityMetadata");
|
||||
public static final PacketType ATTACH_ENTITY = new PacketType(PROTOCOL, SENDER, 0x3A, 0x1B, "AttachEntity");
|
||||
public static final PacketType ENTITY_VELOCITY = new PacketType(PROTOCOL, SENDER, 0x3B, 0x12, "EntityVelocity");
|
||||
public static final PacketType ENTITY_EQUIPMENT = new PacketType(PROTOCOL, SENDER, 0x3C, 0x04, "EntityEquipment");
|
||||
public static final PacketType EXPERIENCE = new PacketType(PROTOCOL, SENDER, 0x3D, 0x1F, "Experience");
|
||||
public static final PacketType UPDATE_HEALTH = new PacketType(PROTOCOL, SENDER, 0x3E, 0x06, "UpdateHealth");
|
||||
public static final PacketType SCOREBOARD_OBJECTIVE = new PacketType(PROTOCOL, SENDER, 0x3F, 0x3B, "ScoreboardObjective");
|
||||
public static final PacketType MOUNT = new PacketType(PROTOCOL, SENDER, 0x40, 0xFB, "Mount");
|
||||
public static final PacketType SCOREBOARD_TEAM = new PacketType(PROTOCOL, SENDER, 0x41, 0x3E, "ScoreboardTeam");
|
||||
public static final PacketType SCOREBOARD_SCORE = new PacketType(PROTOCOL, SENDER, 0x42, 0x3C, "ScoreboardScore");
|
||||
public static final PacketType SPAWN_POSITION = new PacketType(PROTOCOL, SENDER, 0x43, 0x05, "SpawnPosition");
|
||||
public static final PacketType UPDATE_TIME = new PacketType(PROTOCOL, SENDER, 0x44, 0x03, "UpdateTime");
|
||||
public static final PacketType TITLE = new PacketType(PROTOCOL, SENDER, 0x45, 0x45, "Title");
|
||||
public static final PacketType NAMED_SOUND_EFFECT = new PacketType(PROTOCOL, SENDER, 0x46, 0x47, "NamedSoundEffect");
|
||||
public static final PacketType PLAYER_LIST_HEADER_FOOTER = new PacketType(PROTOCOL, SENDER, 0x47, 0x48, "PlayerListHeaderFooter");
|
||||
public static final PacketType COLLECT = new PacketType(PROTOCOL, SENDER, 0x48, 0x49, "Collect");
|
||||
public static final PacketType ENTITY_TELEPORT = new PacketType(PROTOCOL, SENDER, 0x49, 0x4A, "EntityTeleport");
|
||||
public static final PacketType UPDATE_ATTRIBUTES = new PacketType(PROTOCOL, SENDER, 0x4A, 0x4B, "UpdateAttributes");
|
||||
public static final PacketType ENTITY_EFFECT = new PacketType(PROTOCOL, SENDER, 0x4B, 0x4C, "EntityEffect");
|
||||
|
||||
// ---- Removed in 1.9
|
||||
|
||||
/**
|
||||
* @deprecated Removed in 1.9
|
||||
*/
|
||||
@Deprecated
|
||||
public static final PacketType MAP_CHUNK_BULK = new PacketType(PROTOCOL, SENDER, 255, 255, "MapChunkBulk").deprecatedIn(MinecraftVersion.COMBAT_UPDATE);
|
||||
|
||||
/**
|
||||
* @deprecated Removed in 1.9
|
||||
*/
|
||||
@Deprecated
|
||||
public static final PacketType SET_COMPRESSION = new PacketType(PROTOCOL, SENDER, 254, 254, "SetCompression").deprecatedIn(MinecraftVersion.COMBAT_UPDATE);
|
||||
|
||||
/**
|
||||
* @deprecated Removed in 1.9
|
||||
*/
|
||||
@Deprecated
|
||||
public static final PacketType UPDATE_ENTITY_NBT = new PacketType(PROTOCOL, SENDER, 253, 253, "UpdateEntityNBT").deprecatedIn(MinecraftVersion.COMBAT_UPDATE);
|
||||
|
||||
// ----- Renamed packets
|
||||
|
||||
/**
|
||||
* @deprecated Renamed to {@link WINDOW_DATA}
|
||||
*/
|
||||
@Deprecated
|
||||
public static final PacketType CRAFT_PROGRESS_BAR = WINDOW_DATA.deprecated();
|
||||
|
||||
/**
|
||||
* @deprecated Renamed to {@link REL_ENTITY_MOVE_LOOK}
|
||||
*/
|
||||
@Deprecated
|
||||
public static final PacketType ENTITY_MOVE_LOOK = REL_ENTITY_MOVE_LOOK.deprecated();
|
||||
|
||||
/**
|
||||
* @deprecated Renamed to {@link STATISTIC}
|
||||
*/
|
||||
@Deprecated
|
||||
public static final PacketType STATISTICS = STATISTIC.deprecated();
|
||||
|
||||
/**
|
||||
* @deprecated Renamed to {@link OPEN_SIGN_EDITOR}
|
||||
*/
|
||||
@Deprecated
|
||||
public static final PacketType OPEN_SIGN_ENTITY = OPEN_SIGN_EDITOR.deprecated();
|
||||
|
||||
// ----- Replaced in 1.9.4
|
||||
|
||||
/**
|
||||
* @deprecated Replaced by {@link TILE_ENTITY_DATA}
|
||||
*/
|
||||
@Deprecated
|
||||
public static final PacketType UPDATE_SIGN = MinecraftReflection.signUpdateExists() ? new PacketType(PROTOCOL, SENDER, 252, 252, "UpdateSign") :
|
||||
TILE_ENTITY_DATA.deprecated();
|
||||
|
||||
// The instance must
|
||||
private final static Server INSTANCE = new Server();
|
||||
|
||||
// Prevent accidental construction
|
||||
@@ -215,32 +258,36 @@ public class PacketType implements Serializable, Comparable<PacketType> {
|
||||
public static class Client extends ObjectEnum<PacketType> {
|
||||
private final static Sender SENDER = Sender.CLIENT;
|
||||
|
||||
public static final PacketType KEEP_ALIVE = new PacketType(PROTOCOL, SENDER, 0x00, 0, "KeepAlive");
|
||||
public static final PacketType CHAT = new PacketType(PROTOCOL, SENDER, 0x01, 3, "Chat");
|
||||
public static final PacketType USE_ENTITY = new PacketType(PROTOCOL, SENDER, 0x02, 7, "UseEntity");
|
||||
public static final PacketType FLYING = new PacketType(PROTOCOL, SENDER, 0x03, 10, "Flying");
|
||||
public static final PacketType POSITION = new PacketType(PROTOCOL, SENDER, 0x04, 11, "Position");
|
||||
public static final PacketType LOOK = new PacketType(PROTOCOL, SENDER, 0x05, 12, "Look");
|
||||
public static final PacketType POSITION_LOOK = new PacketType(PROTOCOL, SENDER, 0x06, 13, "PositionLook");
|
||||
public static final PacketType BLOCK_DIG = new PacketType(PROTOCOL, SENDER, 0x07, 14, "BlockDig");
|
||||
public static final PacketType BLOCK_PLACE = new PacketType(PROTOCOL, SENDER, 0x08, 15, "BlockPlace");
|
||||
public static final PacketType HELD_ITEM_SLOT = new PacketType(PROTOCOL, SENDER, 0x09, 16, "HeldItemSlot");
|
||||
public static final PacketType ARM_ANIMATION = new PacketType(PROTOCOL, SENDER, 0x0A, 18, "ArmAnimation");
|
||||
public static final PacketType ENTITY_ACTION = new PacketType(PROTOCOL, SENDER, 0x0B, 19, "EntityAction");
|
||||
public static final PacketType STEER_VEHICLE = new PacketType(PROTOCOL, SENDER, 0x0C, 27, "SteerVehicle");
|
||||
public static final PacketType CLOSE_WINDOW = new PacketType(PROTOCOL, SENDER, 0x0D, 101, "CloseWindow");
|
||||
public static final PacketType WINDOW_CLICK = new PacketType(PROTOCOL, SENDER, 0x0E, 102, "WindowClick");
|
||||
public static final PacketType TRANSACTION = new PacketType(PROTOCOL, SENDER, 0x0F, 106, "Transaction");
|
||||
public static final PacketType SET_CREATIVE_SLOT = new PacketType(PROTOCOL, SENDER, 0x10, 107, "SetCreativeSlot");
|
||||
public static final PacketType ENCHANT_ITEM = new PacketType(PROTOCOL, SENDER, 0x11, 108, "EnchantItem");
|
||||
public static final PacketType UPDATE_SIGN = new PacketType(PROTOCOL, SENDER, 0x12, 130, "UpdateSign");
|
||||
public static final PacketType ABILITIES = new PacketType(PROTOCOL, SENDER, 0x13, 202, "Abilities");
|
||||
public static final PacketType TAB_COMPLETE = new PacketType(PROTOCOL, SENDER, 0x14, 203, "TabComplete");
|
||||
public static final PacketType SETTINGS = new PacketType(PROTOCOL, SENDER, 0x15, 204, "Settings");
|
||||
public static final PacketType CLIENT_COMMAND = new PacketType(PROTOCOL, SENDER, 0x16, 205, "ClientCommand");
|
||||
public static final PacketType CUSTOM_PAYLOAD = new PacketType(PROTOCOL, SENDER, 0x17, 250, "CustomPayload");
|
||||
public static final PacketType SPECTATE = new PacketType(PROTOCOL, SENDER, 0x18, -1, "Spectate");
|
||||
public static final PacketType RESOURCE_PACK_STATUS = new PacketType(PROTOCOL, SENDER, 0x19, -1, "ResourcePackStatus");
|
||||
public static final PacketType TELEPORT_ACCEPT = new PacketType(PROTOCOL, SENDER, 0x00, 0xF9, "TeleportAccept");
|
||||
public static final PacketType TAB_COMPLETE = new PacketType(PROTOCOL, SENDER, 0x01, 0x14, "TabComplete");
|
||||
public static final PacketType CHAT = new PacketType(PROTOCOL, SENDER, 0x02, 0x01, "Chat");
|
||||
public static final PacketType CLIENT_COMMAND = new PacketType(PROTOCOL, SENDER, 0x03, 0x16, "ClientCommand");
|
||||
public static final PacketType SETTINGS = new PacketType(PROTOCOL, SENDER, 0x04, 0x15, "Settings");
|
||||
public static final PacketType TRANSACTION = new PacketType(PROTOCOL, SENDER, 0x05, 0x0F, "Transaction");
|
||||
public static final PacketType ENCHANT_ITEM = new PacketType(PROTOCOL, SENDER, 0x06, 0x11, "EnchantItem");
|
||||
public static final PacketType WINDOW_CLICK = new PacketType(PROTOCOL, SENDER, 0x07, 0x0E, "WindowClick");
|
||||
public static final PacketType CLOSE_WINDOW = new PacketType(PROTOCOL, SENDER, 0x08, 0x0D, "CloseWindow");
|
||||
public static final PacketType CUSTOM_PAYLOAD = new PacketType(PROTOCOL, SENDER, 0x09, 0x17, "CustomPayload");
|
||||
public static final PacketType USE_ENTITY = new PacketType(PROTOCOL, SENDER, 0x0A, 0x02, "UseEntity");
|
||||
public static final PacketType KEEP_ALIVE = new PacketType(PROTOCOL, SENDER, 0x0B, 0x00, "KeepAlive");
|
||||
public static final PacketType POSITION = new PacketType(PROTOCOL, SENDER, 0x0C, 0x04, "Position");
|
||||
public static final PacketType POSITION_LOOK = new PacketType(PROTOCOL, SENDER, 0x0D, 0x06, "PositionLook");
|
||||
public static final PacketType LOOK = new PacketType(PROTOCOL, SENDER, 0x0E, 0x05, "Look");
|
||||
public static final PacketType FLYING = new PacketType(PROTOCOL, SENDER, 0x0F, 0x03, "Flying");
|
||||
public static final PacketType VEHICLE_MOVE = new PacketType(PROTOCOL, SENDER, 0x10, 0xF8, "VehicleMove");
|
||||
public static final PacketType BOAT_MOVE = new PacketType(PROTOCOL, SENDER, 0x11, 0xF7, "BoatMove");
|
||||
public static final PacketType ABILITIES = new PacketType(PROTOCOL, SENDER, 0x12, 0x13, "Abilities");
|
||||
public static final PacketType BLOCK_DIG = new PacketType(PROTOCOL, SENDER, 0x13, 0x07, "BlockDig");
|
||||
public static final PacketType ENTITY_ACTION = new PacketType(PROTOCOL, SENDER, 0x14, 0x0B, "EntityAction");
|
||||
public static final PacketType STEER_VEHICLE = new PacketType(PROTOCOL, SENDER, 0x15, 0x0C, "SteerVehicle");
|
||||
public static final PacketType RESOURCE_PACK_STATUS = new PacketType(PROTOCOL, SENDER, 0x16, 0x19, "ResourcePackStatus");
|
||||
public static final PacketType HELD_ITEM_SLOT = new PacketType(PROTOCOL, SENDER, 0x17, 0x09, "HeldItemSlot");
|
||||
public static final PacketType SET_CREATIVE_SLOT = new PacketType(PROTOCOL, SENDER, 0x18, 0x10, "SetCreativeSlot");
|
||||
public static final PacketType UPDATE_SIGN = new PacketType(PROTOCOL, SENDER, 0x19, 0x12, "UpdateSign");
|
||||
public static final PacketType ARM_ANIMATION = new PacketType(PROTOCOL, SENDER, 0x1A, 0x0A, "ArmAnimation");
|
||||
public static final PacketType SPECTATE = new PacketType(PROTOCOL, SENDER, 0x1B, 0x18, "Spectate");
|
||||
public static final PacketType USE_ITEM = new PacketType(PROTOCOL, SENDER, 0x1C, 0xF6, "UseItem");
|
||||
public static final PacketType BLOCK_PLACE = new PacketType(PROTOCOL, SENDER, 0x1D, 0x08, "BlockPlace");
|
||||
|
||||
private final static Client INSTANCE = new Client();
|
||||
|
||||
@@ -274,8 +321,14 @@ public class PacketType implements Serializable, Comparable<PacketType> {
|
||||
public static class Server extends ObjectEnum<PacketType> {
|
||||
private final static Sender SENDER = Sender.SERVER;
|
||||
|
||||
public static final PacketType OUT_SERVER_INFO = new PacketType(PROTOCOL, SENDER, 0x00, 255, "ServerInfo").forceAsync(true);
|
||||
public static final PacketType OUT_PING = new PacketType(PROTOCOL, SENDER, 0x01, 230, "Pong");
|
||||
public static final PacketType SERVER_INFO = new PacketType(PROTOCOL, SENDER, 0x00, 0x00, "ServerInfo").forceAsync(true);
|
||||
public static final PacketType PONG = new PacketType(PROTOCOL, SENDER, 0x01, 0x01, "Pong");
|
||||
|
||||
/**
|
||||
* @deprecated Replaced by {@link SERVER_INFO}
|
||||
*/
|
||||
@Deprecated
|
||||
public static final PacketType OUT_SERVER_INFO = SERVER_INFO.deprecated();
|
||||
|
||||
private final static Server INSTANCE = new Server();
|
||||
|
||||
@@ -297,8 +350,8 @@ public class PacketType implements Serializable, Comparable<PacketType> {
|
||||
public static class Client extends ObjectEnum<PacketType> {
|
||||
private final static Sender SENDER = Sender.CLIENT;
|
||||
|
||||
public static final PacketType IN_START = new PacketType(PROTOCOL, SENDER, 0x00, 254, "Start");
|
||||
public static final PacketType IN_PING = new PacketType(PROTOCOL, SENDER, 0x01, 230, "Ping");
|
||||
public static final PacketType START = new PacketType(PROTOCOL, SENDER, 0x00, 0x00, "Start");
|
||||
public static final PacketType PING = new PacketType(PROTOCOL, SENDER, 0x01, 0x01, "Ping");
|
||||
|
||||
private final static Client INSTANCE = new Client();
|
||||
|
||||
@@ -332,10 +385,10 @@ public class PacketType implements Serializable, Comparable<PacketType> {
|
||||
public static class Server extends ObjectEnum<PacketType> {
|
||||
private final static Sender SENDER = Sender.SERVER;
|
||||
|
||||
public static final PacketType DISCONNECT = new PacketType(PROTOCOL, SENDER, 0x00, 255, "Disconnect");
|
||||
public static final PacketType ENCRYPTION_BEGIN = new PacketType(PROTOCOL, SENDER, 0x01, 253, "EncryptionBegin");
|
||||
public static final PacketType SUCCESS = new PacketType(PROTOCOL, SENDER, 0x02, 232, "Success");
|
||||
public static final PacketType SET_COMPRESSION = new PacketType(PROTOCOL, SENDER, 0x03, -1, "SetCompression");
|
||||
public static final PacketType DISCONNECT = new PacketType(PROTOCOL, SENDER, 0x00, 0x00, "Disconnect");
|
||||
public static final PacketType ENCRYPTION_BEGIN = new PacketType(PROTOCOL, SENDER, 0x01, 0x01, "EncryptionBegin");
|
||||
public static final PacketType SUCCESS = new PacketType(PROTOCOL, SENDER, 0x02, 0x02, "Success");
|
||||
public static final PacketType SET_COMPRESSION = new PacketType(PROTOCOL, SENDER, 0x03, 0x03, "SetCompression");
|
||||
|
||||
private final static Server INSTANCE = new Server();
|
||||
|
||||
@@ -357,8 +410,8 @@ public class PacketType implements Serializable, Comparable<PacketType> {
|
||||
public static class Client extends ObjectEnum<PacketType> {
|
||||
private final static Sender SENDER = Sender.CLIENT;
|
||||
|
||||
public static final PacketType START = new PacketType(PROTOCOL, SENDER, 0x00, 231, "Start");
|
||||
public static final PacketType ENCRYPTION_BEGIN = new PacketType(PROTOCOL, SENDER, 0x01, 252, "EncryptionBegin");
|
||||
public static final PacketType START = new PacketType(PROTOCOL, SENDER, 0x00, 0x00, "Start");
|
||||
public static final PacketType ENCRYPTION_BEGIN = new PacketType(PROTOCOL, SENDER, 0x01, 0x01, "EncryptionBegin");
|
||||
|
||||
private final static Client INSTANCE = new Client();
|
||||
|
||||
@@ -490,7 +543,7 @@ public class PacketType implements Serializable, Comparable<PacketType> {
|
||||
}
|
||||
|
||||
public String getPacketName() {
|
||||
return WordUtils.capitalize(name().toLowerCase());
|
||||
return WordUtils.capitalize(name().toLowerCase(Locale.ENGLISH));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -529,7 +582,7 @@ public class PacketType implements Serializable, Comparable<PacketType> {
|
||||
/**
|
||||
* Protocol version of all the current IDs.
|
||||
*/
|
||||
private static final MinecraftVersion PROTOCOL_VERSION = MinecraftVersion.BOUNTIFUL_UPDATE;
|
||||
private static final MinecraftVersion PROTOCOL_VERSION = MinecraftVersion.EXPLORATION_UPDATE;
|
||||
|
||||
private final Protocol protocol;
|
||||
private final Sender sender;
|
||||
@@ -540,6 +593,7 @@ public class PacketType implements Serializable, Comparable<PacketType> {
|
||||
|
||||
private boolean forceAsync;
|
||||
private boolean dynamic;
|
||||
private boolean deprecated;
|
||||
|
||||
/**
|
||||
* Retrieve the current packet/legacy lookup.
|
||||
@@ -661,11 +715,11 @@ public class PacketType implements Serializable, Comparable<PacketType> {
|
||||
}
|
||||
}
|
||||
|
||||
private static String format(Protocol protocol, Sender sender, String name) {
|
||||
public static String format(Protocol protocol, Sender sender, String name) {
|
||||
if (name.contains("Packet"))
|
||||
return name;
|
||||
|
||||
return String.format("Packet%s%s%s", protocol.getPacketName(), sender.getPacketName(), name);
|
||||
return String.format("Packet%s%s%s", protocol.getPacketName(), sender.getPacketName(), WordUtils.capitalize(name));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -743,24 +797,11 @@ public class PacketType implements Serializable, Comparable<PacketType> {
|
||||
Map<String, PacketType> map = lookup.getMap(protocol, sender);
|
||||
|
||||
// Check the map first
|
||||
String className = packetClass.getSimpleName();
|
||||
PacketType type = map.get(className);
|
||||
String clazz = packetClass.getSimpleName();
|
||||
PacketType type = find(map, clazz);
|
||||
if (type == null) {
|
||||
// Then check any aliases
|
||||
for (PacketType check : map.values()) {
|
||||
String[] aliases = check.getClassNames();
|
||||
if (aliases.length > 1) {
|
||||
for (String alias : aliases) {
|
||||
if (alias.equals(className)) {
|
||||
// We have a match!
|
||||
type = check;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Guess we don't support this packet :/
|
||||
type = new PacketType(protocol, sender, packetId, -1, PROTOCOL_VERSION, className);
|
||||
type = new PacketType(protocol, sender, packetId, -1, PROTOCOL_VERSION, clazz);
|
||||
type.dynamic = true;
|
||||
|
||||
// Many may be scheduled, but only the first will be executed
|
||||
@@ -770,6 +811,28 @@ public class PacketType implements Serializable, Comparable<PacketType> {
|
||||
return type;
|
||||
}
|
||||
|
||||
private static PacketType find(Map<String, PacketType> map, String clazz) {
|
||||
PacketType ret = map.get(clazz);
|
||||
if (ret != null) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Check any aliases
|
||||
for (PacketType check : map.values()) {
|
||||
String[] aliases = check.getClassNames();
|
||||
if (aliases.length > 1) {
|
||||
for (String alias : aliases) {
|
||||
if (alias.equals(clazz)) {
|
||||
// We have a match!
|
||||
return check;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup a packet type from a packet class.
|
||||
* @param packetClass - the packet class.
|
||||
@@ -829,7 +892,7 @@ public class PacketType implements Serializable, Comparable<PacketType> {
|
||||
};
|
||||
|
||||
// Execute in the main thread if possible
|
||||
if (Bukkit.getServer() == null || Application.isPrimaryThread()) {
|
||||
if (Bukkit.getServer() == null || Bukkit.isPrimaryThread()) {
|
||||
try {
|
||||
return Futures.immediateFuture(callable.call());
|
||||
} catch (Exception e) {
|
||||
@@ -891,6 +954,7 @@ public class PacketType implements Serializable, Comparable<PacketType> {
|
||||
for (int i = 0; i < classNames.length; i++) {
|
||||
classNames[i] = format(protocol, sender, names[i]);
|
||||
}
|
||||
//System.out.println(Arrays.toString(classNames));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1020,6 +1084,24 @@ public class PacketType implements Serializable, Comparable<PacketType> {
|
||||
return forceAsync;
|
||||
}
|
||||
|
||||
private PacketType deprecatedIn(MinecraftVersion version) {
|
||||
try {
|
||||
return MinecraftVersion.getCurrentVersion().isAtLeast(version) ? deprecated() : this;
|
||||
} catch (Throwable ex) {
|
||||
return deprecated();
|
||||
}
|
||||
}
|
||||
|
||||
private PacketType deprecated() {
|
||||
PacketType ret = clone();
|
||||
ret.deprecated = true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
public boolean isDeprecated() {
|
||||
return deprecated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(protocol, sender, currentId, legacyId);
|
||||
@@ -1055,8 +1137,17 @@ public class PacketType implements Serializable, Comparable<PacketType> {
|
||||
Class<?> clazz = getPacketClass();
|
||||
|
||||
if (clazz == null)
|
||||
return "UNREGISTERED[" + protocol + ", " + sender + ", " + currentId + ", legacy: " + legacyId + ", classNames: " + Arrays.toString(classNames) + "]";
|
||||
return name() + "[" + protocol + ", " + sender + ", " + currentId + ", legacy: " + legacyId + ", classNames: " + Arrays.toString(classNames) + " (unregistered)]";
|
||||
else
|
||||
return clazz.getSimpleName() + "[" + currentId + ", legacy: " + legacyId + "]";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketType clone() {
|
||||
try {
|
||||
return (PacketType) super.clone();
|
||||
} catch (CloneNotSupportedException ex) {
|
||||
throw new Error("This shouldn't happen", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
File renamed without changes.
+2
-48
@@ -17,10 +17,6 @@
|
||||
|
||||
package com.comphenix.protocol;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import com.comphenix.protocol.injector.PacketFilterManager;
|
||||
import com.comphenix.protocol.reflect.FieldAccessException;
|
||||
import com.comphenix.protocol.reflect.IntEnum;
|
||||
|
||||
/**
|
||||
@@ -165,30 +161,7 @@ public final class Packets {
|
||||
public static Server getRegistry() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given packet is a valid server packet in the current version of Minecraft.
|
||||
* <p>
|
||||
* Use {@link PacketType#isSupported()} instead.
|
||||
* @param packetID - the packet to test.
|
||||
* @return TRUE if this packet is supported, FALSE otherwise.
|
||||
* @throws FieldAccessException If we're unable to retrieve the server packet data from Minecraft.
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean isSupported(int packetID) throws FieldAccessException {
|
||||
return PacketFilterManager.getServerPackets().contains(packetID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve every client packet the current version of Minecraft is aware of.
|
||||
* @return Every supported server packet.
|
||||
* @throws FieldAccessException If we're unable to retrieve the server packet data from Minecraft.
|
||||
*/
|
||||
@Deprecated
|
||||
public static Set<Integer> getSupported() throws FieldAccessException {
|
||||
return PacketFilterManager.getServerPackets();
|
||||
}
|
||||
|
||||
|
||||
// We only allow a single instance of this class
|
||||
private Server() {
|
||||
super();
|
||||
@@ -262,26 +235,7 @@ public final class Packets {
|
||||
public static Client getRegistry() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given packet is a valid client packet in the current version of Minecraft.
|
||||
* @param packetID - the packet to test.
|
||||
* @return TRUE if this packet is supported, FALSE otherwise.
|
||||
* @throws FieldAccessException If we're unable to retrieve the client packet data from Minecraft.
|
||||
*/
|
||||
public static boolean isSupported(int packetID) throws FieldAccessException {
|
||||
return PacketFilterManager.getClientPackets().contains(packetID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve every client packet the current version of Minecraft is aware of.
|
||||
* @return Every supported client packet.
|
||||
* @throws FieldAccessException If we're unable to retrieve the client packet data from Minecraft.
|
||||
*/
|
||||
public static Set<Integer> getSupported() throws FieldAccessException {
|
||||
return PacketFilterManager.getClientPackets();
|
||||
}
|
||||
|
||||
|
||||
// Like above
|
||||
private Client() {
|
||||
super();
|
||||
+8
-4
@@ -20,12 +20,13 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.bukkit.configuration.Configuration;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import com.comphenix.protocol.injector.PacketFilterManager.PlayerInjectHooks;
|
||||
import com.comphenix.protocol.injector.PlayerInjectHooks;
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Lists;
|
||||
@@ -157,6 +158,9 @@ public class ProtocolConfig {
|
||||
}
|
||||
if (global != null) {
|
||||
updater = global.getConfigurationSection(SECTION_AUTOUPDATER);
|
||||
if (updater.getValues(true).isEmpty()) {
|
||||
plugin.getLogger().warning("Updater section is missing, regenerate your config!");
|
||||
}
|
||||
}
|
||||
|
||||
// Automatically copy defaults
|
||||
@@ -256,7 +260,7 @@ public class ProtocolConfig {
|
||||
* @return TRUE if it should, FALSE otherwise.
|
||||
*/
|
||||
public boolean isAutoDownload() {
|
||||
return updater != null && getUpdaterValue(UPDATER_DOWNLAD, true);
|
||||
return updater != null && getUpdaterValue(UPDATER_DOWNLAD, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -461,7 +465,7 @@ public class ProtocolConfig {
|
||||
PlayerInjectHooks hook = getDefaultMethod();
|
||||
|
||||
if (text != null)
|
||||
hook = PlayerInjectHooks.valueOf(text.toUpperCase().replace(" ", "_"));
|
||||
hook = PlayerInjectHooks.valueOf(text.toUpperCase(Locale.ENGLISH).replace(" ", "_"));
|
||||
return hook;
|
||||
}
|
||||
|
||||
@@ -497,4 +501,4 @@ public class ProtocolConfig {
|
||||
valuesChanged = false;
|
||||
configChanged = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2016 dmulloy2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program;
|
||||
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
* 02111-1307 USA
|
||||
*/
|
||||
package com.comphenix.protocol;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import com.comphenix.protocol.error.BasicErrorReporter;
|
||||
import com.comphenix.protocol.error.ErrorReporter;
|
||||
import com.google.common.util.concurrent.ListeningScheduledExecutorService;
|
||||
|
||||
/**
|
||||
* The main entry point for ProtocolLib.
|
||||
* @author dmulloy2
|
||||
*/
|
||||
public class ProtocolLibrary {
|
||||
/**
|
||||
* The minimum version ProtocolLib has been tested with.
|
||||
*/
|
||||
public static final String MINIMUM_MINECRAFT_VERSION = "1.8";
|
||||
|
||||
/**
|
||||
* The maximum version ProtocolLib has been tested with.
|
||||
*/
|
||||
public static final String MAXIMUM_MINECRAFT_VERSION = "1.11.2";
|
||||
|
||||
/**
|
||||
* The date (with ISO 8601 or YYYY-MM-DD) when the most recent version (1.11) was released.
|
||||
*/
|
||||
public static final String MINECRAFT_LAST_RELEASE_DATE = "2016-12-21";
|
||||
|
||||
/**
|
||||
* Plugins that are currently incompatible with ProtocolLib.
|
||||
*/
|
||||
public static final List<String> INCOMPATIBLE = Arrays.asList("TagAPI");
|
||||
|
||||
private static Plugin plugin;
|
||||
private static ProtocolConfig config;
|
||||
private static ProtocolManager manager;
|
||||
private static ErrorReporter reporter = new BasicErrorReporter();
|
||||
|
||||
private static ListeningScheduledExecutorService executorAsync;
|
||||
private static ListeningScheduledExecutorService executorSync;
|
||||
|
||||
private static boolean updatesDisabled;
|
||||
private static boolean initialized;
|
||||
|
||||
protected static void init(Plugin plugin, ProtocolConfig config, ProtocolManager manager, ErrorReporter reporter,
|
||||
ListeningScheduledExecutorService executorAsync, ListeningScheduledExecutorService executorSync) {
|
||||
Validate.isTrue(!initialized, "ProtocolLib has already been initialized.");
|
||||
ProtocolLibrary.plugin = plugin;
|
||||
ProtocolLibrary.config = config;
|
||||
ProtocolLibrary.manager = manager;
|
||||
ProtocolLibrary.reporter = reporter;
|
||||
ProtocolLibrary.executorAsync = executorAsync;
|
||||
ProtocolLibrary.executorSync = executorSync;
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ProtocolLib plugin instance.
|
||||
* @return The plugin instance
|
||||
*/
|
||||
public static Plugin getPlugin() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets ProtocolLib's configuration
|
||||
* @return The config
|
||||
*/
|
||||
public static ProtocolConfig getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the packet protocol manager.
|
||||
* @return Packet protocol manager
|
||||
*/
|
||||
public static ProtocolManager getProtocolManager() {
|
||||
return manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the current error reporter.
|
||||
* @return Current error reporter.
|
||||
*/
|
||||
public static ErrorReporter getErrorReporter() {
|
||||
return reporter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve an executor service for performing asynchronous tasks on the behalf of ProtocolLib.
|
||||
* <p>
|
||||
* Note that this service is NULL if ProtocolLib has not been initialized yet.
|
||||
* @return The executor service, or NULL.
|
||||
*/
|
||||
public static ListeningScheduledExecutorService getExecutorAsync() {
|
||||
return executorAsync;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve an executor service for performing synchronous tasks (main thread) on the behalf of ProtocolLib.
|
||||
* <p>
|
||||
* Note that this service is NULL if ProtocolLib has not been initialized yet.
|
||||
* @return The executor service, or NULL.
|
||||
*/
|
||||
public static ListeningScheduledExecutorService getExecutorSync() {
|
||||
return executorSync;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables the ProtocolLib update checker.
|
||||
*/
|
||||
public static void disableUpdates() {
|
||||
updatesDisabled = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not updates are currently disabled.
|
||||
* @return True if it is, false if not
|
||||
*/
|
||||
public static boolean updatesDisabled() {
|
||||
return updatesDisabled;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2016 dmulloy2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program;
|
||||
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
* 02111-1307 USA
|
||||
*/
|
||||
package com.comphenix.protocol;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
/**
|
||||
* @author dmulloy2
|
||||
*/
|
||||
public class ProtocolLogger {
|
||||
private static Plugin plugin;
|
||||
|
||||
protected static void init(Plugin plugin) {
|
||||
ProtocolLogger.plugin = plugin;
|
||||
}
|
||||
|
||||
private static boolean isDebugEnabled() {
|
||||
try {
|
||||
return plugin.getConfig().getBoolean("global.debug", false);
|
||||
} catch (Throwable ex) { // Maybe we're testing or something
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs a message to console with a given level.
|
||||
* @param level Logging level
|
||||
* @param message Message to log
|
||||
* @param args Arguments to format in
|
||||
*/
|
||||
public static void log(Level level, String message, Object... args) {
|
||||
plugin.getLogger().log(level, MessageFormat.format(message, args));
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs a method to console with the INFO level.
|
||||
* @param message Message to log
|
||||
* @param args Arguments to format in
|
||||
*/
|
||||
public static void log(String message, Object... args) {
|
||||
log(Level.INFO, message, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs a message to console with a given level and exception.
|
||||
* @param level Logging level
|
||||
* @param message Message to log
|
||||
* @param ex Exception to log
|
||||
*/
|
||||
public static void log(Level level, String message, Throwable ex) {
|
||||
plugin.getLogger().log(level, message, ex);
|
||||
}
|
||||
|
||||
public static void debug(String message, Object... args) {
|
||||
if (isDebugEnabled()) {
|
||||
log("[Debug] " + message, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-1
@@ -29,6 +29,7 @@ import org.bukkit.plugin.Plugin;
|
||||
|
||||
import com.comphenix.protocol.async.AsyncMarker;
|
||||
import com.comphenix.protocol.events.ListenerPriority;
|
||||
import com.comphenix.protocol.events.ListeningWhitelist;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.events.PacketListener;
|
||||
import com.comphenix.protocol.injector.PacketConstructor;
|
||||
@@ -279,4 +280,6 @@ public interface ProtocolManager extends PacketStream {
|
||||
* @return Asynchronous packet manager.
|
||||
*/
|
||||
public AsynchronousManager getAsynchronousManager();
|
||||
}
|
||||
|
||||
public void verifyWhitelist(PacketListener listener, ListeningWhitelist whitelist);
|
||||
}
|
||||
+2
-3
@@ -35,7 +35,6 @@ import com.comphenix.protocol.error.ErrorReporter;
|
||||
import com.comphenix.protocol.events.ListeningWhitelist;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
import com.comphenix.protocol.events.PacketListener;
|
||||
import com.comphenix.protocol.injector.PacketFilterManager;
|
||||
import com.comphenix.protocol.injector.PrioritizedListener;
|
||||
import com.comphenix.protocol.injector.SortedPacketListenerList;
|
||||
import com.comphenix.protocol.injector.packet.PacketRegistry;
|
||||
@@ -181,11 +180,11 @@ public class AsyncFilterManager implements AsynchronousManager {
|
||||
|
||||
// Add listener to either or both processing queue
|
||||
if (hasValidWhitelist(sendingWhitelist)) {
|
||||
PacketFilterManager.verifyWhitelist(listener, sendingWhitelist);
|
||||
manager.verifyWhitelist(listener, sendingWhitelist);
|
||||
serverProcessingQueue.addListener(handler, sendingWhitelist);
|
||||
}
|
||||
if (hasValidWhitelist(receivingWhitelist)) {
|
||||
PacketFilterManager.verifyWhitelist(listener, receivingWhitelist);
|
||||
manager.verifyWhitelist(listener, receivingWhitelist);
|
||||
clientProcessingQueue.addListener(handler, receivingWhitelist);
|
||||
}
|
||||
|
||||
File renamed without changes.
+5
-3
@@ -28,7 +28,7 @@ import java.util.logging.Level;
|
||||
|
||||
import com.comphenix.protocol.PacketStream;
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.ProtocolLogger;
|
||||
import com.comphenix.protocol.events.NetworkMarker;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
import com.comphenix.protocol.injector.PrioritizedListener;
|
||||
@@ -429,15 +429,17 @@ public class AsyncMarker implements Serializable, Comparable<AsyncMarker> {
|
||||
// Incoming chat packets are async only if they aren't commands
|
||||
return ! content.startsWith("/");
|
||||
} else {
|
||||
ProtocolLibrary.log(Level.WARNING, "Failed to determine contents of incoming chat packet!");
|
||||
ProtocolLogger.log(Level.WARNING, "Failed to determine contents of incoming chat packet!");
|
||||
alwaysSync = true;
|
||||
}
|
||||
} else if (event.getPacketType() == PacketType.Status.Server.SERVER_INFO) {
|
||||
return true;
|
||||
} else {
|
||||
// TODO: Find more cases of async packets
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
ProtocolLibrary.log(Level.INFO, "Could not determine asynchronous state of packets (this can probably be ignored)");
|
||||
ProtocolLogger.log(Level.INFO, "Could not determine asynchronous state of packets (this can probably be ignored)");
|
||||
alwaysSync = true;
|
||||
}
|
||||
}
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+1
-1
@@ -243,4 +243,4 @@ public class ExpireHashMap<K, V> {
|
||||
return valueView.toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File renamed without changes.
File renamed without changes.
+1
-2
@@ -23,7 +23,6 @@ import java.util.NavigableMap;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import com.comphenix.protocol.compat.guava.Guava;
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.collect.Range;
|
||||
|
||||
@@ -68,7 +67,7 @@ public abstract class AbstractIntervalTree<TKey extends Comparable<TKey>, TValue
|
||||
|
||||
@Override
|
||||
public Range<TKey> getKey() {
|
||||
return Guava.closedRange(left.key, right.key);
|
||||
return Range.closed(left.key, right.key);
|
||||
}
|
||||
|
||||
@Override
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+6
-4
@@ -35,7 +35,7 @@ import org.apache.commons.lang.builder.ToStringStyle;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.ProtocolLogger;
|
||||
import com.comphenix.protocol.collections.ExpireHashMap;
|
||||
import com.comphenix.protocol.error.Report.ReportBuilder;
|
||||
import com.comphenix.protocol.events.PacketAdapter;
|
||||
@@ -464,13 +464,15 @@ public class DetailedErrorReporter implements ErrorReporter {
|
||||
} else {
|
||||
try {
|
||||
if (!apacheCommonsMissing)
|
||||
return (ToStringBuilder.reflectionToString(value, ToStringStyle.MULTI_LINE_STYLE, false, null));
|
||||
return ToStringBuilder.reflectionToString(value, ToStringStyle.MULTI_LINE_STYLE, false, null);
|
||||
} catch (LinkageError ex) {
|
||||
// Apache is probably missing
|
||||
apacheCommonsMissing = true;
|
||||
} catch (Exception e) {
|
||||
} catch (ThreadDeath | OutOfMemoryError e) {
|
||||
throw e;
|
||||
} catch (Throwable ex) {
|
||||
// Don't use the error logger to log errors in error logging (that could lead to infinite loops)
|
||||
ProtocolLibrary.log(Level.WARNING, "Cannot convert to a String with Apache: " + e.getMessage());
|
||||
ProtocolLogger.log(Level.WARNING, "Cannot convert to a String with Apache: " + ex.getMessage());
|
||||
}
|
||||
|
||||
// Use our custom object printer instead
|
||||
+1
-1
@@ -87,4 +87,4 @@ public interface ErrorReporter {
|
||||
* @param reportBuilder - an error report builder that will be used to get the report.
|
||||
*/
|
||||
public abstract void reportDetailed(Object sender, ReportBuilder reportBuilder);
|
||||
}
|
||||
}
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+1
@@ -2,6 +2,7 @@ package com.comphenix.protocol.events;
|
||||
|
||||
import com.comphenix.protocol.injector.GamePhase;
|
||||
|
||||
|
||||
/**
|
||||
* Represents additional options a listener may require.
|
||||
*
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+269
-34
@@ -33,22 +33,23 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.WorldType;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.PacketType.Protocol;
|
||||
import com.comphenix.protocol.compat.netty.Netty;
|
||||
import com.comphenix.protocol.compat.netty.WrappedByteBuf;
|
||||
import com.comphenix.protocol.injector.StructureCache;
|
||||
import com.comphenix.protocol.reflect.EquivalentConverter;
|
||||
import com.comphenix.protocol.reflect.FuzzyReflection;
|
||||
@@ -61,6 +62,7 @@ import com.comphenix.protocol.reflect.cloning.Cloner;
|
||||
import com.comphenix.protocol.reflect.cloning.CollectionCloner;
|
||||
import com.comphenix.protocol.reflect.cloning.FieldCloner;
|
||||
import com.comphenix.protocol.reflect.cloning.ImmutableDetector;
|
||||
import com.comphenix.protocol.reflect.cloning.OptionalCloner;
|
||||
import com.comphenix.protocol.reflect.cloning.SerializableCloner;
|
||||
import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract;
|
||||
import com.comphenix.protocol.reflect.instances.DefaultInstances;
|
||||
@@ -76,7 +78,11 @@ import com.comphenix.protocol.wrappers.EnumWrappers.ChatVisibility;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.ClientCommand;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.CombatEventType;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.Difficulty;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.Direction;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.EntityUseAction;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.EnumConverter;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.Hand;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.ItemSlot;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.NativeGameMode;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.Particle;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.PlayerAction;
|
||||
@@ -84,6 +90,7 @@ import com.comphenix.protocol.wrappers.EnumWrappers.PlayerDigType;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.PlayerInfoAction;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.ResourcePackStatus;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.ScoreboardAction;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.SoundCategory;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.TitleAction;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.WorldBorderAction;
|
||||
import com.comphenix.protocol.wrappers.MultiBlockChangeInfo;
|
||||
@@ -97,11 +104,16 @@ import com.comphenix.protocol.wrappers.WrappedServerPing;
|
||||
import com.comphenix.protocol.wrappers.WrappedStatistic;
|
||||
import com.comphenix.protocol.wrappers.WrappedWatchableObject;
|
||||
import com.comphenix.protocol.wrappers.nbt.NbtBase;
|
||||
import com.comphenix.protocol.wrappers.nbt.NbtCompound;
|
||||
import com.comphenix.protocol.wrappers.nbt.NbtFactory;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.UnpooledByteBufAllocator;
|
||||
|
||||
/**
|
||||
* Represents a Minecraft packet indirectly.
|
||||
*
|
||||
@@ -125,6 +137,7 @@ public class PacketContainer implements Serializable {
|
||||
instanceProvider(DefaultInstances.DEFAULT).
|
||||
andThen(BukkitCloner.class).
|
||||
andThen(ImmutableDetector.class).
|
||||
andThen(OptionalCloner.class).
|
||||
andThen(CollectionCloner.class).
|
||||
andThen(getSpecializedDeepClonerFactory()).
|
||||
build();
|
||||
@@ -147,8 +160,8 @@ public class PacketContainer implements Serializable {
|
||||
|
||||
// Packets that cannot be cloned by our default deep cloner
|
||||
private static final Set<PacketType> CLONING_UNSUPPORTED = Sets.newHashSet(
|
||||
PacketType.Play.Server.UPDATE_ATTRIBUTES, PacketType.Status.Server.OUT_SERVER_INFO);
|
||||
|
||||
PacketType.Play.Server.UPDATE_ATTRIBUTES, PacketType.Status.Server.SERVER_INFO);
|
||||
|
||||
/**
|
||||
* Creates a packet container for a new packet.
|
||||
* <p>
|
||||
@@ -321,7 +334,15 @@ public class PacketContainer implements Serializable {
|
||||
public StructureModifier<String> getStrings() {
|
||||
return structureModifier.withType(String.class);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves a read/write structure for every UUID field.
|
||||
* @return A modifier for every UUID field.
|
||||
*/
|
||||
public StructureModifier<UUID> getUUIDs() {
|
||||
return structureModifier.withType(UUID.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a read/write structure for every String array field.
|
||||
* @return A modifier for every String array field.
|
||||
@@ -357,7 +378,7 @@ public class PacketContainer implements Serializable {
|
||||
/**
|
||||
* Retrieves a read/write structure for ItemStack.
|
||||
* <p>
|
||||
* This modifier will automatically marshall between the Bukkit ItemStack and the
|
||||
* This modifier will automatically marshal between the Bukkit ItemStack and the
|
||||
* internal Minecraft ItemStack.
|
||||
* @return A modifier for ItemStack fields.
|
||||
*/
|
||||
@@ -370,7 +391,7 @@ public class PacketContainer implements Serializable {
|
||||
/**
|
||||
* Retrieves a read/write structure for arrays of ItemStacks.
|
||||
* <p>
|
||||
* This modifier will automatically marshall between the Bukkit ItemStack and the
|
||||
* This modifier will automatically marshal between the Bukkit ItemStack and the
|
||||
* internal Minecraft ItemStack.
|
||||
* @return A modifier for ItemStack array fields.
|
||||
*/
|
||||
@@ -380,7 +401,25 @@ public class PacketContainer implements Serializable {
|
||||
MinecraftReflection.getItemStackArrayClass(),
|
||||
BukkitConverters.getIgnoreNull(new ItemStackArrayConverter()));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves a read/write structure for lists of ItemStacks.
|
||||
* <p>
|
||||
* This modifier will automatically marshal between the Bukkit ItemStack and the
|
||||
* internal Minecraft ItemStack.
|
||||
* @return A modifier for ItemStack list fields.
|
||||
*/
|
||||
public StructureModifier<List<ItemStack>> getItemListModifier() {
|
||||
// Convert to and from the Bukkit wrapper
|
||||
return structureModifier.withType(
|
||||
List.class,
|
||||
BukkitConverters.getListConverter(
|
||||
MinecraftReflection.getItemStackClass(),
|
||||
BukkitConverters.getItemStackConverter()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a read/write structure for maps of statistics.
|
||||
* <p>
|
||||
@@ -399,7 +438,7 @@ public class PacketContainer implements Serializable {
|
||||
/**
|
||||
* Retrieves a read/write structure for the world type enum.
|
||||
* <p>
|
||||
* This modifier will automatically marshall between the Bukkit world type and the
|
||||
* This modifier will automatically marshal between the Bukkit world type and the
|
||||
* internal Minecraft world type.
|
||||
* @return A modifier for world type fields.
|
||||
*/
|
||||
@@ -499,6 +538,21 @@ public class PacketContainer implements Serializable {
|
||||
BukkitConverters.getNbtConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a read/write structure for lists of NBT classes.
|
||||
* @return A modifier for lists of NBT classes.
|
||||
*/
|
||||
public StructureModifier<List<NbtBase<?>>> getListNbtModifier() {
|
||||
// Convert to and from the ProtocolLib wrapper
|
||||
return structureModifier.withType(
|
||||
Collection.class,
|
||||
BukkitConverters.getListConverter(
|
||||
MinecraftReflection.getNBTBaseClass(),
|
||||
BukkitConverters.getNbtConverter()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a read/write structure for Vectors.
|
||||
* @return A modifier for Vectors.
|
||||
@@ -513,7 +567,7 @@ public class PacketContainer implements Serializable {
|
||||
/**
|
||||
* Retrieves a read/write structure for collections of attribute snapshots.
|
||||
* <p>
|
||||
* This modifier will automatically marshall between the visible ProtocolLib WrappedAttribute and the
|
||||
* This modifier will automatically marshal between the visible ProtocolLib WrappedAttribute and the
|
||||
* internal Minecraft AttributeSnapshot.
|
||||
* @return A modifier for AttributeSnapshot collection fields.
|
||||
*/
|
||||
@@ -530,7 +584,7 @@ public class PacketContainer implements Serializable {
|
||||
/**
|
||||
* Retrieves a read/write structure for collections of chunk positions.
|
||||
* <p>
|
||||
* This modifier will automatically marshall between the visible ProtocolLib ChunkPosition and the
|
||||
* This modifier will automatically marshal between the visible ProtocolLib ChunkPosition and the
|
||||
* internal Minecraft ChunkPosition.
|
||||
*
|
||||
* @return A modifier for ChunkPosition list fields.
|
||||
@@ -548,7 +602,7 @@ public class PacketContainer implements Serializable {
|
||||
/**
|
||||
* Retrieves a read/write structure for collections of chunk positions.
|
||||
* <p>
|
||||
* This modifier will automatically marshall between the visible ProtocolLib BlockPosition and the
|
||||
* This modifier will automatically marshal between the visible ProtocolLib BlockPosition and the
|
||||
* internal Minecraft BlockPosition.
|
||||
*
|
||||
* @return A modifier for ChunkPosition list fields.
|
||||
@@ -566,7 +620,7 @@ public class PacketContainer implements Serializable {
|
||||
/**
|
||||
* Retrieves a read/write structure for collections of watchable objects.
|
||||
* <p>
|
||||
* This modifier will automatically marshall between the visible WrappedWatchableObject and the
|
||||
* This modifier will automatically marshal between the visible WrappedWatchableObject and the
|
||||
* internal Minecraft WatchableObject.
|
||||
* @return A modifier for watchable object list fields.
|
||||
*/
|
||||
@@ -575,16 +629,15 @@ public class PacketContainer implements Serializable {
|
||||
return structureModifier.withType(
|
||||
Collection.class,
|
||||
BukkitConverters.getListConverter(
|
||||
MinecraftReflection.getWatchableObjectClass(),
|
||||
MinecraftReflection.getDataWatcherItemClass(),
|
||||
BukkitConverters.getWatchableObjectConverter())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves a read/write structure for block fields.
|
||||
* <p>
|
||||
* This modifier will automatically marshall between Material and the
|
||||
* This modifier will automatically marshal between Material and the
|
||||
* internal Minecraft Block.
|
||||
* @return A modifier for GameProfile fields.
|
||||
*/
|
||||
@@ -597,7 +650,7 @@ public class PacketContainer implements Serializable {
|
||||
/**
|
||||
* Retrieves a read/write structure for game profiles in Minecraft 1.7.2.
|
||||
* <p>
|
||||
* This modifier will automatically marshall between WrappedGameProfile and the
|
||||
* This modifier will automatically marshal between WrappedGameProfile and the
|
||||
* internal Minecraft GameProfile.
|
||||
* @return A modifier for GameProfile fields.
|
||||
*/
|
||||
@@ -610,7 +663,7 @@ public class PacketContainer implements Serializable {
|
||||
/**
|
||||
* Retrieves a read/write structure for BlockData in Minecraft 1.8.
|
||||
* <p>
|
||||
* This modifier will automatically marshall between WrappedBlockData and the
|
||||
* This modifier will automatically marshal between WrappedBlockData and the
|
||||
* internal Minecraft IBlockData.
|
||||
* @return A modifier for BlockData fields.
|
||||
*/
|
||||
@@ -623,7 +676,7 @@ public class PacketContainer implements Serializable {
|
||||
/**
|
||||
* Retrieves a read/write structure for MultiBlockChangeInfo arrays in Minecraft 1.8.
|
||||
* <p>
|
||||
* This modifier will automatically marshall between MultiBlockChangeInfo and the
|
||||
* This modifier will automatically marshal between MultiBlockChangeInfo and the
|
||||
* internal Minecraft MultiBlockChangeInfo.
|
||||
* @return A modifier for BlockData fields.
|
||||
*/
|
||||
@@ -638,7 +691,7 @@ public class PacketContainer implements Serializable {
|
||||
/**
|
||||
* Retrieves a read/write structure for chat components in Minecraft 1.7.2.
|
||||
* <p>
|
||||
* This modifier will automatically marshall between WrappedChatComponent and the
|
||||
* This modifier will automatically marshal between WrappedChatComponent and the
|
||||
* internal Minecraft IChatBaseComponent.
|
||||
* @return A modifier for ChatComponent fields.
|
||||
*/
|
||||
@@ -651,15 +704,19 @@ public class PacketContainer implements Serializable {
|
||||
/**
|
||||
* Retrieves a read/write structure for arrays of chat components.
|
||||
* <p>
|
||||
* This modifier will automatically marshall between WrappedChatComponent and the
|
||||
* internal Minecraft IChatBaseComponent.
|
||||
* This modifier will automatically marshal between WrappedChatComponent and the
|
||||
* internal Minecraft IChatBaseComponent (1.9.2 and below) or the internal
|
||||
* NBTCompound (1.9.4 and up).
|
||||
* <p>
|
||||
* Note that in 1.9.4 and up this modifier only works properly with sign
|
||||
* tile entities.
|
||||
* @return A modifier for ChatComponent array fields.
|
||||
*/
|
||||
public StructureModifier<WrappedChatComponent[]> getChatComponentArrays() {
|
||||
// Convert to and from the Bukkit wrapper
|
||||
return structureModifier.<WrappedChatComponent[]>withType(
|
||||
MinecraftReflection.getIChatBaseComponentArrayClass(),
|
||||
BukkitConverters.getIgnoreNull(new WrappedChatComponentArrayConverter()));
|
||||
ComponentArrayConverter.getGenericType(),
|
||||
BukkitConverters.getIgnoreNull(new ComponentArrayConverter()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -842,6 +899,90 @@ public class PacketContainer implements Serializable {
|
||||
EnumWrappers.getParticleClass(), EnumWrappers.getParticleConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a read/write structure for the MobEffectList class in 1.9.
|
||||
* @return A modifier for MobEffectList fields.
|
||||
*/
|
||||
public StructureModifier<PotionEffectType> getEffectTypes() {
|
||||
// Convert to and from Bukkit
|
||||
return structureModifier.<PotionEffectType>withType(
|
||||
MinecraftReflection.getMobEffectListClass(), BukkitConverters.getEffectTypeConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a read/write structure for the SoundCategory enum in 1.9.
|
||||
* @return A modifier for SoundCategory enum fields.
|
||||
*/
|
||||
public StructureModifier<SoundCategory> getSoundCategories() {
|
||||
// Convert to and from the enums
|
||||
return structureModifier.<SoundCategory>withType(
|
||||
EnumWrappers.getSoundCategoryClass(), EnumWrappers.getSoundCategoryConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a read/write structure for the SoundEffect enum in 1.9.
|
||||
* @return A modifier for SoundEffect enum fields.
|
||||
*/
|
||||
public StructureModifier<Sound> getSoundEffects() {
|
||||
// Convert to and from Bukkit
|
||||
return structureModifier.<Sound>withType(
|
||||
MinecraftReflection.getSoundEffectClass(), BukkitConverters.getSoundConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a read/write structure for the ItemSlot enum in 1.9.
|
||||
* @return A modifier for ItemSlot enum fields.
|
||||
*/
|
||||
public StructureModifier<ItemSlot> getItemSlots() {
|
||||
return structureModifier.<ItemSlot>withType(
|
||||
EnumWrappers.getItemSlotClass(), EnumWrappers.getItemSlotConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a read/write structure for the Hand enum in 1.9.
|
||||
* @return A modifier for Hand enum fields.
|
||||
*/
|
||||
public StructureModifier<Hand> getHands() {
|
||||
return structureModifier.<Hand>withType(
|
||||
EnumWrappers.getHandClass(), EnumWrappers.getHandConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a read/write structure for the Direction enum in 1.10.
|
||||
* @return A modifier for Direction enum fields.
|
||||
*/
|
||||
public StructureModifier<Direction> getDirections() {
|
||||
return structureModifier.<Direction>withType(
|
||||
EnumWrappers.getDirectionClass(), EnumWrappers.getDirectionConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a read/write structure for an enum. This allows for the use of
|
||||
* user-created enums that may not exist in ProtocolLib. The specific (user
|
||||
* created) enum constants must match up perfectly with their generic (NMS)
|
||||
* counterparts.
|
||||
*
|
||||
* @param enumClass The specific Enum class
|
||||
* @param nmsClass The generic Enum class
|
||||
* @return The modifier
|
||||
*/
|
||||
public <T extends Enum<T>> StructureModifier<T> getEnumModifier(Class<T> enumClass, Class<?> nmsClass) {
|
||||
return structureModifier.<T>withType(nmsClass, new EnumConverter<T>(enumClass));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a read/write structure for an enum. This method is for convenience,
|
||||
* see {@link #getEnumModifier(Class, Class)} for more information.
|
||||
*
|
||||
* @param enumClass The specific Enum class
|
||||
* @param index Index of the generic Enum
|
||||
* @return The modifier
|
||||
* @see #getEnumModifier(Class, Class)
|
||||
*/
|
||||
public <T extends Enum<T>> StructureModifier<T> getEnumModifier(Class<T> enumClass, int index) {
|
||||
return getEnumModifier(enumClass, structureModifier.getField(index).getType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the ID of this packet.
|
||||
* <p>
|
||||
@@ -928,8 +1069,8 @@ public class PacketContainer implements Serializable {
|
||||
|
||||
try {
|
||||
if (MinecraftReflection.isUsingNetty()) {
|
||||
WrappedByteBuf buffer = createPacketBuffer();
|
||||
MinecraftMethods.getPacketWriteByteBufMethod().invoke(handle, buffer.getHandle());
|
||||
ByteBuf buffer = createPacketBuffer();
|
||||
MinecraftMethods.getPacketWriteByteBufMethod().invoke(handle, buffer);
|
||||
|
||||
output.writeInt(buffer.readableBytes());
|
||||
buffer.readBytes(output, buffer.readableBytes());
|
||||
@@ -965,10 +1106,10 @@ public class PacketContainer implements Serializable {
|
||||
// Call the read method
|
||||
try {
|
||||
if (MinecraftReflection.isUsingNetty()) {
|
||||
WrappedByteBuf buffer = createPacketBuffer();
|
||||
ByteBuf buffer = createPacketBuffer();
|
||||
buffer.writeBytes(input, input.readInt());
|
||||
|
||||
MinecraftMethods.getPacketReadByteBufMethod().invoke(handle, buffer.getHandle());
|
||||
MinecraftMethods.getPacketReadByteBufMethod().invoke(handle, buffer);
|
||||
} else {
|
||||
if (input.readInt() != -1)
|
||||
throw new IllegalArgumentException("Cannot load a packet from 1.7.2 in 1.6.4.");
|
||||
@@ -993,8 +1134,15 @@ public class PacketContainer implements Serializable {
|
||||
* Construct a new packet data serializer.
|
||||
* @return The packet data serializer.
|
||||
*/
|
||||
private WrappedByteBuf createPacketBuffer() {
|
||||
return Netty.createPacketBuffer();
|
||||
public static ByteBuf createPacketBuffer() {
|
||||
ByteBuf buffer = UnpooledByteBufAllocator.DEFAULT.buffer();
|
||||
Class<?> packetSerializer = MinecraftReflection.getPacketDataSerializerClass();
|
||||
|
||||
try {
|
||||
return (ByteBuf) packetSerializer.getConstructor(ByteBuf.class).newInstance(buffer);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Cannot construct packet serializer.", e);
|
||||
}
|
||||
}
|
||||
|
||||
// ---- Metadata
|
||||
@@ -1134,11 +1282,11 @@ public class PacketContainer implements Serializable {
|
||||
* Represents an equivalent converter for ChatComponent arrays.
|
||||
* @author dmulloy2
|
||||
*/
|
||||
private static class WrappedChatComponentArrayConverter implements EquivalentConverter<WrappedChatComponent[]> {
|
||||
private static class LegacyComponentConverter implements EquivalentConverter<WrappedChatComponent[]> {
|
||||
final EquivalentConverter<WrappedChatComponent> componentConverter = BukkitConverters.getWrappedChatComponentConverter();
|
||||
|
||||
@Override
|
||||
public Object getGeneric(Class<?>genericType, WrappedChatComponent[] specific) {
|
||||
public Object getGeneric(Class<?> genericType, WrappedChatComponent[] specific) {
|
||||
Class<?> nmsComponent = MinecraftReflection.getIChatBaseComponentClass();
|
||||
Object[] result = (Object[]) Array.newInstance(nmsComponent, specific.length);
|
||||
|
||||
@@ -1167,8 +1315,95 @@ public class PacketContainer implements Serializable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts from NBT to WrappedChatComponent arrays
|
||||
* @author dmulloy2
|
||||
*/
|
||||
private static class NBTComponentConverter implements EquivalentConverter<WrappedChatComponent[]> {
|
||||
private EquivalentConverter<NbtBase<?>> nbtConverter = BukkitConverters.getNbtConverter();
|
||||
private final int lines = 4;
|
||||
|
||||
@Override
|
||||
public WrappedChatComponent[] getSpecific(Object generic) {
|
||||
NbtBase<?> nbtBase = nbtConverter.getSpecific(generic);
|
||||
NbtCompound compound = (NbtCompound) nbtBase;
|
||||
|
||||
WrappedChatComponent[] components = new WrappedChatComponent[lines];
|
||||
for (int i = 0; i < lines; i++) {
|
||||
if (compound.containsKey("Text" + (i + 1))) {
|
||||
components[i] = WrappedChatComponent.fromJson(compound.getString("Text" + (i + 1)));
|
||||
} else {
|
||||
components[i] = WrappedChatComponent.fromText("");
|
||||
}
|
||||
}
|
||||
|
||||
return components;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getGeneric(Class<?> genericType, WrappedChatComponent[] specific) {
|
||||
NbtCompound compound = NbtFactory.ofCompound("");
|
||||
|
||||
for (int i = 0; i < lines; i++) {
|
||||
WrappedChatComponent component;
|
||||
if (i < specific.length && specific[i] != null) {
|
||||
component = specific[i];
|
||||
} else {
|
||||
component = WrappedChatComponent.fromText("");
|
||||
}
|
||||
|
||||
compound.put("Text" + (i + 1), component.getJson());
|
||||
}
|
||||
|
||||
return nbtConverter.getGeneric(genericType, compound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<WrappedChatComponent[]> getSpecificType() {
|
||||
return WrappedChatComponent[].class;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A delegated converter that supports NBT to Component Array and regular Component Array
|
||||
* @author dmulloy2
|
||||
*/
|
||||
private static class ComponentArrayConverter implements EquivalentConverter<WrappedChatComponent[]> {
|
||||
private static final EquivalentConverter<WrappedChatComponent[]> DELEGATE;
|
||||
static {
|
||||
if (!PacketType.Play.Server.UPDATE_SIGN.isDeprecated()) {
|
||||
DELEGATE = new LegacyComponentConverter();
|
||||
} else {
|
||||
DELEGATE = new NBTComponentConverter();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public WrappedChatComponent[] getSpecific(Object generic) {
|
||||
return DELEGATE.getSpecific(generic);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getGeneric(Class<?> genericType, WrappedChatComponent[] specific) {
|
||||
return DELEGATE.getGeneric(genericType, specific);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<WrappedChatComponent[]> getSpecificType() {
|
||||
return DELEGATE.getSpecificType();
|
||||
}
|
||||
|
||||
public static Class<?> getGenericType() {
|
||||
if (DELEGATE instanceof NBTComponentConverter) {
|
||||
return MinecraftReflection.getNBTCompoundClass();
|
||||
} else {
|
||||
return MinecraftReflection.getIChatBaseComponentArrayClass();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PacketContainer[type=" + type + ", structureModifier=" + structureModifier + "]";
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
-4
@@ -23,13 +23,14 @@ import java.io.ObjectOutputStream;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.EventObject;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
|
||||
import com.comphenix.protocol.Application;
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.async.AsyncMarker;
|
||||
import com.comphenix.protocol.error.PluginContext;
|
||||
import com.comphenix.protocol.error.Report;
|
||||
import com.comphenix.protocol.error.ReportType;
|
||||
import com.google.common.base.Objects;
|
||||
@@ -202,7 +203,7 @@ public class PacketEvent extends EventObject implements Cancellable {
|
||||
* @return TRUE if we are, FALSE otherwise.
|
||||
*/
|
||||
public boolean isAsync() {
|
||||
return !Application.isPrimaryThread();
|
||||
return !Bukkit.isPrimaryThread();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -231,7 +232,7 @@ public class PacketEvent extends EventObject implements Cancellable {
|
||||
if (CHANGE_WARNINGS.put(oldType, newType)) {
|
||||
ProtocolLibrary.getErrorReporter().reportWarning(this,
|
||||
Report.newBuilder(REPORT_CHANGING_PACKET_TYPE_IS_CONFUSING).
|
||||
messageParam(oldType, newType).
|
||||
messageParam(PluginContext.getPluginCaller(new Exception()), oldType, newType).
|
||||
build());
|
||||
}
|
||||
}
|
||||
@@ -452,4 +453,4 @@ public class PacketEvent extends EventObject implements Cancellable {
|
||||
public String toString() {
|
||||
return "PacketEvent[player=" + getPlayer() + ", packet=" + packet + "]";
|
||||
}
|
||||
}
|
||||
}
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+42
-3
@@ -24,6 +24,9 @@ import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.error.ErrorReporter;
|
||||
import com.comphenix.protocol.error.Report;
|
||||
@@ -31,6 +34,7 @@ import com.comphenix.protocol.error.ReportType;
|
||||
import com.comphenix.protocol.injector.PacketConstructor.Unwrapper;
|
||||
import com.comphenix.protocol.reflect.FieldUtils;
|
||||
import com.comphenix.protocol.reflect.instances.DefaultInstances;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
import com.google.common.primitives.Primitives;
|
||||
|
||||
/**
|
||||
@@ -182,20 +186,55 @@ public class BukkitUnwrapper implements Unwrapper {
|
||||
Report.newBuilder(REPORT_SECURITY_LIMITATION).error(e).callerParam(type)
|
||||
);
|
||||
} catch (NoSuchMethodException e) {
|
||||
// Maybe it's a proxy?
|
||||
Unwrapper proxyUnwrapper = getProxyUnwrapper(type);
|
||||
if (proxyUnwrapper != null)
|
||||
return proxyUnwrapper;
|
||||
|
||||
// Try getting the field unwrapper too
|
||||
Unwrapper fieldUnwrapper = getFieldUnwrapper(type);
|
||||
|
||||
if (fieldUnwrapper != null)
|
||||
return fieldUnwrapper;
|
||||
else
|
||||
reporter.reportDetailed(this,
|
||||
Report.newBuilder(REPORT_CANNOT_FIND_UNWRAP_METHOD).error(e).callerParam(type));
|
||||
}
|
||||
|
||||
|
||||
// Default method
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// Players should /always/ be able to be unwrapped
|
||||
// We should only get here if the 'Player' is a proxy
|
||||
private Unwrapper getProxyUnwrapper(final Class<?> type) {
|
||||
try {
|
||||
if (Player.class.isAssignableFrom(type)) {
|
||||
final Method getHandle = MinecraftReflection.getCraftPlayerClass().getMethod("getHandle");
|
||||
|
||||
Unwrapper unwrapper = new Unwrapper() {
|
||||
@Override
|
||||
public Object unwrapItem(Object wrapped) {
|
||||
try {
|
||||
return getHandle.invoke(((Player) wrapped).getPlayer());
|
||||
} catch (Throwable ex) {
|
||||
try {
|
||||
return getHandle.invoke(Bukkit.getPlayer(((Player) wrapped).getUniqueId()));
|
||||
} catch (ReflectiveOperationException ex1) {
|
||||
throw new RuntimeException("Failed to unwrap proxy " + wrapped, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
unwrapperCache.put(type, unwrapper);
|
||||
return unwrapper;
|
||||
}
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a cached unwrapper using the handle field.
|
||||
* @param type - a cached field unwrapper.
|
||||
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,31 @@
|
||||
package com.comphenix.protocol.injector;
|
||||
|
||||
/**
|
||||
* Sets the inject hook type. Different types allow for maximum compatibility.
|
||||
* @author Kristian
|
||||
*/
|
||||
public enum PlayerInjectHooks {
|
||||
/**
|
||||
* The injection hook that does nothing. Set when every other inject hook fails.
|
||||
*/
|
||||
NONE,
|
||||
|
||||
/**
|
||||
* Override the network handler object itself. Only works in 1.3.
|
||||
* <p>
|
||||
* Cannot intercept MapChunk packets.
|
||||
*/
|
||||
NETWORK_MANAGER_OBJECT,
|
||||
|
||||
/**
|
||||
* Override the packet queue lists in NetworkHandler.
|
||||
* <p>
|
||||
* Cannot intercept MapChunk packets.
|
||||
*/
|
||||
NETWORK_HANDLER_FIELDS,
|
||||
|
||||
/**
|
||||
* Override the server handler object. Versatile, but a tad slower.
|
||||
*/
|
||||
NETWORK_SERVER_OBJECT;
|
||||
}
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
+1
-1
@@ -172,4 +172,4 @@ public class StructureCache {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -14,7 +14,7 @@
|
||||
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
* 02111-1307 USA
|
||||
*/
|
||||
package com.comphenix.protocol.compat.netty.independent;
|
||||
package com.comphenix.protocol.injector.netty;
|
||||
|
||||
import io.netty.buffer.AbstractByteBuf;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
@@ -389,4 +389,4 @@ public class NettyByteBufAdapter extends AbstractByteBuf {
|
||||
public ByteBuf retain() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
+111
-104
@@ -1,104 +1,111 @@
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 dmulloy2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program;
|
||||
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
* 02111-1307 USA
|
||||
*/
|
||||
package com.comphenix.protocol.compat.netty.independent;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.PacketType.Protocol;
|
||||
import com.comphenix.protocol.PacketType.Sender;
|
||||
import com.comphenix.protocol.injector.netty.ProtocolRegistry;
|
||||
import com.comphenix.protocol.injector.packet.MapContainer;
|
||||
import com.comphenix.protocol.reflect.StructureModifier;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
/**
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
public class NettyProtocolRegistry extends ProtocolRegistry {
|
||||
|
||||
@Override
|
||||
protected synchronized void initialize() {
|
||||
Object[] protocols = enumProtocol.getEnumConstants();
|
||||
|
||||
// ID to Packet class maps
|
||||
Map<Object, Map<Integer, Class<?>>> serverMaps = Maps.newLinkedHashMap();
|
||||
Map<Object, Map<Integer, Class<?>>> clientMaps = Maps.newLinkedHashMap();
|
||||
|
||||
Register result = new Register();
|
||||
StructureModifier<Object> modifier = null;
|
||||
|
||||
// Iterate through the protocols
|
||||
for (Object protocol : protocols) {
|
||||
if (modifier == null)
|
||||
modifier = new StructureModifier<Object>(protocol.getClass().getSuperclass(), false);
|
||||
StructureModifier<Map<Object, Map<Integer, Class<?>>>> maps = modifier.withTarget(protocol).withType(Map.class);
|
||||
for (Entry<Object, Map<Integer, Class<?>>> entry : maps.read(0).entrySet()) {
|
||||
String direction = entry.getKey().toString();
|
||||
if (direction.contains("CLIENTBOUND")) { // Sent by Server
|
||||
serverMaps.put(protocol, entry.getValue());
|
||||
} else if (direction.contains("SERVERBOUND")) { // Sent by Client
|
||||
clientMaps.put(protocol, entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Maps we have to occationally check have changed
|
||||
for (Map<Integer, Class<?>> map : serverMaps.values()) {
|
||||
result.containers.add(new MapContainer(map));
|
||||
}
|
||||
|
||||
for (Map<Integer, Class<?>> map : clientMaps.values()) {
|
||||
result.containers.add(new MapContainer(map));
|
||||
}
|
||||
|
||||
for (int i = 0; i < protocols.length; i++) {
|
||||
Object protocol = protocols[i];
|
||||
Enum<?> enumProtocol = (Enum<?>) protocol;
|
||||
Protocol equivalent = Protocol.fromVanilla(enumProtocol);
|
||||
|
||||
// Associate known types
|
||||
if (serverMaps.containsKey(protocol))
|
||||
associatePackets(result, serverMaps.get(protocol), equivalent, Sender.SERVER);
|
||||
if (clientMaps.containsKey(protocol))
|
||||
associatePackets(result, clientMaps.get(protocol), equivalent, Sender.CLIENT);
|
||||
}
|
||||
|
||||
// Exchange (thread safe, as we have only one writer)
|
||||
this.register = result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void associatePackets(Register register, Map<Integer, Class<?>> lookup, Protocol protocol, Sender sender) {
|
||||
for (Entry<Integer, Class<?>> entry : lookup.entrySet()) {
|
||||
PacketType type = PacketType.fromCurrent(protocol, sender, entry.getKey(), entry.getValue());
|
||||
|
||||
try {
|
||||
register.typeToClass.put(type, entry.getValue());
|
||||
|
||||
if (sender == Sender.SERVER)
|
||||
register.serverPackets.add(type);
|
||||
if (sender == Sender.CLIENT)
|
||||
register.clientPackets.add(type);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
// Sometimes this happens with fake packets, just ignore it
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 dmulloy2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program;
|
||||
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
* 02111-1307 USA
|
||||
*/
|
||||
package com.comphenix.protocol.injector.netty;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.ProtocolLogger;
|
||||
import com.comphenix.protocol.PacketType.Protocol;
|
||||
import com.comphenix.protocol.PacketType.Sender;
|
||||
import com.comphenix.protocol.injector.netty.ProtocolRegistry;
|
||||
import com.comphenix.protocol.injector.packet.MapContainer;
|
||||
import com.comphenix.protocol.reflect.StructureModifier;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
/**
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
public class NettyProtocolRegistry extends ProtocolRegistry {
|
||||
|
||||
public NettyProtocolRegistry() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected synchronized void initialize() {
|
||||
ProtocolLogger.debug("Initializing the Netty protocol registry"); // Debug for issue #202
|
||||
|
||||
Object[] protocols = enumProtocol.getEnumConstants();
|
||||
|
||||
// ID to Packet class maps
|
||||
Map<Object, Map<Integer, Class<?>>> serverMaps = Maps.newLinkedHashMap();
|
||||
Map<Object, Map<Integer, Class<?>>> clientMaps = Maps.newLinkedHashMap();
|
||||
|
||||
Register result = new Register();
|
||||
StructureModifier<Object> modifier = null;
|
||||
|
||||
// Iterate through the protocols
|
||||
for (Object protocol : protocols) {
|
||||
if (modifier == null)
|
||||
modifier = new StructureModifier<Object>(protocol.getClass().getSuperclass(), false);
|
||||
StructureModifier<Map<Object, Map<Integer, Class<?>>>> maps = modifier.withTarget(protocol).withType(Map.class);
|
||||
for (Entry<Object, Map<Integer, Class<?>>> entry : maps.read(0).entrySet()) {
|
||||
String direction = entry.getKey().toString();
|
||||
if (direction.contains("CLIENTBOUND")) { // Sent by Server
|
||||
serverMaps.put(protocol, entry.getValue());
|
||||
} else if (direction.contains("SERVERBOUND")) { // Sent by Client
|
||||
clientMaps.put(protocol, entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Maps we have to occasionally check have changed
|
||||
for (Map<Integer, Class<?>> map : serverMaps.values()) {
|
||||
result.containers.add(new MapContainer(map));
|
||||
}
|
||||
|
||||
for (Map<Integer, Class<?>> map : clientMaps.values()) {
|
||||
result.containers.add(new MapContainer(map));
|
||||
}
|
||||
|
||||
for (int i = 0; i < protocols.length; i++) {
|
||||
Object protocol = protocols[i];
|
||||
Enum<?> enumProtocol = (Enum<?>) protocol;
|
||||
Protocol equivalent = Protocol.fromVanilla(enumProtocol);
|
||||
|
||||
// Associate known types
|
||||
if (serverMaps.containsKey(protocol))
|
||||
associatePackets(result, serverMaps.get(protocol), equivalent, Sender.SERVER);
|
||||
if (clientMaps.containsKey(protocol))
|
||||
associatePackets(result, clientMaps.get(protocol), equivalent, Sender.CLIENT);
|
||||
}
|
||||
|
||||
// Exchange (thread safe, as we have only one writer)
|
||||
this.register = result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void associatePackets(Register register, Map<Integer, Class<?>> lookup, Protocol protocol, Sender sender) {
|
||||
for (Entry<Integer, Class<?>> entry : lookup.entrySet()) {
|
||||
PacketType type = PacketType.fromCurrent(protocol, sender, entry.getKey(), entry.getValue());
|
||||
|
||||
try {
|
||||
register.typeToClass.put(type, entry.getValue());
|
||||
|
||||
if (sender == Sender.SERVER)
|
||||
register.serverPackets.add(type);
|
||||
if (sender == Sender.CLIENT)
|
||||
register.clientPackets.add(type);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
// Sometimes this happens with fake packets, just ignore it
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -19,7 +19,7 @@ import com.google.common.collect.Sets;
|
||||
* Represents a way of accessing the new netty Protocol enum.
|
||||
* @author Kristian
|
||||
*/
|
||||
// TODO: Handle modifications to the BiMap
|
||||
|
||||
public abstract class ProtocolRegistry {
|
||||
/**
|
||||
* Represents a register we are currently building.
|
||||
@@ -97,7 +97,7 @@ public abstract class ProtocolRegistry {
|
||||
* This operation may block the calling thread.
|
||||
*/
|
||||
public synchronized void synchronize() {
|
||||
// See if the register is outdated
|
||||
// Check if the packet registry has changed
|
||||
if (register.isOutdated()) {
|
||||
initialize();
|
||||
}
|
||||
@@ -122,4 +122,4 @@ public abstract class ProtocolRegistry {
|
||||
count += map.size();
|
||||
return count;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,255 @@
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 dmulloy2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program;
|
||||
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
* 02111-1307 USA
|
||||
*/
|
||||
package com.comphenix.protocol.injector.netty;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.utility.MinecraftMethods;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
|
||||
/**
|
||||
* A packet represented only by its id and bytes.
|
||||
* @author dmulloy2
|
||||
*/
|
||||
public class WirePacket {
|
||||
private final int id;
|
||||
private final byte[] bytes;
|
||||
|
||||
/**
|
||||
* Constructs a new WirePacket with a given type and contents
|
||||
* @param type Type of the packet
|
||||
* @param bytes Contents of the packet
|
||||
*/
|
||||
public WirePacket(PacketType type, byte[] bytes) {
|
||||
this.id = checkNotNull(type, "type cannot be null").getCurrentId();
|
||||
this.bytes = bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new WirePacket with a given id and contents
|
||||
* @param id ID of the packet
|
||||
* @param bytes Contents of the packet
|
||||
*/
|
||||
public WirePacket(int id, byte[] bytes) {
|
||||
this.id = id;
|
||||
this.bytes = bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this packet's ID
|
||||
* @return The ID
|
||||
*/
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this packet's contents as a byte array
|
||||
* @return The contents
|
||||
*/
|
||||
public byte[] getBytes() {
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the id of this packet to a given output
|
||||
* @param output Output to write to
|
||||
*/
|
||||
public void writeId(ByteBuf output) {
|
||||
writeVarInt(output, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the contents of this packet to a given output
|
||||
* @param output Output to write to
|
||||
*/
|
||||
public void writeBytes(ByteBuf output) {
|
||||
checkNotNull(output, "output cannot be null!");
|
||||
output.writeBytes(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fully writes the ID and contents of this packet to a given output
|
||||
* @param output Output to write to
|
||||
*/
|
||||
public void writeFully(ByteBuf output) {
|
||||
writeId(output);
|
||||
writeBytes(output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes this packet into a byte buffer
|
||||
* @return The buffer
|
||||
*/
|
||||
public ByteBuf serialize() {
|
||||
ByteBuf buffer = Unpooled.buffer();
|
||||
writeFully(buffer);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
|
||||
if (obj instanceof WirePacket) {
|
||||
WirePacket that = (WirePacket) obj;
|
||||
return this.id == that.id &&
|
||||
Arrays.equals(this.bytes, that.bytes);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + Arrays.hashCode(bytes);
|
||||
result = prime * result + id;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "WirePacket[id=" + id + ", bytes=" + Arrays.toString(bytes) + "]";
|
||||
}
|
||||
|
||||
private static byte[] getBytes(ByteBuf buffer) {
|
||||
byte[] array = new byte[buffer.readableBytes()];
|
||||
buffer.readBytes(array);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a WirePacket from an existing PacketContainer
|
||||
* @param packet Existing packet
|
||||
* @return The resulting WirePacket
|
||||
*/
|
||||
public static WirePacket fromPacket(PacketContainer packet) {
|
||||
int id = packet.getType().getCurrentId();
|
||||
return new WirePacket(id, bytesFromPacket(packet));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a byte array from an existing PacketContainer containing all the
|
||||
* bytes from that packet
|
||||
*
|
||||
* @param packet Existing packet
|
||||
* @return The ByteBuf
|
||||
*/
|
||||
public static byte[] bytesFromPacket(PacketContainer packet) {
|
||||
checkNotNull(packet, "packet cannot be null!");
|
||||
|
||||
ByteBuf buffer = PacketContainer.createPacketBuffer();
|
||||
ByteBuf store = PacketContainer.createPacketBuffer();
|
||||
|
||||
// Read the bytes once
|
||||
Method write = MinecraftMethods.getPacketWriteByteBufMethod();
|
||||
|
||||
try {
|
||||
write.invoke(packet.getHandle(), buffer);
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
throw new RuntimeException("Failed to read packet contents.", ex);
|
||||
}
|
||||
|
||||
byte[] bytes = getBytes(buffer);
|
||||
|
||||
// Rewrite them to the packet to avoid issues with certain packets
|
||||
if (packet.getType() == PacketType.Play.Server.CUSTOM_PAYLOAD
|
||||
|| packet.getType() == PacketType.Play.Client.CUSTOM_PAYLOAD) {
|
||||
// Make a copy of the array before writing
|
||||
byte[] ret = Arrays.copyOf(bytes, bytes.length);
|
||||
store.writeBytes(bytes);
|
||||
|
||||
Method read = MinecraftMethods.getPacketReadByteBufMethod();
|
||||
|
||||
try {
|
||||
read.invoke(packet.getHandle(), store);
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
throw new RuntimeException("Failed to rewrite packet contents.", ex);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a WirePacket from an existing Minecraft packet
|
||||
* @param packet Existing Minecraft packet
|
||||
* @return The resulting WirePacket
|
||||
* @throws IllegalArgumentException If the packet is null or not a Minecraft packet
|
||||
*/
|
||||
public static WirePacket fromPacket(Object packet) {
|
||||
checkNotNull(packet, "packet cannot be null!");
|
||||
checkArgument(MinecraftReflection.isPacketClass(packet), "packet must be a Minecraft packet");
|
||||
|
||||
PacketType type = PacketType.fromClass(packet.getClass());
|
||||
int id = type.getCurrentId();
|
||||
|
||||
ByteBuf buffer = PacketContainer.createPacketBuffer();
|
||||
Method write = MinecraftMethods.getPacketWriteByteBufMethod();
|
||||
|
||||
try {
|
||||
write.invoke(packet, buffer);
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
throw new RuntimeException("Failed to serialize packet contents.", ex);
|
||||
}
|
||||
|
||||
return new WirePacket(id, getBytes(buffer));
|
||||
}
|
||||
|
||||
public static void writeVarInt(ByteBuf output, int i) {
|
||||
checkNotNull(output, "output cannot be null!");
|
||||
|
||||
while ((i & -128) != 0) {
|
||||
output.writeByte(i & 127 | 128);
|
||||
i >>>= 7;
|
||||
}
|
||||
|
||||
output.writeByte(i);
|
||||
}
|
||||
|
||||
public static int readVarInt(ByteBuf input) {
|
||||
checkNotNull(input, "input cannot be null!");
|
||||
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
|
||||
byte b0;
|
||||
|
||||
do {
|
||||
b0 = input.readByte();
|
||||
i |= (b0 & 127) << j++ * 7;
|
||||
if (j > 5) {
|
||||
throw new RuntimeException("VarInt too big");
|
||||
}
|
||||
} while ((b0 & 128) == 128);
|
||||
|
||||
return i;
|
||||
}
|
||||
}
|
||||
+13
-9
@@ -3,6 +3,7 @@ package com.comphenix.protocol.injector.packet;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import com.comphenix.protocol.reflect.FieldUtils;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Represents a class that can detect if a map has changed.
|
||||
@@ -10,17 +11,20 @@ import com.comphenix.protocol.reflect.FieldUtils;
|
||||
*/
|
||||
public class MapContainer {
|
||||
// For detecting changes
|
||||
private Field modCountField;
|
||||
private final Field modCountField;
|
||||
private int lastModCount;
|
||||
|
||||
// The object along with whether or not this is the initial run
|
||||
private Object source;
|
||||
private final Object source;
|
||||
private boolean changed;
|
||||
|
||||
public MapContainer(Object source) {
|
||||
this.source = source;
|
||||
this.changed = true;
|
||||
this.modCountField = FieldUtils.getField(source.getClass(), "modCount", true);
|
||||
this.changed = false;
|
||||
|
||||
Field modCountField = FieldUtils.getField(source.getClass(), "modCount", true);
|
||||
this.modCountField = checkNotNull(modCountField, "Could not obtain modCount field");
|
||||
this.lastModCount = getModificationCount();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -55,13 +59,13 @@ public class MapContainer {
|
||||
|
||||
/**
|
||||
* Retrieve the current modification count.
|
||||
* @return The current count, or something different than lastModCount if not accessible.
|
||||
* @return The current count
|
||||
*/
|
||||
private int getModificationCount() {
|
||||
try {
|
||||
return modCountField != null ? modCountField.getInt(source) : lastModCount + 1;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Unable to retrieve modCount.", e);
|
||||
return modCountField.getInt(source);
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
throw new RuntimeException("Unable to retrieve modCount.", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+98
-174
@@ -18,23 +18,18 @@
|
||||
package com.comphenix.protocol.injector.packet;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.PacketType.Sender;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.compat.netty.LegacyProtocolRegistry;
|
||||
import com.comphenix.protocol.compat.netty.independent.NettyProtocolRegistry;
|
||||
import com.comphenix.protocol.error.Report;
|
||||
import com.comphenix.protocol.error.ReportType;
|
||||
import com.comphenix.protocol.injector.netty.NettyProtocolRegistry;
|
||||
import com.comphenix.protocol.injector.netty.ProtocolRegistry;
|
||||
import com.comphenix.protocol.injector.packet.LegacyPacketRegistry.InsufficientPacketsException;
|
||||
import com.comphenix.protocol.reflect.FieldAccessException;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
import com.comphenix.protocol.utility.MinecraftVersion;
|
||||
import com.comphenix.protocol.wrappers.TroveWrapper.CannotFindTroveNoEntryValue;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
@@ -50,45 +45,30 @@ public class PacketRegistry {
|
||||
public static final ReportType REPORT_INSUFFICIENT_SERVER_PACKETS = new ReportType("Too few server packets detected: %s");
|
||||
public static final ReportType REPORT_INSUFFICIENT_CLIENT_PACKETS = new ReportType("Too few client packets detected: %s");
|
||||
|
||||
// Two different packet registry
|
||||
private static volatile LegacyPacketRegistry LEGACY;
|
||||
// The Netty packet registry
|
||||
private static volatile ProtocolRegistry NETTY;
|
||||
|
||||
// Cached for legacy
|
||||
private static volatile Set<PacketType> NETTY_SERVER_PACKETS;
|
||||
private static volatile Set<PacketType> NETTY_CLIENT_PACKETS;
|
||||
|
||||
|
||||
// Cached for Netty
|
||||
private static volatile Set<Integer> LEGACY_SERVER_PACKETS;
|
||||
private static volatile Set<Integer> LEGACY_CLIENT_PACKETS;
|
||||
private static volatile Map<Integer, Class> LEGACY_PREVIOUS_PACKETS;
|
||||
|
||||
// Whether or not the registry has
|
||||
private static boolean INITIALIZED;
|
||||
|
||||
|
||||
// Whether or not the registry has been initialized
|
||||
private static volatile boolean INITIALIZED = false;
|
||||
|
||||
/**
|
||||
* Initialize the packet registry.
|
||||
* Initializes the packet registry.
|
||||
*/
|
||||
private static void initialize() {
|
||||
if (INITIALIZED) {
|
||||
// Make sure they were initialized
|
||||
if (NETTY == null && LEGACY == null)
|
||||
throw new IllegalStateException("No initialized registry.");
|
||||
if (NETTY == null) {
|
||||
throw new IllegalStateException("Failed to initialize packet registry.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for netty
|
||||
if (MinecraftReflection.isUsingNetty()) {
|
||||
if (NETTY == null) {
|
||||
if (MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.BOUNTIFUL_UPDATE)) {
|
||||
NETTY = new NettyProtocolRegistry();
|
||||
} else {
|
||||
NETTY = new LegacyProtocolRegistry();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
initializeLegacy();
|
||||
}
|
||||
|
||||
NETTY = new NettyProtocolRegistry();
|
||||
INITIALIZED = true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -98,41 +78,9 @@ public class PacketRegistry {
|
||||
*/
|
||||
public static boolean isSupported(PacketType type) {
|
||||
initialize();
|
||||
|
||||
if (NETTY != null)
|
||||
return NETTY.getPacketTypeLookup().containsKey(type);
|
||||
|
||||
// Look up the correct type
|
||||
return type.isClient() ?
|
||||
LEGACY.getClientPackets().contains(type.getLegacyId()) :
|
||||
LEGACY.getServerPackets().contains(type.getLegacyId());
|
||||
return NETTY.getPacketTypeLookup().containsKey(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the legacy packet registry.
|
||||
*/
|
||||
private static void initializeLegacy() {
|
||||
if (LEGACY == null) {
|
||||
try {
|
||||
LEGACY = new LegacyPacketRegistry();
|
||||
LEGACY.initialize();
|
||||
} catch (InsufficientPacketsException e) {
|
||||
if (e.isClient()) {
|
||||
ProtocolLibrary.getErrorReporter().reportWarning(
|
||||
PacketRegistry.class, Report.newBuilder(REPORT_INSUFFICIENT_CLIENT_PACKETS).messageParam(e.getPacketCount())
|
||||
);
|
||||
} else {
|
||||
ProtocolLibrary.getErrorReporter().reportWarning(
|
||||
PacketRegistry.class, Report.newBuilder(REPORT_INSUFFICIENT_SERVER_PACKETS).messageParam(e.getPacketCount())
|
||||
);
|
||||
}
|
||||
} catch (CannotFindTroveNoEntryValue e) {
|
||||
ProtocolLibrary.getErrorReporter().reportWarning(PacketRegistry.class,
|
||||
Report.newBuilder(REPORT_CANNOT_CORRECT_TROVE_MAP).error(e.getCause()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve a map of every packet class to every ID.
|
||||
* <p>
|
||||
@@ -142,38 +90,29 @@ public class PacketRegistry {
|
||||
@Deprecated
|
||||
public static Map<Class, Integer> getPacketToID() {
|
||||
initialize();
|
||||
|
||||
if (NETTY != null) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<Class, Integer> result = (Map)Maps.transformValues(NETTY.getPacketClassLookup(), new Function<PacketType, Integer>() {
|
||||
@Override
|
||||
public Integer apply(PacketType type) {
|
||||
return type.getLegacyId();
|
||||
};
|
||||
});
|
||||
return result;
|
||||
}
|
||||
return LEGACY.getPacketToID();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<Class, Integer> result = (Map) Maps.transformValues(
|
||||
NETTY.getPacketClassLookup(),
|
||||
new Function<PacketType, Integer>() {
|
||||
@Override
|
||||
public Integer apply(PacketType type) {
|
||||
return type.getLegacyId();
|
||||
};
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve a map of every packet class to the respective packet type.
|
||||
* @return A map of packet classes and their corresponding packet type.
|
||||
*/
|
||||
public static Map<Class, PacketType> getPacketToType() {
|
||||
initialize();
|
||||
|
||||
if (NETTY != null) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<Class, PacketType> result = (Map)NETTY.getPacketClassLookup();
|
||||
return result;
|
||||
}
|
||||
return Maps.transformValues(LEGACY.getPacketToID(), new Function<Integer, PacketType>() {
|
||||
@Override
|
||||
public PacketType apply(Integer packetId) {
|
||||
return PacketType.findLegacy(packetId);
|
||||
};
|
||||
});
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<Class, PacketType> result = (Map) NETTY.getPacketClassLookup();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -185,12 +124,9 @@ public class PacketRegistry {
|
||||
@Deprecated
|
||||
public static Map<Integer, Class> getOverwrittenPackets() {
|
||||
initialize();
|
||||
|
||||
if (LEGACY != null)
|
||||
return LEGACY.getOverwrittenPackets();
|
||||
throw new IllegalStateException("Not supported on Netty.");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve the vanilla classes handling each packet ID.
|
||||
* @return Vanilla classes.
|
||||
@@ -198,22 +134,19 @@ public class PacketRegistry {
|
||||
@Deprecated
|
||||
public static Map<Integer, Class> getPreviousPackets() {
|
||||
initialize();
|
||||
|
||||
if (NETTY != null) {
|
||||
// Construct it first
|
||||
if (LEGACY_PREVIOUS_PACKETS == null) {
|
||||
Map<Integer, Class> map = Maps.newHashMap();
|
||||
|
||||
for (Entry<PacketType, Class<?>> entry : NETTY.getPacketTypeLookup().entrySet()) {
|
||||
map.put(entry.getKey().getLegacyId(), entry.getValue());
|
||||
}
|
||||
LEGACY_PREVIOUS_PACKETS = Collections.unmodifiableMap(map);
|
||||
|
||||
// Construct it first
|
||||
if (LEGACY_PREVIOUS_PACKETS == null) {
|
||||
Map<Integer, Class> map = Maps.newHashMap();
|
||||
|
||||
for (Entry<PacketType, Class<?>> entry : NETTY.getPacketTypeLookup().entrySet()) {
|
||||
map.put(entry.getKey().getLegacyId(), entry.getValue());
|
||||
}
|
||||
return LEGACY_PREVIOUS_PACKETS;
|
||||
LEGACY_PREVIOUS_PACKETS = Collections.unmodifiableMap(map);
|
||||
}
|
||||
return LEGACY.getPreviousPackets();
|
||||
return LEGACY_PREVIOUS_PACKETS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve every known and supported server packet.
|
||||
* <p>
|
||||
@@ -223,15 +156,11 @@ public class PacketRegistry {
|
||||
*/
|
||||
@Deprecated
|
||||
public static Set<Integer> getServerPackets() throws FieldAccessException {
|
||||
initialize();
|
||||
|
||||
if (NETTY != null) {
|
||||
if (LEGACY_SERVER_PACKETS == null) {
|
||||
LEGACY_SERVER_PACKETS = toLegacy(NETTY.getServerPackets());
|
||||
}
|
||||
return LEGACY_SERVER_PACKETS;
|
||||
if (LEGACY_SERVER_PACKETS == null) {
|
||||
LEGACY_SERVER_PACKETS = toLegacy(getServerPacketTypes());
|
||||
}
|
||||
return LEGACY.getServerPackets();
|
||||
|
||||
return LEGACY_SERVER_PACKETS;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -240,17 +169,18 @@ public class PacketRegistry {
|
||||
*/
|
||||
public static Set<PacketType> getServerPacketTypes() {
|
||||
initialize();
|
||||
|
||||
if (NETTY != null) {
|
||||
NETTY.synchronize();
|
||||
return NETTY.getServerPackets();
|
||||
NETTY.synchronize();
|
||||
|
||||
Set<PacketType> types = new HashSet<>();
|
||||
|
||||
// Filter out unsupported packets
|
||||
for (PacketType type : NETTY.getServerPackets()) {
|
||||
if (!type.isDeprecated()) {
|
||||
types.add(type);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle legacy
|
||||
if (NETTY_SERVER_PACKETS == null) {
|
||||
NETTY_SERVER_PACKETS = toPacketTypes(LEGACY.getServerPackets(), Sender.SERVER);
|
||||
}
|
||||
return NETTY_SERVER_PACKETS;
|
||||
|
||||
return types;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -262,15 +192,11 @@ public class PacketRegistry {
|
||||
*/
|
||||
@Deprecated
|
||||
public static Set<Integer> getClientPackets() throws FieldAccessException {
|
||||
initialize();
|
||||
|
||||
if (NETTY != null) {
|
||||
if (LEGACY_CLIENT_PACKETS == null) {
|
||||
LEGACY_CLIENT_PACKETS = toLegacy(NETTY.getClientPackets());
|
||||
}
|
||||
return LEGACY_CLIENT_PACKETS;
|
||||
if (LEGACY_CLIENT_PACKETS == null) {
|
||||
LEGACY_CLIENT_PACKETS = toLegacy(getClientPacketTypes());
|
||||
}
|
||||
return LEGACY.getClientPackets();
|
||||
|
||||
return LEGACY_CLIENT_PACKETS;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -279,17 +205,18 @@ public class PacketRegistry {
|
||||
*/
|
||||
public static Set<PacketType> getClientPacketTypes() {
|
||||
initialize();
|
||||
|
||||
if (NETTY != null) {
|
||||
NETTY.synchronize();
|
||||
return NETTY.getClientPackets();
|
||||
NETTY.synchronize();
|
||||
|
||||
Set<PacketType> types = new HashSet<>();
|
||||
|
||||
// Filter out unsupported packets
|
||||
for (PacketType type : NETTY.getClientPackets()) {
|
||||
if (!type.isDeprecated()) {
|
||||
types.add(type);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle legacy
|
||||
if (NETTY_CLIENT_PACKETS == null) {
|
||||
NETTY_CLIENT_PACKETS = toPacketTypes(LEGACY.getClientPackets(), Sender.CLIENT);
|
||||
}
|
||||
return NETTY_CLIENT_PACKETS;
|
||||
|
||||
return types;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -338,10 +265,7 @@ public class PacketRegistry {
|
||||
@Deprecated
|
||||
public static Class getPacketClassFromID(int packetID) {
|
||||
initialize();
|
||||
|
||||
if (NETTY != null)
|
||||
return NETTY.getPacketTypeLookup().get(PacketType.findLegacy(packetID));
|
||||
return LEGACY.getPacketClassFromID(packetID);
|
||||
return NETTY.getPacketTypeLookup().get(PacketType.findLegacy(packetID));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -363,12 +287,26 @@ public class PacketRegistry {
|
||||
*/
|
||||
public static Class getPacketClassFromType(PacketType type, boolean forceVanilla) {
|
||||
initialize();
|
||||
|
||||
if (NETTY != null)
|
||||
return NETTY.getPacketTypeLookup().get(type);
|
||||
return LEGACY.getPacketClassFromID(type.getLegacyId(), forceVanilla);
|
||||
|
||||
// Try the lookup first
|
||||
Class<?> clazz = NETTY.getPacketTypeLookup().get(type);
|
||||
if (clazz != null) {
|
||||
return clazz;
|
||||
}
|
||||
|
||||
// Then try looking up the class names
|
||||
for (String name : type.getClassNames()) {
|
||||
try {
|
||||
clazz = MinecraftReflection.getMinecraftClass(name);
|
||||
break;
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Cache the result?
|
||||
return clazz;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the correct packet class from a given packet ID.
|
||||
* <p>
|
||||
@@ -380,12 +318,9 @@ public class PacketRegistry {
|
||||
@Deprecated
|
||||
public static Class getPacketClassFromID(int packetID, boolean forceVanilla) {
|
||||
initialize();
|
||||
|
||||
if (LEGACY != null)
|
||||
return LEGACY.getPacketClassFromID(packetID, forceVanilla);
|
||||
return getPacketClassFromID(packetID);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve the packet ID of a given packet.
|
||||
* <p>
|
||||
@@ -397,12 +332,9 @@ public class PacketRegistry {
|
||||
@Deprecated
|
||||
public static int getPacketID(Class<?> packet) {
|
||||
initialize();
|
||||
|
||||
if (NETTY != null)
|
||||
return NETTY.getPacketClassLookup().get(packet).getLegacyId();
|
||||
return LEGACY.getPacketID(packet);
|
||||
return NETTY.getPacketClassLookup().get(packet).getLegacyId();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve the packet type of a given packet.
|
||||
* @param packet - the class of the packet.
|
||||
@@ -420,14 +352,6 @@ public class PacketRegistry {
|
||||
*/
|
||||
public static PacketType getPacketType(Class<?> packet, Sender sender) {
|
||||
initialize();
|
||||
|
||||
if (NETTY != null) {
|
||||
return NETTY.getPacketClassLookup().get(packet);
|
||||
} else {
|
||||
final int id = LEGACY.getPacketID(packet);
|
||||
|
||||
return PacketType.hasLegacy(id) ?
|
||||
PacketType.fromLegacy(id, sender) : null;
|
||||
}
|
||||
return NETTY.getPacketClassLookup().get(packet);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -11,4 +11,4 @@
|
||||
* }
|
||||
* </pre>
|
||||
*/
|
||||
package com.comphenix.protocol;
|
||||
package com.comphenix.protocol;
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+38
-5
@@ -29,6 +29,8 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
|
||||
import com.comphenix.protocol.reflect.accessors.Accessors;
|
||||
import com.comphenix.protocol.reflect.fuzzy.AbstractFuzzyMatcher;
|
||||
import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract;
|
||||
@@ -168,13 +170,42 @@ public class FuzzyReflection {
|
||||
*/
|
||||
public Method getMethod(AbstractFuzzyMatcher<MethodInfo> matcher) {
|
||||
List<Method> result = getMethodList(matcher);
|
||||
|
||||
if (result.size() > 0)
|
||||
|
||||
if (result.size() > 0) {
|
||||
return result.get(0);
|
||||
else
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unable to find a method that matches " + matcher);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve a method that matches. If there are multiple methods that match, the first one with the preferred
|
||||
* name is selected.
|
||||
* <p>
|
||||
* ForceAccess must be TRUE in order for this method to access private, protected and package level method.
|
||||
* @param matcher - the matcher to use.
|
||||
* @param preferred - the preferred name.
|
||||
* @return The first method that satisfies the given matcher.
|
||||
* @throws IllegalArgumentException If the method cannot be found.
|
||||
*/
|
||||
public Method getMethod(AbstractFuzzyMatcher<MethodInfo> matcher, String preferred) {
|
||||
List<Method> result = getMethodList(matcher);
|
||||
|
||||
if (result.size() > 1) {
|
||||
for (Method method : result) {
|
||||
if (method.getName().equals(preferred)) {
|
||||
return method;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result.size() > 0) {
|
||||
return result.get(0);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unable to find a method that matches " + matcher);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a list of every method that matches the given matcher.
|
||||
* <p>
|
||||
@@ -548,6 +579,8 @@ public class FuzzyReflection {
|
||||
* @return Every field.
|
||||
*/
|
||||
public Set<Field> getFields() {
|
||||
Validate.notNull(source, "source cannot be null!");
|
||||
|
||||
// We will only consider private fields in the declared class
|
||||
if (forceAccess)
|
||||
return setUnion(source.getDeclaredFields(), source.getFields());
|
||||
@@ -603,7 +636,7 @@ public class FuzzyReflection {
|
||||
|
||||
// Prevent duplicate fields
|
||||
|
||||
// @SafeVarargs
|
||||
@SafeVarargs
|
||||
private static <T> Set<T> setUnion(T[]... array) {
|
||||
Set<T> result = new LinkedHashSet<T>();
|
||||
|
||||
File renamed without changes.
File renamed without changes.
Loaded 100 of 359 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user