mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-23 14:20:24 +08:00
Merge remote-tracking branch 'origin/master'
# Conflicts: # mirai-core/src/main/java/net/mamoe/mirai/Robot.java
This commit is contained in:
commit
1c8e5679a1
26
README.md
26
README.md
@ -3,9 +3,9 @@
|
|||||||
一个以<b>TIM QQ协议</b>驱动的JAVA(+Kotlin) QQ机器人服务端核心
|
一个以<b>TIM QQ协议</b>驱动的JAVA(+Kotlin) QQ机器人服务端核心
|
||||||
我们坚持免费与开源
|
我们坚持免费与开源
|
||||||
|
|
||||||
项目处于快速开发阶段, 现在已经可以接受和发送群聊/好友消息.
|
项目处于快速开发阶段, 现在已经可以接受和发送群聊/好友消息.
|
||||||
协议来自网络上开源项目
|
协议来自网络上开源项目
|
||||||
一切开发旨在学习, 请勿用于非法用途
|
一切开发旨在学习, 请勿用于非法用途
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
@ -14,8 +14,8 @@ It use protocols from <i>TIM QQ</i>, that is, it won't be affected by the close
|
|||||||
The project is all for <b>learning proposes</b> and still in <b>developing stage</b><br>
|
The project is all for <b>learning proposes</b> and still in <b>developing stage</b><br>
|
||||||
|
|
||||||
### 代码结构
|
### 代码结构
|
||||||
Network部分使用 Kotlin 完成(因为kt有对 unsigned byte 的支持).
|
Network部分使用 Kotlin 完成(因为kt有对 unsigned byte 的支持).
|
||||||
与插件相关性强(或其他在二次开发中容易接触的部分)均使用 Java 完成,
|
与插件相关性强(或其他在二次开发中容易接触的部分)均使用 Java 完成,
|
||||||
同时也会针对kotlin提供优化的方法调用. 例如对'+'操作符的重载: `String+BufferedImage+QQ.At+Face+URL+String+File` 将会被自动处理为String消息.
|
同时也会针对kotlin提供优化的方法调用. 例如对'+'操作符的重载: `String+BufferedImage+QQ.At+Face+URL+String+File` 将会被自动处理为String消息.
|
||||||
|
|
||||||
|
|
||||||
@ -24,14 +24,14 @@ Network部分使用 Kotlin 完成(因为kt有对 unsigned byte 的支持).
|
|||||||
- [ ] 插件(Plugin)模块 **(Working on)**
|
- [ ] 插件(Plugin)模块 **(Working on)**
|
||||||
- [x] Network - Touch
|
- [x] Network - Touch
|
||||||
- [X] Network - Login
|
- [X] Network - Login
|
||||||
- [X] Network - Session
|
- [X] Network - Session
|
||||||
- [ ] Network - Verification Code (Low priority)
|
- [ ] Network - Verification Code (Low priority)
|
||||||
- [X] Network - Message Receiving
|
- [X] Network - Message Receiving
|
||||||
- [X] Network - Message Sending
|
- [X] Network - Message Sending
|
||||||
- [ ] Network - Events **(Working on)**
|
- [ ] Network - Events **(Working on)**
|
||||||
- [ ] Robot - Friend/group list
|
- [ ] Robot - Friend/group list
|
||||||
- [ ] Message Section **(Working on)**
|
- [ ] Message Section **(Working on)**
|
||||||
- [ ] Contact
|
- [ ] Contact
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ public class MiraiServer {
|
|||||||
MiraiConfig qqs;
|
MiraiConfig qqs;
|
||||||
|
|
||||||
|
|
||||||
protected MiraiServer(){
|
protected MiraiServer() {
|
||||||
instance = this;
|
instance = this;
|
||||||
this.onLoad();
|
this.onLoad();
|
||||||
this.onEnable();
|
this.onEnable();
|
||||||
@ -61,17 +61,17 @@ public class MiraiServer {
|
|||||||
|
|
||||||
private boolean enabled;
|
private boolean enabled;
|
||||||
|
|
||||||
protected void shutdown(){
|
protected void shutdown() {
|
||||||
if(this.enabled) {
|
if (this.enabled) {
|
||||||
getLogger().info(LoggerTextFormat.SKY_BLUE + "About to shutdown Mirai");
|
getLogger().info("About to shutdown Mirai");
|
||||||
this.getEventManager().broadcastEvent(new ServerDisableEvent());
|
this.getEventManager().broadcastEvent(new ServerDisableEvent());
|
||||||
getLogger().info(LoggerTextFormat.SKY_BLUE + "Data have been saved");
|
getLogger().info("Data have been saved");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void onLoad(){
|
private void onLoad() {
|
||||||
this.parentFolder = new File(System.getProperty("user.dir"));
|
this.parentFolder = new File(System.getProperty("user.dir"));
|
||||||
this.unix = !System.getProperties().getProperty("os.name").toUpperCase().contains("WINDOWS");
|
this.unix = !System.getProperties().getProperty("os.name").toUpperCase().contains("WINDOWS");
|
||||||
|
|
||||||
@ -79,36 +79,36 @@ public class MiraiServer {
|
|||||||
this.eventManager = MiraiEventManager.getInstance();
|
this.eventManager = MiraiEventManager.getInstance();
|
||||||
this.taskManager = MiraiTaskManager.getInstance();
|
this.taskManager = MiraiTaskManager.getInstance();
|
||||||
|
|
||||||
getLogger().info(LoggerTextFormat.SKY_BLUE + "About to run Mirai (" + MiraiServer.MIRAI_VERSION + ") under " + (isUnix() ? "unix" : "windows"));
|
getLogger().info("About to run Mirai (" + MiraiServer.MIRAI_VERSION + ") under " + (isUnix() ? "unix" : "windows"));
|
||||||
getLogger().info("Loading data under " + LoggerTextFormat.GREEN + this.parentFolder);
|
getLogger().info("Loading data under " + LoggerTextFormat.GREEN + this.parentFolder);
|
||||||
|
|
||||||
File setting = new File(this.parentFolder + "/Mirai.ini");
|
File setting = new File(this.parentFolder + "/Mirai.ini");
|
||||||
getLogger().info("Selecting setting from " + LoggerTextFormat.GREEN + setting);
|
getLogger().info("Selecting setting from " + LoggerTextFormat.GREEN + setting);
|
||||||
|
|
||||||
if(!setting.exists()){
|
if (!setting.exists()) {
|
||||||
this.initSetting(setting);
|
this.initSetting(setting);
|
||||||
}else {
|
} else {
|
||||||
this.setting = new MiraiSetting(setting);
|
this.setting = new MiraiSetting(setting);
|
||||||
}
|
}
|
||||||
|
|
||||||
File qqs = new File(this.parentFolder + "/QQ.yml");
|
File qqs = new File(this.parentFolder + "/QQ.yml");
|
||||||
getLogger().info("Reading QQ accounts from " + LoggerTextFormat.GREEN + qqs);
|
getLogger().info("Reading QQ accounts from " + LoggerTextFormat.GREEN + qqs);
|
||||||
if(!qqs.exists()){
|
if (!qqs.exists()) {
|
||||||
this.initQQConfig(qqs);
|
this.initQQConfig(qqs);
|
||||||
}else {
|
} else {
|
||||||
this.qqs = new MiraiConfig(qqs);
|
this.qqs = new MiraiConfig(qqs);
|
||||||
}
|
}
|
||||||
if(this.qqs.isEmpty()){
|
if (this.qqs.isEmpty()) {
|
||||||
this.initQQConfig(qqs);
|
this.initQQConfig(qqs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
MiraiSettingMapSection qqs = this.setting.getMapSection("qq");
|
MiraiSettingMapSection qqs = this.setting.getMapSection("qq");
|
||||||
qqs.forEach((a,p) -> {
|
qqs.forEach((a,p) -> {
|
||||||
this.getLogger().info(LoggerTextFormat.SKY_BLUE + "Finding available ports between " + "1-65536");
|
this.getLogger().info("Finding available ports between " + "1-65536");
|
||||||
try {
|
try {
|
||||||
int port = MiraiNetwork.getAvailablePort();
|
int port = MiraiNetwork.getAvailablePort();
|
||||||
this.getLogger().info(LoggerTextFormat.SKY_BLUE + "Listening on port " + port);
|
this.getLogger().info("Listening on port " + port);
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@ -178,56 +178,56 @@ public class MiraiServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void initSetting(File setting) {
|
private void initSetting(File setting) {
|
||||||
getLogger().info(LoggerTextFormat.SKY_BLUE + "Thanks for using Mirai");
|
getLogger().info("Thanks for using Mirai");
|
||||||
getLogger().info(LoggerTextFormat.SKY_BLUE + "initializing Settings");
|
getLogger().info("initializing Settings");
|
||||||
try {
|
try {
|
||||||
if(setting.createNewFile()){
|
if (setting.createNewFile()) {
|
||||||
getLogger().info(LoggerTextFormat.SKY_BLUE + "Mirai Config Created");
|
getLogger().info("Mirai Config Created");
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
this.setting = new MiraiSetting(setting);
|
this.setting = new MiraiSetting(setting);
|
||||||
MiraiSettingMapSection network = this.setting.getMapSection("network");
|
MiraiSettingMapSection network = this.setting.getMapSection("network");
|
||||||
network.set("enable_proxy","not supporting yet");
|
network.set("enable_proxy", "not supporting yet");
|
||||||
|
|
||||||
MiraiSettingListSection proxy = this.setting.getListSection("proxy");
|
MiraiSettingListSection proxy = this.setting.getListSection("proxy");
|
||||||
proxy.add("1.2.3.4:95");
|
proxy.add("1.2.3.4:95");
|
||||||
proxy.add("1.2.3.4:100");
|
proxy.add("1.2.3.4:100");
|
||||||
|
|
||||||
MiraiSettingMapSection worker = this.setting.getMapSection("worker");
|
MiraiSettingMapSection worker = this.setting.getMapSection("worker");
|
||||||
worker.set("core_task_pool_worker_amount",5);
|
worker.set("core_task_pool_worker_amount", 5);
|
||||||
|
|
||||||
MiraiSettingMapSection plugin = this.setting.getMapSection("plugin");
|
MiraiSettingMapSection plugin = this.setting.getMapSection("plugin");
|
||||||
plugin.set("debug", false);
|
plugin.set("debug", false);
|
||||||
|
|
||||||
this.setting.save();
|
this.setting.save();
|
||||||
getLogger().info(LoggerTextFormat.SKY_BLUE + "initialized; changing can be made in setting file: " + setting.toString());
|
getLogger().info("initialized; changing can be made in setting file: " + setting.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initQQConfig(File qqConfig){
|
private void initQQConfig(File qqConfig) {
|
||||||
this.qqs = new MiraiConfig(qqConfig);
|
this.qqs = new MiraiConfig(qqConfig);
|
||||||
|
|
||||||
MiraiConfigSection<Object> section = new MiraiConfigSection<>();
|
MiraiConfigSection<Object> section = new MiraiConfigSection<>();
|
||||||
|
|
||||||
System.out.println("/");
|
System.out.println("/");
|
||||||
Scanner scanner = new Scanner(System.in);
|
Scanner scanner = new Scanner(System.in);
|
||||||
getLogger().info(LoggerTextFormat.SKY_BLUE + "input one " + LoggerTextFormat.RED + " QQ number " + LoggerTextFormat.SKY_BLUE + "for default robotNetworkHandler");
|
getLogger().info("Input a " + LoggerTextFormat.RED + " QQ number " + LoggerTextFormat.GREEN + "for default robotNetworkHandler");
|
||||||
getLogger().info(LoggerTextFormat.SKY_BLUE + "输入用于默认机器人的QQ号");
|
getLogger().info("输入用于默认机器人的QQ号");
|
||||||
long qqNumber = scanner.nextLong();
|
long qqNumber = scanner.nextLong();
|
||||||
getLogger().info(LoggerTextFormat.SKY_BLUE + "input the password for that QQ account");
|
getLogger().info("Input the password for that QQ account");
|
||||||
getLogger().info(LoggerTextFormat.SKY_BLUE + "输入该QQ号对应密码");
|
getLogger().info("输入该QQ号的密码");
|
||||||
String qqPassword = scanner.next();
|
String qqPassword = scanner.next();
|
||||||
|
|
||||||
section.put("password",qqPassword);
|
section.put("password", qqPassword);
|
||||||
section.put("owner","default");
|
section.put("owner", "default");
|
||||||
|
|
||||||
this.qqs.put(String.valueOf(qqNumber),section);
|
this.qqs.put(String.valueOf(qqNumber), section);
|
||||||
this.qqs.save();
|
this.qqs.save();
|
||||||
getLogger().info(LoggerTextFormat.SKY_BLUE + "QQ account initialized; changing can be made in Config file: " + qqConfig.toString());
|
getLogger().info("QQ account initialized; changing can be made in Config file: " + qqConfig.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onEnable(){
|
private void onEnable() {
|
||||||
this.eventManager.broadcastEvent(new ServerEnableEvent());
|
this.eventManager.broadcastEvent(new ServerEnableEvent());
|
||||||
this.enabled = true;
|
this.enabled = true;
|
||||||
getLogger().info(LoggerTextFormat.GREEN + "Server enabled; Welcome to Mirai");
|
getLogger().info(LoggerTextFormat.GREEN + "Server enabled; Welcome to Mirai");
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
package net.mamoe.mirai;
|
package net.mamoe.mirai;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import net.mamoe.mirai.contact.Group;
|
||||||
|
import net.mamoe.mirai.contact.QQ;
|
||||||
import net.mamoe.mirai.network.RobotNetworkHandler;
|
import net.mamoe.mirai.network.RobotNetworkHandler;
|
||||||
|
import net.mamoe.mirai.utils.ContactList;
|
||||||
import net.mamoe.mirai.utils.config.MiraiConfigSection;
|
import net.mamoe.mirai.utils.config.MiraiConfigSection;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -10,10 +13,8 @@ import java.util.List;
|
|||||||
|
|
||||||
public class Robot {
|
public class Robot {
|
||||||
|
|
||||||
private final int qq;
|
private final int qqNumber;
|
||||||
private final String password;
|
private final String password;
|
||||||
|
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private final RobotNetworkHandler handler;
|
private final RobotNetworkHandler handler;
|
||||||
|
|
||||||
@ -23,6 +24,9 @@ public class Robot {
|
|||||||
@Getter
|
@Getter
|
||||||
private final List<String> owners;
|
private final List<String> owners;
|
||||||
|
|
||||||
|
private final ContactList<Group> groups = new ContactList<>();
|
||||||
|
private final ContactList<QQ> qqs = new ContactList<>();
|
||||||
|
|
||||||
public boolean isOwnBy(String ownerName) {
|
public boolean isOwnBy(String ownerName) {
|
||||||
return owners.contains(ownerName);
|
return owners.contains(ownerName);
|
||||||
}
|
}
|
||||||
@ -30,20 +34,36 @@ public class Robot {
|
|||||||
|
|
||||||
public Robot(MiraiConfigSection<Object> data) throws Throwable {
|
public Robot(MiraiConfigSection<Object> data) throws Throwable {
|
||||||
this(
|
this(
|
||||||
data.getIntOrThrow("account", () -> new Exception("can not parse QQ account")),
|
data.getIntOrThrow("account", () -> new IllegalArgumentException("account")),
|
||||||
data.getStringOrThrow("password", () -> new Exception("can not parse QQ password")),
|
data.getStringOrThrow("password", () -> new IllegalArgumentException("password")),
|
||||||
data.getAsOrDefault("owners", ArrayList::new)
|
data.getAsOrDefault("owners", ArrayList::new)
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Robot(int qqNumber, String password, List<String> owners) {
|
||||||
public Robot(int qq, String password, List<String> owners) {
|
this.qqNumber = qqNumber;
|
||||||
this.qq = qq;
|
|
||||||
this.password = password;
|
this.password = password;
|
||||||
this.owners = Collections.unmodifiableList(owners);
|
this.owners = Collections.unmodifiableList(owners);
|
||||||
this.handler = new RobotNetworkHandler(this, this.qq, this.password);
|
this.handler = new RobotNetworkHandler(this, this.qqNumber, this.password);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public QQ getQQ(int qqNumber) {
|
||||||
|
if (!this.qqs.containsKey(qqNumber)) {
|
||||||
|
this.qqs.put(qqNumber, new QQ(qqNumber));
|
||||||
|
}
|
||||||
|
return this.qqs.get(qqNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Group getGroup(int groupNumber) {
|
||||||
|
if (!this.groups.containsKey(groupNumber)) {
|
||||||
|
this.groups.put(groupNumber, new Group(groupNumber));
|
||||||
|
}
|
||||||
|
return groups.get(groupNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Group getGroupByGroupId(int groupId) {
|
||||||
|
return getGroup(Group.Companion.groupIdToNumber(groupId));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
package net.mamoe.mirai.contact
|
package net.mamoe.mirai.contact
|
||||||
|
|
||||||
import net.mamoe.mirai.message.Message
|
import net.mamoe.mirai.message.Message
|
||||||
|
import net.mamoe.mirai.utils.ContactList
|
||||||
|
|
||||||
class Group(number: Int) : Contact(number) {
|
class Group(number: Int) : Contact(number) {
|
||||||
val groupId = groupNumberToId(number)
|
val groupId = groupNumberToId(number)
|
||||||
|
val members = ContactList<QQ>()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
Instances.groups.add(this)
|
Instances.groups.add(this)
|
||||||
@ -55,6 +57,11 @@ class Group(number: Int) : Contact(number) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
groupNumberToId(580266363)
|
||||||
|
}
|
||||||
|
|
||||||
fun groupIdToNumber(id: Int): Int {
|
fun groupIdToNumber(id: Int): Int {
|
||||||
var left: Int = id.toString().let {
|
var left: Int = id.toString().let {
|
||||||
if (it.length < 6) {
|
if (it.length < 6) {
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
package net.mamoe.mirai.event.events.group;
|
||||||
|
|
||||||
|
import net.mamoe.mirai.Robot;
|
||||||
|
import net.mamoe.mirai.contact.Group;
|
||||||
|
import net.mamoe.mirai.event.events.robot.RobotEvent;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Him188moe
|
||||||
|
*/
|
||||||
|
public abstract class GroupEvent extends RobotEvent {
|
||||||
|
private final Group group;
|
||||||
|
|
||||||
|
public GroupEvent(Robot robot, Group group) {
|
||||||
|
super(robot);
|
||||||
|
this.group = group;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public Group getGroup() {
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package net.mamoe.mirai.event.events.group;
|
||||||
|
|
||||||
|
import net.mamoe.mirai.Robot;
|
||||||
|
import net.mamoe.mirai.contact.Group;
|
||||||
|
import net.mamoe.mirai.contact.QQ;
|
||||||
|
import net.mamoe.mirai.message.defaults.MessageChain;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Him188moe
|
||||||
|
*/
|
||||||
|
public final class GroupMessageEvent extends GroupEvent {
|
||||||
|
private final QQ sender;
|
||||||
|
private final MessageChain messageChain;
|
||||||
|
private final String messageString;
|
||||||
|
|
||||||
|
public GroupMessageEvent(@NotNull Robot robot, @NotNull Group group, @NotNull QQ sender, @NotNull MessageChain messageChain) {
|
||||||
|
super(robot, group);
|
||||||
|
this.sender = sender;
|
||||||
|
this.messageChain = messageChain;
|
||||||
|
this.messageString = messageChain.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public MessageChain getMessageChain() {
|
||||||
|
return messageChain;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public String getMessageString() {
|
||||||
|
return messageString;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public QQ getSender() {
|
||||||
|
return sender;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package net.mamoe.mirai.event.events.qq;
|
||||||
|
|
||||||
|
import net.mamoe.mirai.Robot;
|
||||||
|
import net.mamoe.mirai.contact.QQ;
|
||||||
|
import net.mamoe.mirai.event.events.robot.RobotEvent;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Him188moe
|
||||||
|
*/
|
||||||
|
public abstract class FriendEvent extends RobotEvent {
|
||||||
|
private final QQ qq;
|
||||||
|
|
||||||
|
public FriendEvent(@NotNull Robot robot, @NotNull QQ qq) {
|
||||||
|
super(robot);
|
||||||
|
this.qq = Objects.requireNonNull(qq);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public QQ getQQ() {
|
||||||
|
return qq;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package net.mamoe.mirai.event.events.qq;
|
||||||
|
|
||||||
|
import net.mamoe.mirai.Robot;
|
||||||
|
import net.mamoe.mirai.contact.QQ;
|
||||||
|
import net.mamoe.mirai.message.defaults.MessageChain;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Him188moe
|
||||||
|
*/
|
||||||
|
public final class FriendMessageEvent extends FriendEvent {
|
||||||
|
private final MessageChain messageChain;
|
||||||
|
private final String messageString;
|
||||||
|
|
||||||
|
public FriendMessageEvent(@NotNull Robot robot, @NotNull QQ sender, @NotNull MessageChain messageChain) {
|
||||||
|
super(robot, sender);
|
||||||
|
this.messageChain = Objects.requireNonNull(messageChain);
|
||||||
|
this.messageString = messageChain.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessageString() {
|
||||||
|
return messageString;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MessageChain getMessageChain() {
|
||||||
|
return messageChain;
|
||||||
|
}
|
||||||
|
}
|
@ -2,15 +2,20 @@ package net.mamoe.mirai.event.events.robot;
|
|||||||
|
|
||||||
import net.mamoe.mirai.Robot;
|
import net.mamoe.mirai.Robot;
|
||||||
import net.mamoe.mirai.event.events.MiraiEvent;
|
import net.mamoe.mirai.event.events.MiraiEvent;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public abstract class RobotEvent extends MiraiEvent {
|
public abstract class RobotEvent extends MiraiEvent {
|
||||||
private final Robot robot;
|
private final Robot robot;
|
||||||
|
|
||||||
|
public RobotEvent(@NotNull Robot robot) {
|
||||||
|
this.robot = Objects.requireNonNull(robot);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
public Robot getRobot() {
|
public Robot getRobot() {
|
||||||
return robot;
|
return robot;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RobotEvent(Robot robot){
|
|
||||||
this.robot = robot;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,6 @@ package net.mamoe.mirai.event.events.server;
|
|||||||
|
|
||||||
import net.mamoe.mirai.event.events.MiraiEvent;
|
import net.mamoe.mirai.event.events.MiraiEvent;
|
||||||
|
|
||||||
public class ServerDisableEvent extends MiraiEvent {
|
public final class ServerDisableEvent extends MiraiEvent {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ package net.mamoe.mirai.event.events.server;
|
|||||||
|
|
||||||
import net.mamoe.mirai.event.events.MiraiEvent;
|
import net.mamoe.mirai.event.events.MiraiEvent;
|
||||||
|
|
||||||
public class ServerEnableEvent extends MiraiEvent {
|
public final class ServerEnableEvent extends MiraiEvent {
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,12 @@ package net.mamoe.mirai.message.defaults;
|
|||||||
import net.mamoe.mirai.message.Message;
|
import net.mamoe.mirai.message.Message;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Him188moe
|
* @author Him188moe
|
||||||
@ -21,6 +24,19 @@ public final class MessageChain extends Message {
|
|||||||
list.add(tail);
|
list.add(tail);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MessageChain(@NotNull Message message) {
|
||||||
|
Objects.requireNonNull(message);
|
||||||
|
list.add(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Message> toList() {
|
||||||
|
return List.copyOf(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Stream<Message> stream() {
|
||||||
|
return new ArrayList<>(list).stream();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized String toString() {
|
public synchronized String toString() {
|
||||||
return this.list.stream().map(Message::toString).collect(Collectors.joining(""));
|
return this.list.stream().map(Message::toString).collect(Collectors.joining(""));
|
||||||
|
@ -2,11 +2,14 @@ package net.mamoe.mirai.network
|
|||||||
|
|
||||||
import net.mamoe.mirai.MiraiServer
|
import net.mamoe.mirai.MiraiServer
|
||||||
import net.mamoe.mirai.Robot
|
import net.mamoe.mirai.Robot
|
||||||
|
import net.mamoe.mirai.contact.Group
|
||||||
|
import net.mamoe.mirai.event.events.qq.FriendMessageEvent
|
||||||
import net.mamoe.mirai.event.events.robot.RobotLoginSucceedEvent
|
import net.mamoe.mirai.event.events.robot.RobotLoginSucceedEvent
|
||||||
import net.mamoe.mirai.network.packet.*
|
import net.mamoe.mirai.network.packet.*
|
||||||
import net.mamoe.mirai.network.packet.login.*
|
import net.mamoe.mirai.network.packet.login.*
|
||||||
import net.mamoe.mirai.network.packet.message.ClientSendFriendMessagePacket
|
|
||||||
import net.mamoe.mirai.network.packet.message.ClientSendGroupMessagePacket
|
import net.mamoe.mirai.network.packet.message.ClientSendGroupMessagePacket
|
||||||
|
import net.mamoe.mirai.network.packet.message.ServerSendFriendMessageResponsePacket
|
||||||
|
import net.mamoe.mirai.network.packet.message.ServerSendGroupMessageResponsePacket
|
||||||
import net.mamoe.mirai.network.packet.verification.ServerVerificationCodePacket
|
import net.mamoe.mirai.network.packet.verification.ServerVerificationCodePacket
|
||||||
import net.mamoe.mirai.network.packet.verification.ServerVerificationCodePacketEncrypted
|
import net.mamoe.mirai.network.packet.verification.ServerVerificationCodePacketEncrypted
|
||||||
import net.mamoe.mirai.task.MiraiThreadPool
|
import net.mamoe.mirai.task.MiraiThreadPool
|
||||||
@ -84,6 +87,7 @@ class RobotNetworkHandler(val robot: Robot, val number: Int, private val passwor
|
|||||||
*/
|
*/
|
||||||
private lateinit var cookies: String
|
private lateinit var cookies: String
|
||||||
private var gtk: Int = 0
|
private var gtk: Int = 0
|
||||||
|
private var ignoreMessage: Boolean = false
|
||||||
|
|
||||||
init {
|
init {
|
||||||
tlv0105 = lazyEncode {
|
tlv0105 = lazyEncode {
|
||||||
@ -197,6 +201,11 @@ class RobotNetworkHandler(val robot: Robot, val number: Int, private val passwor
|
|||||||
sendPacket(ClientHeartbeatPacket(this.number, this.sessionKey))
|
sendPacket(ClientHeartbeatPacket(this.number, this.sessionKey))
|
||||||
}, 90000, 90000, TimeUnit.MILLISECONDS)
|
}, 90000, 90000, TimeUnit.MILLISECONDS)
|
||||||
RobotLoginSucceedEvent(robot).broadcast()
|
RobotLoginSucceedEvent(robot).broadcast()
|
||||||
|
|
||||||
|
MiraiThreadPool.getInstance().schedule({
|
||||||
|
ignoreMessage = false
|
||||||
|
}, 2, TimeUnit.SECONDS)
|
||||||
|
|
||||||
this.tlv0105 = packet.tlv0105
|
this.tlv0105 = packet.tlv0105
|
||||||
sendPacket(ClientLoginStatusPacket(this.number, this.sessionKey, ClientLoginStatus.ONLINE))
|
sendPacket(ClientLoginStatusPacket(this.number, this.sessionKey, ClientLoginStatus.ONLINE))
|
||||||
}
|
}
|
||||||
@ -225,23 +234,23 @@ class RobotNetworkHandler(val robot: Robot, val number: Int, private val passwor
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
is ServerMessageEventPacketRaw -> onPacketReceived(packet.analyze())
|
|
||||||
|
|
||||||
|
|
||||||
is ServerFriendMessageEventPacket -> {
|
is ServerFriendMessageEventPacket -> {
|
||||||
println(packet.toString())
|
if (ignoreMessage) {
|
||||||
if (packet.message == "牛逼") {
|
return
|
||||||
sendPacket(ClientSendFriendMessagePacket(this.number, packet.qq, this.sessionKey, "牛逼!!"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//friend message
|
FriendMessageEvent(this.robot, this.robot.getQQ(packet.qq), packet.message)
|
||||||
}
|
}
|
||||||
|
|
||||||
is ServerGroupMessageEventPacket -> {
|
is ServerGroupMessageEventPacket -> {
|
||||||
//group message
|
//group message
|
||||||
if (packet.message == "牛逼") {
|
if (packet.message == "牛逼") {
|
||||||
sendPacket(ClientSendGroupMessagePacket(packet.group, this.number, this.sessionKey, "牛逼!"))
|
sendPacket(ClientSendGroupMessagePacket(Group.groupNumberToId(packet.groupNumber), this.number, this.sessionKey, "牛逼!"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//todo
|
||||||
|
//GroupMessageEvent(this.robot, this.robot.getGroup(packet.groupNumber), this.robot.getQQ(packet.qq), packet.message)
|
||||||
}
|
}
|
||||||
|
|
||||||
is UnknownServerEventPacket -> {
|
is UnknownServerEventPacket -> {
|
||||||
@ -256,6 +265,8 @@ class RobotNetworkHandler(val robot: Robot, val number: Int, private val passwor
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is ServerMessageEventPacketRaw -> onPacketReceived(packet.analyze())
|
||||||
|
|
||||||
is ServerVerificationCodePacketEncrypted -> onPacketReceived(packet.decrypt(this.token00BA))
|
is ServerVerificationCodePacketEncrypted -> onPacketReceived(packet.decrypt(this.token00BA))
|
||||||
is ServerLoginResponseVerificationCodePacketEncrypted -> onPacketReceived(packet.decrypt())
|
is ServerLoginResponseVerificationCodePacketEncrypted -> onPacketReceived(packet.decrypt())
|
||||||
is ServerLoginResponseResendPacketEncrypted -> onPacketReceived(packet.decrypt(this.tgtgtKey!!))
|
is ServerLoginResponseResendPacketEncrypted -> onPacketReceived(packet.decrypt(this.tgtgtKey!!))
|
||||||
@ -267,6 +278,11 @@ class RobotNetworkHandler(val robot: Robot, val number: Int, private val passwor
|
|||||||
is ServerMessageEventPacketRawEncoded -> onPacketReceived(packet.decrypt(this.sessionKey))
|
is ServerMessageEventPacketRawEncoded -> onPacketReceived(packet.decrypt(this.sessionKey))
|
||||||
|
|
||||||
|
|
||||||
|
is ServerSendFriendMessageResponsePacket,
|
||||||
|
is ServerSendGroupMessageResponsePacket -> {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
else -> throw IllegalArgumentException(packet.toString())
|
else -> throw IllegalArgumentException(packet.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package net.mamoe.mirai.network.packet
|
package net.mamoe.mirai.network.packet
|
||||||
|
|
||||||
|
import net.mamoe.mirai.message.defaults.MessageChain
|
||||||
|
import net.mamoe.mirai.message.defaults.PlainText
|
||||||
import net.mamoe.mirai.utils.toUHexString
|
import net.mamoe.mirai.utils.toUHexString
|
||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
import java.io.DataInputStream
|
import java.io.DataInputStream
|
||||||
@ -29,15 +31,15 @@ class ServerAndroidOfflineEventPacket(input: DataInputStream, packetId: ByteArra
|
|||||||
* 群文件上传
|
* 群文件上传
|
||||||
*/
|
*/
|
||||||
class ServerGroupUploadFileEventPacket(input: DataInputStream, packetId: ByteArray, eventIdentity: ByteArray) : ServerEventPacket(input, packetId, eventIdentity) {
|
class ServerGroupUploadFileEventPacket(input: DataInputStream, packetId: ByteArray, eventIdentity: ByteArray) : ServerEventPacket(input, packetId, eventIdentity) {
|
||||||
lateinit var message: String
|
lateinit var xmlMessage: String
|
||||||
|
|
||||||
override fun decode() {
|
override fun decode() {
|
||||||
message = String(this.input.goto(65).readNBytes(this.input.goto(60).readShort().toInt()))
|
xmlMessage = String(this.input.goto(65).readNBytes(this.input.goto(60).readShort().toInt()))
|
||||||
}//todo test
|
}//todo test
|
||||||
}
|
}
|
||||||
|
|
||||||
class ServerGroupMessageEventPacket(input: DataInputStream, packetId: ByteArray, eventIdentity: ByteArray) : ServerEventPacket(input, packetId, eventIdentity) {
|
class ServerGroupMessageEventPacket(input: DataInputStream, packetId: ByteArray, eventIdentity: ByteArray) : ServerEventPacket(input, packetId, eventIdentity) {
|
||||||
var group: Int = 0
|
var groupNumber: Int = 0
|
||||||
var qq: Int = 0
|
var qq: Int = 0
|
||||||
lateinit var message: String
|
lateinit var message: String
|
||||||
lateinit var messageType: MessageType
|
lateinit var messageType: MessageType
|
||||||
@ -57,10 +59,10 @@ class ServerGroupMessageEventPacket(input: DataInputStream, packetId: ByteArray,
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun decode() {
|
override fun decode() {
|
||||||
group = this.input.goto(51).readInt()
|
groupNumber = this.input.goto(51).readInt()
|
||||||
qq = this.input.goto(56).readInt()
|
qq = this.input.goto(56).readInt()
|
||||||
val fontLength = this.input.goto(108).readShort()
|
val fontLength = this.input.goto(108).readShort()
|
||||||
//println(this.input.goto(110 + fontLength).readNBytes(2).toUHexString())//always 00 00
|
//println(this.input.goto(110 + fontLength).readNBytesAt(2).toUHexString())//always 00 00
|
||||||
|
|
||||||
messageType = when (val id = this.input.goto(110 + fontLength + 2).readByte().toInt()) {
|
messageType = when (val id = this.input.goto(110 + fontLength + 2).readByte().toInt()) {
|
||||||
19 -> MessageType.NORMAL
|
19 -> MessageType.NORMAL
|
||||||
@ -102,7 +104,7 @@ class ServerGroupMessageEventPacket(input: DataInputStream, packetId: ByteArray,
|
|||||||
message = "[face${faceId}.gif]"
|
message = "[face${faceId}.gif]"
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageType.AT, MessageType.OTHER -> {
|
MessageType.AT, MessageType.OTHER, MessageType.PLAIN_TEXT, MessageType.IMAGE, MessageType.ANONYMOUS -> {
|
||||||
var messageLength: Int = this.input.goto(110 + fontLength + 6).readShort().toInt()
|
var messageLength: Int = this.input.goto(110 + fontLength + 6).readShort().toInt()
|
||||||
message = String(this.input.goto(110 + fontLength + 8).readNBytes(messageLength))
|
message = String(this.input.goto(110 + fontLength + 8).readNBytes(messageLength))
|
||||||
|
|
||||||
@ -120,7 +122,7 @@ class ServerGroupMessageEventPacket(input: DataInputStream, packetId: ByteArray,
|
|||||||
|
|
||||||
//读取 nick, ignore.
|
//读取 nick, ignore.
|
||||||
/*
|
/*
|
||||||
when (this.input.goto(110 + fontLength + 3 + oeLength).readByte().toInt()) {
|
when (this.input.goto(110 + fontLength + 3 + oeLength).readByteAt().toInt()) {
|
||||||
12 -> {
|
12 -> {
|
||||||
this.input.skip(4)//maybe 5?
|
this.input.skip(4)//maybe 5?
|
||||||
|
|
||||||
@ -139,6 +141,35 @@ class ServerGroupMessageEventPacket(input: DataInputStream, packetId: ByteArray,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ServerFriendMessageEventPacket(input: DataInputStream, packetId: ByteArray, eventIdentity: ByteArray) : ServerEventPacket(input, packetId, eventIdentity) {
|
||||||
|
var qq: Int = 0
|
||||||
|
lateinit var message: MessageChain
|
||||||
|
|
||||||
|
|
||||||
|
@ExperimentalUnsignedTypes
|
||||||
|
override fun decode() {
|
||||||
|
//start at Sep1.0:27
|
||||||
|
input.goto(0)
|
||||||
|
println(input.readAllBytes().toUHexString())
|
||||||
|
input.goto(0)
|
||||||
|
|
||||||
|
qq = input.readIntAt(0)
|
||||||
|
val msgLength = input.readShortAt(22)
|
||||||
|
val fontLength = input.readShortAt(93 + msgLength)
|
||||||
|
val offset = msgLength + fontLength
|
||||||
|
message = MessageChain(PlainText(let {
|
||||||
|
val offset2 = input.readShortAt(101 + offset)
|
||||||
|
input.goto(103 + offset).readVarString(offset2.toInt())
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
|
||||||
|
backup
|
||||||
|
|
||||||
class ServerFriendMessageEventPacket(input: DataInputStream, packetId: ByteArray, eventIdentity: ByteArray) : ServerEventPacket(input, packetId, eventIdentity) {
|
class ServerFriendMessageEventPacket(input: DataInputStream, packetId: ByteArray, eventIdentity: ByteArray) : ServerEventPacket(input, packetId, eventIdentity) {
|
||||||
var qq: Int = 0
|
var qq: Int = 0
|
||||||
lateinit var message: String
|
lateinit var message: String
|
||||||
@ -147,17 +178,17 @@ class ServerFriendMessageEventPacket(input: DataInputStream, packetId: ByteArray
|
|||||||
@ExperimentalUnsignedTypes
|
@ExperimentalUnsignedTypes
|
||||||
override fun decode() {
|
override fun decode() {
|
||||||
//start at Sep1.0:27
|
//start at Sep1.0:27
|
||||||
qq = input.readInt(0)
|
qq = input.readIntAt(0)
|
||||||
val msgLength = input.readShort(22)
|
val msgLength = input.readShortAt(22)
|
||||||
val fontLength = input.readShort(93+msgLength)
|
val fontLength = input.readShortAt(93+msgLength)
|
||||||
val offset = msgLength+fontLength
|
val offset = msgLength+fontLength
|
||||||
message = if(input.readByte(97+offset).toUHexString() == "02"){
|
message = if(input.readByteAt(97+offset).toUHexString() == "02"){
|
||||||
"[face" + input.goto(103+offset).readByte(1).toInt().toString() + ".gif]"
|
"[face" + input.goto(103+offset).readByteAt(1).toInt().toString() + ".gif]"
|
||||||
//.gif
|
//.gif
|
||||||
}else {
|
}else {
|
||||||
val offset2 = input.readShort(101 + offset)
|
val offset2 = input.readShortAt(101 + offset)
|
||||||
input.goto(103 + offset).readVarString(offset2.toInt())
|
input.goto(103 + offset).readVarString(offset2.toInt())
|
||||||
}
|
}
|
||||||
// TODO("FRIEND 解析")d
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
@ -145,22 +145,22 @@ infix fun <N : Number> DataInputStream.goto(position: N): DataInputStream {
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <N : Number> DataInputStream.readNBytes(position: N, length: Int): ByteArray {
|
fun <N : Number> DataInputStream.readNBytesAt(position: N, length: Int): ByteArray {
|
||||||
this.goto(position)
|
this.goto(position)
|
||||||
return this.readNBytes(length)
|
return this.readNBytes(length)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <N : Number> DataInputStream.readInt(position: N): Int {
|
fun <N : Number> DataInputStream.readIntAt(position: N): Int {
|
||||||
this.goto(position)
|
this.goto(position)
|
||||||
return this.readInt();
|
return this.readInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <N : Number> DataInputStream.readByte(position: N): Byte {
|
fun <N : Number> DataInputStream.readByteAt(position: N): Byte {
|
||||||
this.goto(position)
|
this.goto(position)
|
||||||
return this.readByte();
|
return this.readByte();
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <N : Number> DataInputStream.readShort(position: N): Short {
|
fun <N : Number> DataInputStream.readShortAt(position: N): Short {
|
||||||
this.goto(position)
|
this.goto(position)
|
||||||
return this.readShort();
|
return this.readShort();
|
||||||
}
|
}
|
@ -3,7 +3,7 @@ package net.mamoe.mirai.network.packet.login
|
|||||||
import net.mamoe.mirai.network.Protocol
|
import net.mamoe.mirai.network.Protocol
|
||||||
import net.mamoe.mirai.network.packet.ServerPacket
|
import net.mamoe.mirai.network.packet.ServerPacket
|
||||||
import net.mamoe.mirai.network.packet.goto
|
import net.mamoe.mirai.network.packet.goto
|
||||||
import net.mamoe.mirai.network.packet.readNBytes
|
import net.mamoe.mirai.network.packet.readNBytesAt
|
||||||
import net.mamoe.mirai.network.packet.readVarString
|
import net.mamoe.mirai.network.packet.readVarString
|
||||||
import net.mamoe.mirai.util.TestedSuccessfully
|
import net.mamoe.mirai.util.TestedSuccessfully
|
||||||
import net.mamoe.mirai.utils.TEACryptor
|
import net.mamoe.mirai.utils.TEACryptor
|
||||||
@ -31,16 +31,16 @@ class ServerLoginResponseSuccessPacket(input: DataInputStream) : ServerPacket(in
|
|||||||
* Version 1 @Deprecated
|
* Version 1 @Deprecated
|
||||||
this.input.skip(7)//8
|
this.input.skip(7)//8
|
||||||
|
|
||||||
encryptionKey = this.input.readNBytes(16)//24
|
encryptionKey = this.input.readNBytesAt(16)//24
|
||||||
|
|
||||||
this.input.skip(2)//25->26
|
this.input.skip(2)//25->26
|
||||||
|
|
||||||
token38 = this.input.readNBytes(56)//81->82
|
token38 = this.input.readNBytesAt(56)//81->82
|
||||||
|
|
||||||
this.input.skip(60L)//142
|
this.input.skip(60L)//142
|
||||||
|
|
||||||
//??
|
//??
|
||||||
var b = this.input.readNBytes(2)
|
var b = this.input.readNBytesAt(2)
|
||||||
val msgLength = when (b.toUByteArray().toUHexString()) {
|
val msgLength = when (b.toUByteArray().toUHexString()) {
|
||||||
"01 07" -> 0
|
"01 07" -> 0
|
||||||
"00 33" -> 28
|
"00 33" -> 28
|
||||||
@ -55,17 +55,17 @@ class ServerLoginResponseSuccessPacket(input: DataInputStream) : ServerPacket(in
|
|||||||
|
|
||||||
this.input.skip(10)//171+msgLength
|
this.input.skip(10)//171+msgLength
|
||||||
|
|
||||||
_0828_rec_decr_key = this.input.readNBytes(16)//187+msgLength
|
_0828_rec_decr_key = this.input.readNBytesAt(16)//187+msgLength
|
||||||
|
|
||||||
|
|
||||||
this.input.skip(2)
|
this.input.skip(2)
|
||||||
|
|
||||||
token88 = this.input.readNBytes(136)//325+ // msgLength
|
token88 = this.input.readNBytesAt(136)//325+ // msgLength
|
||||||
|
|
||||||
this.input.skip(299L)//624+msgLength
|
this.input.skip(299L)//624+msgLength
|
||||||
|
|
||||||
//varString (nickLength bytes)
|
//varString (nickLength bytes)
|
||||||
val nickLength = this.input.readByte().toInt()//625+msgLength
|
val nickLength = this.input.readByteAt().toInt()//625+msgLength
|
||||||
|
|
||||||
System.out.println(nickLength)
|
System.out.println(nickLength)
|
||||||
|
|
||||||
@ -76,11 +76,11 @@ class ServerLoginResponseSuccessPacket(input: DataInputStream) : ServerPacket(in
|
|||||||
/*
|
/*
|
||||||
this.input.skip((dataIndex - (625 + msgLength + nickLength)) + 0L)//-31
|
this.input.skip((dataIndex - (625 + msgLength + nickLength)) + 0L)//-31
|
||||||
|
|
||||||
gender = this.input.readByte().toUByte().toInt()//-30
|
gender = this.input.readByteAt().toUByte().toInt()//-30
|
||||||
|
|
||||||
this.input.skip(9)//-27
|
this.input.skip(9)//-27
|
||||||
|
|
||||||
age = this.input.readShort()//-25
|
age = this.input.readShortAt()//-25
|
||||||
*/
|
*/
|
||||||
age = 0
|
age = 0
|
||||||
gender = 0
|
gender = 0
|
||||||
@ -106,16 +106,16 @@ class ServerLoginResponseSuccessPacket(input: DataInputStream) : ServerPacket(in
|
|||||||
else -> throw IllegalStateException(id)
|
else -> throw IllegalStateException(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
this._0828_rec_decr_key = this.input.readNBytes(171 + msgLength, 16)
|
this._0828_rec_decr_key = this.input.readNBytesAt(171 + msgLength, 16)
|
||||||
|
|
||||||
this.token88 = this.input.readNBytes(189 + msgLength, 136)
|
this.token88 = this.input.readNBytesAt(189 + msgLength, 136)
|
||||||
|
|
||||||
val nickLength = this.input.goto(624 + msgLength).readByte().toInt()
|
val nickLength = this.input.goto(624 + msgLength).readByte().toInt()
|
||||||
this.nick = this.input.readVarString(nickLength)
|
this.nick = this.input.readVarString(nickLength)
|
||||||
|
|
||||||
//this.age = this.input.goto(packetDataLength - 28).readShort()
|
//this.age = this.input.goto(packetDataLength - 28).readShortAt()
|
||||||
|
|
||||||
//this.gender = this.input.goto(packetDataLength - 32).readByte().toInt()
|
//this.gender = this.input.goto(packetDataLength - 32).readByteAt().toInt()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@ package net.mamoe.mirai.network.packet.message
|
|||||||
|
|
||||||
import net.mamoe.mirai.network.Protocol
|
import net.mamoe.mirai.network.Protocol
|
||||||
import net.mamoe.mirai.network.packet.*
|
import net.mamoe.mirai.network.packet.*
|
||||||
|
import net.mamoe.mirai.utils.lazyEncode
|
||||||
|
import net.mamoe.mirai.utils.toUHexString
|
||||||
import java.io.DataInputStream
|
import java.io.DataInputStream
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -21,6 +23,11 @@ class ClientSendGroupMessagePacket(
|
|||||||
this.writeHex(Protocol._fixVer)
|
this.writeHex(Protocol._fixVer)
|
||||||
|
|
||||||
this.encryptAndWrite(sessionKey) {
|
this.encryptAndWrite(sessionKey) {
|
||||||
|
val bytes = message.toByteArray()
|
||||||
|
it.writeByte(0x2A)
|
||||||
|
it.writeInt(groupId)
|
||||||
|
it.writeShort(56 + bytes.size)
|
||||||
|
|
||||||
it.writeHex("00 01 01 00 00 00 00 00 00 00 4D 53 47 00 00 00 00 00")
|
it.writeHex("00 01 01 00 00 00 00 00 00 00 4D 53 47 00 00 00 00 00")
|
||||||
it.writeTime()
|
it.writeTime()
|
||||||
it.writeRandom(4)
|
it.writeRandom(4)
|
||||||
@ -28,21 +35,33 @@ class ClientSendGroupMessagePacket(
|
|||||||
it.writeZero(2)
|
it.writeZero(2)
|
||||||
|
|
||||||
//messages
|
//messages
|
||||||
val bytes = message.toByteArray()
|
|
||||||
it.writeByte(0x2A)
|
|
||||||
it.writeInt(groupId)
|
|
||||||
it.writeShort(19 + bytes.size)
|
|
||||||
|
|
||||||
it.writeByte(0x01)
|
|
||||||
it.writeByte(0x01)
|
it.writeByte(0x01)
|
||||||
it.writeShort(bytes.size + 3)
|
it.writeShort(bytes.size + 3)
|
||||||
it.writeByte(0x01)
|
it.writeByte(0x01)
|
||||||
it.writeShort(bytes.size)
|
it.writeShort(bytes.size)
|
||||||
it.write(bytes)
|
it.write(bytes)
|
||||||
|
|
||||||
|
println(it.toByteArray().toUHexString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
println(lazyEncode {
|
||||||
|
val bytes = "message".toByteArray()
|
||||||
|
it.writeByte(0x2A)
|
||||||
|
it.writeInt(580266363)
|
||||||
|
it.writeShort(19 + bytes.size)
|
||||||
|
|
||||||
|
it.writeByte(0x01)
|
||||||
|
it.writeByte(0x01)
|
||||||
|
it.writeShort(bytes.size + 3)
|
||||||
|
it.writeByte(0x01)
|
||||||
|
it.writeShort(bytes.size)
|
||||||
|
it.write(bytes)
|
||||||
|
}.toUHexString())
|
||||||
|
}
|
||||||
|
|
||||||
@PacketId("00 02")
|
@PacketId("00 02")
|
||||||
class ServerSendGroupMessageResponsePacket(input: DataInputStream) : ServerPacket(input) {
|
class ServerSendGroupMessageResponsePacket(input: DataInputStream) : ServerPacket(input) {
|
||||||
override fun decode() {
|
override fun decode() {
|
||||||
|
@ -27,7 +27,7 @@ class ServerVerificationCodePacket(input: DataInputStream) : ServerPacket(input)
|
|||||||
|
|
||||||
this.unknownBoolean = this.input.readByte().toInt() == 1
|
this.unknownBoolean = this.input.readByte().toInt() == 1
|
||||||
|
|
||||||
//this.token00BA = this.input.goto(packetLength - 60).readNBytes(40)
|
//this.token00BA = this.input.goto(packetLength - 60).readNBytesAt(40)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
package net.mamoe.mirai.utils;
|
||||||
|
|
||||||
|
import net.mamoe.mirai.contact.Contact;
|
||||||
|
import net.mamoe.mirai.utils.config.MiraiSynchronizedLinkedListMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Him188moe
|
||||||
|
*/
|
||||||
|
public class ContactList<C extends Contact> extends MiraiSynchronizedLinkedListMap<Integer, C> {
|
||||||
|
}
|
@ -1,14 +1,25 @@
|
|||||||
package net.mamoe.mirai.utils;
|
package net.mamoe.mirai.utils;
|
||||||
|
|
||||||
import net.mamoe.mirai.MiraiServer;
|
|
||||||
|
|
||||||
public enum LoggerTextFormat {
|
public enum LoggerTextFormat {
|
||||||
RED("\033[31m"),
|
RESET("\33[0m"),
|
||||||
GREEN("\033[32m"),
|
|
||||||
YELLOW("\033[33m"),
|
BLUE("\033[0;34m"),
|
||||||
BLUE("\033[34m"),
|
BLACK("\033[0;30m"),
|
||||||
SKY_BLUE("\033[36m"),
|
DARK_GREY("\033[1;30m"),
|
||||||
RESET("\33[0m");
|
LIGHT_BLUE("\033[1;34m"),
|
||||||
|
GREEN("\033[0;32m"),
|
||||||
|
LIGHT_GTEEN("\033[1;32m"),
|
||||||
|
CYAN("\033[0;36m"),
|
||||||
|
LIGHT_CYAN("\033[1;36m"),
|
||||||
|
RED("\033[0;31m"),
|
||||||
|
LIGHT_RED("\033[1;31m"),
|
||||||
|
PURPLE("\033[0;35m"),
|
||||||
|
LIGHT_PURPLE("\033[1;35m"),
|
||||||
|
BROWN("\033[0;33m"),
|
||||||
|
YELLOW("\033[1;33m"),
|
||||||
|
LIGHT_GRAY("\033[0;37m"),
|
||||||
|
WHITE("\033[1;37m");
|
||||||
|
|
||||||
private String format;
|
private String format;
|
||||||
|
|
||||||
LoggerTextFormat(String format) {
|
LoggerTextFormat(String format) {
|
||||||
@ -17,9 +28,9 @@ public enum LoggerTextFormat {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
if(MiraiServer.getInstance().isUnix()){
|
//if(MiraiServer.getInstance().isUnix()){
|
||||||
return format;
|
return format;
|
||||||
}
|
// }
|
||||||
return "";
|
// return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,21 +7,16 @@ import java.util.*
|
|||||||
* used to replace old logger
|
* used to replace old logger
|
||||||
*/
|
*/
|
||||||
object MiraiLogger {
|
object MiraiLogger {
|
||||||
infix fun info(o: Any?) {
|
|
||||||
this.print(o.toString())
|
|
||||||
}
|
|
||||||
|
|
||||||
infix fun error(o: Any?) {
|
|
||||||
this.print(o.toString(), LoggerTextFormat.RED)
|
|
||||||
}
|
|
||||||
|
|
||||||
infix fun log(o: Any?) = info(o)
|
infix fun log(o: Any?) = info(o)
|
||||||
|
|
||||||
infix fun println(o: Any?) = info(o)
|
infix fun println(o: Any?) = info(o)
|
||||||
|
infix fun info(o: Any?) = this.print(o.toString(), LoggerTextFormat.RESET)
|
||||||
|
|
||||||
infix fun debug(o: Any?) {
|
|
||||||
this.print(o.toString())
|
infix fun error(o: Any?) = this.print(o.toString(), LoggerTextFormat.RED)
|
||||||
}
|
|
||||||
|
infix fun notice(o: Any?) = this.print(o.toString(), LoggerTextFormat.LIGHT_BLUE)
|
||||||
|
|
||||||
|
infix fun debug(o: Any?) = this.print(o.toString(), LoggerTextFormat.YELLOW)
|
||||||
|
|
||||||
infix fun catching(e: Throwable) {
|
infix fun catching(e: Throwable) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
@ -31,7 +26,7 @@ object MiraiLogger {
|
|||||||
this.print(e.cause.toString())*/
|
this.print(e.cause.toString())*/
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun print(value: String?, color: LoggerTextFormat = LoggerTextFormat.BLUE) {
|
private fun print(value: String?, color: LoggerTextFormat = LoggerTextFormat.WHITE) {
|
||||||
val s = SimpleDateFormat("MM-dd HH:mm:ss").format(Date())
|
val s = SimpleDateFormat("MM-dd HH:mm:ss").format(Date())
|
||||||
kotlin.io.println("$color[Mirai] $s : $value")
|
kotlin.io.println("$color[Mirai] $s : $value")
|
||||||
}
|
}
|
||||||
@ -42,4 +37,6 @@ fun Any.logInfo() = MiraiLogger.info(this)
|
|||||||
|
|
||||||
fun Any.logDebug() = MiraiLogger.debug(this)
|
fun Any.logDebug() = MiraiLogger.debug(this)
|
||||||
|
|
||||||
fun Any.logError() = MiraiLogger.error(this)
|
fun Any.logError() = MiraiLogger.error(this)
|
||||||
|
|
||||||
|
fun Any.logNotice() = MiraiLogger.notice(this)
|
@ -6,12 +6,10 @@ import net.mamoe.mirai.network.Protocol;
|
|||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.concurrent.atomic.LongAdder;
|
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -213,16 +211,16 @@ public class HexComparator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
/*
|
|
||||||
System.out.println(HexComparator.compare(
|
System.out.println(HexComparator.compare(
|
||||||
//mirai
|
//mirai
|
||||||
|
|
||||||
"01 12 00 38 56 3A E4 8B B4 64 D2 72 60 FE 01 54 FC B1 5F 88 E0 BA 64 1A 55 F2 84 FC 97 D0 BF 5F 47 A8 D9 76 BB FB 4A 7A F3 5E 0E A4 8E CA 8F 27 C2 02 6E 5D E7 68 9F 7C CF 91 83 F4 03 0F 00 11 00 0F 44 45 53 4B 54 4F 50 2D 4D 31 37 4A 52 45 55 00 05 00 06 00 02 76 E4 B8 DD 00 06 00 78 0D DF 92 9C 5A 08 D1 67 FD 7D D6 DE CE D0 92 39 79 17 53 57 41 9B D6 D3 F9 F8 9A 3B E1 C2 3A E7 CF 02 6E 5E 36 B7 6D CF 33 66 77 FE AC 58 93 A3 85 E7 AF 6F 2D A2 74 E2 60 28 4B 29 17 04 79 95 39 D4 BF 4D C1 ED 61 49 13 23 9D 71 62 29 AF 87 D7 E3 42 49 88 3F D8 5C DB 9F 9E 5A 2A EA 02 F6 4F 2B D3 5B AF BE 0C B2 54 46 AE 99 1B 07 0B BE 6A C2 29 18 25 6A 95 0A 00 15 00 30 00 01 01 27 9B C7 F5 00 10 65 03 FD 8B 00 00 00 00 00 00 00 00 00 00 00 00 02 90 49 55 33 00 10 15 74 C4 89 85 7A 19 F5 5E A9 C9 A3 5E 8A 5A 9B 00 1A 00 40 E2 9A D0 B3 7D CD 3D F4 55 DB 04 A4 68 2A AF 4E 38 46 8B E0 1F 2D 2A B8 F6 C6 AB 4F DF D1 5F 8C D4 CA 2A 91 25 14 33 A3 C5 08 F8 01 4C E6 3D 89 5F 23 38 3A EC 01 58 F6 B1 F6 7F 2E 6A 02 17 4A 00 18 00 16 00 01 00 00 04 53 00 00 00 01 00 00 15 85 76 E4 B8 DD 00 00 00 00 01 03 00 14 00 01 00 10 60 C9 5D A7 45 70 04 7F 21 7D 84 50 5C 66 A5 C6 01 10 00 3C 00 01 00 38 57 3A 37 C3 FB A0 C3 E5 AE F3 0E B6 03 DE BF 9E E2 B5 C5 FE A0 F0 03 4F F7 8A 5C 29 5C E0 5A A2 89 D5 3F 60 E2 B2 81 FE D4 16 04 D4 E3 C6 4A D7 A9 D9 E6 FC 2E 7E 0C F3 03 12 00 05 01 00 00 00 01 05 08 00 05 10 00 00 00 00 03 13 00 19 01 01 02 00 10 04 EA 78 D1 A4 FF CD CC 7C B8 D4 12 7D BB 03 AA 00 00 00 00 01 02 00 62 00 01 04 EB B7 C1 86 F9 08 96 ED 56 84 AB 50 85 2E 48 00 38 E9 AA 2B 4D 26 4C 76 18 FE 59 D5 A9 82 6A 0C 04 B4 49 50 D7 9B B1 FE 5D 97 54 8D 82 F3 22 C2 48 B9 C9 22 69 CA 78 AD 3E 2D E9 C9 DF A8 9E 7D 8C 8D 6B DF 4C D7 34 D0 D3 00 14 10 21 DF C4 F3 DD 42 09 6F A0 93 8C 7E 0E 78 EF 22 8D 88 35"
|
"2A 22 96 29 7B 00 40 00 01 01 00 00 00 00 00 00 00 4D 53 47 00 00 00 00 00 EC 21 40 06 18 89 54 BC 00 00 00 00 09 00 86 00 00 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91 00 00 01 00 0A 01 00 07 E7 89 9B E9 80 BC 21\n"
|
||||||
,
|
,
|
||||||
//e
|
//e
|
||||||
"01 12 00 38 56 3A E4 8B B4 64 D2 72 60 FE 01 54 FC B1 5F 88 E0 BA 64 1A 55 F2 84 FC 97 D0 BF 5F 47 A8 D9 76 BB FB 4A 7A F3 5E 0E A4 8E CA 8F 27 C2 02 6E 5D E7 68 9F 7C CF 91 83 F4 03 0F 00 11 00 0F 44 45 53 4B 54 4F 50 2D 4D 31 37 4A 52 45 55 00 05 00 06 00 02 76 E4 B8 DD 00 06 00 78 0D DF 92 9C 5A 08 D1 67 FD 7D D6 DE CE D0 92 39 79 17 53 57 41 9B D6 D3 F9 F8 9A 3B E1 C2 3A E7 CF 02 6E 5E 36 B7 6D CF 33 66 77 FE AC 58 93 A3 85 E7 AF 6F 2D A2 74 E2 60 28 4B 29 17 04 79 95 39 D4 BF 4D C1 ED 61 49 13 23 9D 71 62 29 AF 87 D7 E3 42 49 88 3F D8 5C DB 9F 9E 5A 2A EA 02 F6 4F 2B D3 5B AF BE 0C B2 54 46 AE 99 1B 07 0B BE 6A C2 29 18 25 6A 95 0A 00 15 00 30 00 01 01 27 9B C7 F5 00 10 65 03 FD 8B 00 00 00 00 00 00 00 00 00 00 00 00 02 90 49 55 33 00 10 15 74 C4 89 85 7A 19 F5 5E A9 C9 A3 5E 8A 5A 9B 00 1A 00 40 26 2B FE EB 21 8E 08 16 BA 42 B3 A3 C5 6A 5B 31 33 A9 B3 F0 EB 16 80 BE F0 58 D3 51 98 2F A7 23 27 7C 06 97 F4 85 01 77 5C 5B D6 A2 82 54 06 A0 07 53 39 E2 E7 62 E5 09 1A 25 79 6F D9 E0 ED B6 00 18 00 16 00 01 00 00 04 53 00 00 00 01 00 00 15 85 76 E4 B8 DD 00 00 00 00 01 03 00 14 00 01 00 10 60 C9 5D A7 45 70 04 7F 21 7D 84 50 5C 66 A5 C6 01 10 00 3C 00 01 00 38 57 3A 37 C3 FB A0 C3 E5 AE F3 0E B6 03 DE BF 9E E2 B5 C5 FE A0 F0 03 4F F7 8A 5C 29 5C E0 5A A2 89 D5 3F 60 E2 B2 81 FE D4 16 04 D4 E3 C6 4A D7 A9 D9 E6 FC 2E 7E 0C F3 03 12 00 05 01 00 00 00 01 05 08 00 05 01 00 00 00 00 03 13 00 19 01 01 02 00 10 04 EA 78 D1 A4 FF CD CC 7C B8 D4 12 7D BB 03 AA 00 00 00 00 01 02 00 62 00 01 04 EB B7 C1 86 F9 08 96 ED 56 84 AB 50 85 2E 48 00 38 E9 AA 2B 4D 26 4C 76 18 FE 59 D5 A9 82 6A 0C 04 B4 49 50 D7 9B B1 FE 5D 97 54 8D 82 F3 22 C2 48 B9 C9 22 69 CA 78 AD 3E 2D E9 C9 DF A8 9E 7D 8C 8D 6B DF 4C D7 34 D0 D3 00 14 4C 97 73 32 83 1A 6F C4 94 91 0A 7A D8 21 81 58 73 3D 24 F6"
|
"2A 22 96 29 7B 00 3F 00 01 01 00 00 00 00 00 00 00 4D 53 47 00 00 00 00 00 5D 6B 8E 1A FE 39 0B FC 00 00 00 00 09 00 86 00 00 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91 00 00 01 00 0A 01 00 07 6D 65 73 73 61 67 65"
|
||||||
));
|
));
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
System.out.println(HexComparator.compare(
|
System.out.println(HexComparator.compare(
|
||||||
|
Loading…
Reference in New Issue
Block a user