mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-08 17:20:11 +08:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
72e4208df9
@ -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() {
|
||||
|
@ -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)
|
||||
}
|
@ -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)
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
@ -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<String> {
|
||||
public final class CharImageConverter implements Callable<String> {
|
||||
|
||||
/**
|
||||
* width should depends on the width of the terminal
|
||||
@ -19,74 +20,73 @@ public class CharImageConverter implements Callable<String> {
|
||||
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<StringBuilder> lines = new ArrayList<>(this.image.getHeight());
|
||||
List<StringBuilder> 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<lines.size();++i) {
|
||||
builder.append(lines.get(i).substring(minXPos, maxXPos)).append("\n");
|
||||
for (int y = 0; y < image.getHeight(); y++) {
|
||||
StringBuilder builderLine = new StringBuilder();
|
||||
for (int x = 0; x < image.getWidth(); x++) {
|
||||
int gray = 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);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user