Compare commits

...

24 commits

Author SHA1 Message Date
bafaa358d5 added forgejo workflow file 2025-06-09 21:49:04 +02:00
2395370a7b version bump 2025-06-09 21:46:14 +02:00
9f3750b52d fixed github actions java version 2024-06-21 23:45:55 +02:00
261aa55568 port to 1.21 2024-06-21 23:16:13 +02:00
e9d1537d83 bumped version 2024-05-11 19:31:28 +02:00
7c65b9c0ff removed debug code 2024-05-11 19:31:24 +02:00
95777078b0 removed wrong error message 2024-05-11 19:31:15 +02:00
1ed05887f8 fixed error on no newline 2024-05-11 19:31:00 +02:00
06fc172a6b updated project 2024-05-11 19:30:30 +02:00
8b110345c4 Port to 1.20.3/.4 2023-12-13 03:33:05 +01:00
eb9464e60a bumped version to first full release! 2023-09-26 23:56:22 +02:00
5937c06074 Removed ExecutionBlockTimeout from config file
Removed the block timeout property from the config file documentation in the comments
2023-09-26 23:55:59 +02:00
d287466669 Removed ExecutionBlockTimeout property
Removed ExecutionBLockTimeout property since it is pointless
2023-09-26 23:46:21 +02:00
01214a78e7 Added Command ExecutionTimeout
Added the long missing feature of a timeout after which the process would be cleared as specified in the config file
2023-09-26 23:34:11 +02:00
f897d7630e Fixed Command Output Buffering
Fixed an issue where the Server would wait for the Command Process to terminate before returning the Command Output
2023-09-26 23:32:49 +02:00
2f759e2edf Fixed wrong line in Error Code
Fixed an issue where the wrong line was showing in the Error Code
2023-09-26 23:31:46 +02:00
a4d242b6ef Fixed typos
Fixed typos in the comments of the command config file
2023-09-26 23:30:45 +02:00
3c73ed16a5 Added lombok getters
Cleaned up some lines by using lombok.Getter
2023-09-26 23:28:06 +02:00
f4c6c6d22a
removed fixed bugs from list 2023-09-12 10:29:57 +02:00
Jonas_Jones
076017bec5 code cleanup and respect command return type 2023-09-07 20:23:05 +02:00
Jonas_Jones
3ea416faea added config toggle for console command log 2023-09-07 19:39:22 +02:00
Jonas_Jones
d7f982af05 fixed player not getting command feedback 2023-09-07 19:38:38 +02:00
Jonas_Jones
bdb60f3ebe fixed only 1 command being registered 2023-09-07 19:17:50 +02:00
Jonas_Jones
f4ef7ba992 improved bad english 2023-09-07 19:02:09 +02:00
18 changed files with 220 additions and 136 deletions

View file

