mirror of
https://hub.spigotmc.org/stash/scm/spigot/craftbukkit.git
synced 2025-08-05 16:49:30 +00:00
Update to JLine 3
This commit is contained in:
parent
d257c87b12
commit
2ed8fab2ee
11 changed files with 148 additions and 228 deletions
|
@ -1,6 +1,6 @@
|
||||||
--- a/net/minecraft/server/MinecraftServer.java
|
--- a/net/minecraft/server/MinecraftServer.java
|
||||||
+++ b/net/minecraft/server/MinecraftServer.java
|
+++ b/net/minecraft/server/MinecraftServer.java
|
||||||
@@ -177,13 +177,39 @@
|
@@ -177,13 +177,40 @@
|
||||||
import net.minecraft.world.phys.Vec3D;
|
import net.minecraft.world.phys.Vec3D;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
|
@ -9,7 +9,6 @@
|
||||||
+import com.mojang.serialization.Lifecycle;
|
+import com.mojang.serialization.Lifecycle;
|
||||||
+import java.io.File;
|
+import java.io.File;
|
||||||
+import java.util.Random;
|
+import java.util.Random;
|
||||||
+import jline.console.ConsoleReader;
|
|
||||||
+import joptsimple.OptionSet;
|
+import joptsimple.OptionSet;
|
||||||
+import net.minecraft.nbt.NbtException;
|
+import net.minecraft.nbt.NbtException;
|
||||||
+import net.minecraft.nbt.ReportedNbtException;
|
+import net.minecraft.nbt.ReportedNbtException;
|
||||||
|
@ -28,6 +27,8 @@
|
||||||
+import org.bukkit.craftbukkit.Main;
|
+import org.bukkit.craftbukkit.Main;
|
||||||
+import org.bukkit.craftbukkit.event.CraftEventFactory;
|
+import org.bukkit.craftbukkit.event.CraftEventFactory;
|
||||||
+import org.bukkit.event.server.ServerLoadEvent;
|
+import org.bukkit.event.server.ServerLoadEvent;
|
||||||
|
+import org.jline.terminal.Terminal;
|
||||||
|
+import org.jline.terminal.TerminalBuilder;
|
||||||
+// CraftBukkit end
|
+// CraftBukkit end
|
||||||
+
|
+
|
||||||
public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTask> implements ServerInfo, ChunkIOErrorReporter, ICommandListener {
|
public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTask> implements ServerInfo, ChunkIOErrorReporter, ICommandListener {
|
||||||
|
@ -41,7 +42,7 @@
|
||||||
private static final int OVERLOADED_TICKS_THRESHOLD = 20;
|
private static final int OVERLOADED_TICKS_THRESHOLD = 20;
|
||||||
private static final long OVERLOADED_WARNING_INTERVAL_NANOS = 10L * TimeRange.NANOSECONDS_PER_SECOND;
|
private static final long OVERLOADED_WARNING_INTERVAL_NANOS = 10L * TimeRange.NANOSECONDS_PER_SECOND;
|
||||||
private static final int OVERLOADED_TICKS_WARNING_INTERVAL = 100;
|
private static final int OVERLOADED_TICKS_WARNING_INTERVAL = 100;
|
||||||
@@ -274,6 +300,19 @@
|
@@ -274,6 +301,19 @@
|
||||||
private final SuppressedExceptionCollector suppressedExceptions;
|
private final SuppressedExceptionCollector suppressedExceptions;
|
||||||
private final DiscontinuousFrame tickFrame;
|
private final DiscontinuousFrame tickFrame;
|
||||||
|
|
||||||
|
@ -50,7 +51,7 @@
|
||||||
+ public org.bukkit.craftbukkit.CraftServer server;
|
+ public org.bukkit.craftbukkit.CraftServer server;
|
||||||
+ public OptionSet options;
|
+ public OptionSet options;
|
||||||
+ public org.bukkit.command.ConsoleCommandSender console;
|
+ public org.bukkit.command.ConsoleCommandSender console;
|
||||||
+ public ConsoleReader reader;
|
+ public Terminal terminal;
|
||||||
+ public static int currentTick = (int) (System.currentTimeMillis() / 50);
|
+ public static int currentTick = (int) (System.currentTimeMillis() / 50);
|
||||||
+ public java.util.Queue<Runnable> processQueue = new java.util.concurrent.ConcurrentLinkedQueue<Runnable>();
|
+ public java.util.Queue<Runnable> processQueue = new java.util.concurrent.ConcurrentLinkedQueue<Runnable>();
|
||||||
+ public int autosavePeriod;
|
+ public int autosavePeriod;
|
||||||
|
@ -61,7 +62,7 @@
|
||||||
public static <S extends MinecraftServer> S spin(Function<Thread, S> function) {
|
public static <S extends MinecraftServer> S spin(Function<Thread, S> function) {
|
||||||
AtomicReference<S> atomicreference = new AtomicReference();
|
AtomicReference<S> atomicreference = new AtomicReference();
|
||||||
Thread thread = new Thread(() -> {
|
Thread thread = new Thread(() -> {
|
||||||
@@ -294,7 +333,7 @@
|
@@ -294,7 +334,7 @@
|
||||||
return s0;
|
return s0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +71,7 @@
|
||||||
super("Server");
|
super("Server");
|
||||||
this.metricsRecorder = InactiveMetricsRecorder.INSTANCE;
|
this.metricsRecorder = InactiveMetricsRecorder.INSTANCE;
|
||||||
this.onMetricsRecordingStopped = (methodprofilerresults) -> {
|
this.onMetricsRecordingStopped = (methodprofilerresults) -> {
|
||||||
@@ -318,7 +357,7 @@
|
@@ -318,7 +358,7 @@
|
||||||
this.suppressedExceptions = new SuppressedExceptionCollector();
|
this.suppressedExceptions = new SuppressedExceptionCollector();
|
||||||
this.registries = worldstem.registries();
|
this.registries = worldstem.registries();
|
||||||
this.worldData = worldstem.worldData();
|
this.worldData = worldstem.worldData();
|
||||||
|
@ -79,7 +80,7 @@
|
||||||
throw new IllegalStateException("Missing Overworld dimension data");
|
throw new IllegalStateException("Missing Overworld dimension data");
|
||||||
} else {
|
} else {
|
||||||
this.proxy = proxy;
|
this.proxy = proxy;
|
||||||
@@ -346,6 +385,33 @@
|
@@ -346,6 +386,30 @@
|
||||||
this.fuelValues = FuelValues.vanillaBurnTimes(this.registries.compositeAccess(), this.worldData.enabledFeatures());
|
this.fuelValues = FuelValues.vanillaBurnTimes(this.registries.compositeAccess(), this.worldData.enabledFeatures());
|
||||||
this.tickFrame = TracyClient.createDiscontinuousFrame("Server Tick");
|
this.tickFrame = TracyClient.createDiscontinuousFrame("Server Tick");
|
||||||
}
|
}
|
||||||
|
@ -88,22 +89,19 @@
|
||||||
+ this.worldLoader = worldLoader;
|
+ this.worldLoader = worldLoader;
|
||||||
+ this.vanillaCommandDispatcher = worldstem.dataPackResources().commands; // CraftBukkit
|
+ this.vanillaCommandDispatcher = worldstem.dataPackResources().commands; // CraftBukkit
|
||||||
+ // Try to see if we're actually running in a terminal, disable jline if not
|
+ // Try to see if we're actually running in a terminal, disable jline if not
|
||||||
+ if (System.console() == null && System.getProperty("jline.terminal") == null) {
|
+ if (System.console() == null && System.getProperty(TerminalBuilder.PROP_PROVIDER) == null) {
|
||||||
+ System.setProperty("jline.terminal", "jline.UnsupportedTerminal");
|
+ System.setProperty(TerminalBuilder.PROP_PROVIDER, Terminal.TYPE_DUMB);
|
||||||
+ Main.useJline = false;
|
+ Main.useJline = false;
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ try {
|
+ try {
|
||||||
+ reader = new ConsoleReader(System.in, System.out);
|
+ terminal = TerminalBuilder.builder().dumb(false).build();
|
||||||
+ reader.setExpandEvents(false); // Avoid parsing exceptions for uncommonly used event designators
|
|
||||||
+ } catch (Throwable e) {
|
+ } catch (Throwable e) {
|
||||||
+ try {
|
+ try {
|
||||||
+ // Try again with jline disabled for Windows users without C++ 2008 Redistributable
|
+ // Try again with jline disabled for Windows users without C++ 2008 Redistributable
|
||||||
+ System.setProperty("jline.terminal", "jline.UnsupportedTerminal");
|
+ System.setProperty(TerminalBuilder.PROP_PROVIDER, Terminal.TYPE_DUMB);
|
||||||
+ System.setProperty("user.language", "en");
|
|
||||||
+ Main.useJline = false;
|
+ Main.useJline = false;
|
||||||
+ reader = new ConsoleReader(System.in, System.out);
|
+ terminal = TerminalBuilder.builder().build();
|
||||||
+ reader.setExpandEvents(false);
|
|
||||||
+ } catch (IOException ex) {
|
+ } catch (IOException ex) {
|
||||||
+ LOGGER.warn((String) null, ex);
|
+ LOGGER.warn((String) null, ex);
|
||||||
+ }
|
+ }
|
||||||
|
@ -113,7 +111,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
private void readScoreboard(WorldPersistentData worldpersistentdata) {
|
private void readScoreboard(WorldPersistentData worldpersistentdata) {
|
||||||
@@ -354,7 +420,7 @@
|
@@ -354,7 +418,7 @@
|
||||||
|
|
||||||
protected abstract boolean initServer() throws IOException;
|
protected abstract boolean initServer() throws IOException;
|
||||||
|
|
||||||
|
@ -122,7 +120,7 @@
|
||||||
if (!JvmProfiler.INSTANCE.isRunning()) {
|
if (!JvmProfiler.INSTANCE.isRunning()) {
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
@@ -362,12 +428,8 @@
|
@@ -362,12 +426,8 @@
|
||||||
boolean flag = false;
|
boolean flag = false;
|
||||||
ProfiledDuration profiledduration = JvmProfiler.INSTANCE.onWorldLoadedStarted();
|
ProfiledDuration profiledduration = JvmProfiler.INSTANCE.onWorldLoadedStarted();
|
||||||
|
|
||||||
|
@ -136,7 +134,7 @@
|
||||||
if (profiledduration != null) {
|
if (profiledduration != null) {
|
||||||
profiledduration.finish(true);
|
profiledduration.finish(true);
|
||||||
}
|
}
|
||||||
@@ -384,23 +446,217 @@
|
@@ -384,23 +444,217 @@
|
||||||
|
|
||||||
protected void forceDifficulty() {}
|
protected void forceDifficulty() {}
|
||||||
|
|
||||||
|
@ -368,7 +366,7 @@
|
||||||
|
|
||||||
if (!iworlddataserver.isInitialized()) {
|
if (!iworlddataserver.isInitialized()) {
|
||||||
try {
|
try {
|
||||||
@@ -424,28 +680,8 @@
|
@@ -424,28 +678,8 @@
|
||||||
iworlddataserver.setInitialized(true);
|
iworlddataserver.setInitialized(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -398,7 +396,7 @@
|
||||||
|
|
||||||
private static void setInitialSpawn(WorldServer worldserver, IWorldDataServer iworlddataserver, boolean flag, boolean flag1) {
|
private static void setInitialSpawn(WorldServer worldserver, IWorldDataServer iworlddataserver, boolean flag, boolean flag1) {
|
||||||
if (flag1) {
|
if (flag1) {
|
||||||
@@ -453,6 +689,21 @@
|
@@ -453,6 +687,21 @@
|
||||||
} else {
|
} else {
|
||||||
ChunkProviderServer chunkproviderserver = worldserver.getChunkSource();
|
ChunkProviderServer chunkproviderserver = worldserver.getChunkSource();
|
||||||
ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(chunkproviderserver.randomState().sampler().findSpawnPosition());
|
ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(chunkproviderserver.randomState().sampler().findSpawnPosition());
|
||||||
|
@ -420,7 +418,7 @@
|
||||||
int i = chunkproviderserver.getGenerator().getSpawnHeight(worldserver);
|
int i = chunkproviderserver.getGenerator().getSpawnHeight(worldserver);
|
||||||
|
|
||||||
if (i < worldserver.getMinY()) {
|
if (i < worldserver.getMinY()) {
|
||||||
@@ -511,8 +762,11 @@
|
@@ -511,8 +760,11 @@
|
||||||
iworlddataserver.setGameType(EnumGamemode.SPECTATOR);
|
iworlddataserver.setGameType(EnumGamemode.SPECTATOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -434,7 +432,7 @@
|
||||||
|
|
||||||
MinecraftServer.LOGGER.info("Preparing start region for dimension {}", worldserver.dimension().location());
|
MinecraftServer.LOGGER.info("Preparing start region for dimension {}", worldserver.dimension().location());
|
||||||
BlockPosition blockposition = worldserver.getSharedSpawnPos();
|
BlockPosition blockposition = worldserver.getSharedSpawnPos();
|
||||||
@@ -522,18 +776,21 @@
|
@@ -522,18 +774,21 @@
|
||||||
|
|
||||||
this.nextTickTimeNanos = SystemUtils.getNanos();
|
this.nextTickTimeNanos = SystemUtils.getNanos();
|
||||||
worldserver.setDefaultSpawnPos(blockposition, worldserver.getSharedSpawnAngle());
|
worldserver.setDefaultSpawnPos(blockposition, worldserver.getSharedSpawnAngle());
|
||||||
|
@ -462,7 +460,7 @@
|
||||||
TicketStorage ticketstorage = (TicketStorage) worldserver1.getDataStorage().get(TicketStorage.TYPE);
|
TicketStorage ticketstorage = (TicketStorage) worldserver1.getDataStorage().get(TicketStorage.TYPE);
|
||||||
|
|
||||||
if (ticketstorage != null) {
|
if (ticketstorage != null) {
|
||||||
@@ -541,10 +798,17 @@
|
@@ -541,10 +796,17 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -483,7 +481,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public EnumGamemode getDefaultGameType() {
|
public EnumGamemode getDefaultGameType() {
|
||||||
@@ -573,12 +837,16 @@
|
@@ -573,12 +835,16 @@
|
||||||
flag3 = true;
|
flag3 = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -500,7 +498,7 @@
|
||||||
if (flag1) {
|
if (flag1) {
|
||||||
for (WorldServer worldserver2 : this.getAllLevels()) {
|
for (WorldServer worldserver2 : this.getAllLevels()) {
|
||||||
MinecraftServer.LOGGER.info("ThreadedAnvilChunkStorage ({}): All chunks are saved", worldserver2.getChunkSource().chunkMap.getStorageName());
|
MinecraftServer.LOGGER.info("ThreadedAnvilChunkStorage ({}): All chunks are saved", worldserver2.getChunkSource().chunkMap.getStorageName());
|
||||||
@@ -609,18 +877,40 @@
|
@@ -609,18 +875,40 @@
|
||||||
this.stopServer();
|
this.stopServer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -541,7 +539,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
MinecraftServer.LOGGER.info("Saving worlds");
|
MinecraftServer.LOGGER.info("Saving worlds");
|
||||||
@@ -700,7 +990,7 @@
|
@@ -700,7 +988,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
this.nextTickTimeNanos = SystemUtils.getNanos();
|
this.nextTickTimeNanos = SystemUtils.getNanos();
|
||||||
|
@ -550,7 +548,7 @@
|
||||||
this.status = this.buildServerStatus();
|
this.status = this.buildServerStatus();
|
||||||
|
|
||||||
while (this.running) {
|
while (this.running) {
|
||||||
@@ -717,6 +1007,7 @@
|
@@ -717,6 +1005,7 @@
|
||||||
if (j > MinecraftServer.OVERLOADED_THRESHOLD_NANOS + 20L * i && this.nextTickTimeNanos - this.lastOverloadWarningNanos >= MinecraftServer.OVERLOADED_WARNING_INTERVAL_NANOS + 100L * i) {
|
if (j > MinecraftServer.OVERLOADED_THRESHOLD_NANOS + 20L * i && this.nextTickTimeNanos - this.lastOverloadWarningNanos >= MinecraftServer.OVERLOADED_WARNING_INTERVAL_NANOS + 100L * i) {
|
||||||
long k = j / i;
|
long k = j / i;
|
||||||
|
|
||||||
|
@ -558,7 +556,7 @@
|
||||||
MinecraftServer.LOGGER.warn("Can't keep up! Is the server overloaded? Running {}ms or {} ticks behind", j / TimeRange.NANOSECONDS_PER_MILLISECOND, k);
|
MinecraftServer.LOGGER.warn("Can't keep up! Is the server overloaded? Running {}ms or {} ticks behind", j / TimeRange.NANOSECONDS_PER_MILLISECOND, k);
|
||||||
this.nextTickTimeNanos += k * i;
|
this.nextTickTimeNanos += k * i;
|
||||||
this.lastOverloadWarningNanos = this.nextTickTimeNanos;
|
this.lastOverloadWarningNanos = this.nextTickTimeNanos;
|
||||||
@@ -730,6 +1021,7 @@
|
@@ -730,6 +1019,7 @@
|
||||||
this.debugCommandProfiler = new MinecraftServer.TimeProfiler(SystemUtils.getNanos(), this.tickCount);
|
this.debugCommandProfiler = new MinecraftServer.TimeProfiler(SystemUtils.getNanos(), this.tickCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -566,20 +564,20 @@
|
||||||
this.nextTickTimeNanos += i;
|
this.nextTickTimeNanos += i;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -803,6 +1095,12 @@
|
@@ -803,6 +1093,12 @@
|
||||||
this.services.profileCache().clearExecutor();
|
this.services.profileCache().clearExecutor();
|
||||||
}
|
}
|
||||||
|
|
||||||
+ // CraftBukkit start - Restore terminal to original settings
|
+ // CraftBukkit start - Restore terminal to original settings
|
||||||
+ try {
|
+ try {
|
||||||
+ reader.getTerminal().restore();
|
+ terminal.close();
|
||||||
+ } catch (Exception ignored) {
|
+ } catch (Exception ignored) {
|
||||||
+ }
|
+ }
|
||||||
+ // CraftBukkit end
|
+ // CraftBukkit end
|
||||||
this.onServerExit();
|
this.onServerExit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -862,7 +1160,14 @@
|
@@ -862,7 +1158,14 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean haveTime() {
|
private boolean haveTime() {
|
||||||
|
@ -595,7 +593,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean throwIfFatalException() {
|
public static boolean throwIfFatalException() {
|
||||||
@@ -876,7 +1181,7 @@
|
@@ -876,7 +1179,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setFatalException(RuntimeException runtimeexception) {
|
public static void setFatalException(RuntimeException runtimeexception) {
|
||||||
|
@ -604,7 +602,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -946,7 +1251,7 @@
|
@@ -946,7 +1249,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -613,7 +611,7 @@
|
||||||
Profiler.get().incrementCounter("runTask");
|
Profiler.get().incrementCounter("runTask");
|
||||||
super.doRunTask(ticktask);
|
super.doRunTask(ticktask);
|
||||||
}
|
}
|
||||||
@@ -1010,6 +1315,7 @@
|
@@ -1010,6 +1313,7 @@
|
||||||
this.autoSave();
|
this.autoSave();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -621,7 +619,7 @@
|
||||||
this.tickConnection();
|
this.tickConnection();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1024,7 +1330,7 @@
|
@@ -1024,7 +1328,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
--this.ticksUntilAutosave;
|
--this.ticksUntilAutosave;
|
||||||
|
@ -630,7 +628,7 @@
|
||||||
this.autoSave();
|
this.autoSave();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1043,7 +1349,7 @@
|
@@ -1043,7 +1347,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
private void autoSave() {
|
private void autoSave() {
|
||||||
|
@ -639,7 +637,7 @@
|
||||||
MinecraftServer.LOGGER.debug("Autosave started");
|
MinecraftServer.LOGGER.debug("Autosave started");
|
||||||
GameProfilerFiller gameprofilerfiller = Profiler.get();
|
GameProfilerFiller gameprofilerfiller = Profiler.get();
|
||||||
|
|
||||||
@@ -1123,21 +1429,38 @@
|
@@ -1123,21 +1427,38 @@
|
||||||
this.getPlayerList().getPlayers().forEach((entityplayer) -> {
|
this.getPlayerList().getPlayers().forEach((entityplayer) -> {
|
||||||
entityplayer.connection.suspendFlushing();
|
entityplayer.connection.suspendFlushing();
|
||||||
});
|
});
|
||||||
|
@ -678,7 +676,7 @@
|
||||||
|
|
||||||
gameprofilerfiller.push("tick");
|
gameprofilerfiller.push("tick");
|
||||||
|
|
||||||
@@ -1227,6 +1550,22 @@
|
@@ -1227,6 +1548,22 @@
|
||||||
return (WorldServer) this.levels.get(resourcekey);
|
return (WorldServer) this.levels.get(resourcekey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -701,7 +699,7 @@
|
||||||
public Set<ResourceKey<World>> levelKeys() {
|
public Set<ResourceKey<World>> levelKeys() {
|
||||||
return this.levels.keySet();
|
return this.levels.keySet();
|
||||||
}
|
}
|
||||||
@@ -1256,7 +1595,7 @@
|
@@ -1256,7 +1593,7 @@
|
||||||
|
|
||||||
@DontObfuscate
|
@DontObfuscate
|
||||||
public String getServerModName() {
|
public String getServerModName() {
|
||||||
|
@ -710,7 +708,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public SystemReport fillSystemReport(SystemReport systemreport) {
|
public SystemReport fillSystemReport(SystemReport systemreport) {
|
||||||
@@ -1590,11 +1929,11 @@
|
@@ -1590,11 +1927,11 @@
|
||||||
|
|
||||||
public CompletableFuture<Void> reloadResources(Collection<String> collection) {
|
public CompletableFuture<Void> reloadResources(Collection<String> collection) {
|
||||||
CompletableFuture<Void> completablefuture = CompletableFuture.supplyAsync(() -> {
|
CompletableFuture<Void> completablefuture = CompletableFuture.supplyAsync(() -> {
|
||||||
|
@ -724,7 +722,7 @@
|
||||||
}, this).thenCompose((immutablelist) -> {
|
}, this).thenCompose((immutablelist) -> {
|
||||||
IReloadableResourceManager ireloadableresourcemanager = new ResourceManager(EnumResourcePackType.SERVER_DATA, immutablelist);
|
IReloadableResourceManager ireloadableresourcemanager = new ResourceManager(EnumResourcePackType.SERVER_DATA, immutablelist);
|
||||||
List<IRegistry.a<?>> list = TagDataPack.loadTagsForExistingRegistries(ireloadableresourcemanager, this.registries.compositeAccess());
|
List<IRegistry.a<?>> list = TagDataPack.loadTagsForExistingRegistries(ireloadableresourcemanager, this.registries.compositeAccess());
|
||||||
@@ -1610,6 +1949,7 @@
|
@@ -1610,6 +1947,7 @@
|
||||||
}).thenAcceptAsync((minecraftserver_reloadableresources) -> {
|
}).thenAcceptAsync((minecraftserver_reloadableresources) -> {
|
||||||
this.resources.close();
|
this.resources.close();
|
||||||
this.resources = minecraftserver_reloadableresources;
|
this.resources = minecraftserver_reloadableresources;
|
||||||
|
@ -732,7 +730,7 @@
|
||||||
this.packRepository.setSelected(collection);
|
this.packRepository.setSelected(collection);
|
||||||
WorldDataConfiguration worlddataconfiguration = new WorldDataConfiguration(getSelectedPacks(this.packRepository, true), this.worldData.enabledFeatures());
|
WorldDataConfiguration worlddataconfiguration = new WorldDataConfiguration(getSelectedPacks(this.packRepository, true), this.worldData.enabledFeatures());
|
||||||
|
|
||||||
@@ -1939,6 +2279,22 @@
|
@@ -1939,6 +2277,22 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -755,7 +753,7 @@
|
||||||
private GameProfilerFiller createProfiler() {
|
private GameProfilerFiller createProfiler() {
|
||||||
if (this.willStartRecordingMetrics) {
|
if (this.willStartRecordingMetrics) {
|
||||||
this.metricsRecorder = ActiveMetricsRecorder.createStarted(new ServerMetricsSamplersProvider(SystemUtils.timeSource, this.isDedicatedServer()), SystemUtils.timeSource, SystemUtils.ioPool(), new MetricsPersister("server"), this.onMetricsRecordingStopped, (path) -> {
|
this.metricsRecorder = ActiveMetricsRecorder.createStarted(new ServerMetricsSamplersProvider(SystemUtils.timeSource, this.isDedicatedServer()), SystemUtils.timeSource, SystemUtils.ioPool(), new MetricsPersister("server"), this.onMetricsRecordingStopped, (path) -> {
|
||||||
@@ -2066,6 +2422,11 @@
|
@@ -2066,6 +2420,11 @@
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -767,7 +765,7 @@
|
||||||
public ChatDecorator getChatDecorator() {
|
public ChatDecorator getChatDecorator() {
|
||||||
return ChatDecorator.PLAIN;
|
return ChatDecorator.PLAIN;
|
||||||
}
|
}
|
||||||
@@ -2076,8 +2437,11 @@
|
@@ -2076,8 +2435,11 @@
|
||||||
|
|
||||||
public void subscribeToDebugSample(EntityPlayer entityplayer, RemoteDebugSampleType remotedebugsampletype) {}
|
public void subscribeToDebugSample(EntityPlayer entityplayer, RemoteDebugSampleType remotedebugsampletype) {}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
--- a/net/minecraft/server/dedicated/DedicatedServer.java
|
--- a/net/minecraft/server/dedicated/DedicatedServer.java
|
||||||
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
|
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
|
||||||
@@ -59,6 +59,18 @@
|
@@ -59,6 +59,21 @@
|
||||||
import net.minecraft.world.level.storage.Convertable;
|
import net.minecraft.world.level.storage.Convertable;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
|
@ -10,16 +10,19 @@
|
||||||
+import org.apache.logging.log4j.LogManager;
|
+import org.apache.logging.log4j.LogManager;
|
||||||
+import org.apache.logging.log4j.io.IoBuilder;
|
+import org.apache.logging.log4j.io.IoBuilder;
|
||||||
+import org.bukkit.command.CommandSender;
|
+import org.bukkit.command.CommandSender;
|
||||||
+import org.bukkit.craftbukkit.util.TerminalCompletionHandler;
|
|
||||||
+import org.bukkit.craftbukkit.util.TerminalConsoleWriterThread;
|
+import org.bukkit.craftbukkit.util.TerminalConsoleWriterThread;
|
||||||
+import org.bukkit.event.server.ServerCommandEvent;
|
+import org.bukkit.event.server.ServerCommandEvent;
|
||||||
+import org.bukkit.event.server.RemoteServerCommandEvent;
|
+import org.bukkit.event.server.RemoteServerCommandEvent;
|
||||||
|
+import org.jline.reader.EndOfFileException;
|
||||||
|
+import org.jline.reader.LineReader;
|
||||||
|
+import org.jline.reader.LineReaderBuilder;
|
||||||
|
+import org.jline.reader.UserInterruptException;
|
||||||
+// CraftBukkit end
|
+// CraftBukkit end
|
||||||
+
|
+
|
||||||
public class DedicatedServer extends MinecraftServer implements IMinecraftServer {
|
public class DedicatedServer extends MinecraftServer implements IMinecraftServer {
|
||||||
|
|
||||||
static final Logger LOGGER = LogUtils.getLogger();
|
static final Logger LOGGER = LogUtils.getLogger();
|
||||||
@@ -67,7 +79,7 @@
|
@@ -67,7 +82,7 @@
|
||||||
private final List<ServerCommand> consoleInput = Collections.synchronizedList(Lists.newArrayList());
|
private final List<ServerCommand> consoleInput = Collections.synchronizedList(Lists.newArrayList());
|
||||||
@Nullable
|
@Nullable
|
||||||
private RemoteStatusListener queryThreadGs4;
|
private RemoteStatusListener queryThreadGs4;
|
||||||
|
@ -28,7 +31,7 @@
|
||||||
@Nullable
|
@Nullable
|
||||||
private RemoteControlListener rconThread;
|
private RemoteControlListener rconThread;
|
||||||
public DedicatedServerSettings settings;
|
public DedicatedServerSettings settings;
|
||||||
@@ -81,10 +93,12 @@
|
@@ -81,33 +96,93 @@
|
||||||
private DebugSampleSubscriptionTracker debugSampleSubscriptionTracker;
|
private DebugSampleSubscriptionTracker debugSampleSubscriptionTracker;
|
||||||
public ServerLinks serverLinks;
|
public ServerLinks serverLinks;
|
||||||
|
|
||||||
|
@ -44,8 +47,15 @@
|
||||||
this.serverTextFilter = ServerTextFilter.createFromConfig(dedicatedserversettings.getProperties());
|
this.serverTextFilter = ServerTextFilter.createFromConfig(dedicatedserversettings.getProperties());
|
||||||
this.serverLinks = createServerLinks(dedicatedserversettings);
|
this.serverLinks = createServerLinks(dedicatedserversettings);
|
||||||
}
|
}
|
||||||
@@ -93,13 +107,44 @@
|
|
||||||
|
@Override
|
||||||
public boolean initServer() throws IOException {
|
public boolean initServer() throws IOException {
|
||||||
|
+ LineReader reader = LineReaderBuilder.builder()
|
||||||
|
+ .terminal(terminal)
|
||||||
|
+ .option(LineReader.Option.DISABLE_EVENT_EXPANSION, true)
|
||||||
|
+ .completer(new org.bukkit.craftbukkit.command.ConsoleCommandCompleter())
|
||||||
|
+ .build();
|
||||||
|
+
|
||||||
Thread thread = new Thread("Server console handler") {
|
Thread thread = new Thread("Server console handler") {
|
||||||
public void run() {
|
public void run() {
|
||||||
- BufferedReader bufferedreader = new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8));
|
- BufferedReader bufferedreader = new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8));
|
||||||
|
@ -53,7 +63,6 @@
|
||||||
+ if (!org.bukkit.craftbukkit.Main.useConsole) {
|
+ if (!org.bukkit.craftbukkit.Main.useConsole) {
|
||||||
+ return;
|
+ return;
|
||||||
+ }
|
+ }
|
||||||
+ jline.console.ConsoleReader bufferedreader = reader;
|
|
||||||
+
|
+
|
||||||
+ // MC-33041, SPIGOT-5538: if System.in is not valid due to javaw, then return
|
+ // MC-33041, SPIGOT-5538: if System.in is not valid due to javaw, then return
|
||||||
+ try {
|
+ try {
|
||||||
|
@ -70,29 +79,31 @@
|
||||||
- DedicatedServer.this.handleConsoleInput(s, DedicatedServer.this.createCommandSourceStack());
|
- DedicatedServer.this.handleConsoleInput(s, DedicatedServer.this.createCommandSourceStack());
|
||||||
+ // CraftBukkit start - JLine disabling compatibility
|
+ // CraftBukkit start - JLine disabling compatibility
|
||||||
+ while (!DedicatedServer.this.isStopped() && DedicatedServer.this.isRunning()) {
|
+ while (!DedicatedServer.this.isStopped() && DedicatedServer.this.isRunning()) {
|
||||||
+ if (org.bukkit.craftbukkit.Main.useJline) {
|
+ try {
|
||||||
+ s = bufferedreader.readLine(">", null);
|
+ if (org.bukkit.craftbukkit.Main.useJline) {
|
||||||
+ } else {
|
+ s = reader.readLine(">", null);
|
||||||
+ s = bufferedreader.readLine();
|
+ } else {
|
||||||
+ }
|
+ s = reader.readLine();
|
||||||
|
+ }
|
||||||
+
|
+
|
||||||
+ // SPIGOT-5220: Throttle if EOF (ctrl^d) or stdin is /dev/null
|
+ if (s.trim().length() > 0) { // Trim to filter lines which are just spaces
|
||||||
+ if (s == null) {
|
+ DedicatedServer.this.handleConsoleInput(s, DedicatedServer.this.createCommandSourceStack());
|
||||||
|
+ }
|
||||||
|
+ } catch (EndOfFileException | UserInterruptException eof) {
|
||||||
|
+ // SPIGOT-5220: Throttle if EOF (ctrl^d) or stdin is /dev/null
|
||||||
+ try {
|
+ try {
|
||||||
+ Thread.sleep(50L);
|
+ Thread.sleep(50L);
|
||||||
+ } catch (InterruptedException ex) {
|
+ } catch (InterruptedException ex) {
|
||||||
+ Thread.currentThread().interrupt();
|
+ Thread.currentThread().interrupt();
|
||||||
+ }
|
+ }
|
||||||
+ continue;
|
|
||||||
+ }
|
+ }
|
||||||
+ if (s.trim().length() > 0) { // Trim to filter lines which are just spaces
|
|
||||||
+ DedicatedServer.this.handleConsoleInput(s, DedicatedServer.this.createCommandSourceStack());
|
|
||||||
+ }
|
|
||||||
+ // CraftBukkit end
|
|
||||||
}
|
}
|
||||||
} catch (IOException ioexception) {
|
- } catch (IOException ioexception) {
|
||||||
|
+ } catch (Throwable ioexception) {
|
||||||
|
+ // CraftBukkit end
|
||||||
DedicatedServer.LOGGER.error("Exception handling console input", ioexception);
|
DedicatedServer.LOGGER.error("Exception handling console input", ioexception);
|
||||||
@@ -108,6 +153,29 @@
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -111,8 +122,7 @@
|
||||||
+ }
|
+ }
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ TerminalConsoleWriterThread writerThread = new TerminalConsoleWriterThread(System.out, this.reader);
|
+ TerminalConsoleWriterThread writerThread = new TerminalConsoleWriterThread(System.out, reader);
|
||||||
+ this.reader.setCompletionHandler(new TerminalCompletionHandler(writerThread, this.reader.getCompletionHandler()));
|
|
||||||
+ writerThread.start();
|
+ writerThread.start();
|
||||||
+
|
+
|
||||||
+ System.setOut(IoBuilder.forLogger(logger).setLevel(Level.INFO).buildPrintStream());
|
+ System.setOut(IoBuilder.forLogger(logger).setLevel(Level.INFO).buildPrintStream());
|
||||||
|
@ -122,7 +132,7 @@
|
||||||
thread.setDaemon(true);
|
thread.setDaemon(true);
|
||||||
thread.setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler(DedicatedServer.LOGGER));
|
thread.setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler(DedicatedServer.LOGGER));
|
||||||
thread.start();
|
thread.start();
|
||||||
@@ -132,7 +200,7 @@
|
@@ -132,7 +207,7 @@
|
||||||
this.setMotd(dedicatedserverproperties.motd);
|
this.setMotd(dedicatedserverproperties.motd);
|
||||||
super.setPlayerIdleTimeout((Integer) dedicatedserverproperties.playerIdleTimeout.get());
|
super.setPlayerIdleTimeout((Integer) dedicatedserverproperties.playerIdleTimeout.get());
|
||||||
this.setEnforceWhitelist(dedicatedserverproperties.enforceWhitelist);
|
this.setEnforceWhitelist(dedicatedserverproperties.enforceWhitelist);
|
||||||
|
@ -131,7 +141,7 @@
|
||||||
DedicatedServer.LOGGER.info("Default game type: {}", dedicatedserverproperties.gamemode);
|
DedicatedServer.LOGGER.info("Default game type: {}", dedicatedserverproperties.gamemode);
|
||||||
InetAddress inetaddress = null;
|
InetAddress inetaddress = null;
|
||||||
|
|
||||||
@@ -156,6 +224,12 @@
|
@@ -156,6 +231,12 @@
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,7 +154,7 @@
|
||||||
if (!this.usesAuthentication()) {
|
if (!this.usesAuthentication()) {
|
||||||
DedicatedServer.LOGGER.warn("**** SERVER IS RUNNING IN OFFLINE/INSECURE MODE!");
|
DedicatedServer.LOGGER.warn("**** SERVER IS RUNNING IN OFFLINE/INSECURE MODE!");
|
||||||
DedicatedServer.LOGGER.warn("The server will make no attempt to authenticate usernames. Beware.");
|
DedicatedServer.LOGGER.warn("The server will make no attempt to authenticate usernames. Beware.");
|
||||||
@@ -170,7 +244,7 @@
|
@@ -170,7 +251,7 @@
|
||||||
if (!NameReferencingFileConverter.serverReadyAfterUserconversion(this)) {
|
if (!NameReferencingFileConverter.serverReadyAfterUserconversion(this)) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
|
@ -153,7 +163,7 @@
|
||||||
this.debugSampleSubscriptionTracker = new DebugSampleSubscriptionTracker(this.getPlayerList());
|
this.debugSampleSubscriptionTracker = new DebugSampleSubscriptionTracker(this.getPlayerList());
|
||||||
this.tickTimeLogger = new RemoteSampleLogger(TpsDebugDimensions.values().length, this.debugSampleSubscriptionTracker, RemoteDebugSampleType.TICK_TIME);
|
this.tickTimeLogger = new RemoteSampleLogger(TpsDebugDimensions.values().length, this.debugSampleSubscriptionTracker, RemoteDebugSampleType.TICK_TIME);
|
||||||
long i = SystemUtils.getNanos();
|
long i = SystemUtils.getNanos();
|
||||||
@@ -178,13 +252,13 @@
|
@@ -178,13 +259,13 @@
|
||||||
TileEntitySkull.setup(this.services, this);
|
TileEntitySkull.setup(this.services, this);
|
||||||
UserCache.setUsesAuthentication(this.usesAuthentication());
|
UserCache.setUsesAuthentication(this.usesAuthentication());
|
||||||
DedicatedServer.LOGGER.info("Preparing level \"{}\"", this.getLevelIdName());
|
DedicatedServer.LOGGER.info("Preparing level \"{}\"", this.getLevelIdName());
|
||||||
|
@ -169,7 +179,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dedicatedserverproperties.enableQuery) {
|
if (dedicatedserverproperties.enableQuery) {
|
||||||
@@ -278,6 +352,7 @@
|
@@ -278,6 +359,7 @@
|
||||||
this.queryThreadGs4.stop();
|
this.queryThreadGs4.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,7 +187,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -299,7 +374,15 @@
|
@@ -299,7 +381,15 @@
|
||||||
while (!this.consoleInput.isEmpty()) {
|
while (!this.consoleInput.isEmpty()) {
|
||||||
ServerCommand servercommand = (ServerCommand) this.consoleInput.remove(0);
|
ServerCommand servercommand = (ServerCommand) this.consoleInput.remove(0);
|
||||||
|
|
||||||
|
@ -194,7 +204,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -524,16 +607,52 @@
|
@@ -524,16 +614,52 @@
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getPluginNames() {
|
public String getPluginNames() {
|
||||||
|
@ -251,7 +261,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public void storeUsingWhiteList(boolean flag) {
|
public void storeUsingWhiteList(boolean flag) {
|
||||||
@@ -643,4 +762,15 @@
|
@@ -643,4 +769,15 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
public final WorldNBTStorage playerIo;
|
public final WorldNBTStorage playerIo;
|
||||||
private boolean doWhiteList;
|
private boolean doWhiteList;
|
||||||
private final LayeredRegistryAccess<RegistryLayer> registries;
|
private final LayeredRegistryAccess<RegistryLayer> registries;
|
||||||
@@ -131,13 +155,23 @@
|
@@ -131,13 +155,22 @@
|
||||||
private static final boolean ALLOW_LOGOUTIVATOR = false;
|
private static final boolean ALLOW_LOGOUTIVATOR = false;
|
||||||
private int sendAllPlayerInfoIn;
|
private int sendAllPlayerInfoIn;
|
||||||
|
|
||||||
|
@ -59,7 +59,6 @@
|
||||||
public PlayerList(MinecraftServer minecraftserver, LayeredRegistryAccess<RegistryLayer> layeredregistryaccess, WorldNBTStorage worldnbtstorage, int i) {
|
public PlayerList(MinecraftServer minecraftserver, LayeredRegistryAccess<RegistryLayer> layeredregistryaccess, WorldNBTStorage worldnbtstorage, int i) {
|
||||||
+ this.cserver = minecraftserver.server = new CraftServer((DedicatedServer) minecraftserver, this);
|
+ this.cserver = minecraftserver.server = new CraftServer((DedicatedServer) minecraftserver, this);
|
||||||
+ minecraftserver.console = org.bukkit.craftbukkit.command.ColouredConsoleSender.getInstance();
|
+ minecraftserver.console = org.bukkit.craftbukkit.command.ColouredConsoleSender.getInstance();
|
||||||
+ minecraftserver.reader.addCompleter(new org.bukkit.craftbukkit.command.ConsoleCommandCompleter(minecraftserver.server));
|
|
||||||
+ // CraftBukkit end
|
+ // CraftBukkit end
|
||||||
+
|
+
|
||||||
this.bans = new GameProfileBanList(PlayerList.USERBANLIST_FILE);
|
this.bans = new GameProfileBanList(PlayerList.USERBANLIST_FILE);
|
||||||
|
@ -75,7 +74,7 @@
|
||||||
this.server = minecraftserver;
|
this.server = minecraftserver;
|
||||||
this.registries = layeredregistryaccess;
|
this.registries = layeredregistryaccess;
|
||||||
this.maxPlayers = i;
|
this.maxPlayers = i;
|
||||||
@@ -160,9 +194,16 @@
|
@@ -160,9 +193,16 @@
|
||||||
|
|
||||||
try (ProblemReporter.j problemreporter_j = new ProblemReporter.j(entityplayer.problemPath(), PlayerList.LOGGER)) {
|
try (ProblemReporter.j problemreporter_j = new ProblemReporter.j(entityplayer.problemPath(), PlayerList.LOGGER)) {
|
||||||
Optional<ValueInput> optional1 = this.load(entityplayer, problemreporter_j);
|
Optional<ValueInput> optional1 = this.load(entityplayer, problemreporter_j);
|
||||||
|
@ -93,7 +92,7 @@
|
||||||
WorldServer worldserver = this.server.getLevel(resourcekey);
|
WorldServer worldserver = this.server.getLevel(resourcekey);
|
||||||
WorldServer worldserver1;
|
WorldServer worldserver1;
|
||||||
|
|
||||||
@@ -181,10 +222,11 @@
|
@@ -181,10 +221,11 @@
|
||||||
worldserver1.waitForChunkAndEntities(entityplayer.chunkPosition(), 1);
|
worldserver1.waitForChunkAndEntities(entityplayer.chunkPosition(), 1);
|
||||||
String s1 = networkmanager.getLoggableAddress(this.server.logIPs());
|
String s1 = networkmanager.getLoggableAddress(this.server.logIPs());
|
||||||
|
|
||||||
|
@ -107,7 +106,7 @@
|
||||||
PlayerConnection playerconnection = new PlayerConnection(this.server, networkmanager, entityplayer, commonlistenercookie);
|
PlayerConnection playerconnection = new PlayerConnection(this.server, networkmanager, entityplayer, commonlistenercookie);
|
||||||
|
|
||||||
networkmanager.setupInboundProtocol(GameProtocols.SERVERBOUND_TEMPLATE.bind(RegistryFriendlyByteBuf.decorator(this.server.registryAccess()), playerconnection), playerconnection);
|
networkmanager.setupInboundProtocol(GameProtocols.SERVERBOUND_TEMPLATE.bind(RegistryFriendlyByteBuf.decorator(this.server.registryAccess()), playerconnection), playerconnection);
|
||||||
@@ -194,6 +236,7 @@
|
@@ -194,6 +235,7 @@
|
||||||
boolean flag2 = gamerules.getBoolean(GameRules.RULE_LIMITED_CRAFTING);
|
boolean flag2 = gamerules.getBoolean(GameRules.RULE_LIMITED_CRAFTING);
|
||||||
|
|
||||||
playerconnection.send(new PacketPlayOutLogin(entityplayer.getId(), worlddata.isHardcore(), this.server.levelKeys(), this.getMaxPlayers(), this.viewDistance, this.simulationDistance, flag1, !flag, flag2, entityplayer.createCommonSpawnInfo(worldserver1), this.server.enforceSecureProfile()));
|
playerconnection.send(new PacketPlayOutLogin(entityplayer.getId(), worlddata.isHardcore(), this.server.levelKeys(), this.getMaxPlayers(), this.viewDistance, this.simulationDistance, flag1, !flag, flag2, entityplayer.createCommonSpawnInfo(worldserver1), this.server.enforceSecureProfile()));
|
||||||
|
@ -115,7 +114,7 @@
|
||||||
playerconnection.send(new PacketPlayOutServerDifficulty(worlddata.getDifficulty(), worlddata.isDifficultyLocked()));
|
playerconnection.send(new PacketPlayOutServerDifficulty(worlddata.getDifficulty(), worlddata.isDifficultyLocked()));
|
||||||
playerconnection.send(new PacketPlayOutAbilities(entityplayer.getAbilities()));
|
playerconnection.send(new PacketPlayOutAbilities(entityplayer.getAbilities()));
|
||||||
playerconnection.send(new PacketPlayOutHeldItemSlot(entityplayer.getInventory().getSelectedSlot()));
|
playerconnection.send(new PacketPlayOutHeldItemSlot(entityplayer.getInventory().getSelectedSlot()));
|
||||||
@@ -212,8 +255,10 @@
|
@@ -212,8 +254,10 @@
|
||||||
} else {
|
} else {
|
||||||
ichatmutablecomponent = IChatBaseComponent.translatable("multiplayer.player.joined.renamed", entityplayer.getDisplayName(), s);
|
ichatmutablecomponent = IChatBaseComponent.translatable("multiplayer.player.joined.renamed", entityplayer.getDisplayName(), s);
|
||||||
}
|
}
|
||||||
|
@ -127,7 +126,7 @@
|
||||||
playerconnection.teleport(entityplayer.getX(), entityplayer.getY(), entityplayer.getZ(), entityplayer.getYRot(), entityplayer.getXRot());
|
playerconnection.teleport(entityplayer.getX(), entityplayer.getY(), entityplayer.getZ(), entityplayer.getYRot(), entityplayer.getXRot());
|
||||||
ServerPing serverping = this.server.getStatus();
|
ServerPing serverping = this.server.getStatus();
|
||||||
|
|
||||||
@@ -221,19 +266,72 @@
|
@@ -221,19 +265,72 @@
|
||||||
entityplayer.sendServerStatus(serverping);
|
entityplayer.sendServerStatus(serverping);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,7 +203,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -260,30 +358,31 @@
|
@@ -260,30 +357,31 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addWorldborderListener(WorldServer worldserver) {
|
public void addWorldborderListener(WorldServer worldserver) {
|
||||||
|
@ -241,7 +240,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -312,14 +411,15 @@
|
@@ -312,14 +410,15 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void save(EntityPlayer entityplayer) {
|
protected void save(EntityPlayer entityplayer) {
|
||||||
|
@ -259,7 +258,7 @@
|
||||||
|
|
||||||
if (advancementdataplayer != null) {
|
if (advancementdataplayer != null) {
|
||||||
advancementdataplayer.save();
|
advancementdataplayer.save();
|
||||||
@@ -327,10 +427,24 @@
|
@@ -327,10 +426,24 @@
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,7 +284,7 @@
|
||||||
this.save(entityplayer);
|
this.save(entityplayer);
|
||||||
if (entityplayer.isPassenger()) {
|
if (entityplayer.isPassenger()) {
|
||||||
Entity entity = entityplayer.getRootVehicle();
|
Entity entity = entityplayer.getRootVehicle();
|
||||||
@@ -339,7 +453,7 @@
|
@@ -339,7 +452,7 @@
|
||||||
PlayerList.LOGGER.debug("Removing player mount");
|
PlayerList.LOGGER.debug("Removing player mount");
|
||||||
entityplayer.stopRiding();
|
entityplayer.stopRiding();
|
||||||
entity.getPassengersAndSelf().forEach((entity1) -> {
|
entity.getPassengersAndSelf().forEach((entity1) -> {
|
||||||
|
@ -294,7 +293,7 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -347,7 +461,7 @@
|
@@ -347,7 +460,7 @@
|
||||||
entityplayer.unRide();
|
entityplayer.unRide();
|
||||||
|
|
||||||
for (EntityEnderPearl entityenderpearl : entityplayer.getEnderPearls()) {
|
for (EntityEnderPearl entityenderpearl : entityplayer.getEnderPearls()) {
|
||||||
|
@ -303,7 +302,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
worldserver.removePlayerImmediately(entityplayer, Entity.RemovalReason.UNLOADED_WITH_PLAYER);
|
worldserver.removePlayerImmediately(entityplayer, Entity.RemovalReason.UNLOADED_WITH_PLAYER);
|
||||||
@@ -359,15 +473,58 @@
|
@@ -359,15 +472,58 @@
|
||||||
|
|
||||||
if (entityplayer1 == entityplayer) {
|
if (entityplayer1 == entityplayer) {
|
||||||
this.playersByUUID.remove(uuid);
|
this.playersByUUID.remove(uuid);
|
||||||
|
@ -367,7 +366,7 @@
|
||||||
if (this.bans.isBanned(gameprofile)) {
|
if (this.bans.isBanned(gameprofile)) {
|
||||||
GameProfileBanEntry gameprofilebanentry = (GameProfileBanEntry) this.bans.get(gameprofile);
|
GameProfileBanEntry gameprofilebanentry = (GameProfileBanEntry) this.bans.get(gameprofile);
|
||||||
IChatMutableComponent ichatmutablecomponent = IChatBaseComponent.translatable("multiplayer.disconnect.banned.reason", gameprofilebanentry.getReason());
|
IChatMutableComponent ichatmutablecomponent = IChatBaseComponent.translatable("multiplayer.disconnect.banned.reason", gameprofilebanentry.getReason());
|
||||||
@@ -376,9 +533,11 @@
|
@@ -376,9 +532,11 @@
|
||||||
ichatmutablecomponent.append((IChatBaseComponent) IChatBaseComponent.translatable("multiplayer.disconnect.banned.expiration", PlayerList.BAN_DATE_FORMAT.format(gameprofilebanentry.getExpires())));
|
ichatmutablecomponent.append((IChatBaseComponent) IChatBaseComponent.translatable("multiplayer.disconnect.banned.expiration", PlayerList.BAN_DATE_FORMAT.format(gameprofilebanentry.getExpires())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -381,7 +380,7 @@
|
||||||
} else if (this.ipBans.isBanned(socketaddress)) {
|
} else if (this.ipBans.isBanned(socketaddress)) {
|
||||||
IpBanEntry ipbanentry = this.ipBans.get(socketaddress);
|
IpBanEntry ipbanentry = this.ipBans.get(socketaddress);
|
||||||
IChatMutableComponent ichatmutablecomponent1 = IChatBaseComponent.translatable("multiplayer.disconnect.banned_ip.reason", ipbanentry.getReason());
|
IChatMutableComponent ichatmutablecomponent1 = IChatBaseComponent.translatable("multiplayer.disconnect.banned_ip.reason", ipbanentry.getReason());
|
||||||
@@ -387,13 +546,25 @@
|
@@ -387,13 +545,25 @@
|
||||||
ichatmutablecomponent1.append((IChatBaseComponent) IChatBaseComponent.translatable("multiplayer.disconnect.banned_ip.expiration", PlayerList.BAN_DATE_FORMAT.format(ipbanentry.getExpires())));
|
ichatmutablecomponent1.append((IChatBaseComponent) IChatBaseComponent.translatable("multiplayer.disconnect.banned_ip.expiration", PlayerList.BAN_DATE_FORMAT.format(ipbanentry.getExpires())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -410,7 +409,7 @@
|
||||||
UUID uuid = gameprofile.getId();
|
UUID uuid = gameprofile.getId();
|
||||||
Set<EntityPlayer> set = Sets.newIdentityHashSet();
|
Set<EntityPlayer> set = Sets.newIdentityHashSet();
|
||||||
|
|
||||||
@@ -414,32 +585,66 @@
|
@@ -414,32 +584,66 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
return !set.isEmpty();
|
return !set.isEmpty();
|
||||||
|
@ -479,7 +478,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
byte b0 = (byte) (flag ? 1 : 0);
|
byte b0 = (byte) (flag ? 1 : 0);
|
||||||
@@ -447,17 +652,19 @@
|
@@ -447,17 +651,19 @@
|
||||||
WorldData worlddata = worldserver1.getLevelData();
|
WorldData worlddata = worldserver1.getLevelData();
|
||||||
|
|
||||||
entityplayer1.connection.send(new PacketPlayOutRespawn(entityplayer1.createCommonSpawnInfo(worldserver1), b0));
|
entityplayer1.connection.send(new PacketPlayOutRespawn(entityplayer1.createCommonSpawnInfo(worldserver1), b0));
|
||||||
|
@ -504,7 +503,7 @@
|
||||||
entityplayer1.setHealth(entityplayer1.getHealth());
|
entityplayer1.setHealth(entityplayer1.getHealth());
|
||||||
EntityPlayer.RespawnConfig entityplayer_respawnconfig = entityplayer1.getRespawnConfig();
|
EntityPlayer.RespawnConfig entityplayer_respawnconfig = entityplayer1.getRespawnConfig();
|
||||||
|
|
||||||
@@ -473,6 +680,27 @@
|
@@ -473,6 +679,27 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -532,7 +531,7 @@
|
||||||
|
|
||||||
return entityplayer1;
|
return entityplayer1;
|
||||||
}
|
}
|
||||||
@@ -497,7 +725,18 @@
|
@@ -497,7 +724,18 @@
|
||||||
|
|
||||||
public void tick() {
|
public void tick() {
|
||||||
if (++this.sendAllPlayerInfoIn > 600) {
|
if (++this.sendAllPlayerInfoIn > 600) {
|
||||||
|
@ -552,7 +551,7 @@
|
||||||
this.sendAllPlayerInfoIn = 0;
|
this.sendAllPlayerInfoIn = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -510,6 +749,25 @@
|
@@ -510,6 +748,25 @@
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -578,7 +577,7 @@
|
||||||
public void broadcastAll(Packet<?> packet, ResourceKey<World> resourcekey) {
|
public void broadcastAll(Packet<?> packet, ResourceKey<World> resourcekey) {
|
||||||
for (EntityPlayer entityplayer : this.players) {
|
for (EntityPlayer entityplayer : this.players) {
|
||||||
if (entityplayer.level().dimension() == resourcekey) {
|
if (entityplayer.level().dimension() == resourcekey) {
|
||||||
@@ -604,6 +862,7 @@
|
@@ -604,6 +861,7 @@
|
||||||
entityplayer.connection.send(new PacketPlayOutEntityStatus(entityplayer, b0));
|
entityplayer.connection.send(new PacketPlayOutEntityStatus(entityplayer, b0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -586,7 +585,7 @@
|
||||||
this.server.getCommands().sendCommands(entityplayer);
|
this.server.getCommands().sendCommands(entityplayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -634,6 +893,12 @@
|
@@ -634,6 +892,12 @@
|
||||||
for (int i = 0; i < this.players.size(); ++i) {
|
for (int i = 0; i < this.players.size(); ++i) {
|
||||||
EntityPlayer entityplayer = (EntityPlayer) this.players.get(i);
|
EntityPlayer entityplayer = (EntityPlayer) this.players.get(i);
|
||||||
|
|
||||||
|
@ -599,7 +598,7 @@
|
||||||
if (entityplayer != entityhuman && entityplayer.level().dimension() == resourcekey) {
|
if (entityplayer != entityhuman && entityplayer.level().dimension() == resourcekey) {
|
||||||
double d4 = d0 - entityplayer.getX();
|
double d4 = d0 - entityplayer.getX();
|
||||||
double d5 = d1 - entityplayer.getY();
|
double d5 = d1 - entityplayer.getY();
|
||||||
@@ -673,15 +938,19 @@
|
@@ -673,15 +937,19 @@
|
||||||
public void reloadWhiteList() {}
|
public void reloadWhiteList() {}
|
||||||
|
|
||||||
public void sendLevelInfo(EntityPlayer entityplayer, WorldServer worldserver) {
|
public void sendLevelInfo(EntityPlayer entityplayer, WorldServer worldserver) {
|
||||||
|
@ -623,7 +622,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
entityplayer.connection.send(new PacketPlayOutGameStateChange(PacketPlayOutGameStateChange.LEVEL_CHUNKS_LOAD_START, 0.0F));
|
entityplayer.connection.send(new PacketPlayOutGameStateChange(PacketPlayOutGameStateChange.LEVEL_CHUNKS_LOAD_START, 0.0F));
|
||||||
@@ -690,8 +959,16 @@
|
@@ -690,8 +958,16 @@
|
||||||
|
|
||||||
public void sendAllPlayerInfo(EntityPlayer entityplayer) {
|
public void sendAllPlayerInfo(EntityPlayer entityplayer) {
|
||||||
entityplayer.inventoryMenu.sendAllDataToRemote();
|
entityplayer.inventoryMenu.sendAllDataToRemote();
|
||||||
|
@ -641,7 +640,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getPlayerCount() {
|
public int getPlayerCount() {
|
||||||
@@ -744,11 +1021,21 @@
|
@@ -744,11 +1020,21 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeAll() {
|
public void removeAll() {
|
||||||
|
@ -665,7 +664,7 @@
|
||||||
|
|
||||||
public void broadcastSystemMessage(IChatBaseComponent ichatbasecomponent, boolean flag) {
|
public void broadcastSystemMessage(IChatBaseComponent ichatbasecomponent, boolean flag) {
|
||||||
this.broadcastSystemMessage(ichatbasecomponent, (entityplayer) -> {
|
this.broadcastSystemMessage(ichatbasecomponent, (entityplayer) -> {
|
||||||
@@ -803,16 +1090,23 @@
|
@@ -803,16 +1089,23 @@
|
||||||
return playerchatmessage.hasSignature() && !playerchatmessage.hasExpiredServer(Instant.now());
|
return playerchatmessage.hasSignature() && !playerchatmessage.hasExpiredServer(Instant.now());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -693,7 +692,7 @@
|
||||||
Path path = file2.toPath();
|
Path path = file2.toPath();
|
||||||
|
|
||||||
if (FileUtils.isPathNormalized(path) && FileUtils.isPathPortable(path) && path.startsWith(file.getPath()) && file2.isFile()) {
|
if (FileUtils.isPathNormalized(path) && FileUtils.isPathPortable(path) && path.startsWith(file.getPath()) && file2.isFile()) {
|
||||||
@@ -821,7 +1115,7 @@
|
@@ -821,7 +1114,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
serverstatisticmanager = new ServerStatisticManager(this.server, file1);
|
serverstatisticmanager = new ServerStatisticManager(this.server, file1);
|
||||||
|
@ -702,7 +701,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
return serverstatisticmanager;
|
return serverstatisticmanager;
|
||||||
@@ -829,13 +1123,13 @@
|
@@ -829,13 +1122,13 @@
|
||||||
|
|
||||||
public AdvancementDataPlayer getPlayerAdvancements(EntityPlayer entityplayer) {
|
public AdvancementDataPlayer getPlayerAdvancements(EntityPlayer entityplayer) {
|
||||||
UUID uuid = entityplayer.getUUID();
|
UUID uuid = entityplayer.getUUID();
|
||||||
|
@ -718,7 +717,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
advancementdataplayer.setPlayer(entityplayer);
|
advancementdataplayer.setPlayer(entityplayer);
|
||||||
@@ -880,11 +1174,24 @@
|
@@ -880,11 +1173,24 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reloadResources() {
|
public void reloadResources() {
|
||||||
|
|
4
pom.xml
4
pom.xml
|
@ -40,9 +40,9 @@
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>jline</groupId>
|
<groupId>org.jline</groupId>
|
||||||
<artifactId>jline</artifactId>
|
<artifactId>jline</artifactId>
|
||||||
<version>2.12.1</version>
|
<version>3.30.4</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|
|
@ -43,7 +43,6 @@ import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
import jline.console.ConsoleReader;
|
|
||||||
import net.minecraft.advancements.AdvancementHolder;
|
import net.minecraft.advancements.AdvancementHolder;
|
||||||
import net.minecraft.commands.CommandDispatcher;
|
import net.minecraft.commands.CommandDispatcher;
|
||||||
import net.minecraft.commands.CommandListenerWrapper;
|
import net.minecraft.commands.CommandListenerWrapper;
|
||||||
|
@ -264,6 +263,7 @@ import org.bukkit.scoreboard.Criteria;
|
||||||
import org.bukkit.structure.StructureManager;
|
import org.bukkit.structure.StructureManager;
|
||||||
import org.bukkit.util.StringUtil;
|
import org.bukkit.util.StringUtil;
|
||||||
import org.bukkit.util.permissions.DefaultPermissions;
|
import org.bukkit.util.permissions.DefaultPermissions;
|
||||||
|
import org.jline.terminal.Terminal;
|
||||||
import org.yaml.snakeyaml.LoaderOptions;
|
import org.yaml.snakeyaml.LoaderOptions;
|
||||||
import org.yaml.snakeyaml.Yaml;
|
import org.yaml.snakeyaml.Yaml;
|
||||||
import org.yaml.snakeyaml.constructor.SafeConstructor;
|
import org.yaml.snakeyaml.constructor.SafeConstructor;
|
||||||
|
@ -1334,8 +1334,8 @@ public final class CraftServer implements Server {
|
||||||
return logger;
|
return logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConsoleReader getReader() {
|
public Terminal getTerminal() {
|
||||||
return console.reader;
|
return console.terminal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -13,7 +13,8 @@ import java.util.logging.Logger;
|
||||||
import joptsimple.OptionParser;
|
import joptsimple.OptionParser;
|
||||||
import joptsimple.OptionSet;
|
import joptsimple.OptionSet;
|
||||||
import joptsimple.util.PathConverter;
|
import joptsimple.util.PathConverter;
|
||||||
import org.fusesource.jansi.AnsiConsole;
|
import org.jline.terminal.Terminal;
|
||||||
|
import org.jline.terminal.TerminalBuilder;
|
||||||
|
|
||||||
public class Main {
|
public class Main {
|
||||||
public static boolean useJline = true;
|
public static boolean useJline = true;
|
||||||
|
@ -169,22 +170,15 @@ public class Main {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// This trick bypasses Maven Shade's clever rewriting of our getProperty call when using String literals
|
useJline = !Terminal.TYPE_DUMB.equals(System.getProperty(TerminalBuilder.PROP_PROVIDER));
|
||||||
String jline_UnsupportedTerminal = new String(new char[]{'j', 'l', 'i', 'n', 'e', '.', 'U', 'n', 's', 'u', 'p', 'p', 'o', 'r', 't', 'e', 'd', 'T', 'e', 'r', 'm', 'i', 'n', 'a', 'l'});
|
|
||||||
String jline_terminal = new String(new char[]{'j', 'l', 'i', 'n', 'e', '.', 't', 'e', 'r', 'm', 'i', 'n', 'a', 'l'});
|
|
||||||
|
|
||||||
useJline = !(jline_UnsupportedTerminal).equals(System.getProperty(jline_terminal));
|
|
||||||
|
|
||||||
if (options.has("nojline")) {
|
if (options.has("nojline")) {
|
||||||
System.setProperty("user.language", "en");
|
|
||||||
useJline = false;
|
useJline = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (useJline) {
|
if (!useJline) {
|
||||||
AnsiConsole.systemInstall();
|
|
||||||
} else {
|
|
||||||
// This ensures the terminal literal will always match the jline implementation
|
// This ensures the terminal literal will always match the jline implementation
|
||||||
System.setProperty(jline.TerminalFactory.JLINE_TERMINAL, jline.UnsupportedTerminal.class.getName());
|
System.setProperty(TerminalBuilder.PROP_PROVIDER, Terminal.TYPE_DUMB);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.has("noconsole")) {
|
if (options.has("noconsole")) {
|
||||||
|
|
|
@ -5,27 +5,29 @@ import java.util.EnumMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import jline.Terminal;
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.command.ConsoleCommandSender;
|
import org.bukkit.command.ConsoleCommandSender;
|
||||||
import org.bukkit.craftbukkit.CraftServer;
|
import org.bukkit.craftbukkit.CraftServer;
|
||||||
import org.fusesource.jansi.Ansi;
|
import org.jline.jansi.Ansi;
|
||||||
import org.fusesource.jansi.Ansi.Attribute;
|
import org.jline.jansi.Ansi.Attribute;
|
||||||
|
import org.jline.terminal.Terminal;
|
||||||
|
|
||||||
public class ColouredConsoleSender extends CraftConsoleCommandSender {
|
public class ColouredConsoleSender extends CraftConsoleCommandSender {
|
||||||
private final Terminal terminal;
|
private final Terminal terminal;
|
||||||
private final Map<ChatColor, String> replacements = new EnumMap<ChatColor, String>(ChatColor.class);
|
private final Map<ChatColor, String> replacements = new EnumMap<ChatColor, String>(ChatColor.class);
|
||||||
private final ChatColor[] colors = ChatColor.values();
|
private final ChatColor[] colors = ChatColor.values();
|
||||||
private final boolean jansiPassthrough;
|
private final boolean jansiPassthrough;
|
||||||
|
private final boolean supportsAnsi;
|
||||||
private static final char ANSI_ESC_CHAR = '\u001B';
|
private static final char ANSI_ESC_CHAR = '\u001B';
|
||||||
private static final String RGB_STRING = String.valueOf(ANSI_ESC_CHAR) + "[38;2;%d;%d;%dm";
|
private static final String RGB_STRING = String.valueOf(ANSI_ESC_CHAR) + "[38;2;%d;%d;%dm";
|
||||||
private static final Pattern RBG_TRANSLATE = Pattern.compile(String.valueOf(ChatColor.COLOR_CHAR) + "x(" + String.valueOf(ChatColor.COLOR_CHAR) + "[A-F0-9]){6}", Pattern.CASE_INSENSITIVE);
|
private static final Pattern RBG_TRANSLATE = Pattern.compile(String.valueOf(ChatColor.COLOR_CHAR) + "x(" + String.valueOf(ChatColor.COLOR_CHAR) + "[A-F0-9]){6}", Pattern.CASE_INSENSITIVE);
|
||||||
|
|
||||||
protected ColouredConsoleSender() {
|
protected ColouredConsoleSender() {
|
||||||
super();
|
super();
|
||||||
this.terminal = ((CraftServer) getServer()).getReader().getTerminal();
|
this.terminal = ((CraftServer) getServer()).getTerminal();
|
||||||
this.jansiPassthrough = Boolean.getBoolean("jansi.passthrough");
|
this.jansiPassthrough = Boolean.getBoolean("jansi.passthrough");
|
||||||
|
this.supportsAnsi = !Terminal.TYPE_DUMB.equals(terminal.getType());
|
||||||
|
|
||||||
replacements.put(ChatColor.BLACK, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.BLACK).boldOff().toString());
|
replacements.put(ChatColor.BLACK, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.BLACK).boldOff().toString());
|
||||||
replacements.put(ChatColor.DARK_BLUE, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.BLUE).boldOff().toString());
|
replacements.put(ChatColor.DARK_BLUE, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.BLUE).boldOff().toString());
|
||||||
|
@ -54,7 +56,7 @@ public class ColouredConsoleSender extends CraftConsoleCommandSender {
|
||||||
@Override
|
@Override
|
||||||
public void sendMessage(String message) {
|
public void sendMessage(String message) {
|
||||||
// support jansi passthrough VM option when jansi doesn't detect an ANSI supported terminal
|
// support jansi passthrough VM option when jansi doesn't detect an ANSI supported terminal
|
||||||
if (jansiPassthrough || terminal.isAnsiSupported()) {
|
if (jansiPassthrough || supportsAnsi) {
|
||||||
if (!conversationTracker.isConversingModaly()) {
|
if (!conversationTracker.isConversingModaly()) {
|
||||||
String result = convertRGBColors(message);
|
String result = convertRGBColors(message);
|
||||||
for (ChatColor color : colors) {
|
for (ChatColor color : colors) {
|
||||||
|
|
|
@ -4,20 +4,25 @@ import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import jline.console.completer.Completer;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.craftbukkit.CraftServer;
|
import org.bukkit.craftbukkit.CraftServer;
|
||||||
import org.bukkit.craftbukkit.util.Waitable;
|
import org.bukkit.craftbukkit.util.Waitable;
|
||||||
import org.bukkit.event.server.TabCompleteEvent;
|
import org.bukkit.event.server.TabCompleteEvent;
|
||||||
|
import org.jline.reader.Candidate;
|
||||||
|
import org.jline.reader.Completer;
|
||||||
|
import org.jline.reader.LineReader;
|
||||||
|
import org.jline.reader.ParsedLine;
|
||||||
|
|
||||||
public class ConsoleCommandCompleter implements Completer {
|
public class ConsoleCommandCompleter implements Completer {
|
||||||
private final CraftServer server;
|
|
||||||
|
|
||||||
public ConsoleCommandCompleter(CraftServer server) {
|
|
||||||
this.server = server;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int complete(final String buffer, final int cursor, final List<CharSequence> candidates) {
|
public void complete(LineReader reader, ParsedLine line, List<Candidate> candidates) {
|
||||||
|
CraftServer server = (CraftServer) Bukkit.getServer();
|
||||||
|
if (server == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String buffer = line.line();
|
||||||
Waitable<List<String>> waitable = new Waitable<List<String>>() {
|
Waitable<List<String>> waitable = new Waitable<List<String>>() {
|
||||||
@Override
|
@Override
|
||||||
protected List<String> evaluate() {
|
protected List<String> evaluate() {
|
||||||
|
@ -29,25 +34,17 @@ public class ConsoleCommandCompleter implements Completer {
|
||||||
return tabEvent.isCancelled() ? Collections.EMPTY_LIST : tabEvent.getCompletions();
|
return tabEvent.isCancelled() ? Collections.EMPTY_LIST : tabEvent.getCompletions();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
this.server.getServer().processQueue.add(waitable);
|
server.getServer().processQueue.add(waitable);
|
||||||
try {
|
try {
|
||||||
List<String> offers = waitable.get();
|
List<String> offers = waitable.get();
|
||||||
if (offers == null) {
|
if (offers == null) {
|
||||||
return cursor;
|
return;
|
||||||
}
|
|
||||||
candidates.addAll(offers);
|
|
||||||
|
|
||||||
final int lastSpace = buffer.lastIndexOf(' ');
|
|
||||||
if (lastSpace == -1) {
|
|
||||||
return cursor - buffer.length();
|
|
||||||
} else {
|
|
||||||
return cursor - (buffer.length() - lastSpace - 1);
|
|
||||||
}
|
}
|
||||||
|
offers.stream().map(Candidate::new).forEach((candidate) -> candidates.add(candidate));
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
this.server.getLogger().log(Level.WARNING, "Unhandled exception when tab completing", e);
|
server.getLogger().log(Level.WARNING, "Unhandled exception when tab completing", e);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
}
|
}
|
||||||
return cursor;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ public class ServerShutdownThread extends Thread {
|
||||||
server.close();
|
server.close();
|
||||||
} finally {
|
} finally {
|
||||||
try {
|
try {
|
||||||
server.reader.getTerminal().restore();
|
server.terminal.close();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,53 +0,0 @@
|
||||||
package org.bukkit.craftbukkit.util;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import jline.console.ConsoleReader;
|
|
||||||
import jline.console.completer.CompletionHandler;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SPIGOT-6705: Make sure we print the display line again on tab completion, so that the user does not get stuck on it
|
|
||||||
* e.g. The user needs to press y / n to continue
|
|
||||||
*/
|
|
||||||
public class TerminalCompletionHandler implements CompletionHandler {
|
|
||||||
|
|
||||||
private final TerminalConsoleWriterThread writerThread;
|
|
||||||
private final CompletionHandler delegate;
|
|
||||||
|
|
||||||
public TerminalCompletionHandler(TerminalConsoleWriterThread writerThread, CompletionHandler delegate) {
|
|
||||||
this.writerThread = writerThread;
|
|
||||||
this.delegate = delegate;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean complete(ConsoleReader reader, List<CharSequence> candidates, int position) throws IOException {
|
|
||||||
// First check normal list, so that we do not unnecessarily create a new HashSet if the not distinct list is already lower
|
|
||||||
if (candidates.size() <= reader.getAutoprintThreshold()) {
|
|
||||||
return delegate.complete(reader, candidates, position);
|
|
||||||
}
|
|
||||||
|
|
||||||
Set<CharSequence> distinct = new HashSet<>(candidates);
|
|
||||||
if (distinct.size() <= reader.getAutoprintThreshold()) {
|
|
||||||
return delegate.complete(reader, candidates, position);
|
|
||||||
}
|
|
||||||
|
|
||||||
writerThread.setCompletion(distinct.size());
|
|
||||||
|
|
||||||
// FIXME: Potential concurrency issue, when terminal writer prints the display message before the delegate does it
|
|
||||||
// resulting in two display message being present, until a new message gets logged or the user presses y / n
|
|
||||||
// But the probability of this happening are probably lower than the effort needed to fix this
|
|
||||||
// And seeing the display message at all should be a higher priority than seeing it two times in rare cases.
|
|
||||||
boolean result = delegate.complete(reader, candidates, position);
|
|
||||||
|
|
||||||
writerThread.setCompletion(-1);
|
|
||||||
// draw line to prevent concurrency issue,
|
|
||||||
// where terminal write would print the display message between delegate#complete finished and the completion set back to -1
|
|
||||||
// Resulting in the display message being present even after pressing y / n
|
|
||||||
reader.drawLine();
|
|
||||||
reader.flush();
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,23 +3,16 @@ package org.bukkit.craftbukkit.util;
|
||||||
import com.mojang.logging.LogQueues;
|
import com.mojang.logging.LogQueues;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.ResourceBundle;
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import jline.console.ConsoleReader;
|
|
||||||
import jline.console.completer.CandidateListCompletionHandler;
|
|
||||||
import org.bukkit.craftbukkit.Main;
|
import org.bukkit.craftbukkit.Main;
|
||||||
import org.fusesource.jansi.Ansi;
|
import org.jline.reader.LineReader;
|
||||||
import org.fusesource.jansi.Ansi.Erase;
|
|
||||||
|
|
||||||
public class TerminalConsoleWriterThread extends Thread {
|
public class TerminalConsoleWriterThread extends Thread {
|
||||||
private final ResourceBundle bundle = ResourceBundle.getBundle(CandidateListCompletionHandler.class.getName(), Locale.getDefault());
|
private final LineReader reader;
|
||||||
private final ConsoleReader reader;
|
|
||||||
private final OutputStream output;
|
private final OutputStream output;
|
||||||
private volatile int completion = -1;
|
|
||||||
|
|
||||||
public TerminalConsoleWriterThread(OutputStream output, ConsoleReader reader) {
|
public TerminalConsoleWriterThread(OutputStream output, LineReader reader) {
|
||||||
super("TerminalConsoleWriter");
|
super("TerminalConsoleWriter");
|
||||||
this.output = output;
|
this.output = output;
|
||||||
this.reader = reader;
|
this.reader = reader;
|
||||||
|
@ -40,23 +33,7 @@ public class TerminalConsoleWriterThread extends Thread {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (Main.useJline) {
|
if (Main.useJline) {
|
||||||
reader.print(Ansi.ansi().eraseLine(Erase.ALL).toString() + ConsoleReader.RESET_LINE);
|
reader.printAbove(message);
|
||||||
reader.flush();
|
|
||||||
output.write(message.getBytes());
|
|
||||||
output.flush();
|
|
||||||
|
|
||||||
try {
|
|
||||||
reader.drawLine();
|
|
||||||
} catch (Throwable ex) {
|
|
||||||
reader.getCursorBuffer().clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (completion > -1) {
|
|
||||||
// SPIGOT-6705: Make sure we print the display line again on tab completion, so that the user does not get stuck on it
|
|
||||||
reader.print(String.format(bundle.getString("DISPLAY_CANDIDATES"), completion));
|
|
||||||
}
|
|
||||||
|
|
||||||
reader.flush();
|
|
||||||
} else {
|
} else {
|
||||||
output.write(message.getBytes());
|
output.write(message.getBytes());
|
||||||
output.flush();
|
output.flush();
|
||||||
|
@ -66,8 +43,4 @@ public class TerminalConsoleWriterThread extends Thread {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setCompletion(int completion) {
|
|
||||||
this.completion = completion;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue