Code Monkey home page Code Monkey logo

grasspictures's People

Contributors

hejinding-aipiao avatar whitrayhb avatar xiaym-gh avatar yanji314 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

grasspictures's Issues

Performance issues

  1. HttpClient 未复用

OkHttpClient client = new OkHttpClient.Builder().connectTimeout(3, TimeUnit.SECONDS).readTimeout(10, TimeUnit.SECONDS).build();

OkHttpClient client = new OkHttpClient.Builder().connectTimeout(3, TimeUnit.SECONDS).readTimeout(10, TimeUnit.SECONDS).build();

OkHttpClient client = new OkHttpClient.Builder().connectTimeout(3, TimeUnit.SECONDS).callTimeout(10, TimeUnit.SECONDS).build();

OkHttpClient client = new OkHttpClient.Builder().connectTimeout(3, TimeUnit.SECONDS).readTimeout(10, TimeUnit.SECONDS).build();


  1. 应该使用 JvmPlugin.getDataFolder() 而不是直接硬编码绝对路径, 以及变量名命名不规范

File file = new File("./data/cn.whitrayhb.grasspics/cache/grasspic/");

and more...

File directory = new File(INSTANCE.getDataFolder(), "cache/grasspic/");
// .....


File savedImage = new File(directory, id);
Files.copy(/**/, savedImage.toPath());

return savedImage;

  1. 未使用线程安全的集合类型

public static final PostGrassPic INSTANCE = new PostGrassPic();
private static final ArrayList<User> nextAreYou = new ArrayList<>();
private static final HashMap<User, Thread> listeningThreads = new HashMap<>();

mirai 是多线程模型, 需要考虑并发执行的情况


其他建议:

  • 可以考虑使用线程池而不是到处 new Thread
  • 不建议使用 Thread.stop 而是使用 中断 Thread.interrupt

并发:

