This commit is contained in:
liujiahua123123 2019-08-28 11:04:31 +08:00
parent 01771cdcee
commit 2c17c9f3a8
15 changed files with 265 additions and 37 deletions

View File

@ -1,6 +1,9 @@
package net.mamoe.mirai; package net.mamoe.mirai;
import net.mamoe.mirai.utils.config.MiraiConfig;
import net.mamoe.mirai.utils.config.MiraiConfigSection;
/** /**
* @author Him188moe * @author Him188moe
*/ */
@ -11,5 +14,15 @@ public final class MiraiMain {
Runtime.getRuntime().addShutdownHook(new Thread(() -> { Runtime.getRuntime().addShutdownHook(new Thread(() -> {
server.shutdown(); server.shutdown();
})); }));
MiraiConfig config = new MiraiConfig("QQ.yml");
MiraiConfigSection<Object> data = config.getSection("123123");
data.put("account","123123a");
try {
Robot robot = new Robot(data);
} catch (Throwable throwable) {
throwable.printStackTrace();
}
} }
} }

View File

@ -4,8 +4,6 @@ import lombok.Getter;
import net.mamoe.mirai.event.MiraiEventManager; import net.mamoe.mirai.event.MiraiEventManager;
import net.mamoe.mirai.event.events.server.ServerDisableEvent; import net.mamoe.mirai.event.events.server.ServerDisableEvent;
import net.mamoe.mirai.event.events.server.ServerEnableEvent; import net.mamoe.mirai.event.events.server.ServerEnableEvent;
import net.mamoe.mirai.network.Robot;
import net.mamoe.mirai.network.packet.client.touch.ClientTouchPacket;
import net.mamoe.mirai.task.MiraiTaskManager; import net.mamoe.mirai.task.MiraiTaskManager;
import net.mamoe.mirai.utils.LoggerTextFormat; import net.mamoe.mirai.utils.LoggerTextFormat;
import net.mamoe.mirai.utils.MiraiLogger; import net.mamoe.mirai.utils.MiraiLogger;
@ -60,7 +58,7 @@ public class MiraiServer {
protected void shutdown(){ protected void shutdown(){
if(this.enabled) { if(this.enabled) {
getLogger().info(LoggerTextFormat.SKY_BLUE + "About to shutdown Mirai"); getLogger().info(LoggerTextFormat.SKY_BLUE + "About to shutdown Mirai");
this.getEventManager().boardcastEvent(new ServerDisableEvent()); this.getEventManager().broadcastEvent(new ServerDisableEvent());
getLogger().info(LoggerTextFormat.SKY_BLUE + "Data have been saved"); getLogger().info(LoggerTextFormat.SKY_BLUE + "Data have been saved");
} }
@ -137,17 +135,18 @@ public class MiraiServer {
*/ */
Robot robot = new Robot(1994701021, "xiaoqqq"); /*
RobotNetworkHandler robotNetworkHandler = new RobotNetworkHandler(1994701021, "xiaoqqq");
try { try {
//System.out.println(Protocol.Companion.getSERVER_IP().get(3)); //System.out.println(Protocol.Companion.getSERVER_IP().get(3));
//System.out.println(Protocol.Companion.getSERVER_IP().toString()); //System.out.println(Protocol.Companion.getSERVER_IP().toString());
robot.setServerIP("14.116.136.106"); robotNetworkHandler.setServerIP("14.116.136.106");
robot.sendPacket(new ClientTouchPacket(1994701021, "14.116.136.106")); robotNetworkHandler.sendPacket(new ClientTouchPacket(1994701021, "14.116.136.106"));
while (true) ; while (true) ;
//robot.connect("14.116.136.106"); //robotNetworkHandler.connect("14.116.136.106");
//robot.connect(Protocol.Companion.getSERVER_IP().get(2)); //robotNetworkHandler.connect(Protocol.Companion.getSERVER_IP().get(2));
//robot.connect("125.39.132.242"); //robotNetworkHandler.connect("125.39.132.242");
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
System.exit(1); System.exit(1);
@ -207,7 +206,7 @@ public class MiraiServer {
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 robot"); getLogger().info(LoggerTextFormat.SKY_BLUE + "input one " + LoggerTextFormat.RED + " QQ number " + LoggerTextFormat.SKY_BLUE + "for default robotNetworkHandler");
getLogger().info(LoggerTextFormat.SKY_BLUE + "输入用于默认机器人的QQ号"); getLogger().info(LoggerTextFormat.SKY_BLUE + "输入用于默认机器人的QQ号");
long qqNumber = scanner.nextLong(); long qqNumber = scanner.nextLong();
getLogger().info(LoggerTextFormat.SKY_BLUE + "input the password for that QQ account"); getLogger().info(LoggerTextFormat.SKY_BLUE + "input the password for that QQ account");
@ -223,7 +222,7 @@ public class MiraiServer {
} }
private void onEnable(){ private void onEnable(){
this.eventManager.boardcastEvent(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");
getLogger().info("Mirai Version=" + MiraiServer.MIRAI_VERSION + " QQ Version=" + MiraiServer.QQ_VERSION); getLogger().info("Mirai Version=" + MiraiServer.MIRAI_VERSION + " QQ Version=" + MiraiServer.QQ_VERSION);

View File

@ -0,0 +1,58 @@
package net.mamoe.mirai;
import lombok.Getter;
import net.mamoe.mirai.network.RobotNetworkHandler;
import net.mamoe.mirai.utils.config.MiraiConfigSection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Robot {
private final int qq;
private final String password;
private final RobotNetworkHandler handler ;
/**
* Ref list
*/
@Getter
private final List<String> owners;
public boolean isOwnBy(String ownerName){
return owners.contains(ownerName);
}
public Robot(MiraiConfigSection<Object> data) throws Throwable {
this(
data.getIntOrThrow("account", () -> new Exception("can not parse QQ account")),
data.getStringOrThrow("password", () -> new Exception("can not parse QQ password")),
data.getAsOrDefault("owners",new ArrayList<>())
);
}
public Robot(int qq, String password, List<String> owners){
this.qq = qq;
this.password = password;
this.owners = Collections.unmodifiableList(owners);
this.handler = new RobotNetworkHandler(this.qq,this.password);
}
public void connect(){
}
public void onPacketReceive(){
}
}

View File

@ -1,10 +1,13 @@
package net.mamoe.mirai.event; package net.mamoe.mirai.event;
import net.mamoe.mirai.MiraiServer;
import net.mamoe.mirai.event.events.MiraiEvent; import net.mamoe.mirai.event.events.MiraiEvent;
import java.util.*; import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -90,7 +93,7 @@ public class MiraiEventManager {
public void boardcastEvent(MiraiEvent event){ public void broadcastEvent(MiraiEvent event){
hooksLock.lock(); hooksLock.lock();
if(hooks.containsKey(event.getClass())){ if(hooks.containsKey(event.getClass())){
hooks.put(event.getClass(), hooks.put(event.getClass(),
@ -104,6 +107,20 @@ public class MiraiEventManager {
hooksLock.unlock(); hooksLock.unlock();
} }
public void ansycBroadcastEvent(MiraiEvent event){
this.ansycBroadcastEvent(event,a -> {});
}
public <D extends MiraiEvent> void ansycBroadcastEvent(D event, Consumer<D> callback){
MiraiServer.getInstance().getTaskManager().ansycTask(() -> {
MiraiEventManager.this.broadcastEvent(event);
return event;
},callback);
}
} }

View File

@ -0,0 +1,11 @@
package net.mamoe.mirai.event.events.robot;
import net.mamoe.mirai.Robot;
public class RobotConnectedEvent extends RobotEvent {
public RobotConnectedEvent(Robot robot) {
super(robot);
}
}

View File

@ -0,0 +1,14 @@
package net.mamoe.mirai.event.events.robot;
import lombok.Getter;
import net.mamoe.mirai.Robot;
import net.mamoe.mirai.event.events.MiraiEvent;
public abstract class RobotEvent extends MiraiEvent {
@Getter
private final Robot robot;
public RobotEvent(Robot robot){
this.robot = robot;
}
}

View File

@ -1,16 +1,16 @@
package net.mamoe.mirai.event.events.robot package net.mamoe.mirai.event.events.robot
import net.mamoe.mirai.event.events.MiraiEvent import net.mamoe.mirai.event.events.MiraiEvent
import net.mamoe.mirai.network.Robot import net.mamoe.mirai.network.RobotNetworkHandler
/** /**
* @author Him188moe * @author Him188moe
*/ */
class RobotLoginEvent(val robot: Robot) : MiraiEvent() class RobotLoginEvent(val robotNetworkHandler: RobotNetworkHandler) : MiraiEvent()
class RobotLogoutEvent(val robot: Robot) : MiraiEvent() class RobotLogoutEvent(val robotNetworkHandler: RobotNetworkHandler) : MiraiEvent()
class RobotMessageReceivedEvent(val robot: Robot, val type: Type, val message: String) : MiraiEvent() { class RobotMessageReceivedEvent(val robotNetworkHandler: RobotNetworkHandler, val type: Type, val message: String) : MiraiEvent() {
enum class Type { enum class Type {
FRIEND, FRIEND,
GROUP GROUP

View File

@ -18,11 +18,11 @@ import java.net.DatagramSocket
import java.net.InetSocketAddress import java.net.InetSocketAddress
/** /**
* A robot account. * A robotNetworkHandler account.
* *
* @author Him188moe * @author Him188moe
*/ */
class Robot(val number: Int, private val password: String) { class RobotNetworkHandler(val number: Int, private val password: String) {
private var sequence: Int = 0 private var sequence: Int = 0
private var channel: Channel? = null private var channel: Channel? = null
@ -205,7 +205,7 @@ private lateinit var ctx: ChannelHandlerContext
.handler(object : ChannelInitializer<NioDatagramChannel>() { .handler(object : ChannelInitializer<NioDatagramChannel>() {
override fun channelActive(ctx: ChannelHandlerContext?) { override fun channelActive(ctx: ChannelHandlerContext?) {
this@Robot.ctx = ctx!! this@RobotNetworkHandler.ctx = ctx!!
super.channelActive(ctx) super.channelActive(ctx)
} }
@ -217,7 +217,7 @@ private lateinit var ctx: ChannelHandlerContext
ch.pipeline().addLast(object : SimpleChannelInboundHandler<ByteArray>() { ch.pipeline().addLast(object : SimpleChannelInboundHandler<ByteArray>() {
override fun channelRead0(ctx: ChannelHandlerContext, bytes: ByteArray) { override fun channelRead0(ctx: ChannelHandlerContext, bytes: ByteArray) {
try { try {
this@Robot.onPacketReceived(ServerPacket.ofByteArray(bytes)) this@RobotNetworkHandler.onPacketReceived(ServerPacket.ofByteArray(bytes))
} catch (e: Exception) { } catch (e: Exception) {
MiraiLogger.catching(e) MiraiLogger.catching(e)
} }
@ -231,7 +231,7 @@ private lateinit var ctx: ChannelHandlerContext
ch.pipeline().addLast(object : SimpleChannelInboundHandler<DatagramPacket>() { ch.pipeline().addLast(object : SimpleChannelInboundHandler<DatagramPacket>() {
override fun channelRead0(ctx: ChannelHandlerContext, bytes: DatagramPacket) { override fun channelRead0(ctx: ChannelHandlerContext, bytes: DatagramPacket) {
try { try {
this@Robot.onPacketReceived(ServerPacket.ofByteArray(bytes.data)) this@RobotNetworkHandler.onPacketReceived(ServerPacket.ofByteArray(bytes.data))
} catch (e: Exception) { } catch (e: Exception) {
MiraiLogger.catching(e) MiraiLogger.catching(e)
} }
@ -247,7 +247,7 @@ private lateinit var ctx: ChannelHandlerContext
channel = b.bind(15345).sync().channel() channel = b.bind(15345).sync().channel()
MiraiLogger info "Succeed" MiraiLogger info "Succeed"
sendPacket(ClientTouchPacket(this@Robot.number, serverIP)) sendPacket(ClientTouchPacket(this@RobotNetworkHandler.number, serverIP))
channel!!.closeFuture().sync() channel!!.closeFuture().sync()
} finally { } finally {
group.shutdownGracefully().sync() group.shutdownGracefully().sync()

View File

@ -34,7 +34,7 @@ class ServerLoginResponseResendPacket(input: DataInputStream, val flag: Flag) :
Flag.OTHER -> { Flag.OTHER -> {
//do nothing in this packet. //do nothing in this packet.
//[this.token] will be set in [Robot] //[this.token] will be set in [RobotNetworkHandler]
//token //token
} }
} }

View File

@ -37,7 +37,7 @@ class ServerSessionKeyResponsePacket(inputStream: DataInputStream) : ServerPacke
} }
/** /**
* Encrypted using []0828_rec_decr_key], decrypting in Robot * Encrypted using []0828_rec_decr_key], decrypting in RobotNetworkHandler
* *
* @author Him188moe * @author Him188moe
*/ */

View File

@ -14,18 +14,18 @@ object Utils {
fun toHexString(byteArray: ByteArray, separator: String = " "): String = byteArray.joinToString(separator) { fun toHexString(byteArray: ByteArray, separator: String = " "): String = byteArray.joinToString(separator) {
var ret = it.toString(16).toUpperCase(); var ret = it.toString(16).toUpperCase();
if (ret.length == 1) { if (ret.length == 1) {
ret = "0$ret"; ret = "0$ret"
} }
return@joinToString ret; return@joinToString ret
} }
@ExperimentalUnsignedTypes @ExperimentalUnsignedTypes
fun toHexString(byteArray: UByteArray, separator: String = " "): String = byteArray.joinToString(separator) { fun toHexString(byteArray: UByteArray, separator: String = " "): String = byteArray.joinToString(separator) {
var ret = it.toString(16).toUpperCase(); var ret = it.toString(16).toUpperCase();
if (ret.length == 1) { if (ret.length == 1) {
ret = "0$ret"; ret = "0$ret"
} }
return@joinToString ret; return@joinToString ret
} }
} }
@ -68,7 +68,7 @@ fun lazyEncode(t: (ByteArrayDataOutputStream) -> Unit): ByteArray = ByteArrayDat
@ExperimentalUnsignedTypes @ExperimentalUnsignedTypes
fun getRandomKey(length: Int): ByteArray { fun getRandomKey(length: Int): ByteArray {
val bytes = LinkedList<Byte>(); val bytes = LinkedList<Byte>()
repeat(length) { bytes.add((Math.random() * 255).toByte()) } repeat(length) { bytes.add((Math.random() * 255).toByte()) }
return bytes.toByteArray(); return bytes.toByteArray();
} }

View File

@ -68,4 +68,5 @@ public class MiraiConfig extends MiraiConfigSection<Object> {
} }
} }

View File

@ -1,8 +1,10 @@
package net.mamoe.mirai.utils.config; package net.mamoe.mirai.utils.config;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.IllegalFormatException;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.Callable;
public class MiraiConfigSection<T> extends MiraiSynchronizedLinkedListMap<String, T> { public class MiraiConfigSection<T> extends MiraiSynchronizedLinkedListMap<String, T> {
@ -14,24 +16,122 @@ public class MiraiConfigSection<T> extends MiraiSynchronizedLinkedListMap<String
super(map); super(map);
} }
public int getInt(String key){
public Integer getInt(String key){
return Integer.valueOf(this.get(key).toString()); return Integer.valueOf(this.get(key).toString());
} }
public Double getDouble(String key){ public int getIntOrDefault(String key, int defaultV){
Object result = this.getOrDefault(key, null);
try {
return result == null ? defaultV : Integer.valueOf(result.toString());
}catch (NumberFormatException ignored){
return defaultV;
}
}
public int getIntOrThrow(String key, Callable<Throwable> throwableCallable) throws Throwable {
Object result = this.getOrDefault(key, null);
if(result == null){
throw throwableCallable.call();
}
try {
return Integer.valueOf(result.toString());
}catch (NumberFormatException ignored){
throw throwableCallable.call();
}
}
public double getDouble(String key){
return Double.valueOf(this.get(key).toString()); return Double.valueOf(this.get(key).toString());
} }
public Float getFloat(String key){ public double getDoubleOrDefault(String key, double defaultV){
Object result = this.getOrDefault(key, null);
try {
return result==null?defaultV:Double.valueOf(result.toString());
}catch (NumberFormatException ignored){
return defaultV;
}
}
public double getDoubleOrThrow(String key, Callable<Throwable> throwableCallable) throws Throwable {
Object result = this.getOrDefault(key, null);
if(result == null){
throw throwableCallable.call();
}
try {
return Double.valueOf(result.toString());
}catch (NumberFormatException ignored){
throw throwableCallable.call();
}
}
public float getFloat(String key){
return Float.valueOf(this.get(key).toString()); return Float.valueOf(this.get(key).toString());
} }
public float getFloatOrDefault(String key, float defaultV){
Object result = this.getOrDefault(key, null);
try {
return result == null ? defaultV : Float.valueOf(result.toString());
}catch (NumberFormatException ignored){
return defaultV;
}
}
public float getFloatOrThrow(String key, Callable<Throwable> throwableCallable) throws Throwable {
Object result = this.getOrDefault(key, null);
if(result == null){
throw throwableCallable.call();
}
try {
return Float.valueOf(result.toString());
}catch (NumberFormatException ignored){
throw throwableCallable.call();
}
}
public long getLong(String key){
return Long.valueOf(this.get(key).toString());
}
public long getLongOrDefault(String key, long defaultV){
Object result = this.getOrDefault(key, null);
try {
return result == null ? defaultV : Long.valueOf(result.toString());
}catch (NumberFormatException ignored){
return defaultV;
}
}
public long getLongOrThrow(String key, Callable<Throwable> throwableCallable) throws Throwable {
Object result = this.getOrDefault(key, null);
if(result == null){
throw throwableCallable.call();
}
try {
return Long.valueOf(result.toString());
}catch (NumberFormatException ignored){
throw throwableCallable.call();
}
}
public String getString(String key){ public String getString(String key){
return String.valueOf(this.get(key)); return String.valueOf(this.get(key));
} }
public String getStringOrDefault(String key, String defaultV){
Object result = this.getOrDefault(key, null);
return result==null?defaultV:result.toString();
}
public String getStringOrThrow(String key, Callable<Throwable> throwableCallable) throws Throwable {
Object result = this.getOrDefault(key, null);
if(result == null){
throw throwableCallable.call();
}
return result.toString();
}
@Nullable @Nullable
@Override @Override
@ -57,6 +157,8 @@ public class MiraiConfigSection<T> extends MiraiSynchronizedLinkedListMap<String
return this.getTypedSection(key); return this.getTypedSection(key);
} }
@SuppressWarnings("unchecked")
public <D extends T> D getAsOrDefault(String key, D defaultV){
return (D)this.getOrDefault(key,defaultV);
}
} }

View File

@ -153,8 +153,13 @@ public class MiraiSynchronizedLinkedListMap<K,V> extends AbstractMap<K,V> {
return this.sortedMap.merge(key,value,remappingFunction); return this.sortedMap.merge(key,value,remappingFunction);
} }
public boolean equals(MiraiSynchronizedLinkedListMap o) {
return this.sortedMap.equals(o.sortedMap);
}
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
return this.sortedMap.equals(o); return o instanceof MiraiSynchronizedLinkedListMap?this.equals((MiraiSynchronizedLinkedListMap)o):super.equals(o);
} }
} }

View File

@ -0,0 +1,8 @@
import net.mamoe.mirai.MiraiServer;
import net.mamoe.mirai.utils.config.MiraiConfig;
public class ConfigTest {
public static void main(String[] args){
MiraiConfig config = new MiraiConfig("QQ.yml");
}
}