@ -0,0 +1,41 @@
name: build-java
on: [ push, pull_request ]
jobs:
build:
runs-on: docker
steps:
- name: checkout repository
uses: https://code.forgejo.org/actions/checkout@v4
- name: setup jdk
uses: https://github.com/actions/setup-java@v4
with:
java-version: |
8
21
distribution: temurin
- name: restore cached dependencies
uses: https://code.forgejo.org/actions/cache/restore@v4
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-Gradle
- name: build
run: ./gradlew build --no-daemon --warning-mode=all
- name: capture build artifacts
uses: https://code.forgejo.org/forgejo/upload-artifact@v4
with:
name: build-artifacts.zip
path: |
build/libs
!build/libs/*-all.jar
if-no-files-found: error
- name: cache downloaded dependencies
if: ${{ github.ref_name == github.event.repository.default_branch }}
uses: https://code.forgejo.org/actions/cache/save@v4
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-Gradle

View file

@ -12,7 +12,7 @@ jobs:
matrix: matrix:
# Use these Java versions # Use these Java versions
java: [ java: [
17, # Current Java LTS & minimum supported by Minecraft 21, # Current Java LTS
] ]
# and run on both Linux and Windows # and run on both Linux and Windows
os: [ubuntu-22.04, windows-2022] os: [ubuntu-22.04, windows-2022]

View file

@ -38,9 +38,6 @@ Beware that anyone who has write access to the MC server's files is able to edit
5. Restart your Minecraft server and You're good to go! 5. Restart your Minecraft server and You're good to go!
# KNOWN ISSUES # KNOWN ISSUES
- It is only possible to define a single command at this point - subject to change once I figure out how to do things - Execution Timeout and Execution block Timeout have no effect on the command at this point
- Execution Timeout and Execution block Timeout have no effect on the command at this point.
- The command mode has no effect on the command feedback itself. in any case, the output will be sent in chat
- the console is spamed with debug messages - the console is spamed with debug messages
- threads are not closed after a task exits - threads are not closed after a task exit
- and many more....

View file

@ -1,15 +1,15 @@
plugins { plugins {
id 'fabric-loom' version '1.0-SNAPSHOT' id 'fabric-loom' version '1.10-SNAPSHOT'
id 'maven-publish' id 'maven-publish'
} }
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
archivesBaseName = project.archives_base_name
version = project.mod_version version = project.mod_version
group = project.maven_group group = project.maven_group
base {
archivesName = project.archives_base_name
}
repositories { repositories {
// Add repositories to retrieve artifacts from in here. // Add repositories to retrieve artifacts from in here.
// You should only use this when depending on other mods because // You should only use this when depending on other mods because
@ -18,6 +18,18 @@ repositories {
// for more information about repositories. // for more information about repositories.
} }
loom {
splitEnvironmentSourceSets()
mods {
"modid" {
sourceSet sourceSets.main
sourceSet sourceSets.client
}
}
}
dependencies { dependencies {
// To change the versions see the gradle.properties file // To change the versions see the gradle.properties file
minecraft "com.mojang:minecraft:${project.minecraft_version}" minecraft "com.mojang:minecraft:${project.minecraft_version}"
@ -27,23 +39,21 @@ dependencies {
// Fabric API. This is technically optional, but you probably want it anyway. // Fabric API. This is technically optional, but you probably want it anyway.
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
// Uncomment the following line to enable the deprecated Fabric API modules. compileOnly 'org.projectlombok:lombok:1.18.32'
// These are included in the Fabric API production distribution and allow you to update your mod to the latest modules at a later more convenient time. annotationProcessor 'org.projectlombok:lombok:1.18.32'
// modImplementation "net.fabricmc.fabric-api:fabric-api-deprecated:${project.fabric_version}"
} }
processResources { processResources {
inputs.property "version", project.version inputs.property "version", project.version
filesMatching("fabric.mod.json") { filesMatching("fabric.mod.json") {
expand "version": project.version expand "version": inputs.properties.version
} }
} }
tasks.withType(JavaCompile).configureEach { tasks.withType(JavaCompile).configureEach {
// Minecraft 1.18 (1.18-pre2) upwards uses Java 17. it.options.release = 21
it.options.release = 17
} }
java { java {
@ -51,18 +61,24 @@ java {
// if it is present. // if it is present.
// If you remove this line, sources will not be generated. // If you remove this line, sources will not be generated.
withSourcesJar() withSourcesJar()
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
} }
jar { jar {
inputs.property "archivesName", project.base.archivesName
from("LICENSE") { from("LICENSE") {
rename { "${it}_${project.archivesBaseName}"} rename { "${it}_${inputs.properties.archivesName}"}
} }
} }
// configure the maven publication // configure the maven publication
publishing { publishing {
publications { publications {
mavenJava(MavenPublication) { create("mavenJava", MavenPublication) {
artifactId = project.archives_base_name
from components.java from components.java
} }
} }

View file

@ -3,14 +3,15 @@ org.gradle.jvmargs=-Xmx1G
org.gradle.parallel=true org.gradle.parallel=true
# Fabric Properties; # Fabric Properties;
minecraft_version=1.20.1 minecraft_version=1.21.5
yarn_mappings=1.20.1+build.10 yarn_mappings=1.21.5+build.1
loader_version=0.14.22 loader_version=0.16.14
loom_version=1.10-SNAPSHOT
# Mod Properties # Mod Properties
mod_version = 0.0.1+alpha-build03 mod_version = 1.0.2
maven_group = me.jonasjones maven_group = me.jonasjones
archives_base_name = betterconsolemc archives_base_name = betterconsolemc
# Dependencies # Dependencies
fabric_version=0.88.1+1.20.1 fabric_version=0.126.0+1.21.5

Binary file not shown.

View file

@ -1,6 +1,7 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.12.1-bin.zip
networkTimeout=10000 networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

33
gradlew vendored
View file

@ -15,6 +15,8 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
# #
# SPDX-License-Identifier: Apache-2.0
#
############################################################################## ##############################################################################
# #
@ -55,7 +57,7 @@
# Darwin, MinGW, and NonStop. # Darwin, MinGW, and NonStop.
# #
# (3) This script is generated from the Groovy template # (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project. # within the Gradle project.
# #
# You can find Gradle at https://github.com/gradle/gradle/. # You can find Gradle at https://github.com/gradle/gradle/.
@ -83,10 +85,8 @@ done
# This is normally unused # This is normally unused
# shellcheck disable=SC2034 # shellcheck disable=SC2034
APP_BASE_NAME=${0##*/} APP_BASE_NAME=${0##*/}
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
# 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. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum MAX_FD=maximum
@ -133,10 +133,13 @@ location of your Java installation."
fi fi
else else
JAVACMD=java 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. if ! command -v java >/dev/null 2>&1
then
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 Please set the JAVA_HOME variable in your environment to match the
location of your Java installation." location of your Java installation."
fi
fi fi
# Increase the maximum file descriptors if we can. # Increase the maximum file descriptors if we can.
@ -144,7 +147,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #( case $MAX_FD in #(
max*) max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045 # shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) || MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit" warn "Could not query maximum file descriptor limit"
esac esac
@ -152,7 +155,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
'' | soft) :;; #( '' | soft) :;; #(
*) *)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045 # shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" || ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD" warn "Could not set maximum file descriptor limit to $MAX_FD"
esac esac
@ -197,11 +200,15 @@ if "$cygwin" || "$msys" ; then
done done
fi fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
# shell script including quotes and variable substitutions, so put them in DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded. # Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \ set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \ "-Dorg.gradle.appname=$APP_BASE_NAME" \

