Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions .github/workflows/1mb-start-tests.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
name: 1MB start wrapper tests

on:
push:
paths:
- "Resources/Server/1MB-start.sh"
- "Resources/Server/tests/1MB-start/**"
- ".github/workflows/1mb-start-tests.yml"
pull_request:
paths:
- "Resources/Server/1MB-start.sh"
- "Resources/Server/tests/1MB-start/**"
- ".github/workflows/1mb-start-tests.yml"
workflow_dispatch:

permissions:
contents: read

jobs:
test:
name: ${{ matrix.os }}
runs-on: ${{ matrix.os }}
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
os:
- macos-latest
- ubuntu-latest

steps:
- name: Check out repository
uses: actions/checkout@v6

- name: Install ShellCheck on macOS
if: runner.os == 'macOS'
run: command -v shellcheck >/dev/null 2>&1 || brew install shellcheck

- name: Install ShellCheck on Ubuntu
if: runner.os == 'Linux'
run: |
if ! command -v shellcheck >/dev/null 2>&1; then
sudo apt-get update
sudo apt-get install --yes shellcheck
fi

- name: Run syntax, behavior, and lint tests
shell: bash
run: /bin/bash Resources/Server/tests/1MB-start/run-tests.sh all
147 changes: 126 additions & 21 deletions Resources/Server/1MB-start.sh
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env bash

# @Filename: 1MB-start.sh
# @Version: 2.17.9, build 082 for Minecraft 26.2 (Java 25, 64bit)
# @Version: 2.18.3, build 086 for Minecraft 26.2 (Java 25, 64bit)
# @Release: August 4th, 2026
# @Description: Helps us start and fork a Minecraft 26.2 server session.
# @Contact: I am @floris on Twitter, and mrfloris in MineCraft.
Expand All@@ -18,7 +18,8 @@
###

_serverName="mcserver"
# Keep the name short, simple, and lowercase (no numbers or weird characters).
# Use 1-32 lowercase ASCII letters, numbers, hyphens or underscores. The first
# character must be a letter or number.
# The name makes it easier to recognize the session in 'tmux ls', you can
# re-attach to the forked sessions with 'tmux attach -t (name)'.

Expand All@@ -30,6 +31,7 @@ _serverName="mcserver"
###

_sibling="1MB-minecraft.sh"
_startupCheckSeconds=2 # Check process liveness only; this is not Paper readiness.
_debug=true # Set to false to minimize output.

### FUNCTIONS AND CODE
Expand All@@ -52,7 +54,7 @@ function _output {
fi

case "$_mode" in
oops|okay) _fd=2 ;;
oops) _fd=2 ;;
esac

if [ -z "${NO_COLOR+x}" ] && [ -t "$_fd" ]; then
Expand All@@ -68,7 +70,7 @@ function _output {
;;
okay)
_args="${*:2}"; _prefix="(Info)";
printf '\n%s%s%s %s%s\n' "$_yellow" "$_prefix" "$_cyan" "$_args" "$_reset" >&2; exit 1
printf '\n%s%s%s %s%s\n' "$_yellow" "$_prefix" "$_cyan" "$_args" "$_reset"; return 0
;;
debug)
_args="${*:2}"; _prefix="(Debug)";
Expand DownExpand Up@@ -131,46 +133,139 @@ function _showHelp {
" --attach [name] Attach to the exact tmux session." \
" --help, -h Show this help." \
"" \
"The session name defaults to '$_serverName'."
"The session name defaults to '$_serverName'." \
"Names use 1-32 lowercase ASCII letters, numbers, hyphens or underscores." \
"The first character must be a letter or number."
}

function _setServerName {
local _requestedName="${1:-}"
local _input=""
local _requestedName="${1-}"
local LC_ALL=C

if [ -n "$_requestedName" ]; then
_input=$(printf '%s\n' "$_requestedName" | awk '{ print tolower($1) }')
_input=$(printf '%s\n' "$_input" | awk '{ print substr($0, 1, 16) }')
if [ "${#_requestedName}" -gt 32 ] || ! [[ "$_requestedName" =~ ^[a-z0-9][a-z0-9_-]*$ ]]; then
_output oops "Invalid session name. Use 1-32 lowercase ASCII letters, numbers, hyphens or underscores. The first character must be a letter or number."
fi

if [[ "$_input" =~ ^[a-z]+$ ]]; then
_serverName="$_input"
else
_output oops "Provided input is invalid! Input is for a unique '_serverName'. Do not use numbers, spaces or weird chars. Keep it short, and a-z characters only."
_serverName="$_requestedName"
}

function _isPaneId {
local _paneId="${1:-}"
local _paneNumber=""

case "$_paneId" in
%*) _paneNumber="${_paneId#%}" ;;
*) return 1 ;;
esac

case "$_paneNumber" in
""|*[!0-9]*) return 1 ;;
*) return 0 ;;
esac
}

function _verifyStartedPane {
local _paneId="${1:-}"
local _paneReport=""
local _paneDead=""
local _paneResult=""
local _paneStatus=""
local _paneSignal=""
local _exitDescription=""

_output debug "Checking whether '$_sibling' remains active for $_startupCheckSeconds seconds ..."

if ! sleep "$_startupCheckSeconds"; then
if ! tmux set-option -p -t "$_paneId" remain-on-exit off >/dev/null 2>&1; then
_output oops "The $_startupCheckSeconds-second startup check was interrupted, and tmux could not restore normal close-on-exit behavior. Inspect the '$_serverName' session before retrying."
fi
_output oops "The $_startupCheckSeconds-second startup check was interrupted. The tmux session was not reported as started."
fi

if ! _paneReport=$(tmux display-message -p -t "$_paneId" '#{pane_dead}|#{pane_dead_status}|#{pane_dead_signal}' 2>/dev/null); then
tmux set-option -p -t "$_paneId" remain-on-exit off >/dev/null 2>&1 || true
_output oops "'$_sibling' ended or its tmux pane disappeared during the $_startupCheckSeconds-second startup check. Run './$_sibling' directly from '$_scriptDir' to inspect its full output."
fi

_paneDead="${_paneReport%%|*}"
_paneResult="${_paneReport#*|}"
_paneStatus="${_paneResult%%|*}"
_paneSignal="${_paneResult#*|}"

case "$_paneDead" in
0)
if ! tmux set-option -p -t "$_paneId" remain-on-exit off >/dev/null 2>&1; then
_output oops "'$_sibling' remained active, but tmux could not restore normal close-on-exit behavior for pane '$_paneId'. Inspect the '$_serverName' session before retrying."
fi

if ! _paneDead=$(tmux display-message -p -t "$_paneId" '#{pane_dead}' 2>/dev/null); then
_output oops "'$_sibling' ended as the $_startupCheckSeconds-second startup check completed. The tmux session was not reported as started."
fi

if [ "$_paneDead" != 0 ]; then
tmux kill-pane -t "$_paneId" >/dev/null 2>&1 || true
_output oops "'$_sibling' ended as the $_startupCheckSeconds-second startup check completed. The tmux session was not reported as started."
fi
;;
1)
if [ -n "$_paneStatus" ]; then
_exitDescription="exit status $_paneStatus"
fi
if [ -n "$_paneSignal" ]; then
if [ -n "$_exitDescription" ]; then
_exitDescription="$_exitDescription, signal $_paneSignal"
else
_exitDescription="signal $_paneSignal"
fi
fi
[ -z "$_exitDescription" ] && _exitDescription="unknown exit status"

tmux kill-pane -t "$_paneId" >/dev/null 2>&1 || true
_output oops "'$_sibling' exited during the $_startupCheckSeconds-second startup check ($_exitDescription). Run './$_sibling' directly from '$_scriptDir' to inspect its full output."
;;
*)
tmux set-option -p -t "$_paneId" remain-on-exit off >/dev/null 2>&1 || true
_output oops "tmux returned an unexpected state for pane '$_paneId' during the startup check. The session was not reported as started."
;;
esac
}

_action="start"
_nameArgument="${1:-}"
_nameArgument="$_serverName"

case "${1:-}" in
-h|--help)
[ "$#" -eq 1 ] || _output oops "Unexpected extra arguments. Run '$0 --help' for usage."
_showHelp
exit 0
;;
--status)
[ "$#" -le 2 ] || _output oops "Unexpected extra arguments. Run '$0 --help' for usage."
_action="status"
_nameArgument="${2:-}"
if [ "$#" -eq 2 ]; then
_nameArgument="$2"
fi
;;
--attach)
[ "$#" -le 2 ] || _output oops "Unexpected extra arguments. Run '$0 --help' for usage."
_action="attach"
_nameArgument="${2:-}"
if [ "$#" -eq 2 ]; then
_nameArgument="$2"
fi
;;
--*)
_output oops "Unknown option '$1'. Run '$0 --help' for usage."
;;
*)
[ "$#" -le 1 ] || _output oops "Unexpected extra arguments. Run '$0 --help' for usage."
if [ "$#" -eq 1 ]; then
_nameArgument="$1"
fi
;;
esac

_setServerName "$_nameArgument"

[ "$EUID" -eq 0 ] && _output oops "*!* This script should not be run using sudo, or as the root user!"

if [ "$_action" = start ]; then
Expand All@@ -182,8 +277,6 @@ if [ "$_action" = start ]; then
fi
fi

_setServerName "$_nameArgument"

if ! type "tmux" >/dev/null 2>&1; then
_output oops "'tmux' is required but was not found. On macOS, install it with: brew install tmux"
fi
Expand DownExpand Up@@ -214,9 +307,21 @@ _output debug "Using server directory: $_scriptDir"

_output debug "Found 'tmux', attempting to start '$_sibling' in a detached tmux session ..."
# Deliberately launch only ./1MB-minecraft.sh from the wrapper's own directory.
if ! tmux new-session -d -s "$_serverName" -c "$_scriptDir" "exec \"./$_sibling\""; then
_output oops "Could not create the '$_serverName' tmux session and start '$_sibling'. Review the tmux error above and check with 'tmux ls'."
_paneId=""
if ! _paneId=$(tmux new-session -d -P -F '#{pane_id}' -s "$_serverName" -c "$_scriptDir" "exec \"./$_sibling\"" \; set-option -p -t "=$_serverName:" remain-on-exit on); then
if _isPaneId "$_paneId"; then
tmux kill-pane -t "$_paneId" >/dev/null 2>&1 || true
fi
_output oops "Could not create the '$_serverName' tmux session and prepare its startup check. Review the tmux error above and check with 'tmux ls'."
fi

if ! _isPaneId "$_paneId"; then
tmux kill-session -t "=$_serverName" >/dev/null 2>&1 || true
_output oops "tmux created the '$_serverName' session but did not return a valid pane identifier, so the new session was closed."
fi

_verifyStartedPane "$_paneId"

[[ "$_debug" == true ]] && tmux ls; _output debug "To re-attach: tmux attach -t $_serverName"

