78 Commits
lts ... dev

Author SHA1 Message Date
402fb532e0 [PORT] 25w35a 2025-08-26 22:31:53 +02:00
Teal
aba17260c3 Add Pirate Speak (#21) 2025-08-26 22:02:43 +02:00
3bda062a70 [PORT] 25w31a 2025-07-29 18:07:15 +02:00
a4a51b7cd8 1.21.6 prep 2025-06-17 19:16:28 +02:00
ff56045903 [PORT] 1.21.6-pre3 2025-06-06 23:57:58 +02:00
062b3a642a [PORT] Port up, for yet more code breakage..... 😠 2025-05-06 18:48:04 +02:00
8bb17f3c4c [FEAT] Added Compat API for Advanced Chat 2025-04-28 14:07:53 +02:00
4a0314462e [NOJANG] Allow commands to send feedback as chat messages, if command feedback is disabled 2025-04-28 14:01:14 +02:00
c6e5549fa9 [BUG] Handle Adventure serializer errors with a fallback value 2025-04-28 13:57:21 +02:00
fbcf545119 [PORT] Port for 25w17a.... 2025-04-28 13:46:44 +02:00
7eb86b012e [PORT] Port for 25w15a.... Seriously mojang, JUST STOP.... 2025-04-08 20:19:03 +02:00
Korben
cf3b89ea7f [ci-skip] Create ru_ru.json (#15) 2025-03-25 19:48:06 +02:00
79b2277a77 [PORT] 1.21.5 2025-03-25 19:46:55 +02:00
e7b3e33253 [PORT] 1.21.5-rc-1 2025-03-22 17:56:40 +02:00
dc3f3aa0b8 [PORT] 1.21.5-pre-3 2025-03-19 18:19:37 +02:00
771d438533 [FEAT] Expose Adventure JSON Serializer to mods 2025-03-14 21:58:01 +02:00
c38c7e4722 [BUG] Bump MoonConfig to fix thread hang 2025-03-14 21:54:44 +02:00
b800a4ea78 [BUG] Fix Config watcher using too many threads and not detecting changes on Linux systems 2025-03-13 14:58:15 +02:00
15b9b40b0e Temporarily disable luckperms command integration on Paper 2025-03-09 18:30:50 +02:00
76be1292f9 [NOJANG] New GameRules API to access game rules in mods 2025-03-09 15:38:22 +02:00
f4ba4d43f6 [BUG] Fix LuckPerms classes being missing on Paper 2025-03-09 15:18:01 +02:00
801f92a223 [PORT] Update for 25w10a 2025-03-09 15:13:22 +02:00
a91ebdaa7b [PORT] Update for 25w07a 2025-02-13 19:57:42 +02:00
f33363fc2d [PORT] Update for 25w06a 2025-02-11 17:44:54 +02:00
3986f08540 [DEV] Add Ability to Skip Builds 2025-02-01 18:27:34 +02:00
7f9ff38768 [FEAT] APIs for Player Revive mod and Whitelist changes 2025-02-01 17:42:04 +02:00
4c3cc6b034 [FEAT] Expose extra APIs to Command API 2025-01-15 08:03:08 +02:00
5d0ad68c64 [DEV] New Cloth Config GUIs, new nojang apis, and bug fixes 2025-01-14 18:56:19 +02:00
aded006f30 Revert "[PORT] 1.21.4"
This reverts commit 78cc17f718.
2025-01-14 15:08:53 +02:00
78cc17f718 [PORT] 1.21.4 2024-12-03 15:09:07 +02:00
5a8769bee9 Prepare for release and deprecate old RPC sdk 2024-12-02 11:46:36 +02:00
d2aca8ffa9 [WIP] FTB Ranks/LuckPerms API's 2024-11-25 18:57:14 +02:00
cc26cd450d [FEAT] Paper Support 2024-11-19 19:27:44 +02:00
4e2eafb702 [PORT] Update to 1.21.2 2024-10-22 18:44:15 +02:00
4fab7e51a1 [PORT] Update to 1.21.2-rc1 2024-10-18 12:30:15 +02:00
1ccb4c1f56 [PORT] Update for 1.21.2-pre3 2024-10-12 13:53:16 +02:00
d4a8de0fd2 [DEV] Bump Version 2024-10-09 16:43:09 +02:00
197bfaf6df [DEV] FTB Essentials Muting System Compat 2024-10-09 08:46:44 +02:00
eda815c460 [DEV] Update for 1.21.2-pre1 2024-10-09 07:57:04 +02:00
dbf5415b50 [DEV] Update for 24w37a 2024-09-13 19:23:48 +02:00
6f6c93c6ee [FEAT] MiniMessage formatting support 2024-08-31 12:19:08 +02:00
c808f53841 [BUG] Use Sync config loading, so config doesn't parse before it's loaded 2024-08-30 16:10:33 +02:00
fcc1c816e7 [PORT] Update game versions 2024-08-21 22:58:01 +02:00
aea07af3d5 [PORT] Update to 24w34a 2024-08-21 22:46:50 +02:00
0dbf07de46 - [FEAT] New APIs for Maintenance Mode and rewrite commands system
- [FEAT] Improved config system to fix old loading bugs and support JSON
- [FEAT] LuckPerms support for commands
2024-08-10 14:13:51 +02:00
2c13d507c3 [FEAT] Improved chat handling for mods like StyledChat 2024-08-08 21:34:36 +02:00
862b5b2af4 [BUG] Fix NeoForge/Forge issue with adventure 2024-08-07 21:09:10 +02:00
c8cfa985b1 [BUG] Fix NeoForge crash when Vanish is installed 2024-07-22 21:09:29 +02:00
df50b0e82d [BUG] Fix Markdown not being stripped when formatting is disabled. SDLink 2024-07-21 12:28:22 +02:00
e895a71cad [DEV] Deprecate old "isFabric" check in ModloaderEnvironment 2024-07-17 21:04:04 +02:00
597358db06 [BUG] Fix PlayerEvents ignoring isFromVanish 2024-07-14 23:08:24 +02:00
abdb68ca08 [DEV] Override jenkins build number for builds 2024-07-09 23:11:08 +02:00
4314009479 [DEV] Update modpublisher and fix nightbloom configs for jenkins 2024-07-09 22:53:50 +02:00
d21bf13b4a [CHORE] Bump Version 2024-07-05 21:15:36 +02:00
8d135fe0f2 [DEV] Nightbloom stuff 2024-07-05 21:10:46 +02:00
0f17e8f844 [FEAT] Add a way for login/logout event to know if it was sent from vanish 2024-07-05 20:49:37 +02:00
55e7e2211b [BUG] Return null for singlePlayer server when not single player 2024-07-05 20:38:48 +02:00
7d5c11772a [BUG] Don't ping server constantly for player data, if server status is null 2024-07-05 20:36:40 +02:00
843f23b9c7 [CHORE] Update dev branch with hotfixes 2024-07-05 20:29:10 +02:00
ce16c08760 [DEV] Switch to manual release approvals 2024-06-13 19:01:48 +02:00
6a8301f79a [DEV] Switch to 1.21 release 2024-06-13 18:58:31 +02:00
6b05af6c83 This is needed for nightbloom IDIOT 2024-06-11 22:55:40 +02:00
dd69ecd7cc [CHORE] Fix build display info for jenkins 2024-06-11 22:24:12 +02:00
fabef0e6f1 [BUG] Fix Adventure Serializer being configured wrong 2024-06-11 18:53:10 +02:00
a355daccb2 [CLEANUP] Nuke .idea and unused changelogs, because they shouldn't be there anyway 2024-06-11 18:42:20 +02:00
648441ec78 [no-orbit] [DEV] Fix some jenkins configs 2024-06-09 17:49:17 +02:00
40bb37e111 [CHORE] Update NeoForge version 2024-06-09 13:13:35 +02:00
d3ffc2856f [CHORE] Port for 1.21 2024-06-09 01:48:07 +02:00
493a1568ff [CHORE] Bye Bye Forge 2024-06-09 00:36:11 +02:00
55c6f60197 Update readme and add orbit config 2024-05-19 19:22:05 +02:00
d9fcf54728 Update Orion 2024-05-19 14:18:58 +02:00
da7518e08d JAVA 21 IDIOT!!! 21!!! NOT 17!!!! 2024-05-09 19:54:18 +02:00
f712036d2e Fucking orion 2024-05-09 19:41:18 +02:00
261ea4c3f8 Fuck sakes 2024-05-09 19:19:15 +02:00
16163ac944 [BUG] Disable vanish on forge, since it doesn't have a forge version anymore 2024-05-09 19:08:53 +02:00
7bbbd7be62 [IDIOT] Hypherion updated to wrong version.... 2024-05-09 18:15:44 +02:00
21d9618283 [CHORE] Update orion and fix potential forge bug 2024-05-09 18:02:32 +02:00
97d8eaa5e8 [DEV] Switch out Commons Lang TriConsumer which doesn't exist on older versions 2024-05-09 15:31:41 +02:00
2536 changed files with 323 additions and 98258 deletions

2
.gitattributes vendored
View File

@@ -2,7 +2,7 @@
*.bat text eol=crlf
*.patch text eol=lf
*.java text eol=lf
*.gradle text eol=lf
*.gradle text eol=crlf
*.png binary
*.gif binary
*.exe binary

6
.gitignore vendored
View File

@@ -23,7 +23,7 @@ run
artifacts
src/test/**
dev
workspace
upstream
rejects
workspace
rejects

View File

@@ -1,5 +1,5 @@
def JDK = "21"
def majorMc = "1.21";
def majorMc = "1.21.9";
pipeline {
agent {
@@ -26,33 +26,25 @@ pipeline {
}
stage("Prepare") {
steps {
dir("${WORKSPACE}/${majorMc}") {
sh "chmod +x ./gradlew"
sh "./gradlew clean"
}
sh "chmod +x ./gradlew"
sh "./gradlew clean"
}
}
stage("Publish to Modrinth/Curseforge") {
steps {
dir("${WORKSPACE}/${majorMc}") {
sh "./gradlew publishMod -Prelease=true"
}
sh "./gradlew publishMod -Prelease=true"
}
}
stage("Publish to Maven") {
steps {
dir("${WORKSPACE}/${majorMc}") {
sh "./gradlew publish -Prelease=true"
}
sh "./gradlew publish -Prelease=true"
}
}
}
post {
always {
dir("${WORKSPACE}/${majorMc}") {
sh "./gradlew --stop"
deleteDir()
}
sh "./gradlew --stop"
deleteDir()
discordSend webhookURL: env.FDD_WH_ADMIN,
title: "CraterLib Port Deploy #${BUILD_NUMBER}",

View File

@@ -0,0 +1,74 @@
def projectName = "CraterLib";
def projectIcon = "https://cdn.modrinth.com/data/Nn8Wasaq/a172c634683a11a2e9ae593e56eba7885743bb44.png";
def JDK = "21";
def majorMc = "25w35a";
def modLoaders = "fabric|quilt";
def supportedMc = "25w35a";
def reltype = "experimental";
pipeline {
agent {
docker {
image "registry.firstdark.dev/java${JDK}:latest"
alwaysPull true
args '-v gradle-cache:/home/gradle/.gradle'
}
}
environment {
GRADLE_USER_HOME = '/home/gradle/.gradle'
}
stages {
stage('Checkout') {
steps {
scmSkip(deleteBuild: false, skipPattern:'.*\\[ci skip\\].*')
}
}
stage("Notify Discord") {
steps {
discordSend webhookURL: env.SSS_WEBHOOK,
title: "Deploy Started: ${projectName} ${majorMc} Deploy #${BUILD_NUMBER}",
link: env.BUILD_URL,
result: 'SUCCESS',
description: "Build: [${BUILD_NUMBER}](${env.BUILD_URL})"
}
}
stage("Prepare") {
steps {
sh "chmod +x ./gradlew"
sh "./gradlew build -PreleaseType=${reltype}"
}
}
stage("Publish to Maven") {
steps {
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
sh "./gradlew publish -PreleaseType=${reltype}"
}
}
}
}
post {
always {
sh "./gradlew --stop"
archiveArtifacts artifacts: 'artifacts/*.jar'
fddsnapshotter apiKey: env.PLATFORM_KEY,
projectSlug: "craterlib",
projectName: "${projectName}",
projectIcon: "${projectIcon}",
modLoaders: "${modLoaders}",
minecraftVersions: "${supportedMc}",
type: "experimental",
dependsOn: "",
failWebhook: env.SSS_WEBHOOK,
publishWebhooks: "${env.SSS_WEBHOOK}|${env.FDD_WH}"
deleteDir()
}
}
}

15
1.18.2/.gitattributes vendored
View File

@@ -1,15 +0,0 @@
* text eol=lf
*.bat text eol=crlf
*.patch text eol=lf
*.java text eol=lf
*.gradle text eol=crlf
*.png binary
*.gif binary
*.exe binary
*.dll binary
*.jar binary
*.lzma binary
*.zip binary
*.pyd binary
*.cfg text eol=lf
*.jks binary

29
1.18.2/.gitignore vendored
View File

@@ -1,29 +0,0 @@
# eclipse
bin
*.launch
.settings
.metadata
.classpath
.project
# idea
out
*.ipr
*.iws
*.iml
.idea
# gradle
build
.gradle
# other
eclipse
run
artifacts
src/test/**
workspace
upstream
rejects

View File

@@ -1,64 +0,0 @@
def majorMc = "1.18.2";
def JDK = "17"
pipeline {
agent {
docker {
image "registry.firstdark.dev/java${JDK}:latest"
alwaysPull true
args '-v gradle-cache:/home/gradle/.gradle'
}
}
environment {
GRADLE_USER_HOME = '/home/gradle/.gradle'
}
stages {
stage("Notify Discord") {
steps {
discordSend webhookURL: env.FDD_WH_ADMIN,
title: "Deploy Started: CraterLib ${majorMc} Deploy #${BUILD_NUMBER}",
link: env.BUILD_URL,
result: 'SUCCESS',
description: "Build: [${BUILD_NUMBER}](${env.BUILD_URL})"
}
}
stage("Prepare") {
steps {
dir("${WORKSPACE}/${majorMc}") {
sh "chmod +x ./gradlew"
sh "./gradlew clean"
}
}
}
stage("Publish to Modrinth/Curseforge") {
steps {
dir("${WORKSPACE}/${majorMc}") {
sh "./gradlew publishMod -Prelease=true"
}
}
}
stage("Publish to Maven") {
steps {
dir("${WORKSPACE}/${majorMc}") {
sh "./gradlew publish -Prelease=true"
}
}
}
}
post {
always {
dir("${WORKSPACE}/${majorMc}") {
sh "./gradlew --stop"
deleteDir()
}
discordSend webhookURL: env.FDD_WH_ADMIN,
title: "CraterLib Port Deploy #${BUILD_NUMBER}",
link: env.BUILD_URL,
result: currentBuild.currentResult,
description: "Build: [${BUILD_NUMBER}](${env.BUILD_URL})\nStatus: ${currentBuild.currentResult}"
}
}
}

View File

@@ -1,80 +0,0 @@
def projectName = "CraterLib";
def projectIcon = "https://cdn.modrinth.com/data/Nn8Wasaq/a172c634683a11a2e9ae593e56eba7885743bb44.png";
def JDK = "17";
def majorMc = "1.18.2";
def modLoaders = "forge|fabric|quilt";
def supportedMc = "1.18.2";
def reltype = "snapshot";
pipeline {
agent {
docker {
image "registry.firstdark.dev/java${JDK}:latest"
alwaysPull true
args '-v gradle-cache:/home/gradle/.gradle'
}
}
environment {
GRADLE_USER_HOME = '/home/gradle/.gradle'
}
stages {
stage('Checkout') {
steps {
scmSkip(deleteBuild: false, skipPattern:'.*\\[ci skip\\].*')
}
}
stage("Notify Discord") {
steps {
discordSend webhookURL: env.SSS_WEBHOOK,
title: "Deploy Started: ${projectName} ${majorMc} Deploy #${BUILD_NUMBER}",
link: env.BUILD_URL,
result: 'SUCCESS',
description: "Build: [${BUILD_NUMBER}](${env.BUILD_URL})"
}
}
stage("Prepare") {
steps {
dir("${WORKSPACE}/${majorMc}") {
sh "chmod +x ./gradlew"
sh "./gradlew build -PreleaseType=${reltype}"
}
}
}
stage("Publish to Maven") {
steps {
dir ("${WORKSPACE}/${majorMc}") {
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
sh "./gradlew publish -PreleaseType=${reltype}"
}
}
}
}
}
post {
always {
dir("${WORKSPACE}/${majorMc}") {
sh "./gradlew --stop"
archiveArtifacts artifacts: 'artifacts/*.jar'
fddsnapshotter apiKey: env.PLATFORM_KEY,
projectSlug: "craterlib",
projectName: "${projectName}",
projectIcon: "${projectIcon}",
modLoaders: "${modLoaders}",
minecraftVersions: "${supportedMc}",
type: "snapshot",
dependsOn: "",
failWebhook: env.SSS_WEBHOOK,
publishWebhooks: "${env.SSS_WEBHOOK}|${env.FDD_WH}"
deleteDir()
}
}
}
}

View File

@@ -1,71 +0,0 @@
archivesBaseName = "${mod_name.replace(" ", "")}-Common-${minecraft_version}"
dependencies {
stupidRemapArch("dev.ftb.mods:ftb-ranks:${ftb_ranks}")
stupidRemapArch("me.shedaniel.cloth:cloth-config:${cloth_config}")
}
shadowJar {
from sourceSets.main.output
configurations = [project.configurations.shade]
dependencies {
exclude(dependency('com.google.code.gson:.*'))
relocate 'me.hypherionmc.moonconfig', 'shadow.hypherionmc.moonconfig'
relocate 'me.hypherionmc.mcdiscordformatter', 'shadow.hypherionmc.mcdiscordformatter'
relocate 'net.kyori', 'shadow.kyori'
}
setArchiveClassifier("dev")
}
/**
* ===============================================================================
* = DO NOT EDIT BELOW THIS LINE UNLESS YOU KNOW WHAT YOU ARE DOING =
* ===============================================================================
*/
unimined.minecraft {
fabric {
loader fabric_loader
}
defaultRemapJar = false
}
processResources {
def buildProps = project.properties.clone()
filesMatching(['pack.mcmeta']) {
expand buildProps
}
}
/**
* Publishing Config
*/
publishing {
publications {
mavenCommon(MavenPublication) {
artifactId project.archivesBaseName
from components.java
pom.withXml {
Node pomNode = asNode()
pomNode.dependencies.'*'.findAll() {
it.artifactId.text() == 'regutils-joined-fabric' ||
it.artifactId.text() == 'core' ||
it.artifactId.text() == 'toml'
}.each() {
it.parent().remove(it)
}
}
}
}
repositories {
maven rootProject.orion.getPublishingMaven()
}
}

View File

@@ -1,163 +0,0 @@
package com.hypherionmc.craterlib.api.commands;
import com.hypherionmc.craterlib.CraterConstants;
import com.hypherionmc.craterlib.compat.LuckPermsCompat;
import com.hypherionmc.craterlib.core.platform.LoaderType;
import com.hypherionmc.craterlib.core.platform.ModloaderEnvironment;
import com.hypherionmc.craterlib.nojang.authlib.BridgedGameProfile;
import com.hypherionmc.craterlib.nojang.commands.BridgedCommandSourceStack;
import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer;
import com.hypherionmc.craterlib.utils.TriConsumer;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.BoolArgumentType;
import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.commands.arguments.GameProfileArgument;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player;
import org.jetbrains.annotations.ApiStatus;
import java.util.List;
import java.util.function.Consumer;
public class CraterCommand {
private final LiteralArgumentBuilder<CommandSourceStack> mojangCommand;
private int permLevel = 4;
private String luckPermNode = "";
CraterCommand(LiteralArgumentBuilder<CommandSourceStack> cmd) {
this.mojangCommand = cmd;
}
public static CraterCommand literal(String commandName) {
return new CraterCommand(Commands.literal(commandName));
}
public CraterCommand requiresPermission(int perm) {
this.permLevel = perm;
this.mojangCommand.requires(this::checkPermission);
return this;
}
public CraterCommand withNode(String key) {
this.luckPermNode = key;
return this;
}
public CraterCommand then(CraterCommand child) {
this.mojangCommand.then(child.mojangCommand);
return this;
}
public CraterCommand withGameProfilesArgument(String key, CommandExecutorWithArgs<List<BridgedGameProfile>> executor) {
this.mojangCommand.then(Commands.argument(key, GameProfileArgument.gameProfile())
.executes(context -> executor.run(
BridgedPlayer.of(context.getSource().getPlayerOrException()),
GameProfileArgument.getGameProfiles(context, key).stream().map(BridgedGameProfile::of).toList(),
BridgedCommandSourceStack.of(context.getSource()))
));
return this;
}
public CraterCommand withBoolArgument(String key, CommandExecutorWithArgs<Boolean> executor) {
this.mojangCommand.then(Commands.argument(key, BoolArgumentType.bool())
.executes(context -> executor.run(
BridgedPlayer.of(context.getSource().getPlayerOrException()),
BoolArgumentType.getBool(context, key),
BridgedCommandSourceStack.of(context.getSource())
)));
return this;
}
public CraterCommand withWordArgument(String key, CommandExecutorWithArgs<String> executor) {
this.mojangCommand.then(Commands.argument(key, StringArgumentType.word())
.executes(context -> executor.run(
BridgedPlayer.of(context.getSource().getPlayerOrException()),
StringArgumentType.getString(context, key),
BridgedCommandSourceStack.of(context.getSource())
)));
return this;
}
public CraterCommand withStringArgument(String key, CommandExecutorWithArgs<String> executor) {
this.mojangCommand.then(Commands.argument(key, StringArgumentType.string())
.executes(context -> executor.run(
BridgedPlayer.of(context.getSource().getPlayerOrException()),
StringArgumentType.getString(context, key),
BridgedCommandSourceStack.of(context.getSource())
)));
return this;
}
public CraterCommand withPhraseArgument(String key, CommandExecutorWithArgs<String> executor) {
this.mojangCommand.then(Commands.argument(key, StringArgumentType.greedyString())
.executes(context -> executor.run(
BridgedPlayer.of(context.getSource().getPlayerOrException()),
StringArgumentType.getString(context, key),
BridgedCommandSourceStack.of(context.getSource())
)));
return this;
}
public CraterCommand withIntegerArgument(String key, CommandExecutorWithArgs<Integer> executor) {
this.mojangCommand.then(Commands.argument(key, IntegerArgumentType.integer())
.executes(context -> executor.run(
BridgedPlayer.of(context.getSource().getPlayerOrException()),
IntegerArgumentType.getInteger(context, key),
BridgedCommandSourceStack.of(context.getSource())
)));
return this;
}
public CraterCommand execute(SingleCommandExecutor<BridgedCommandSourceStack> executor) {
this.mojangCommand.executes(context -> executor.run(BridgedCommandSourceStack.of(context.getSource())));
return this;
}
@Deprecated(forRemoval = true)
public CraterCommand executes(Consumer<BridgedCommandSourceStack> ctx) {
return this.execute(stack -> {
ctx.accept(stack);
return 1;
});
}
@Deprecated(forRemoval = true)
public CraterCommand withGameProfileArgument(String key, TriConsumer<BridgedPlayer, List<BridgedGameProfile>, BridgedCommandSourceStack> executor) {
return this.withGameProfilesArgument(key, (player, argument, stack) -> {
executor.accept(player, argument, stack);
return 1;
});
}
@ApiStatus.Internal
public void register(CommandDispatcher<CommandSourceStack> stack) {
stack.register(this.mojangCommand);
}
private boolean checkPermission(CommandSourceStack stack) {
try {
if (!ModloaderEnvironment.INSTANCE.isModLoaded("luckperms") || ModloaderEnvironment.INSTANCE.getLoaderType() == LoaderType.PAPER || !(stack.getEntity() instanceof Player) || luckPermNode.isEmpty())
return stack.hasPermission(this.permLevel);
} catch (Exception e) {
CraterConstants.LOG.error("Failed to check luckperms permissions", e);
return stack.hasPermission(this.permLevel);
}
return LuckPermsCompat.INSTANCE.hasPermission((ServerPlayer) stack.getEntity(), this.luckPermNode) || stack.hasPermission(this.permLevel);
}
@FunctionalInterface
public interface CommandExecutorWithArgs<S> {
int run(BridgedPlayer player, S argument, BridgedCommandSourceStack stack);
}
@FunctionalInterface
public interface SingleCommandExecutor<S> {
int run(S stack);
}
}

View File

@@ -1,58 +0,0 @@
package com.hypherionmc.craterlib.api.events.server;
import com.hypherionmc.craterlib.core.event.CraterEvent;
import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer;
import com.hypherionmc.craterlib.utils.ChatUtils;
import com.mojang.brigadier.ParseResults;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.context.StringRange;
import lombok.Getter;
import lombok.Setter;
import net.kyori.adventure.text.Component;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.arguments.ComponentArgument;
import net.minecraft.world.entity.player.Player;
import org.jetbrains.annotations.Nullable;
@Getter
public class CraterCommandEvent extends CraterEvent {
private final ParseResults<CommandSourceStack> parseResults;
@Setter private Throwable exception;
private final String command;
private CraterCommandEvent(ParseResults<CommandSourceStack> parseResults, String command) {
this.parseResults = parseResults;
this.command = command;
}
public static CraterCommandEvent of(ParseResults<CommandSourceStack> stack, String command) {
return new CraterCommandEvent(stack, command);
}
public String getCommandString() {
return parseResults.getReader().getString();
}
@Nullable
public BridgedPlayer getPlayer() {
try {
Player p = parseResults.getContext().getLastChild().getSource().getPlayerOrException();
if (p != null)
return BridgedPlayer.of(p);
} catch (Exception ignored) {}
return null;
}
public String getTarget() {
CommandContext<CommandSourceStack> context = parseResults.getContext().build(parseResults.getReader().getString());
StringRange selector_range = parseResults.getContext().getArguments().get("targets").getRange();
return context.getInput().substring(selector_range.getStart(), selector_range.getEnd());
}
public Component getMessage() {
return ChatUtils.mojangToAdventure(ComponentArgument.getComponent(parseResults.getContext().build(parseResults.getReader().getString()), "message"));
}
}

View File

@@ -1,411 +0,0 @@
package com.hypherionmc.craterlib.client.gui.config;
import com.hypherionmc.craterlib.CraterConstants;
import com.hypherionmc.craterlib.client.gui.config.widgets.ClothConfigButtonEntry;
import com.hypherionmc.craterlib.core.config.AbstractConfig;
import com.hypherionmc.craterlib.core.config.annotations.HideFromScreen;
import com.hypherionmc.craterlib.core.config.annotations.SubConfig;
import com.hypherionmc.craterlib.core.config.annotations.Tooltip;
import me.hypherionmc.moonconfig.core.conversion.SpecComment;
import me.shedaniel.clothconfig2.api.ConfigBuilder;
import me.shedaniel.clothconfig2.api.ConfigCategory;
import me.shedaniel.clothconfig2.api.ConfigEntryBuilder;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.components.toasts.SystemToast;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TextComponent;
import net.minecraft.network.chat.TranslatableComponent;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.List;
/**
* @author HypherionSA
* A Helper Class to convert {@link AbstractConfig}s into Cloth Config Screens
*/
@SuppressWarnings({"rawtypes", "unchecked"})
@ApiStatus.Internal
public class ClothConfigScreenBuilder {
/**
* Build a new Cloth Config screen, from an {@link AbstractConfig}
*
* @param config The {@link AbstractConfig} the config screen is for
* @param parent The parent {@link Screen} this screen will return to when closed
* @return A fully usable Cloth Config screen
*/
public static Screen buildConfigScreen(AbstractConfig config, @Nullable Screen parent) {
ConfigBuilder builder = ConfigBuilder.create()
.setParentScreen(parent)
.setTitle(getTranslationKey(config, config, null));
readConfigFields(config, config, builder);
builder.setSavingRunnable(() -> safeSaveConfig(config));
return builder.build();
}
/**
* Build a new sub-screen for config entries marked with {@link SubConfig}
*
* @param config The {@link AbstractConfig} the config screen is for
* @param clazz The object or class that the screen is being built for
* @param parent The parent {@link Screen} this screen will return to when closed
* @return A fully usable Cloth Config screen
*/
private static Screen buildSubScreen(AbstractConfig config, Object clazz, @Nullable Screen parent) {
ConfigBuilder builder = ConfigBuilder.create()
.setParentScreen(parent)
.setTitle(getTranslationKey(config, clazz, null));
readConfigFields(config, clazz, builder);
builder.setSavingRunnable(() -> safeSaveConfig(config));
return builder.build();
}
/**
* Build a new screen, that allows editing lists of complex objects, like a list of Classes
*
* @param config The {@link AbstractConfig} the config screen is for
* @param list The list of objects this screen will be responsible for
* @param field The field this list belongs to in the main config
* @param invoker The object used to invoke the field, when setting the new value
* @param parent The parent {@link Screen} this screen will return to when closed
* @param edited Was this list edited
* @return A fully usable Cloth Config screen
*/
private static Screen buildListScreen(AbstractConfig config, List list, Field field, Object invoker, @Nullable Screen parent, boolean edited) {
ConfigBuilder builder = ConfigBuilder.create()
.setParentScreen(parent)
.setTitle(getTranslationKey(config, invoker, field.getName()));
ConfigCategory category = builder.getOrCreateCategory(new TextComponent("Entries"));
// Handle Existing items in the list
for (int i = 0; i < list.size(); i++) {
Object item = list.get(i);
int finalI = i;
// Add a button to open the edit screen, as well as a delete button
category.addEntry(
new ClothConfigButtonEntry(
new TranslatableComponent("cl.buttons.entry", (i + 1)),
new TranslatableComponent("cl.buttons.edit"),
button -> Minecraft.getInstance().setScreen(
buildSubScreen(config, item, builder.build())
),
button -> {
list.remove(finalI);
saveFieldValue(list, field, invoker);
Minecraft.getInstance().setScreen(buildListScreen(config, list, field, invoker, parent, true));
},
edited
)
);
}
// Add a button to add new list entries
Type listType = field.getGenericType();
if (listType instanceof ParameterizedType paramType) {
Class<?> elementType = (Class<?>) paramType.getActualTypeArguments()[0];
category.addEntry(
new ClothConfigButtonEntry(
new TextComponent(""),
new TranslatableComponent("cl.buttons.add_entry"),
button -> {
try {
Object newItem = elementType.getDeclaredConstructor().newInstance();
list.add(newItem);
saveFieldValue(list, field, invoker);
Minecraft.getInstance().setScreen(buildListScreen(config, list, field, invoker, parent, true));
} catch (Exception e) {
CraterConstants.LOG.error("Failed to create new list entry", e);
}
}
)
);
}
builder.setSavingRunnable(() -> safeSaveConfig(config));
return builder.build();
}
/**
* A helper method to convert an {@link AbstractConfig} into the corresponding cloth config gui fields
*
* @param baseConfig The {@link AbstractConfig} to convert
* @param config The base class that is being processed
* @param builder The {@link ClothConfigScreenBuilder} we are currently working with
*/
private static void readConfigFields(AbstractConfig baseConfig, Object config, ConfigBuilder builder) {
ConfigEntryBuilder entryBuilder = builder.entryBuilder();
ConfigCategory configCategory = builder.getOrCreateCategory(new TextComponent("General"));
for (Field field : config.getClass().getDeclaredFields()) {
try {
field.setAccessible(true);
// We ignore static, transient fields or fields marked with @HideFromScreen
final int fieldModifiers = field.getModifiers();
if (Modifier.isStatic(fieldModifiers) || Modifier.isTransient(fieldModifiers) || field.isAnnotationPresent(HideFromScreen.class))
continue;
Object val = field.get(config);
// Field is marked as sub-config, so we add a button field for it
if (field.isAnnotationPresent(SubConfig.class)) {
if (val != null) {
configCategory.addEntry(
new ClothConfigButtonEntry(
new TranslatableComponent("cl.config." + baseConfig.getClass().getSimpleName().toLowerCase() + "." + field.getName().toLowerCase()),
new TranslatableComponent("cl.buttons.edit"),
button -> Minecraft.getInstance().setScreen(
buildSubScreen(baseConfig, val, builder.build())
)
)
);
continue;
}
}
// Boolean Values
if (val instanceof Boolean bool) {
configCategory.addEntry(entryBuilder.startBooleanToggle(getTranslationKey(baseConfig, config, field.getName()), bool)
.setTooltip(getToolTip(field))
.setSaveConsumer(newValue -> saveFieldValue(newValue, field, config))
.setDefaultValue(bool).build());
}
// Enum Values
if (val instanceof Enum<?> enumValue) {
Class<Enum> enumClass = (Class<Enum>)enumValue.getDeclaringClass();
configCategory.addEntry(entryBuilder.startEnumSelector(
getTranslationKey(baseConfig, config, field.getName()),
enumClass,
enumValue)
.setTooltip(getToolTip(field))
.setSaveConsumer(newValue -> saveFieldValue(newValue, field, config))
.setDefaultValue(enumValue)
.build());
}
// Int Values
if (val instanceof Integer intt) {
configCategory.addEntry(entryBuilder.startIntField(getTranslationKey(baseConfig, config, field.getName()), intt)
.setTooltip(getToolTip(field))
.setSaveConsumer(newValue -> saveFieldValue(newValue, field, config))
.setDefaultValue(intt).build());
}
// Long Values
if (val instanceof Long longt) {
configCategory.addEntry(entryBuilder.startLongField(getTranslationKey(baseConfig, config, field.getName()), longt)
.setTooltip(getToolTip(field))
.setSaveConsumer(newValue -> saveFieldValue(newValue, field, config))
.setDefaultValue(longt).build());
}
// Float Values
if (val instanceof Float floatt) {
configCategory.addEntry(entryBuilder.startFloatField(getTranslationKey(baseConfig, config, field.getName()), floatt)
.setTooltip(getToolTip(field))
.setSaveConsumer(newValue -> saveFieldValue(newValue, field, config))
.setDefaultValue(floatt).build());
}
// Double Values
if (val instanceof Double doublet) {
configCategory.addEntry(entryBuilder.startDoubleField(getTranslationKey(baseConfig, config, field.getName()), doublet)
.setTooltip(getToolTip(field))
.setSaveConsumer(newValue -> saveFieldValue(newValue, field, config))
.setDefaultValue(doublet).build());
}
// String Values
if (val instanceof String string) {
configCategory.addEntry(entryBuilder.startStrField(getTranslationKey(baseConfig, config, field.getName()), string)
.setTooltip(getToolTip(field))
.setSaveConsumer(newValue -> saveFieldValue(newValue, field, config))
.setDefaultValue(string).build());
}
// Lists
if (val instanceof List<?> list) {
Type listType = field.getGenericType();
if (listType instanceof ParameterizedType paramType) {
Type elementType = paramType.getActualTypeArguments()[0];
// String List
if (elementType.equals(String.class)) {
configCategory.addEntry(entryBuilder.startStrList(getTranslationKey(baseConfig, config, field.getName()), (List<String>) list)
.setTooltip(getToolTip(field))
.setSaveConsumer(newValue -> saveFieldValue(new ArrayList<>(newValue), field, config))
.setDefaultValue((List<String>) list).build());
// Int List
} else if (elementType.equals(Integer.class)) {
configCategory.addEntry(entryBuilder.startIntList(getTranslationKey(baseConfig, config, field.getName()), (List<Integer>) list)
.setTooltip(getToolTip(field))
.setSaveConsumer(newValue -> saveFieldValue(new ArrayList<>(newValue), field, config))
.setDefaultValue((List<Integer>) list).build());
// Long List
} else if (elementType.equals(Long.class)) {
configCategory.addEntry(entryBuilder.startLongList(getTranslationKey(baseConfig, config, field.getName()), (List<Long>) list)
.setTooltip(getToolTip(field))
.setSaveConsumer(newValue -> saveFieldValue(new ArrayList<>(newValue), field, config))
.setDefaultValue((List<Long>) list).build());
// Float List
} else if (elementType.equals(Float.class)) {
configCategory.addEntry(entryBuilder.startFloatList(getTranslationKey(baseConfig, config, field.getName()), (List<Float>) list)
.setTooltip(getToolTip(field))
.setSaveConsumer(newValue -> saveFieldValue(new ArrayList<>(newValue), field, config))
.setDefaultValue((List<Float>) list).build());
// Double List
} else if (elementType.equals(Double.class)) {
configCategory.addEntry(entryBuilder.startDoubleList(getTranslationKey(baseConfig, config, field.getName()), (List<Double>) list)
.setTooltip(getToolTip(field))
.setSaveConsumer(newValue -> saveFieldValue(new ArrayList<>(newValue), field, config))
.setDefaultValue((List<Double>) list).build());
} else {
// List of complex objects
configCategory.addEntry(
new ClothConfigButtonEntry(
getTranslationKey(baseConfig, config, field.getName()),
new TranslatableComponent("cl.buttons.edit"),
button -> Minecraft.getInstance().setScreen(
buildListScreen(baseConfig, list, field, config, builder.build(), false)
)
)
);
}
}
}
} catch (Exception e) {
CraterConstants.LOG.error("Failed to process config file {}", baseConfig.getConfigName(), e);
}
}
}
/**
* Helper method to supply tooltips to config fields.
* If the field has an {@link SpecComment}, we use that, otherwise we use the {@link Tooltip} annotation
* or generate one from the field name
*
* @param field The field that is being processed
* @return A {@link Component} that can be used for the tooltip
*/
private static Component getToolTip(Field field) {
Component component = new TextComponent("");
if (field.isAnnotationPresent(SpecComment.class)) {
SpecComment comment = field.getAnnotation(SpecComment.class);
component = new TextComponent(comment.value());
}
if (field.isAnnotationPresent(Tooltip.class)) {
Tooltip tooltip = field.getAnnotation(Tooltip.class);
Component c = new TextComponent("");
for (String comment : tooltip.value()) {
c.getSiblings().add(new TextComponent(comment));
}
component = c;
}
return component;
}
/**
* A helper method to build translation keys for config screens, fields etc
*
* @param baseConfig The {@link AbstractConfig} being processed
* @param currentConfig The field being processed
* @param fieldName The raw name of the field
* @return A {@link Component} with the new translation key
*/
private static Component getTranslationKey(AbstractConfig baseConfig, Object currentConfig, String fieldName) {
String baseKey = "cl.config." + baseConfig.getClass().getSimpleName().toLowerCase();
if (currentConfig != baseConfig) {
baseKey += "." + currentConfig.getClass().getSimpleName().toLowerCase();
}
if (fieldName != null) {
baseKey += "." + fieldName.toLowerCase();
}
return new TranslatableComponent(baseKey);
}
/**
* Helper method to write changes values back to the config using reflection
*
* @param value The new value of the field
* @param field The field that needs to be updated
* @param config The object used to invoke the field for updating
*/
private static void saveFieldValue(Object value, Field field, Object config) {
try {
if (value instanceof List && !field.getType().equals(List.class)) {
List newList = (List)field.getType().getDeclaredConstructor().newInstance();
newList.addAll((List)value);
field.set(config, newList);
} else {
field.set(config, value);
}
} catch (Exception e) {
CraterConstants.LOG.error("Failed to write config field {}", field.getName(), e);
}
}
/**
* Safety method to prevent config screens from corrupting configs. In some edge cases, the config gui
* can generate invalid values, that cause the config saving to fail, and then save an empty file.
* This method makes a backup of the config before writing to it, and restores the backup if it fails
*
* @param config The {@link AbstractConfig} being saved
*/
private static void safeSaveConfig(AbstractConfig config) {
File configPath = config.getConfigPath();
Path backupPath = configPath.toPath().resolveSibling(configPath.getName() + ".bak");
try {
Files.copy(configPath.toPath(), backupPath, StandardCopyOption.REPLACE_EXISTING);
config.saveConfig(config);
Files.deleteIfExists(backupPath);
} catch (Exception e) {
Minecraft.getInstance().getToasts().addToast(
new SystemToast(
SystemToast.SystemToastIds.PACK_LOAD_FAILURE,
new TextComponent("Failed To Save Config"),
new TextComponent("Restoring Backup Copy. Check log for details"))
);
CraterConstants.LOG.error("Failed to save config, restoring backup", e);
try {
Files.copy(backupPath, configPath.toPath(), StandardCopyOption.REPLACE_EXISTING);
config.configReloaded();
} catch (Exception restoreError) {
CraterConstants.LOG.error("Failed to restore config backup", restoreError);
}
}
}
}

View File

@@ -1,395 +0,0 @@
package com.hypherionmc.craterlib.client.gui.config;
import com.hypherionmc.craterlib.CraterConstants;
import com.hypherionmc.craterlib.client.gui.config.widgets.*;
import com.hypherionmc.craterlib.core.config.AbstractConfig;
import com.hypherionmc.craterlib.core.config.annotations.HideFromScreen;
import com.hypherionmc.craterlib.core.config.annotations.SubConfig;
import com.hypherionmc.craterlib.core.config.annotations.Tooltip;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.*;
import com.mojang.math.Matrix4f;
import me.hypherionmc.moonconfig.core.conversion.SpecComment;
import net.minecraft.ChatFormatting;
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.screens.ConfirmScreen;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TextComponent;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.Mth;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
/**
* @author HypherionSA
*/
@Deprecated(forRemoval = true, since = "2.1.3")
public class CraterConfigScreen extends Screen {
public static final float SCROLLBAR_BOTTOM_COLOR = .5f;
public static final float SCROLLBAR_TOP_COLOR = .67f;
private static final int TOP = 26;
private static final int BOTTOM = 24;
private final Screen parent;
private final List<Option<?>> options = new ArrayList<>();
private final AbstractConfig config;
public double scrollerAmount;
private boolean dragging;
public CraterConfigScreen(AbstractConfig config, Screen parent, Object subConfig) {
super(new TranslatableComponent("cl." + config.getClass().getSimpleName().toLowerCase() + ".title"));
this.parent = parent;
this.config = config;
if (subConfig != null) {
setupScreenFromConfig(subConfig, subConfig.getClass());
} else {
setupScreenFromConfig(config, config.getClass());
}
}
public CraterConfigScreen(AbstractConfig config, Screen parent) {
this(config, parent, null);
}
private static Component toText(Enum<?> val) {
return new TranslatableComponent(val.toString());
}
private static Component toText(Boolean bool) {
return new TranslatableComponent(bool.toString());
}
private void setupScreenFromConfig(Object object, Class<?> clazz) {
while (clazz != Object.class) {
for (Field field : clazz.getDeclaredFields()) {
final int fieldModifiers = field.getModifiers();
if (object == null || Modifier.isStatic(fieldModifiers) || Modifier.isTransient(fieldModifiers)) {
continue;
}
try {
if (!field.isAccessible()) {
field.setAccessible(true);
}
if (field.isAnnotationPresent(HideFromScreen.class))
return;
Object val = field.get(object);
/* Lang Stuff */
String baseLangKey = "cl." + clazz.getSimpleName().toLowerCase() + "." + field.getName().toLowerCase();
String[] tooltipLang = field.isAnnotationPresent(SpecComment.class) ? new String[]{field.getAnnotation(SpecComment.class).value()} : new String[0];
if (field.isAnnotationPresent(Tooltip.class)) {
tooltipLang = field.getAnnotation(Tooltip.class).value();
}
add(new TranslatableComponent(baseLangKey),
val,
() -> val,
(ret) -> {
try {
field.set(object, ret);
config.saveConfig(config);
} catch (IllegalAccessException e) {
CraterConstants.LOG.error("Failed to update value for field {} in config {}", field.getName(), config.getConfigName(), e);
}
},
field.isAnnotationPresent(SubConfig.class),
tooltipLang
);
} catch (IllegalAccessException e) {
CraterConstants.LOG.error("Failed to access value for field {} in config {}", field.getName(), config.getConfigName(), e);
}
}
clazz = clazz.getSuperclass();
}
}
public <T> void add(Component text, T value, @Nullable Supplier<T> defaultValue, Consumer<T> savingConsumer, boolean isSubConfig, String... langKeys) {
Option<T> option = (Option<T>) createOption(value, isSubConfig);
option.text = text;
option.defaultValue = defaultValue;
option.savingConsumer = savingConsumer;
option.originalValue = value;
option.value = value;
option.setLangKeys(List.of(langKeys));
options.add(option);
option.onAdd();
}
private <T> Option<?> createOption(T value, boolean isSubConfig) {
if (value instanceof Enum) {
Object[] objects = value.getClass().getEnumConstants();
return new ToggleButton<Enum<?>>((List) Arrays.asList(objects), CraterConfigScreen::toText);
}
if (value instanceof Boolean) {
return new ToggleButton<>(Arrays.asList(Boolean.TRUE, Boolean.FALSE), CraterConfigScreen::toText);
}
if (value instanceof String) {
return new TextConfigOption<>(Function.identity(), Function.identity());
}
if (value instanceof Integer) {
return new TextConfigOption<>(Objects::toString, Integer::valueOf);
}
if (value instanceof Long) {
return new TextConfigOption<>(Objects::toString, Long::valueOf);
}
if (value instanceof Double) {
return new TextConfigOption<>(Objects::toString, Double::valueOf);
}
if (value instanceof Float) {
return new TextConfigOption<>(Objects::toString, Float::valueOf);
}
if (value instanceof BigInteger) {
return new TextConfigOption<>(Objects::toString, BigInteger::new);
}
if (value instanceof BigDecimal) {
return new TextConfigOption<>(Objects::toString, BigDecimal::new);
}
if (value instanceof ResourceLocation) {
return new TextConfigOption<>(Objects::toString, ResourceLocation::new);
}
if (isSubConfig) {
return new SubConfigWidget<>(config, this, value);
}
throw new IllegalArgumentException(String.valueOf(value));
}
@Override
protected void init() {
super.init();
((List) children()).addAll(options);
int buttonWidths = Math.min(200, (width - 50 - 12) / 3);
addRenderableWidget(new InternalConfigButton(this, width / 2 - buttonWidths - 3, height - 22, buttonWidths, 20, new TextComponent(""), true));
addRenderableWidget(new InternalConfigButton(this, width / 2 + 3, height - 22, buttonWidths, 20, new TextComponent(""), false));
}
@Override
public void render(@NotNull PoseStack matrices, int mouseX, int mouseY, float delta) {
overlayBackground(matrices, TOP, height - BOTTOM, 32);
renderScrollBar();
matrices.pushPose();
matrices.translate(0, 0, 500.0);
overlayBackground(matrices, 0, TOP, 64);
overlayBackground(matrices, height - BOTTOM, height, 64);
renderShadow(matrices);
drawCenteredString(matrices, font, getTitle(), width / 2, 9, 0xFFFFFF);
super.render(matrices, mouseX, mouseY, delta);
matrices.popPose();
int y = (int) (TOP + 4 - Math.round(scrollerAmount));
for (Option<?> option : options) {
int height1 = option.height();
option.render(minecraft, font, 40, y, width - 80, height1, matrices, mouseX, mouseY, delta);
renderConfigTooltip(matrices, font, mouseX, mouseY, 40, y, font.width(option.text), height1, option.text.getString(), option.getLangKeys().toArray(new String[0]));
y += height1;
}
}
private void renderScrollBar() {
int listHeight = height - BOTTOM - TOP;
int totalHeight = totalHeight();
if (totalHeight > listHeight) {
int maxScroll = Math.max(0, totalHeight - listHeight);
int height = listHeight * listHeight / totalHeight;
height = Mth.clamp(height, 32, listHeight);
height = Math.max(10, height);
int minY = Math.min(Math.max((int) scrollerAmount * (listHeight - height) / maxScroll + TOP, TOP), this.height - BOTTOM - height);
int scrollbarPositionMaxX = width;
int scrollbarPositionMinX = scrollbarPositionMaxX - 6;
int maxY = this.height - BOTTOM;
//RenderSystem.disableTexture();
Tesselator tesselator = Tesselator.getInstance();
BufferBuilder buffer = tesselator.getBuilder();
RenderSystem.setShader(GameRenderer::getPositionColorShader);
buffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR);
buffer.vertex(scrollbarPositionMinX, maxY, 0.0D).color(0, 0, 0, 255).endVertex();
buffer.vertex(scrollbarPositionMaxX, maxY, 0.0D).color(0, 0, 0, 255).endVertex();
buffer.vertex(scrollbarPositionMaxX, TOP, 0.0D).color(0, 0, 0, 255).endVertex();
buffer.vertex(scrollbarPositionMinX, TOP, 0.0D).color(0, 0, 0, 255).endVertex();
buffer.vertex(scrollbarPositionMinX, minY + height, 0.0D).color(SCROLLBAR_BOTTOM_COLOR, SCROLLBAR_BOTTOM_COLOR, SCROLLBAR_BOTTOM_COLOR, 1).endVertex();
buffer.vertex(scrollbarPositionMaxX, minY + height, 0.0D).color(SCROLLBAR_BOTTOM_COLOR, SCROLLBAR_BOTTOM_COLOR, SCROLLBAR_BOTTOM_COLOR, 1).endVertex();
buffer.vertex(scrollbarPositionMaxX, minY, 0.0D).color(SCROLLBAR_BOTTOM_COLOR, SCROLLBAR_BOTTOM_COLOR, SCROLLBAR_BOTTOM_COLOR, 1).endVertex();
buffer.vertex(scrollbarPositionMinX, minY, 0.0D).color(SCROLLBAR_BOTTOM_COLOR, SCROLLBAR_BOTTOM_COLOR, SCROLLBAR_BOTTOM_COLOR, 1).endVertex();
buffer.vertex(scrollbarPositionMinX, (minY + height - 1), 0.0D).color(SCROLLBAR_TOP_COLOR, SCROLLBAR_TOP_COLOR, SCROLLBAR_TOP_COLOR, 1).endVertex();
buffer.vertex((scrollbarPositionMaxX - 1), (minY + height - 1), 0.0D).color(SCROLLBAR_TOP_COLOR, SCROLLBAR_TOP_COLOR, SCROLLBAR_TOP_COLOR, 1).endVertex();
buffer.vertex((scrollbarPositionMaxX - 1), minY, 0.0D).color(SCROLLBAR_TOP_COLOR, SCROLLBAR_TOP_COLOR, SCROLLBAR_TOP_COLOR, 1).endVertex();
buffer.vertex(scrollbarPositionMinX, minY, 0.0D).color(SCROLLBAR_TOP_COLOR, SCROLLBAR_TOP_COLOR, SCROLLBAR_TOP_COLOR, 1).endVertex();
tesselator.end();
RenderSystem.disableBlend();
//RenderSystem.enableTexture();
}
}
private void renderShadow(PoseStack matrices) {
Tesselator tesselator = Tesselator.getInstance();
BufferBuilder buffer = tesselator.getBuilder();
RenderSystem.enableBlend();
RenderSystem.blendFuncSeparate(770, 771, 0, 1);
//RenderSystem.disableTexture();
RenderSystem.setShader(GameRenderer::getPositionTexColorShader);
Matrix4f matrix = matrices.last().pose();
buffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX_COLOR);
buffer.vertex(matrix, 0, TOP + 4, 0.0F).uv(0, 1).color(0, 0, 0, 0).endVertex();
buffer.vertex(matrix, width, TOP + 4, 0.0F).uv(1, 1).color(0, 0, 0, 0).endVertex();
buffer.vertex(matrix, width, TOP, 0.0F).uv(1, 0).color(0, 0, 0, 185).endVertex();
buffer.vertex(matrix, 0, TOP, 0.0F).uv(0, 0).color(0, 0, 0, 185).endVertex();
buffer.vertex(matrix, 0, height - BOTTOM, 0.0F).uv(0, 1).color(0, 0, 0, 185).endVertex();
buffer.vertex(matrix, width, height - BOTTOM, 0.0F).uv(1, 1).color(0, 0, 0, 185).endVertex();
buffer.vertex(matrix, width, height - BOTTOM - 4, 0.0F).uv(1, 0).color(0, 0, 0, 0).endVertex();
buffer.vertex(matrix, 0, height - BOTTOM - 4, 0.0F).uv(0, 0).color(0, 0, 0, 0).endVertex();
tesselator.end();
//RenderSystem.enableTexture();
RenderSystem.disableBlend();
}
protected void overlayBackground(PoseStack matrices, int h1, int h2, int color) {
overlayBackground(matrices.last().pose(), 0, h1, width, h2, color, color, color, 255, 255);
}
protected void overlayBackground(Matrix4f matrix, int minX, int minY, int maxX, int maxY, int red, int green, int blue, int startAlpha, int endAlpha) {
Tesselator tesselator = Tesselator.getInstance();
BufferBuilder buffer = tesselator.getBuilder();
RenderSystem.setShaderTexture(0, Screen.BACKGROUND_LOCATION);
RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f);
RenderSystem.setShader(GameRenderer::getPositionTexColorShader);
buffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX_COLOR);
buffer.vertex(matrix, minX, maxY, 0.0F).uv(minX / 32.0F, maxY / 32.0F).color(red, green, blue, endAlpha).endVertex();
buffer.vertex(matrix, maxX, maxY, 0.0F).uv(maxX / 32.0F, maxY / 32.0F).color(red, green, blue, endAlpha).endVertex();
buffer.vertex(matrix, maxX, minY, 0.0F).uv(maxX / 32.0F, minY / 32.0F).color(red, green, blue, startAlpha).endVertex();
buffer.vertex(matrix, minX, minY, 0.0F).uv(minX / 32.0F, minY / 32.0F).color(red, green, blue, startAlpha).endVertex();
tesselator.end();
}
public int scrollHeight() {
int totalHeight = totalHeight();
int listHeight = height - BOTTOM - TOP;
if (totalHeight <= listHeight) {
return 0;
}
return totalHeight - listHeight;
}
public int totalHeight() {
int i = 8;
for (Option<?> option : options) {
i += option.height();
}
return i;
}
public boolean hasErrors() {
for (Option<?> option : options) {
if (option.hasErrors) {
return true;
}
}
return false;
}
public boolean isEdited() {
for (Option<?> option : options) {
if (option.isEdited()) {
return true;
}
}
return false;
}
public void save() {
for (Option option : options) {
option.save();
option.originalValue = option.value;
}
}
@Override
public void onClose() {
if (isEdited()) {
minecraft.setScreen(new ConfirmScreen(this::acceptConfirm, new TranslatableComponent("t.clc.quit_config"),
new TranslatableComponent("t.clc.quit_config_sure"),
new TranslatableComponent("t.clc.quit_discard"),
new TranslatableComponent("gui.cancel")));
} else {
minecraft.setScreen(parent);
}
}
@Override
public boolean mouseScrolled(double d, double e, double f) {
if (e >= TOP && e <= height - BOTTOM) {
scrollerAmount = Mth.clamp(scrollerAmount - f * 16.0D, 0, scrollHeight());
return true;
}
return super.mouseScrolled(d, e, f);
}
@Override
public boolean mouseClicked(double d, double e, int i) {
this.dragging = i == 0 && d >= width - 6 && d < width;
return super.mouseClicked(d, e, i) || dragging;
}
@Override
public boolean mouseDragged(double d, double e, int i, double f, double g) {
if (super.mouseDragged(d, e, i, f, g)) {
return true;
}
if (i != 0 || !this.dragging) {
return false;
}
if (e < TOP) {
scrollerAmount = 0;
} else if (e > height - BOTTOM) {
scrollerAmount = scrollHeight();
} else {
double h = Math.max(1, this.scrollHeight());
int j = height - BOTTOM - TOP;
int k = Mth.clamp((int) ((float) (j * j) / (float) this.scrollHeight()), 32, j - 8);
double l = Math.max(1.0, h / (double) (j - k));
scrollerAmount = Mth.clamp(scrollerAmount + g * l, 0, scrollHeight());
}
return true;
}
private void acceptConfirm(boolean t) {
if (!t) {
minecraft.setScreen(this);
} else {
minecraft.setScreen(parent);
}
}
private void renderConfigTooltip(PoseStack stack, Font font, int mouseX, int mouseY, int startX, int startY, int sizeX, int sizeY, String title, String... description) {
if (mouseX > startX && mouseX < startX + sizeX) {
if (mouseY > startY && mouseY < startY + sizeY) {
List<Component> list = new ArrayList<>();
list.add(new TranslatableComponent(ChatFormatting.BOLD + "" + ChatFormatting.YELLOW + title));
for (String desc : description) {
list.add(new TranslatableComponent(desc));
}
renderComponentTooltip(stack, list, mouseX, mouseY);
}
}
}
}

