99import io .netty .buffer .ByteBuf ;
1010import io .netty .buffer .ByteBufUtil ;
1111import io .netty .buffer .Unpooled ;
12+ import io .netty .channel .Channel ;
1213import io .netty .channel .ChannelHandlerContext ;
1314import io .netty .handler .codec .MessageToMessageCodec ;
1415import io .netty .handler .codec .http .websocketx .BinaryWebSocketFrame ;
3536import java .awt .image .Raster ;
3637import java .io .ByteArrayOutputStream ;
3738import java .io .IOException ;
39+ import java .io .InputStream ;
3840import java .nio .charset .StandardCharsets ;
3941import java .util .List ;
4042import java .util .*;
@@ -153,59 +155,88 @@ public void encodeOld(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
153155 }
154156 if (in .readableBytes () >= 2 && in .getUnsignedByte (0 ) == 2 ) {
155157 in .setByte (1 , in .getUnsignedByte (1 ) + 8 );
158+ out .add (new BinaryWebSocketFrame (in .retain ()));
159+
160+ Channel c2p ;
161+ if (proxyConnection instanceof ProxyConnection ) {
162+ c2p = ((ProxyConnection ) proxyConnection ).getC2P ();
163+ } else {
164+ c2p = ((LegacyProxyConnection ) proxyConnection ).getC2P ();
165+ }
166+ if (c2p .hasAttr (EaglercraftHandler .profileDataKey )) {
167+ EaglercraftHandler .ProfileData profileData = c2p .attr (EaglercraftHandler .profileDataKey ).get ();
168+ if (profileData .type .equals ("skin_v1" )) {
169+ int packetType = profileData .data [0 ] & 0xFF ;
170+ if (packetType == 1 || packetType == 2 ) {
171+ try {
172+ byte [] res = SkinService .newToOldSkin (profileData .data );
173+ ByteBuf bb = ctx .alloc ().buffer ();
174+ bb .writeByte ((byte ) 250 );
175+ Types1_6_4 .STRING .write (bb , "EAG|MySkin" );
176+ bb .writeShort (res .length );
177+ bb .writeBytes (res );
178+ out .add (new BinaryWebSocketFrame (bb ));
179+ } catch (Exception ignored ) {}
180+ }
181+
182+ }
183+ }
184+ return ;
156185 }
157186 if (in .getUnsignedByte (0 ) == 0xFD ) {
158187 return ;
159188 }
160- if (in .readableBytes () >= 3 && in .getUnsignedByte (0 ) == 250 ) {
161- in .skipBytes (1 );
162- String tag ;
163- byte [] msg ;
164- try {
165- tag = Types1_6_4 .STRING .read (in );
166- if (tag .equals ("EAG|Skins-1.8" )) {
167- msg = new byte [in .readShort ()];
168- in .readBytes (msg );
169- if (msg .length == 0 ) {
170- throw new IOException ("Zero-length packet recieved" );
171- }
172- final int packetId = msg [0 ] & 0xFF ;
173- switch (packetId ) {
174- case 3 : {
175- if (msg .length != 17 ) {
176- throw new IOException ("Invalid length " + msg .length + " for skin request packet" );
189+ if (proxyConnection instanceof ProxyConnection ) {
190+ if (in .readableBytes () >= 3 && in .getUnsignedByte (0 ) == 250 ) {
191+ in .skipBytes (1 );
192+ String tag ;
193+ byte [] msg ;
194+ try {
195+ tag = Types1_6_4 .STRING .read (in );
196+ if (tag .equals ("EAG|Skins-1.8" )) {
197+ msg = new byte [in .readShort ()];
198+ in .readBytes (msg );
199+ if (msg .length == 0 ) {
200+ throw new IOException ("Zero-length packet recieved" );
201+ }
202+ final int packetId = msg [0 ] & 0xFF ;
203+ switch (packetId ) {
204+ case 3 : {
205+ if (msg .length != 17 ) {
206+ throw new IOException ("Invalid length " + msg .length + " for skin request packet" );
207+ }
208+ final UUID searchUUID = SkinPackets .bytesToUUID (msg , 1 );
209+ if (uuidStringMap .containsKey (searchUUID )) {
210+ short id = skinFetchCounter ++;
211+ skinsBeingFetched .put (id , searchUUID );
212+ String name = uuidStringMap .get (searchUUID );
213+ ByteBuf bb = ctx .alloc ().buffer ();
214+ bb .writeByte ((byte ) 250 );
215+ Types1_6_4 .STRING .write (bb , "EAG|FetchSkin" );
216+ ByteBuf bbb = ctx .alloc ().buffer ();
217+ bbb .writeByte ((byte ) ((id >> 8 ) & 0xFF ));
218+ bbb .writeByte ((byte ) (id & 0xFF ));
219+ bbb .writeBytes (name .getBytes (StandardCharsets .UTF_8 ));
220+ bb .writeShort (bbb .readableBytes ());
221+ bb .writeBytes (bbb );
222+ bbb .release ();
223+ out .add (new BinaryWebSocketFrame (bb ));
224+ }
225+ break ;
177226 }
178- final UUID searchUUID = SkinPackets .bytesToUUID (msg , 1 );
179- if (uuidStringMap .containsKey (searchUUID )) {
180- short id = skinFetchCounter ++;
181- skinsBeingFetched .put (id , searchUUID );
182- String name = uuidStringMap .get (searchUUID );
183- ByteBuf bb = ctx .alloc ().buffer ();
184- bb .writeByte ((byte ) 250 );
185- Types1_6_4 .STRING .write (bb , "EAG|FetchSkin" );
186- ByteBuf bbb = ctx .alloc ().buffer ();
187- bbb .writeByte ((byte ) ((id >> 8 ) & 0xFF ));
188- bbb .writeByte ((byte ) (id & 0xFF ));
189- bbb .writeBytes (name .getBytes (StandardCharsets .UTF_8 ));
190- bb .writeShort (bbb .readableBytes ());
191- bb .writeBytes (bbb );
192- bbb .release ();
193- out .add (new BinaryWebSocketFrame (bb ));
227+ case 6 : {
228+ break ;
229+ }
230+ default : {
231+ throw new IOException ("Unknown packet type " + packetId );
194232 }
195- break ;
196- }
197- case 6 : {
198- break ;
199- }
200- default : {
201- throw new IOException ("Unknown packet type " + packetId );
202233 }
234+ return ;
203235 }
204- return ;
236+ } catch ( Exception ignored ) {
205237 }
206- } catch ( Exception ignored ) {
238+ in . resetReaderIndex ();
207239 }
208- in .resetReaderIndex ();
209240 }
210241 out .add (new BinaryWebSocketFrame (in .retain ()));
211242 }
@@ -438,35 +469,37 @@ public void decode(ChannelHandlerContext ctx, WebSocketFrame in, List<Object> ou
438469 }
439470 }
440471 public void decodeOld (ChannelHandlerContext ctx , ByteBuf in , List <Object > out ) {
441- if (in .getUnsignedByte (0 ) == 0x14 ) {
442- try {
443- in .skipBytes (1 );
444- int eid = in .readInt ();
445- String name = Types1_6_4 .STRING .read (in );
446- UUID uuid = UUID .nameUUIDFromBytes (("OfflinePlayer:" + name ).getBytes (StandardCharsets .UTF_8 ));
447- eidUuidMap .put (eid , uuid );
448- uuidStringMap .put (uuid , name );
449- } catch (Exception ignored ) {
450- }
451- in .resetReaderIndex ();
452- }
453- if (in .getUnsignedByte (0 ) == 0x1D ) {
454- try {
455- in .skipBytes (1 );
456- short count = in .readUnsignedByte ();
457- for (short i = 0 ; i < count ; i ++) {
472+ if (proxyConnection instanceof ProxyConnection ) {
473+ if (in .getUnsignedByte (0 ) == 0x14 ) {
474+ try {
475+ in .skipBytes (1 );
458476 int eid = in .readInt ();
459- if (eidUuidMap .containsKey (eid )) {
460- uuidStringMap .remove (eidUuidMap .remove (eid ));
477+ String name = Types1_6_4 .STRING .read (in );
478+ UUID uuid = UUID .nameUUIDFromBytes (("OfflinePlayer:" + name ).getBytes (StandardCharsets .UTF_8 ));
479+ eidUuidMap .put (eid , uuid );
480+ uuidStringMap .put (uuid , name );
481+ } catch (Exception ignored ) {
482+ }
483+ in .resetReaderIndex ();
484+ }
485+ if (in .getUnsignedByte (0 ) == 0x1D ) {
486+ try {
487+ in .skipBytes (1 );
488+ short count = in .readUnsignedByte ();
489+ for (short i = 0 ; i < count ; i ++) {
490+ int eid = in .readInt ();
491+ if (eidUuidMap .containsKey (eid )) {
492+ uuidStringMap .remove (eidUuidMap .remove (eid ));
493+ }
461494 }
495+ } catch (Exception ignored ) {
462496 }
463- } catch (Exception ignored ) {
497+ in .resetReaderIndex ();
498+ }
499+ if (in .getUnsignedByte (0 ) == 0x09 ) {
500+ eidUuidMap .clear ();
501+ uuidStringMap .clear ();
464502 }
465- in .resetReaderIndex ();
466- }
467- if (in .getUnsignedByte (0 ) == 0x09 ) {
468- eidUuidMap .clear ();
469- uuidStringMap .clear ();
470503 }
471504 if (in .getUnsignedByte (0 ) == 0xFD ) {
472505 in .writerIndex (0 );
@@ -481,16 +514,32 @@ public void decodeOld(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
481514 byte [] msg ;
482515 try {
483516 tag = Types1_6_4 .STRING .read (in );
484- if (tag .equals ("EAG|UserSkin" )) {
517+ if (proxyConnection instanceof ProxyConnection && tag .equals ("EAG|UserSkin" )) {
485518 msg = new byte [in .readShort ()];
486519 in .readBytes (msg );
487520 short id = (short ) ((msg [0 ] << 8 ) + msg [1 ]);
488521 if (!skinsBeingFetched .containsKey (id )) {
489522 return ;
490523 }
491- byte [] res = new byte [msg .length - 3 ];
524+ byte [] res = new byte [Math . min ( 16384 , msg .length - 3 ) ];
492525 System .arraycopy (msg , 3 , res , 0 , res .length );
493- if (res .length == 8192 ) {
526+ if (res .length <= 16 ) {
527+ int presetId = res [0 ] & 0xFF ;
528+ InputStream stream = Main .class .getResourceAsStream ("/n" + presetId + ".png" );
529+ if (stream != null ) {
530+ try {
531+ res = ((DataBufferByte ) ImageIO .read (stream ).getRaster ().getDataBuffer ()).getData ();
532+ for (int i = 0 ; i < res .length ; i += 4 ) {
533+ final byte tmp = res [i ];
534+ res [i ] = res [i + 1 ];
535+ res [i + 1 ] = res [i + 2 ];
536+ res [i + 2 ] = res [i + 3 ];
537+ res [i + 3 ] = tmp ;
538+ }
539+ } catch (IOException ignored ) {}
540+ }
541+ }
542+ if (res .length >= 8192 && res .length < 16384 ) {
494543 final int [] tmp1 = new int [2048 ];
495544 final int [] tmp2 = new int [4096 ];
496545 for (int i = 0 ; i < tmp1 .length ; ++i ) {
0 commit comments