Listener<GroupMessageEvent> listener = GlobalEventChannel.INSTANCE.subscribeAlways(GroupMessageEvent.class, m -> {
if (!nextAreYou.contains(m.getSender())) return;
SingleMessage message = m.getMessage().stream().filter(msg -> msg instanceof Image).findFirst().orElse(null);

if (listeningThreads.containsKey(user)) {
listeningThreads.get(user).interrupt();
listeningThreads.remove(user);
}

if (nextAreYou.remove(m.getSender().getId()) == null) return;

private static final ArrayList<User> nextAreYou = new ArrayList<>();

指的是 <User> 泛型: see mamoe/mirai#585


public static String fetchJson(String inURL) {
try {
OkHttpClient client = new OkHttpClient.Builder().connectTimeout(3, TimeUnit.SECONDS).callTimeout(10, TimeUnit.SECONDS).build();
Request request = new Request.Builder().url(inURL).get().build();
Response res = client.newCall(request).execute();
if (res.code() != 200) {
GrasspicsMain.INSTANCE.getLogger().error("JSON下载失败!状态码为" + res.code());
return null;
}
if (res.body() == null) {
GrasspicsMain.INSTANCE.getLogger().error("Unexpected null body.");
return null;
}
return res.body().string();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}

如果最后都要检查是不是 null, 我建议不如干脆直接抛出一个 RuntimeException


public class Cooler {
private static final ConcurrentHashSet<Long> set = new ConcurrentHashSet<>();
public static void lock(CommandSender sender, int second) {
if (sender instanceof ConsoleCommandSender) {
sender.sendMessage("请勿在控制台中使用该命令");
return;
} else {
set.add(Objects.requireNonNull(sender.getUser()).getId());
}
Thread unlockThread = new Thread(() -> {
try {
Thread.sleep(second * 1000L);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
unlock(sender);
});
unlockThread.start();
}
public static void unlock(CommandSender sender) {
set.remove(Objects.requireNonNull(sender.getUser()).getId());
}
public static boolean isLocked(CommandSender sender) {
if (sender instanceof ConsoleCommandSender) return false;
return set.contains(Objects.requireNonNull(sender.getUser()).getId());
}
}

通用的实现方法是创建一个 Map</*id*/ Long, /* timestamp */ Long>

然后 lock 方法直接 put(id, System.currentTimeMillis())

isLocked(long id) {
Long value = map.get(id);
if (value == null) return false;
return System.currentTimeMills() - value <= 1000L;
}

当然我建议使用 guavaCache 指定过期时间, 实现起来更加简单, 并且解决了内存释放的问题

草图服务失效,获取草图时返回“您指定的图片不存在!”,投稿草图时报错

重启过,问题没有解决。


如题。
具体情况如图所示:
IMG_20230430_133308

后台输出显示:(个人信息已作处理)

2023-04-30 13:32:57 V/Bot.xxxxxxxxxx: [Bot(xxxxxxxxxx)] 秋水(xxxxxxxxxx) -> 生草
2023-04-30 13:32:59 V/Bot.xxxxxxxxxx: Group(xxxxxxxxxx) <- [mirai:quote:[mirai:source:ids=[100926], internalIds=[370393661], from group xxxxxxxxxx to xxxxxxxxxx at 1682832777], content=生草]您指定的图片不存在!

并没有“图片下载失败”之类的报错

经过咨询相关人员后得知,机器人并未被ban或者被限流

同时机器人的草图投稿功能也出现了问题,如图所示:
IMG_20230430_134036

控制台输出:

2023-04-30 13:41:26 W/stderr: org.json.JSONException: Expected a ',' or '}' at 11 [character 12 line 1]
2023-04-30 13:41:26 W/stderr:   at GrassPictures-1.2.0.mirai2.jar[private]//org.json.JSONTokener.syntaxError(JSONTokener.java:501)
2023-04-30 13:41:26 W/stderr:   at GrassPictures-1.2.0.mirai2.jar[private]//org.json.JSONObject.<init>(JSONObject.java:264)
2023-04-30 13:41:26 W/stderr:   at GrassPictures-1.2.0.mirai2.jar[private]//org.json.JSONObject.<init>(JSONObject.java:404)
2023-04-30 13:41:26 W/stderr:   at GrassPictures-1.2.0.mirai2.jar//cn.whitrayhb.grasspics.commands.PostGrassPic.lambda$postToPublicChannel$1(PostGrassPic.java:92)
2023-04-30 13:41:26 W/stderr:   at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
2023-04-30 13:41:26 W/stderr:   at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
2023-04-30 13:41:26 W/stderr:   at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
2023-04-30 13:41:26 W/stderr:   at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
2023-04-30 13:41:26 W/stderr:   at java.base/java.lang.Thread.run(Thread.java:833)

投稿报错

2023-02-11 10:17:19 W/草图插件: Exception in executing command [mirai:source:ids=[164576], internalIds=[-331462555], from group 3291584316 to 182850795 at 1676081839][mirai:quote:[mirai:source:ids=[164574], internalIds=[294937614], from 3466938657 to 182850795 at 1676081805], content=<not yet initialized>] 草图投稿
java.lang.IllegalArgumentException: message is empty
at net.mamoe.mirai.internal.contact.AbstractUserKt.sendMessageImpl(AbstractUser.kt:258)
at net.mamoe.mirai.internal.contact.CommonGroupImpl.sendMessage$suspendImpl(GroupImpl.kt:219)
at net.mamoe.mirai.internal.contact.CommonGroupImpl.sendMessage(GroupImpl.kt)
at net.mamoe.mirai.console.command.MemberCommandSender.sendMessage$suspendImpl(CommandSender.kt:687)
at net.mamoe.mirai.console.command.MemberCommandSender.sendMessage(CommandSender.kt)
at net.mamoe.mirai.console.command.MemberCommandSender$sendMessage$4.invoke(CommandSender.kt)
at net.mamoe.mirai.console.command.MemberCommandSender$sendMessage$4.invoke(CommandSender.kt)
at kotlin.coroutines.intrinsics.IntrinsicsKt__IntrinsicsJvmKt$createCoroutineUnintercepted$$inlined$createCoroutineFromSuspendFunction$IntrinsicsKt__IntrinsicsJvmKt$1.invokeSuspend(IntrinsicsJvm.kt:205)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlin.coroutines.ContinuationKt.startCoroutine(Continuation.kt:115)
at me.him188.kotlin.jvm.blocking.bridge.internal.RunSuspendKt.$runSuspend$(RunSuspend.kt:18)
at net.mamoe.mirai.console.command.MemberCommandSender.sendMessage(CommandSender.kt)
at GrassPictures-1.1.9.mirai2.jar//cn.whitrayhb.grasspics.commands.PostGrassPic.onCommand(PostGrassPic.java:209)
at net.mamoe.mirai.console.command.java.JRawCommand$overloads$1$invokeSuspend$$inlined$runBIO$1.invoke(CoroutineUtils.kt:23)
at kotlinx.coroutines.InterruptibleKt.runInterruptibleInExpectedContext(Interruptible.kt:51)
at kotlinx.coroutines.InterruptibleKt.access$runInterruptibleInExpectedContext(Interruptible.kt:1)
at kotlinx.coroutines.InterruptibleKt$runInterruptible$2.invokeSuspend(Interruptible.kt:43)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at kotlinx.coroutines.internal.LimitedDispatcher.run(LimitedDispatcher.kt:42)
at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:95)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.