View File

@@ -1,28 +0,0 @@
package com.hypherionmc.craterlib.client.gui.config.widgets;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.components.AbstractWidget;
import net.minecraft.client.gui.components.EditBox;
/**
* Copied from Cloth Config Lite
* <a href="https://github.com/shedaniel/cloth-config-lite/blob/1.17/src/main/java/me/shedaniel/clothconfiglite/impl/option/AbstractWidgetOption.java">...</a>
*/
@Deprecated(forRemoval = true, since = "2.1.3")
public class AbstractConfigWidget<T, W extends AbstractWidget> extends BaseWidget<T> {
public static final int buttonWidth = 200;
public static final int buttonHeight = 20;
public W widget;
@Override
public void render(Minecraft minecraft, Font font, int x, int y, int width, int height, PoseStack matrices, int mouseX, int mouseY, float delta) {
super.render(minecraft, font, x, y, width, height, matrices, mouseX, mouseY, delta);
int i = (widget instanceof EditBox ? 1 : 0);
widget.x = (x + width - 200 - resetButtonOffset + i);
widget.y = (y + i + 1);
widget.render(matrices, mouseX, mouseY, delta);
}
}

View File

@@ -1,62 +0,0 @@
package com.hypherionmc.craterlib.client.gui.config.widgets;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.ChatFormatting;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.components.Button;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.network.chat.TextColor;
import net.minecraft.network.chat.TextComponent;
/**
* Copied from Cloth Config Lite
* <a href="https://github.com/shedaniel/cloth-config-lite/blob/1.17/src/main/java/me/shedaniel/clothconfiglite/impl/option/BaseOption.java">...</a>
*/
@Deprecated(forRemoval = true, since = "2.1.3")
public class BaseWidget<T> extends Option<T> {
public static final int resetButtonOffset = 48;
private final Button resetButton = addChild(new Button(0, 0, 46, 20, new TextComponent("Reset"), this::onResetPressed));
private boolean hideReset = false;
private boolean isSubConfig = false;
private void onResetPressed(Button button) {
value = defaultValue.get();
reset();
}
public void hideReset() {
this.hideReset = true;
}
public boolean isSubConfig() {
return isSubConfig;
}
public void setSubConfig(boolean subConfig) {
isSubConfig = subConfig;
}
@Override
public void render(Minecraft minecraft, Font font, int x, int y, int width, int height, PoseStack matrices, int mouseX, int mouseY, float delta) {
MutableComponent text = new TextComponent(this.text.getString());
boolean edited = isEdited() || hasErrors;
if (edited) {
text.withStyle(ChatFormatting.ITALIC);
if (hasErrors) {
text.withStyle(style -> style.withColor(TextColor.fromRgb(16733525)));
}
} else {
text.withStyle(ChatFormatting.GRAY);
}
font.draw(matrices, text, x, y, 0xFFFFFF);
resetButton.x = (x + width - 46);
resetButton.y = (y + 1);
resetButton.active = isNotDefault();
if (!hideReset) {
resetButton.render(matrices, mouseX, mouseY, delta);
}
}
}