_output debug "tmux session started."
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions .github/workflows/1mb-start-tests.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
name: 1MB start wrapper tests

on:
push:
paths:
- "Resources/Server/1MB-start.sh"
- "Resources/Server/tests/1MB-start/**"
- ".github/workflows/1mb-start-tests.yml"
pull_request:
paths:
- "Resources/Server/1MB-start.sh"
- "Resources/Server/tests/1MB-start/**"
- ".github/workflows/1mb-start-tests.yml"
workflow_dispatch:

permissions:
contents: read

jobs:
test:
name: ${{ matrix.os }}
runs-on: ${{ matrix.os }}
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
os:
- macos-latest
- ubuntu-latest

steps:
- name: Check out repository
uses: actions/checkout@v6

- name: Install ShellCheck on macOS
if: runner.os == 'macOS'
run: command -v shellcheck >/dev/null 2>&1 || brew install shellcheck

- name: Install ShellCheck on Ubuntu
if: runner.os == 'Linux'
run: |
if ! command -v shellcheck >/dev/null 2>&1; then
sudo apt-get update
sudo apt-get install --yes shellcheck
fi

- name: Run syntax, behavior, and lint tests
shell: bash
run: /bin/bash Resources/Server/tests/1MB-start/run-tests.sh all
147 changes: 126 additions & 21 deletions Resources/Server/1MB-start.sh
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env bash

# @Filename: 1MB-start.sh
# @Version: 2.17.9, build 082 for Minecraft 26.2 (Java 25, 64bit)
# @Version: 2.18.3, build 086 for Minecraft 26.2 (Java 25, 64bit)
# @Release: August 4th, 2026
# @Description: Helps us start and fork a Minecraft 26.2 server session.
# @Contact: I am @floris on Twitter, and mrfloris in MineCraft.
Expand All@@ -18,7 +18,8 @@
###

_serverName="mcserver"
# Keep the name short, simple, and lowercase (no numbers or weird characters).
# Use 1-32 lowercase ASCII letters, numbers, hyphens or underscores. The first
# character must be a letter or number.
# The name makes it easier to recognize the session in 'tmux ls', you can
# re-attach to the forked sessions with 'tmux attach -t (name)'.

Expand All@@ -30,6 +31,7 @@ _serverName="mcserver"
###

_sibling="1MB-minecraft.sh"
_startupCheckSeconds=2 # Check process liveness only; this is not Paper readiness.
_debug=true # Set to false to minimize output.

### FUNCTIONS AND CODE
Expand All@@ -52,7 +54,7 @@ function _output {
fi

case "$_mode" in
oops|okay) _fd=2 ;;
oops) _fd=2 ;;
esac

if [ -z "${NO_COLOR+x}" ] && [ -t "$_fd" ]; then
Expand All@@ -68,7 +70,7 @@ function _output {
;;
okay)
_args="${*:2}"; _prefix="(Info)";
printf '\n%s%s%s %s%s\n' "$_yellow" "$_prefix" "$_cyan" "$_args" "$_reset" >&2; exit 1
printf '\n%s%s%s %s%s\n' "$_yellow" "$_prefix" "$_cyan" "$_args" "$_reset"; return 0
;;
debug)
_args="${*:2}"; _prefix="(Debug)";
Expand DownExpand Up@@ -131,46 +133,139 @@ function _showHelp {
" --attach [name] Attach to the exact tmux session." \
" --help, -h Show this help." \
"" \
"The session name defaults to '$_serverName'."
"The session name defaults to '$_serverName'." \
"Names use 1-32 lowercase ASCII letters, numbers, hyphens or underscores." \
"The first character must be a letter or number."
}

function _setServerName {
local _requestedName="${1:-}"
local _input=""
local _requestedName="${1-}"
local LC_ALL=C

if [ -n "$_requestedName" ]; then
_input=$(printf '%s\n' "$_requestedName" | awk '{ print tolower($1) }')
_input=$(printf '%s\n' "$_input" | awk '{ print substr($0, 1, 16) }')
if [ "${#_requestedName}" -gt 32 ] || ! [[ "$_requestedName" =~ ^[a-z0-9][a-z0-9_-]*$ ]]; then
_output oops "Invalid session name. Use 1-32 lowercase ASCII letters, numbers, hyphens or underscores. The first character must be a letter or number."
fi

if [[ "$_input" =~ ^[a-z]+$ ]]; then
_serverName="$_input"
else
_output oops "Provided input is invalid! Input is for a unique '_serverName'. Do not use numbers, spaces or weird chars. Keep it short, and a-z characters only."
_serverName="$_requestedName"
}

function _isPaneId {
local _paneId="${1:-}"
local _paneNumber=""

case "$_paneId" in
%*) _paneNumber="${_paneId#%}" ;;
*) return 1 ;;
esac

case "$_paneNumber" in
""|*[!0-9]*) return 1 ;;
*) return 0 ;;
esac
}

function _verifyStartedPane {
local _paneId="${1:-}"
local _paneReport=""
local _paneDead=""
local _paneResult=""
local _paneStatus=""
local _paneSignal=""
local _exitDescription=""

_output debug "Checking whether '$_sibling' remains active for $_startupCheckSeconds seconds ..."

if ! sleep "$_startupCheckSeconds"; then
if ! tmux set-option -p -t "$_paneId" remain-on-exit off >/dev/null 2>&1; then
_output oops "The $_startupCheckSeconds-second startup check was interrupted, and tmux could not restore normal close-on-exit behavior. Inspect the '$_serverName' session before retrying."
fi
_output oops "The $_startupCheckSeconds-second startup check was interrupted. The tmux session was not reported as started."
fi

if ! _paneReport=$(tmux display-message -p -t "$_paneId" '#{pane_dead}|#{pane_dead_status}|#{pane_dead_signal}' 2>/dev/null); then
tmux set-option -p -t "$_paneId" remain-on-exit off >/dev/null 2>&1 || true
_output oops "'$_sibling' ended or its tmux pane disappeared during the $_startupCheckSeconds-second startup check. Run './$_sibling' directly from '$_scriptDir' to inspect its full output."
fi

_paneDead="${_paneReport%%|*}"
_paneResult="${_paneReport#*|}"
_paneStatus="${_paneResult%%|*}"
_paneSignal="${_paneResult#*|}"

case "$_paneDead" in
0)
if ! tmux set-option -p -t "$_paneId" remain-on-exit off >/dev/null 2>&1; then
_output oops "'$_sibling' remained active, but tmux could not restore normal close-on-exit behavior for pane '$_paneId'. Inspect the '$_serverName' session before retrying."
fi

if ! _paneDead=$(tmux display-message -p -t "$_paneId" '#{pane_dead}' 2>/dev/null); then
_output oops "'$_sibling' ended as the $_startupCheckSeconds-second startup check completed. The tmux session was not reported as started."
fi

if [ "$_paneDead" != 0 ]; then
tmux kill-pane -t "$_paneId" >/dev/null 2>&1 || true
_output oops "'$_sibling' ended as the $_startupCheckSeconds-second startup check completed. The tmux session was not reported as started."
fi
;;
1)
if [ -n "$_paneStatus" ]; then
_exitDescription="exit status $_paneStatus"
fi
if [ -n "$_paneSignal" ]; then
if [ -n "$_exitDescription" ]; then
_exitDescription="$_exitDescription, signal $_paneSignal"
else
_exitDescription="signal $_paneSignal"
fi
fi
[ -z "$_exitDescription" ] && _exitDescription="unknown exit status"

tmux kill-pane -t "$_paneId" >/dev/null 2>&1 || true
_output oops "'$_sibling' exited during the $_startupCheckSeconds-second startup check ($_exitDescription). Run './$_sibling' directly from '$_scriptDir' to inspect its full output."
;;
*)
tmux set-option -p -t "$_paneId" remain-on-exit off >/dev/null 2>&1 || true
_output oops "tmux returned an unexpected state for pane '$_paneId' during the startup check. The session was not reported as started."
;;
esac
}

_action="start"
_nameArgument="${1:-}"
_nameArgument="$_serverName"

case "${1:-}" in
-h|--help)
[ "$#" -eq 1 ] || _output oops "Unexpected extra arguments. Run '$0 --help' for usage."
_showHelp
exit 0
;;
--status)
[ "$#" -le 2 ] || _output oops "Unexpected extra arguments. Run '$0 --help' for usage."
_action="status"
_nameArgument="${2:-}"
if [ "$#" -eq 2 ]; then
_nameArgument="$2"
fi
;;
--attach)
[ "$#" -le 2 ] || _output oops "Unexpected extra arguments. Run '$0 --help' for usage."
_action="attach"
_nameArgument="${2:-}"
if [ "$#" -eq 2 ]; then
_nameArgument="$2"
fi
;;
--*)
_output oops "Unknown option '$1'. Run '$0 --help' for usage."
;;
*)
[ "$#" -le 1 ] || _output oops "Unexpected extra arguments. Run '$0 --help' for usage."
if [ "$#" -eq 1 ]; then
_nameArgument="$1"
fi
;;
esac

_setServerName "$_nameArgument"

[ "$EUID" -eq 0 ] && _output oops "*!* This script should not be run using sudo, or as the root user!"

if [ "$_action" = start ]; then
Expand All@@ -182,8 +277,6 @@ if [ "$_action" = start ]; then
fi
fi

_setServerName "$_nameArgument"

if ! type "tmux" >/dev/null 2>&1; then
_output oops "'tmux' is required but was not found. On macOS, install it with: brew install tmux"
fi
Expand DownExpand Up@@ -214,9 +307,21 @@ _output debug "Using server directory: $_scriptDir"

_output debug "Found 'tmux', attempting to start '$_sibling' in a detached tmux session ..."
# Deliberately launch only ./1MB-minecraft.sh from the wrapper's own directory.
if ! tmux new-session -d -s "$_serverName" -c "$_scriptDir" "exec \"./$_sibling\""; then
_output oops "Could not create the '$_serverName' tmux session and start '$_sibling'. Review the tmux error above and check with 'tmux ls'."
_paneId=""
if ! _paneId=$(tmux new-session -d -P -F '#{pane_id}' -s "$_serverName" -c "$_scriptDir" "exec \"./$_sibling\"" \; set-option -p -t "=$_serverName:" remain-on-exit on); then
if _isPaneId "$_paneId"; then
tmux kill-pane -t "$_paneId" >/dev/null 2>&1 || true
fi
_output oops "Could not create the '$_serverName' tmux session and prepare its startup check. Review the tmux error above and check with 'tmux ls'."
fi

if ! _isPaneId "$_paneId"; then
tmux kill-session -t "=$_serverName" >/dev/null 2>&1 || true
_output oops "tmux created the '$_serverName' session but did not return a valid pane identifier, so the new session was closed."
fi

_verifyStartedPane "$_paneId"

[[ "$_debug" == true ]] && tmux ls; _output debug "To re-attach: tmux attach -t $_serverName"

