This commit is contained in:
Xujiayao 2024-10-29 12:48:08 +08:00 committed by Jason Xu
parent d545e0c096
commit 858fee217e
10 changed files with 585 additions and 8 deletions

View file

@ -1,6 +1,7 @@
plugins {
id "fabric-loom" version "1.8-SNAPSHOT" apply false
id "com.replaymod.preprocess" version "88169fcb"
id "com.gradleup.shadow" version "8.3.3" apply false
}
preprocess {

View file

@ -31,7 +31,10 @@ import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.ExecutorService;
@ -170,7 +173,7 @@ public class MinecraftEventListener {
}
if (CONFIG.generic.broadcastChatMessages) {
sendDiscordMessage(contentToDiscord, Objects.requireNonNull(player.getDisplayName()).getString(), CONFIG.generic.avatarApi.replace("%player%", (CONFIG.generic.useUuidInsteadOfName ? player.getUUID().toString() : player.getDisplayName().getString())));
sendDiscordMessage(contentToDiscord, Objects.requireNonNull(player.getDisplayName()).getString(), getAvatarUrl(player));
if (CONFIG.multiServer.enable) {
MULTI_SERVER.sendMessage(false, true, false, Objects.requireNonNull(player.getDisplayName()).getString(), CONFIG.generic.formatChatMessages ? contentToMinecraft : message);
}
@ -186,7 +189,7 @@ public class MinecraftEventListener {
MinecraftEvents.PLAYER_COMMAND.register((player, command) -> {
if (CONFIG.generic.broadcastPlayerCommandExecution) {
for (String excludedCommand : CONFIG.generic.excludedCommands) {
if (command.startsWith(excludedCommand + " ")) {
if (command.matches(excludedCommand)) {
return;
}
}
@ -214,7 +217,7 @@ public class MinecraftEventListener {
//$$ SERVER.sendMessage(message);
//#endif
sendDiscordMessage(MarkdownSanitizer.escape(command), Objects.requireNonNull(player.getDisplayName()).getString(), CONFIG.generic.avatarApi.replace("%player%", (CONFIG.generic.useUuidInsteadOfName ? player.getUUID().toString() : player.getDisplayName().getString())));
sendDiscordMessage(MarkdownSanitizer.escape(command), Objects.requireNonNull(player.getDisplayName()).getString(), getAvatarUrl(player));
if (CONFIG.multiServer.enable) {
MULTI_SERVER.sendMessage(false, true, false, player.getDisplayName().getString(), MarkdownSanitizer.escape(command));
}
@ -354,9 +357,29 @@ public class MinecraftEventListener {
}
}
// TODO reverted
// TODO Commit cafa9c4
// {player_name} conflicts with nickname-changing mods
// TODO Move to Placeholder class
private static String getAvatarUrl(Player player) {
return CONFIG.generic.avatarApi.replace("%player%", (CONFIG.generic.useUuidInsteadOfName ? player.getUUID().toString() : Objects.requireNonNull(player.getDisplayName()).getString()));
String hash = "null";
if (CONFIG.generic.avatarApi.contains("{player_textures}")) {
try {
//#if MC > 12001
String textures = player.getGameProfile().getProperties().get("textures").iterator().next().value();
//#else
//$$ String textures = player.getGameProfile().getProperties().get("textures").iterator().next().getValue();
//#endif
JsonObject json = new Gson().fromJson(new String(Base64.getDecoder().decode(textures), StandardCharsets.UTF_8), JsonObject.class);
String url = json.getAsJsonObject("textures").getAsJsonObject("SKIN").get("url").getAsString();
hash = url.replace("http://textures.minecraft.net/texture/", "");
} catch (NoSuchElementException ignored) {
}
}
return CONFIG.generic.avatarApi
.replace("{player_uuid}", player.getUUID().toString())
.replace("{player_name}", player.getName().getString())
.replace("{player_textures}", hash);
}
}

View file

@ -2,6 +2,7 @@ import groovy.json.JsonBuilder
import groovy.json.JsonSlurper
apply plugin: "fabric-loom"
apply plugin: "com.gradleup.shadow"
java {
sourceCompatibility = JavaVersion.VERSION_21
@ -15,6 +16,13 @@ base {
archivesName = archives_base_name
}
repositories {
maven {
name = "IntelliJ Release"
url = "https://www.jetbrains.com/intellij-repository/releases"
}
}
dependencies {
minecraft("com.mojang:minecraft:${minecraft_version}")
mappings(loom.officialMojangMappings())
@ -27,7 +35,8 @@ dependencies {
}
include("net.sf.trove4j:core:3.1.0")
include("org.apache.commons:commons-collections4:4.4")
include("org.slf4j:slf4j-api:2.0.13") // 1.x is Incompatible with Quilt (#164)
shadow(implementation("org.slf4j:slf4j-api:2.0.13")) // 1.x is Incompatible with Quilt (#164)
shadow(implementation("org.apache.logging.log4j:log4j-slf4j2-impl:2.24.1")) // TODO Any better way?
include("com.neovisionaries:nv-websocket-client:2.14")
include("com.fasterxml.jackson.core:jackson-core:2.17.2")
include("com.fasterxml.jackson.core:jackson-databind:2.17.2")
@ -38,7 +47,11 @@ dependencies {
include("net.fellbaum:jemoji:1.3.4") // File size of 1.4.x is too big
include("com.google.code.gson:gson:2.11.0")
shadow(implementation("com.google.code.gson:gson:2.11.0"))
shadow(implementation("com.jetbrains.intellij.java:java-gui-forms-rt:242.22855.106"))
shadow(implementation("com.formdev:flatlaf:3.5.2"))
shadow(implementation("com.formdev:flatlaf-extras:3.5.2"))
}
def fabric_subprojects = parent.subprojects.findAll({
@ -48,7 +61,10 @@ def fabric_subprojects = parent.subprojects.findAll({
remapJar {
outputs.upToDateWhen { false }
inputFile.set shadowJar.archiveFile
dependsOn {
shadowJar
fabric_subprojects.collect {
it.tasks.remapJar
}
@ -75,6 +91,7 @@ remapJar {
copy {
from "build/libs"
into "../build"
exclude "*wrapper*"
}
}
}
@ -103,4 +120,16 @@ processResources {
writer.flush()
writer.close()
}
}
jar {
manifest {
attributes "Main-Class": "com.xujiayao.discord_mc_chat.wrapper.Main"
}
}
shadowJar {
archiveClassifier = "wrapper"
configurations = [project.configurations.shadow]
// FlatLaf does not support minimization and relocation
}

View file

@ -0,0 +1,137 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.xujiayao.discord_mc_chat.wrapper.GUI">
<grid id="27dc6" binding="contentPane" layout-manager="GridLayoutManager" row-count="13" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="10" left="10" bottom="10" right="10"/>
<constraints>
<xy x="20" y="20" width="658" height="514"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="a81dc" class="javax.swing.JLabel" binding="versionLabel">
<constraints>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false">
<preferred-size width="248" height="22"/>
</grid>
</constraints>
<properties>
<font size="12"/>
<text resource-bundle="lang/lang" key="version"/>
</properties>
</component>
<component id="7f8" class="javax.swing.JSeparator">
<constraints>
<grid row="2" column="0" row-span="1" col-span="3" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<orientation value="0"/>
</properties>
</component>
<component id="d92a4" class="javax.swing.JLabel">
<constraints>
<grid row="3" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="9" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<font size="12"/>
<text resource-bundle="lang/lang" key="description1"/>
</properties>
</component>
<component id="f21cf" class="javax.swing.JSeparator">
<constraints>
<grid row="11" column="0" row-span="1" col-span="3" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<orientation value="0"/>
</properties>
</component>
<component id="2943f" class="javax.swing.JButton" binding="button">
<constraints>
<grid row="12" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<font size="12"/>
<horizontalAlignment value="0"/>
<text resource-bundle="lang/lang" key="buttonText"/>
</properties>
</component>
<component id="d9f15" class="javax.swing.JLabel">
<constraints>
<grid row="0" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<font size="20" style="1"/>
<text resource-bundle="lang/lang" key="welcome"/>
</properties>
</component>
<component id="deecd" class="javax.swing.JLabel">
<constraints>
<grid row="1" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<font size="12"/>
<text resource-bundle="lang/lang" key="author"/>
</properties>
</component>
<component id="ed076" class="javax.swing.JLabel" binding="iconLabel">
<constraints>
<grid row="0" column="0" row-span="2" col-span="1" vsize-policy="0" hsize-policy="0" anchor="10" fill="0" indent="0" use-parent-layout="false">
<minimum-size width="50" height="50"/>
<preferred-size width="50" height="50"/>
<maximum-size width="50" height="50"/>
</grid>
</constraints>
<properties/>
</component>
<component id="3772" class="javax.swing.JLabel">
<constraints>
<grid row="5" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="9" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<font size="12"/>
<opaque value="false"/>
<text resource-bundle="lang/lang" key="description2"/>
</properties>
</component>
<component id="b2631" class="javax.swing.JLabel" binding="docsLabel">
<constraints>
<grid row="7" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="9" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<font size="12"/>
<text resource-bundle="lang/lang" key="description3"/>
<toolTipText value="https://blog.xujiayao.com/posts/4ba0a17a/" noi18n="true"/>
</properties>
</component>
<vspacer id="26498">
<constraints>
<grid row="8" column="0" row-span="1" col-span="3" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<vspacer id="13b05">
<constraints>
<grid row="6" column="0" row-span="1" col-span="3" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<vspacer id="b64a9">
<constraints>
<grid row="4" column="0" row-span="1" col-span="3" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<vspacer id="b7b17">
<constraints>
<grid row="10" column="0" row-span="1" col-span="3" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<component id="63dc0" class="javax.swing.JLabel" binding="discordLabel">
<constraints>
<grid row="9" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="9" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<font size="12"/>
<text resource-bundle="lang/lang" key="description4"/>
<toolTipText value="https://discord.gg/kbXkV6k2XU" noi18n="true"/>
</properties>
</component>
</children>
</grid>
</form>

View file

@ -0,0 +1,264 @@
package com.xujiayao.discord_mc_chat.wrapper;
import com.formdev.flatlaf.extras.FlatSVGIcon;
import com.formdev.flatlaf.extras.FlatSVGUtils;
import com.intellij.uiDesigner.core.GridConstraints;
import com.intellij.uiDesigner.core.GridLayoutManager;
import com.intellij.uiDesigner.core.Spacer;
import javax.swing.*;
import javax.swing.plaf.FontUIResource;
import javax.swing.text.StyleContext;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.lang.reflect.Method;
import java.net.URI;
import java.text.MessageFormat;
import java.util.Locale;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
import static com.xujiayao.discord_mc_chat.wrapper.Main.LOGGER;
import static com.xujiayao.discord_mc_chat.wrapper.Main.VERSION;
/**
* @author Xujiayao
*/
public class GUI extends JFrame {
private JPanel contentPane;
private JLabel versionLabel;
private JButton button;
private JLabel iconLabel;
private JLabel docsLabel;
private JLabel discordLabel;
public GUI() {
ResourceBundle bundle = PropertyResourceBundle.getBundle("lang/lang");
setTitle(bundle.getString("title"));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setContentPane(contentPane);
setIconImages(FlatSVGUtils.createWindowIconImages("/icon.svg"));
iconLabel.setIcon(new FlatSVGIcon("icon.svg", 50, 50));
String pattern = bundle.getString("version");
versionLabel.setText(MessageFormat.format(pattern, VERSION));
docsLabel.setCursor(new Cursor(Cursor.HAND_CURSOR));
discordLabel.setCursor(new Cursor(Cursor.HAND_CURSOR));
docsLabel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
try {
Desktop.getDesktop().browse(new URI("https://blog.xujiayao.com/posts/4ba0a17a/"));
} catch (Exception ex) {
LOGGER.error("Exception", ex);
}
}
});
discordLabel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
try {
Desktop.getDesktop().browse(new URI("https://discord.gg/kbXkV6k2XU"));
} catch (Exception ex) {
LOGGER.error("Exception", ex);
}
}
});
setPreferredSize(new Dimension(500, 400));
pack();
setLocationRelativeTo(null);
setResizable(false);
button.addActionListener(e -> dispose());
}
{
// GUI initializer generated by IntelliJ IDEA GUI Designer
// >>> IMPORTANT!! <<<
// DO NOT EDIT OR ADD ANY CODE HERE!
$$$setupUI$$$();
}
/**
* Method generated by IntelliJ IDEA GUI Designer
* >>> IMPORTANT!! <<<
* DO NOT edit this method OR call it in your code!
*
* @noinspection ALL
*/
private void $$$setupUI$$$() {
contentPane = new JPanel();
contentPane.setLayout(new GridLayoutManager(13, 3, new Insets(10, 10, 10, 10), -1, -1));
versionLabel = new JLabel();
Font versionLabelFont = this.$$$getFont$$$(null, -1, 12, versionLabel.getFont());
if (versionLabelFont != null) versionLabel.setFont(versionLabelFont);
this.$$$loadLabelText$$$(versionLabel, this.$$$getMessageFromBundle$$$("lang/lang", "version"));
contentPane.add(versionLabel, new GridConstraints(1, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(248, 22), null, 0, false));
final JSeparator separator1 = new JSeparator();
separator1.setOrientation(0);
contentPane.add(separator1, new GridConstraints(2, 0, 1, 3, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
final JLabel label1 = new JLabel();
Font label1Font = this.$$$getFont$$$(null, -1, 12, label1.getFont());
if (label1Font != null) label1.setFont(label1Font);
this.$$$loadLabelText$$$(label1, this.$$$getMessageFromBundle$$$("lang/lang", "description1"));
contentPane.add(label1, new GridConstraints(3, 0, 1, 3, GridConstraints.ANCHOR_NORTHWEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false));
final JSeparator separator2 = new JSeparator();
separator2.setOrientation(0);
contentPane.add(separator2, new GridConstraints(11, 0, 1, 3, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
button = new JButton();
Font buttonFont = this.$$$getFont$$$(null, -1, 12, button.getFont());
if (buttonFont != null) button.setFont(buttonFont);
button.setHorizontalAlignment(0);
this.$$$loadButtonText$$$(button, this.$$$getMessageFromBundle$$$("lang/lang", "buttonText"));
contentPane.add(button, new GridConstraints(12, 2, 1, 1, GridConstraints.ANCHOR_EAST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
final JLabel label2 = new JLabel();
Font label2Font = this.$$$getFont$$$(null, Font.BOLD, 20, label2.getFont());
if (label2Font != null) label2.setFont(label2Font);
this.$$$loadLabelText$$$(label2, this.$$$getMessageFromBundle$$$("lang/lang", "welcome"));
contentPane.add(label2, new GridConstraints(0, 1, 1, 2, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
final JLabel label3 = new JLabel();
Font label3Font = this.$$$getFont$$$(null, -1, 12, label3.getFont());
if (label3Font != null) label3.setFont(label3Font);
this.$$$loadLabelText$$$(label3, this.$$$getMessageFromBundle$$$("lang/lang", "author"));
contentPane.add(label3, new GridConstraints(1, 2, 1, 1, GridConstraints.ANCHOR_EAST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
iconLabel = new JLabel();
contentPane.add(iconLabel, new GridConstraints(0, 0, 2, 1, GridConstraints.ANCHOR_SOUTHWEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, new Dimension(50, 50), new Dimension(50, 50), new Dimension(50, 50), 0, false));
final JLabel label4 = new JLabel();
Font label4Font = this.$$$getFont$$$(null, -1, 12, label4.getFont());
if (label4Font != null) label4.setFont(label4Font);
label4.setOpaque(false);
this.$$$loadLabelText$$$(label4, this.$$$getMessageFromBundle$$$("lang/lang", "description2"));
contentPane.add(label4, new GridConstraints(5, 0, 1, 3, GridConstraints.ANCHOR_NORTHWEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false));
docsLabel = new JLabel();
Font docsLabelFont = this.$$$getFont$$$(null, -1, 12, docsLabel.getFont());
if (docsLabelFont != null) docsLabel.setFont(docsLabelFont);
this.$$$loadLabelText$$$(docsLabel, this.$$$getMessageFromBundle$$$("lang/lang", "description3"));
docsLabel.setToolTipText("https://blog.xujiayao.com/posts/4ba0a17a/");
contentPane.add(docsLabel, new GridConstraints(7, 0, 1, 3, GridConstraints.ANCHOR_NORTHWEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false));
final Spacer spacer1 = new Spacer();
contentPane.add(spacer1, new GridConstraints(8, 0, 1, 3, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_VERTICAL, 1, GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false));
final Spacer spacer2 = new Spacer();
contentPane.add(spacer2, new GridConstraints(6, 0, 1, 3, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_VERTICAL, 1, GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false));
final Spacer spacer3 = new Spacer();
contentPane.add(spacer3, new GridConstraints(4, 0, 1, 3, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_VERTICAL, 1, GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false));
final Spacer spacer4 = new Spacer();
contentPane.add(spacer4, new GridConstraints(10, 0, 1, 3, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_VERTICAL, 1, GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false));
discordLabel = new JLabel();
Font discordLabelFont = this.$$$getFont$$$(null, -1, 12, discordLabel.getFont());
if (discordLabelFont != null) discordLabel.setFont(discordLabelFont);
this.$$$loadLabelText$$$(discordLabel, this.$$$getMessageFromBundle$$$("lang/lang", "description4"));
discordLabel.setToolTipText("https://discord.gg/kbXkV6k2XU");
contentPane.add(discordLabel, new GridConstraints(9, 0, 1, 3, GridConstraints.ANCHOR_NORTHWEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false));
}
/**
* @noinspection ALL
*/
private Font $$$getFont$$$(String fontName, int style, int size, Font currentFont) {
if (currentFont == null) return null;
String resultName;
if (fontName == null) {
resultName = currentFont.getName();
} else {
Font testFont = new Font(fontName, Font.PLAIN, 10);
if (testFont.canDisplay('a') && testFont.canDisplay('1')) {
resultName = fontName;
} else {
resultName = currentFont.getName();
}
}
Font font = new Font(resultName, style >= 0 ? style : currentFont.getStyle(), size >= 0 ? size : currentFont.getSize());
boolean isMac = System.getProperty("os.name", "").toLowerCase(Locale.ENGLISH).startsWith("mac");
Font fontWithFallback = isMac ? new Font(font.getFamily(), font.getStyle(), font.getSize()) : new StyleContext().getFont(font.getFamily(), font.getStyle(), font.getSize());
return fontWithFallback instanceof FontUIResource ? fontWithFallback : new FontUIResource(fontWithFallback);
}
private static Method $$$cachedGetBundleMethod$$$ = null;
private String $$$getMessageFromBundle$$$(String path, String key) {
ResourceBundle bundle;
try {
Class<?> thisClass = this.getClass();
if ($$$cachedGetBundleMethod$$$ == null) {
Class<?> dynamicBundleClass = thisClass.getClassLoader().loadClass("com.intellij.DynamicBundle");
$$$cachedGetBundleMethod$$$ = dynamicBundleClass.getMethod("getBundle", String.class, Class.class);
}
bundle = (ResourceBundle) $$$cachedGetBundleMethod$$$.invoke(null, path, thisClass);
} catch (Exception e) {
bundle = ResourceBundle.getBundle(path);
}
return bundle.getString(key);
}
/**
* @noinspection ALL
*/
private void $$$loadLabelText$$$(JLabel component, String text) {
StringBuffer result = new StringBuffer();
boolean haveMnemonic = false;
char mnemonic = '\0';
int mnemonicIndex = -1;
for (int i = 0; i < text.length(); i++) {
if (text.charAt(i) == '&') {
i++;
if (i == text.length()) break;
if (!haveMnemonic && text.charAt(i) != '&') {
haveMnemonic = true;
mnemonic = text.charAt(i);
mnemonicIndex = result.length();
}
}
result.append(text.charAt(i));
}
component.setText(result.toString());
if (haveMnemonic) {
component.setDisplayedMnemonic(mnemonic);
component.setDisplayedMnemonicIndex(mnemonicIndex);
}
}
/**
* @noinspection ALL
*/
private void $$$loadButtonText$$$(AbstractButton component, String text) {
StringBuffer result = new StringBuffer();
boolean haveMnemonic = false;
char mnemonic = '\0';
int mnemonicIndex = -1;
for (int i = 0; i < text.length(); i++) {
if (text.charAt(i) == '&') {
i++;
if (i == text.length()) break;
if (!haveMnemonic && text.charAt(i) != '&') {
haveMnemonic = true;
mnemonic = text.charAt(i);
mnemonicIndex = result.length();
}
}
result.append(text.charAt(i));
}
component.setText(result.toString());
if (haveMnemonic) {
component.setMnemonic(mnemonic);
component.setDisplayedMnemonicIndex(mnemonicIndex);
}
}
/**
* @noinspection ALL
*/
public JComponent $$$getRootComponent$$$() {
return contentPane;
}
}

View file

@ -0,0 +1,69 @@
package com.xujiayao.discord_mc_chat.wrapper;
import com.formdev.flatlaf.FlatIntelliJLaf;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.swing.*;
import java.awt.*;
import java.io.InputStreamReader;
import java.io.Reader;
import java.text.MessageFormat;
import java.util.Objects;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
/**
* @author Xujiayao
*/
public class Main {
public static final String VERSION;
public static final Logger LOGGER = LoggerFactory.getLogger("Discord-MC-Chat Wrapper");
static {
String version = null;
try (Reader reader = new InputStreamReader(Objects.requireNonNull(Main.class.getResourceAsStream("/fabric.mod.json")))) {
version = new Gson().fromJson(reader, JsonObject.class).get("version").getAsString();
} catch (Exception e) {
LOGGER.error("Exception", e);
}
VERSION = version;
}
public static void main(String[] args) {
// Locale.setDefault(Locale.US);
if (Desktop.isDesktopSupported()) {
SwingUtilities.invokeLater(() -> {
FlatIntelliJLaf.setup();
GUI gui = new GUI();
gui.setVisible(true);
});
} else {
ResourceBundle bundle = PropertyResourceBundle.getBundle("lang/lang");
String description2 = bundle.getString("description2").replaceAll("<html>|</html>", "");
LOGGER.info("-----------------------------------------");
LOGGER.info(bundle.getString("welcome"));
LOGGER.info(MessageFormat.format(bundle.getString("version"), VERSION));
LOGGER.info(bundle.getString("author"));
LOGGER.info("");
LOGGER.info(bundle.getString("description1").replaceAll("<html>|</html>", ""));
LOGGER.info("");
LOGGER.info(description2.substring(0, description2.indexOf("<")));
LOGGER.info(description2.substring(description2.indexOf("<br>") + 8));
LOGGER.info("");
LOGGER.info(bundle.getString("description3").replaceAll("<html>|</html>", "").replaceAll("</font>", " (https://blog.xujiayao.com/posts/4ba0a17a/)").replaceAll("<(.*?)>", ""));
LOGGER.info("");
LOGGER.info(bundle.getString("description4").replaceAll("<html>|</html>", "").replaceAll("</font>", " (https://discord.gg/kbXkV6k2XU)").replaceAll("<(.*?)>", ""));
LOGGER.info("-----------------------------------------");
}
}
}
// TODO icon size?

View file

@ -0,0 +1,27 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="256.000000pt" height="256.000000pt" viewBox="0 0 256.000000 256.000000"
preserveAspectRatio="xMidYMid meet">
<g transform="translate(0.000000,256.000000) scale(0.100000,-0.100000)"
fill="#5662F6" stroke="none">
<path d="M1140 2550 c-470 -58 -870 -360 -1041 -785 -117 -292 -126 -607 -25
-902 117 -342 389 -631 721 -764 292 -117 607 -126 902 -25 342 117 631 389
764 721 117 292 126 607 25 902 -147 431 -519 751 -974 837 -106 20 -277 27
-372 16z m-62 -686 l19 -36 183 0 183 0 20 37 c18 36 20 37 62 32 24 -4 95
-23 157 -43 137 -44 151 -57 230 -210 108 -209 151 -393 146 -619 l-3 -130
-103 -62 c-94 -56 -214 -111 -283 -128 -24 -6 -30 0 -68 59 -22 36 -41 68 -41
71 0 2 30 18 67 35 50 23 64 33 55 42 -9 9 -34 4 -104 -20 -140 -47 -199 -55
-360 -49 -143 5 -195 15 -320 63 -37 14 -50 16 -60 6 -9 -9 4 -19 55 -43 l67
-31 -25 -46 c-14 -26 -34 -58 -45 -72 l-19 -25 -58 20 c-74 25 -222 99 -295
149 l-58 38 0 132 c0 228 36 382 141 594 80 161 100 181 219 220 188 62 213
64 238 16z"/>
<path d="M920 1415 l0 -115 120 0 120 0 0 115 0 115 -120 0 -120 0 0 -115z"/>
<path d="M1400 1415 l0 -115 120 0 120 0 0 115 0 115 -120 0 -120 0 0 -115z"/>
<path d="M1160 1230 l0 -60 -60 0 -60 0 0 -120 0 -120 60 0 60 0 0 60 0 60
120 0 120 0 0 -60 0 -60 60 0 60 0 0 120 0 120 -60 0 -60 0 0 60 0 60 -120 0
-120 0 0 -60z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -0,0 +1,9 @@
title=Welcome - Discord-MC-Chat (DMCC)
welcome=Welcome to Discord-MC-Chat (DMCC)!
version=Version: {0}
author=By Xujiayao
description1=<html>Oops! You are attempting to run Discord-MC-Chat directly!</html>
description2=<html>Note:<br><br>Discord-MC-Chat is a Fabric Minecraft mod. Please place the JAR file in the "mods" folder of your Minecraft server and run it through the Fabric mod loader, instead of opening it directly.</html>
description3=<html>Please follow <font color="#1B75D0">Discord-MC-Chat Docs</font> to configure Discord-MC-Chat.</html>
description4=<html>If you need more help, you can ask me questions in the <font color="#1B75D0">DMCC Discord Server</font>.</html>
buttonText=&Close

View file

@ -0,0 +1,9 @@
title=Welcome - Discord-MC-Chat (DMCC)
welcome=Welcome to Discord-MC-Chat (DMCC)!
version=Version: {0}
author=By Xujiayao
description1=<html>Oops! You are attempting to run Discord-MC-Chat directly!</html>
description2=<html>Note:<br><br>Discord-MC-Chat is a Fabric Minecraft mod. Please place the JAR file in the "mods" folder of your Minecraft server and run it through the Fabric mod loader, instead of opening it directly.</html>
description3=<html>Please follow <font color="#1B75D0">Discord-MC-Chat Docs</font> to configure Discord-MC-Chat.</html>
description4=<html>If you need more help, you can ask me questions in the <font color="#1B75D0">DMCC Discord Server</font>.</html>
buttonText=&Close

View file

@ -0,0 +1,9 @@
title=欢迎 - Discord-MC-Chat (DMCC)
welcome=欢迎使用 Discord-MC-Chat (DMCC)
version=版本:{0}
author=作者Xujiayao
description1=<html>哎呀!你正试图直接运行 Discord-MC-Chat</html>
description2=<html>注意:<br><br>Discord-MC-Chat 是一个 Fabric Minecraft 模组。请将 JAR 文件放入 Minecraft 服务器的 "mods" 文件夹中,并通过 Fabric 模组加载器运行,而并非直接打开。</html>
description3=<html>请按照 <font color="#1B75D0">Discord-MC-Chat 文档</font> 配置 Discord-MC-Chat。</html>
description4=<html>如果你需要更多帮助,你可以在 <font color="#1B75D0">DMCC Discord 服务器</font> 向我提问。</html>
buttonText=&关闭