View File

@@ -1,129 +0,0 @@
package com.hypherionmc.craterlib.client.gui.config.widgets;
import com.mojang.blaze3d.platform.Window;
import com.mojang.blaze3d.vertex.PoseStack;
import me.shedaniel.clothconfig2.api.AbstractConfigListEntry;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.components.events.GuiEventListener;
import net.minecraft.client.gui.narration.NarratableEntry;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TextComponent;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
/**
* @author HypherionSA
* A Custom Cloth Config GUI entry to allow buttons to be added to the GUI
*/
public class ClothConfigButtonEntry extends AbstractConfigListEntry<Void> {
private final Button button;
private final Button deleteButton;
private final Component displayName;
private final boolean hasDeleteButton;
private final boolean wasEdited;
/**
* Create a new Cloth Button Entry, that will have no delete button
*
* @param displayName The Display Name that will be used for the field
* @param fieldName The Display Name that will be used on the button
* @param onPress The Action to perform when the button was pressed
*/
public ClothConfigButtonEntry(Component displayName, Component fieldName, @Nullable Button.OnPress onPress) {
this(displayName, fieldName, onPress, null, false);
}
/***
* Create a new Cloth Button Entry, with optional delete button
*
* @param displayName The Display Name that will be used for the field
* @param fieldName The Display Name that will be used on the button
* @param onPress The Action to perform when the button was pressed
* @param deletePress The Action to perform when the delete button is pressed. If this is null, the button is disabled
* @param wasEdited Was a change made to the field this button belongs to. This is to tell cloth to enable the save button
*/
public ClothConfigButtonEntry(Component displayName, Component fieldName, Button.OnPress onPress, @Nullable Button.OnPress deletePress, boolean wasEdited) {
super(fieldName, false);
this.hasDeleteButton = deletePress != null;
this.wasEdited = wasEdited;
int mainButtonWidth = hasDeleteButton ? 75 : 100;
this.button = new Button(0, 0, mainButtonWidth, 20, fieldName, onPress);
this.deleteButton = deletePress != null ? new Button(0, 0, 20, 20, new TextComponent("X"), deletePress) : null;
this.displayName = displayName;
}
@Override
public void render(PoseStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isHovered, float delta) {
Window window = Minecraft.getInstance().getWindow();
Component displayedFieldName = displayName;
if (Minecraft.getInstance().font.isBidirectional()) {
drawString(matrices, Minecraft.getInstance().font, displayedFieldName.getVisualOrderText(), window.getGuiScaledWidth() - x - Minecraft.getInstance().font.width(displayedFieldName), y + 6, 16777215);
this.button.x = x;
if (hasDeleteButton) {
this.deleteButton.x = x + this.button.getWidth() + 4;
}
} else {
drawString(matrices, Minecraft.getInstance().font, displayedFieldName.getVisualOrderText(), x, y + 6, this.getPreferredTextColor());
if (hasDeleteButton) {
this.button.x = x + entryWidth - this.button.getWidth() - 24;
this.deleteButton.x = x + entryWidth - 20;
} else {
this.button.x = x + entryWidth - this.button.getWidth();
}
}
button.y = y + (entryHeight - 20) / 2;
button.render(matrices, mouseX, mouseY, delta);
if (hasDeleteButton) {
deleteButton.y = y + (entryHeight - 20) / 2;
deleteButton.render(matrices, mouseX, mouseY, delta);
}
}
@Override
public Void getValue() { return null; }
@Override
public Optional<Void> getDefaultValue() { return Optional.empty(); }
@Override
public void save() {}
@NotNull
@Override
public List<? extends GuiEventListener> children() {
ArrayList<GuiEventListener> children = new ArrayList<>();
children.add(button);
if (hasDeleteButton) {
children.add(deleteButton);
}
return children;
}
@Override
public List<? extends NarratableEntry> narratables() {
ArrayList<NarratableEntry> children = new ArrayList<>();
children.add(button);
if (hasDeleteButton) {
children.add(deleteButton);
}
return children;
}
@Override
public boolean isEdited() {
return wasEdited;
}
}

View File

@@ -1,54 +0,0 @@
package com.hypherionmc.craterlib.client.gui.config.widgets;
import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.gui.components.AbstractButton;
import net.minecraft.client.gui.narration.NarratedElementType;
import net.minecraft.client.gui.narration.NarrationElementOutput;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TranslatableComponent;
import org.jetbrains.annotations.NotNull;
/**
* @author HypherionSA
*/
@Deprecated(forRemoval = true, since = "2.1.3")
public class InternalConfigButton extends AbstractButton {
CraterConfigScreen screen;
boolean cancel;
public InternalConfigButton(CraterConfigScreen screen, int i, int j, int k, int l, Component component, boolean cancel) {
super(i, j, k, l, component);
this.screen = screen;
this.cancel = cancel;
}
@Override
public void render(@NotNull PoseStack poseStack, int i, int j, float f) {
if (cancel) {
setMessage(new TranslatableComponent(screen.isEdited() ? "t.clc.cancel_discard" : "gui.cancel"));
} else {
boolean hasErrors = screen.hasErrors();
active = screen.isEdited() && !hasErrors;
setMessage(new TranslatableComponent(hasErrors ? "t.clc.error" : "t.clc.save"));
}
super.render(poseStack, i, j, f);
}
@Override
public void updateNarration(NarrationElementOutput narrationElementOutput) {
narrationElementOutput.add(NarratedElementType.USAGE, getMessage());
}
@Override
public void onPress() {
if (cancel) {
screen.onClose();
} else {
screen.save();
}
}
}

View File

@@ -1,72 +0,0 @@
package com.hypherionmc.craterlib.client.gui.config.widgets;
import com.mojang.blaze3d.vertex.PoseStack;
import lombok.Getter;
import lombok.Setter;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.components.events.AbstractContainerEventHandler;
import net.minecraft.client.gui.components.events.GuiEventListener;
import net.minecraft.network.chat.Component;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Supplier;
/**
* Copied from Cloth Config Lite
* <a href="https://github.com/shedaniel/cloth-config-lite/blob/1.17/src/main/java/me/shedaniel/clothconfiglite/impl/option/Option.java">...</a>
*/
@Deprecated(forRemoval = true, since = "2.1.3")
public abstract class Option<T> extends AbstractContainerEventHandler {
public Component text;
@Nullable
public Supplier<T> defaultValue;
public Consumer<T> savingConsumer;
public T originalValue;
public T value;
public boolean hasErrors;
public List<? extends GuiEventListener> children = new ArrayList<>();
@Setter
@Getter
private List<String> langKeys = new ArrayList<>();
public abstract void render(Minecraft minecraft, Font font, int x, int y, int width, int height, PoseStack matrices, int mouseX, int mouseY, float delta);
public int height() {
return 22;
}
@Override
public List<? extends GuiEventListener> children() {
return children;
}
protected <R extends GuiEventListener> R addChild(R listener) {
((List) children).add(listener);
return listener;
}
public void onAdd() {
}
protected void reset() {
onAdd();
}
public boolean isEdited() {
return !Objects.equals(originalValue, value);
}
protected boolean isNotDefault() {
return defaultValue != null && !Objects.equals(defaultValue.get(), value);
}
public void save() {
savingConsumer.accept(value);
}
}