_output debug "tmux session started."
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions .github/workflows/1mb-start-tests.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
name: 1MB start wrapper tests

on:
push:
paths:
- "Resources/Server/1MB-start.sh"
- "Resources/Server/tests/1MB-start/**"
- ".github/workflows/1mb-start-tests.yml"
pull_request:
paths:
- "Resources/Server/1MB-start.sh"
- "Resources/Server/tests/1MB-start/**"
- ".github/workflows/1mb-start-tests.yml"
workflow_dispatch:

permissions:
contents: read

jobs:
test:
name: ${{ matrix.os }}
runs-on: ${{ matrix.os }}
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
os:
- macos-latest
- ubuntu-latest

steps:
- name: Check out repository
uses: actions/checkout@v6

- name: Install ShellCheck on macOS
if: runner.os == 'macOS'
run: command -v shellcheck >/dev/null 2>&1 || brew install shellcheck

- name: Install ShellCheck on Ubuntu
if: runner.os == 'Linux'
run: |
if ! command -v shellcheck >/dev/null 2>&1; then
sudo apt-get update
sudo apt-get install --yes shellcheck
fi

- name: Run syntax, behavior, and lint tests
shell: bash
run: /bin/bash Resources/Server/tests/1MB-start/run-tests.sh all
147 changes: 126 additions & 21 deletions Resources/Server/1MB-start.sh
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env bash

# @Filename: 1MB-start.sh
# @Version: 2.17.9, build 082 for Minecraft 26.2 (Java 25, 64bit)
# @Version: 2.18.3, build 086 for Minecraft 26.2 (Java 25, 64bit)
# @Release: August 4th, 2026
# @Description: Helps us start and fork a Minecraft 26.2 server session.
# @Contact: I am @floris on Twitter, and mrfloris in MineCraft.
Expand All@@ -18,7 +18,8 @@
###

_serverName="mcserver"
# Keep the name short, simple, and lowercase (no numbers or weird characters).
# Use 1-32 lowercase ASCII letters, numbers, hyphens or underscores. The first
# character must be a letter or number.
# The name makes it easier to recognize the session in 'tmux ls', you can
# re-attach to the forked sessions with 'tmux attach -t (name)'.

Expand All@@ -30,6 +31,7 @@ _serverName="mcserver"
###

_sibling="1MB-minecraft.sh"
_startupCheckSeconds=2 # Check process liveness only; this is not Paper readiness.
_debug=true # Set to false to minimize output.

### FUNCTIONS AND CODE
Expand All@@ -52,7 +54,7 @@ function _output {
fi

case "$_mode" in
oops|okay) _fd=2 ;;
oops) _fd=2 ;;
esac

if [ -z "${NO_COLOR+x}" ] && [ -t "$_fd" ]; then
Expand All@@ -68,7 +70,7 @@ function _output {
;;
okay)
_args="${*:2}"; _prefix="(Info)";
printf '\n%s%s%s %s%s\n' "$_yellow" "$_prefix" "$_cyan" "$_args" "$_reset" >&2; exit 1
printf '\n%s%s%s %s%s\n' "$_yellow" "$_prefix" "$_cyan" "$_args" "$_reset"; return 0
;;
debug)
_args="${*:2}"; _prefix="(Debug)";
Expand DownExpand Up@@ -131,46 +133,139 @@ function _showHelp {
" --attach [name] Attach to the exact tmux session." \
" --help, -h Show this help." \
"" \
"The session name defaults to '$_serverName'."
"The session name defaults to '$_serverName'." \
"Names use 1-32 lowercase ASCII letters, numbers, hyphens or underscores." \
"The first character must be a letter or number."
}

function _setServerName {
local _requestedName="${1:-}"
local _input=""
local _requestedName="${1-}"
local LC_ALL=C

if [ -n "$_requestedName" ]; then
_input=$(printf '%s\n' "$_requestedName" | awk '{ print tolower($1) }')
_input=$(printf '%s\n' "$_input" | awk '{ print substr($0, 1, 16) }')
if [ "${#_requestedName}" -gt 32 ] || ! [[ "$_requestedName" =~ ^[a-z0-9][a-z0-9_-]*$ ]]; then
_output oops "Invalid session name. Use 1-32 lowercase ASCII letters, numbers, hyphens or underscores. The first character must be a letter or number."
fi

if [[ "$_input" =~ ^[a-z]+$ ]]; then
_serverName="$_input"
else
_output oops "Provided input is invalid! Input is for a unique '_serverName'. Do not use numbers, spaces or weird chars. Keep it short, and a-z characters only."
_serverName="$_requestedName"
}

function _isPaneId {
local _paneId="${1:-}"
local _paneNumber=""

case "$_paneId" in
%*) _paneNumber="${_paneId#%}" ;;
*) return 1 ;;
esac

case "$_paneNumber" in
""|*[!0-9]*) return 1 ;;
*) return 0 ;;
esac
}

function _verifyStartedPane {
local _paneId="${1:-}"
local _paneReport=""
local _paneDead=""
local _paneResult=""
local _paneStatus=""
local _paneSignal=""
local _exitDescription=""

_output debug "Checking whether '$_sibling' remains active for $_startupCheckSeconds seconds ..."

if ! sleep "$_startupCheckSeconds"; then
if ! tmux set-option -p -t "$_paneId" remain-on-exit off >/dev/null 2>&1; then
_output oops "The $_startupCheckSeconds-second startup check was interrupted, and tmux could not restore normal close-on-exit behavior. Inspect the '$_serverName' session before retrying."
fi
_output oops "The $_startupCheckSeconds-second startup check was interrupted. The tmux session was not reported as started."
fi

if ! _paneReport=$(tmux display-message -p -t "$_paneId" '#{pane_dead}|#{pane_dead_status}|#{pane_dead_signal}' 2>/dev/null); then
tmux set-option -p -t "$_paneId" remain-on-exit off >/dev/null 2>&1 || true
_output oops "'$_sibling' ended or its tmux pane disappeared during the $_startupCheckSeconds-second startup check. Run './$_sibling' directly from '$_scriptDir' to inspect its full output."
fi

_paneDead="${_paneReport%%|*}"
_paneResult="${_paneReport#*|}"
_paneStatus="${_paneResult%%|*}"
_paneSignal="${_paneResult#*|}"

case "$_paneDead" in
0)
if ! tmux set-option -p -t "$_paneId" remain-on-exit off >/dev/null 2>&1; then
_output oops "'$_sibling' remained active, but tmux could not restore normal close-on-exit behavior for pane '$_paneId'. Inspect the '$_serverName' session before retrying."
fi

if ! _paneDead=$(tmux display-message -p -t "$_paneId" '#{pane_dead}' 2>/dev/null); then
_output oops "'$_sibling' ended as the $_startupCheckSeconds-second startup check completed. The tmux session was not reported as started."
fi

if [ "$_paneDead" != 0 ]; then
tmux kill-pane -t "$_paneId" >/dev/null 2>&1 || true
_output oops "'$_sibling' ended as the $_startupCheckSeconds-second startup check completed. The tmux session was not reported as started."
fi
;;
1)
if [ -n "$_paneStatus" ]; then
_exitDescription="exit status $_paneStatus"
fi
if [ -n "$_paneSignal" ]; then
if [ -n "$_exitDescription" ]; then
_exitDescription="$_exitDescription, signal $_paneSignal"
else
_exitDescription="signal $_paneSignal"
fi
fi
[ -z "$_exitDescription" ] && _exitDescription="unknown exit status"

tmux kill-pane -t "$_paneId" >/dev/null 2>&1 || true
_output oops "'$_sibling' exited during the $_startupCheckSeconds-second startup check ($_exitDescription). Run './$_sibling' directly from '$_scriptDir' to inspect its full output."
;;
*)
tmux set-option -p -t "$_paneId" remain-on-exit off >/dev/null 2>&1 || true
_output oops "tmux returned an unexpected state for pane '$_paneId' during the startup check. The session was not reported as started."
;;
esac
}

_action="start"
_nameArgument="${1:-}"
_nameArgument="$_serverName"

case "${1:-}" in
-h|--help)
[ "$#" -eq 1 ] || _output oops "Unexpected extra arguments. Run '$0 --help' for usage."
_showHelp
exit 0
;;
--status)
[ "$#" -le 2 ] || _output oops "Unexpected extra arguments. Run '$0 --help' for usage."
_action="status"
_nameArgument="${2:-}"
if [ "$#" -eq 2 ]; then
_nameArgument="$2"
fi
;;
--attach)
[ "$#" -le 2 ] || _output oops "Unexpected extra arguments. Run '$0 --help' for usage."
_action="attach"
_nameArgument="${2:-}"
if [ "$#" -eq 2 ]; then
_nameArgument="$2"
fi
;;
--*)
_output oops "Unknown option '$1'. Run '$0 --help' for usage."
;;
*)
[ "$#" -le 1 ] || _output oops "Unexpected extra arguments. Run '$0 --help' for usage."
if [ "$#" -eq 1 ]; then
_nameArgument="$1"
fi
;;
esac

_setServerName "$_nameArgument"

[ "$EUID" -eq 0 ] && _output oops "*!* This script should not be run using sudo, or as the root user!"

if [ "$_action" = start ]; then
Expand All@@ -182,8 +277,6 @@ if [ "$_action" = start ]; then
fi
fi

_setServerName "$_nameArgument"

if ! type "tmux" >/dev/null 2>&1; then
_output oops "'tmux' is required but was not found. On macOS, install it with: brew install tmux"
fi
Expand DownExpand Up@@ -214,9 +307,21 @@ _output debug "Using server directory: $_scriptDir"

_output debug "Found 'tmux', attempting to start '$_sibling' in a detached tmux session ..."
# Deliberately launch only ./1MB-minecraft.sh from the wrapper's own directory.
if ! tmux new-session -d -s "$_serverName" -c "$_scriptDir" "exec \"./$_sibling\""; then
_output oops "Could not create the '$_serverName' tmux session and start '$_sibling'. Review the tmux error above and check with 'tmux ls'."
_paneId=""
if ! _paneId=$(tmux new-session -d -P -F '#{pane_id}' -s "$_serverName" -c "$_scriptDir" "exec \"./$_sibling\"" \; set-option -p -t "=$_serverName:" remain-on-exit on); then
if _isPaneId "$_paneId"; then
tmux kill-pane -t "$_paneId" >/dev/null 2>&1 || true
fi
_output oops "Could not create the '$_serverName' tmux session and prepare its startup check. Review the tmux error above and check with 'tmux ls'."
fi

if ! _isPaneId "$_paneId"; then
tmux kill-session -t "=$_serverName" >/dev/null 2>&1 || true
_output oops "tmux created the '$_serverName' session but did not return a valid pane identifier, so the new session was closed."
fi

_verifyStartedPane "$_paneId"

[[ "$_debug" == true ]] && tmux ls; _output debug "To re-attach: tmux attach -t $_serverName"

