some java code, update deps

This commit is contained in:
creeper123123321 2023-01-04 08:32:43 -03:00
parent 776e2fb33c
commit 69ec77b331
18 changed files with 389 additions and 240 deletions

View File

@ -9,18 +9,18 @@ import java.nio.file.Files as JFiles
buildscript {
repositories { mavenCentral() }
dependencies { classpath("com.github.hazendaz:htmlcompressor:1.7.3") }
dependencies { classpath("com.github.hazendaz:htmlcompressor:1.8.0") }
}
plugins {
`java-library`
application
kotlin("jvm") version "1.7.20"
kotlin("jvm") version "1.8.0"
id("maven-publish")
id("com.github.ben-manes.versions") version "0.42.0"
id("com.github.ben-manes.versions") version "0.44.0"
id("com.github.johnrengelman.shadow") version "7.1.2"
id("com.palantir.git-version") version "0.15.0"
id("org.gradlewebtools.minify") version "1.3.1" apply false
id("org.gradlewebtools.minify") version "1.3.2" apply false
}
application {
@ -78,12 +78,12 @@ dependencies {
implementation("com.google.guava:guava:31.1-jre")
implementation("com.velocitypowered:velocity-native:3.1.2-SNAPSHOT")
implementation("net.coobird:thumbnailator:0.4.18")
implementation("net.coobird:thumbnailator:0.4.19")
implementation("org.powernukkit.fastutil:fastutil-lite:8.1.1")
implementation("org.yaml:snakeyaml:1.33")
val log4jVer = "2.19.0"
val slf4jVer = "2.0.5"
val slf4jVer = "2.0.6"
implementation("com.lmax:disruptor:3.4.4")
implementation("net.minecrell:terminalconsoleappender:1.3.0")
implementation("org.apache.logging.log4j:log4j-core:$log4jVer")
@ -93,7 +93,7 @@ dependencies {
implementation("org.jline:jline-terminal-jansi:3.21.0")
implementation("org.slf4j:slf4j-api:$slf4jVer")
val ktorVersion = "2.2.1"
val ktorVersion = "2.2.2"
implementation("io.ktor:ktor-network-tls-certificates-jvm:$ktorVersion")
implementation("io.ktor:ktor-server-websockets:$ktorVersion")
implementation("io.ktor:ktor-server-netty-jvm:$ktorVersion")

Binary file not shown.

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

6
gradlew vendored
View File

@ -205,6 +205,12 @@ set -- \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.

14
gradlew.bat vendored
View File

@ -14,7 +14,7 @@
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@ -25,7 +25,7 @@
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
if "%DIRNAME%"=="" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@ -75,13 +75,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal

View File

@ -0,0 +1,51 @@
package com.viaversion.aas.codec;
import com.viaversion.aas.UtilKt;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.exception.CancelDecoderException;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageCodec;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
public class FrameCodec extends ByteToMessageCodec<ByteBuf> {
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
if (!ctx.channel().isActive()) {
in.clear();
// Netty throws an exception when there's no output
throw CancelDecoderException.CACHED;
}
// Ignore, should prevent DoS https://github.com/SpigotMC/BungeeCord/pull/2908
int index = in.readerIndex();
AtomicInteger nByte = new AtomicInteger();
int result = in.forEachByte(it -> {
nByte.getAndIncrement();
boolean hasNext = (it & 0x10000000) != 0;
if (nByte.get() > 3) throw UtilKt.getBadLength();
return hasNext;
});
in.readerIndex(index);
if (result == -1) return; // not readable
int length = Type.VAR_INT.readPrimitive(in);
if (length >= 2097152 || length < 0) throw UtilKt.getBadLength();
if (!in.isReadable(length)) {
in.readerIndex(index);
return;
}
out.add(in.readRetainedSlice(length));
}
@Override
protected void encode(ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out) throws Exception {
if (msg.readableBytes() >= 2097152) throw UtilKt.getBadLength();
Type.VAR_INT.writePrimitive(out, msg.readableBytes());
out.writeBytes(msg);
}
}

View File

@ -0,0 +1,62 @@
package com.viaversion.aas.codec.packet.handshake;
import com.viaversion.aas.codec.packet.Packet;
import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.api.type.Type;
import io.netty.buffer.ByteBuf;
import org.jetbrains.annotations.NotNull;
public class Handshake implements Packet {
private int protocolId;
private String address;
private int port;
private State nextState;
@Override
public void decode(@NotNull ByteBuf byteBuf, int protocolVersion) throws Exception {
protocolId = Type.VAR_INT.readPrimitive(byteBuf);
address = Type.STRING.read(byteBuf);
port = byteBuf.readUnsignedShort();
nextState = State.values()[Type.VAR_INT.readPrimitive(byteBuf)];
}
@Override
public void encode(@NotNull ByteBuf byteBuf, int protocolVersion) throws Exception {
Type.VAR_INT.writePrimitive(byteBuf, protocolId);
Type.STRING.write(byteBuf, address);
byteBuf.writeShort(port);
byteBuf.writeByte(nextState.ordinal()); // var int is too small, fits in a byte
}
public int getProtocolId() {
return protocolId;
}
public void setProtocolId(int protocolId) {
this.protocolId = protocolId;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public State getNextState() {
return nextState;
}
public void setNextState(State nextState) {
this.nextState = nextState;
}
}

View File

@ -0,0 +1,75 @@
package com.viaversion.aas.codec.packet.login;
import com.viaversion.aas.UtilKt;
import com.viaversion.aas.codec.packet.Packet;
import com.viaversion.aas.protocol.AspirinProtocolsKt;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.api.type.Type;
import io.netty.buffer.ByteBuf;
import org.jetbrains.annotations.NotNull;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
public class CryptoRequest implements Packet {
private String serverId;
private PublicKey publicKey;
private byte[] nonce;
@Override
public void decode(@NotNull ByteBuf byteBuf, int protocolVersion) throws Exception {
serverId = Type.STRING.read(byteBuf);
if (protocolVersion >= ProtocolVersion.v1_8.getVersion()
|| protocolVersion == AspirinProtocolsKt.getSharewareVersion().getVersion()) {
publicKey = KeyFactory.getInstance("RSA")
.generatePublic(new X509EncodedKeySpec(Type.BYTE_ARRAY_PRIMITIVE.read(byteBuf)));
nonce = Type.BYTE_ARRAY_PRIMITIVE.read(byteBuf);
} else {
publicKey = KeyFactory.getInstance("RSA")
.generatePublic(new X509EncodedKeySpec(UtilKt.readByteArray(byteBuf, byteBuf.readUnsignedShort())));
nonce = UtilKt.readByteArray(byteBuf, byteBuf.readUnsignedShort());
}
}
@Override
public void encode(@NotNull ByteBuf byteBuf, int protocolVersion) throws Exception {
Type.STRING.write(byteBuf, serverId);
if (protocolVersion >= ProtocolVersion.v1_8.getVersion()
|| protocolVersion == AspirinProtocolsKt.getSharewareVersion().getVersion()) {
Type.BYTE_ARRAY_PRIMITIVE.write(byteBuf, publicKey.getEncoded());
Type.BYTE_ARRAY_PRIMITIVE.write(byteBuf, nonce);
} else {
byte[] encodedKey = publicKey.getEncoded();
byteBuf.writeShort(encodedKey.length);
byteBuf.writeBytes(encodedKey);
byteBuf.writeShort(nonce.length);
byteBuf.writeBytes(nonce);
}
}
public String getServerId() {
return serverId;
}
public void setServerId(String serverId) {
this.serverId = serverId;
}
public PublicKey getPublicKey() {
return publicKey;
}
public void setPublicKey(PublicKey publicKey) {
this.publicKey = publicKey;
}
public byte[] getNonce() {
return nonce;
}
public void setNonce(byte[] nonce) {
this.nonce = nonce;
}
}

View File

@ -0,0 +1,51 @@
package com.viaversion.aas.codec.packet.login;
import com.viaversion.aas.UtilKt;
import com.viaversion.aas.codec.packet.Packet;
import com.viaversion.viaversion.api.type.Type;
import io.netty.buffer.ByteBuf;
import org.jetbrains.annotations.NotNull;
public class PluginRequest implements Packet {
private int id;
private String channel;
private byte[] data;
@Override
public void decode(@NotNull ByteBuf byteBuf, int protocolVersion) throws Exception {
id = Type.VAR_INT.readPrimitive(byteBuf);
channel = Type.STRING.read(byteBuf);
data = UtilKt.readRemainingBytes(byteBuf);
}
@Override
public void encode(@NotNull ByteBuf byteBuf, int protocolVersion) throws Exception {
Type.VAR_INT.writePrimitive(byteBuf, id);
Type.STRING.write(byteBuf, channel);
byteBuf.writeBytes(data);
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getChannel() {
return channel;
}
public void setChannel(String channel) {
this.channel = channel;
}
public byte[] getData() {
return data;
}
public void setData(byte[] data) {
this.data = data;
}
}

View File

@ -0,0 +1,55 @@
package com.viaversion.aas.codec.packet.login;
import com.viaversion.aas.UtilKt;
import com.viaversion.aas.codec.packet.Packet;
import com.viaversion.viaversion.api.type.Type;
import io.netty.buffer.ByteBuf;
import org.jetbrains.annotations.NotNull;
public class PluginResponse implements Packet {
private int id;
private boolean success;
private byte[] data;
@Override
public void decode(@NotNull ByteBuf byteBuf, int protocolVersion) throws Exception {
id = Type.VAR_INT.readPrimitive(byteBuf);
success = byteBuf.readBoolean();
if (success) {
data = UtilKt.readRemainingBytes(byteBuf);
}
}
@Override
public void encode(@NotNull ByteBuf byteBuf, int protocolVersion) throws Exception {
Type.VAR_INT.writePrimitive(byteBuf, id);
byteBuf.writeBoolean(success);
if (success) {
byteBuf.writeBytes(data);
}
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public byte[] getData() {
return data;
}
public void setData(byte[] data) {
this.data = data;
}
}

View File

@ -0,0 +1,71 @@
package com.viaversion.aas.codec.packet.play;
import com.viaversion.aas.UtilKt;
import com.viaversion.aas.codec.packet.Packet;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.api.type.Type;
import io.netty.buffer.ByteBuf;
import org.jetbrains.annotations.NotNull;
public class PluginMessage implements Packet {
private String channel;
private byte[] data;
@Override
public void decode(@NotNull ByteBuf byteBuf, int protocolVersion) throws Exception {
channel = Type.STRING.read(byteBuf);
if (protocolVersion <= ProtocolVersion.v1_7_6.getVersion()) {
data = UtilKt.readByteArray(byteBuf, readExtendedForgeShort(byteBuf));
} else {
data = UtilKt.readRemainingBytes(byteBuf);
}
}
@Override
public void encode(@NotNull ByteBuf byteBuf, int protocolVersion) throws Exception {
Type.STRING.write(byteBuf, channel);
if (protocolVersion <= ProtocolVersion.v1_7_6.getVersion()) {
writeExtendedForgeShort(byteBuf, data.length);
}
byteBuf.writeBytes(data);
}
// stolen from https://github.com/VelocityPowered/Velocity/blob/27ccb9d387fc9a0aecd5c4b570d7d957558efddc/proxy/src/main/java/com/velocitypowered/proxy/protocol/ProtocolUtils.java#L418
private int readExtendedForgeShort(ByteBuf buf) {
int low = buf.readUnsignedShort();
int high = 0;
if ((low & 0x8000) != 0) {
low = low & 0x7FFF;
high = buf.readUnsignedByte();
}
return ((high & 0xFF) << 15) | low;
}
private void writeExtendedForgeShort(ByteBuf buf, int toWrite) {
int low = toWrite & 0x7FFF;
int high = (toWrite & 0x7F8000) << 15;
if (high != 0) {
low = low | 0x8000;
}
buf.writeShort(low);
if (high != 0) {
buf.writeByte(high);
}
}
public String getChannel() {
return channel;
}
public void setChannel(String channel) {
this.channel = channel;
}
public byte[] getData() {
return data;
}
public void setData(byte[] data) {
this.data = data;
}
}

View File

@ -1,46 +0,0 @@
package com.viaversion.aas.codec
import com.viaversion.aas.badLength
import com.viaversion.viaversion.api.type.Type
import com.viaversion.viaversion.exception.CancelDecoderException
import io.netty.buffer.ByteBuf
import io.netty.channel.ChannelHandlerContext
import io.netty.handler.codec.ByteToMessageCodec
class FrameCodec : ByteToMessageCodec<ByteBuf>() {
override fun decode(ctx: ChannelHandlerContext, input: ByteBuf, out: MutableList<Any>) {
if (!ctx.channel().isActive) {
input.clear()
// Netty throws an exception when there's no output
throw CancelDecoderException.CACHED
}
// Ignore, should prevent DoS https://github.com/SpigotMC/BungeeCord/pull/2908
val index = input.readerIndex()
var nByte = 0
val result = input.forEachByte {
nByte++
val hasNext = it.toInt().and(0x10000000) != 0
if (nByte > 3) throw badLength
hasNext
}
input.readerIndex(index)
if (result == -1) return // not readable
val length = Type.VAR_INT.readPrimitive(input)
if (length >= 2097152 || length < 0) throw badLength
if (!input.isReadable(length)) {
input.readerIndex(index)
return
}
out.add(input.readRetainedSlice(length))
}
override fun encode(ctx: ChannelHandlerContext, msg: ByteBuf, out: ByteBuf) {
if (msg.readableBytes() >= 2097152) throw badLength
Type.VAR_INT.writePrimitive(out, msg.readableBytes())
out.writeBytes(msg)
}
}

View File

@ -1,29 +0,0 @@
package com.viaversion.aas.codec.packet.handshake
import com.viaversion.aas.codec.packet.Packet
import com.viaversion.viaversion.api.protocol.packet.State
import com.viaversion.viaversion.api.type.Type
import com.viaversion.viaversion.api.type.types.StringType
import io.netty.buffer.ByteBuf
import kotlin.properties.Delegates
class Handshake : Packet {
var protocolId by Delegates.notNull<Int>()
lateinit var address: String
var port by Delegates.notNull<Int>()
lateinit var nextState: State
override fun decode(byteBuf: ByteBuf, protocolVersion: Int) {
protocolId = Type.VAR_INT.readPrimitive(byteBuf)
address = Type.STRING.read(byteBuf)
port = byteBuf.readUnsignedShort()
nextState = State.values()[Type.VAR_INT.readPrimitive(byteBuf)]
}
override fun encode(byteBuf: ByteBuf, protocolVersion: Int) {
Type.VAR_INT.writePrimitive(byteBuf, protocolId)
Type.STRING.write(byteBuf, address)
byteBuf.writeShort(port)
byteBuf.writeByte(nextState.ordinal) // var int is too small, fits in a byte
}
}

View File

@ -1,44 +0,0 @@
package com.viaversion.aas.codec.packet.login
import com.viaversion.aas.codec.packet.Packet
import com.viaversion.aas.protocol.sharewareVersion
import com.viaversion.aas.readByteArray
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion
import com.viaversion.viaversion.api.type.Type
import io.netty.buffer.ByteBuf
import java.security.KeyFactory
import java.security.PublicKey
import java.security.spec.X509EncodedKeySpec
class CryptoRequest : Packet {
lateinit var serverId: String
lateinit var publicKey: PublicKey
lateinit var nonce: ByteArray
override fun decode(byteBuf: ByteBuf, protocolVersion: Int) {
serverId = Type.STRING.read(byteBuf)
if (protocolVersion >= ProtocolVersion.v1_8.version || protocolVersion == sharewareVersion.version) {
publicKey = KeyFactory.getInstance("RSA")
.generatePublic(X509EncodedKeySpec(Type.BYTE_ARRAY_PRIMITIVE.read(byteBuf)))
nonce = Type.BYTE_ARRAY_PRIMITIVE.read(byteBuf)
} else {
publicKey = KeyFactory.getInstance("RSA")
.generatePublic(X509EncodedKeySpec(byteBuf.readByteArray(byteBuf.readUnsignedShort())))
nonce = byteBuf.readByteArray(byteBuf.readUnsignedShort())
}
}
override fun encode(byteBuf: ByteBuf, protocolVersion: Int) {
Type.STRING.write(byteBuf, serverId)
if (protocolVersion >= ProtocolVersion.v1_8.version || protocolVersion == sharewareVersion.version) {
Type.BYTE_ARRAY_PRIMITIVE.write(byteBuf, publicKey.encoded)
Type.BYTE_ARRAY_PRIMITIVE.write(byteBuf, nonce)
} else {
val encodedKey = publicKey.encoded
byteBuf.writeShort(encodedKey.size)
byteBuf.writeBytes(encodedKey)
byteBuf.writeShort(nonce.size)
byteBuf.writeBytes(nonce)
}
}
}

View File

@ -1,24 +0,0 @@
package com.viaversion.aas.codec.packet.login
import com.viaversion.aas.codec.packet.Packet
import com.viaversion.aas.readRemainingBytes
import com.viaversion.viaversion.api.type.Type
import io.netty.buffer.ByteBuf
import kotlin.properties.Delegates
class PluginRequest : Packet {
var id by Delegates.notNull<Int>()
lateinit var channel: String
lateinit var data: ByteArray
override fun decode(byteBuf: ByteBuf, protocolVersion: Int) {
id = Type.VAR_INT.readPrimitive(byteBuf)
channel = Type.STRING.read(byteBuf)
data = readRemainingBytes(byteBuf)
}
override fun encode(byteBuf: ByteBuf, protocolVersion: Int) {
Type.VAR_INT.writePrimitive(byteBuf, id)
Type.STRING.write(byteBuf, channel)
byteBuf.writeBytes(data)
}
}

View File

@ -1,28 +0,0 @@
package com.viaversion.aas.codec.packet.login
import com.viaversion.aas.codec.packet.Packet
import com.viaversion.aas.readRemainingBytes
import com.viaversion.viaversion.api.type.Type
import io.netty.buffer.ByteBuf
import kotlin.properties.Delegates
class PluginResponse : Packet {
var id by Delegates.notNull<Int>()
var success by Delegates.notNull<Boolean>()
lateinit var data: ByteArray
override fun decode(byteBuf: ByteBuf, protocolVersion: Int) {
id = Type.VAR_INT.readPrimitive(byteBuf)
success = byteBuf.readBoolean()
if (success) {
data = readRemainingBytes(byteBuf)
}
}
override fun encode(byteBuf: ByteBuf, protocolVersion: Int) {
Type.VAR_INT.writePrimitive(byteBuf, id)
byteBuf.writeBoolean(success)
if (success) {
byteBuf.writeBytes(data)
}
}
}

View File

@ -1,53 +0,0 @@
package com.viaversion.aas.codec.packet.play
import com.viaversion.aas.codec.packet.Packet
import com.viaversion.aas.readByteArray
import com.viaversion.aas.readRemainingBytes
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion
import com.viaversion.viaversion.api.type.Type
import io.netty.buffer.ByteBuf
class PluginMessage : Packet {
lateinit var channel: String
lateinit var data: ByteArray
override fun decode(byteBuf: ByteBuf, protocolVersion: Int) {
channel = Type.STRING.read(byteBuf)
data = if (protocolVersion <= ProtocolVersion.v1_7_6.version) {
byteBuf.readByteArray(readExtendedForgeShort(byteBuf))
} else {
readRemainingBytes(byteBuf)
}
}
override fun encode(byteBuf: ByteBuf, protocolVersion: Int) {
Type.STRING.write(byteBuf, channel)
if (protocolVersion <= ProtocolVersion.v1_7_6.version) {
writeExtendedForgeShort(byteBuf, data.size)
}
byteBuf.writeBytes(data)
}
// stolen from https://github.com/VelocityPowered/Velocity/blob/27ccb9d387fc9a0aecd5c4b570d7d957558efddc/proxy/src/main/java/com/velocitypowered/proxy/protocol/ProtocolUtils.java#L418
fun readExtendedForgeShort(buf: ByteBuf): Int {
var low = buf.readUnsignedShort()
var high = 0
if (low and 0x8000 != 0) {
low = low and 0x7FFF
high = buf.readUnsignedByte().toInt()
}
return high and 0xFF shl 15 or low
}
fun writeExtendedForgeShort(buf: ByteBuf, toWrite: Int) {
var low = toWrite and 0x7FFF
val high = toWrite.and(0x7F8000).shr(15)
if (high != 0) {
low = low or 0x8000
}
buf.writeShort(low)
if (high != 0) {
buf.writeByte(high)
}
}
}

View File

@ -72,7 +72,7 @@ class LoginState : ConnectionState {
private fun handleReauthResponse(packet: PluginResponse): Boolean {
if (packet.id == pendingReauth) {
pendingReauth = null
if (packet.success) {
if (packet.isSuccess) {
val buf = Unpooled.wrappedBuffer(packet.data)
callbackReauth.complete(buf.readBoolean())
} else {
@ -212,7 +212,7 @@ class LoginState : ConnectionState {
val id = Type.VAR_INT.readPrimitive(buffer)
val data = readRemainingBytes(buffer)
if (handleReauthResponse(PluginResponse().also {
it.success = true
it.isSuccess = true
it.id = id
it.data = data
})) return