View File

@@ -1,41 +0,0 @@
package com.hypherionmc.craterlib.client.gui.config.widgets;
import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen;
import com.hypherionmc.craterlib.core.config.AbstractConfig;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.TranslatableComponent;
/**
* @author HypherionSA
*/
@Deprecated(forRemoval = true, since = "2.1.3")
public class SubConfigWidget<T> extends AbstractConfigWidget<T, Button> {
private final Object subConfig;
private final AbstractConfig config;
private final Screen screen;
public SubConfigWidget(AbstractConfig config, Screen screen, Object subConfig) {
this.config = config;
this.subConfig = subConfig;
this.screen = screen;
this.widget = addChild(new Button(0, 0, 200, buttonHeight, new TranslatableComponent("t.clc.opensubconfig"), this::openSubConfig));
}
@Override
public void render(Minecraft minecraft, Font font, int x, int y, int width, int height, PoseStack matrices, int mouseX, int mouseY, float delta) {
this.text = new TranslatableComponent(subConfig.getClass().getSimpleName().toLowerCase());
this.hideReset();
super.render(minecraft, font, x, y, width, height, matrices, mouseX, mouseY, delta);
}
private void openSubConfig(Button button) {
Minecraft.getInstance().setScreen(new CraterConfigScreen(config, screen, subConfig));
}
}

View File

@@ -1,46 +0,0 @@
package com.hypherionmc.craterlib.client.gui.config.widgets;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font;
import java.util.function.Function;
/**
* Copied from Cloth Config Lite
* <a href="https://github.com/shedaniel/cloth-config-lite/blob/1.17/src/main/java/me/shedaniel/clothconfiglite/impl/option/TextFieldOption.java">...</a>
*/
@Deprecated(forRemoval = true, since = "2.1.3")
public class TextConfigOption<T> extends AbstractConfigWidget<T, WrappedEditBox> {
private final Function<T, String> toString;
private final Function<String, T> fromString;
public TextConfigOption(Function<T, String> toString, Function<String, T> fromString) {
this.toString = toString;
this.fromString = fromString;
this.widget = addChild(new WrappedEditBox(Minecraft.getInstance().font, 0, 0, 198, 18, null));
}
@Override
public void onAdd() {
widget.setMaxLength(1000000);
widget.setValue(toString.apply(value));
widget.setResponder(this::update);
}
@Override
public void render(Minecraft minecraft, Font font, int x, int y, int width, int height, PoseStack matrices, int mouseX, int mouseY, float delta) {
widget.setTextColor(hasErrors ? 16733525 : 14737632);
super.render(minecraft, font, x, y, width, height, matrices, mouseX, mouseY, delta);
}
private void update(String s) {
try {
this.value = fromString.apply(s);
this.hasErrors = false;
} catch (Exception e) {
this.hasErrors = true;
}
}
}

View File

@@ -1,35 +0,0 @@
package com.hypherionmc.craterlib.client.gui.config.widgets;
import net.minecraft.client.gui.components.Button;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TextComponent;
import java.util.List;
import java.util.function.Function;
/**
* Copied from Cloth Config Lite
* <a href="https://github.com/shedaniel/cloth-config-lite/blob/1.17/src/main/java/me/shedaniel/clothconfiglite/impl/option/ToggleOption.java">...</a>
*/
@Deprecated(forRemoval = true, since = "2.1.3")
public class ToggleButton<T> extends AbstractConfigWidget<T, Button> {
private final List<T> options;
private final Function<T, Component> toComponent;
public ToggleButton(List<T> options, Function<T, Component> toComponent) {
this.options = options;
this.toComponent = toComponent;
this.widget = addChild(new Button(0, 0, buttonWidth, buttonHeight, new TextComponent(""), this::switchNext));
}
@Override
public void onAdd() {
widget.setMessage(toComponent.apply(value));
}
private void switchNext(Button button) {
value = options.get((options.indexOf(value) + 1) % options.size());
onAdd();
}
}

View File

@@ -1,17 +0,0 @@
// @excludeplugin
package com.hypherionmc.craterlib.compat;
import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer;
import dev.ftb.mods.ftbessentials.util.FTBEPlayerData;
import java.util.Optional;
public class FTBEssentials {
public static boolean isPlayerMuted(BridgedPlayer player) {
FTBEPlayerData data = FTBEPlayerData.get(player.toMojang());
return data != null && data.muted;
}
}

View File

@@ -1,83 +0,0 @@
// @excludeplugin
package com.hypherionmc.craterlib.compat.ftbranks;
import com.hypherionmc.craterlib.api.events.compat.FTBRankEvents;
import com.hypherionmc.craterlib.core.event.CraterEventBus;
import com.hypherionmc.craterlib.nojang.authlib.BridgedGameProfile;
import dev.ftb.mods.ftbranks.api.FTBRanksAPI;
import dev.ftb.mods.ftbranks.api.event.PlayerAddedToRankEvent;
import dev.ftb.mods.ftbranks.api.event.PlayerRemovedFromRankEvent;
import dev.ftb.mods.ftbranks.api.event.RankDeletedEvent;
import dev.ftb.mods.ftbranks.api.event.RankEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
public class FTBRanks {
public static final FTBRanks INSTANCE = new FTBRanks();
private FTBRanks() {
registerEvents();
}
public List<BridgedRank> getPlayerRanks(BridgedGameProfile profile) {
List<BridgedRank> ranks = new ArrayList<>();
FTBRanksAPI.INSTANCE.getManager().getAddedRanks(profile.toMojang()).forEach(rank -> ranks.add(BridgedRank.of(rank)));
return ranks;
}
public List<BridgedRank> getAllRanks() {
List<BridgedRank> ranks = new ArrayList<>();
FTBRanksAPI.INSTANCE.getManager().getAllRanks().forEach(r -> ranks.add(BridgedRank.of(r)));
return ranks;
}
public boolean hasRank(BridgedGameProfile profile, String rank) {
return getPlayerRanks(profile).stream().anyMatch(r -> r.toFtb().getName().equalsIgnoreCase(rank) || r.toFtb().getId().equalsIgnoreCase(rank));
}
public boolean addRank(BridgedGameProfile profile, String rank) {
rank = rank.toLowerCase();
AtomicBoolean didAddRank = new AtomicBoolean(false);
FTBRanksAPI.INSTANCE.getManager().getRank(rank).ifPresent(r -> {
r.add(profile.toMojang());
didAddRank.set(true);
});
return didAddRank.get();
}
public boolean removeRank(BridgedGameProfile profile, String rank) {
rank = rank.toLowerCase();
AtomicBoolean didRemoveRank = new AtomicBoolean(false);
FTBRanksAPI.INSTANCE.getManager().getRank(rank).ifPresent(r -> {
r.remove(profile.toMojang());
didRemoveRank.set(true);
});
return didRemoveRank.get();
}
public void registerEvents() {
RankEvent.ADD_PLAYER.register(this::playerAddedToRank);
RankEvent.REMOVE_PLAYER.register(this::playerRemovedFromRank);
RankEvent.DELETED.register(this::rankDeleted);
}
private void rankDeleted(RankDeletedEvent rankDeletedEvent) {
CraterEventBus.INSTANCE.postEvent(FTBRankEvents.RankDeletedEvent.of(rankDeletedEvent.getRank()));
}
private void playerRemovedFromRank(PlayerRemovedFromRankEvent playerRemovedFromRankEvent) {
CraterEventBus.INSTANCE.postEvent(FTBRankEvents.RankRemovedEvent.of(playerRemovedFromRankEvent.getPlayer(), playerRemovedFromRankEvent.getRank()));
}
private void playerAddedToRank(PlayerAddedToRankEvent playerAddedToRankEvent) {
CraterEventBus.INSTANCE.postEvent(FTBRankEvents.RankAddedEvent.of(playerAddedToRankEvent.getPlayer(), playerAddedToRankEvent.getRank()));
}
}

View File

@@ -1,18 +0,0 @@
package com.hypherionmc.craterlib.core.networking.data;
import com.hypherionmc.craterlib.nojang.network.BridgedFriendlyByteBuf;
import com.hypherionmc.craterlib.nojang.resources.ResourceIdentifier;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
/**
* Based on https://github.com/mysticdrew/common-networking/tree/1.20.4
*/
public record PacketHolder<T>(ResourceIdentifier type,
Class<T> messageType,
BiConsumer<T, BridgedFriendlyByteBuf> encoder,
Function<BridgedFriendlyByteBuf, T> decoder,
Consumer<PacketContext<T>> handler) {
}

View File

@@ -1,57 +0,0 @@
package com.hypherionmc.craterlib.mixin.events;
import com.google.common.base.Throwables;
import com.hypherionmc.craterlib.api.events.server.CraterCommandEvent;
import com.hypherionmc.craterlib.core.event.CraterEventBus;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.ParseResults;
import com.mojang.brigadier.StringReader;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(Commands.class)
public class CommandMixin {
@Shadow
@Final
private CommandDispatcher<CommandSourceStack> dispatcher;
@Inject(
method = "performCommand",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/util/profiling/ProfilerFiller;push(Ljava/lang/String;)V",
shift = At.Shift.AFTER
),
cancellable = true
)
private void injectCommandEvent(CommandSourceStack stack, String command, CallbackInfoReturnable<Integer> cir) {
StringReader stringreader = new StringReader(command);
if (stringreader.canRead() && stringreader.peek() == '/') {
stringreader.skip();
}
try {
ParseResults<CommandSourceStack> parse = dispatcher.parse(stringreader, stack);
CraterCommandEvent commandEvent = CraterCommandEvent.of(parse, command);
CraterEventBus.INSTANCE.postEvent(commandEvent);
if (commandEvent.wasCancelled()) {
cir.setReturnValue(1);
return;
}
if (commandEvent.getException() != null) {
Throwables.throwIfUnchecked(commandEvent.getException());
cir.setReturnValue(1);
}
} catch (Exception ignored) {}
}
}

View File

@@ -1,29 +0,0 @@
package com.hypherionmc.craterlib.mixin.events;
import com.hypherionmc.craterlib.api.events.server.CraterAdvancementEvent;
import com.hypherionmc.craterlib.core.event.CraterEventBus;
import com.hypherionmc.craterlib.nojang.advancements.BridgedAdvancement;
import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer;
import net.minecraft.advancements.Advancement;
import net.minecraft.server.PlayerAdvancements;
import net.minecraft.server.level.ServerPlayer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(PlayerAdvancements.class)
public class PlayerAdvancementsMixin {
@Shadow
private ServerPlayer player;
@Inject(method = "award", at = @At(value = "INVOKE", target = "Lnet/minecraft/advancements/AdvancementRewards;grant(Lnet/minecraft/server/level/ServerPlayer;)V", shift = At.Shift.AFTER))
private void injectAdvancementEvent(Advancement advancement, String string, CallbackInfoReturnable<Boolean> cir) {
if (advancement.getDisplay() == null || !advancement.getDisplay().shouldAnnounceChat())
return;
CraterEventBus.INSTANCE.postEvent(new CraterAdvancementEvent(BridgedPlayer.of(this.player), BridgedAdvancement.of(advancement)));
}
}

View File

@@ -1,53 +0,0 @@
package com.hypherionmc.craterlib.mixin.events;
import com.hypherionmc.craterlib.api.events.server.CraterPlayerEvent;
import com.hypherionmc.craterlib.api.events.server.MessageBroadcastEvent;
import com.hypherionmc.craterlib.api.events.server.PlayerPreLoginEvent;
import com.hypherionmc.craterlib.core.event.CraterEventBus;
import com.hypherionmc.craterlib.nojang.authlib.BridgedGameProfile;
import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer;
import com.hypherionmc.craterlib.utils.ChatUtils;
import com.mojang.authlib.GameProfile;
import net.minecraft.network.Connection;
import net.minecraft.network.chat.ChatType;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.players.PlayerList;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.net.SocketAddress;
import java.util.UUID;
@Mixin(PlayerList.class)
public class PlayerListMixin {
@Inject(method = "broadcastMessage(Lnet/minecraft/network/chat/Component;Lnet/minecraft/network/chat/ChatType;Ljava/util/UUID;)V", at = @At("HEAD"))
private void injectBroadcast(Component component, ChatType chatType, UUID uUID, CallbackInfo ci) {
String thread = Thread.currentThread().getStackTrace()[3].getClassName();
MessageBroadcastEvent event = new MessageBroadcastEvent(ChatUtils.mojangToAdventure(component), (s) -> null, false, thread);
CraterEventBus.INSTANCE.postEvent(event);
}
@Inject(method = "placeNewPlayer", at = @At("TAIL"))
private void injectPlayerLoginEvent(Connection arg, ServerPlayer serverPlayer, CallbackInfo ci) {
CraterEventBus.INSTANCE.postEvent(new CraterPlayerEvent.PlayerLoggedIn(BridgedPlayer.of(serverPlayer)));
}
@Inject(method = "remove", at = @At("HEAD"))
private void injectPlayerLogoutEvent(ServerPlayer player, CallbackInfo ci) {
CraterEventBus.INSTANCE.postEvent(new CraterPlayerEvent.PlayerLoggedOut(BridgedPlayer.of(player)));
}
@Inject(method = "canPlayerLogin", at = @At("HEAD"), cancellable = true)
private void injectPreLoginEvent(SocketAddress address, GameProfile gameProfile, CallbackInfoReturnable<Component> cir) {
PlayerPreLoginEvent event = new PlayerPreLoginEvent(address, BridgedGameProfile.of(gameProfile));
CraterEventBus.INSTANCE.postEvent(event);
if (event.getMessage() != null) {
cir.setReturnValue(ChatUtils.adventureToMojang(event.getMessage()));
}
}
}

View File

@@ -1,31 +0,0 @@
package com.hypherionmc.craterlib.mixin.events;
import com.hypherionmc.craterlib.api.events.server.ServerStatusEvent;
import com.hypherionmc.craterlib.core.event.CraterEventBus;
import com.hypherionmc.craterlib.nojang.network.protocol.status.WrappedServerStatus;
import net.minecraft.network.protocol.status.ServerStatus;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.Optional;
@Mixin(ServerStatus.class)
public class ServerStatusMixin {
@Inject(method = "getFavicon", at = @At("RETURN"), cancellable = true)
private void injectIconEvent(CallbackInfoReturnable<String> cir) {
ServerStatusEvent.FaviconRequestEvent event = new ServerStatusEvent.FaviconRequestEvent(isEmpty(cir.getReturnValue()) ? Optional.empty() : Optional.of(new WrappedServerStatus.WrappedFavicon(cir.getReturnValue())));
CraterEventBus.INSTANCE.postEvent(event);
if (event.getNewIcon().isPresent()) {
cir.setReturnValue(event.getNewIcon().get().toMojang());
}
}
private boolean isEmpty(String input) {
return input == null || input.isEmpty();
}
}

View File

@@ -1,46 +0,0 @@
package com.hypherionmc.craterlib.mixin.events;
import com.hypherionmc.craterlib.api.events.server.ServerStatusEvent;
import com.hypherionmc.craterlib.core.event.CraterEventBus;
import com.hypherionmc.craterlib.utils.ChatUtils;
import net.minecraft.network.Connection;
import net.minecraft.network.protocol.status.ClientboundStatusResponsePacket;
import net.minecraft.network.protocol.status.ServerStatus;
import net.minecraft.network.protocol.status.ServerboundStatusRequestPacket;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.network.ServerStatusPacketListenerImpl;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ServerStatusPacketListenerImpl.class)
public class ServerStatusPacketListenerMixin {
@Shadow @Final private Connection connection;
@Shadow @Final private MinecraftServer server;
@Inject(method = "handleStatusRequest",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/network/Connection;send(Lnet/minecraft/network/protocol/Packet;)V",
shift = At.Shift.BEFORE),
cancellable = true
)
private void injectHandleStatusRequest(ServerboundStatusRequestPacket arg, CallbackInfo ci) {
ServerStatusEvent.StatusRequestEvent event = new ServerStatusEvent.StatusRequestEvent(ChatUtils.mojangToAdventure(server.getStatus().getDescription()));
CraterEventBus.INSTANCE.postEvent(event);
if (event.getNewStatus() != null) {
ci.cancel();
ServerStatus serverStatus = this.server.getStatus();
serverStatus.setDescription(ChatUtils.adventureToMojang(event.getNewStatus()));
this.connection.send(new ClientboundStatusResponsePacket(serverStatus));
}
}
}

View File

@@ -1,25 +0,0 @@
package com.hypherionmc.craterlib.mixin.events.client;
import com.hypherionmc.craterlib.api.events.client.CraterSinglePlayerEvent;
import com.hypherionmc.craterlib.core.event.CraterEventBus;
import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ClientLevel.class)
public class ClientLevelMixin {
@Inject(method = "addEntity", at = @At("HEAD"))
private void injectSinglePlayerJoinEvent(int i, Entity entity, CallbackInfo ci) {
if (entity instanceof Player player) {
CraterSinglePlayerEvent.PlayerLogin playerLogin = new CraterSinglePlayerEvent.PlayerLogin(BridgedPlayer.of(player));
CraterEventBus.INSTANCE.postEvent(playerLogin);
}
}
}

View File

@@ -1,23 +0,0 @@
package com.hypherionmc.craterlib.mixin.events.client;
import com.hypherionmc.craterlib.api.events.client.PlayerJoinRealmEvent;
import com.hypherionmc.craterlib.core.event.CraterEventBus;
import com.hypherionmc.craterlib.nojang.realmsclient.dto.BridgedRealmsServer;
import com.mojang.realmsclient.RealmsMainScreen;
import com.mojang.realmsclient.dto.RealmsServer;
import net.minecraft.client.gui.screens.Screen;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(RealmsMainScreen.class)
public class RealmsMainScreenMixin {
@Inject(at = @At("HEAD"), method = "play")
private void play(RealmsServer serverData, Screen arg2, CallbackInfo ci) {
PlayerJoinRealmEvent playerJoinRealm = new PlayerJoinRealmEvent(BridgedRealmsServer.of(serverData));
CraterEventBus.INSTANCE.postEvent(playerJoinRealm);
}
}

View File

@@ -1,21 +0,0 @@
package com.hypherionmc.craterlib.nojang.advancements;
import lombok.RequiredArgsConstructor;
import net.minecraft.advancements.Advancement;
import java.util.Optional;
@RequiredArgsConstructor(staticName = "of")
public class BridgedAdvancement {
private final Advancement internal;
public Optional<BridgedDisplayInfo> displayInfo() {
if (internal.getDisplay() != null) {
return Optional.of(BridgedDisplayInfo.of(internal.getDisplay()));
}
return Optional.empty();
}
}

View File

@@ -1,29 +0,0 @@
package com.hypherionmc.craterlib.nojang.authlib;
import com.mojang.authlib.GameProfile;
import lombok.RequiredArgsConstructor;
import java.util.UUID;
@RequiredArgsConstructor(staticName = "of")
public class BridgedGameProfile {
private final GameProfile internal;
public static BridgedGameProfile mojang(UUID id, String name) {
return new BridgedGameProfile(new GameProfile(id, name));
}
public String getName() {
return internal.getName();
}
public UUID getId() {
return internal.getId();
}
public GameProfile toMojang() {
return internal;
}
}

View File

@@ -1,110 +0,0 @@
package com.hypherionmc.craterlib.nojang.client;
import com.hypherionmc.craterlib.nojang.client.multiplayer.BridgedClientLevel;
import com.hypherionmc.craterlib.nojang.client.multiplayer.BridgedServerData;
import com.hypherionmc.craterlib.nojang.client.server.BridgedIntegratedServer;
import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer;
import com.hypherionmc.craterlib.utils.ChatUtils;
import lombok.Getter;
import net.kyori.adventure.text.Component;
import net.minecraft.SharedConstants;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.AlertScreen;
import net.minecraft.client.gui.screens.Screen;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.UUID;
public class BridgedMinecraft {
@Getter
private static final BridgedMinecraft instance = new BridgedMinecraft();
private final Minecraft internal = Minecraft.getInstance();
public File getGameDirectory() {
return internal.gameDirectory;
}
public BridgedOptions getOptions() {
return BridgedOptions.of(internal.options);
}
@Nullable
public BridgedClientLevel getLevel() {
if (internal.level == null)
return null;
return BridgedClientLevel.of(internal.level);
}
public boolean isRealmServer() {
return internal.getCurrentServer() != null && internal.isConnectedToRealms();
}
public boolean isSinglePlayer() {
return internal.hasSingleplayerServer();
}
@Nullable
public BridgedPlayer getPlayer() {
if (internal.player == null)
return null;
return BridgedPlayer.of(internal.player);
}
public String getGameVersion() {
return SharedConstants.getCurrentVersion().getName();
}
public String getUserName() {
return internal.getUser().getName();
}
public UUID getPlayerId() {
return internal.getUser().getGameProfile().getId();
}
@Nullable
public BridgedServerData getCurrentServer() {
if (internal.getCurrentServer() == null)
return null;
return BridgedServerData.of(internal.getCurrentServer());
}
@Nullable
public BridgedIntegratedServer getSinglePlayerServer() {
if (internal.getSingleplayerServer() == null)
return null;
return BridgedIntegratedServer.of(internal.getSingleplayerServer());
}
public void showWarningScreen(Component title, Component message) {
Screen currentScreen = internal.screen;
internal.setScreen(
new AlertScreen(
() -> internal.setScreen(currentScreen),
ChatUtils.adventureToMojang(title),
ChatUtils.adventureToMojang(message)
)
);
}
public Screen buildWarningScreen(Component title, Component message, Screen parent) {
return new AlertScreen(
() -> internal.setScreen(parent),
ChatUtils.adventureToMojang(title),
ChatUtils.adventureToMojang(message)
);
}
public int getServerPlayerCount () {
if (internal.getConnection() == null)
return 0;
return internal.getConnection().getOnlinePlayers().size();
}
}

View File

