Skip to content

Commit

Permalink
Merge pull request #2 from MinecraftChampions/minimessage
Browse files Browse the repository at this point in the history
feat(Building): 新增模块message
  • Loading branch information
mcchampions authored Sep 17, 2023
2 parents 43f7ed9 + 9ad6fec commit 1500ce7
Show file tree
Hide file tree
Showing 12 changed files with 625 additions and 1 deletion.
4 changes: 4 additions & 0 deletions core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,9 @@
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,13 @@ public static JSONObject toJSONObject(String xml) {
return XML.toJSONObject(xml);
}

/**
* json转换为Toml
*
* @param jsonObject json
* @return toml
*/
public static String jsonToXml(JSONObject jsonObject) {
return XML.toString(jsonObject);
}
}
}
34 changes: 34 additions & 0 deletions message/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>io.github.minecraftchampions.dodoopenjava</groupId>
<artifactId>DodoOpenJava</artifactId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>

<groupId>io.github.minecraftchampions.dodoopenjava.message</groupId>
<artifactId>message</artifactId>
<packaging>jar</packaging>

<properties>
<maven.compiler.source>16</maven.compiler.source>
<maven.compiler.target>16</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
<dependency>
<groupId>io.github.minecraftchampions.dodoopenjava</groupId>
<artifactId>core</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.vladsch.flexmark</groupId>
<artifactId>flexmark-all</artifactId>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
package io.github.minecraftchampions.dodoopenjava.message;

import com.vladsch.flexmark.html.HtmlRenderer;
import com.vladsch.flexmark.parser.Parser;
import com.vladsch.flexmark.util.ast.Node;
import com.vladsch.flexmark.util.data.MutableDataSet;

import java.util.AbstractMap.SimpleEntry;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;

/**
* 消息组件
*/
public class MessageComponent {
private final String text;

private MessageComponent(String text) {
this.text = text;
}

/**
* 将Markdown转换为MessageComponent
*
* @param text Markdown
* @return MessageComponent
*/
public static MessageComponent parseMarkdown(String text) {
MutableDataSet options = new MutableDataSet();
Parser parser = Parser.builder(options).build();
HtmlRenderer renderer = HtmlRenderer.builder()
.build();
Node document = parser.parse(text);
String html = renderer.render(document);
html = html.substring(0,html.length()-1);
html = html.replaceAll("\\n<([^>]*)>\\n","\n<$1>");
Matcher matcher = MessageUtil.pattern.matcher(html);
while (matcher.find()) {
String tempToken = matcher.group("token");
int start = matcher.start("token");
int end = matcher.end("token");
Matcher m = MessageUtil.tokenPattern.matcher(tempToken);
if (m.find()) {
String token = m.group("token");
String attrKey = m.group("attrkey");
boolean isEnd = false;
if (token.indexOf("/") == 0) {
token = token.split("/")[1];
isEnd = true;
}
Map<String, TextComponent> map = TextComponentGroup.getHtmlReplaceMap();
if (map.containsKey(token)) {
TextComponent component = map.get(token);
String replacement = component.getKey();
token = token.replaceFirst(token, replacement);
String str = token;
if (!isEnd && attrKey != null) {
attrKey = component.getAttribute();
str = str + " " + attrKey + "=\"" + m.group("attrvalue") + "\"";
}
if (isEnd) {
str = "/" + str;
}
String tempStr = html.substring(start);
tempStr = tempStr.replaceFirst(tempToken, str);
html = html.substring(0, start) + tempStr;
}
}
}
html = html.replaceAll("</?content>", "").replaceAll("([^|])\\|([^|])", "$1&#124$2").replaceAll("\\|\\|([^|]*)\\|\\|", "<antispoiler>$1</antispoiler>").replaceAll("([^_])_([^_])", "$1&#95$2").replaceAll("__([^_]*)__", "<underline>$1</underline>").replaceAll("([^~])~([^~])", "$1&#126$2").replaceAll("~~([^~]*)~~", "<strikethrough>$1</strikethrough>");
return new MessageComponent(html);
}

public String toString() {
return text;
}

static MessageComponent parse(String miniMessage) {
return new MessageComponent(miniMessage);
}

/**
* 获取构造器
*
* @return 构造器
*/
public static MessageComponentBuilder builder() {
return new MessageComponentBuilder();
}

/**
* 构造器
*/
public static class MessageComponentBuilder {
MessageComponentBuilder() {
}

private final LinkedHashMap<TextComponent, Entry<String, String>> parts = new LinkedHashMap<>();

/**
* 增加组件
*
* @param component 指定组件类型
* @param str 字符
* @return 构造器
*/
public MessageComponentBuilder append(TextComponent component, String str) {
this.parts.put(component, new SimpleEntry<>(str, null));
return this;
}

/**
* 增加文字组件
*
* @param str 字符
* @return 构造器
*/
public MessageComponentBuilder append(String str) {
this.parts.put(TextComponentGroup.contentComponent, new SimpleEntry<>(str, null));
return this;
}

/**
* 增加组件
*
* @param component 指定组件类型
* @param str 字符
* @param attr 属性值,目前为链接
* @return 构造器
*/
public MessageComponentBuilder append(TextComponent component, String str, String attr) {
this.parts.put(component, new SimpleEntry<>(str, attr));
return this;
}

/**
* 构造
*
* @return messageComponent
*/
public MessageComponent build() {
StringBuilder sb = new StringBuilder();
for (Entry<TextComponent, Entry<String, String>> entry : parts.entrySet()) {
sb.append(MessageUtil.toMiniMessage(entry));
}
return MiniMessageParser.parse(sb.toString());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package io.github.minecraftchampions.dodoopenjava.message;

import java.util.Map.Entry;
import java.util.regex.Pattern;

/**
* 工具类
*/
public class MessageUtil {
public static final Pattern tokenPattern = Pattern.compile("(?<token>\\S+)(\\s(?<attr>(?<attrkey>[^=]+)=\"(?<attrvalue>[^>]*)\"))?");
public static final Pattern pattern = Pattern.compile("((?<start><)(?<token>[^<>]+(:(?<inner>['\"]?([^'\"](\\\\['\"])?)+['\"]?))*)(?<end>>))+?");


/**
* 替换特殊字符
* @param text 要替换的字符
* @return str
*/
public static String replaceXmlSpecialCharacters(String text) {
return text.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll("'", "&apos;").replaceAll("\"", "&quot;");
}

/**
* 替换为MiniMessage
*
* @param entry 第一个参数为TextComponent即对应的组件,第二个参数为Entry,里面的第一个参数为内容,第二个参数为属性(如link组件的url)
* @return Str
*/
public static String toMiniMessage(Entry<TextComponent, Entry<String, String>> entry) {
TextComponent textComponent = entry.getKey();
Entry<String, String> strE = entry.getValue();
String str = strE.getKey();
String attr = strE.getValue();
if (textComponent == TextComponentGroup.contentComponent) {
return str;
}
StringBuilder attrSb = new StringBuilder();
if (textComponent.getAttribute() != null) {
if (attr == null) {
attr = "";
}
attrSb.append(" ").append(textComponent.getAttribute()).append("=\"").append(attr).append("\"");
}
return "<" + textComponent.getKey() + attrSb + ">" + str + "</" + textComponent.getKey() + ">";
}
}
Loading

0 comments on commit 1500ce7

Please sign in to comment.