diff --git a/mirai-core/src/main/java/net/mamoe/mirai/MiraiServer.java b/mirai-core/src/main/java/net/mamoe/mirai/MiraiServer.java index 06eacdb74..a93fba56d 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/MiraiServer.java +++ b/mirai-core/src/main/java/net/mamoe/mirai/MiraiServer.java @@ -28,7 +28,7 @@ import java.util.concurrent.ExecutionException; * * @author NaturalHG */ -public class MiraiServer { +public final class MiraiServer { private static MiraiServer instance; public static MiraiServer getInstance() { diff --git a/mirai-core/src/main/java/net/mamoe/mirai/message/defaults/Image.kt b/mirai-core/src/main/java/net/mamoe/mirai/message/defaults/Image.kt index b168c250c..08b80853e 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/message/defaults/Image.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/message/defaults/Image.kt @@ -2,6 +2,8 @@ package net.mamoe.mirai.message.defaults import net.mamoe.mirai.message.Message import net.mamoe.mirai.message.MessageId +import net.mamoe.mirai.network.packet.cutTail +import net.mamoe.mirai.network.packet.md5 import java.awt.image.BufferedImage import java.io.* import java.net.URL @@ -54,4 +56,12 @@ class Image : Message { } return this.imageID == another.imageID } + + companion object { + fun getImageID(filename: String): ByteArray = md5(filename).cutTail(1) + } +} + +fun main() { + println(0xB0) } \ No newline at end of file diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ClientPacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ClientPacket.kt index 54ad2301a..e1d671231 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ClientPacket.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ClientPacket.kt @@ -244,4 +244,14 @@ fun DataOutputStream.writeVarByteArray(byteArray: ByteArray) { fun DataOutputStream.writeVarString(str: String) { this.writeVarByteArray(str.toByteArray()) +} + +fun DataOutputStream.writeVarShort(short: Int) { + this.writeByte(0x02) + this.writeShort(short) +} + +fun DataOutputStream.writeVarInt(int: Int) { + this.writeByte(0x04) + this.writeInt(int) } \ No newline at end of file diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/image/ClientGetGroupImageIDPacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/image/ClientGetGroupImageIDPacket.kt new file mode 100644 index 000000000..fec7478db --- /dev/null +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/image/ClientGetGroupImageIDPacket.kt @@ -0,0 +1,35 @@ +package net.mamoe.mirai.network.packet.image + +import net.mamoe.mirai.network.packet.* +import net.mamoe.mirai.utils.writeProtoInt +import java.awt.image.BufferedImage + +/** + * 查询群消息的 image id. + * That is, 查询服务器上是否有这个图片, 有就返回 id, 没有就需要上传 + * + * @author Him188moe + */ +@PacketId("03 88") +@ExperimentalUnsignedTypes +class ClientGetGroupImageIDPacket( + val bot: Long, + val sessionKey: ByteArray, + val group: Long, + val image: BufferedImage +) : ClientPacket() { + override fun encode() { + this.writeRandom(2) + + this.writeQQ(bot) + this.writeHex("04 00 00 00 01 01 01 00 00 68 20 00 00 00 00 00 00 00 00") + this.encryptAndWrite(sessionKey) { + it.writeHex("00 00 00 07 00 00 00 5E 08 01 12 03 98 01 01 10 01 1A") + it.writeHex("5A") + it.writeHex("08") + it.writeProtoInt(group) + it.writeHex("08") + it.writeProtoInt(image.height) + } + } +} \ No newline at end of file diff --git a/mirai-core/src/main/java/net/mamoe/mirai/utils/CharImageConverter.java b/mirai-core/src/main/java/net/mamoe/mirai/utils/CharImageConverter.java index 23ca34656..365b41756 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/utils/CharImageConverter.java +++ b/mirai-core/src/main/java/net/mamoe/mirai/utils/CharImageConverter.java @@ -8,9 +8,10 @@ import java.util.concurrent.Callable; /** * Convert IMAGE into Chars that could shows in terminal + * * @author NaturalHG */ -public class CharImageConverter implements Callable { +public final class CharImageConverter implements Callable { /** * width should depends on the width of the terminal @@ -19,74 +20,73 @@ public class CharImageConverter implements Callable { private int width; private double ignoreRate; - public CharImageConverter(BufferedImage image, int width){ - this(image,width,0.95); + public CharImageConverter(BufferedImage image, int width) { + this(image, width, 0.95); } - public CharImageConverter(BufferedImage image, int width, double ignoreRate){ + public CharImageConverter(BufferedImage image, int width, double ignoreRate) { this.image = image; this.width = width; this.ignoreRate = ignoreRate; } @Override - public String call(){ - /* - * resize Image - * */ - int newHeight = (int)(this.image.getHeight() * (((double)width) /this.image.getWidth())); + public String call() { + /* + * resize Image + * */ + int newHeight = (int) (this.image.getHeight() * (((double) width) / this.image.getWidth())); Image tmp = image.getScaledInstance(width, newHeight, Image.SCALE_SMOOTH); BufferedImage dimg = new BufferedImage(width, newHeight, BufferedImage.TYPE_INT_ARGB); Graphics2D g2d = dimg.createGraphics(); g2d.drawImage(tmp, 0, 0, null); this.image = dimg; - int background = this.gray(image.getRGB(0,0)); + int background = gray(image.getRGB(0, 0)); - StringBuilder builder = new StringBuilder(); + StringBuilder builder = new StringBuilder(); - List lines = new ArrayList<>(this.image.getHeight()); + List lines = new ArrayList<>(this.image.getHeight()); - int minXPos = this.width; - int maxXPos = 0; + int minXPos = this.width; + int maxXPos = 0; - for (int y = 0; y < image.getHeight(); y++) { - StringBuilder builderLine = new StringBuilder(); - for (int x = 0; x < image.getWidth(); x++) { - int gray = this.gray(image.getRGB(x, y)); - if (grayCompare(gray, background)) { - builderLine.append(" "); - } else { - builderLine.append("#"); - if (x < minXPos) { - minXPos = x; - } - if (x > maxXPos) { - maxXPos = x; - } - } - } - if (builderLine.toString().isBlank()) { - continue; - } - lines.add(builderLine); - } - for (int i=0;i maxXPos) { + maxXPos = x; + } + } + } + if (builderLine.toString().isBlank()) { + continue; + } + lines.add(builderLine); } - return builder.toString(); + for (StringBuilder line : lines) { + builder.append(line.substring(minXPos, maxXPos)).append("\n"); + } + return builder.toString(); } - private int gray(int rgb) { + private static int gray(int rgb) { int R = (rgb & 0xff0000) >> 16; int G = (rgb & 0x00ff00) >> 8; int B = rgb & 0x0000ff; - int gray = (R * 30 + G * 59 + B * 11 + 50) / 100; return (R * 30 + G * 59 + B * 11 + 50) / 100; } - public boolean grayCompare(int g1, int g2){ - return ((double)Math.min(g1,g2)/Math.max(g1,g2)) >= ignoreRate; + public boolean grayCompare(int g1, int g2) { + return ((double) Math.min(g1, g2) / Math.max(g1, g2)) >= ignoreRate; } } diff --git a/mirai-core/src/main/java/net/mamoe/mirai/utils/ProtocolBuff.kt b/mirai-core/src/main/java/net/mamoe/mirai/utils/ProtocolBuff.kt index 79fcf7e28..16f23cc26 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/utils/ProtocolBuff.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/utils/ProtocolBuff.kt @@ -15,13 +15,13 @@ import java.io.DataOutputStream * TODO improve */ @ExperimentalUnsignedTypes -fun DataOutputStream.writeProtoFixedInt(int: Int) { - if (int == 128) { +fun DataOutputStream.writeProtoFixedInt(int: Long) { + if (int == 0xFFL) { this.writeShort(0x80_01)//unsigned//1000000010000001 return } - this.writeByte(int.rem(128) + 128) - this.writeByte(int / 128) + this.writeByte((int.rem(0xFF) + 0xFF).toInt()) + this.writeByte((int / 0xFF).toInt()) } /** @@ -30,9 +30,9 @@ fun DataOutputStream.writeProtoFixedInt(int: Int) { * TODO improve */ @ExperimentalUnsignedTypes -fun DataOutputStream.writeProtoInt(int: Int) { - if (int < 128) { - this.writeByte(int and 0xFF)//10000000 +fun DataOutputStream.writeProtoInt(int: Long) { + if (int < 0xFF) { + this.writeByte((int and 0xFF).toInt())//10000000 return } this.writeProtoFixedInt(int)