@@ -1,41 +0,0 @@
package com.hypherionmc.craterlib.nojang.client.gui;
import lombok.RequiredArgsConstructor;
import net.minecraft.client.gui.screens.*;
import net.minecraft.client.gui.screens.multiplayer.JoinMultiplayerScreen;
import net.minecraft.realms.RealmsScreen;
@RequiredArgsConstructor(staticName = "of")
public class BridgedScreen {
private final Screen internal;
public boolean isTitleScreen() {
return internal instanceof TitleScreen;
}
public boolean isRealmsScreen() {
return internal instanceof RealmsScreen;
}
public boolean isServerBrowserScreen() {
return internal instanceof JoinMultiplayerScreen;
}
public boolean isLoadingScreen() {
return internal instanceof LevelLoadingScreen || internal instanceof ReceivingLevelScreen;
}
public boolean isPauseScreen() {
return internal instanceof PauseScreen;
}
public boolean isDisconnetedScreen() {
return internal instanceof DisconnectedScreen;
}
public Screen toMojang() {
return internal;
}
}

View File

@@ -1,42 +0,0 @@
package com.hypherionmc.craterlib.nojang.client.multiplayer;
import com.hypherionmc.craterlib.utils.ChatUtils;
import lombok.RequiredArgsConstructor;
import net.kyori.adventure.text.Component;
import net.minecraft.ChatFormatting;
import net.minecraft.client.multiplayer.ServerData;
@RequiredArgsConstructor(staticName = "of")
public class BridgedServerData {
private final ServerData internal;
public String name() {
return internal.name;
}
public String ip() {
return internal.ip;
}
public Component motd() {
return ChatUtils.mojangToAdventure(internal.motd);
}
public int getMaxPlayers() {
if (!internal.pinged || internal.status.getString() == null) {
return internal.playerList.size() + 1;
}
try {
return Integer.parseInt(ChatFormatting.stripFormatting(internal.status.getString()).split("/")[1]);
} catch (Exception ignored) {}
return 0;
}
public ServerData toMojang() {
return internal;
}
}

View File

@@ -1,61 +0,0 @@
package com.hypherionmc.craterlib.nojang.commands;
import com.hypherionmc.craterlib.CraterConstants;
import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer;
import com.hypherionmc.craterlib.utils.ChatUtils;
import lombok.RequiredArgsConstructor;
import net.kyori.adventure.text.Component;
import net.minecraft.commands.CommandSourceStack;
import java.util.function.Supplier;
import static net.minecraft.world.level.GameRules.RULE_SENDCOMMANDFEEDBACK;
@RequiredArgsConstructor(staticName = "of")
public class BridgedCommandSourceStack {
private final CommandSourceStack internal;
public void sendSuccess(Supplier<Component> supplier, boolean bl) {
if (!internal.getServer().getGameRules().getBoolean(RULE_SENDCOMMANDFEEDBACK)) {
try {
internal.getPlayerOrException().displayClientMessage(ChatUtils.adventureToMojang(supplier.get()), false);
} catch (Exception ignored) {}
} else {
internal.sendSuccess(ChatUtils.adventureToMojang(supplier.get()), bl);
}
}
public void sendMessage(Component text) {
try {
internal.getPlayerOrException().displayClientMessage(ChatUtils.adventureToMojang(text), false);
} catch (Exception ignored) {}
}
public void sendFailure(Component text) {
internal.sendFailure(ChatUtils.adventureToMojang(text));
}
public boolean isPlayer() {
try {
internal.getPlayerOrException();
return true;
} catch (Exception ignored) {
return false;
}
}
public BridgedPlayer getPlayer() {
try {
return BridgedPlayer.of(internal.getPlayerOrException());
} catch (Exception e) {
CraterConstants.LOG.error("Failed to retrieve player", e);
}
return null;
}
public CommandSourceStack toMojang() {
return internal;
}
}

View File

@@ -1,56 +0,0 @@
package com.hypherionmc.craterlib.nojang.commands;
import com.hypherionmc.craterlib.nojang.server.BridgedMinecraftServer;
import com.hypherionmc.craterlib.utils.ChatUtils;
import net.minecraft.commands.CommandSource;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TextComponent;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.phys.Vec2;
import net.minecraft.world.phys.Vec3;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Supplier;
public abstract class BridgedFakePlayer {
final MojangBridge internal;
public BridgedFakePlayer(BridgedMinecraftServer server, int perm, String name) {
internal = new MojangBridge(server.toMojang(), perm, name, this::onSuccess, this::onError);
}
public abstract void onSuccess(Supplier<net.kyori.adventure.text.Component> supplier, Boolean aBoolean);
public void onError(net.kyori.adventure.text.Component component) {
this.onSuccess(() -> component, false);
}
public CommandSourceStack toMojang() {
return internal;
}
static class MojangBridge extends CommandSourceStack {
private final BiConsumer<Supplier<net.kyori.adventure.text.Component>, Boolean> successCallback;
public final Consumer<net.kyori.adventure.text.Component> errorCallback;
MojangBridge(MinecraftServer server, int perm, String name, BiConsumer<Supplier<net.kyori.adventure.text.Component>, Boolean> successCallback, Consumer<net.kyori.adventure.text.Component> errorCallback) {
super(CommandSource.NULL, Vec3.ZERO, Vec2.ZERO, server.overworld(), perm, name, new TextComponent(name), server, null);
this.successCallback = successCallback;
this.errorCallback = errorCallback;
}
@Override
public void sendSuccess(Component supplier, boolean bl) {
successCallback.accept(() -> ChatUtils.mojangToAdventure(supplier), bl);
}
@Override
public void sendFailure(Component arg) {
errorCallback.accept(ChatUtils.mojangToAdventure(arg));
}
}
}

View File

@@ -1,49 +0,0 @@
package com.hypherionmc.craterlib.nojang.nbt;
import lombok.RequiredArgsConstructor;
import net.minecraft.nbt.CompoundTag;
import java.util.Set;
@RequiredArgsConstructor(staticName = "of")
public class BridgedCompoundTag {
private final CompoundTag internal;
public static BridgedCompoundTag empty() {
return new BridgedCompoundTag(new CompoundTag());
}
public BridgedCompoundTag getCompound(String key) {
return BridgedCompoundTag.of(internal.getCompound(key));
}
public Set<String> getAllKeys() {
return internal.getAllKeys();
}
public String getString(String key) {
return internal.getString(key);
}
public boolean getBoolean(String key) {
return internal.getBoolean(key);
}
public void putString(String key, String value) {
internal.putString(key, value);
}
public void put(String key, BridgedCompoundTag value) {
internal.put(key, value.toMojang());
}
public void putBoolean(String key, boolean value) {
internal.putBoolean(key, value);
}
public CompoundTag toMojang() {
return internal;
}
}

View File

@@ -1,42 +0,0 @@
package com.hypherionmc.craterlib.nojang.network.protocol.status;
import org.jetbrains.annotations.ApiStatus;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public final class WrappedServerStatus {
public static final class WrappedFavicon {
private final String internal;
private final byte[] iconBytes;
public WrappedFavicon(byte[] iconBytes) {
this.iconBytes = iconBytes;
if (iconBytes != null) {
byte[] encoded = Base64.getEncoder().encode(iconBytes);
internal = "data:image/png;base64," + new String(encoded, StandardCharsets.UTF_8);
} else {
internal = null;
}
}
@ApiStatus.Internal
public WrappedFavicon(String internal) {
this.internal = internal;
this.iconBytes = new byte[0];
}
public byte[] iconBytes() {
return iconBytes;
}
public String toMojang() {
return internal;
}
}
}

View File

@@ -1,36 +0,0 @@
package com.hypherionmc.craterlib.nojang.resources;
import net.minecraft.resources.ResourceLocation;
public class ResourceIdentifier {
private final ResourceLocation internal;
public ResourceIdentifier(String namespace, String path) {
this.internal = new ResourceLocation(namespace, path);
}
public ResourceIdentifier(String path) {
this.internal = new ResourceLocation(path);
}
public String getNamespace() {
return internal.getNamespace();
}
public String getPath() {
return internal.getPath();
}
public String getString() {
return internal.toString();
}
public static ResourceIdentifier fromMojang(ResourceLocation location) {
return new ResourceIdentifier(location.getNamespace(), location.getPath());
}
public ResourceLocation toMojang() {
return internal;
}
}

View File

@@ -1,99 +0,0 @@
package com.hypherionmc.craterlib.nojang.server;
import com.hypherionmc.craterlib.nojang.authlib.BridgedGameProfile;
import com.hypherionmc.craterlib.nojang.client.multiplayer.BridgedClientLevel;
import com.hypherionmc.craterlib.nojang.commands.BridgedFakePlayer;
import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer;
import com.hypherionmc.craterlib.nojang.world.level.BridgedGameRules;
import com.hypherionmc.craterlib.utils.ChatUtils;
import lombok.RequiredArgsConstructor;
import net.kyori.adventure.text.Component;
import net.minecraft.SharedConstants;
import net.minecraft.Util;
import net.minecraft.network.chat.ChatType;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.players.UserBanListEntry;
import net.minecraft.server.players.UserWhiteListEntry;
import java.util.ArrayList;
import java.util.List;
@RequiredArgsConstructor(staticName = "of")
public class BridgedMinecraftServer {
private final MinecraftServer internal;
public boolean isUsingWhitelist() {
return internal.getPlayerList().isUsingWhitelist();
}
public int getPlayerCount() {
return internal.getPlayerList().getPlayerCount();
}
public int getMaxPlayers() {
return internal.getPlayerList().getMaxPlayers();
}
public String getServerModName() {
return internal.getServerModName();
}
public String getName() {
return SharedConstants.getCurrentVersion().getName();
}
public boolean usesAuthentication() {
return internal.usesAuthentication();
}
public void broadcastSystemMessage(Component text, boolean bl) {
internal.getPlayerList().broadcastMessage(ChatUtils.adventureToMojang(text), ChatType.SYSTEM, Util.NIL_UUID);
}
public boolean isPlayerBanned(BridgedGameProfile profile) {
return internal.getPlayerList().getBans().isBanned(profile.toMojang());
}
public void whitelistPlayer(BridgedGameProfile gameProfile) {
if (!internal.getPlayerList().isUsingWhitelist())
return;
internal.getPlayerList().getWhiteList().add(new UserWhiteListEntry(gameProfile.toMojang()));
}
public void unWhitelistPlayer(BridgedGameProfile gameProfile) {
if (!internal.getPlayerList().isUsingWhitelist())
return;
internal.getPlayerList().getWhiteList().remove(new UserWhiteListEntry(gameProfile.toMojang()));
}
public List<BridgedPlayer> getPlayers() {
List<BridgedPlayer> profiles = new ArrayList<>();
if (internal.getPlayerList() == null)
return profiles;
internal.getPlayerList().getPlayers().forEach(p -> profiles.add(BridgedPlayer.of(p)));
return profiles;
}
public BridgedGameRules getGameRules() {
return BridgedGameRules.bridge(internal.getGameRules());
}
public void banPlayer(BridgedGameProfile profile) {
internal.getPlayerList().getBans().add(new UserBanListEntry(profile.toMojang()));
}
public void executeCommand(BridgedMinecraftServer server, BridgedFakePlayer player, String command) {
internal.getCommands().performCommand(player.toMojang(), command);
}
public MinecraftServer toMojang() {
return internal;
}
}

View File

@@ -1,103 +0,0 @@
package com.hypherionmc.craterlib.nojang.world.level;
import lombok.RequiredArgsConstructor;
import net.minecraft.world.level.GameRules;
@RequiredArgsConstructor(staticName = "bridge")
public class BridgedGameRules {
private final GameRules internal;
// Wrapped Mojang Rules for convenience
public static final WrappedBooleanKey RULE_DOFIRETICK = WrappedBooleanKey.wrap(GameRules.RULE_DOFIRETICK);
public static final WrappedBooleanKey RULE_ALLOWFIRETICKAWAYFROMPLAYERS = WrappedBooleanKey.wrap(null);
public static final WrappedBooleanKey RULE_MOBGRIEFING = WrappedBooleanKey.wrap(GameRules.RULE_MOBGRIEFING);
public static final WrappedBooleanKey RULE_KEEPINVENTORY = WrappedBooleanKey.wrap(GameRules.RULE_KEEPINVENTORY);
public static final WrappedBooleanKey RULE_DOMOBSPAWNING = WrappedBooleanKey.wrap(GameRules.RULE_DOMOBSPAWNING);
public static final WrappedBooleanKey RULE_DOMOBLOOT = WrappedBooleanKey.wrap(GameRules.RULE_DOMOBLOOT);
public static final WrappedBooleanKey RULE_PROJECTILESCANBREAKBLOCKS = WrappedBooleanKey.wrap(null);
public static final WrappedBooleanKey RULE_DOBLOCKDROPS = WrappedBooleanKey.wrap(GameRules.RULE_DOBLOCKDROPS);
public static final WrappedBooleanKey RULE_DOENTITYDROPS = WrappedBooleanKey.wrap(GameRules.RULE_DOENTITYDROPS);
public static final WrappedBooleanKey RULE_COMMANDBLOCKOUTPUT = WrappedBooleanKey.wrap(GameRules.RULE_COMMANDBLOCKOUTPUT);
public static final WrappedBooleanKey RULE_NATURAL_REGENERATION = WrappedBooleanKey.wrap(GameRules.RULE_NATURAL_REGENERATION);
public static final WrappedBooleanKey RULE_DAYLIGHT = WrappedBooleanKey.wrap(GameRules.RULE_DAYLIGHT);
public static final WrappedBooleanKey RULE_LOGADMINCOMMANDS = WrappedBooleanKey.wrap(GameRules.RULE_LOGADMINCOMMANDS);
public static final WrappedBooleanKey RULE_SHOWDEATHMESSAGES = WrappedBooleanKey.wrap(GameRules.RULE_SHOWDEATHMESSAGES);
public static final WrappedIntegerKey RULE_RANDOMTICKING = WrappedIntegerKey.wrap(GameRules.RULE_RANDOMTICKING);
public static final WrappedBooleanKey RULE_SENDCOMMANDFEEDBACK = WrappedBooleanKey.wrap(GameRules.RULE_SENDCOMMANDFEEDBACK);
public static final WrappedBooleanKey RULE_REDUCEDDEBUGINFO = WrappedBooleanKey.wrap(GameRules.RULE_REDUCEDDEBUGINFO);
public static final WrappedBooleanKey RULE_SPECTATORSGENERATECHUNKS = WrappedBooleanKey.wrap(GameRules.RULE_SPECTATORSGENERATECHUNKS);
public static final WrappedIntegerKey RULE_SPAWN_RADIUS = WrappedIntegerKey.wrap(GameRules.RULE_SPAWN_RADIUS);
public static final WrappedBooleanKey RULE_DISABLE_PLAYER_MOVEMENT_CHECK = WrappedBooleanKey.wrap(null);
public static final WrappedBooleanKey RULE_DISABLE_ELYTRA_MOVEMENT_CHECK = WrappedBooleanKey.wrap(GameRules.RULE_DISABLE_ELYTRA_MOVEMENT_CHECK);
public static final WrappedIntegerKey RULE_MAX_ENTITY_CRAMMING = WrappedIntegerKey.wrap(GameRules.RULE_MAX_ENTITY_CRAMMING);
public static final WrappedBooleanKey RULE_WEATHER_CYCLE = WrappedBooleanKey.wrap(GameRules.RULE_WEATHER_CYCLE);
public static final WrappedBooleanKey RULE_LIMITED_CRAFTING = WrappedBooleanKey.wrap(GameRules.RULE_LIMITED_CRAFTING);
public static final WrappedIntegerKey RULE_MAX_COMMAND_CHAIN_LENGTH = WrappedIntegerKey.wrap(GameRules.RULE_MAX_COMMAND_CHAIN_LENGTH);
public static final WrappedIntegerKey RULE_MAX_COMMAND_FORK_COUNT = WrappedIntegerKey.wrap(null);
public static final WrappedIntegerKey RULE_COMMAND_MODIFICATION_BLOCK_LIMIT = WrappedIntegerKey.wrap(null);
public static final WrappedBooleanKey RULE_ANNOUNCE_ADVANCEMENTS = WrappedBooleanKey.wrap(GameRules.RULE_ANNOUNCE_ADVANCEMENTS);
public static final WrappedBooleanKey RULE_DISABLE_RAIDS = WrappedBooleanKey.wrap(GameRules.RULE_DISABLE_RAIDS);
public static final WrappedBooleanKey RULE_DOINSOMNIA = WrappedBooleanKey.wrap(GameRules.RULE_DOINSOMNIA);
public static final WrappedBooleanKey RULE_DO_IMMEDIATE_RESPAWN = WrappedBooleanKey.wrap(GameRules.RULE_DO_IMMEDIATE_RESPAWN);
public static final WrappedIntegerKey RULE_PLAYERS_NETHER_PORTAL_DEFAULT_DELAY = WrappedIntegerKey.wrap(null);
public static final WrappedIntegerKey RULE_PLAYERS_NETHER_PORTAL_CREATIVE_DELAY = WrappedIntegerKey.wrap(null);
public static final WrappedBooleanKey RULE_DROWNING_DAMAGE = WrappedBooleanKey.wrap(GameRules.RULE_DROWNING_DAMAGE);
public static final WrappedBooleanKey RULE_FALL_DAMAGE = WrappedBooleanKey.wrap(GameRules.RULE_FALL_DAMAGE);
public static final WrappedBooleanKey RULE_FIRE_DAMAGE = WrappedBooleanKey.wrap(GameRules.RULE_FIRE_DAMAGE);
public static final WrappedBooleanKey RULE_FREEZE_DAMAGE = WrappedBooleanKey.wrap(GameRules.RULE_FREEZE_DAMAGE);
public static final WrappedBooleanKey RULE_DO_PATROL_SPAWNING = WrappedBooleanKey.wrap(GameRules.RULE_DO_PATROL_SPAWNING);
public static final WrappedBooleanKey RULE_DO_TRADER_SPAWNING = WrappedBooleanKey.wrap(GameRules.RULE_DO_TRADER_SPAWNING);
public static final WrappedBooleanKey RULE_DO_WARDEN_SPAWNING = WrappedBooleanKey.wrap(null);
public static final WrappedBooleanKey RULE_FORGIVE_DEAD_PLAYERS = WrappedBooleanKey.wrap(GameRules.RULE_FORGIVE_DEAD_PLAYERS);
public static final WrappedBooleanKey RULE_UNIVERSAL_ANGER = WrappedBooleanKey.wrap(GameRules.RULE_UNIVERSAL_ANGER);
public static final WrappedIntegerKey RULE_PLAYERS_SLEEPING_PERCENTAGE = WrappedIntegerKey.wrap(GameRules.RULE_PLAYERS_SLEEPING_PERCENTAGE);
public static final WrappedBooleanKey RULE_BLOCK_EXPLOSION_DROP_DECAY = WrappedBooleanKey.wrap(null);
public static final WrappedBooleanKey RULE_MOB_EXPLOSION_DROP_DECAY = WrappedBooleanKey.wrap(null);
public static final WrappedBooleanKey RULE_TNT_EXPLOSION_DROP_DECAY = WrappedBooleanKey.wrap(null);
public static final WrappedIntegerKey RULE_SNOW_ACCUMULATION_HEIGHT = WrappedIntegerKey.wrap(null);
public static final WrappedBooleanKey RULE_WATER_SOURCE_CONVERSION = WrappedBooleanKey.wrap(null);
public static final WrappedBooleanKey RULE_LAVA_SOURCE_CONVERSION = WrappedBooleanKey.wrap(null);
public static final WrappedBooleanKey RULE_GLOBAL_SOUND_EVENTS = WrappedBooleanKey.wrap(null);
public static final WrappedBooleanKey RULE_DO_VINES_SPREAD = WrappedBooleanKey.wrap(null);
public static final WrappedBooleanKey RULE_ENDER_PEARLS_VANISH_ON_DEATH = WrappedBooleanKey.wrap(null);
public static final WrappedIntegerKey RULE_MINECART_MAX_SPEED = WrappedIntegerKey.wrap(null);
public static final WrappedIntegerKey RULE_SPAWN_CHUNK_RADIUS = WrappedIntegerKey.wrap(null);
public static final WrappedBooleanKey RULE_TNT_EXPLODES = WrappedBooleanKey.wrap(null);
public boolean getBoolean(WrappedBooleanKey key) {
if (key.toMojang() == null)
return false;
return internal.getBoolean(key.toMojang());
}
public int getInt(WrappedIntegerKey key) {
if (key.toMojang() == null)
return 0;
return internal.getInt(key.toMojang());
}
public GameRules toMojang() {
return internal;
}
@RequiredArgsConstructor(staticName = "wrap")
public static final class WrappedBooleanKey {
private final GameRules.Key<GameRules.BooleanValue> internal;
public GameRules.Key<GameRules.BooleanValue> toMojang() {
return internal;
}
}
@RequiredArgsConstructor(staticName = "wrap")
public static final class WrappedIntegerKey {
private final GameRules.Key<GameRules.IntegerValue> internal;
public GameRules.Key<GameRules.IntegerValue> toMojang() {
return internal;
}
}
}

View File