_output debug "tmux session started."
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions .github/workflows/1mb-start-tests.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
name: 1MB start wrapper tests

on:
push:
paths:
- "Resources/Server/1MB-start.sh"
- "Resources/Server/tests/1MB-start/**"
- ".github/workflows/1mb-start-tests.yml"
pull_request:
paths:
- "Resources/Server/1MB-start.sh"
- "Resources/Server/tests/1MB-start/**"
- ".github/workflows/1mb-start-tests.yml"
workflow_dispatch:

permissions:
contents: read

jobs:
test:
name: ${{ matrix.os }}
runs-on: ${{ matrix.os }}
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
os:
- macos-latest
- ubuntu-latest

steps:
- name: Check out repository
uses: actions/checkout@v6

- name: Install ShellCheck on macOS
if: runner.os == 'macOS'
run: command -v shellcheck >/dev/null 2>&1 || brew install shellcheck

- name: Install ShellCheck on Ubuntu
if: runner.os == 'Linux'
run: |
if ! command -v shellcheck >/dev/null 2>&1; then
sudo apt-get update
sudo apt-get install --yes shellcheck
fi

- name: Run syntax, behavior, and lint tests
shell: bash
run: /bin/bash Resources/Server/tests/1MB-start/run-tests.sh all
147 changes: 126 additions & 21 deletions Resources/Server/1MB-start.sh
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env bash

# @Filename: 1MB-start.sh
# @Version: 2.17.9, build 082 for Minecraft 26.2 (Java 25, 64bit)
# @Version: 2.18.3, build 086 for Minecraft 26.2 (Java 25, 64bit)
# @Release: August 4th, 2026
# @Description: Helps us start and fork a Minecraft 26.2 server session.
# @Contact: I am @floris on Twitter, and mrfloris in MineCraft.
Expand All@@ -18,7 +18,8 @@
###

_serverName="mcserver"
# Keep the name short, simple, and lowercase (no numbers or weird characters).
# Use 1-32 lowercase ASCII letters, numbers, hyphens or underscores. The first
# character must be a letter or number.
# The name makes it easier to recognize the session in 'tmux ls', you can
# re-attach to the forked sessions with 'tmux attach -t (name)'.

Expand All@@ -30,6 +31,7 @@ _serverName="mcserver"
###

_sibling="1MB-minecraft.sh"
_startupCheckSeconds=2 # Check process liveness only; this is not Paper readiness.
_debug=true # Set to false to minimize output.

### FUNCTIONS AND CODE
Expand All@@ -52,7 +54,7 @@ function _output {
fi

case "$_mode" in
oops|okay) _fd=2 ;;
oops) _fd=2 ;;
esac

if [ -z "${NO_COLOR+x}" ] && [ -t "$_fd" ]; then
Expand All@@ -68,7 +70,7 @@ function _output {
;;
okay)
_args="${*:2}"; _prefix="(Info)";
printf '\n%s%s%s %s%s\n' "$_yellow" "$_prefix" "$_cyan" "$_args" "$_reset" >&2; exit 1
printf '\n%s%s%s %s%s\n' "$_yellow" "$_prefix" "$_cyan" "$_args" "$_reset"; return 0
;;
debug)
_args="${*:2}"; _prefix="(Debug)";
Expand DownExpand Up@@ -131,46 +133,139 @@ function _showHelp {
" --attach [name] Attach to the exact tmux session." \
" --help, -h Show this help." \
"" \
"The session name defaults to '$_serverName'."
"The session name defaults to '$_serverName'." \
"Names use 1-32 lowercase ASCII letters, numbers, hyphens or underscores." \
"The first character must be a letter or number."
}

function _setServerName {
local _requestedName="${1:-}"
local _input=""
local _requestedName="${1-}"
local LC_ALL=C

if [ -n "$_requestedName" ]; then
_input=$(printf '%s\n' "$_requestedName" | awk '{ print tolower($1) }')
_input=$(printf '%s\n' "$_input" | awk '{ print substr($0, 1, 16) }')
if [ "${#_requestedName}" -gt 32 ] || ! [[ "$_requestedName" =~ ^[a-z0-9][a-z0-9_-]*$ ]]; then
_output oops "Invalid session name. Use 1-32 lowercase ASCII letters, numbers, hyphens or underscores. The first character must be a letter or number."
fi

if [[ "$_input" =~ ^[a-z]+$ ]]; then
_serverName="$_input"
else
_output oops "Provided input is invalid! Input is for a unique '_serverName'. Do not use numbers, spaces or weird chars. Keep it short, and a-z characters only."
_serverName="$_requestedName"
}

function _isPaneId {
local _paneId="${1:-}"
local _paneNumber=""

case "$_paneId" in
%*) _paneNumber="${_paneId#%}" ;;
*) return 1 ;;
esac

case "$_paneNumber" in
""|*[!0-9]*) return 1 ;;
*) return 0 ;;
esac
}

function _verifyStartedPane {
local _paneId="${1:-}"
local _paneReport=""
local _paneDead=""
local _paneResult=""
local _paneStatus=""
local _paneSignal=""
local _exitDescription=""

_output debug "Checking whether '$_sibling' remains active for $_startupCheckSeconds seconds ..."

if ! sleep "$_startupCheckSeconds"; then
if ! tmux set-option -p -t "$_paneId" remain-on-exit off >/dev/null 2>&1; then
_output oops "The $_startupCheckSeconds-second startup check was interrupted, and tmux could not restore normal close-on-exit behavior. Inspect the '$_serverName' session before retrying."
fi
_output oops "The $_startupCheckSeconds-second startup check was interrupted. The tmux session was not reported as started."
fi

if ! _paneReport=$(tmux display-message -p -t "$_paneId" '#{pane_dead}|#{pane_dead_status}|#{pane_dead_signal}' 2>/dev/null); then
tmux set-option -p -t "$_paneId" remain-on-exit off >/dev/null 2>&1 || true
_output oops "'$_sibling' ended or its tmux pane disappeared during the $_startupCheckSeconds-second startup check. Run './$_sibling' directly from '$_scriptDir' to inspect its full output."
fi

_paneDead="${_paneReport%%|*}"
_paneResult="${_paneReport#*|}"
_paneStatus="${_paneResult%%|*}"
_paneSignal="${_paneResult#*|}"

case "$_paneDead" in
0)
if ! tmux set-option -p -t "$_paneId" remain-on-exit off >/dev/null 2>&1; then
_output oops "'$_sibling' remained active, but tmux could not restore normal close-on-exit behavior for pane '$_paneId'. Inspect the '$_serverName' session before retrying."
fi

if ! _paneDead=$(tmux display-message -p -t "$_paneId" '#{pane_dead}' 2>/dev/null); then
_output oops "'$_sibling' ended as the $_startupCheckSeconds-second startup check completed. The tmux session was not reported as started."
fi

if [ "$_paneDead" != 0 ]; then
tmux kill-pane -t "$_paneId" >/dev/null 2>&1 || true
_output oops "'$_sibling' ended as the $_startupCheckSeconds-second startup check completed. The tmux session was not reported as started."
fi
;;
1)
if [ -n "$_paneStatus" ]; then
_exitDescription="exit status $_paneStatus"
fi
if [ -n "$_paneSignal" ]; then
if [ -n "$_exitDescription" ]; then
_exitDescription="$_exitDescription, signal $_paneSignal"
else
_exitDescription="signal $_paneSignal"
fi
fi
[ -z "$_exitDescription" ] && _exitDescription="unknown exit status"

tmux kill-pane -t "$_paneId" >/dev/null 2>&1 || true
_output oops "'$_sibling' exited during the $_startupCheckSeconds-second startup check ($_exitDescription). Run './$_sibling' directly from '$_scriptDir' to inspect its full output."
;;
*)
tmux set-option -p -t "$_paneId" remain-on-exit off >/dev/null 2>&1 || true
_output oops "tmux returned an unexpected state for pane '$_paneId' during the startup check. The session was not reported as started."
;;
esac
}

_action="start"
_nameArgument="${1:-}"
_nameArgument="$_serverName"

case "${1:-}" in
-h|--help)
[ "$#" -eq 1 ] || _output oops "Unexpected extra arguments. Run '$0 --help' for usage."
_showHelp
exit 0
;;
--status)
[ "$#" -le 2 ] || _output oops "Unexpected extra arguments. Run '$0 --help' for usage."
_action="status"
_nameArgument="${2:-}"
if [ "$#" -eq 2 ]; then
_nameArgument="$2"
fi
;;
--attach)
[ "$#" -le 2 ] || _output oops "Unexpected extra arguments. Run '$0 --help' for usage."
_action="attach"
_nameArgument="${2:-}"
if [ "$#" -eq 2 ]; then
_nameArgument="$2"
fi
;;
--*)
_output oops "Unknown option '$1'. Run '$0 --help' for usage."
;;
*)
[ "$#" -le 1 ] || _output oops "Unexpected extra arguments. Run '$0 --help' for usage."
if [ "$#" -eq 1 ]; then
_nameArgument="$1"
fi
;;
esac

_setServerName "$_nameArgument"

[ "$EUID" -eq 0 ] && _output oops "*!* This script should not be run using sudo, or as the root user!"

if [ "$_action" = start ]; then
Expand All@@ -182,8 +277,6 @@ if [ "$_action" = start ]; then
fi
fi

_setServerName "$_nameArgument"

if ! type "tmux" >/dev/null 2>&1; then
_output oops "'tmux' is required but was not found. On macOS, install it with: brew install tmux"
fi
Expand DownExpand Up@@ -214,9 +307,21 @@ _output debug "Using server directory: $_scriptDir"

_output debug "Found 'tmux', attempting to start '$_sibling' in a detached tmux session ..."
# Deliberately launch only ./1MB-minecraft.sh from the wrapper's own directory.
if ! tmux new-session -d -s "$_serverName" -c "$_scriptDir" "exec \"./$_sibling\""; then
_output oops "Could not create the '$_serverName' tmux session and start '$_sibling'. Review the tmux error above and check with 'tmux ls'."
_paneId=""
if ! _paneId=$(tmux new-session -d -P -F '#{pane_id}' -s "$_serverName" -c "$_scriptDir" "exec \"./$_sibling\"" \; set-option -p -t "=$_serverName:" remain-on-exit on); then
if _isPaneId "$_paneId"; then
tmux kill-pane -t "$_paneId" >/dev/null 2>&1 || true
fi
_output oops "Could not create the '$_serverName' tmux session and prepare its startup check. Review the tmux error above and check with 'tmux ls'."
fi

if ! _isPaneId "$_paneId"; then
tmux kill-session -t "=$_serverName" >/dev/null 2>&1 || true
_output oops "tmux created the '$_serverName' session but did not return a valid pane identifier, so the new session was closed."
fi

_verifyStartedPane "$_paneId"

[[ "$_debug" == true ]] && tmux ls; _output debug "To re-attach: tmux attach -t $_serverName"

