· 9 years ago · Aug 31, 2016, 07:40 PM
1package net.minecraft.server.v1_8_R3;
2
3import com.google.common.collect.Queues;
4import com.google.common.util.concurrent.ThreadFactoryBuilder;
5import com.mojang.authlib.properties.Property;
6import io.netty.channel.Channel;
7import io.netty.channel.ChannelConfig;
8import io.netty.channel.ChannelFuture;
9import io.netty.channel.ChannelFutureListener;
10import io.netty.channel.ChannelHandler;
11import io.netty.channel.ChannelHandlerContext;
12import io.netty.channel.ChannelPipeline;
13import io.netty.channel.EventLoop;
14import io.netty.channel.SimpleChannelInboundHandler;
15import io.netty.channel.epoll.EpollEventLoopGroup;
16import io.netty.channel.local.LocalChannel;
17import io.netty.channel.local.LocalEventLoopGroup;
18import io.netty.channel.local.LocalServerChannel;
19import io.netty.channel.nio.NioEventLoopGroup;
20import io.netty.handler.timeout.TimeoutException;
21import io.netty.util.Attribute;
22import io.netty.util.AttributeKey;
23import io.netty.util.concurrent.Future;
24import io.netty.util.concurrent.GenericFutureListener;
25import java.net.SocketAddress;
26import java.util.Queue;
27import java.util.UUID;
28import java.util.concurrent.ThreadFactory;
29import java.util.concurrent.locks.ReentrantReadWriteLock;
30import javax.crypto.Cipher;
31import javax.crypto.SecretKey;
32import net.minecraft.server.v1_8_R3.CancelledPacketHandleException;
33import net.minecraft.server.v1_8_R3.ChatComponentText;
34import net.minecraft.server.v1_8_R3.ChatMessage;
35import net.minecraft.server.v1_8_R3.EnumProtocol;
36import net.minecraft.server.v1_8_R3.EnumProtocolDirection;
37import net.minecraft.server.v1_8_R3.IChatBaseComponent;
38import net.minecraft.server.v1_8_R3.IUpdatePlayerListBox;
39import net.minecraft.server.v1_8_R3.LazyInitVar;
40import net.minecraft.server.v1_8_R3.MinecraftEncryption;
41import net.minecraft.server.v1_8_R3.MinecraftServer;
42import net.minecraft.server.v1_8_R3.Packet;
43import net.minecraft.server.v1_8_R3.PacketCompressor;
44import net.minecraft.server.v1_8_R3.PacketDecompressor;
45import net.minecraft.server.v1_8_R3.PacketDecrypter;
46import net.minecraft.server.v1_8_R3.PacketEncrypter;
47import net.minecraft.server.v1_8_R3.PacketListener;
48import org.apache.commons.lang3.ArrayUtils;
49import org.apache.commons.lang3.Validate;
50import org.apache.logging.log4j.LogManager;
51import org.apache.logging.log4j.Logger;
52import org.apache.logging.log4j.Marker;
53import org.apache.logging.log4j.MarkerManager;
54
55public class NetworkManager
56extends SimpleChannelInboundHandler<Packet> {
57 private static final Logger g = LogManager.getLogger();
58 public static final Marker a = MarkerManager.getMarker("NETWORK");
59 public static final Marker b = MarkerManager.getMarker("NETWORK_PACKETS", a);
60 public static final AttributeKey<EnumProtocol> c = AttributeKey.valueOf("protocol");
61 public static final LazyInitVar<NioEventLoopGroup> d = new LazyInitVar(){
62
63 protected NioEventLoopGroup a() {
64 return new NioEventLoopGroup(0, new ThreadFactoryBuilder().setNameFormat("Netty Client IO #%d").setDaemon(true).build());
65 }
66
67 protected Object init() {
68 return this.a();
69 }
70 };
71 public static final LazyInitVar<EpollEventLoopGroup> e = new LazyInitVar(){
72
73 protected EpollEventLoopGroup a() {
74 return new EpollEventLoopGroup(0, new ThreadFactoryBuilder().setNameFormat("Netty Epoll Client IO #%d").setDaemon(true).build());
75 }
76
77 protected Object init() {
78 return this.a();
79 }
80 };
81 public static final LazyInitVar<LocalEventLoopGroup> f = new LazyInitVar(){
82
83 protected LocalEventLoopGroup a() {
84 return new LocalEventLoopGroup(0, new ThreadFactoryBuilder().setNameFormat("Netty Local Client IO #%d").setDaemon(true).build());
85 }
86
87 protected Object init() {
88 return this.a();
89 }
90 };
91 private final EnumProtocolDirection h;
92 private final Queue<QueuedPacket> i = Queues.newConcurrentLinkedQueue();
93 private final ReentrantReadWriteLock j = new ReentrantReadWriteLock();
94 public Channel channel;
95 public SocketAddress l;
96 public UUID spoofedUUID;
97 public Property[] spoofedProfile;
98 public boolean preparing = true;
99 private PacketListener m;
100 private IChatBaseComponent n;
101 private boolean o;
102 private boolean p;
103
104 public NetworkManager(EnumProtocolDirection enumprotocoldirection) {
105 this.h = enumprotocoldirection;
106 }
107
108 @Override
109 public void channelActive(ChannelHandlerContext channelhandlercontext) throws Exception {
110 super.channelActive(channelhandlercontext);
111 this.channel = channelhandlercontext.channel();
112 this.l = this.channel.remoteAddress();
113 this.preparing = false;
114 try {
115 this.a(EnumProtocol.HANDSHAKING);
116 }
117 catch (Throwable throwable) {
118 g.fatal(throwable);
119 }
120 }
121
122 public void a(EnumProtocol enumprotocol) {
123 this.channel.attr(c).set(enumprotocol);
124 this.channel.config().setAutoRead(true);
125 g.debug("Enabled auto read");
126 }
127
128 @Override
129 public void channelInactive(ChannelHandlerContext channelhandlercontext) throws Exception {
130 this.close(new ChatMessage("disconnect.endOfStream", new Object[0]));
131 }
132
133 @Override
134 public void exceptionCaught(ChannelHandlerContext channelhandlercontext, Throwable throwable) throws Exception {
135 ChatMessage chatmessage = throwable instanceof TimeoutException ? new ChatMessage("disconnect.timeout", new Object[0]) : new ChatMessage("disconnect.genericReason", "Internal Exception: " + throwable);
136 this.close(chatmessage);
137 if (MinecraftServer.getServer().isDebugging()) {
138 throwable.printStackTrace();
139 }
140 }
141
142 protected void a(ChannelHandlerContext channelhandlercontext, Packet packet) throws Exception {
143 if (this.channel.isOpen()) {
144 try {
145 packet.a(this.m);
146 }
147 catch (CancelledPacketHandleException v0) {}
148 }
149 }
150
151 public void a(PacketListener packetlistener) {
152 Validate.notNull(packetlistener, "packetListener", new Object[0]);
153 g.debug("Set listener of {} to {}", this, packetlistener);
154 this.m = packetlistener;
155 }
156
157 public void handle(Packet packet) {
158 if (this.g()) {
159 this.m();
160 this.a(packet, null);
161 } else {
162 this.j.writeLock().lock();
163 try {
164 this.i.add(new QueuedPacket(packet, null));
165 }
166 finally {
167 this.j.writeLock().unlock();
168 }
169 }
170 }
171
172 public /* varargs */ void a(Packet packet, GenericFutureListener<? extends Future<? super Void>> genericfuturelistener, GenericFutureListener<? extends Future<? super Void>> ... agenericfuturelistener) {
173 if (this.g()) {
174 this.m();
175 this.a(packet, ArrayUtils.add(agenericfuturelistener, 0, genericfuturelistener));
176 } else {
177 this.j.writeLock().lock();
178 try {
179 this.i.add(new QueuedPacket(packet, ArrayUtils.add(agenericfuturelistener, 0, genericfuturelistener)));
180 }
181 finally {
182 this.j.writeLock().unlock();
183 }
184 }
185 }
186
187 private void a(final Packet packet, final GenericFutureListener<? extends Future<? super Void>>[] agenericfuturelistener) {
188 final EnumProtocol enumprotocol = EnumProtocol.a(packet);
189 final EnumProtocol enumprotocol1 = this.channel.attr(c).get();
190 if (enumprotocol1 != enumprotocol) {
191 g.debug("Disabled auto read");
192 this.channel.config().setAutoRead(false);
193 }
194 if (this.channel.eventLoop().inEventLoop()) {
195 if (enumprotocol != enumprotocol1) {
196 this.a(enumprotocol);
197 }
198 ChannelFuture channelfuture = this.channel.writeAndFlush(packet);
199 if (agenericfuturelistener != null) {
200 channelfuture.addListeners(agenericfuturelistener);
201 }
202 channelfuture.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
203 } else {
204 this.channel.eventLoop().execute(new Runnable(){
205
206 @Override
207 public void run() {
208 if (enumprotocol != enumprotocol1) {
209 NetworkManager.this.a(enumprotocol);
210 }
211 ChannelFuture channelfuture = NetworkManager.this.channel.writeAndFlush(packet);
212 if (agenericfuturelistener != null) {
213 channelfuture.addListeners(agenericfuturelistener);
214 }
215 channelfuture.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
216 }
217 });
218 }
219 }
220
221 private void m() {
222 if (this.channel != null && this.channel.isOpen()) {
223 this.j.readLock().lock();
224 try {
225 while (!this.i.isEmpty()) {
226 QueuedPacket networkmanager_queuedpacket = this.i.poll();
227 this.a(networkmanager_queuedpacket.a, networkmanager_queuedpacket.b);
228 }
229 }
230 finally {
231 this.j.readLock().unlock();
232 }
233 }
234 }
235
236 public void a() {
237 this.m();
238 if (this.m instanceof IUpdatePlayerListBox) {
239 ((IUpdatePlayerListBox)((Object)this.m)).c();
240 }
241 this.channel.flush();
242 }
243
244 public SocketAddress getSocketAddress() {
245 return this.l;
246 }
247
248 public void close(IChatBaseComponent ichatbasecomponent) {
249 this.preparing = false;
250 if (this.channel.isOpen()) {
251 this.channel.close();
252 this.n = ichatbasecomponent;
253 }
254 }
255
256 public boolean c() {
257 if (!(this.channel instanceof LocalChannel) && !(this.channel instanceof LocalServerChannel)) {
258 return false;
259 }
260 return true;
261 }
262
263 public void a(SecretKey secretkey) {
264 this.o = true;
265 this.channel.pipeline().addBefore("splitter", "decrypt", new PacketDecrypter(MinecraftEncryption.a(2, secretkey)));
266 this.channel.pipeline().addBefore("prepender", "encrypt", new PacketEncrypter(MinecraftEncryption.a(1, secretkey)));
267 }
268
269 public boolean g() {
270 if (this.channel != null && this.channel.isOpen()) {
271 return true;
272 }
273 return false;
274 }
275
276 public boolean h() {
277 if (this.channel == null) {
278 return true;
279 }
280 return false;
281 }
282
283 public PacketListener getPacketListener() {
284 return this.m;
285 }
286
287 public IChatBaseComponent j() {
288 return this.n;
289 }
290
291 public void k() {
292 this.channel.config().setAutoRead(false);
293 }
294
295 public void a(int i) {
296 if (i >= 0) {
297 if (this.channel.pipeline().get("decompress") instanceof PacketDecompressor) {
298 ((PacketDecompressor)this.channel.pipeline().get("decompress")).a(i);
299 } else {
300 this.channel.pipeline().addBefore("decoder", "decompress", new PacketDecompressor(i));
301 }
302 if (this.channel.pipeline().get("compress") instanceof PacketCompressor) {
303 ((PacketCompressor)this.channel.pipeline().get("decompress")).a(i);
304 } else {
305 this.channel.pipeline().addBefore("encoder", "compress", new PacketCompressor(i));
306 }
307 } else {
308 if (this.channel.pipeline().get("decompress") instanceof PacketDecompressor) {
309 this.channel.pipeline().remove("decompress");
310 }
311 if (this.channel.pipeline().get("compress") instanceof PacketCompressor) {
312 this.channel.pipeline().remove("compress");
313 }
314 }
315 }
316
317 public void l() {
318 if (this.channel != null && !this.channel.isOpen()) {
319 if (!this.p) {
320 this.p = true;
321 if (this.j() != null) {
322 this.getPacketListener().a(this.j());
323 } else if (this.getPacketListener() != null) {
324 this.getPacketListener().a(new ChatComponentText("Disconnected"));
325 }
326 this.i.clear();
327 } else {
328 g.warn("handleDisconnection() called twice");
329 }
330 }
331 }
332
333 @Override
334 protected void channelRead0(ChannelHandlerContext channelhandlercontext, Packet object) throws Exception {
335 this.a(channelhandlercontext, object);
336 }
337
338 public SocketAddress getRawAddress() {
339 return this.channel.remoteAddress();
340 }
341
342 static class QueuedPacket {
343 private final Packet a;
344 private final GenericFutureListener<? extends Future<? super Void>>[] b;
345
346 public /* varargs */ QueuedPacket(Packet packet, GenericFutureListener<? extends Future<? super Void>> ... agenericfuturelistener) {
347 this.a = packet;
348 this.b = agenericfuturelistener;
349 }
350 }
351
352}