@@ -1,123 +0,0 @@
package com.hypherionmc.craterlib.utils;
import com.hypherionmc.craterlib.nojang.resources.ResourceIdentifier;
import lombok.Getter;
import me.hypherionmc.mcdiscordformatter.discord.DiscordSerializer;
import me.hypherionmc.mcdiscordformatter.minecraft.MinecraftSerializer;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.kyori.adventure.text.serializer.json.JSONOptions;
import net.minecraft.ChatFormatting;
import net.minecraft.SharedConstants;
import net.minecraft.Util;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.Style;
import net.minecraft.network.chat.TextComponent;
import net.minecraft.network.chat.TranslatableComponent;
public class ChatUtils {
@Getter
private static final GsonComponentSerializer adventureSerializer = GsonComponentSerializer.builder().options(
JSONOptions.byDataVersion().at(SharedConstants.getCurrentVersion().getDataVersion().getVersion())
).build();
private static final MiniMessage miniMessage = MiniMessage.miniMessage();
public static Component adventureToMojang(net.kyori.adventure.text.Component inComponent) {
final String serialised = adventureSerializer.serialize(inComponent);
return Component.Serializer.fromJson(serialised);
}
public static net.kyori.adventure.text.Component mojangToAdventure(Component inComponent) {
try {
final String serialised = Component.Serializer.toJson(inComponent);
return adventureSerializer.deserialize(serialised);
} catch (Exception e) {
return net.kyori.adventure.text.Component.text(inComponent.getString());
}
}
// Some text components contain duplicate text, resulting in duplicate messages
// sent back to discord. This should help fix those issues
public static Component safeCopy(Component inComponent) {
String value = inComponent.getString();
Style style = inComponent.getStyle();
return new TextComponent(value).withStyle(style);
}
public static String strip(String inString, String... toStrip) {
String finalString = inString;
for (String strip : toStrip) {
if (finalString.startsWith(strip))
finalString = finalString.replaceFirst(strip, "");
if (finalString.startsWith(" "))
finalString = finalString.replaceFirst(" ", "");
}
return finalString;
}
public static String resolve(net.kyori.adventure.text.Component component, boolean formatted) {
Component c = adventureToMojang(component);
String returnVal = ChatFormatting.stripFormatting(DiscordMarkdownStripper.stripMarkdown(c.getString()));
if (formatted) {
returnVal = DiscordSerializer.INSTANCE.serialize(safeCopy(c).copy());
}
return returnVal;
}
public static net.kyori.adventure.text.Component resolve(String component, boolean formatted) {
Component returnVal = new TextComponent(component);
if (formatted) {
returnVal = MinecraftSerializer.INSTANCE.serialize(component);
}
return mojangToAdventure(returnVal);
}
public static net.kyori.adventure.text.Component getTooltipTitle(String key) {
return net.kyori.adventure.text.Component.text(NamedTextColor.YELLOW + net.kyori.adventure.text.Component.translatable(key).key());
}
public static String resolveTranslation(String key) {
return net.kyori.adventure.text.Component.translatable(key).key();
}
public static net.kyori.adventure.text.Component getTranslation(String key) {
return net.kyori.adventure.text.Component.translatable(key);
}
public static net.kyori.adventure.text.Component makeComponent(String text) {
return net.kyori.adventure.text.Component.translatable(text);
}
public static net.kyori.adventure.text.Component getBiomeName(ResourceIdentifier identifier) {
if (identifier == null)
return net.kyori.adventure.text.Component.text("Unknown");
return mojangToAdventure(new TranslatableComponent(Util.makeDescriptionId("biome", identifier.toMojang())));
}
public static net.kyori.adventure.text.Component format(String value) {
value = convertFormattingCodes(value);
try {
return miniMessage.deserializeOr(value, net.kyori.adventure.text.Component.translatable(value));
} catch (Exception ignored) {
// Mini message fails to format text that contain legacy formatting. Since we support both, that's bad.
// We just ignore the exception here so that the whole format doesn't fail
}
return net.kyori.adventure.text.Component.translatable(value);
}
private static String convertFormattingCodes(String input) {
return input.replaceAll("§([0-9a-fklmnor])", "\u00A7$1");
}
}

View File

@@ -1,28 +0,0 @@
{
"required": true,
"minVersion": "0.8",
"package": "com.hypherionmc.craterlib.mixin",
"compatibilityLevel": "JAVA_17",
"mixins": [
"events.StoredUserEntryAccessor",
"events.WhitelistMixin"
],
"client": [
"ChatInputSuggestorMixin",
"events.PlayerMixin",
"events.client.ClientLevelMixin",
"events.client.MinecraftMixin",
"events.client.RealmsMainScreenMixin"
],
"server": [
"events.CommandMixin",
"events.PlayerAdvancementsMixin",
"events.PlayerListMixin",
"events.ServerPlayerMixin",
"events.ServerStatusMixin",
"events.ServerStatusPacketListenerMixin"
],
"injectors": {
"defaultRequire": 1
}
}

View File

@@ -1,133 +0,0 @@
archivesBaseName = "${mod_name.replace(" ", "")}-Fabric-${minecraft_version}"
dependencies {
// Core
modImplementation "net.fabricmc.fabric-api:fabric-api:${fabric_api}"
// Compat
modImplementation("com.terraformersmc:modmenu:${mod_menu_version}") {
exclude(group: "net.fabricmc.fabric-api")
}
modImplementation("me.shedaniel.cloth:cloth-config-fabric:${cloth_config}")
modImplementation "maven.modrinth:fabrictailor:${fabrictailor}"
modImplementation "maven.modrinth:vanish:${vanish}"
// Do not edit or remove
implementation project(":Common")
}
shadowJar {
from sourceSets.main.output
configurations = [project.configurations.shade]
dependencies {
exclude(dependency('com.google.code.gson:.*'))
relocate 'me.hypherionmc.moonconfig', 'shadow.hypherionmc.moonconfig'
relocate 'me.hypherionmc.mcdiscordformatter', 'shadow.hypherionmc.mcdiscordformatter'
relocate 'net.kyori', 'shadow.kyori'
}
setArchiveClassifier('dev-shadow')
mergeServiceFiles()
}
/**
* ===============================================================================
* = DO NOT EDIT BELOW THIS LINE UNLESS YOU KNOW WHAT YOU ARE DOING =
* ===============================================================================
*/
unimined.minecraft {
fabric {
loader fabric_loader
}
}
remapJar {
inputFile.set shadowJar.archiveFile
dependsOn shadowJar
archiveClassifier.set null
}
jar {
archiveClassifier.set "dev"
}
processResources {
from project(":Common").sourceSets.main.resources
def buildProps = project.properties.clone()
filesMatching(['fabric.mod.json']) {
expand buildProps
}
}
compileTestJava.enabled = false
tasks.withType(JavaCompile).configureEach {
source(project(":Common").sourceSets.main.allSource)
}
/**
* Publishing Config
*/
publishing {
publications {
mavenJava(MavenPublication) {
artifactId project.archivesBaseName
from components.java
artifact(remapJar) {
builtBy remapJar
}
pom.withXml {
Node pomNode = asNode()
pomNode.dependencies.'*'.findAll() {
it.artifactId.text() == 'regutils-joined-fabric' ||
it.artifactId.text() == 'core' ||
it.artifactId.text() == 'toml'
}.each() {
it.parent().remove(it)
}
}
}
}
repositories {
maven rootProject.orion.getPublishingMaven()
}
}
publisher {
apiKeys {
modrinth(System.getenv("MODRINTH_TOKEN"))
curseforge(System.getenv("CURSE_TOKEN"))
nightbloom(System.getenv("PLATFORM_KEY"))
}
setCurseID(curse_id)
setModrinthID(modrinth_id)
setNightbloomID("craterlib")
setVersionType("release")
setChangelog(rootProject.file("changelog.md"))
setProjectVersion("${minecraft_version}-${project.version}")
setDisplayName("[FABRIC/QUILT 1.18.2] CraterLib - ${project.version}")
setGameVersions("1.18.2")
setLoaders("fabric", "quilt")
setArtifact(remapJar)
setCurseEnvironment("both")
setIsManualRelease(true)
modrinthDepends {
required("fabric-api")
optional("cloth-config", "modmenu")
}
curseDepends {
required("fabric-api")
optional("cloth-config", "modmenu")
}
}

View File

@@ -1,40 +0,0 @@
package com.hypherionmc.craterlib;
import com.hypherionmc.craterlib.api.events.server.CraterRegisterCommandEvent;
import com.hypherionmc.craterlib.api.events.server.CraterServerLifecycleEvent;
import com.hypherionmc.craterlib.common.FabricCommonPlatform;
import com.hypherionmc.craterlib.compat.Vanish;
import com.hypherionmc.craterlib.core.event.CraterEventBus;
import com.hypherionmc.craterlib.core.networking.CraterPacketNetwork;
import com.hypherionmc.craterlib.core.networking.data.PacketSide;
import com.hypherionmc.craterlib.core.platform.ModloaderEnvironment;
import com.hypherionmc.craterlib.network.CraterFabricNetworkHandler;
import com.hypherionmc.craterlib.nojang.server.BridgedMinecraftServer;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.command.v1.CommandRegistrationCallback;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
public class CraterLibInitializer implements ModInitializer {
@Override
public void onInitialize() {
new CraterPacketNetwork(new CraterFabricNetworkHandler(PacketSide.SERVER));
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> {
CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent(dispatcher));
});
ServerLifecycleEvents.SERVER_STARTING.register(server -> {
FabricCommonPlatform.server = server;
CraterEventBus.INSTANCE.postEvent(new CraterServerLifecycleEvent.Starting(BridgedMinecraftServer.of(server)));
});
ServerLifecycleEvents.SERVER_STARTED.register(li -> CraterEventBus.INSTANCE.postEvent(new CraterServerLifecycleEvent.Started(BridgedMinecraftServer.of(li))));
ServerLifecycleEvents.SERVER_STOPPING.register(server -> CraterEventBus.INSTANCE.postEvent(new CraterServerLifecycleEvent.Stopping(BridgedMinecraftServer.of(server))));
ServerLifecycleEvents.SERVER_STOPPED.register(server -> CraterEventBus.INSTANCE.postEvent(new CraterServerLifecycleEvent.Stopped(BridgedMinecraftServer.of(server))));
if (ModloaderEnvironment.INSTANCE.isModLoaded("melius-vanish")) {
Vanish.register();
}
}
}

View File

@@ -1,49 +0,0 @@
package com.hypherionmc.craterlib.common;
import com.hypherionmc.craterlib.compat.FabricTailor;
import com.hypherionmc.craterlib.compat.Vanish;
import com.hypherionmc.craterlib.core.platform.CompatUtils;
import com.hypherionmc.craterlib.core.platform.ModloaderEnvironment;
import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer;
import net.kyori.adventure.text.Component;
public class FabricCompatHelper implements CompatUtils {
@Override
public boolean isPlayerActive(BridgedPlayer player) {
if (!ModloaderEnvironment.INSTANCE.isModLoaded("melius-vanish"))
return true;
return !Vanish.isPlayerVanished(player.toMojangServerPlayer());
}
@Override
public String getSkinUUID(BridgedPlayer player) {
return FabricTailor.getTailorSkin(player.toMojangServerPlayer());
}
@Override
public boolean isPlayerBleeding(BridgedPlayer player) {
return false;
}
@Override
public boolean playerBledOut(BridgedPlayer player) {
return false;
}
@Override
public boolean playerRevived(BridgedPlayer player) {
return false;
}
@Override
public boolean isPrivateMessage(BridgedPlayer player) {
return false;
}
@Override
public Component getChannelPrefix(BridgedPlayer player) {
return Component.empty();
}
}

View File

@@ -1,75 +0,0 @@
package com.hypherionmc.craterlib.common;
import com.hypherionmc.craterlib.core.platform.Environment;
import com.hypherionmc.craterlib.core.platform.LoaderType;
import com.hypherionmc.craterlib.core.platform.ModloaderEnvironment;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.SharedConstants;
import net.minecraft.client.Minecraft;
import java.io.File;
/**
* @author HypherionSA
* @date 07/08/2022
*/
public class FabricLoaderHelper implements ModloaderEnvironment {
@Override
public boolean isFabric() {
return true;
}
@Override
public LoaderType getLoaderType() {
return LoaderType.FABRIC;
}
@Override
public String getGameVersion() {
return SharedConstants.VERSION_STRING;
}
@Override
public File getGameFolder() {
return Minecraft.getInstance().gameDirectory;
}
@Override
public File getConfigFolder() {
return FabricLoader.getInstance().getConfigDir().toFile();
}
@Override
public File getModsFolder() {
return new File(FabricLoader.getInstance().getGameDir().toString() + File.separator + "mods");
}
@Override
public Environment getEnvironment() {
switch (FabricLoader.getInstance().getEnvironmentType()) {
case SERVER -> {
return Environment.SERVER;
}
case CLIENT -> {
return Environment.CLIENT;
}
}
return Environment.UNKNOWN;
}
@Override
public boolean isModLoaded(String modid) {
return FabricLoader.getInstance().isModLoaded(modid);
}
@Override
public boolean isDevEnv() {
return FabricLoader.getInstance().isDevelopmentEnvironment();
}
@Override
public int getModCount() {
return FabricLoader.getInstance().getAllMods().size();
}
}

View File

@@ -1,40 +0,0 @@
package com.hypherionmc.craterlib.mixin;
import com.hypherionmc.craterlib.api.events.server.CraterServerChatEvent;
import com.hypherionmc.craterlib.core.event.CraterEventBus;
import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer;
import com.hypherionmc.craterlib.utils.ChatUtils;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TextComponent;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.network.ServerGamePacketListenerImpl;
import net.minecraft.server.network.TextFilter;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(value = ServerGamePacketListenerImpl.class, priority = Integer.MIN_VALUE)
public class ServerGamePacketListenerImplMixin {
@Shadow
public ServerPlayer player;
@Inject(
method = "handleChat(Lnet/minecraft/server/network/TextFilter$FilteredText;)V",
at = @At(value = "INVOKE", target = "Lnet/minecraft/server/network/TextFilter$FilteredText;getFiltered()Ljava/lang/String;"),
cancellable = true
)
private void injectChatEvent(TextFilter.FilteredText arg, CallbackInfo ci) {
Component message = new TextComponent(arg.getRaw());
if (message.getString().startsWith("/"))
return;
CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), arg.getFiltered(), ChatUtils.mojangToAdventure(message));
CraterEventBus.INSTANCE.postEvent(event);
if (event.wasCancelled())
ci.cancel();
}
}

View File

@@ -1,81 +0,0 @@
package com.hypherionmc.craterlib.network;
import com.hypherionmc.craterlib.CraterConstants;
import com.hypherionmc.craterlib.core.networking.PacketRegistry;
import com.hypherionmc.craterlib.core.networking.data.PacketContext;
import com.hypherionmc.craterlib.core.networking.data.PacketHolder;
import com.hypherionmc.craterlib.core.networking.data.PacketSide;
import com.hypherionmc.craterlib.nojang.network.BridgedFriendlyByteBuf;
import com.hypherionmc.craterlib.nojang.resources.ResourceIdentifier;
import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import net.minecraft.network.FriendlyByteBuf;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;
/**
* Based on https://github.com/mysticdrew/common-networking/tree/1.20.4
*/
public class CraterFabricNetworkHandler extends PacketRegistry {
private final Map<Class<?>, Message<?>> CHANNELS = new HashMap();
public CraterFabricNetworkHandler(PacketSide side) {
super(side);
}
protected <T> void registerPacket(PacketHolder<T> holder) {
if (CHANNELS.get(holder.messageType()) == null) {
CHANNELS.put(holder.messageType(), new Message<>(holder.type(), holder.encoder()));
if (PacketSide.CLIENT.equals(this.side)) {
ClientPlayNetworking.registerGlobalReceiver(holder.type().toMojang(), ((client, listener, buf, responseSender) -> {
buf.readByte();
T message = holder.decoder().apply(BridgedFriendlyByteBuf.of(buf));
client.execute(() -> holder.handler().accept(new PacketContext<>(message, PacketSide.CLIENT)));
}));
} else {
ServerPlayNetworking.registerGlobalReceiver(holder.type().toMojang(), ((server, player, listener, buf, responseSender) -> {
buf.readByte();
T message = holder.decoder().apply(BridgedFriendlyByteBuf.of(buf));
server.execute(() -> holder.handler().accept(new PacketContext<>(BridgedPlayer.of(player), message, PacketSide.SERVER)));
}));
}
} else {
CraterConstants.LOG.error("Trying to register duplicate packet for type {}", holder.messageType());
}
}
public <T> void sendToServer(T packet) {
this.sendToServer(packet, false);
}
public <T> void sendToServer(T packet, boolean ignoreCheck) {
Message<T> message = (Message<T>) CHANNELS.get(packet.getClass());
if (ClientPlayNetworking.canSend(message.id().toMojang()) || ignoreCheck) {
FriendlyByteBuf buf = PacketByteBufs.create();
buf.writeByte(0);
message.encoder().accept(packet, BridgedFriendlyByteBuf.of(buf));
ClientPlayNetworking.send(message.id().toMojang(), buf);
}
}
public <T> void sendToClient(T packet, BridgedPlayer player) {
Message<T> message = (Message<T>) CHANNELS.get(packet.getClass());
if (ServerPlayNetworking.canSend(player.toMojangServerPlayer(), message.id().toMojang())) {
FriendlyByteBuf buf = PacketByteBufs.create();
buf.writeByte(0);
message.encoder().accept(packet, BridgedFriendlyByteBuf.of(buf));
ServerPlayNetworking.send(player.toMojangServerPlayer(), message.id().toMojang(), buf);
}
}
public record Message<T>(ResourceIdentifier id, BiConsumer<T, BridgedFriendlyByteBuf> encoder) { }
}

View File

@@ -1,17 +0,0 @@
{
"required": true,
"minVersion": "0.8",
"package": "com.hypherionmc.craterlib.mixin",
"compatibilityLevel": "JAVA_17",
"mixins": [
],
"client": [
"TutorialMixin"
],
"server": [
"ServerGamePacketListenerImplMixin"
],
"injectors": {
"defaultRequire": 1
}
}

View File

@@ -1,39 +0,0 @@
{
"schemaVersion": 1,
"id": "${mod_id}",
"version": "${version}",
"name": "${mod_name}",
"description": "A library mod used by First Dark Development and HypherionSA Mods",
"authors": [
"${mod_author}",
"Misha"
],
"contact": {
"homepage": "https://modrinth.com/mod/craterlib",
"sources": "https://github.com/firstdarkdev/craterLib/"
},
"license": "MIT",
"icon": "assets/craterlib/craterlib_logo.png",
"environment": "*",
"entrypoints": {
"main": [
"com.hypherionmc.craterlib.CraterLibInitializer"
],
"client": [
"com.hypherionmc.craterlib.client.CraterLibClientInitializer"
],
"modmenu": [
"com.hypherionmc.craterlib.CraterLibModMenuIntegration"
]
},
"mixins": [
"${mod_id}.mixins.json",
"${mod_id}.fabric.mixins.json"
],
"depends": {
"fabricloader": ">=0.15.0",
"fabric-api": "*",
"minecraft": "1.18.2",
"java": ">=17"
}
}

View File

@@ -1,128 +0,0 @@
// Adjust the output jar name here
archivesBaseName = "${mod_name.replace(" ", "")}-Forge-${minecraft_version}"
dependencies {
// Compat
modImplementation("maven.modrinth:vanishmod:${vanishmod}")
modImplementation("me.shedaniel.cloth:cloth-config-forge:${cloth_config}")
modImplementation("unimaven.curseforge:playerrevive-266890:${player_revive}")
modImplementation("unimaven.curseforge:creativecore-257814:${creative_core}")
// Do not edit or remove
implementation project(":Common")
}
shadowJar {
from sourceSets.main.output
configurations = [project.configurations.shade]
dependencies {
exclude(dependency('com.google.code.gson:.*'))
relocate 'me.hypherionmc.moonconfig', 'shadow.hypherionmc.moonconfig'
relocate 'me.hypherionmc.mcdiscordformatter', 'shadow.hypherionmc.mcdiscordformatter'
relocate 'net.kyori', 'shadow.kyori'
}
setArchiveClassifier('dev-shadow')
mergeServiceFiles()
}
/**
* ===============================================================================
* = DO NOT EDIT BELOW THIS LINE UNLESS YOU KNOW WHAT YOU ARE DOING =
* ===============================================================================
*/
unimined.minecraft {
minecraftForge {
loader forge_version
mixinConfig("${mod_id}.mixins.json", "${mod_id}.forge.mixins.json")
}
}
remapJar {
inputFile.set shadowJar.archiveFile
dependsOn shadowJar
archiveClassifier.set null
}
jar {
archiveClassifier.set "dev"
}
processResources {
from project(":Common").sourceSets.main.resources
def buildProps = project.properties.clone()
filesMatching("META-INF/mods.toml") {
expand buildProps
}
}
compileTestJava.enabled = false
tasks.withType(JavaCompile).configureEach {
source(project(":Common").sourceSets.main.allSource)
}
/**
* Publishing Config
*/
publishing {
publications {
mavenJava(MavenPublication) {
artifactId project.archivesBaseName
from components.java
artifact(remapJar) {
builtBy remapJar
}
pom.withXml {
Node pomNode = asNode()
pomNode.dependencies.'*'.findAll() {
it.artifactId.text() == 'regutils-joined-fabric' ||
it.artifactId.text() == 'core' ||
it.artifactId.text() == 'toml'
}.each() {
it.parent().remove(it)
}
}
}
}
repositories {
maven rootProject.orion.getPublishingMaven()
}
}
publisher {
apiKeys {
modrinth(System.getenv("MODRINTH_TOKEN"))
curseforge(System.getenv("CURSE_TOKEN"))
nightbloom(System.getenv("PLATFORM_KEY"))
}
setCurseID(curse_id)
setModrinthID(modrinth_id)
setNightbloomID("craterlib")
setVersionType("release")
setChangelog(rootProject.file("changelog.md"))
setProjectVersion("${minecraft_version}-${project.version}")
setDisplayName("[Forge 1.18.2] CraterLib - ${project.version}")
setGameVersions("1.18.2")
setLoaders("forge")
setArtifact(remapJar)
setCurseEnvironment("both")
setIsManualRelease(true)
curseDepends {
optional("cloth-config")
}
modrinthDepends {
optional("cloth-config")
}
}

View File

