diff --git a/README.md b/README.md
index 19ec0e879..043aed085 100644
--- a/README.md
+++ b/README.md
@@ -19,7 +19,7 @@

[](https://github.com/cabaletta/baritone/graphs/contributors/)
[](https://github.com/cabaletta/baritone/commit/)
-[](https://impactclient.net/)
+[](https://impactclient.net/)
[](https://github.com/fr1kin/ForgeHax/)
[](https://gitlab.com/emc-mods-indrit/baritone_api)
[](https://wweclient.com/)
diff --git a/USAGE.md b/USAGE.md
index 25fef11e8..0f911efaa 100644
--- a/USAGE.md
+++ b/USAGE.md
@@ -8,11 +8,23 @@ Baritone commands can also by default be typed in the chatbox. However if you ma
To disable direct chat control (with no prefix), turn off the `chatControl` setting. To disable chat control with the `#` prefix, turn off the `prefixControl` setting. In Impact, `.b` cannot be disabled. Be careful that you don't leave yourself with all control methods disabled (if you do, reset your settings by deleting the file `minecraft/baritone/settings.txt` and relaunching).
+# For Baritone 1.2.10+, 1.3.5+, 1.4.2+
+
+Lots of the commands have changed, BUT `#help` is improved vastly (its clickable! commands have tab completion! oh my!).
+
+Try `#help` I promise it won't just send you back here =)
+
+"wtf where is cleararea" -> look at `#help sel`
+
+"wtf where is goto death, goto waypoint" -> look at `#help wp` (a "tag" is like "home" (created automatically on right clicking a bed) or "death" (created automatically on death) or "user" (has to be created manually)). So you might want `#wp save user coolbiome` then, to set the goal `#wp goal coolbiome` then `#path` to path to it. For death, `#wp goal death` (remember stuff is clickable!).
+
+just look at `#help` lmao
+
# Commands
**All** of these commands may need a prefix before them, as above ^.
-`help` for (rudimentary) help. You can see what it says [here](https://github.com/cabaletta/baritone/blob/master/src/api/java/baritone/api/utils/ExampleBaritoneControl.java#L47).
+`help`
To toggle a boolean setting, just say its name in chat (for example saying `allowBreak` toggles whether Baritone will consider breaking blocks). For a numeric setting, say its name then the new value (like `primaryTimeoutMS 250`). It's case insensitive. To reset a setting to its default value, say `acceptableThrowawayItems reset`. To reset all settings, say `reset`. To see all settings that have been modified from their default values, say `modified`.
@@ -38,12 +50,6 @@ Some common examples:
- `version` to get the version of Baritone you're running
- `damn` daniel
-
-New commands:
-- `sel` to manage selections
-- some others
-
-
For the rest of the commands, you can take a look at the code [here](https://github.com/cabaletta/baritone/blob/master/src/api/java/baritone/api/utils/ExampleBaritoneControl.java).
All the settings and documentation are here. If you find HTML easier to read than Javadoc, you can look here.
diff --git a/build.gradle b/build.gradle
index f3844ab91..c74538e35 100755
--- a/build.gradle
+++ b/build.gradle
@@ -20,7 +20,6 @@ version '1.4.3'
buildscript {
repositories {
- jcenter()
maven {
name = 'forge'
url = 'http://files.minecraftforge.net/maven'
@@ -29,6 +28,7 @@ buildscript {
name = 'impactdevelopment-repo'
url = 'https://impactdevelopment.github.io/maven/'
}
+ jcenter()
}
dependencies {
diff --git a/src/api/java/baritone/api/IBaritoneProvider.java b/src/api/java/baritone/api/IBaritoneProvider.java
index d6e3d93ba..697f25dc6 100644
--- a/src/api/java/baritone/api/IBaritoneProvider.java
+++ b/src/api/java/baritone/api/IBaritoneProvider.java
@@ -21,6 +21,7 @@ import baritone.api.cache.IWorldScanner;
import baritone.api.command.ICommand;
import baritone.api.command.ICommandSystem;
import net.minecraft.client.entity.player.ClientPlayerEntity;
+import baritone.api.schematic.ISchematicSystem;
import java.util.List;
import java.util.Objects;
@@ -82,4 +83,9 @@ public interface IBaritoneProvider {
* @return The {@link ICommandSystem} instance.
*/
ICommandSystem getCommandSystem();
+
+ /**
+ * @return The {@link ISchematicSystem} instance.
+ */
+ ISchematicSystem getSchematicSystem();
}
diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java
index b6a8770f0..7fb9c53b9 100644
--- a/src/api/java/baritone/api/Settings.java
+++ b/src/api/java/baritone/api/Settings.java
@@ -181,6 +181,20 @@ public final class Settings {
Blocks.TRAPPED_CHEST
)));
+ /**
+ * A list of blocks to be treated as if they're air.
+ *
+ * If a schematic asks for air at a certain position, and that position currently contains a block on this list, it will be treated as correct.
+ */
+ public final Setting> buildIgnoreBlocks = new Setting<>(new ArrayList<>(Arrays.asList(
+
+ )));
+
+ /**
+ * If this is true, the builder will treat all non-air blocks as correct. It will only place new blocks.
+ */
+ public final Setting buildIgnoreExisting = new Setting<>(false);
+
/**
* If this setting is true, Baritone will never break a block that is adjacent to an unsupported falling block.
*
@@ -231,7 +245,7 @@ public final class Settings {
/**
* If we overshoot a traverse and end up one block beyond the destination, mark it as successful anyway.
*
- * This helps with speed at >=20m/s
+ * This helps with speed exceeding 20m/s
*/
public final Setting overshootTraverse = new Setting<>(true);
@@ -250,6 +264,11 @@ public final class Settings {
*/
public final Setting randomLooking113 = new Setting<>(2d);
+ /**
+ * Block reach distance
+ */
+ public final Setting blockReachDistance = new Setting<>(4.5f);
+
/**
* How many degrees to randomize the pitch and yaw every tick. Set to 0 to disable
*/
@@ -740,6 +759,11 @@ public final class Settings {
*/
public final Setting buildRepeat = new Setting<>(new Vec3i(0, 0, 0));
+ /**
+ * How many times to buildrepeat. -1 for infinite.
+ */
+ public final Setting buildRepeatCount = new Setting<>(-1);
+
/**
* Allow standing above a block while mining it, in BuilderProcess
*
@@ -789,6 +813,12 @@ public final class Settings {
*/
public final Setting schematicOrientationZ = new Setting<>(false);
+ /**
+ * The fallback used by the build command when no extension is specified. This may be useful if schematics of a
+ * particular format are used often, and the user does not wish to have to specify the extension with every usage.
+ */
+ public final Setting schematicFallbackExtension = new Setting<>("schematic");
+
/**
* Distance to scan every tick for updates. Expanding this beyond player reach distance (i.e. setting it to 6 or above)
* is only necessary in very large schematics where rescanning the whole thing is costly.
diff --git a/src/api/java/baritone/api/cache/ICachedWorld.java b/src/api/java/baritone/api/cache/ICachedWorld.java
index 837ae076c..e681ce51c 100644
--- a/src/api/java/baritone/api/cache/ICachedWorld.java
+++ b/src/api/java/baritone/api/cache/ICachedWorld.java
@@ -81,6 +81,4 @@ public interface ICachedWorld {
* in a new thread by default.
*/
void save();
-
-
}
diff --git a/src/api/java/baritone/api/cache/IWorldScanner.java b/src/api/java/baritone/api/cache/IWorldScanner.java
index 325d4bd0e..224f64c76 100644
--- a/src/api/java/baritone/api/cache/IWorldScanner.java
+++ b/src/api/java/baritone/api/cache/IWorldScanner.java
@@ -77,10 +77,20 @@ public interface IWorldScanner {
}
/**
- * Repacks 40 chunks around the player.
+ * Overload of {@link #repack(IPlayerContext, int)} where the value of the {@code range} parameter is {@code 40}.
*
- * @param ctx The player context for that player.
- * @return The number of chunks queued for repacking.
+ * @param ctx The player, describing the origin
+ * @return The amount of chunks successfully queued for repacking
*/
int repack(IPlayerContext ctx);
+
+ /**
+ * Queues the chunks in a square formation around the specified player, using the specified
+ * range, which represents 1/2 the square's dimensions, where the player is in the center.
+ *
+ * @param ctx The player, describing the origin
+ * @param range The range to repack
+ * @return The amount of chunks successfully queued for repacking
+ */
+ int repack(IPlayerContext ctx, int range);
}
diff --git a/src/api/java/baritone/api/command/datatypes/RelativeGoal.java b/src/api/java/baritone/api/command/datatypes/RelativeGoal.java
index cda0ad665..19312907e 100644
--- a/src/api/java/baritone/api/command/datatypes/RelativeGoal.java
+++ b/src/api/java/baritone/api/command/datatypes/RelativeGoal.java
@@ -38,38 +38,26 @@ public enum RelativeGoal implements IDatatypePost {
if (origin == null) {
origin = BetterBlockPos.ORIGIN;
}
+
final IArgConsumer consumer = ctx.getConsumer();
- List> coords = new ArrayList<>();
- final IArgConsumer copy = consumer.copy(); // This is a hack and should be fixed in the future probably
- for (int i = 0; i < 3; i++) {
- if (copy.peekDatatypeOrNull(RelativeCoordinate.INSTANCE) != null) {
- coords.add(o -> consumer.getDatatypePost(RelativeCoordinate.INSTANCE, o));
- copy.get(); // Consume so we actually decrement the remaining arguments
- }
+ GoalBlock goalBlock = consumer.peekDatatypePostOrNull(RelativeGoalBlock.INSTANCE, origin);
+ if (goalBlock != null) {
+ return goalBlock;
}
- switch (coords.size()) {
- case 0:
- return new GoalBlock(origin);
- case 1:
- return new GoalYLevel(
- MathHelper.floor(coords.get(0).apply((double) origin.y))
- );
- case 2:
- return new GoalXZ(
- MathHelper.floor(coords.get(0).apply((double) origin.x)),
- MathHelper.floor(coords.get(1).apply((double) origin.z))
- );
- case 3:
- return new GoalBlock(
- MathHelper.floor(coords.get(0).apply((double) origin.x)),
- MathHelper.floor(coords.get(1).apply((double) origin.y)),
- MathHelper.floor(coords.get(2).apply((double) origin.z))
- );
- default:
- throw new IllegalStateException("Unexpected coords size: " + coords.size());
+ GoalXZ goalXZ = consumer.peekDatatypePostOrNull(RelativeGoalXZ.INSTANCE, origin);
+ if (goalXZ != null) {
+ return goalXZ;
}
+
+ GoalYLevel goalYLevel = consumer.peekDatatypePostOrNull(RelativeGoalYLevel.INSTANCE, origin);
+ if (goalYLevel != null) {
+ return goalYLevel;
+ }
+
+ // when the user doesn't input anything, default to the origin
+ return new GoalBlock(origin);
}
@Override
diff --git a/src/api/java/baritone/api/command/exception/CommandErrorMessageException.java b/src/api/java/baritone/api/command/exception/CommandErrorMessageException.java
index 4a21bede7..b31615163 100644
--- a/src/api/java/baritone/api/command/exception/CommandErrorMessageException.java
+++ b/src/api/java/baritone/api/command/exception/CommandErrorMessageException.java
@@ -22,4 +22,8 @@ public abstract class CommandErrorMessageException extends CommandException {
protected CommandErrorMessageException(String reason) {
super(reason);
}
+
+ protected CommandErrorMessageException(String reason, Throwable cause) {
+ super(reason, cause);
+ }
}
diff --git a/src/api/java/baritone/api/command/exception/CommandException.java b/src/api/java/baritone/api/command/exception/CommandException.java
index b8962c159..53b8e6023 100644
--- a/src/api/java/baritone/api/command/exception/CommandException.java
+++ b/src/api/java/baritone/api/command/exception/CommandException.java
@@ -22,4 +22,8 @@ public abstract class CommandException extends Exception implements ICommandExce
protected CommandException(String reason) {
super(reason);
}
+
+ protected CommandException(String reason, Throwable cause) {
+ super(reason, cause);
+ }
}
diff --git a/src/api/java/baritone/api/command/exception/CommandInvalidArgumentException.java b/src/api/java/baritone/api/command/exception/CommandInvalidArgumentException.java
index 1902d7355..6997d6d69 100644
--- a/src/api/java/baritone/api/command/exception/CommandInvalidArgumentException.java
+++ b/src/api/java/baritone/api/command/exception/CommandInvalidArgumentException.java
@@ -23,12 +23,21 @@ public abstract class CommandInvalidArgumentException extends CommandErrorMessag
public final ICommandArgument arg;
- protected CommandInvalidArgumentException(ICommandArgument arg, String reason) {
- super(String.format(
- "Error at argument #%s: %s",
- arg.getIndex() == -1 ? "" : Integer.toString(arg.getIndex() + 1),
- reason
- ));
+ protected CommandInvalidArgumentException(ICommandArgument arg, String message) {
+ super(formatMessage(arg, message));
this.arg = arg;
}
+
+ protected CommandInvalidArgumentException(ICommandArgument arg, String message, Throwable cause) {
+ super(formatMessage(arg, message), cause);
+ this.arg = arg;
+ }
+
+ private static String formatMessage(ICommandArgument arg, String message) {
+ return String.format(
+ "Error at argument #%s: %s",
+ arg.getIndex() == -1 ? "" : Integer.toString(arg.getIndex() + 1),
+ message
+ );
+ }
}
diff --git a/src/api/java/baritone/api/command/exception/CommandInvalidTypeException.java b/src/api/java/baritone/api/command/exception/CommandInvalidTypeException.java
index 516fd308f..06658c3a0 100644
--- a/src/api/java/baritone/api/command/exception/CommandInvalidTypeException.java
+++ b/src/api/java/baritone/api/command/exception/CommandInvalidTypeException.java
@@ -26,7 +26,7 @@ public class CommandInvalidTypeException extends CommandInvalidArgumentException
}
public CommandInvalidTypeException(ICommandArgument arg, String expected, Throwable cause) {
- super(arg, String.format("Expected %s.\nMore details: %s", expected, cause.getMessage()));
+ super(arg, String.format("Expected %s", expected), cause);
}
public CommandInvalidTypeException(ICommandArgument arg, String expected, String got) {
@@ -34,6 +34,6 @@ public class CommandInvalidTypeException extends CommandInvalidArgumentException
}
public CommandInvalidTypeException(ICommandArgument arg, String expected, String got, Throwable cause) {
- super(arg, String.format("Expected %s, but got %s instead.\nMore details: %s", expected, got, cause.getMessage()));
+ super(arg, String.format("Expected %s, but got %s instead", expected, got), cause);
}
}
diff --git a/src/api/java/baritone/api/command/exception/CommandUnhandledException.java b/src/api/java/baritone/api/command/exception/CommandUnhandledException.java
index fe0b09fad..02987d4ee 100644
--- a/src/api/java/baritone/api/command/exception/CommandUnhandledException.java
+++ b/src/api/java/baritone/api/command/exception/CommandUnhandledException.java
@@ -37,7 +37,7 @@ public class CommandUnhandledException extends RuntimeException implements IComm
@Override
public void handle(ICommand command, List args) {
- HELPER.logDirect("An unhandled exception occurred." +
+ HELPER.logDirect("An unhandled exception occurred. " +
"The error is in your game's log, please report this at https://github.com/cabaletta/baritone/issues",
TextFormatting.RED);
diff --git a/src/api/java/baritone/api/event/events/TickEvent.java b/src/api/java/baritone/api/event/events/TickEvent.java
index da8f8878a..5c484ae49 100644
--- a/src/api/java/baritone/api/event/events/TickEvent.java
+++ b/src/api/java/baritone/api/event/events/TickEvent.java
@@ -19,22 +19,20 @@ package baritone.api.event.events;
import baritone.api.event.events.type.EventState;
+import java.util.function.BiFunction;
+
public final class TickEvent {
+ private static int overallTickCount;
+
private final EventState state;
private final Type type;
private final int count;
- private static int overallTickCount;
-
- public TickEvent(EventState state, Type type) {
+ public TickEvent(EventState state, Type type, int count) {
this.state = state;
this.type = type;
- this.count = incrementCount();
- }
-
- private static synchronized int incrementCount() {
- return overallTickCount++;
+ this.count = count;
}
public int getCount() {
@@ -49,6 +47,10 @@ public final class TickEvent {
return state;
}
+ public static synchronized BiFunction createNextProvider() {
+ final int count = overallTickCount++;
+ return (state, type) -> new TickEvent(state, type, count);
+ }
public enum Type {
/**
diff --git a/src/api/java/baritone/api/schematic/AbstractSchematic.java b/src/api/java/baritone/api/schematic/AbstractSchematic.java
index 3cd14747d..cca6bc966 100644
--- a/src/api/java/baritone/api/schematic/AbstractSchematic.java
+++ b/src/api/java/baritone/api/schematic/AbstractSchematic.java
@@ -23,6 +23,10 @@ public abstract class AbstractSchematic implements ISchematic {
protected int y;
protected int z;
+ public AbstractSchematic() {
+ this(0, 0, 0);
+ }
+
public AbstractSchematic(int x, int y, int z) {
this.x = x;
this.y = y;
diff --git a/src/api/java/baritone/api/schematic/FillSchematic.java b/src/api/java/baritone/api/schematic/FillSchematic.java
index 2adcbbfc0..e43ddb93c 100644
--- a/src/api/java/baritone/api/schematic/FillSchematic.java
+++ b/src/api/java/baritone/api/schematic/FillSchematic.java
@@ -32,6 +32,10 @@ public class FillSchematic extends AbstractSchematic {
this.bom = bom;
}
+ public FillSchematic(int x, int y, int z, BlockState state) {
+ this(x, y, z, new BlockOptionalMeta(state.getBlock()));
+ }
+
public BlockOptionalMeta getBom() {
return bom;
}
diff --git a/src/api/java/baritone/api/schematic/ISchematicSystem.java b/src/api/java/baritone/api/schematic/ISchematicSystem.java
new file mode 100644
index 000000000..c8f039070
--- /dev/null
+++ b/src/api/java/baritone/api/schematic/ISchematicSystem.java
@@ -0,0 +1,44 @@
+/*
+ * This file is part of Baritone.
+ *
+ * Baritone is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Baritone is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Baritone. If not, see .
+ */
+
+package baritone.api.schematic;
+
+import baritone.api.command.registry.Registry;
+import baritone.api.schematic.format.ISchematicFormat;
+
+import java.io.File;
+import java.util.Optional;
+
+/**
+ * @author Brady
+ * @since 12/23/2019
+ */
+public interface ISchematicSystem {
+
+ /**
+ * @return The registry of supported schematic formats
+ */
+ Registry getRegistry();
+
+ /**
+ * Attempts to find an {@link ISchematicFormat} that supports the specified schematic file.
+ *
+ * @param file A schematic file
+ * @return The corresponding format for the file, {@link Optional#empty()} if no candidates were found.
+ */
+ Optional getByFile(File file);
+}
diff --git a/src/api/java/baritone/api/schematic/IStaticSchematic.java b/src/api/java/baritone/api/schematic/IStaticSchematic.java
new file mode 100644
index 000000000..e0872ede3
--- /dev/null
+++ b/src/api/java/baritone/api/schematic/IStaticSchematic.java
@@ -0,0 +1,60 @@
+/*
+ * This file is part of Baritone.
+ *
+ * Baritone is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Baritone is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Baritone. If not, see .
+ */
+
+package baritone.api.schematic;
+
+import net.minecraft.block.BlockState;
+
+/**
+ * A static schematic is capable of providing the desired state at a given position without
+ * additional context. Schematics of this type are expected to have non-varying contents.
+ *
+ * @see #getDirect(int, int, int)
+ *
+ * @author Brady
+ * @since 12/24/2019
+ */
+public interface IStaticSchematic extends ISchematic {
+
+ /**
+ * Gets the {@link BlockState} for a given position in this schematic. It should be guaranteed
+ * that the return value of this method will not change given that the parameters are the same.
+ *
+ * @param x The X block position
+ * @param y The Y block position
+ * @param z The Z block position
+ * @return The desired state at the specified position.
+ */
+ BlockState getDirect(int x, int y, int z);
+
+ /**
+ * Returns an {@link BlockState} array of size {@link #heightY()} which contains all
+ * desired block states in the specified vertical column. The index of {@link BlockState}s
+ * in the array are equivalent to their Y position in the schematic.
+ *
+ * @param x The X column position
+ * @param z The Z column position
+ * @return An {@link BlockState} array
+ */
+ default BlockState[] getColumn(int x, int z) {
+ BlockState[] column = new BlockState[this.heightY()];
+ for (int i = 0; i < this.heightY(); i++) {
+ column[i] = getDirect(x, i, z);
+ }
+ return column;
+ }
+}
diff --git a/src/api/java/baritone/api/schematic/format/ISchematicFormat.java b/src/api/java/baritone/api/schematic/format/ISchematicFormat.java
new file mode 100644
index 000000000..3fe045bcf
--- /dev/null
+++ b/src/api/java/baritone/api/schematic/format/ISchematicFormat.java
@@ -0,0 +1,45 @@
+/*
+ * This file is part of Baritone.
+ *
+ * Baritone is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Baritone is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Baritone. If not, see .
+ */
+
+package baritone.api.schematic.format;
+
+import baritone.api.schematic.ISchematic;
+import baritone.api.schematic.IStaticSchematic;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * The base of a {@link ISchematic} file format
+ *
+ * @author Brady
+ * @since 12/23/2019
+ */
+public interface ISchematicFormat {
+
+ /**
+ * @return The parser for creating schematics of this format
+ */
+ IStaticSchematic parse(InputStream input) throws IOException;
+
+ /**
+ * @param file The file to check against
+ * @return Whether or not the specified file matches this schematic format
+ */
+ boolean isFileType(File file);
+}
diff --git a/src/api/java/baritone/api/utils/BlockOptionalMeta.java b/src/api/java/baritone/api/utils/BlockOptionalMeta.java
index 85408ac95..a1b38cca1 100644
--- a/src/api/java/baritone/api/utils/BlockOptionalMeta.java
+++ b/src/api/java/baritone/api/utils/BlockOptionalMeta.java
@@ -24,9 +24,6 @@ import net.minecraft.block.*;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.resources.*;
-import net.minecraft.state.IProperty;
-import net.minecraft.state.properties.*;
-import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.Unit;
import net.minecraft.util.math.BlockPos;
@@ -36,7 +33,6 @@ import net.minecraft.world.storage.loot.*;
import javax.annotation.Nonnull;
import java.util.*;
import java.util.concurrent.CompletableFuture;
-import java.util.function.Consumer;
import java.util.regex.MatchResult;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -49,7 +45,6 @@ public final class BlockOptionalMeta {
private final ImmutableSet stateHashes;
private final ImmutableSet stackHashes;
private static final Pattern pattern = Pattern.compile("^(.+?)(?::(\\d+))?$");
- private static final Map