_output debug "tmux session started."
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions .github/workflows/1mb-start-tests.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
name: 1MB start wrapper tests

on:
push:
paths:
- "Resources/Server/1MB-start.sh"
- "Resources/Server/tests/1MB-start/**"
- ".github/workflows/1mb-start-tests.yml"
pull_request:
paths:
- "Resources/Server/1MB-start.sh"
- "Resources/Server/tests/1MB-start/**"
- ".github/workflows/1mb-start-tests.yml"
workflow_dispatch:

permissions:
contents: read

jobs:
test:
name: ${{ matrix.os }}
runs-on: ${{ matrix.os }}
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
os:
- macos-latest
- ubuntu-latest

steps:
- name: Check out repository
uses: actions/checkout@v6

- name: Install ShellCheck on macOS
if: runner.os == 'macOS'
run: command -v shellcheck >/dev/null 2>&1 || brew install shellcheck

- name: Install ShellCheck on Ubuntu
if: runner.os == 'Linux'
run: |
if ! command -v shellcheck >/dev/null 2>&1; then
sudo apt-get update
sudo apt-get install --yes shellcheck
fi

- name: Run syntax, behavior, and lint tests
shell: bash
run: /bin/bash Resources/Server/tests/1MB-start/run-tests.sh all
147 changes: 126 additions & 21 deletions Resources/Server/1MB-start.sh
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env bash

# @Filename: 1MB-start.sh
# @Version: 2.17.9, build 082 for Minecraft 26.2 (Java 25, 64bit)
# @Version: 2.18.3, build 086 for Minecraft 26.2 (Java 25, 64bit)
# @Release: August 4th, 2026
# @Description: Helps us start and fork a Minecraft 26.2 server session.
# @Contact: I am @floris on Twitter, and mrfloris in MineCraft.
Expand All@@ -18,7 +18,8 @@
###

_serverName="mcserver"
# Keep the name short, simple, and lowercase (no numbers or weird characters).
# Use 1-32 lowercase ASCII letters, numbers, hyphens or underscores. The first
# character must be a letter or number.
# The name makes it easier to recognize the session in 'tmux ls', you can
# re-attach to the forked sessions with 'tmux attach -t (name)'.

Expand All@@ -30,6 +31,7 @@ _serverName="mcserver"
###

_sibling="1MB-minecraft.sh"
_startupCheckSeconds=2 # Check process liveness only; this is not Paper readiness.
_debug=true # Set to false to minimize output.

### FUNCTIONS AND CODE
Expand All@@ -52,7 +54,7 @@ function _output {
fi

case "$_mode" in
oops|okay) _fd=2 ;;
oops) _fd=2 ;;
esac

if [ -z "${NO_COLOR+x}" ] && [ -t "$_fd" ]; then
Expand All@@ -68,7 +70,7 @@ function _output {
;;
okay)
_args="${*:2}"; _prefix="(Info)";
printf '\n%s%s%s %s%s\n' "$_yellow" "$_prefix" "$_cyan" "$_args" "$_reset" >&2; exit 1
printf '\n%s%s%s %s%s\n' "$_yellow" "$_prefix" "$_cyan" "$_args" "$_reset"; return 0
;;
debug)
_args="${*:2}"; _prefix="(Debug)";
Expand DownExpand Up@@ -131,46 +133,139 @@ function _showHelp {
" --attach [name] Attach to the exact tmux session." \
" --help, -h Show this help." \
"" \
"The session name defaults to '$_serverName'."
"The session name defaults to '$_serverName'." \
"Names use 1-32 lowercase ASCII letters, numbers, hyphens or underscores." \
"The first character must be a letter or number."
}

function _setServerName {
local _requestedName="${1:-}"
local _input=""
local _requestedName="${1-}"
local LC_ALL=C

if [ -n "$_requestedName" ]; then
_input=$(printf '%s\n' "$_requestedName" | awk '{ print tolower($1) }')
_input=$(printf '%s\n' "$_input" | awk '{ print substr($0, 1, 16) }')
if [ "${#_requestedName}" -gt 32 ] || ! [[ "$_requestedName" =~ ^[a-z0-9][a-z0-9_-]*$ ]]; then
_output oops "Invalid session name. Use 1-32 lowercase ASCII letters, numbers, hyphens or underscores. The first character must be a letter or number."
fi

if [[ "$_input" =~ ^[a-z]+$ ]]; then
_serverName="$_input"
else
_output oops "Provided input is invalid! Input is for a unique '_serverName'. Do not use numbers, spaces or weird chars. Keep it short, and a-z characters only."
_serverName="$_requestedName"
}

function _isPaneId {
local _paneId="${1:-}"
local _paneNumber=""

case "$_paneId" in
%*) _paneNumber="${_paneId#%}" ;;
*) return 1 ;;
esac

case "$_paneNumber" in
""|*[!0-9]*) return 1 ;;
*) return 0 ;;
esac
}

function _verifyStartedPane {
local _paneId="${1:-}"
local _paneReport=""
local _paneDead=""
local _paneResult=""
local _paneStatus=""
local _paneSignal=""
local _exitDescription=""

_output debug "Checking whether '$_sibling' remains active for $_startupCheckSeconds seconds ..."

if ! sleep "$_startupCheckSeconds"; then
if ! tmux set-option -p -t "$_paneId" remain-on-exit off >/dev/null 2>&1; then
_output oops "The $_startupCheckSeconds-second startup check was interrupted, and tmux could not restore normal close-on-exit behavior. Inspect the '$_serverName' session before retrying."
fi
_output oops "The $_startupCheckSeconds-second startup check was interrupted. The tmux session was not reported as started."
fi

if ! _paneReport=$(tmux display-message -p -t "$_paneId" '#{pane_dead}|#{pane_dead_status}|#{pane_dead_signal}' 2>/dev/null); then
tmux set-option -p -t "$_paneId" remain-on-exit off >/dev/null 2>&1 || true
_output oops "'$_sibling' ended or its tmux pane disappeared during the $_startupCheckSeconds-second startup check. Run './$_sibling' directly from '$_scriptDir' to inspect its full output."
fi

_paneDead="${_paneReport%%|*}"
_paneResult="${_paneReport#*|}"
_paneStatus="${_paneResult%%|*}"
_paneSignal="${_paneResult#*|}"

case "$_paneDead" in
0)
if ! tmux set-option -p -t "$_paneId" remain-on-exit off >/dev/null 2>&1; then
_output oops "'$_sibling' remained active, but tmux could not restore normal close-on-exit behavior for pane '$_paneId'. Inspect the '$_serverName' session before retrying."
fi

if ! _paneDead=$(tmux display-message -p -t "$_paneId" '#{pane_dead}' 2>/dev/null); then
_output oops "'$_sibling' ended as the $_startupCheckSeconds-second startup check completed. The tmux session was not reported as started."
fi

if [ "$_paneDead" != 0 ]; then
tmux kill-pane -t "$_paneId" >/dev/null 2>&1 || true
_output oops "'$_sibling' ended as the $_startupCheckSeconds-second startup check completed. The tmux session was not reported as started."
fi
;;
1)
if [ -n "$_paneStatus" ]; then
_exitDescription="exit status $_paneStatus"
fi
if [ -n "$_paneSignal" ]; then
if [ -n "$_exitDescription" ]; then
_exitDescription="$_exitDescription, signal $_paneSignal"
else
_exitDescription="signal $_paneSignal"
fi
fi
[ -z "$_exitDescription" ] && _exitDescription="unknown exit status"

tmux kill-pane -t "$_paneId" >/dev/null 2>&1 || true
_output oops "'$_sibling' exited during the $_startupCheckSeconds-second startup check ($_exitDescription). Run './$_sibling' directly from '$_scriptDir' to inspect its full output."
;;
*)
tmux set-option -p -t "$_paneId" remain-on-exit off >/dev/null 2>&1 || true
_output oops "tmux returned an unexpected state for pane '$_paneId' during the startup check. The session was not reported as started."
;;
esac
}

_action="start"
_nameArgument="${1:-}"
_nameArgument="$_serverName"

case "${1:-}" in
-h|--help)
[ "$#" -eq 1 ] || _output oops "Unexpected extra arguments. Run '$0 --help' for usage."
_showHelp
exit 0
;;
--status)
[ "$#" -le 2 ] || _output oops "Unexpected extra arguments. Run '$0 --help' for usage."
_action="status"
_nameArgument="${2:-}"
if [ "$#" -eq 2 ]; then
_nameArgument="$2"
fi
;;
--attach)
[ "$#" -le 2 ] || _output oops "Unexpected extra arguments. Run '$0 --help' for usage."
_action="attach"
_nameArgument="${2:-}"
if [ "$#" -eq 2 ]; then
_nameArgument="$2"
fi
;;
--*)
_output oops "Unknown option '$1'. Run '$0 --help' for usage."
;;
*)
[ "$#" -le 1 ] || _output oops "Unexpected extra arguments. Run '$0 --help' for usage."
if [ "$#" -eq 1 ]; then
_nameArgument="$1"
fi
;;
esac

_setServerName "$_nameArgument"

[ "$EUID" -eq 0 ] && _output oops "*!* This script should not be run using sudo, or as the root user!"

if [ "$_action" = start ]; then
Expand All@@ -182,8 +277,6 @@ if [ "$_action" = start ]; then
fi
fi

_setServerName "$_nameArgument"

if ! type "tmux" >/dev/null 2>&1; then
_output oops "'tmux' is required but was not found. On macOS, install it with: brew install tmux"
fi
Expand DownExpand Up@@ -214,9 +307,21 @@ _output debug "Using server directory: $_scriptDir"

_output debug "Found 'tmux', attempting to start '$_sibling' in a detached tmux session ..."
# Deliberately launch only ./1MB-minecraft.sh from the wrapper's own directory.
if ! tmux new-session -d -s "$_serverName" -c "$_scriptDir" "exec \"./$_sibling\""; then
_output oops "Could not create the '$_serverName' tmux session and start '$_sibling'. Review the tmux error above and check with 'tmux ls'."
_paneId=""
if ! _paneId=$(tmux new-session -d -P -F '#{pane_id}' -s "$_serverName" -c "$_scriptDir" "exec \"./$_sibling\"" \; set-option -p -t "=$_serverName:" remain-on-exit on); then
if _isPaneId "$_paneId"; then
tmux kill-pane -t "$_paneId" >/dev/null 2>&1 || true
fi
_output oops "Could not create the '$_serverName' tmux session and prepare its startup check. Review the tmux error above and check with 'tmux ls'."
fi

if ! _isPaneId "$_paneId"; then
tmux kill-session -t "=$_serverName" >/dev/null 2>&1 || true
_output oops "tmux created the '$_serverName' session but did not return a valid pane identifier, so the new session was closed."
fi

_verifyStartedPane "$_paneId"

[[ "$_debug" == true ]] && tmux ls; _output debug "To re-attach: tmux attach -t $_serverName"

