├── gradle.properties ├── settings.gradle.kts ├── src └── main │ ├── resources │ └── META-INF │ │ └── services │ │ └── net.mamoe.mirai.console.plugin.jvm.JvmPlugin │ └── java │ └── com │ └── samcream │ ├── Test.java │ ├── reception │ ├── ReceptionIllustrative.java │ ├── Reception.java │ ├── MessageHandler.java │ └── ReceptionHandler.java │ ├── qqRobot.java │ └── EventList.java ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── README.md ├── .gitignore ├── gradlew.bat ├── gradlew └── LICENSE /gradle.properties: -------------------------------------------------------------------------------- 1 | kotlin.code.style=official -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "qqRobot" -------------------------------------------------------------------------------- /src/main/resources/META-INF/services/net.mamoe.mirai.console.plugin.jvm.JvmPlugin: -------------------------------------------------------------------------------- 1 | com.samcream.qqRobot -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Samera2022/TutorialRobot/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.8-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Tutorial QQ Robot ![](https://img.shields.io/badge/license-Apache-blue) 2 | This is a QQ Robot Plugin based on Mirai Console Loader! 3 | # Authors 4 | @Samera2022 5 | # Contact 6 | QQ Group Number: 865907066 7 | # Future Plan 8 | 增加线上玩家等待厅来实现跨群等待联机,借助新数据类型Requester来完成。其中应包含“申请者QQ名,申请者所在群,申请者游戏名,联机内容,申请时间”。 -------------------------------------------------------------------------------- /src/main/java/com/samcream/Test.java: -------------------------------------------------------------------------------- 1 | package com.samcream; 2 | 3 | public class Test { 4 | public static void main(String[] args){ 5 | String t = "sss"; 6 | System.out.println(t.length()); 7 | } 8 | } 9 | class Tester{ 10 | private int num; 11 | private String arg; 12 | public Tester(int num,String arg){ 13 | this.num = num; 14 | this.arg = arg; 15 | } 16 | public int getNum() { 17 | return num; 18 | } 19 | public String getArg() { 20 | return arg; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/samcream/reception/ReceptionIllustrative.java: -------------------------------------------------------------------------------- 1 | package com.samcream.reception; 2 | 3 | import net.mamoe.mirai.message.data.MessageChainBuilder; 4 | 5 | 6 | public class ReceptionIllustrative extends Reception{ 7 | private String[] requireWords; 8 | private int repeatTimes; 9 | private MessageChainBuilder reply; 10 | private int receptionType; 11 | public ReceptionIllustrative(String[] requireWords, int repeatTimes, MessageChainBuilder reply, int receptionType) { 12 | super(requireWords, repeatTimes, reply); 13 | this.requireWords = requireWords; 14 | this.repeatTimes = repeatTimes; 15 | this.reply = reply; 16 | this.receptionType = receptionType; 17 | } 18 | public int getReceptionType() { 19 | return receptionType; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/samcream/reception/Reception.java: -------------------------------------------------------------------------------- 1 | package com.samcream.reception; 2 | 3 | import net.mamoe.mirai.message.data.MessageChainBuilder; 4 | 5 | 6 | public class Reception { 7 | public static final int MESSAGE_DEFAULT = -1; 8 | public static final int MESSAGE_MUST_INCLUDE = 1; 9 | public static final int MESSAGE_WHAT = 2; 10 | public static final int MESSAGE_ERROR = 3; 11 | public static final int MESSAGE_HOW = 4; 12 | public static final int MESSAGE_ELSE = 5; 13 | //此处requireWords指必须全部包含的词 14 | private String[] requireWords; 15 | private int repeatTimes; 16 | private MessageChainBuilder reply; 17 | public Reception(String[] requireWords, int repeatTimes, MessageChainBuilder reply){ 18 | this.requireWords = requireWords; 19 | this.repeatTimes = repeatTimes; 20 | this.reply = reply; 21 | } 22 | public String[] getRequireWords() { 23 | return requireWords; 24 | } 25 | 26 | public int getRepeatTimes() { 27 | return repeatTimes; 28 | } 29 | 30 | public MessageChainBuilder getReply(){ 31 | return reply; 32 | } 33 | } -------------------------------------------------------------------------------- /src/main/java/com/samcream/qqRobot.java: -------------------------------------------------------------------------------- 1 | package com.samcream; 2 | 3 | import com.samcream.reception.ReceptionHandler; 4 | import net.mamoe.mirai.console.plugin.jvm.JavaPlugin; 5 | import net.mamoe.mirai.console.plugin.jvm.JvmPluginDescriptionBuilder; 6 | import net.mamoe.mirai.event.Event; 7 | import net.mamoe.mirai.event.EventChannel; 8 | import net.mamoe.mirai.event.GlobalEventChannel; 9 | import net.mamoe.mirai.event.ListenerHost; 10 | import net.mamoe.mirai.event.events.BotEvent; 11 | 12 | public final class qqRobot extends JavaPlugin { 13 | private static final long DEVELOPER_ID = 572360179L; 14 | private static final long BOT_ID = 2328790565L; 15 | public static long START_TIME; 16 | //private static final long BOT_ID = 2328790565L; 17 | 18 | public static final qqRobot INSTANCE = new qqRobot(); 19 | 20 | private qqRobot() { 21 | super((new JvmPluginDescriptionBuilder("com.samcream.qqRobot", "1.0.0")) 22 | .name("QQ Robot") 23 | .info("Just a robot") 24 | .author("_S_A_M") 25 | .build()); 26 | } 27 | 28 | public void onEnable() { 29 | getLogger().info("Plugin qqRobot loaded!"); 30 | START_TIME = System.currentTimeMillis(); 31 | EventChannel eventChannel = GlobalEventChannel.INSTANCE.filter(ev -> Boolean.valueOf((ev instanceof BotEvent && ((BotEvent)ev).getBot().getId() == BOT_ID))); 32 | eventChannel.registerListenerHost((ListenerHost)new EventList()); 33 | ReceptionHandler.init(); 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # User-specific stuff 2 | .idea/ 3 | 4 | *.iml 5 | *.ipr 6 | *.iws 7 | 8 | # IntelliJ 9 | out/ 10 | # mpeltonen/sbt-idea plugin 11 | .idea_modules/ 12 | 13 | # JIRA plugin 14 | atlassian-ide-plugin.xml 15 | 16 | # Compiled class file 17 | *.class 18 | 19 | # Log file 20 | *.log 21 | 22 | # BlueJ files 23 | *.ctxt 24 | 25 | # Package Files # 26 | *.jar 27 | *.war 28 | *.nar 29 | *.ear 30 | *.zip 31 | *.tar.gz 32 | *.rar 33 | 34 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 35 | hs_err_pid* 36 | 37 | *~ 38 | 39 | # temporary files which can be created if a process still has a handle open of a deleted file 40 | .fuse_hidden* 41 | 42 | # KDE directory preferences 43 | .directory 44 | 45 | # Linux trash folder which might appear on any partition or disk 46 | .Trash-* 47 | 48 | # .nfs files are created when an open file is removed but is still being accessed 49 | .nfs* 50 | 51 | # General 52 | .DS_Store 53 | .AppleDouble 54 | .LSOverride 55 | 56 | # Icon must end with two \r 57 | Icon 58 | 59 | # Thumbnails 60 | ._* 61 | 62 | # Files that might appear in the root of a volume 63 | .DocumentRevisions-V100 64 | .fseventsd 65 | .Spotlight-V100 66 | .TemporaryItems 67 | .Trashes 68 | .VolumeIcon.icns 69 | .com.apple.timemachine.donotpresent 70 | 71 | # Directories potentially created on remote AFP share 72 | .AppleDB 73 | .AppleDesktop 74 | Network Trash Folder 75 | Temporary Items 76 | .apdisk 77 | 78 | # Windows thumbnail cache files 79 | Thumbs.db 80 | Thumbs.db:encryptable 81 | ehthumbs.db 82 | ehthumbs_vista.db 83 | 84 | # Dump file 85 | *.stackdump 86 | 87 | # Folder config file 88 | [Dd]esktop.ini 89 | 90 | # Recycle Bin used on file shares 91 | $RECYCLE.BIN/ 92 | 93 | # Windows Installer files 94 | *.cab 95 | *.msi 96 | *.msix 97 | *.msm 98 | *.msp 99 | 100 | # Windows shortcuts 101 | *.lnk 102 | 103 | .gradle 104 | build/ 105 | 106 | # Ignore Gradle GUI config 107 | gradle-app.setting 108 | 109 | # Cache of project 110 | .gradletasknamecache 111 | 112 | **/build/ 113 | 114 | # Common working directory 115 | run/ 116 | 117 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) 118 | !gradle-wrapper.jar 119 | 120 | 121 | # Local Test Launch point 122 | src/test/kotlin/RunTerminal.kt 123 | 124 | # Mirai console files with direct bootstrap 125 | /config 126 | /data 127 | /plugins 128 | /bots 129 | 130 | # Local Test Launch Point working directory 131 | /debug-sandbox 132 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /src/main/java/com/samcream/reception/MessageHandler.java: -------------------------------------------------------------------------------- 1 | package com.samcream.reception; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | 5 | import java.util.ArrayList; 6 | 7 | import static com.samcream.reception.Reception.*; 8 | import static com.samcream.reception.ReceptionHandler.*; 9 | 10 | public class MessageHandler { 11 | private static String REPLY = null; 12 | private static final String[] WHAT = new String[]{"什么","啥"}; 13 | private static final String[] HOW_BY_ASKING = new String[]{"怎么","如何","如果","怎样","咋"}; 14 | private static final String[] HOW_TO_DO = new String[]{"下载","导入","开房","联机","解决","启动","设置","办","整","弄","搞","装","安","进","加","下"}; 15 | private static final String[] ERROR = new String[]{"报错","错误","异常","崩溃"}; 16 | public static String getReply(String message) { 17 | int messageType = MESSAGE_DEFAULT; 18 | boolean isRequireAll = false; 19 | for (Reception reception : ONLY_REQUIRE_ALL) { 20 | for (String requireWord : reception.getRequireWords()) { 21 | if (requireWord.equals(message)) { 22 | messageType = MESSAGE_MUST_INCLUDE; 23 | REPLY = reception.getReply().asMessageChain().contentToString(); 24 | isRequireAll = true; 25 | break; 26 | } 27 | } 28 | } 29 | if (!isRequireAll) { 30 | if ((repeatTimes(message, WHAT) >= 1) && contain(message, "是")) { 31 | messageType = MESSAGE_WHAT; 32 | } else if ((repeatTimes(message, HOW_BY_ASKING) >= 1) && (repeatTimes(message, HOW_TO_DO) >= 1)) { 33 | if (repeatTimes(message, ERROR) >= 1) { 34 | messageType = MESSAGE_ERROR; 35 | } else { 36 | messageType = MESSAGE_HOW; 37 | } 38 | } else if (loop(MESSAGE_ELSE, message) != null) { 39 | messageType = MESSAGE_ELSE; 40 | } 41 | } 42 | String finalReturn = null; 43 | if (REPLY == null) { 44 | finalReturn = loop(messageType, message); 45 | } 46 | else { 47 | finalReturn = REPLY; 48 | REPLY = null; 49 | } 50 | return finalReturn; 51 | } 52 | private static String loop(int num, String message){ 53 | String replyText = null; 54 | ArrayList RI = null; 55 | switch (num){ 56 | case MESSAGE_DEFAULT: 57 | break; 58 | case MESSAGE_WHAT: 59 | RI = ILLUSTRATOR_WHAT; 60 | break; 61 | case MESSAGE_ERROR: 62 | RI = ILLUSTRATOR_ERROR; 63 | break; 64 | case MESSAGE_HOW: 65 | RI = ILLUSTRATOR_HOW; 66 | break; 67 | case MESSAGE_ELSE: 68 | RI = ILLUSTRATOR_ELSE; 69 | } 70 | if (RI!=null) { 71 | for (ReceptionIllustrative illustrator : RI) { 72 | if (repeatTimes(message, illustrator.getRequireWords())>=illustrator.getRepeatTimes()) { 73 | replyText = illustrator.getReply().asMessageChain().contentToString(); 74 | break; 75 | } 76 | } 77 | } 78 | return replyText; 79 | } 80 | private static boolean contain(@NotNull String string1, String string2) { 81 | //string2在string1中 82 | int code = string1.indexOf(string2); 83 | return (code != -1); 84 | } 85 | 86 | private static int repeatTimes(String string1, @NotNull String[] strings2) { 87 | //string1中出现过多少次strings2中的内容 88 | //注意:strings2中的一个内容如果在string1中出现多次不会重复计数 89 | int i = 0; 90 | int repeat = 0; 91 | while (i < strings2.length) { 92 | String content = strings2[i]; 93 | if (contain(string1, content)) { 94 | repeat++; 95 | } else if (i == strings2.length - 1) { 96 | break; 97 | } 98 | i++; 99 | } 100 | return repeat; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/main/java/com/samcream/EventList.java: -------------------------------------------------------------------------------- 1 | package com.samcream; 2 | 3 | import com.samcream.reception.MessageHandler; 4 | import kotlin.coroutines.CoroutineContext; 5 | import net.mamoe.mirai.contact.Contact; 6 | import net.mamoe.mirai.event.EventHandler; 7 | import net.mamoe.mirai.event.SimpleListenerHost; 8 | import net.mamoe.mirai.event.events.*; 9 | import org.jetbrains.annotations.NotNull; 10 | 11 | import java.util.Calendar; 12 | 13 | public class EventList extends SimpleListenerHost { 14 | 15 | public void handleException(@NotNull CoroutineContext context, @NotNull Throwable exception) {} 16 | 17 | @EventHandler 18 | public void MemberJoin(@NotNull MemberJoinEvent event) { 19 | String name = event.getMember().getNick(); 20 | event.getGroup().sendMessage("欢迎"+ name + "加群啦~\n" + 21 | "主群865907066 主要提供基础的视频教程与文本教程\n" + 22 | "1群955061228 主要提供插件开发教程与Mirai设置\n" + 23 | "2群829314911 主要提供模组开发教程与ServerSync设置\n" + 24 | "3群565669662 主要用于沟通与交流(大白话就是闲聊群啦)\n" + 25 | "群频道https://qun.qq.com/qqweb/qunpro/share?_wv=3&_wwv=128&appChannel=share&inviteCode=1W5F6Nm&appChannel=share&businessType=9&from=246610&biz=ka" + 26 | "如果觉得群不错的话可以推荐给朋友哦OvO!\n" + 27 | "在聊天框输入(菜单)可以进入机器人的联机等待大厅哦"); 28 | } 29 | 30 | @EventHandler 31 | public void WelcomeTest(GroupMessageEvent event){ 32 | if (event.getMessage().contentToString().equals("欢迎测试")){ 33 | event.getGroup().sendMessage("欢迎"+ event.getSender().getNick() + "加群啦~\n" + 34 | "主群865907066 主要提供基础的视频教程与文本教程\n" + 35 | "1群955061228 主要提供插件开发教程与Mirai设置\n" + 36 | "2群829314911 主要提供模组开发教程与ServerSync设置\n" + 37 | "3群565669662 主要用于沟通与交流(大白话就是闲聊群啦)\n" + 38 | "群频道https://qun.qq.com/qqweb/qunpro/share?_wv=3&_wwv=128&appChannel=share&inviteCode=1W5F6Nm&appChannel=share&businessType=9&from=246610&biz=ka\n" + 39 | "如果觉得群不错的话可以推荐给朋友哦OvO!\n" + 40 | "在聊天框输入(菜单)可以进入机器人的联机等待大厅哦"); 41 | } 42 | } 43 | 44 | @EventHandler 45 | public void onMessage(@NotNull GroupMessageEvent event) throws Exception { 46 | String reply = MessageHandler.getReply(event.getMessage().contentToString()); 47 | if (reply != null) { 48 | event.getGroup().sendMessage(reply); 49 | } 50 | } 51 | @EventHandler 52 | public void messageBreak(@NotNull GroupMessageEvent event){ 53 | if (event.getMessage().contentToString().equals("口令弹出")){ 54 | event.getGroup().sendMessage("收到中止指令!正在传递口令信息!"); 55 | long endTime = System.currentTimeMillis(); 56 | for (Contact contact : event.getBot().getGroups()){ 57 | contact.sendMessage("程序遭到中止!详细信息如下:\n"+ 58 | "中止口令: 「弹出」\n" + 59 | "中止发起群: 「"+event.getGroup().getName()+"("+event.getGroup().getId()+")"+"」\n" + 60 | "中止发起源: 「"+event.getSender().getNick()+"("+event.getSender().getId()+")"+"」\n" + 61 | "系统运行时间: "+timeTranslate(endTime-qqRobot.START_TIME)); 62 | } 63 | System.exit(0); 64 | } 65 | } 66 | @EventHandler 67 | public void STChange(MemberSpecialTitleChangeEvent event) { 68 | String reply; 69 | if (!event.getOrigin().equals("")){ 70 | reply = event.getMember().getNick() +"(" + event.getMember().getId() + ")" + "的头衔由“" + event.getOrigin() + "”变为了“" + event.getNew() + "”"; 71 | } 72 | else { 73 | reply = "恭喜" + event.getMember().getNick() +"(" + event.getMember().getId() + ")" + "获得了群主授予的头衔\"" + event.getNew() + "\""; 74 | } 75 | event.getGroup().sendMessage(reply); 76 | } 77 | 78 | private String timeTranslate(long time){ 79 | String reply = ""; 80 | //获得系统的时间,单位为毫秒,转换为秒 81 | long totalSeconds=time/1000; 82 | //求当前时间的秒 83 | long totalSecond=totalSeconds%60; 84 | //求当前时间的分 85 | long totalMinutes=totalSeconds/60; 86 | long totalMinute=totalMinutes%60; 87 | //求当前时间的时 88 | long totalHours=totalSeconds/3600; 89 | long totalHour=totalHours%24; 90 | if (totalHour!=0){ 91 | if (totalMinute!=0){ 92 | if (totalSecond!=0){ 93 | reply = totalHour+"时"+totalMinute+"分"+totalSecond+"秒"; 94 | } 95 | else { 96 | reply = totalHour+"时"+totalMinute+"分"; 97 | } 98 | } 99 | else { 100 | if (totalSecond!=0){ 101 | reply = totalHour+"时"+totalSecond+"秒"; 102 | } 103 | else { 104 | reply = totalHour+"时"; 105 | } 106 | } 107 | } 108 | else { 109 | if (totalMinute!=0){ 110 | if (totalSecond!=0){ 111 | reply = totalMinute+"分"+totalSecond+"秒"; 112 | } 113 | else { 114 | reply = totalMinute+"分"; 115 | } 116 | } 117 | else { 118 | if (totalSecond!=0){ 119 | reply = totalSecond+"秒"; 120 | } 121 | else { 122 | reply = ""; 123 | } 124 | } 125 | } 126 | return reply; 127 | } 128 | } -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | 86 | # Determine the Java command to use to start the JVM. 87 | if [ -n "$JAVA_HOME" ] ; then 88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 89 | # IBM's JDK on AIX uses strange locations for the executables 90 | JAVACMD="$JAVA_HOME/jre/sh/java" 91 | else 92 | JAVACMD="$JAVA_HOME/bin/java" 93 | fi 94 | if [ ! -x "$JAVACMD" ] ; then 95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 96 | 97 | Please set the JAVA_HOME variable in your environment to match the 98 | location of your Java installation." 99 | fi 100 | else 101 | JAVACMD="java" 102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 103 | 104 | Please set the JAVA_HOME variable in your environment to match the 105 | location of your Java installation." 106 | fi 107 | 108 | # Increase the maximum file descriptors if we can. 109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 110 | MAX_FD_LIMIT=`ulimit -H -n` 111 | if [ $? -eq 0 ] ; then 112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 113 | MAX_FD="$MAX_FD_LIMIT" 114 | fi 115 | ulimit -n $MAX_FD 116 | if [ $? -ne 0 ] ; then 117 | warn "Could not set maximum file descriptor limit: $MAX_FD" 118 | fi 119 | else 120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 121 | fi 122 | fi 123 | 124 | # For Darwin, add options to specify how the application appears in the dock 125 | if $darwin; then 126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 127 | fi 128 | 129 | # For Cygwin or MSYS, switch paths to Windows format before running java 130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 133 | 134 | JAVACMD=`cygpath --unix "$JAVACMD"` 135 | 136 | # We build the pattern for arguments to be converted via cygpath 137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 138 | SEP="" 139 | for dir in $ROOTDIRSRAW ; do 140 | ROOTDIRS="$ROOTDIRS$SEP$dir" 141 | SEP="|" 142 | done 143 | OURCYGPATTERN="(^($ROOTDIRS))" 144 | # Add a user-defined pattern to the cygpath arguments 145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 147 | fi 148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 149 | i=0 150 | for arg in "$@" ; do 151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 153 | 154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 156 | else 157 | eval `echo args$i`="\"$arg\"" 158 | fi 159 | i=`expr $i + 1` 160 | done 161 | case $i in 162 | 0) set -- ;; 163 | 1) set -- "$args0" ;; 164 | 2) set -- "$args0" "$args1" ;; 165 | 3) set -- "$args0" "$args1" "$args2" ;; 166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 172 | esac 173 | fi 174 | 175 | # Escape application args 176 | save () { 177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 178 | echo " " 179 | } 180 | APP_ARGS=`save "$@"` 181 | 182 | # Collect all arguments for the java command, following the shell quoting and substitution rules 183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 184 | 185 | exec "$JAVACMD" "$@" 186 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /src/main/java/com/samcream/reception/ReceptionHandler.java: -------------------------------------------------------------------------------- 1 | package com.samcream.reception; 2 | 3 | import net.mamoe.mirai.message.data.MessageChainBuilder; 4 | 5 | import java.util.ArrayList; 6 | 7 | import static com.samcream.reception.Reception.*; 8 | 9 | public class ReceptionHandler { 10 | public static ArrayList ONLY_REQUIRE_ALL = new ArrayList(); 11 | public static ArrayList ILLUSTRATOR_WHAT = new ArrayList(); 12 | public static ArrayList ILLUSTRATOR_HOW = new ArrayList(); 13 | public static ArrayList ILLUSTRATOR_ERROR = new ArrayList(); 14 | public static ArrayList ILLUSTRATOR_ELSE = new ArrayList(); 15 | 16 | public static void init() { 17 | ILLUSTRATOR_ELSE.add(new ReceptionIllustrative(new String[]{"测试口令"}, 1, new MessageChainBuilder().append("测试成功"),MESSAGE_ELSE)); 18 | ILLUSTRATOR_HOW.add(new ReceptionIllustrative(new String[]{"Java", "java"}, 1, new MessageChainBuilder() 19 | .append("群文件中的Java安装文件夹有哦~\n下载之后安装完就可以了。1.16.5及以下要用Java8,1.16.5以上要用Java17"), MESSAGE_HOW)); 20 | ILLUSTRATOR_ERROR.add(new ReceptionIllustrative(new String[]{"Java", "java"}, 1, new MessageChainBuilder() 21 | .append("Java安装还能出问题啊......\n试试下载群里面的离线安装包安装试试吧...再出问题我也不会了(/doge)"), MESSAGE_ERROR)); 22 | ILLUSTRATOR_HOW.add(new ReceptionIllustrative(new String[]{"游戏","启动"}, 2, new MessageChainBuilder() 23 | .append("先下载对应版本的Java,然后双击打开启动器。打开启动器之后找到安装版本的地方," + 24 | "选择好是否安装Forge Fabric Optifine LiteLoader之后点击安装就好了。安装完之后登录你的账户," + 25 | "选择对应启动的版本就好啦~\n" + 26 | "具体的操作详见群文件中Minecraft教程里的《我的世界教程广版》序章:开始游戏(启动游戏 P6)\n" + 27 | "或者也可以点击https://www.bilibili.com/read/cv12422013/?from=readlist直接查看教程"),MESSAGE_HOW)); 28 | ONLY_REQUIRE_ALL.add(new Reception(new String[]{"账户分类"}, 1, new MessageChainBuilder() 29 | .append("我的世界所有类型账户分类:\n1.微软账户(自微软收购MOJANG后开始使用的一种正版账户)\n2.Mojang账户(最开始的正版账户)\n" + 30 | "3.外置账户(也被称为皮肤站账户,是一种第三方账户)\n4.通行证账户(统一通行证账户,也是一种第三方账户)\n" + 31 | "5.离线账户(不联网都能用的账户,应该算是第三方账户吧)\n" + 32 | "查看哪些账户可以进哪些服务器请输入(账户查看)" + 33 | "具体账户间的区别详见群文件中Minecraft教程里的《我的世界教程广版》第一张:本地个性化设置(账户 P7)\n" + 34 | "或者也可以点击https://www.bilibili.com/read/cv12445111/?from=readlist直接查看教程"))); 35 | ONLY_REQUIRE_ALL.add(new Reception(new String[]{"账户查看"}, 1, new MessageChainBuilder() 36 | .append("准确地说,服务器有下述方法来限制账户。\n" + 37 | "1.开启正版认证(只允许正版玩家进入)\n" + 38 | "2.开启白名单认证(只允许所有玩家中的白名单玩家进入)\n" + 39 | "3.开启皮肤站认证(只有指定皮肤站的玩家可以进入)\n" + 40 | "4.开启统一通行证认证(只有统一通行证玩家可以进入)\n" + 41 | "5.其他认证方式(属于自定义服务器核心,详情询问服主)\n" + 42 | "特别注意!\n" + 43 | "如果你是选择加入房间的话,需要使用外置或正版!如果房主是外置的话那么你可以使用外置或正版," + 44 | "如果房主是正版的话你只能使用正版加入!"))); 45 | ILLUSTRATOR_WHAT.add(new ReceptionIllustrative(new String[]{"微软账户","Microsoft账户"}, 1, new MessageChainBuilder() 46 | .append("微软账户应该算是占比比较大的一种账户类型了,它在微软收购Mojang之后出现。并且还在一段时间要求Mojang账户迁移到微软账户," + 47 | "但之后不了了之了。\n它属于正版账户,但是登陆方式异于Mojang账户。它需要在启动器(旧版启动器并不支持微软登录)或其他地方中打开一个Microsoft的界面,验证完账户密码才可以," + 48 | "有时候还会要求验证邮箱或输入验证代码。\n请注意区分微软我的世界账户和微软商店我的世界账户的区别!前者是Java版我的世界的账户,后者为基岩版我的世界的账户\n" + 49 | "它可以在我的世界Mojang官网购买,并且从2022年之后所有在我的世界Mojang官网购买的账户都是微软账户。\n"+ 50 | "具体的分类详见群文件中Minecraft教程里的《我的世界教程广版》第一章:本地个性化设置(账户 P7)\n" + 51 | "或者也可以点击https://www.bilibili.com/read/cv12445111/?from=readlist直接查看教程\n" + 52 | "查看具体分类请输入(账户分类)"),MESSAGE_WHAT)); 53 | ILLUSTRATOR_WHAT.add(new ReceptionIllustrative(new String[]{"Mojang账户"}, 1, new MessageChainBuilder() 54 | .append("Mojang账户其实是最早的正版账户,但是在微软收购Mojang后被要求迁移到微软账户了(但是至少到现在还没有对未转移的用户做出什么限制)\n" + 55 | "它可以在旧的任何启动器上登录,但似乎新的启动器不再支持这一古老的账户了。只需要在启动器中输入账户和密码就可以了。" + 56 | "它现在已经无法在官网上被购买,但是还可以在各个启动器上登录。\n" + 57 | "具体的分类详见群文件中Minecraft教程里的《我的世界教程广版》第一章:本地个性化设置(账户 P7)\n" + 58 | "或者也可以点击https://www.bilibili.com/read/cv12445111/?from=readlist直接查看教程\n" + 59 | "查看具体分类请输入(账户分类)"),MESSAGE_WHAT)); 60 | ILLUSTRATOR_WHAT.add(new ReceptionIllustrative(new String[]{"皮肤站账户","外置账户","外置"}, 1, new MessageChainBuilder() 61 | .append("外置账户其实也可以被称之为皮肤站账户,是独立于正版(MOJANG和MICROSOFT)账户和离线账户,通行证账户" + 62 | "之外的一种账户。它可以从网上搜索到注册的方法,这边推荐LittleSkin和BlessingSkin。\n" + 63 | "具体的分类详见群文件中Minecraft教程里的《我的世界教程广版》第一章:本地个性化设置(账户 P7)\n" + 64 | "或者也可以点击https://www.bilibili.com/read/cv12445111/?from=readlist直接查看教程\n" + 65 | "查看具体分类请输入(账户分类)"),MESSAGE_WHAT)); 66 | ILLUSTRATOR_WHAT.add(new ReceptionIllustrative(new String[]{"通行证账户"}, 1, new MessageChainBuilder() 67 | .append("通行证账户很少见,它起源于一个名为统一通行证的计划。以下文本节自统一通行证官网↓" + 68 | "无需在游戏中输入/login,可直接在启动器登录,支持Spigot、PaperSpigot、TacoSpigot、Thermos、(K)Cauldron、(K)Bungeecord群组、SpongeVanilla、Torch、" + 69 | "纯Forge、CraftBukkit、官方服务器等所有服务端、客户端,防压测、防假人,一个账号通行所有服务器,无需重复注册,不存在游戏ID冲突的情况。" + 70 | "\n选自https://login2.nide8.com:233/account/login\n" + 71 | "具体的分类详见群文件中Minecraft教程里的《我的世界教程广版》第一章:本地个性化设置(账户 P7)\n"+ 72 | "或者也可以点击https://www.bilibili.com/read/cv12445111/?from=readlist直接查看教程\n"+ 73 | "查看具体分类请输入(账户分类)"),MESSAGE_WHAT)); 74 | ILLUSTRATOR_WHAT.add(new ReceptionIllustrative(new String[]{"离线账户"}, 1, new MessageChainBuilder() 75 | .append("离线账户其实可以不联网也能用。这玩意没啥特殊得功能,也没啥特殊得注册方法。启动器上输入名字就结了。\n" + 76 | "具体的分类详见群文件中Minecraft教程里的《我的世界教程广版》第一章:本地个性化设置(账户 P7)\n" + 77 | "或者也可以点击https://www.bilibili.com/read/cv12445111/?from=readlist直接查看教程\n" + 78 | "查看具体分类请输入(账户分类)"),MESSAGE_WHAT)); 79 | ILLUSTRATOR_WHAT.add(new ReceptionIllustrative(new String[]{"正版账户","正版"}, 1, new MessageChainBuilder() 80 | .append("其实微软账户和Mojang账户都属于正版账户,分别查询他俩试试啦~"),MESSAGE_WHAT)); 81 | ILLUSTRATOR_WHAT.add(new ReceptionIllustrative(new String[]{"材质包","资源包","数据包","resource-pack","data-pack"}, 1, new MessageChainBuilder() 82 | .append("资源包一般都是zip格式的压缩文件。在游戏的菜单(指在服务器或存档中按esc调出的页面)或主页面中选择设置便能看到资源包设置。" + 83 | "把你获得的压缩文件放进游戏目录中(指.minecraft/version/xxx/resource-packs版本隔离启动器)" + 84 | "(若为非版本隔离启动器则在游戏中资源包设置中选择打开资源包文件夹)" + 85 | ",之后将鼠标(光标)移动到那个资源包" + 86 | "的图片上,等看到一个向左的箭头后点击那个向左的箭头,按完成就好了。可能会卡一会,但很快就会好。\n" + 87 | "具体的关系详见群文件中Minecraft教程里的《我的世界教程广版》第一章:本地个性化设置(材质包 P9)\n" + 88 | "或者也可以点击https://www.bilibili.com/read/cv12445329/?from=readlist直接查看教程"),MESSAGE_WHAT)); 89 | ILLUSTRATOR_WHAT.add(new ReceptionIllustrative(new String[]{"模组","mod"}, 1, new MessageChainBuilder() 90 | .append("mod是我的世界极其重要的一个组成部分。甚至可以说,没有模组就没有MC的今日。模组主要分为三大类:" + 91 | "Forge Fabric和LiteLoader。这三类分别对应三类模组加载器啦~" + 92 | "具体的关系详见群文件中Minecraft教程里的《我的世界教程广版》第一章:本地个性化设置(模组 P10)\n" + 93 | "或者也可以点击https://www.bilibili.com/read/cv12445943/?from=readlist直接查看教程\n" + 94 | "查看具体分类请输入(模组加载器分类)"),MESSAGE_WHAT)); 95 | ILLUSTRATOR_ELSE.add(new ReceptionIllustrative(new String[]{"模组","加载器","分类"}, 3, new MessageChainBuilder() 96 | .append("我的世界所有类型模组加载器分类:\n1.Forge(最老牌的模组加载器,模组以jar和zip结尾)\n2.Fabric(新兴模组加载器,模组以jar结尾)\n" + 97 | "3.LiteLoader(轻型模组加载器,模组以litemod结尾)\n" + 98 | "注意事项1:Optifine不是模组加载器!它和Iris都是光影加载器!\n" + 99 | "注意事项2:在1.12.2以上,Forge和Fabric不再兼容。这意味着不论你使用什么方法都不能在1.12.2以上同时安装Forge和" + 100 | "Fabric!\n" + 101 | "注意事项3:Optifine可以以模组或外置加载器的方式安装在Forge和Fabric中。\n" + 102 | "具体的关系详见群文件中Minecraft教程里的《我的世界教程广版》第一章:本地个性化设置(模组 P10)\n" + 103 | "或者也可以点击https://www.bilibili.com/read/cv12445943/?from=readlist直接查看教程"),MESSAGE_ELSE)); 104 | ILLUSTRATOR_HOW.add(new ReceptionIllustrative(new String[]{"模组","mod"}, 1, new MessageChainBuilder() 105 | .append("模组安装.......(真的有人会考虑在机器人中设置模组安装这个回答吗?)\n" + 106 | "建议去看群文件中Minecraft教程里的《我的世界教程广版》第一章:本地个性化设置(模组 P10)\n" + 107 | "或者也可以点击https://www.bilibili.com/read/cv12445943/?from=readlist直接查看教程"),MESSAGE_HOW)); 108 | ILLUSTRATOR_WHAT.add(new ReceptionIllustrative(new String[]{"光影"}, 1, new MessageChainBuilder() 109 | .append("光影是一种显著提升游戏画质的方法,但是还是建议参照自己电脑的配置酌情使用" + 110 | "(显卡烧了就不好玩了)\n目前已知的光影加载器有Optifine和Iris(光影加载器在某种意义上也可以优化游戏的):\n" + 111 | "Optifine(支持绝大多数版本,且同时支持Fabric和Forge)\n" + 112 | "Iris(仅支持高版本,且只支持Fabric,优化效果明显)"),MESSAGE_WHAT)); 113 | ILLUSTRATOR_HOW.add(new ReceptionIllustrative(new String[]{"光影"}, 1, new MessageChainBuilder() 114 | .append("光影一般都是zip格式的文件。在安装光影加载器后(不知道光影加载器可以发(光影是什么))" + 115 | "可以在游戏的菜单(指在服务器或存档中按esc调出的页面)或主页面中选择设置->视频设置->光影。打开这个界面之后就可以" + 116 | "点击左下角打开光影包文件夹,把你的光影放进去。之后点击完成,再进去一次就能在列表里找到你放的光影的名字啦~\n" + 117 | "点击你放的光影的名字,再点完成。可能会卡一会,但很快就会好。\n" + 118 | "建议去看群文件中Minecraft教程里的《我的世界教程广版》第一章:本地个性化设置(光影 P14)\n" + 119 | "或者也可以点击https://www.bilibili.com/read/cv12450055/?from=readlist直接查看教程"),MESSAGE_HOW)); 120 | ILLUSTRATOR_WHAT.add(new ReceptionIllustrative(new String[]{"地图","存档"}, 1, new MessageChainBuilder() 121 | .append("地图一般指存档(save),是我的世界的一个重要组成部分。它可以在不同的启动器和客户端服务端中使用,但要求版本和模组必须一致。" + 122 | "否则会出现缺失元素的提示。"),MESSAGE_WHAT)); 123 | ILLUSTRATOR_HOW.add(new ReceptionIllustrative(new String[]{"地图","存档"}, 1, new MessageChainBuilder() 124 | .append("地图一般都是以文件夹的形式出现的。如果你拿到的是压缩包格式,请尝试把他解压(如果里面只有一个文件夹的话)。" + 125 | "把你获得的文件夹放进游戏目录中(指.minecraft/version/xxx/saves版本隔离启动器)" + 126 | "(若为非版本隔离启动器,请参照各大启动器的设置)\n"+ 127 | "在完成上述操作后再打开游戏,进入单人游戏就可以看到了。\n" + 128 | "建议去看群文件中Minecraft教程里的《我的世界教程广版》第一章:本地个性化设置(存档 P15)\n" + 129 | "或者也可以点击https://www.bilibili.com/read/cv12882303/?from=readlist直接查看教程"),MESSAGE_HOW)); 130 | ILLUSTRATOR_HOW.add(new ReceptionIllustrative(new String[]{"联机"}, 1, new MessageChainBuilder() 131 | .append("目前的联机方式有很多方式,按照通信方式的话可以划分为公网ip联机,内网穿透联机,启动器所支持的联机。\n" + 132 | "按照服务端的类型还可以分为服务器联机和共享存档(即开房)联机。\n" + 133 | "注意:ipv6联机方法在亘古之前被认为是不可以的,现在尚不确定。\n" + 134 | "建议去看群文件中Minecraft教程里的《我的世界教程广版》第二章:联机 P16\n" + 135 | "或者也可以点击https://www.bilibili.com/read/cv12498928/?from=readlist直接查看教程\n" + 136 | "问我这些联机方式如何进行的话,可以问我(咋开房联机?咋开服?)"),MESSAGE_HOW)); 137 | ILLUSTRATOR_HOW.add(new ReceptionIllustrative(new String[]{"穿透","映射"}, 1, new MessageChainBuilder() 138 | .append("(真的有人会把这么长的映射放到一句回答里面吗?)\n" + 139 | "建议去看群文件中Minecraft教程里的《我的世界教程广版》第二章:联机 (映射 P16)\n" + 140 | "或者也可以点击https://www.bilibili.com/read/cv12518757/?from=readlist直接查看教程"),MESSAGE_HOW)); 141 | ILLUSTRATOR_HOW.add(new ReceptionIllustrative(new String[]{"开","房"}, 1, new MessageChainBuilder() 142 | .append("在完成《映射》章节之后,可以在游戏的菜单(指在存档中按esc调出的页面)->开放到局域网。\n" + 143 | "这时候就可以发现游戏的左下角文本栏里面出现了一行字,找到里面的数字端口并抄下来,填在《映射》章节中的本地端口中。\n" + 144 | "这时候再打开隧道,把(地址:远程端口)发送给需要联机的人就可以了哦~\n" + 145 | "(不知道啥是《映射》章节?试试输入内网穿透咋整吧~)\n" + 146 | "注意!开房联机有限制!详情输入(账户查看)\n" + 147 | "建议去看群文件中Minecraft教程里的《我的世界教程广版》第二章:联机 (开房联机 P18)\n" + 148 | "或者也可以点击https://www.bilibili.com/read/cv12500724/?from=readlist直接查看教程"),MESSAGE_HOW)); 149 | ILLUSTRATOR_HOW.add(new ReceptionIllustrative(new String[]{"开","服"}, 2, new MessageChainBuilder() 150 | .append("服务器哪有这么容易开啊.......\n" + 151 | "建议去看群文件中Minecraft教程里的《我的世界教程广版》第二章:联机 (服务器联机 P19)\n" + 152 | "或者也可以点击https://www.bilibili.com/read/cv12500859/?from=readlist直接查看教程"),MESSAGE_HOW)); 153 | ILLUSTRATOR_HOW.add(new ReceptionIllustrative(new String[]{"服","房","加"}, 2, new MessageChainBuilder() 154 | .append("首先需要准备好目标服务器所需要的客户端。(如果你是开房联机的话,需要准备和房主一样的客户端)\n" + 155 | "模组必须要和服务器、开房的人同步,你可以多加模组,但是多的模组的内容将不会出现在游戏中。\n" + 156 | "但是诸如一些功能性的模组,比如JEI,小地图,高清修复等仍然可以发挥作用。\n" + 157 | "准备好这些之后进入游戏,选择多人游戏。然后选择添加服务器,输入你想要的备注名称和对方所给你的ip。\n" + 158 | "点击完成,再选择刚创建的服务器,点击加入就可以啦~\n" + 159 | "建议去看群文件中Minecraft教程里的《我的世界教程广版》第二章:联机 (如何进入别人的房间/服务器 P20)\n" + 160 | "或者也可以点击https://www.bilibili.com/read/cv12500878/?from=readlist直接查看教程"),MESSAGE_HOW)); 161 | ILLUSTRATOR_WHAT.add(new ReceptionIllustrative(new String[]{"插件"}, 1, new MessageChainBuilder() 162 | .append("插件是一种仅能用在服务器上的游戏附加内容。它可以有限地为服务器提供额外的玩法,但是它无法添加新的物品,实体等。"),MESSAGE_WHAT)); 163 | ILLUSTRATOR_HOW.add(new ReceptionIllustrative(new String[]{"插件"}, 1, new MessageChainBuilder() 164 | .append("插件(绝对)都是jar格式的,打开你(必须要启动过的)服务器的目录,可以找到一个名叫plugins的文件夹。\n" + 165 | "把插件放到这个文件夹里,再启动一下服务器就可以啦~\n" + 166 | "建议去看群文件中Minecraft教程里的《我的世界教程广版》第三章:服务器个性化设置 (插件 P21)\n" + 167 | "或者也可以点击https://www.bilibili.com/read/cv12803744/?from=readlist直接查看教程"),MESSAGE_WHAT)); 168 | ILLUSTRATOR_HOW.add(new ReceptionIllustrative(new String[]{"server.properties"}, 1, new MessageChainBuilder() 169 | .append("server.properties太长啦~" + 170 | "建议去看群文件中Minecraft教程里的《我的世界教程广版》第三章:服务器个性化设置 (server.properties个性化 P21)\n" + 171 | "或者也可以点击https://www.bilibili.com/read/cv12804181/?from=readlist直接查看教程"),MESSAGE_HOW)); 172 | ILLUSTRATOR_HOW.add(new ReceptionIllustrative(new String[]{"服","图标"}, 2, new MessageChainBuilder() 173 | .append("首先需要准备一个64*64大小的png文件。并且把这个文件改名叫server-icon.png。" + 174 | "把他放到服务器目录中再重新启动一次服务器,就可以在多人游戏界面看到这个图标了。" + 175 | "建议去看群文件中Minecraft教程里的《我的世界教程广版》第三章:服务器个性化设置 (图标设置 P23)\n" + 176 | "或者也可以点击https://www.bilibili.com/read/cv12804379/?from=readlist直接查看教程"),MESSAGE_HOW)); 177 | //注意:服务器如何添加模组已被删除。 178 | ILLUSTRATOR_HOW.add(new ReceptionIllustrative(new String[]{"整合包"}, 1, new MessageChainBuilder() 179 | .append("整合包的话一般有三种结构,所以出现三种安装方式。" + 180 | "首先你需要解压你获得的整合包,并且观察这个整合包的结构。\n" + 181 | "1.如果解压出的文件夹里有名叫(modpack)的压缩包,那么把原来的压缩包直接拖进启动器就可以安装了,之后看启动器的提示进行后续操作即可。\n" + 182 | "2.如果解压出的文件夹里有名叫(.minecraft)的文件夹,那么找到里面的启动器,双击打开设置好个人信息就可以了。" + 183 | "如果里面没有启动器,就放一个自己的启动器进去。\n" + 184 | "3.如果没有观察到上述现象,请向你所在的群的管理求助。"),MESSAGE_HOW)); 185 | ILLUSTRATOR_ERROR.add(new ReceptionIllustrative(new String[]{"游戏"}, 1, new MessageChainBuilder() 186 | .append("如果游戏发生崩溃了的话,可以去群文件中的报错检索表进行排查啦~"), MESSAGE_ERROR)); 187 | } 188 | } 189 | --------------------------------------------------------------------------------