@@ -1,46 +0,0 @@
package com.hypherionmc.craterlib;
import com.hypherionmc.craterlib.api.events.client.LateInitEvent;
import com.hypherionmc.craterlib.common.ForgeServerEvents;
import com.hypherionmc.craterlib.compat.PlayerReviveEvents;
import com.hypherionmc.craterlib.compat.Vanish;
import com.hypherionmc.craterlib.core.event.CraterEventBus;
import com.hypherionmc.craterlib.core.networking.CraterPacketNetwork;
import com.hypherionmc.craterlib.core.networking.data.PacketSide;
import com.hypherionmc.craterlib.core.platform.ModloaderEnvironment;
import com.hypherionmc.craterlib.network.CraterForgeNetworkHandler;
import com.hypherionmc.craterlib.nojang.client.BridgedMinecraft;
import com.hypherionmc.craterlib.nojang.client.BridgedOptions;
import net.minecraft.client.Minecraft;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.fml.loading.FMLLoader;
@Mod(CraterConstants.MOD_ID)
public class CraterLib {
public CraterLib() {
MinecraftForge.EVENT_BUS.register(new ForgeServerEvents());
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::commonSetup);
}
public void commonSetup(FMLCommonSetupEvent evt) {
new CraterPacketNetwork(new CraterForgeNetworkHandler(FMLLoader.getDist().isClient() ? PacketSide.CLIENT : PacketSide.SERVER));
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> {
LateInitEvent event = new LateInitEvent(new BridgedMinecraft(), BridgedOptions.of(Minecraft.getInstance().options));
CraterEventBus.INSTANCE.postEvent(event);
});
if (ModloaderEnvironment.INSTANCE.isModLoaded("vmod")) {
MinecraftForge.EVENT_BUS.register(new Vanish());
}
if (ModloaderEnvironment.INSTANCE.isModLoaded("playerrevive")) {
MinecraftForge.EVENT_BUS.register(new PlayerReviveEvents());
}
}
}

View File

@@ -1,25 +0,0 @@
package com.hypherionmc.craterlib.client;
import com.hypherionmc.craterlib.CraterConstants;
import com.hypherionmc.craterlib.api.events.client.CraterClientTickEvent;
import com.hypherionmc.craterlib.core.event.CraterEventBus;
import com.hypherionmc.craterlib.nojang.client.multiplayer.BridgedClientLevel;
import net.minecraft.client.Minecraft;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
@Mod.EventBusSubscriber(modid = CraterConstants.MOD_ID, bus = Mod.EventBusSubscriber.Bus.FORGE, value = Dist.CLIENT)
public class ForgeClientEvents {
@SubscribeEvent
public static void clientTick(TickEvent.WorldTickEvent event) {
if (Minecraft.getInstance().level == null)
return;
CraterClientTickEvent craterClientTickEvent = new CraterClientTickEvent(BridgedClientLevel.of(Minecraft.getInstance().level));
CraterEventBus.INSTANCE.postEvent(craterClientTickEvent);
}
}

View File

@@ -1,61 +0,0 @@
package com.hypherionmc.craterlib.common;
import com.hypherionmc.craterlib.core.platform.CompatUtils;
import com.hypherionmc.craterlib.core.platform.ModloaderEnvironment;
import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer;
import net.kyori.adventure.text.Component;
import team.creative.playerrevive.api.IBleeding;
import team.creative.playerrevive.server.PlayerReviveServer;
import redstonedubstep.mods.vanishmod.VanishUtil;
public class ForgeCompatHelper implements CompatUtils {
@Override
public boolean isPlayerActive(BridgedPlayer player) {
if (!ModloaderEnvironment.INSTANCE.isModLoaded("vmod"))
return true;
return !VanishUtil.isVanished(player.toMojangServerPlayer());
}
@Override
public String getSkinUUID(BridgedPlayer player) {
return player.getStringUUID();
}
@Override
public boolean isPlayerBleeding(BridgedPlayer player) {
if (!ModloaderEnvironment.INSTANCE.isModLoaded("playerrevive"))
return false;
return PlayerReviveServer.isBleeding(player.toMojangServerPlayer());
}
@Override
public boolean playerBledOut(BridgedPlayer player) {
if (!ModloaderEnvironment.INSTANCE.isModLoaded("playerrevive"))
return false;
IBleeding bleeding = PlayerReviveServer.getBleeding(player.toMojangServerPlayer());
return bleeding != null && bleeding.bledOut();
}
@Override
public boolean playerRevived(BridgedPlayer player) {
if (!ModloaderEnvironment.INSTANCE.isModLoaded("playerrevive"))
return false;
IBleeding bleeding = PlayerReviveServer.getBleeding(player.toMojangServerPlayer());
return bleeding != null && bleeding.revived();
}
@Override
public boolean isPrivateMessage(BridgedPlayer player) {
return false;
}
@Override
public Component getChannelPrefix(BridgedPlayer player) {
return Component.empty();
}
}

View File

@@ -1,41 +0,0 @@
package com.hypherionmc.craterlib.common;
import com.hypherionmc.craterlib.api.events.server.CraterRegisterCommandEvent;
import com.hypherionmc.craterlib.api.events.server.CraterServerLifecycleEvent;
import com.hypherionmc.craterlib.core.event.CraterEventBus;
import com.hypherionmc.craterlib.nojang.server.BridgedMinecraftServer;
import net.minecraftforge.event.RegisterCommandsEvent;
import net.minecraftforge.event.server.ServerStartedEvent;
import net.minecraftforge.event.server.ServerStartingEvent;
import net.minecraftforge.event.server.ServerStoppedEvent;
import net.minecraftforge.event.server.ServerStoppingEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
public class ForgeServerEvents {
@SubscribeEvent
public void serverStarting(ServerStartingEvent event) {
CraterEventBus.INSTANCE.postEvent(new CraterServerLifecycleEvent.Starting(BridgedMinecraftServer.of(event.getServer())));
}
@SubscribeEvent
public void serverStarted(ServerStartedEvent event) {
CraterEventBus.INSTANCE.postEvent(new CraterServerLifecycleEvent.Started(BridgedMinecraftServer.of(event.getServer())));
}
@SubscribeEvent
public void serverStopping(ServerStoppingEvent event) {
CraterEventBus.INSTANCE.postEvent(new CraterServerLifecycleEvent.Stopping(BridgedMinecraftServer.of(event.getServer())));
}
@SubscribeEvent
public void serverStopped(ServerStoppedEvent event) {
CraterEventBus.INSTANCE.postEvent(new CraterServerLifecycleEvent.Stopped(BridgedMinecraftServer.of(event.getServer())));
}
@SubscribeEvent
public void onCommandRegister(RegisterCommandsEvent event) {
CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent(event.getDispatcher()));
}
}

View File

@@ -1,23 +0,0 @@
package com.hypherionmc.craterlib.compat;
import com.hypherionmc.craterlib.core.event.CraterEventBus;
import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer;
import lombok.NoArgsConstructor;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import team.creative.playerrevive.api.event.PlayerBleedOutEvent;
import team.creative.playerrevive.api.event.PlayerRevivedEvent;
@NoArgsConstructor
public class PlayerReviveEvents {
@SubscribeEvent
public void playerRevived(PlayerRevivedEvent event) {
CraterEventBus.INSTANCE.postEvent(com.hypherionmc.craterlib.api.events.compat.PlayerRevivedEvent.of(BridgedPlayer.of(event.getPlayer())));
}
@SubscribeEvent
public void playerBledOutEvent(PlayerBleedOutEvent event) {
CraterEventBus.INSTANCE.postEvent(com.hypherionmc.craterlib.api.events.compat.PlayerRevivedEvent.of(BridgedPlayer.of(event.getPlayer())));
}
}

View File

@@ -1,27 +0,0 @@
package com.hypherionmc.craterlib.compat;
import com.hypherionmc.craterlib.api.events.server.CraterPlayerEvent;
import com.hypherionmc.craterlib.core.event.CraterEventBus;
import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer;
import net.minecraft.world.entity.player.Player;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import redstonedubstep.mods.vanishmod.api.PlayerVanishEvent;
public class Vanish {
public Vanish() {
}
@SubscribeEvent
public void vanishevent(PlayerVanishEvent event) {
if (event.getEntity() instanceof Player p) {
if (event.isVanished()) {
CraterEventBus.INSTANCE.postEvent(new CraterPlayerEvent.PlayerLoggedOut(BridgedPlayer.of(p), true));
} else {
CraterEventBus.INSTANCE.postEvent(new CraterPlayerEvent.PlayerLoggedIn(BridgedPlayer.of(p), true));
}
}
}
}

View File

@@ -1,52 +0,0 @@
package com.hypherionmc.craterlib.mixin;
import com.hypherionmc.craterlib.client.gui.config.ClothConfigScreenBuilder;
import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen;
import com.hypherionmc.craterlib.core.config.AbstractConfig;
import com.hypherionmc.craterlib.core.config.ConfigController;
import com.hypherionmc.craterlib.core.config.annotations.ClothScreen;
import com.hypherionmc.craterlib.core.config.annotations.NoConfigScreen;
import com.hypherionmc.craterlib.core.platform.ModloaderEnvironment;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.Screen;
import net.minecraftforge.client.ConfigGuiHandler;
import net.minecraftforge.forgespi.language.IModInfo;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.Optional;
import java.util.function.BiFunction;
/**
* @author HypherionSA
*/
@Mixin(ConfigGuiHandler.class)
public class ConfigScreenHandlerMixin {
/**
* Inject Auto Generated config Screens into forge
*
*/
@Inject(at = @At("RETURN"), method = "getGuiFactoryFor", cancellable = true, remap = false)
private static void injectConfigScreen(IModInfo selectedMod, CallbackInfoReturnable<Optional<BiFunction<Minecraft, Screen, Screen>>> cir) {
ConfigController.getWatchedConfigs().forEach((conf, config) -> {
if (config.getClass().isAnnotationPresent(NoConfigScreen.class))
return;
if (config.getModId().equals(selectedMod.getModId())) {
if (config.getClass().isAnnotationPresent(ClothScreen.class) && ModloaderEnvironment.INSTANCE.isModLoaded("cloth_config")) {
cir.setReturnValue(
Optional.of((minecraft, screen) -> ClothConfigScreenBuilder.buildConfigScreen(config, screen))
);
} else {
cir.setReturnValue(
Optional.of((minecraft, screen) -> new CraterConfigScreen(config, screen))
);
}
}
});
}
}

View File

@@ -1,40 +0,0 @@
package com.hypherionmc.craterlib.mixin;
import com.hypherionmc.craterlib.api.events.server.CraterServerChatEvent;
import com.hypherionmc.craterlib.core.event.CraterEventBus;
import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer;
import com.hypherionmc.craterlib.utils.ChatUtils;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TextComponent;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.network.ServerGamePacketListenerImpl;
import net.minecraft.server.network.TextFilter;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(value = ServerGamePacketListenerImpl.class, priority = Integer.MIN_VALUE)
public class ServerGamePacketListenerImplMixin {
@Shadow
public ServerPlayer player;
@Inject(
method = "handleChat(Lnet/minecraft/server/network/TextFilter$FilteredText;)V",
at = @At(value = "INVOKE", target = "Lnet/minecraft/server/network/TextFilter$FilteredText;getFiltered()Ljava/lang/String;"),
cancellable = true
)
private void injectChatEvent(TextFilter.FilteredText arg, CallbackInfo ci) {
Component message = new TextComponent(arg.getRaw());
if (message.getString().startsWith("/"))
return;
CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), arg.getFiltered(), ChatUtils.mojangToAdventure(message));
CraterEventBus.INSTANCE.postEvent(event);
if (event.wasCancelled())
ci.cancel();
}
}

View File

@@ -1,100 +0,0 @@
package com.hypherionmc.craterlib.network;
import com.hypherionmc.craterlib.CraterConstants;
import com.hypherionmc.craterlib.core.networking.PacketRegistry;
import com.hypherionmc.craterlib.core.networking.data.PacketContext;
import com.hypherionmc.craterlib.core.networking.data.PacketHolder;
import com.hypherionmc.craterlib.core.networking.data.PacketSide;
import com.hypherionmc.craterlib.nojang.network.BridgedFriendlyByteBuf;
import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer;
import net.minecraft.client.Minecraft;
import net.minecraft.network.Connection;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.network.ServerGamePacketListenerImpl;
import net.minecraftforge.network.NetworkDirection;
import net.minecraftforge.network.NetworkEvent;
import net.minecraftforge.network.NetworkRegistry;
import net.minecraftforge.network.simple.SimpleChannel;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
/**
* Based on https://github.com/mysticdrew/common-networking/tree/1.20.4
*/
public class CraterForgeNetworkHandler extends PacketRegistry {
private final Map<Class<?>, SimpleChannel> CHANNELS = new HashMap<>();
public CraterForgeNetworkHandler(PacketSide side) {
super(side);
}
protected <T> void registerPacket(PacketHolder<T> holder) {
if (CHANNELS.get(holder.messageType()) == null) {
SimpleChannel channel = NetworkRegistry.ChannelBuilder
.named(holder.type().toMojang())
.clientAcceptedVersions((a) -> true)
.serverAcceptedVersions((a) -> true)
.networkProtocolVersion(() -> "1")
.simpleChannel();
channel.registerMessage(
0,
holder.messageType(),
mojangEncoder(holder.encoder()),
mojangDecoder(holder.decoder()),
buildHandler(holder.handler()));
CHANNELS.put(holder.messageType(), channel);
} else {
CraterConstants.LOG.error("Trying to register duplicate packet for type {}", holder.messageType());
}
}
public <T> void sendToServer(T packet) {
this.sendToServer(packet, false);
}
public <T> void sendToServer(T packet, boolean ignoreCheck) {
SimpleChannel channel = CHANNELS.get(packet.getClass());
Connection connection = Minecraft.getInstance().getConnection().getConnection();
if (channel.isRemotePresent(connection) || ignoreCheck) {
channel.sendToServer(packet);
}
}
public <T> void sendToClient(T packet, BridgedPlayer player) {
SimpleChannel channel = CHANNELS.get(packet.getClass());
ServerGamePacketListenerImpl connection = player.getConnection();
if (connection == null)
return;
if (channel.isRemotePresent(connection.connection)) {
channel.sendTo(packet, player.getConnection().connection, NetworkDirection.PLAY_TO_CLIENT);
}
}
private <T> Function<FriendlyByteBuf, T> mojangDecoder(Function<BridgedFriendlyByteBuf, T> handler) {
return byteBuf -> handler.apply(BridgedFriendlyByteBuf.of(byteBuf));
}
private <T> BiConsumer<T, FriendlyByteBuf> mojangEncoder(BiConsumer<T, BridgedFriendlyByteBuf> handler) {
return ((t, byteBuf) -> handler.accept(t, BridgedFriendlyByteBuf.of(byteBuf)));
}
private <T> BiConsumer<T, Supplier<NetworkEvent.Context>> buildHandler(Consumer<PacketContext<T>> handler) {
return (message, ctx) -> {
ctx.get().enqueueWork(() -> {
PacketSide side = ctx.get().getDirection().getReceptionSide().isServer() ? PacketSide.SERVER : PacketSide.CLIENT;
ServerPlayer player = ctx.get().getSender();
handler.accept(new PacketContext<>(BridgedPlayer.of(player), message, side));
});
ctx.get().setPacketHandled(true);
};
}
}

View File

@@ -1,31 +0,0 @@
modLoader = "javafml"
loaderVersion = "[40,)"
license = "MIT"
issueTrackerURL = "https://github.com/firstdarkdev/craterLib/issues"
[[mods]]
modId = "${mod_id}"
version = "${version}"
displayName = "${mod_name}"
displayURL = "https://modrinth.com/mod/craterlib"
logoFile = "craterlib_logo.png"
#credits="Thanks for this example mod goes to Java"
authors = "${mod_author}, Zenith"
description = '''
A library mod used by First Dark Development and HypherionSA Mods
'''
displayTest = "NONE"
[[dependencies.${ mod_id }]]
modId = "forge"
mandatory = true
versionRange = "[40,)"
ordering = "NONE"
side = "BOTH"
[[dependencies.${ mod_id }]]
modId = "minecraft"
mandatory = true
versionRange = "[1.18.2,1.19)"
ordering = "NONE"
side = "BOTH"

View File

@@ -1,17 +0,0 @@
{
"required": true,
"minVersion": "0.8",
"package": "com.hypherionmc.craterlib.mixin",
"compatibilityLevel": "JAVA_17",
"mixins": [
],
"client": [
"ConfigScreenHandlerMixin"
],
"server": [
"ServerGamePacketListenerImplMixin"
],
"injectors": {
"defaultRequire": 1
}
}

View File