_output debug "tmux session started."
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions .github/workflows/1mb-start-tests.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
name: 1MB start wrapper tests

on:
push:
paths:
- "Resources/Server/1MB-start.sh"
- "Resources/Server/tests/1MB-start/**"
- ".github/workflows/1mb-start-tests.yml"
pull_request:
paths:
- "Resources/Server/1MB-start.sh"
- "Resources/Server/tests/1MB-start/**"
- ".github/workflows/1mb-start-tests.yml"
workflow_dispatch:

permissions:
contents: read

jobs:
test:
name: ${{ matrix.os }}
runs-on: ${{ matrix.os }}
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
os:
- macos-latest
- ubuntu-latest

steps:
- name: Check out repository
uses: actions/checkout@v6

- name: Install ShellCheck on macOS
if: runner.os == 'macOS'
run: command -v shellcheck >/dev/null 2>&1 || brew install shellcheck

- name: Install ShellCheck on Ubuntu
if: runner.os == 'Linux'
run: |
if ! command -v shellcheck >/dev/null 2>&1; then
sudo apt-get update
sudo apt-get install --yes shellcheck
fi

- name: Run syntax, behavior, and lint tests
shell: bash
run: /bin/bash Resources/Server/tests/1MB-start/run-tests.sh all
147 changes: 126 additions & 21 deletions Resources/Server/1MB-start.sh
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env bash

# @Filename: 1MB-start.sh
# @Version: 2.17.9, build 082 for Minecraft 26.2 (Java 25, 64bit)
# @Version: 2.18.3, build 086 for Minecraft 26.2 (Java 25, 64bit)
# @Release: August 4th, 2026
# @Description: Helps us start and fork a Minecraft 26.2 server session.
# @Contact: I am @floris on Twitter, and mrfloris in MineCraft.
Expand All@@ -18,7 +18,8 @@
###

_serverName="mcserver"
# Keep the name short, simple, and lowercase (no numbers or weird characters).
# Use 1-32 lowercase ASCII letters, numbers, hyphens or underscores. The first
# character must be a letter or number.
# The name makes it easier to recognize the session in 'tmux ls', you can
# re-attach to the forked sessions with 'tmux attach -t (name)'.

Expand All@@ -30,6 +31,7 @@ _serverName="mcserver"
###

_sibling="1MB-minecraft.sh"
_startupCheckSeconds=2 # Check process liveness only; this is not Paper readiness.
_debug=true # Set to false to minimize output.

### FUNCTIONS AND CODE
Expand All@@ -52,7 +54,7 @@ function _output {
fi

case "$_mode" in
oops|okay) _fd=2 ;;
oops) _fd=2 ;;
esac

if [ -z "${NO_COLOR+x}" ] && [ -t "$_fd" ]; then
Expand All@@ -68,7 +70,7 @@ function _output {
;;
okay)
_args="${*:2}"; _prefix="(Info)";
printf '\n%s%s%s %s%s\n' "$_yellow" "$_prefix" "$_cyan" "$_args" "$_reset" >&2; exit 1
printf '\n%s%s%s %s%s\n' "$_yellow" "$_prefix" "$_cyan" "$_args" "$_reset"; return 0
;;
debug)
_args="${*:2}"; _prefix="(Debug)";
Expand DownExpand Up@@ -131,46 +133,139 @@ function _showHelp {
" --attach [name] Attach to the exact tmux session." \
" --help, -h Show this help." \
"" \
"The session name defaults to '$_serverName'."
"The session name defaults to '$_serverName'." \
"Names use 1-32 lowercase ASCII letters, numbers, hyphens or underscores." \
"The first character must be a letter or number."
}

function _setServerName {
local _requestedName="${1:-}"
local _input=""
local _requestedName="${1-}"
local LC_ALL=C

if [ -n "$_requestedName" ]; then
_input=$(printf '%s\n' "$_requestedName" | awk '{ print tolower($1) }')
_input=$(printf '%s\n' "$_input" | awk '{ print substr($0, 1, 16) }')
if [ "${#_requestedName}" -gt 32 ] || ! [[ "$_requestedName" =~ ^[a-z0-9][a-z0-9_-]*$ ]]; then
_output oops "Invalid session name. Use 1-32 lowercase ASCII letters, numbers, hyphens or underscores. The first character must be a letter or number."
fi

if [[ "$_input" =~ ^[a-z]+$ ]]; then
_serverName="$_input"
else
_output oops "Provided input is invalid! Input is for a unique '_serverName'. Do not use numbers, spaces or weird chars. Keep it short, and a-z characters only."
_serverName="$_requestedName"
}

function _isPaneId {
local _paneId="${1:-}"
local _paneNumber=""

case "$_paneId" in
%*) _paneNumber="${_paneId#%}" ;;
*) return 1 ;;
esac

case "$_paneNumber" in
""|*[!0-9]*) return 1 ;;
*) return 0 ;;
esac
}

function _verifyStartedPane {
local _paneId="${1:-}"
local _paneReport=""
local _paneDead=""
local _paneResult=""
local _paneStatus=""
local _paneSignal=""
local _exitDescription=""

_output debug "Checking whether '$_sibling' remains active for $_startupCheckSeconds seconds ..."

if ! sleep "$_startupCheckSeconds"; then
if ! tmux set-option -p -t "$_paneId" remain-on-exit off >/dev/null 2>&1; then
_output oops "The $_startupCheckSeconds-second startup check was interrupted, and tmux could not restore normal close-on-exit behavior. Inspect the '$_serverName' session before retrying."
fi
_output oops "The $_startupCheckSeconds-second startup check was interrupted. The tmux session was not reported as started."
fi

if ! _paneReport=$(tmux display-message -p -t "$_paneId" '#{pane_dead}|#{pane_dead_status}|#{pane_dead_signal}' 2>/dev/null); then
tmux set-option -p -t "$_paneId" remain-on-exit off >/dev/null 2>&1 || true
_output oops "'$_sibling' ended or its tmux pane disappeared during the $_startupCheckSeconds-second startup check. Run './$_sibling' directly from '$_scriptDir' to inspect its full output."
fi

_paneDead="${_paneReport%%|*}"
_paneResult="${_paneReport#*|}"
_paneStatus="${_paneResult%%|*}"
_paneSignal="${_paneResult#*|}"

case "$_paneDead" in
0)
if ! tmux set-option -p -t "$_paneId" remain-on-exit off >/dev/null 2>&1; then
_output oops "'$_sibling' remained active, but tmux could not restore normal close-on-exit behavior for pane '$_paneId'. Inspect the '$_serverName' session before retrying."
fi

if ! _paneDead=$(tmux display-message -p -t "$_paneId" '#{pane_dead}' 2>/dev/null); then
_output oops "'$_sibling' ended as the $_startupCheckSeconds-second startup check completed. The tmux session was not reported as started."
fi

if [ "$_paneDead" != 0 ]; then
tmux kill-pane -t "$_paneId" >/dev/null 2>&1 || true
_output oops "'$_sibling' ended as the $_startupCheckSeconds-second startup check completed. The tmux session was not reported as started."
fi
;;
1)
if [ -n "$_paneStatus" ]; then
_exitDescription="exit status $_paneStatus"
fi
if [ -n "$_paneSignal" ]; then
if [ -n "$_exitDescription" ]; then
_exitDescription="$_exitDescription, signal $_paneSignal"
else
_exitDescription="signal $_paneSignal"
fi
fi
[ -z "$_exitDescription" ] && _exitDescription="unknown exit status"

tmux kill-pane -t "$_paneId" >/dev/null 2>&1 || true
_output oops "'$_sibling' exited during the $_startupCheckSeconds-second startup check ($_exitDescription). Run './$_sibling' directly from '$_scriptDir' to inspect its full output."
;;
*)
tmux set-option -p -t "$_paneId" remain-on-exit off >/dev/null 2>&1 || true
_output oops "tmux returned an unexpected state for pane '$_paneId' during the startup check. The session was not reported as started."
;;
esac
}

_action="start"
_nameArgument="${1:-}"
_nameArgument="$_serverName"

case "${1:-}" in
-h|--help)
[ "$#" -eq 1 ] || _output oops "Unexpected extra arguments. Run '$0 --help' for usage."
_showHelp
exit 0
;;
--status)
[ "$#" -le 2 ] || _output oops "Unexpected extra arguments. Run '$0 --help' for usage."
_action="status"
_nameArgument="${2:-}"
if [ "$#" -eq 2 ]; then
_nameArgument="$2"
fi
;;
--attach)
[ "$#" -le 2 ] || _output oops "Unexpected extra arguments. Run '$0 --help' for usage."
_action="attach"
_nameArgument="${2:-}"
if [ "$#" -eq 2 ]; then
_nameArgument="$2"
fi
;;
--*)
_output oops "Unknown option '$1'. Run '$0 --help' for usage."
;;
*)
[ "$#" -le 1 ] || _output oops "Unexpected extra arguments. Run '$0 --help' for usage."
if [ "$#" -eq 1 ]; then
_nameArgument="$1"
fi
;;
esac

_setServerName "$_nameArgument"

[ "$EUID" -eq 0 ] && _output oops "*!* This script should not be run using sudo, or as the root user!"

if [ "$_action" = start ]; then
Expand All@@ -182,8 +277,6 @@ if [ "$_action" = start ]; then
fi
fi

_setServerName "$_nameArgument"

if ! type "tmux" >/dev/null 2>&1; then
_output oops "'tmux' is required but was not found. On macOS, install it with: brew install tmux"
fi
Expand DownExpand Up@@ -214,9 +307,21 @@ _output debug "Using server directory: $_scriptDir"

_output debug "Found 'tmux', attempting to start '$_sibling' in a detached tmux session ..."
# Deliberately launch only ./1MB-minecraft.sh from the wrapper's own directory.
if ! tmux new-session -d -s "$_serverName" -c "$_scriptDir" "exec \"./$_sibling\""; then
_output oops "Could not create the '$_serverName' tmux session and start '$_sibling'. Review the tmux error above and check with 'tmux ls'."
_paneId=""
if ! _paneId=$(tmux new-session -d -P -F '#{pane_id}' -s "$_serverName" -c "$_scriptDir" "exec \"./$_sibling\"" \; set-option -p -t "=$_serverName:" remain-on-exit on); then
if _isPaneId "$_paneId"; then
tmux kill-pane -t "$_paneId" >/dev/null 2>&1 || true
fi
_output oops "Could not create the '$_serverName' tmux session and prepare its startup check. Review the tmux error above and check with 'tmux ls'."
fi

if ! _isPaneId "$_paneId"; then
tmux kill-session -t "=$_serverName" >/dev/null 2>&1 || true
_output oops "tmux created the '$_serverName' session but did not return a valid pane identifier, so the new session was closed."
fi

_verifyStartedPane "$_paneId"

[[ "$_debug" == true ]] && tmux ls; _output debug "To re-attach: tmux attach -t $_serverName"