22
gradlew.bat vendored
View file

@ -13,6 +13,8 @@
@rem See the License for the specific language governing permissions and @rem See the License for the specific language governing permissions and
@rem limitations under the License. @rem limitations under the License.
@rem @rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off @if "%DEBUG%"=="" @echo off
@rem ########################################################################## @rem ##########################################################################
@ -43,11 +45,11 @@ set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1 %JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute if %ERRORLEVEL% equ 0 goto execute
echo. echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. echo location of your Java installation. 1>&2
goto fail goto fail
@ -57,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute if exist "%JAVA_EXE%" goto execute
echo. echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. echo location of your Java installation. 1>&2
goto fail goto fail

View file

@ -1,10 +1,10 @@
pluginManagement { pluginManagement {
repositories { repositories {
maven { maven {
name = 'Fabric' name = 'Fabric'
url = 'https://maven.fabricmc.net/' url = 'https://maven.fabricmc.net/'
} }
mavenCentral() mavenCentral()
gradlePluginPortal() gradlePluginPortal()
} }
} }

View file

@ -2,17 +2,17 @@ package me.jonasjones.betterconsolemc;
import me.jonasjones.betterconsolemc.cmdconfig.CmdConfigHandler; import me.jonasjones.betterconsolemc.cmdconfig.CmdConfigHandler;
import me.jonasjones.betterconsolemc.cmdconfig.CmdConfigs; import me.jonasjones.betterconsolemc.cmdconfig.CmdConfigs;
import me.jonasjones.betterconsolemc.command.GameCommandHandler;
import me.jonasjones.betterconsolemc.modconfig.ModConfigs; import me.jonasjones.betterconsolemc.modconfig.ModConfigs;
import me.jonasjones.betterconsolemc.util.CommandPreRegistry; import me.jonasjones.betterconsolemc.util.CommandPreRegistry;
import net.fabricmc.api.ModInitializer; import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.FabricLoader;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.nio.file.Path; import java.nio.file.Path;
import static me.jonasjones.betterconsolemc.command.GameCommandHandler.registerCommands;
public class BetterConsoleMC implements ModInitializer { public class BetterConsoleMC implements ModInitializer {
// This logger is used to write text to the console and the log file. // This logger is used to write text to the console and the log file.
// It is considered best practice to use your mod id as the logger's name. // It is considered best practice to use your mod id as the logger's name.
@ -24,13 +24,6 @@ public class BetterConsoleMC implements ModInitializer {
public static Path CONFIGDIR = FabricLoader.getInstance().getConfigDir(); public static Path CONFIGDIR = FabricLoader.getInstance().getConfigDir();
public static CommandPreRegistry COMMANDPREREGISTRY; public static CommandPreRegistry COMMANDPREREGISTRY;
public static void registerCommands() {
for (CommandPreRegistry commandPreRegistry : CmdConfigHandler.FULLREG) {
COMMANDPREREGISTRY = commandPreRegistry;
CommandRegistrationCallback.EVENT.register(GameCommandHandler::register);
}
}
@Override @Override
public void onInitialize() { public void onInitialize() {
// This code runs as soon as Minecraft is in a mod-load-ready state. // This code runs as soon as Minecraft is in a mod-load-ready state.
@ -45,7 +38,7 @@ public class BetterConsoleMC implements ModInitializer {
} catch (Exception e) { } catch (Exception e) {
ModConfigs.IS_ENABLED = false; ModConfigs.IS_ENABLED = false;
LOGGER.error("SYNTAX ERROR(S) IN COMMAND CONFIG FILE OF BETTERCONSOLEMC"); LOGGER.error("SYNTAX ERROR(S) IN COMMAND CONFIG FILE OF BETTERCONSOLEMC");
LOGGER.error("For security reasons, the mod has therefore beeen disabled and all commands are therefore nonfunctional"); LOGGER.error("For security reasons, the mod has beeen disabled and all commands are nonfunctional");
} }
} }
} }

