diff --git a/pom.xml b/pom.xml index e1b26d9..87bcf7a 100644 --- a/pom.xml +++ b/pom.xml @@ -158,7 +158,12 @@ retrofit 2.11.0 - + + + org.jsoup + jsoup + 1.17.2 + diff --git a/src/main/java/com/yutou/napcat/event/MessageEvent.java b/src/main/java/com/yutou/napcat/event/MessageEvent.java index b89dfe1..2f465ae 100644 --- a/src/main/java/com/yutou/napcat/event/MessageEvent.java +++ b/src/main/java/com/yutou/napcat/event/MessageEvent.java @@ -70,55 +70,63 @@ public class MessageEvent { public static MessageEvent parseHandle(String jsonString) { JSONObject json = JSONObject.parseObject(jsonString); - JSONArray array = json.getJSONArray("message"); List> messageList = new ArrayList<>(); - for (Object o : array) { - JSONObject _json = (JSONObject) o; - Type classType = null; - MessageEnum _type = MessageEnum.of(_json.getString("type")); - classType = switch (_type) { - case TEXT -> Text.TextInfo.class; - case IMAGE -> Image.ImageInfo.class; - case AT -> At.AtData.class; - case JSON -> OtherHandle.OtherInfo.class; - case REPLY -> Reply.ReplyInfo.class; - default -> classType; - }; - BaseHandle handle = new BaseHandle<>(_type.getType()); - if (_type == MessageEnum.JSON) { - handle.setData(JSONObject.parseObject(((JSONObject) o).getJSONObject("data").getString("data"), classType)); - } else { - handle.setData(JSONObject.parseObject(((JSONObject) o).getJSONObject("data").toString(), classType)); + if (array != null) { + for (Object o : array) { + JSONObject _json = (JSONObject) o; + Type classType = null; + MessageEnum _type = MessageEnum.of(_json.getString("type")); + classType = switch (_type) { + case TEXT -> Text.TextInfo.class; + case IMAGE -> Image.ImageInfo.class; + case AT -> At.AtData.class; + case JSON -> OtherHandle.OtherInfo.class; + case REPLY -> Reply.ReplyInfo.class; + default -> classType; + }; + BaseHandle handle = new BaseHandle<>(_type.getType()); + if (_type == MessageEnum.JSON) { + handle.setData(JSONObject.parseObject(((JSONObject) o).getJSONObject("data").getString("data"), classType)); + } else { + handle.setData(JSONObject.parseObject(((JSONObject) o).getJSONObject("data").toString(), classType)); + } + messageList.add(handle); } - messageList.add(handle); } - - - SourceFrom sender = new SourceFrom(); - sender.setUserId(json.getJSONObject("sender").getLong("user_id")); - sender.setNickname(json.getJSONObject("sender").getString("nickname")); - sender.setCard(json.getJSONObject("sender").getString("card")); - MessageEvent event = new MessageEvent(); - event.setSelfId(json.getLong("self_id")); - event.setUserId(json.getLong("user_id")); event.setTime(json.getLong("time")); - event.setMessageId(json.getInteger("message_id")); - event.setRealId(json.getInteger("real_id")); - event.setMessageType(json.getString("message_type")); - event.setSource(sender); - event.setRawMessage(json.getString("raw_message")); - event.setFont(json.getInteger("font")); - event.setSubType(json.getString("sub_type")); - event.setMessageFormat(json.getString("message_format")); + event.setSelfId(json.getLong("self_id")); event.setPostType(json.getString("post_type")); event.setGroupId(json.getLong("group_id")); - event.setMessage(messageList); + event.setUserId(json.getLong("user_id")); + event.setSubType(json.getString("sub_type")); + try { + SourceFrom sender = new SourceFrom(); + sender.setUserId(event.getUserId()); + event.setSource(sender); + sender.setUserId(json.getJSONObject("sender").getLong("user_id")); + sender.setNickname(json.getJSONObject("sender").getString("nickname")); + sender.setCard(json.getJSONObject("sender").getString("card")); + event.setMessageId(json.getInteger("message_id")); + event.setRealId(json.getInteger("real_id")); + event.setMessageType(json.getString("message_type")); + event.setSource(sender); + event.setRawMessage(json.getString("raw_message")); + event.setFont(json.getInteger("font")); + event.setMessageFormat(json.getString("message_format")); + event.setMessage(messageList); + return event; + } catch (Exception e) { + System.err.println("jsonString:\n" + jsonString); + } return event; } public boolean hasType(MessageEnum messageEnum) { + if(message==null||message.isEmpty()){ + return false; + } for (BaseHandle handle : message) { if (MessageEnum.of(handle.getType()) == messageEnum) { return true; @@ -129,6 +137,9 @@ public class MessageEvent { public List findAllType(Class t) { List tmp = new ArrayList<>(); + if (message == null || message.isEmpty()) { + return tmp; + } try { T newed = t.getDeclaredConstructor().newInstance(); for (BaseHandle baseHandle : message) { diff --git a/src/main/java/com/yutou/napcat/http/GroupApi.java b/src/main/java/com/yutou/napcat/http/GroupApi.java index 9631841..1d7d9c7 100644 --- a/src/main/java/com/yutou/napcat/http/GroupApi.java +++ b/src/main/java/com/yutou/napcat/http/GroupApi.java @@ -15,10 +15,10 @@ import java.util.List; public interface GroupApi { /** * 禁言 - * @param group 群号 - * @param user 用户 - * @param duration 禁言时长,单位秒 * + * @param group 群号 + * @param user 用户 + * @param duration 禁言时长,单位秒 */ @FormUrlEncoded @POST("/set_group_ban") @@ -30,6 +30,7 @@ public interface GroupApi { /** * 禁言群组全体成员 + * * @param group 群号 */ @FormUrlEncoded @@ -61,11 +62,28 @@ public interface GroupApi { /** * 获取群组成员列表 + * * @param group 群号 */ @FormUrlEncoded @POST("/get_group_member_list") - Call> getGroupUserList( - @Field("group_id") long group + Call>> getGroupUserList( + @Field("group_id") long group, + @Field("no_cache")boolean noCache ); + + /** + * 设置群组专属头衔 + * @param group 群号 + * @param user 用户 + * @param title 头衔 + * @param duration 持续时间,单位秒 + */ + @POST("/set_group_special_title") + @FormUrlEncoded + Call> setGroupSpecialTitle( + @Field("group_id") long group, + @Field("user_id") long user, + @Field("special_title") String title, + @Field("duration") long duration ); } diff --git a/src/main/java/com/yutou/napcat/model/GroupUserBean.java b/src/main/java/com/yutou/napcat/model/GroupUserBean.java index 9e20250..e09c0cb 100644 --- a/src/main/java/com/yutou/napcat/model/GroupUserBean.java +++ b/src/main/java/com/yutou/napcat/model/GroupUserBean.java @@ -65,5 +65,8 @@ public class GroupUserBean extends BaseBean { // 是否允许修改群名片 @JSONField(name = "card_changeable") private boolean cardChangeable; + // 禁言剩余时间 + @JSONField(name = "shut_up_timestamp") + private long shutUpTimestamp; } diff --git a/src/main/java/com/yutou/qqbot/QQBotApplication.java b/src/main/java/com/yutou/qqbot/QQBotApplication.java index 8c746cb..8a93256 100644 --- a/src/main/java/com/yutou/qqbot/QQBotApplication.java +++ b/src/main/java/com/yutou/qqbot/QQBotApplication.java @@ -10,7 +10,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class QQBotApplication { - public static final String version = "QQBot v.1.7.6.2"; + public static final String version = "QQBot v.1.7.7"; public static void main(String[] args) { System.out.println("version = " + version); diff --git a/src/main/java/com/yutou/qqbot/QQBotManager.java b/src/main/java/com/yutou/qqbot/QQBotManager.java index a3ed549..249b1bc 100644 --- a/src/main/java/com/yutou/qqbot/QQBotManager.java +++ b/src/main/java/com/yutou/qqbot/QQBotManager.java @@ -10,10 +10,13 @@ import com.yutou.napcat.handle.Text; import com.yutou.napcat.http.NapCatApi; import com.yutou.napcat.model.FriendBean; import com.yutou.napcat.model.GroupBean; +import com.yutou.napcat.model.GroupUserBean; import com.yutou.napcat.model.SendMessageResponse; +import com.yutou.okhttp.BaseBean; import com.yutou.okhttp.HttpBody; import com.yutou.okhttp.HttpCallback; import com.yutou.qqbot.data.MessageChainBuilder; +import com.yutou.qqbot.interfaces.ObjectInterface; import com.yutou.qqbot.utlis.*; import retrofit2.Response; @@ -120,7 +123,7 @@ public class QQBotManager { public SendMessageResponse sendMessage(boolean isUser, Long qq, List> items) { try { - if(!ConfigTools.load(ConfigTools.CONFIG,ConfigTools.QQ, Boolean.class)){ + if (!ConfigTools.load(ConfigTools.CONFIG, ConfigTools.QQ, Boolean.class)) { return null; } MessageHandleBuild handleBuild = MessageHandleBuild @@ -193,6 +196,45 @@ public class QQBotManager { } + public void groupBan(long qqGroup, long user, int timer, ObjectInterface objectInterface) { + NapCatApi.getGroupApi().groupBan(qqGroup, user, timer).enqueue(new HttpCallback() { + @Override + public void onResponse(int code, String status, BaseBean response, String rawResponse) { + if (objectInterface != null) { + objectInterface.out("1"); + } + } + + @Override + public void onFailure(Throwable throwable) { + if (objectInterface != null) { + objectInterface.out(null); + } + } + }); + } + + public void getShutUpList(long qqGroup, HttpCallback> callback) { + NapCatApi.getGroupApi().getGroupUserList(qqGroup,true).enqueue(callback); + } + + public void setGroupSpecialTitle(long group, + long user, + String title, + long duration) { + NapCatApi.getGroupApi().setGroupSpecialTitle(group, user, title, duration).enqueue(new HttpCallback() { + + @Override + public void onResponse(int code, String status, BaseBean response, String rawResponse) { + + } + + @Override + public void onFailure(Throwable throwable) { + + } + }); + } public static void main(String[] args) { JSONObject json = new JSONObject(); diff --git a/src/main/java/com/yutou/qqbot/models/Animal/TurnipProphet.java b/src/main/java/com/yutou/qqbot/models/Animal/TurnipProphet.java index 1202631..30c920e 100644 --- a/src/main/java/com/yutou/qqbot/models/Animal/TurnipProphet.java +++ b/src/main/java/com/yutou/qqbot/models/Animal/TurnipProphet.java @@ -17,6 +17,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; + @UseModel public class TurnipProphet extends Model { public static class TurnipData { @@ -271,14 +272,19 @@ public class TurnipProphet extends Model { out.append("网页版:").append("\n").append(url).append("\n"); out.append("祝好运 :)"); - Log.i("TurnipProphet", out.toString()+"\n 发送QQ:"+sendQQ); + if (ConfigTools.load(ConfigTools.CONFIG, ConfigTools.TURNIP_PROPHET_SEND_TMP_GROUP, Boolean.class)) { + out.append("\n使用者:").append(sendQQ); + sendQQ = 891655174L; + } + + Log.i("TurnipProphet", out.toString() + "\n 发送QQ:" + sendQQ); QQBotManager.getInstance().sendMessage(sendQQ, getMessage(out.toString())); return prArray.getJSONObject(0).getString(TurnipData.MODEL); } @Override - public void onTime(Long qq,String time) { - super.onTime(qq,time); + public void onTime(Long qq, String time) { + super.onTime(qq, time); nowTime = Integer.parseInt(time.split(":")[0]); } @@ -295,16 +301,17 @@ public class TurnipProphet extends Model { public static void main(String[] args) throws Exception { TurnipProphet prophet = new TurnipProphet(); - String prices="108.93.89.84.79........"; - String pattern="0"; - Mapmap=prophet.openTurnip(prices,pattern); - prophet.sendQQ(map,prices,pattern); + String prices = "108.93.89.84.79........"; + String pattern = "0"; + Map map = prophet.openTurnip(prices, pattern); + prophet.sendQQ(map, prices, pattern); } public Map openTurnip(String prices, String pattern) throws Exception { - String url = String.format("http://192.168.31.88:7000/?prices=%s%s", + String url = String.format("http://%s/?prices=%s%s", + ConfigTools.load(ConfigTools.CONFIG, ConfigTools.TURNIP_PROPHET_SERVER, String.class), prices, pattern == null ? "" : "&pattern=" + pattern ); diff --git a/src/main/java/com/yutou/qqbot/models/Commands/QQBean.java b/src/main/java/com/yutou/qqbot/models/Commands/QQBean.java new file mode 100644 index 0000000..094274d --- /dev/null +++ b/src/main/java/com/yutou/qqbot/models/Commands/QQBean.java @@ -0,0 +1,148 @@ +package com.yutou.qqbot.models.Commands; + +import com.yutou.napcat.event.MessageEvent; +import com.yutou.napcat.handle.At; +import com.yutou.napcat.handle.Text; +import com.yutou.napcat.http.NapCatApi; +import com.yutou.napcat.model.GroupUserBean; +import com.yutou.okhttp.BaseBean; +import com.yutou.okhttp.HttpCallback; +import com.yutou.qqbot.Annotations.UseModel; +import com.yutou.qqbot.QQBotManager; +import com.yutou.qqbot.interfaces.ObjectInterface; +import com.yutou.qqbot.models.Model; +import com.yutou.qqbot.utlis.RedisTools; + +import java.text.SimpleDateFormat; +import java.util.*; + +@UseModel +public class QQBean extends Model { + @Override + public boolean isUserPublic() { + return true; + } + + @Override + public String[] getUsePowers() { + return new String[0]; + } + + @Override + public String getModelName() { + return "QQ禁言"; + } + + Random random = new Random(); + + @Override + public void onMessage(Long qq, MessageEvent event, boolean isGroup) { + super.onMessage(qq, event, isGroup); + if (!isGroup) return; + if ("抽奖".equals(msg)) { + int hour = 60; + int day = 1440; + int max = 30 * day; + int time = 1; + if (random.nextInt(100) == 23) { + releaseAll(qq, true); + } else if (random.nextInt(10) > 2) { + time = random.nextInt(hour); + } else if (random.nextInt(10) > 4) { + time = random.nextInt(day); + } else if (random.nextInt(10) > 5) { + time = random.nextInt(day, 3 * day); + } else { + time = random.nextInt(max); + + } + int sendTime = time; + QQBotManager.getInstance().groupBan(qq, user, sendTime * 60, new ObjectInterface() { + @Override + public void out(String data) { + super.out(data); + if (data != null) { + QQBotManager.getInstance().sendMessage(event.isUser(), qq, + new Text("恭喜"), + new At(user), + new Text("获得了" + sendTime + "分钟的禁言," + sendAchievement(qq, user, sendTime)) + ); + if (sendTime > day && random.nextInt(10) >= 3) { + int tmp = random.nextInt(sendTime / 2, sendTime); + QQBotManager.getInstance().groupBan(qq, user, (sendTime - tmp) * 60, null); + QQBotManager.getInstance().sendMessage(qq, "触发减伤:-" + tmp); + } + } + } + }); + } else if ("大赦天下".equals(msg) && isAdmin()) { + releaseAll(qq, true); + } else if ("查看禁言列表".equals(msg) && isAdmin()) { + releaseAll(qq, false); + } + + } + + String sendAchievement(long qq, long user, int timer) { + Calendar data1 = Calendar.getInstance(); + Calendar data2 = Calendar.getInstance(); + data1.setTime(new Date()); + data2.set(Calendar.HOUR_OF_DAY, 23); + data2.set(Calendar.MINUTE, 59); + data2.set(Calendar.SECOND, 59); + long time = data2.getTimeInMillis() - data1.getTimeInMillis(); + String achievement = RedisTools.get("shut_" + qq + "_" + user); + int achievementTimer = timer; + if (achievement != null) { + achievementTimer += Integer.parseInt(achievement); + } + RedisTools.set("shut_" + qq + "_" + user, achievementTimer + "", time / 1000); + return "今日累计" + achievementTimer + "分钟禁言"; + } + + void releaseAll(long qq, boolean isRelease) { + QQBotManager.getInstance().getShutUpList(qq, new HttpCallback>() { + @Override + public void onResponse(int code, String status, List response, String rawResponse) { + List shutList = new ArrayList<>(); + for (GroupUserBean bean : response) { + if (bean.getShutUpTimestamp() > 60) { + shutList.add(bean); + } + } + if (!shutList.isEmpty()) { + + if (!isRelease) { + StringBuilder sb = new StringBuilder(); + for (GroupUserBean bean : shutList) { + sb.append(bean.getNickname()).append(":").append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",Locale.CHINA).format(new Date(bean.getShutUpTimestamp()))).append("\n"); + } + QQBotManager.getInstance().sendMessage(qq, "当前塞了:" + shutList.size() + "人" + "\n" + sb); + return; + } + QQBotManager.getInstance().sendMessage(qq, "触发自动解禁,解禁人数:" + shutList.size() + "人"); + for (GroupUserBean bean : shutList) { + NapCatApi.getGroupApi().groupBan(qq, bean.getUserId(), 0).enqueue(new HttpCallback() { + @Override + public void onResponse(int code, String status, BaseBean response, String rawResponse) { + + } + + @Override + public void onFailure(Throwable throwable) { + + } + }); + } + } else { + QQBotManager.getInstance().sendMessage(qq, "阿巴阿巴"); + } + } + + @Override + public void onFailure(Throwable throwable) { + + } + }); + } +} diff --git a/src/main/java/com/yutou/qqbot/models/Model.java b/src/main/java/com/yutou/qqbot/models/Model.java index 21cbdba..1cf7318 100644 --- a/src/main/java/com/yutou/qqbot/models/Model.java +++ b/src/main/java/com/yutou/qqbot/models/Model.java @@ -84,6 +84,9 @@ public abstract class Model implements ModelInterface { public void onMessage(Long qq, MessageEvent event, boolean isGroup) { this.event = event; msg = event.getRawMessage(); + if(msg==null){ + msg=""; + } msg = msg.replace("!", "!").trim(); this.isGroup = event.isGroup(); if (isGroup) { diff --git a/src/main/java/com/yutou/qqbot/utlis/ConfigTools.java b/src/main/java/com/yutou/qqbot/utlis/ConfigTools.java index 9730339..ecdd0de 100644 --- a/src/main/java/com/yutou/qqbot/utlis/ConfigTools.java +++ b/src/main/java/com/yutou/qqbot/utlis/ConfigTools.java @@ -31,6 +31,8 @@ public class ConfigTools { public static final String BAIDU_GPT_APPID = "baidu.gpt.appid"; public static final String BAIDU_GPT_API_KEY = "baidu.gpt.apikey"; public static final String BAIDU_GPT_SECRET_KEY = "baidu.gpt.SecretKey"; + public static final String TURNIP_PROPHET_SERVER = "turnip.server"; + public static final String TURNIP_PROPHET_SEND_TMP_GROUP = "turnip.send.tmp.group"; static { diff --git a/src/main/java/com/yutou/qqbot/utlis/RedisTools.java b/src/main/java/com/yutou/qqbot/utlis/RedisTools.java index 7dafb6b..fe3a932 100644 --- a/src/main/java/com/yutou/qqbot/utlis/RedisTools.java +++ b/src/main/java/com/yutou/qqbot/utlis/RedisTools.java @@ -90,7 +90,7 @@ public class RedisTools { } public static String get(String key, int dbIndex) { - String value = "-999"; + String value = null; if (isNotInstallRedis) { return value; } @@ -411,7 +411,7 @@ public class RedisTools { } public static void main(String[] args) { - // RedisTools.pullMsg("msg", "abc"); - RedisTools.set("test","abc"); + // RedisTools.pullMsg("msg", "abc"); + RedisTools.set("test", "abc"); } }