_output debug "tmux session started."
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions .github/workflows/1mb-start-tests.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
name: 1MB start wrapper tests

on:
push:
paths:
- "Resources/Server/1MB-start.sh"
- "Resources/Server/tests/1MB-start/**"
- ".github/workflows/1mb-start-tests.yml"
pull_request:
paths:
- "Resources/Server/1MB-start.sh"
- "Resources/Server/tests/1MB-start/**"
- ".github/workflows/1mb-start-tests.yml"
workflow_dispatch:

permissions:
contents: read

jobs:
test:
name: ${{ matrix.os }}
runs-on: ${{ matrix.os }}
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
os:
- macos-latest
- ubuntu-latest

steps:
- name: Check out repository
uses: actions/checkout@v6

- name: Install ShellCheck on macOS
if: runner.os == 'macOS'
run: command -v shellcheck >/dev/null 2>&1 || brew install shellcheck

- name: Install ShellCheck on Ubuntu
if: runner.os == 'Linux'
run: |
if ! command -v shellcheck >/dev/null 2>&1; then
sudo apt-get update
sudo apt-get install --yes shellcheck
fi

- name: Run syntax, behavior, and lint tests
shell: bash
run: /bin/bash Resources/Server/tests/1MB-start/run-tests.sh all
147 changes: 126 additions & 21 deletions Resources/Server/1MB-start.sh
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env bash

# @Filename: 1MB-start.sh
# @Version: 2.17.9, build 082 for Minecraft 26.2 (Java 25, 64bit)
# @Version: 2.18.3, build 086 for Minecraft 26.2 (Java 25, 64bit)
# @Release: August 4th, 2026
# @Description: Helps us start and fork a Minecraft 26.2 server session.
# @Contact: I am @floris on Twitter, and mrfloris in MineCraft.
Expand All@@ -18,7 +18,8 @@
###

_serverName="mcserver"
# Keep the name short, simple, and lowercase (no numbers or weird characters).
# Use 1-32 lowercase ASCII letters, numbers, hyphens or underscores. The first
# character must be a letter or number.
# The name makes it easier to recognize the session in 'tmux ls', you can
# re-attach to the forked sessions with 'tmux attach -t (name)'.

Expand All@@ -30,6 +31,7 @@ _serverName="mcserver"
###

_sibling="1MB-minecraft.sh"
_startupCheckSeconds=2 # Check process liveness only; this is not Paper readiness.
_debug=true # Set to false to minimize output.

### FUNCTIONS AND CODE
Expand All@@ -52,7 +54,7 @@ function _output {
fi

case "$_mode" in
oops|okay) _fd=2 ;;
oops) _fd=2 ;;
esac

if [ -z "${NO_COLOR+x}" ] && [ -t "$_fd" ]; then
Expand All@@ -68,7 +70,7 @@ function _output {
;;
okay)
_args="${*:2}"; _prefix="(Info)";
printf '\n%s%s%s %s%s\n' "$_yellow" "$_prefix" "$_cyan" "$_args" "$_reset" >&2; exit 1
printf '\n%s%s%s %s%s\n' "$_yellow" "$_prefix" "$_cyan" "$_args" "$_reset"; return 0
;;
debug)
_args="${*:2}"; _prefix="(Debug)";
Expand DownExpand Up@@ -131,46 +133,139 @@ function _showHelp {
" --attach [name] Attach to the exact tmux session." \
" --help, -h Show this help." \
"" \
"The session name defaults to '$_serverName'."
"The session name defaults to '$_serverName'." \
"Names use 1-32 lowercase ASCII letters, numbers, hyphens or underscores." \
"The first character must be a letter or number."
}

function _setServerName {
local _requestedName="${1:-}"
local _input=""
local _requestedName="${1-}"
local LC_ALL=C

if [ -n "$_requestedName" ]; then
_input=$(printf '%s\n' "$_requestedName" | awk '{ print tolower($1) }')
_input=$(printf '%s\n' "$_input" | awk '{ print substr($0, 1, 16) }')
if [ "${#_requestedName}" -gt 32 ] || ! [[ "$_requestedName" =~ ^[a-z0-9][a-z0-9_-]*$ ]]; then
_output oops "Invalid session name. Use 1-32 lowercase ASCII letters, numbers, hyphens or underscores. The first character must be a letter or number."
fi

if [[ "$_input" =~ ^[a-z]+$ ]]; then
_serverName="$_input"
else
_output oops "Provided input is invalid! Input is for a unique '_serverName'. Do not use numbers, spaces or weird chars. Keep it short, and a-z characters only."
_serverName="$_requestedName"
}

function _isPaneId {
local _paneId="${1:-}"
local _paneNumber=""

case "$_paneId" in
%*) _paneNumber="${_paneId#%}" ;;
*) return 1 ;;
esac

case "$_paneNumber" in
""|*[!0-9]*) return 1 ;;
*) return 0 ;;
esac
}

function _verifyStartedPane {
local _paneId="${1:-}"
local _paneReport=""
local _paneDead=""
local _paneResult=""
local _paneStatus=""
local _paneSignal=""
local _exitDescription=""

_output debug "Checking whether '$_sibling' remains active for $_startupCheckSeconds seconds ..."

if ! sleep "$_startupCheckSeconds"; then
if ! tmux set-option -p -t "$_paneId" remain-on-exit off >/dev/null 2>&1; then
_output oops "The $_startupCheckSeconds-second startup check was interrupted, and tmux could not restore normal close-on-exit behavior. Inspect the '$_serverName' session before retrying."
fi
_output oops "The $_startupCheckSeconds-second startup check was interrupted. The tmux session was not reported as started."
fi

if ! _paneReport=$(tmux display-message -p -t "$_paneId" '#{pane_dead}|#{pane_dead_status}|#{pane_dead_signal}' 2>/dev/null); then
tmux set-option -p -t "$_paneId" remain-on-exit off >/dev/null 2>&1 || true
_output oops "'$_sibling' ended or its tmux pane disappeared during the $_startupCheckSeconds-second startup check. Run './$_sibling' directly from '$_scriptDir' to inspect its full output."
fi

_paneDead="${_paneReport%%|*}"
_paneResult="${_paneReport#*|}"
_paneStatus="${_paneResult%%|*}"
_paneSignal="${_paneResult#*|}"

case "$_paneDead" in
0)
if ! tmux set-option -p -t "$_paneId" remain-on-exit off >/dev/null 2>&1; then
_output oops "'$_sibling' remained active, but tmux could not restore normal close-on-exit behavior for pane '$_paneId'. Inspect the '$_serverName' session before retrying."
fi

if ! _paneDead=$(tmux display-message -p -t "$_paneId" '#{pane_dead}' 2>/dev/null); then
_output oops "'$_sibling' ended as the $_startupCheckSeconds-second startup check completed. The tmux session was not reported as started."
fi

if [ "$_paneDead" != 0 ]; then
tmux kill-pane -t "$_paneId" >/dev/null 2>&1 || true
_output oops "'$_sibling' ended as the $_startupCheckSeconds-second startup check completed. The tmux session was not reported as started."
fi
;;
1)
if [ -n "$_paneStatus" ]; then
_exitDescription="exit status $_paneStatus"
fi
if [ -n "$_paneSignal" ]; then
if [ -n "$_exitDescription" ]; then
_exitDescription="$_exitDescription, signal $_paneSignal"
else
_exitDescription="signal $_paneSignal"
fi
fi
[ -z "$_exitDescription" ] && _exitDescription="unknown exit status"

tmux kill-pane -t "$_paneId" >/dev/null 2>&1 || true
_output oops "'$_sibling' exited during the $_startupCheckSeconds-second startup check ($_exitDescription). Run './$_sibling' directly from '$_scriptDir' to inspect its full output."
;;
*)
tmux set-option -p -t "$_paneId" remain-on-exit off >/dev/null 2>&1 || true
_output oops "tmux returned an unexpected state for pane '$_paneId' during the startup check. The session was not reported as started."
;;
esac
}

_action="start"
_nameArgument="${1:-}"
_nameArgument="$_serverName"

case "${1:-}" in
-h|--help)
[ "$#" -eq 1 ] || _output oops "Unexpected extra arguments. Run '$0 --help' for usage."
_showHelp
exit 0
;;
--status)
[ "$#" -le 2 ] || _output oops "Unexpected extra arguments. Run '$0 --help' for usage."
_action="status"
_nameArgument="${2:-}"
if [ "$#" -eq 2 ]; then
_nameArgument="$2"
fi
;;
--attach)
[ "$#" -le 2 ] || _output oops "Unexpected extra arguments. Run '$0 --help' for usage."
_action="attach"
_nameArgument="${2:-}"
if [ "$#" -eq 2 ]; then
_nameArgument="$2"
fi
;;
--*)
_output oops "Unknown option '$1'. Run '$0 --help' for usage."
;;
*)
[ "$#" -le 1 ] || _output oops "Unexpected extra arguments. Run '$0 --help' for usage."
if [ "$#" -eq 1 ]; then
_nameArgument="$1"
fi
;;
esac

_setServerName "$_nameArgument"

[ "$EUID" -eq 0 ] && _output oops "*!* This script should not be run using sudo, or as the root user!"

if [ "$_action" = start ]; then
Expand All@@ -182,8 +277,6 @@ if [ "$_action" = start ]; then
fi
fi

_setServerName "$_nameArgument"

if ! type "tmux" >/dev/null 2>&1; then
_output oops "'tmux' is required but was not found. On macOS, install it with: brew install tmux"
fi
Expand DownExpand Up@@ -214,9 +307,21 @@ _output debug "Using server directory: $_scriptDir"

_output debug "Found 'tmux', attempting to start '$_sibling' in a detached tmux session ..."
# Deliberately launch only ./1MB-minecraft.sh from the wrapper's own directory.
if ! tmux new-session -d -s "$_serverName" -c "$_scriptDir" "exec \"./$_sibling\""; then
_output oops "Could not create the '$_serverName' tmux session and start '$_sibling'. Review the tmux error above and check with 'tmux ls'."
_paneId=""
if ! _paneId=$(tmux new-session -d -P -F '#{pane_id}' -s "$_serverName" -c "$_scriptDir" "exec \"./$_sibling\"" \; set-option -p -t "=$_serverName:" remain-on-exit on); then
if _isPaneId "$_paneId"; then
tmux kill-pane -t "$_paneId" >/dev/null 2>&1 || true
fi
_output oops "Could not create the '$_serverName' tmux session and prepare its startup check. Review the tmux error above and check with 'tmux ls'."
fi

if ! _isPaneId "$_paneId"; then
tmux kill-session -t "=$_serverName" >/dev/null 2>&1 || true
_output oops "tmux created the '$_serverName' session but did not return a valid pane identifier, so the new session was closed."
fi

_verifyStartedPane "$_paneId"

[[ "$_debug" == true ]] && tmux ls; _output debug "To re-attach: tmux attach -t $_serverName"