View file

@ -20,11 +20,10 @@ public class CmdConfigHandler {
public static void getCommands(String path) throws IOException { public static void getCommands(String path) throws IOException {
List<CommandPreRegistry> commands = new ArrayList<CommandPreRegistry>(); List<CommandPreRegistry> commands = new ArrayList<CommandPreRegistry>();
BufferedReader reader = new BufferedReader(new FileReader(path)); BufferedReader reader = new BufferedReader(new FileReader(path));
int linecount = 0; int linecount = 1;
String linecontent = reader.readLine(); String linecontent = reader.readLine();
while (linecontent != null) { while (!linecontent.isEmpty()) {
if (!linecontent.startsWith("#") || linecontent.equals("")) { if (!linecontent.startsWith("#") || linecontent.equals("\n")) {
System.out.println(linecontent);
try { try {
commands.add(preRegisterCommands(linecontent)); commands.add(preRegisterCommands(linecontent));
} catch (Exception e) { } catch (Exception e) {
@ -33,6 +32,9 @@ public class CmdConfigHandler {
} }
} }
linecontent = reader.readLine(); linecontent = reader.readLine();
if (linecontent == null) {
break;
}
linecount++; linecount++;
} }
FULLREG = commands; FULLREG = commands;
@ -43,12 +45,11 @@ public class CmdConfigHandler {
CmdMode commandMode = getCommandMode(configCommandDef); CmdMode commandMode = getCommandMode(configCommandDef);
int permissionLevel = getPermissionLevel(configCommandDef); int permissionLevel = getPermissionLevel(configCommandDef);
int execTimeout = getExecTimeout(configCommandDef); int execTimeout = getExecTimeout(configCommandDef);
int execRerunTimeout = getExecRerunTiemout(configCommandDef);
boolean broadcastToOP = doBroadcastToOP(configCommandDef); boolean broadcastToOP = doBroadcastToOP(configCommandDef);
String ingameCommand = getIngameCommand(configCommandDef); String ingameCommand = getIngameCommand(configCommandDef);
String command = getCommand(configCommandDef); String command = getCommand(configCommandDef);
preRegisteredCommand.init(commandMode, command, permissionLevel, execTimeout, ingameCommand, execRerunTimeout, broadcastToOP); preRegisteredCommand.init(commandMode, command, permissionLevel, execTimeout, ingameCommand, broadcastToOP);
return preRegisteredCommand; return preRegisteredCommand;
} }
@ -80,21 +81,17 @@ public class CmdConfigHandler {
} }
private static String getIngameCommand(String configCommandDef) { private static String getIngameCommand(String configCommandDef) {
return getSplitCommandPartByIndex(configCommandDef, 5);
}
private static int getExecRerunTiemout(String configCommandDef) {
return Integer.parseInt(getSplitCommandPartByIndex(configCommandDef, 3));
}
private static String getBroadcastToOP(String configCommandDef) throws BroadcastToOpNotBoolException {
return getSplitCommandPartByIndex(configCommandDef, 4); return getSplitCommandPartByIndex(configCommandDef, 4);
} }
private static String getBroadcastToOP(String configCommandDef) throws BroadcastToOpNotBoolException {
return getSplitCommandPartByIndex(configCommandDef, 3);
}
private static boolean doBroadcastToOP(String configCommandDef) throws BroadcastToOpNotBoolException { private static boolean doBroadcastToOP(String configCommandDef) throws BroadcastToOpNotBoolException {
if (getSplitCommandPartByIndex(configCommandDef, 4).equals("true")) { if (getSplitCommandPartByIndex(configCommandDef, 3).equals("true")) {
return true; return true;
} else if (getSplitCommandPartByIndex(configCommandDef, 5).equals("false")) { } else if (getSplitCommandPartByIndex(configCommandDef, 4).equals("false")) {
return false; return false;
} else { } else {
throw new BroadcastToOpNotBoolException(); throw new BroadcastToOpNotBoolException();
@ -102,7 +99,7 @@ public class CmdConfigHandler {
} }
private static String getCommand(String configCommandDef) throws Exception { private static String getCommand(String configCommandDef) throws Exception {
return configCommandDef.replaceFirst(getCommandMode(configCommandDef).name() + " " + getPermissionLevel(configCommandDef) + " " + getExecTimeout(configCommandDef) + " " + getExecRerunTiemout(configCommandDef) + " " + getBroadcastToOP(configCommandDef) + " " + getIngameCommand(configCommandDef) + " ", "") return configCommandDef.replaceFirst(getCommandMode(configCommandDef).name() + " " + getPermissionLevel(configCommandDef) + " " + getExecTimeout(configCommandDef) + " " + getBroadcastToOP(configCommandDef) + " " + getIngameCommand(configCommandDef) + " ", "")
.replaceFirst("\"", "") .replaceFirst("\"", "")
.replaceAll("\"$", ""); .replaceAll("\"$", "");
} }

View file

@ -22,12 +22,12 @@ public class CmdConfigs {
private static void createConfigs() { private static void createConfigs() {
cmdconfigs.addSingleLineComment("This is the command configuration file for BetterConsoleMC"); cmdconfigs.addSingleLineComment("This is the command configuration file for BetterConsoleMC");
if (ISWINDOWS) { if (ISWINDOWS) {
cmdconfigs.addSingleLineComment("This message is there to remind you that the mod is running on a WINODWS machine"); cmdconfigs.addSingleLineComment("This message is there to remind you that the mod is running on a WINDOWS machine");
} else { } else {
cmdconfigs.addSingleLineComment("This message is there to remind you that the mod is running on a UNIX-LIKE machine"); cmdconfigs.addSingleLineComment("This message is there to remind you that the mod is running on a UNIX-LIKE machine");
} }
cmdconfigs.addSingleLineComment("The general syntax of defining a command goes like this:"); cmdconfigs.addSingleLineComment("The general syntax of defining a command goes like this:");
cmdconfigs.addSingleLineComment("[Command Mode] [Permissione Level] [Execution Timeout] [Execution Block Timeout] [Broadcast to OP] [Ingame Command name] [command to execute]"); cmdconfigs.addSingleLineComment("[Command Mode] [Permission Level] [Execution Timeout] [Broadcast to OP] [In-game Command name] [command to execute]");
cmdconfigs.addSingleLineComment("Documentation and examples are available at the wiki of the repository"); cmdconfigs.addSingleLineComment("Documentation and examples are available at the wiki of the repository");
} }

View file

@ -3,8 +3,11 @@ package me.jonasjones.betterconsolemc.command;
import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.context.CommandContext;
import me.jonasjones.betterconsolemc.BetterConsoleMC; import me.jonasjones.betterconsolemc.BetterConsoleMC;
import me.jonasjones.betterconsolemc.cmdconfig.CmdConfigHandler;
import me.jonasjones.betterconsolemc.system.ShellCommand; import me.jonasjones.betterconsolemc.system.ShellCommand;
import me.jonasjones.betterconsolemc.util.CommandPreRegistry; import me.jonasjones.betterconsolemc.util.CommandPreRegistry;
import me.jonasjones.betterconsolemc.util.Constants;
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
import net.minecraft.command.CommandRegistryAccess; import net.minecraft.command.CommandRegistryAccess;
import net.minecraft.server.command.CommandManager; import net.minecraft.server.command.CommandManager;
import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.command.ServerCommandSource;
@ -13,21 +16,31 @@ import net.minecraft.text.Text;
import static me.jonasjones.betterconsolemc.BetterConsoleMC.COMMANDPREREGISTRY; import static me.jonasjones.betterconsolemc.BetterConsoleMC.COMMANDPREREGISTRY;
public class GameCommandHandler { public class GameCommandHandler {
public static void register(CommandDispatcher<ServerCommandSource> serverCommandSourceCommandDispatcher, CommandRegistryAccess commandRegistryAccess, CommandManager.RegistrationEnvironment registrationEnvironment) {
serverCommandSourceCommandDispatcher.register((CommandManager.literal(COMMANDPREREGISTRY.getIngamecommand()).requires(source -> source.hasPermissionLevel(COMMANDPREREGISTRY.getPermissionLevel())) public static void registerCommands() {
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
for (CommandPreRegistry commandPreRegistry : CmdConfigHandler.FULLREG) {
COMMANDPREREGISTRY = commandPreRegistry;
register(dispatcher, registryAccess, environment, COMMANDPREREGISTRY);
}
});
}
public static void register(CommandDispatcher<ServerCommandSource> serverCommandSourceCommandDispatcher, CommandRegistryAccess commandRegistryAccess, CommandManager.RegistrationEnvironment registrationEnvironment, CommandPreRegistry commandPreRegistry) {
serverCommandSourceCommandDispatcher.register((CommandManager.literal(commandPreRegistry.getIngamecommand()).requires(source -> source.hasPermissionLevel(commandPreRegistry.getPermissionLevel()))
.executes((context -> { .executes((context -> {
context.getSource().sendFeedback(() -> runCommand(COMMANDPREREGISTRY, context), COMMANDPREREGISTRY.doBroadcastToOp()); if (commandPreRegistry.getCommandmode() == Constants.CmdMode.RETURN) {
runCommand(commandPreRegistry, context);
return 1;
}
return 1; return 1;
}))) })))
); );
} }
public static Text runCommand(CommandPreRegistry commandPreRegistry, CommandContext<ServerCommandSource> context) { public static Text runCommand(CommandPreRegistry commandPreRegistry, CommandContext<ServerCommandSource> context) {
new Thread(() -> { return Text.of(ShellCommand.execute(commandPreRegistry, context));
ShellCommand.execute(commandPreRegistry, context);
}).start();
return Text.of("Return");
} }
public static void returnCommandOutput(String cmd, String commandFeedback, CommandContext<ServerCommandSource> context) { public static void returnCommandOutput(String cmd, String commandFeedback, CommandContext<ServerCommandSource> context) {

View file

@ -7,6 +7,7 @@ public class ModConfigs {
public static SimpleConfig MODCONFIG; public static SimpleConfig MODCONFIG;
public static boolean IS_ENABLED; public static boolean IS_ENABLED;
public static boolean REUQIRE_OP; public static boolean REUQIRE_OP;
public static boolean LOG_CMD_OUTPUT;
private static ModConfigProvider modconfigs; private static ModConfigProvider modconfigs;
public static void registerConfigs() { public static void registerConfigs() {
@ -22,11 +23,13 @@ public class ModConfigs {
modconfigs.addSingleLineComment("This is the config file for BetterConsoleMC"); modconfigs.addSingleLineComment("This is the config file for BetterConsoleMC");
modconfigs.addKeyValuePair(new Pair<>("bettercmd.enable", true), "whether or not to the mod is enabled or not."); modconfigs.addKeyValuePair(new Pair<>("bettercmd.enable", true), "whether or not to the mod is enabled or not.");
modconfigs.addKeyValuePair(new Pair<>("bettercmd.requireOp", true), "whether or not operator level is required in order to run commands."); modconfigs.addKeyValuePair(new Pair<>("bettercmd.requireOp", true), "whether or not operator level is required in order to run commands.");
modconfigs.addKeyValuePair(new Pair<>("bettercmd.logCmdOutput", false), "whether or not to log the output of commands to the console.");
} }
private static void assignConfigs() { private static void assignConfigs() {
IS_ENABLED = MODCONFIG.getOrDefault("cmd.enable", true); IS_ENABLED = MODCONFIG.getOrDefault("cmd.enable", true);
REUQIRE_OP = MODCONFIG.getOrDefault("cmd.requireOp", true); REUQIRE_OP = MODCONFIG.getOrDefault("cmd.requireOp", true);
LOG_CMD_OUTPUT = MODCONFIG.getOrDefault("cmd.logCmdOutput", false);
SimpleConfig.LOGGER.info("All " + modconfigs.getConfigsList().size() + " have been set properly"); SimpleConfig.LOGGER.info("All " + modconfigs.getConfigsList().size() + " have been set properly");
} }

View file

@ -62,8 +62,10 @@ public class SimpleConfig {
try { try {
loadConfig(); loadConfig();
} catch (Exception e) { } catch (Exception e) {
LOGGER.error(identifier + " failed to load!"); if (!identifier.equals("Config 'betterconsolemc-commands_config'")) { // this is good code, I swear
LOGGER.trace(e); LOGGER.error(identifier + " failed to load!");
LOGGER.trace(e);
}
broken = true; broken = true;
} }
} }

View file

@ -3,15 +3,19 @@ package me.jonasjones.betterconsolemc.system;
import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.context.CommandContext;
import me.jonasjones.betterconsolemc.BetterConsoleMC; import me.jonasjones.betterconsolemc.BetterConsoleMC;
import me.jonasjones.betterconsolemc.command.GameCommandHandler; import me.jonasjones.betterconsolemc.command.GameCommandHandler;
import me.jonasjones.betterconsolemc.modconfig.ModConfigs;
import me.jonasjones.betterconsolemc.util.CommandPreRegistry; import me.jonasjones.betterconsolemc.util.CommandPreRegistry;
import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.text.Text;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
public class ShellCommand { public class ShellCommand {
public static int execute(CommandPreRegistry command, CommandContext<ServerCommandSource> context) { public static String execute(CommandPreRegistry command, CommandContext<ServerCommandSource> context) {
StringBuilder output = new StringBuilder();
ProcessBuilder processBuilder = new ProcessBuilder(); ProcessBuilder processBuilder = new ProcessBuilder();
if (BetterConsoleMC.ISWINDOWS) { if (BetterConsoleMC.ISWINDOWS) {
@ -24,26 +28,60 @@ public class ShellCommand {
Process process = processBuilder.start(); Process process = processBuilder.start();
//set timeout
long timeout = System.currentTimeMillis()/1000L + command.getExecTimeout();
//if timeout is 0, set it to not have a timeout
if (command.getExecTimeout() == 0) {
timeout = Long.MAX_VALUE;
}
BufferedReader reader = BufferedReader reader =
new BufferedReader(new InputStreamReader(process.getInputStream())); new BufferedReader(new InputStreamReader(process.getInputStream()));
String line; String line;
// WIP
//System.out.println("TIMEOUT: " + timeout);
//System.out.println("TIME: " + System.currentTimeMillis()/1000L);
long finalTimeout = timeout;
new Thread(() -> {
while (System.currentTimeMillis()/1000L < finalTimeout) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (process.isAlive()) {
process.destroy();
}
}).start();
while ((line = reader.readLine()) != null) { while ((line = reader.readLine()) != null) {
GameCommandHandler.returnCommandOutput(command.getCommand(), line, context); if (ModConfigs.LOG_CMD_OUTPUT) {
GameCommandHandler.returnCommandOutput(command.getCommand(), line, context);
}
//get the ingame command name
output.append("[").append(command.getIngamecommand()).append("]").append(line).append("\n");
String finalLine = line;
context.getSource().sendFeedback(() -> Text.of("[" + command.getIngamecommand() + "] " + finalLine), command.isBroadcastToOp());
} }
int exitCode = process.waitFor(); //quit the process if it's still running
if (exitCode == 0) { if (process.isAlive()) {
BetterConsoleMC.LOGGER.info("Exited with error code : " + exitCode); process.destroy();
} else {
BetterConsoleMC.LOGGER.error("Exited with error code : " + exitCode);
} }
// Read buffered reader line by line and append to output with prefix of command before each line
int exitCode = process.waitFor();
BetterConsoleMC.LOGGER.info("Exited with error code : " + exitCode);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }
return 1; return output.toString();
} }
} }

View file

@ -1,49 +1,22 @@
package me.jonasjones.betterconsolemc.util; package me.jonasjones.betterconsolemc.util;
import lombok.Getter;
@Getter
public class CommandPreRegistry { //TODO: Add timeout before command can be ran again (unixtimestamp) public class CommandPreRegistry { //TODO: Add timeout before command can be ran again (unixtimestamp)
private Constants.CmdMode commandmode; private Constants.CmdMode commandmode;
private String command; private String command;
private int permissionLevel; private int permissionLevel;
private int execTimeout; private int execTimeout;
private String ingamecommand; private String ingamecommand;
private int execRerunTimeout;
private boolean broadcastToOp; private boolean broadcastToOp;
public void init(Constants.CmdMode commandmode, String command, int permissionLevel, int execTimeout, String ingamecommand, int execRerunTimeout, boolean broadcastToOp) { public void init(Constants.CmdMode commandmode, String command, int permissionLevel, int execTimeout, String ingamecommand, boolean broadcastToOp) {
this.commandmode = commandmode; this.commandmode = commandmode;
this.command = command; this.command = command;
this.permissionLevel = permissionLevel; this.permissionLevel = permissionLevel;
this.execTimeout = execTimeout; this.execTimeout = execTimeout;
this.ingamecommand = ingamecommand; this.ingamecommand = ingamecommand;
this.execRerunTimeout = execRerunTimeout;
this.broadcastToOp = broadcastToOp; this.broadcastToOp = broadcastToOp;
} }
public Constants.CmdMode getCommandmode() {
return this.commandmode;
}
public String getCommand() {
return this.command;
}
public int getPermissionLevel() {
return this.permissionLevel;
}
public int getExecTimeout() {
return this.execTimeout;
}
public String getIngamecommand() {
return this.ingamecommand;
}
public int getExecRerunTimeout() {
return this.execRerunTimeout;
}
public boolean doBroadcastToOp() {
return this.broadcastToOp;
}
} }