@@ -1,21 +0,0 @@
The MIT License (MIT)
Copyright (c) HypherionSA and Contributors 2024
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -1,55 +0,0 @@
# CraterLib
![badge-snapshot](https://maven.firstdarkdev.xyz/api/badge/latest/snapshots/me/hypherionmc/craterlib/CraterLib-common-1.20-pre6?color=40c14a&name=CraterLib-Snapshot)
***
A Library mod and modding api for easier multi-version minecraft and mod loader development
***
### Supported Minecraft Versions
| Minecraft Version | Support Status |
|-------------------| -------------- |
| < 1.18.2 | |
| 1.18.2-1.20.2 | |
| 1.20.4 | |
| 1.21.x | |
- - Not Supported; no bug fixes or new features.
- 🚧 - Work in Progress; not ready for release.
- - Long Term Support; receives changes through backports only.
- - In Support; the active version, receiving all bugfixes and features directly.
***
## Library Features
* Universal Config System (TOML Based)
* Built in Helper Classes for Various minecraft features
* Built in Optifine-Compat utilities
* Various utilities for Blockstates, LANG, Math and Rendering
* Cross Mod-Loader Events - Based on [Acara](https://github.com/Keksuccino/acara)
* Cross Mod-Loader Config Screens (Based on [Cloth Config Lite](https://github.com/shedaniel/cloth-config-lite))
* Automatic ModMenu and Forge Config screen registration
* Built in Cross Mod-Loader Network system
* Nojang Modding API
***
## Setup Instructions
There's a **wiki coming soon**, but for now, here's some basic instructions for building the project:
1. `git clone` the project to a safe spot.
2. Install Java's JDK 17. Make sure you have the development version explicitly:
* Fedora: `sudo dnf install java-17-openjdk-devel`
* Ubuntu: `sudo apt install openjdk-17-jdk`
* macOS: `brew install openjdk@17`
3. Set it accordingly:
* Windows/macOS: Set the `JAVA_HOME` environment variable or use system settings
* Linux: `sudo update-alternatives --config java`
4. Navigate to the CraterLib folder, then run a `gradlew` file depending on your operating system:
* Windows: `.\gradlew.bat build`
* macOS/Linux/BSD: `chmod +x gradlew` and `./gradlew`

View File

@@ -1,135 +0,0 @@
plugins {
id 'java'
id 'com.github.johnrengelman.shadow' version '8.1.1' apply false
id "xyz.wagyourtail.unimined" version "1.3.9" apply false
id "com.hypherionmc.modutils.modpublisher" version "2.1.6"
id "com.hypherionmc.modutils.orion" version "1.0.24"
id "com.hypherionmc.modutils.orion.origami" version "1.0.24" apply false
id 'maven-publish'
}
orion.setup {
multiProject = true
enableMirrorMaven = true
enableReleasesMaven = true
dopplerToken = System.getenv("DOPPLER_KEY")
versioning {
var relType = project.properties["releaseType"] ?: "${release_type}"
identifier("${relType}")
}
}
group = project_group
subprojects {
apply plugin: "xyz.wagyourtail.unimined"
apply plugin: "java"
apply plugin: 'maven-publish'
apply plugin: 'com.github.johnrengelman.shadow'
apply plugin: 'com.hypherionmc.modutils.modpublisher'
if (project.name === "Paper") {
apply plugin: 'com.hypherionmc.modutils.orion.origami'
}
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
group = rootProject.group
repositories {
mavenCentral()
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
content {
includeGroup "maven.modrinth"
}
}
maven {
url = "https://unimaven.cc"
}
}
configurations {
shade
modCompileOnly
stupidRemapArch
implementation.extendsFrom shade
compileOnly.extendsFrom modCompileOnly
compileOnly.extendsFrom stupidRemapArch
}
dependencies {
// All Projects
shade "me.hypherionmc.moon-config:core:${moon_config}"
shade "me.hypherionmc.moon-config:toml:${moon_config}"
shade "me.hypherionmc.moon-config:json:${moon_config}"
shade "com.hypherionmc:rpcsdk:${rpc_sdk}"
shade "me.hypherionmc.sdlink:mcdiscordformatter-1.18.1:${discord_formatter}"
shade "net.kyori:adventure-api:${adventure}"
shade "net.kyori:adventure-text-serializer-gson:${adventure}"
shade "net.kyori:adventure-text-minimessage:${adventure}"
stupidRemapArch("dev.ftb.mods:ftb-essentials:${ftb_essentials}")
stupidRemapArch("dev.ftb.mods:ftb-ranks:${ftb_ranks}")
compileOnly 'net.luckperms:api:5.4'
compileOnly("org.projectlombok:lombok:${lombok}")
annotationProcessor("org.projectlombok:lombok:${lombok}")
}
jar {
manifest {
attributes([
'Specification-Title' : mod_name,
'Specification-Vendor' : mod_author,
'Specification-Version' : project.jar.archiveVersion,
'Implementation-Title' : project.name,
'Implementation-Version' : project.jar.archiveVersion,
'Implementation-Vendor' : mod_author,
'Implementation-Timestamp': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
'Timestamp' : System.currentTimeMillis(),
'Built-On-Java' : "${System.getProperty('java.vm.version')} (${System.getProperty('java.vm.vendor')})",
'Built-On-Minecraft' : minecraft_version
])
}
}
/**
* ===============================================================================
* = DO NOT EDIT BELOW THIS LINE UNLESS YOU KNOW WHAT YOU ARE DOING =
* ===============================================================================
*/
if (project.name !== "Paper") {
unimined.minecraft(sourceSets.main, true) {
version minecraft_version
mappings {
mojmap()
devNamespace "mojmap"
}
mods {
remap(configurations.stupidRemapArch) {
catchAWNamespaceAssertion()
}
}
}
}
tasks.withType(JavaCompile).configureEach {
it.options.encoding = 'UTF-8'
it.options.release = 17
}
tasks.withType(GenerateModuleMetadata).configureEach {
enabled = false
}
}
// TODO MODULE JARS

View File

@@ -1,49 +0,0 @@
#Project
version_major=2
version_minor=1
version_patch=5
version_build=0
#Mod
mod_author=HypherionSA
mod_id=craterlib
mod_name=CraterLib
# Shared
minecraft_version=1.18.2
project_group=com.hypherionmc.craterlib
# Fabric
fabric_loader=0.15.11
fabric_api=0.76.0+1.18.2
# Forge
forge_version=40.2.0
# Dependencies
moon_config=1.0.12
lombok=1.18.32
adventure=4.17.0
rpc_sdk=1.0
discord_formatter=2.0.0
cloth_config=6.5.102
# Mod Dependencies
advanced_chat=SNA4dye5
player_revive=5335413
creative_core=5335387
ftb_ranks=1802.1.11-build.71
ftb_essentials=1802.2.2-build.83
fabrictailor=1.9.0+1.18.2
vanish=1.1.0
mod_menu_version=3.2.5
vanishmod=1.1.14
# Publishing
curse_id=867099
modrinth_id=Nn8Wasaq
release_type=release
# Gradle
org.gradle.jvmargs=-Xmx3G
org.gradle.daemon=false

Binary file not shown.

View File

@@ -1,5 +0,0 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

183
1.18.2/gradlew vendored
View File

@@ -1,183 +0,0 @@
#!/usr/bin/env bash
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MSYS* | MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
ARGV=("$@")
eval set -- $DEFAULT_JVM_OPTS
IFS=$'
' read -rd '' -a JAVA_OPTS_ARR <<< "$(echo $JAVA_OPTS | xargs -n1)"
IFS=$'
' read -rd '' -a GRADLE_OPTS_ARR <<< "$(echo $GRADLE_OPTS | xargs -n1)"
exec "$JAVACMD" "$@" "${JAVA_OPTS_ARR[@]}" "${GRADLE_OPTS_ARR[@]}" "-Dorg.gradle.appname=$APP_BASE_NAME" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "${ARGV[@]}"

89
1.18.2/gradlew.bat vendored
View File

@@ -1,89 +0,0 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View File

@@ -1,17 +0,0 @@
pluginManagement {
repositories {
gradlePluginPortal()
maven {
url "https://mcentral.firstdark.dev/releases"
}
maven {
url "https://maven.firstdark.dev/releases"
}
maven {
url "https://maven.firstdark.dev/snapshots"
}
}
}
rootProject.name = 'CraterLib-1.18.2'
include("Common", "Fabric", "Forge")

15
1.19.2/.gitattributes vendored
View File

@@ -1,15 +0,0 @@
* text eol=lf
*.bat text eol=crlf
*.patch text eol=lf
*.java text eol=lf
*.gradle text eol=crlf
*.png binary
*.gif binary
*.exe binary
*.dll binary
*.jar binary
*.lzma binary
*.zip binary
*.pyd binary
*.cfg text eol=lf
*.jks binary

29
1.19.2/.gitignore vendored
View File

@@ -1,29 +0,0 @@
# eclipse
bin
*.launch
.settings
.metadata
.classpath
.project
# idea
out
*.ipr
*.iws
*.iml
.idea
# gradle
build
.gradle
# other
eclipse
run
artifacts
src/test/**
workspace
upstream
rejects

View File

@@ -1,64 +0,0 @@
def majorMc = "1.19.2";
def JDK = "17"
pipeline {
agent {
docker {
image "registry.firstdark.dev/java${JDK}:latest"
alwaysPull true
args '-v gradle-cache:/home/gradle/.gradle'
}
}
environment {
GRADLE_USER_HOME = '/home/gradle/.gradle'
}
stages {
stage("Notify Discord") {
steps {
discordSend webhookURL: env.FDD_WH_ADMIN,
title: "Deploy Started: CraterLib ${majorMc} Deploy #${BUILD_NUMBER}",
link: env.BUILD_URL,
result: 'SUCCESS',
description: "Build: [${BUILD_NUMBER}](${env.BUILD_URL})"
}
}
stage("Prepare") {
steps {
dir("${WORKSPACE}/${majorMc}") {
sh "chmod +x ./gradlew"
sh "./gradlew clean"
}
}
}
stage("Publish to Modrinth/Curseforge") {
steps {
dir("${WORKSPACE}/${majorMc}") {
sh "./gradlew publishMod -Prelease=true"
}
}
}
stage("Publish to Maven") {
steps {
dir("${WORKSPACE}/${majorMc}") {
sh "./gradlew publish -Prelease=true"
}
}
}
}
post {
always {
dir("${WORKSPACE}/${majorMc}") {
sh "./gradlew --stop"
deleteDir()
}
discordSend webhookURL: env.FDD_WH_ADMIN,
title: "CraterLib Port Deploy #${BUILD_NUMBER}",
link: env.BUILD_URL,
result: currentBuild.currentResult,
description: "Build: [${BUILD_NUMBER}](${env.BUILD_URL})\nStatus: ${currentBuild.currentResult}"
}
}
}

View File

@@ -1,80 +0,0 @@
def projectName = "CraterLib";
def projectIcon = "https://cdn.modrinth.com/data/Nn8Wasaq/a172c634683a11a2e9ae593e56eba7885743bb44.png";
def JDK = "17";
def majorMc = "1.19.2";
def modLoaders = "forge|fabric|quilt|paper";
def supportedMc = "1.19.2";
def reltype = "snapshot";
pipeline {
agent {
docker {
image "registry.firstdark.dev/java${JDK}:latest"
alwaysPull true
args '-v gradle-cache:/home/gradle/.gradle'
}
}
environment {
GRADLE_USER_HOME = '/home/gradle/.gradle'
}
stages {
stage('Checkout') {
steps {
scmSkip(deleteBuild: false, skipPattern:'.*\\[ci skip\\].*')
}
}
stage("Notify Discord") {
steps {
discordSend webhookURL: env.SSS_WEBHOOK,
title: "Deploy Started: ${projectName} ${majorMc} Deploy #${BUILD_NUMBER}",
link: env.BUILD_URL,
result: 'SUCCESS',
description: "Build: [${BUILD_NUMBER}](${env.BUILD_URL})"
}
}
stage("Prepare") {
steps {
dir("${WORKSPACE}/${majorMc}") {
sh "chmod +x ./gradlew"
sh "./gradlew build -PreleaseType=${reltype}"
}
}
}
stage("Publish to Maven") {
steps {
dir ("${WORKSPACE}/${majorMc}") {
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
sh "./gradlew publish -PreleaseType=${reltype}"
}
}
}
}
}
post {
always {
dir("${WORKSPACE}/${majorMc}") {
sh "./gradlew --stop"
archiveArtifacts artifacts: 'artifacts/*.jar'
fddsnapshotter apiKey: env.PLATFORM_KEY,
projectSlug: "craterlib",
projectName: "${projectName}",
projectIcon: "${projectIcon}",
modLoaders: "${modLoaders}",
minecraftVersions: "${supportedMc}",
type: "snapshot",
dependsOn: "",
failWebhook: env.SSS_WEBHOOK,
publishWebhooks: "${env.SSS_WEBHOOK}|${env.FDD_WH}"
deleteDir()
}
}
}
}

View File

@@ -1,10 +0,0 @@
package com.hypherionmc.craterlib;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class CraterConstants {
public static final String MOD_ID = "craterlib";
public static final String MOD_NAME = "CraterLib";
public static final Logger LOG = LoggerFactory.getLogger(MOD_NAME);
}

View File

@@ -1,14 +0,0 @@
package com.hypherionmc.craterlib.api.events.client;
import com.hypherionmc.craterlib.core.event.CraterEvent;
import com.hypherionmc.craterlib.nojang.client.multiplayer.BridgedClientLevel;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@Getter
public class CraterClientTickEvent extends CraterEvent {
private final BridgedClientLevel level;
}

View File

@@ -1,21 +0,0 @@
package com.hypherionmc.craterlib.api.events.client;
import com.hypherionmc.craterlib.core.event.CraterEvent;
import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@Getter
public class CraterSinglePlayerEvent extends CraterEvent {
private final BridgedPlayer player;
public static class PlayerLogin extends CraterSinglePlayerEvent {
public PlayerLogin(BridgedPlayer player) {
super(player);
}
}
}

View File

@@ -1,16 +0,0 @@
package com.hypherionmc.craterlib.api.events.client;
import com.hypherionmc.craterlib.core.event.CraterEvent;
import com.hypherionmc.craterlib.nojang.client.BridgedMinecraft;
import com.hypherionmc.craterlib.nojang.client.BridgedOptions;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@Getter
public class LateInitEvent extends CraterEvent {
private final BridgedMinecraft minecraft;
private final BridgedOptions options;
}

View File

@@ -1,14 +0,0 @@
package com.hypherionmc.craterlib.api.events.client;
import com.hypherionmc.craterlib.core.event.CraterEvent;
import com.hypherionmc.craterlib.nojang.realmsclient.dto.BridgedRealmsServer;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@Getter
public class PlayerJoinRealmEvent extends CraterEvent {
private final BridgedRealmsServer server;
}

View File

@@ -1,27 +0,0 @@
package com.hypherionmc.craterlib.api.events.client;
import com.hypherionmc.craterlib.core.event.CraterEvent;
import com.hypherionmc.craterlib.nojang.client.gui.BridgedScreen;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
@Getter
@RequiredArgsConstructor
public class ScreenEvent extends CraterEvent {
private final BridgedScreen screen;
@Getter
public static class Opening extends ScreenEvent {
private final BridgedScreen currentScreen;
@Setter private BridgedScreen newScreen;
public Opening(BridgedScreen currentScreen, BridgedScreen newScreen) {
super(newScreen);
this.currentScreen = currentScreen;
this.newScreen = newScreen;
}
}
}

View File

@@ -1,27 +0,0 @@
package com.hypherionmc.craterlib.api.events.common;
import com.hypherionmc.craterlib.core.event.CraterEvent;
import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer;
import com.hypherionmc.craterlib.utils.ChatUtils;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import net.kyori.adventure.text.Component;
import net.minecraft.world.damagesource.DamageSource;
@RequiredArgsConstructor
@Getter
public class CraterPlayerDeathEvent extends CraterEvent {
private final BridgedPlayer player;
private final DamageSource damageSource;
private Component deathMessage;
public CraterPlayerDeathEvent(BridgedPlayer player, DamageSource source, Component deathMessage) {
this(player, source);
this.deathMessage = deathMessage;
}
public Component getDeathMessage() {
return deathMessage != null ? deathMessage : ChatUtils.mojangToAdventure(damageSource.getLocalizedDeathMessage(player.toMojang()));
}
}

View File

@@ -1,56 +0,0 @@
// @excludeplugin
package com.hypherionmc.craterlib.api.events.compat;
import com.hypherionmc.craterlib.compat.ftbranks.BridgedRank;
import com.hypherionmc.craterlib.core.event.CraterEvent;
import com.hypherionmc.craterlib.nojang.authlib.BridgedGameProfile;
import com.mojang.authlib.GameProfile;
import dev.ftb.mods.ftbranks.api.Rank;
import lombok.Getter;
public class FTBRankEvents {
@Getter
public static class RankAddedEvent extends CraterEvent {
private final BridgedGameProfile gameProfile;
private final BridgedRank rank;
private RankAddedEvent(BridgedGameProfile gameProfile, BridgedRank rank) {
this.gameProfile = gameProfile;
this.rank = rank;
}
public static RankAddedEvent of(GameProfile profile, Rank rank) {
return new RankAddedEvent(BridgedGameProfile.of(profile), BridgedRank.of(rank));
}
}
@Getter
public static class RankRemovedEvent extends CraterEvent {
private final BridgedGameProfile gameProfile;
private final BridgedRank rank;
private RankRemovedEvent(BridgedGameProfile gameProfile, BridgedRank rank) {
this.gameProfile = gameProfile;
this.rank = rank;
}
public static RankRemovedEvent of(GameProfile profile, Rank rank) {
return new RankRemovedEvent(BridgedGameProfile.of(profile), BridgedRank.of(rank));
}
}
@Getter
public static class RankDeletedEvent extends CraterEvent {
private final BridgedRank rank;
private RankDeletedEvent(BridgedRank rank) {
this.rank = rank;
}
public static RankDeletedEvent of(Rank rank) {
return new RankDeletedEvent(BridgedRank.of(rank));
}
}
}

View File

@@ -1,35 +0,0 @@
package com.hypherionmc.craterlib.api.events.compat;
import com.hypherionmc.craterlib.core.event.CraterEvent;
import com.hypherionmc.craterlib.nojang.authlib.BridgedGameProfile;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import java.util.UUID;
public class LuckPermsCompatEvents {
@RequiredArgsConstructor(staticName = "of")
@Getter
public static class GroupAddedEvent extends CraterEvent {
private final String identifier;
private final UUID uuid;
private final String username;
public BridgedGameProfile toProfile() {
return BridgedGameProfile.mojang(uuid, username);
}
}
@RequiredArgsConstructor(staticName = "of")
@Getter
public static class GroupRemovedEvent extends CraterEvent {
private final String identifier;
private final UUID uuid;
private final String username;
public BridgedGameProfile toProfile() {
return BridgedGameProfile.mojang(uuid, username);
}
}
}

View File

@@ -1,12 +0,0 @@
package com.hypherionmc.craterlib.api.events.compat;
import com.hypherionmc.craterlib.core.event.CraterEvent;
import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor(staticName = "of")
@Getter
public class PlayerBleedOutEvent extends CraterEvent {
private final BridgedPlayer player;
}

View File

@@ -1,12 +0,0 @@
package com.hypherionmc.craterlib.api.events.compat;
import com.hypherionmc.craterlib.core.event.CraterEvent;
import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor(staticName = "of")
@Getter
public class PlayerRevivedEvent extends CraterEvent {
private final BridgedPlayer player;
}

View File

@@ -1,34 +0,0 @@
package com.hypherionmc.craterlib.api.events.server;
import com.hypherionmc.craterlib.core.event.CraterEvent;
import com.hypherionmc.craterlib.nojang.advancements.BridgedAdvancement;
import com.hypherionmc.craterlib.nojang.advancements.BridgedDisplayInfo;
import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer;
import lombok.Getter;
import net.kyori.adventure.text.Component;
import java.util.Optional;
@Getter
public class CraterAdvancementEvent extends CraterEvent {
private final BridgedAdvancement advancement;
private final BridgedPlayer player;
private final Component title;
private final Component description;
public CraterAdvancementEvent(BridgedPlayer player, BridgedAdvancement advancement) {
this.advancement = advancement;
this.player = player;
Optional<BridgedDisplayInfo> displayInfo = advancement.displayInfo();
if (displayInfo.isPresent()) {
this.title = displayInfo.get().displayName();
this.description = displayInfo.get().description();
} else {
this.title = Component.text("Unknown");
this.description = Component.text("Unknown");
}
}
}

View File

@@ -1,58 +0,0 @@
package com.hypherionmc.craterlib.api.events.server;
import com.hypherionmc.craterlib.core.event.CraterEvent;
import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer;
import com.hypherionmc.craterlib.utils.ChatUtils;
import com.mojang.brigadier.ParseResults;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.context.StringRange;
import lombok.Getter;
import lombok.Setter;
import net.kyori.adventure.text.Component;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.arguments.ComponentArgument;
import net.minecraft.world.entity.player.Player;
import org.jetbrains.annotations.Nullable;
@Getter
public class CraterCommandEvent extends CraterEvent {
private final ParseResults<CommandSourceStack> parseResults;
@Setter private Throwable exception;
private final String command;
private CraterCommandEvent(ParseResults<CommandSourceStack> parseResults, String command) {
this.parseResults = parseResults;
this.command = command;
}
public static CraterCommandEvent of(ParseResults<CommandSourceStack> stack, String command) {
return new CraterCommandEvent(stack, command);
}
public String getCommandString() {
return parseResults.getReader().getString();
}
@Nullable
public BridgedPlayer getPlayer() {
try {
Player p = parseResults.getContext().getLastChild().getSource().getPlayer();
if (p != null)
return BridgedPlayer.of(p);
} catch (Exception ignored) {}
return null;
}
public String getTarget() {
CommandContext<CommandSourceStack> context = parseResults.getContext().build(parseResults.getReader().getString());
StringRange selector_range = parseResults.getContext().getArguments().get("targets").getRange();
return context.getInput().substring(selector_range.getStart(), selector_range.getEnd());
}
public Component getMessage() {
return ChatUtils.mojangToAdventure(ComponentArgument.getComponent(parseResults.getContext().build(parseResults.getReader().getString()), "message"));
}
}

View File

@@ -1,44 +0,0 @@
package com.hypherionmc.craterlib.api.events.server;
import com.hypherionmc.craterlib.core.event.CraterEvent;
import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@Getter
public class CraterPlayerEvent extends CraterEvent {
private final BridgedPlayer player;
@Getter
public static class PlayerLoggedIn extends CraterPlayerEvent {
private final boolean isFromVanish;
public PlayerLoggedIn(BridgedPlayer player) {
this(player, false);
}
public PlayerLoggedIn(BridgedPlayer player, boolean isFromVanish) {
super(player);
this.isFromVanish = isFromVanish;
}
}
@Getter
public static class PlayerLoggedOut extends CraterPlayerEvent {
private final boolean isFromVanish;
public PlayerLoggedOut(BridgedPlayer player) {
this(player, false);
}
public PlayerLoggedOut(BridgedPlayer player, boolean isFromVanish) {
super(player);
this.isFromVanish = isFromVanish;
}
}
}

View File

@@ -1,18 +0,0 @@
package com.hypherionmc.craterlib.api.events.server;
import com.hypherionmc.craterlib.api.commands.CraterCommand;
import com.hypherionmc.craterlib.core.event.CraterEvent;
import com.mojang.brigadier.CommandDispatcher;
import lombok.AllArgsConstructor;
import net.minecraft.commands.CommandSourceStack;
@AllArgsConstructor
public class CraterRegisterCommandEvent extends CraterEvent {
private final CommandDispatcher<CommandSourceStack> stack;
public void registerCommand(CraterCommand cmd) {
cmd.register(stack);
}
}

View File

@@ -1,25 +0,0 @@
package com.hypherionmc.craterlib.api.events.server;
import com.hypherionmc.craterlib.core.event.CraterEvent;
import com.hypherionmc.craterlib.core.event.annot.Cancellable;
import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer;
import lombok.Getter;
import lombok.Setter;
import net.kyori.adventure.text.Component;
@Cancellable
@Getter
public class CraterServerChatEvent extends CraterEvent {
public final String message, username;
public final BridgedPlayer player;
@Setter private Component component;
public CraterServerChatEvent(BridgedPlayer player, String message, Component component) {
this.message = message;
this.player = player;
this.username = player.getGameProfile().getName();
this.component = component;
}
}

View File

@@ -1,34 +0,0 @@
package com.hypherionmc.craterlib.api.events.server;
import com.hypherionmc.craterlib.core.event.CraterEvent;
import com.hypherionmc.craterlib.nojang.server.BridgedMinecraftServer;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
public class CraterServerLifecycleEvent extends CraterEvent {
@RequiredArgsConstructor
@Getter
public static class Starting extends CraterServerLifecycleEvent {
private final BridgedMinecraftServer server;
}
@RequiredArgsConstructor
@Getter
public static class Started extends CraterServerLifecycleEvent {
private final BridgedMinecraftServer server;
}
@RequiredArgsConstructor
@Getter
public static class Stopping extends CraterServerLifecycleEvent {
private final BridgedMinecraftServer server;
}
@RequiredArgsConstructor
@Getter
public static class Stopped extends CraterServerLifecycleEvent {
private final BridgedMinecraftServer server;
}
}

View File

@@ -1,20 +0,0 @@
package com.hypherionmc.craterlib.api.events.server;
import com.hypherionmc.craterlib.core.event.CraterEvent;
import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import net.kyori.adventure.text.Component;
import java.util.function.Function;
@RequiredArgsConstructor
@Getter
public class MessageBroadcastEvent extends CraterEvent {
private final Component component;
private final Function<BridgedPlayer, Component> function;
private final boolean bl;
private final String threadName;
}

View File

@@ -1,20 +0,0 @@
package com.hypherionmc.craterlib.api.events.server;
import com.hypherionmc.craterlib.core.event.CraterEvent;
import com.hypherionmc.craterlib.nojang.authlib.BridgedGameProfile;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import net.kyori.adventure.text.Component;
import java.net.SocketAddress;
@RequiredArgsConstructor
@Getter
public class PlayerPreLoginEvent extends CraterEvent {
private final SocketAddress address;
private final BridgedGameProfile gameProfile;
@Setter private Component message;
}

View File

@@ -1,35 +0,0 @@
package com.hypherionmc.craterlib.api.events.server;
import com.hypherionmc.craterlib.core.event.CraterEvent;
import com.hypherionmc.craterlib.nojang.network.protocol.status.WrappedServerStatus;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import net.kyori.adventure.text.Component;
import org.jetbrains.annotations.Nullable;
import java.util.Optional;
public class ServerStatusEvent {
@RequiredArgsConstructor
@Getter
@Setter
public static class StatusRequestEvent extends CraterEvent {
private final Component status;
@Nullable
private Component newStatus = null;
}
@RequiredArgsConstructor
@Getter
@Setter
public static class FaviconRequestEvent extends CraterEvent {
private final Optional<WrappedServerStatus.WrappedFavicon> favicon;
private Optional<WrappedServerStatus.WrappedFavicon> newIcon = Optional.empty();
}
}

View File

@@ -1,26 +0,0 @@
package com.hypherionmc.craterlib.api.events.server;
import com.hypherionmc.craterlib.core.event.CraterEvent;
import com.hypherionmc.craterlib.nojang.authlib.BridgedGameProfile;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
public class WhitelistChangedEvent {
@RequiredArgsConstructor
@Getter
public static final class EntryAdded extends CraterEvent {
private final BridgedGameProfile profile;
}
@RequiredArgsConstructor
@Getter
public static final class EntryRemoved extends CraterEvent {
private final BridgedGameProfile profile;
}
}

View File

@@ -1,28 +0,0 @@
package com.hypherionmc.craterlib.api.networking;
import com.hypherionmc.craterlib.nojang.server.BridgedMinecraftServer;
import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer;
import java.util.List;
/**
* Based on https://github.com/mysticdrew/common-networking/tree/1.20.4
*/
public interface CraterNetworkHandler {
<T> void sendToServer(T packet);
<T> void sendToServer(T packet, boolean ignoreCheck);
<T> void sendToClient(T packet, BridgedPlayer player);
default <T> void sendToClients(T packet, List<BridgedPlayer> players) {
for (BridgedPlayer player : players) {
sendToClient(packet, player);
}
}
default <T> void sendToAllClients(T packet, BridgedMinecraftServer server) {
sendToClients(packet, server.getPlayers());
}
}

Some files were not shown because too many files have changed in this diff Show More