_output debug "tmux session started."
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions .github/workflows/1mb-start-tests.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
name: 1MB start wrapper tests

on:
push:
paths:
- "Resources/Server/1MB-start.sh"
- "Resources/Server/tests/1MB-start/**"
- ".github/workflows/1mb-start-tests.yml"
pull_request:
paths:
- "Resources/Server/1MB-start.sh"
- "Resources/Server/tests/1MB-start/**"
- ".github/workflows/1mb-start-tests.yml"
workflow_dispatch:

permissions:
contents: read

jobs:
test:
name: ${{ matrix.os }}
runs-on: ${{ matrix.os }}
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
os:
- macos-latest
- ubuntu-latest

steps:
- name: Check out repository
uses: actions/checkout@v6

- name: Install ShellCheck on macOS
if: runner.os == 'macOS'
run: command -v shellcheck >/dev/null 2>&1 || brew install shellcheck

- name: Install ShellCheck on Ubuntu
if: runner.os == 'Linux'
run: |
if ! command -v shellcheck >/dev/null 2>&1; then
sudo apt-get update
sudo apt-get install --yes shellcheck
fi

- name: Run syntax, behavior, and lint tests
shell: bash
run: /bin/bash Resources/Server/tests/1MB-start/run-tests.sh all
147 changes: 126 additions & 21 deletions Resources/Server/1MB-start.sh
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env bash

# @Filename: 1MB-start.sh
# @Version: 2.17.9, build 082 for Minecraft 26.2 (Java 25, 64bit)
# @Version: 2.18.3, build 086 for Minecraft 26.2 (Java 25, 64bit)
# @Release: August 4th, 2026
# @Description: Helps us start and fork a Minecraft 26.2 server session.
# @Contact: I am @floris on Twitter, and mrfloris in MineCraft.
Expand All@@ -18,7 +18,8 @@
###

_serverName="mcserver"
# Keep the name short, simple, and lowercase (no numbers or weird characters).
# Use 1-32 lowercase ASCII letters, numbers, hyphens or underscores. The first
# character must be a letter or number.
# The name makes it easier to recognize the session in 'tmux ls', you can
# re-attach to the forked sessions with 'tmux attach -t (name)'.

Expand All@@ -30,6 +31,7 @@ _serverName="mcserver"
###

_sibling="1MB-minecraft.sh"
_startupCheckSeconds=2 # Check process liveness only; this is not Paper readiness.
_debug=true # Set to false to minimize output.

### FUNCTIONS AND CODE
Expand All@@ -52,7 +54,7 @@ function _output {
fi

case "$_mode" in
oops|okay) _fd=2 ;;
oops) _fd=2 ;;
esac

if [ -z "${NO_COLOR+x}" ] && [ -t "$_fd" ]; then
Expand All@@ -68,7 +70,7 @@ function _output {
;;
okay)
_args="${*:2}"; _prefix="(Info)";
printf '\n%s%s%s %s%s\n' "$_yellow" "$_prefix" "$_cyan" "$_args" "$_reset" >&2; exit 1
printf '\n%s%s%s %s%s\n' "$_yellow" "$_prefix" "$_cyan" "$_args" "$_reset"; return 0
;;
debug)
_args="${*:2}"; _prefix="(Debug)";
Expand DownExpand Up@@ -131,46 +133,139 @@ function _showHelp {
" --attach [name] Attach to the exact tmux session." \
" --help, -h Show this help." \
"" \
"The session name defaults to '$_serverName'."
"The session name defaults to '$_serverName'." \
"Names use 1-32 lowercase ASCII letters, numbers, hyphens or underscores." \
"The first character must be a letter or number."
}

function _setServerName {
local _requestedName="${1:-}"
local _input=""
local _requestedName="${1-}"
local LC_ALL=C

if [ -n "$_requestedName" ]; then
_input=$(printf '%s\n' "$_requestedName" | awk '{ print tolower($1) }')
_input=$(printf '%s\n' "$_input" | awk '{ print substr($0, 1, 16) }')
if [ "${#_requestedName}" -gt 32 ] || ! [[ "$_requestedName" =~ ^[a-z0-9][a-z0-9_-]*$ ]]; then
_output oops "Invalid session name. Use 1-32 lowercase ASCII letters, numbers, hyphens or underscores. The first character must be a letter or number."
fi

if [[ "$_input" =~ ^[a-z]+$ ]]; then
_serverName="$_input"
else
_output oops "Provided input is invalid! Input is for a unique '_serverName'. Do not use numbers, spaces or weird chars. Keep it short, and a-z characters only."
_serverName="$_requestedName"
}

function _isPaneId {
local _paneId="${1:-}"
local _paneNumber=""

case "$_paneId" in
%*) _paneNumber="${_paneId#%}" ;;
*) return 1 ;;
esac

case "$_paneNumber" in
""|*[!0-9]*) return 1 ;;
*) return 0 ;;
esac
}

function _verifyStartedPane {
local _paneId="${1:-}"
local _paneReport=""
local _paneDead=""
local _paneResult=""
local _paneStatus=""
local _paneSignal=""
local _exitDescription=""

_output debug "Checking whether '$_sibling' remains active for $_startupCheckSeconds seconds ..."

if ! sleep "$_startupCheckSeconds"; then
if ! tmux set-option -p -t "$_paneId" remain-on-exit off >/dev/null 2>&1; then
_output oops "The $_startupCheckSeconds-second startup check was interrupted, and tmux could not restore normal close-on-exit behavior. Inspect the '$_serverName' session before retrying."
fi
_output oops "The $_startupCheckSeconds-second startup check was interrupted. The tmux session was not reported as started."
fi

if ! _paneReport=$(tmux display-message -p -t "$_paneId" '#{pane_dead}|#{pane_dead_status}|#{pane_dead_signal}' 2>/dev/null); then
tmux set-option -p -t "$_paneId" remain-on-exit off >/dev/null 2>&1 || true
_output oops "'$_sibling' ended or its tmux pane disappeared during the $_startupCheckSeconds-second startup check. Run './$_sibling' directly from '$_scriptDir' to inspect its full output."
fi

_paneDead="${_paneReport%%|*}"
_paneResult="${_paneReport#*|}"
_paneStatus="${_paneResult%%|*}"
_paneSignal="${_paneResult#*|}"

case "$_paneDead" in
0)
if ! tmux set-option -p -t "$_paneId" remain-on-exit off >/dev/null 2>&1; then
_output oops "'$_sibling' remained active, but tmux could not restore normal close-on-exit behavior for pane '$_paneId'. Inspect the '$_serverName' session before retrying."
fi

if ! _paneDead=$(tmux display-message -p -t "$_paneId" '#{pane_dead}' 2>/dev/null); then
_output oops "'$_sibling' ended as the $_startupCheckSeconds-second startup check completed. The tmux session was not reported as started."
fi

if [ "$_paneDead" != 0 ]; then
tmux kill-pane -t "$_paneId" >/dev/null 2>&1 || true
_output oops "'$_sibling' ended as the $_startupCheckSeconds-second startup check completed. The tmux session was not reported as started."
fi
;;
1)
if [ -n "$_paneStatus" ]; then
_exitDescription="exit status $_paneStatus"
fi
if [ -n "$_paneSignal" ]; then
if [ -n "$_exitDescription" ]; then
_exitDescription="$_exitDescription, signal $_paneSignal"
else
_exitDescription="signal $_paneSignal"
fi
fi
[ -z "$_exitDescription" ] && _exitDescription="unknown exit status"

tmux kill-pane -t "$_paneId" >/dev/null 2>&1 || true
_output oops "'$_sibling' exited during the $_startupCheckSeconds-second startup check ($_exitDescription). Run './$_sibling' directly from '$_scriptDir' to inspect its full output."
;;
*)
tmux set-option -p -t "$_paneId" remain-on-exit off >/dev/null 2>&1 || true
_output oops "tmux returned an unexpected state for pane '$_paneId' during the startup check. The session was not reported as started."
;;
esac
}

_action="start"
_nameArgument="${1:-}"
_nameArgument="$_serverName"

case "${1:-}" in
-h|--help)
[ "$#" -eq 1 ] || _output oops "Unexpected extra arguments. Run '$0 --help' for usage."
_showHelp
exit 0
;;
--status)
[ "$#" -le 2 ] || _output oops "Unexpected extra arguments. Run '$0 --help' for usage."
_action="status"
_nameArgument="${2:-}"
if [ "$#" -eq 2 ]; then
_nameArgument="$2"
fi
;;
--attach)
[ "$#" -le 2 ] || _output oops "Unexpected extra arguments. Run '$0 --help' for usage."
_action="attach"
_nameArgument="${2:-}"
if [ "$#" -eq 2 ]; then
_nameArgument="$2"
fi
;;
--*)
_output oops "Unknown option '$1'. Run '$0 --help' for usage."
;;
*)
[ "$#" -le 1 ] || _output oops "Unexpected extra arguments. Run '$0 --help' for usage."
if [ "$#" -eq 1 ]; then
_nameArgument="$1"
fi
;;
esac

_setServerName "$_nameArgument"

[ "$EUID" -eq 0 ] && _output oops "*!* This script should not be run using sudo, or as the root user!"

if [ "$_action" = start ]; then
Expand All@@ -182,8 +277,6 @@ if [ "$_action" = start ]; then
fi
fi

_setServerName "$_nameArgument"

if ! type "tmux" >/dev/null 2>&1; then
_output oops "'tmux' is required but was not found. On macOS, install it with: brew install tmux"
fi
Expand DownExpand Up@@ -214,9 +307,21 @@ _output debug "Using server directory: $_scriptDir"

_output debug "Found 'tmux', attempting to start '$_sibling' in a detached tmux session ..."
# Deliberately launch only ./1MB-minecraft.sh from the wrapper's own directory.
if ! tmux new-session -d -s "$_serverName" -c "$_scriptDir" "exec \"./$_sibling\""; then
_output oops "Could not create the '$_serverName' tmux session and start '$_sibling'. Review the tmux error above and check with 'tmux ls'."
_paneId=""
if ! _paneId=$(tmux new-session -d -P -F '#{pane_id}' -s "$_serverName" -c "$_scriptDir" "exec \"./$_sibling\"" \; set-option -p -t "=$_serverName:" remain-on-exit on); then
if _isPaneId "$_paneId"; then
tmux kill-pane -t "$_paneId" >/dev/null 2>&1 || true
fi
_output oops "Could not create the '$_serverName' tmux session and prepare its startup check. Review the tmux error above and check with 'tmux ls'."
fi

if ! _isPaneId "$_paneId"; then
tmux kill-session -t "=$_serverName" >/dev/null 2>&1 || true
_output oops "tmux created the '$_serverName' session but did not return a valid pane identifier, so the new session was closed."
fi

_verifyStartedPane "$_paneId"

[[ "$_debug" == true ]] && tmux ls; _output debug "To re-attach: tmux attach -t $_serverName"

_output debug "tmux session started."
Expand Down
Loading
Loading