mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-10-11 19:14:11 +00:00
Refreshed pregeneration runtime
- Generation router reads avoid the attachment monitor after publication - Desktop pregeneration uses a proportional map with distinct controls and metrics - Preview updates remain bounded through large targets and window state changes - Pause controls stay bound to their owning job - Startup failures retain a readable error window - Bundled language catalogs cover the revised window
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
package art.arcane.iris.core.gui;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.DataBufferInt;
|
||||
import java.util.Arrays;
|
||||
import java.util.BitSet;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
final class PregenMapPanel extends JPanel {
|
||||
private static final int MAX_RASTER_SIZE = 1024;
|
||||
static final Color WAITING = new Color(29, 35, 46);
|
||||
|
||||
private final PregenRenderSnapshot.Bounds bounds;
|
||||
private final BufferedImage image;
|
||||
private final int[] imagePixels;
|
||||
private final int[] pendingPixels;
|
||||
private final BitSet dirtyPixels;
|
||||
private final ReentrantLock lock = new ReentrantLock();
|
||||
private volatile boolean pendingChanges;
|
||||
private volatile boolean disposed;
|
||||
|
||||
PregenMapPanel(PregenRenderSnapshot.Bounds bounds) {
|
||||
this.bounds = bounds;
|
||||
int width = (int) Math.min(MAX_RASTER_SIZE, bounds.width());
|
||||
int height = (int) Math.min(MAX_RASTER_SIZE, bounds.height());
|
||||
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||||
imagePixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
|
||||
pendingPixels = new int[imagePixels.length];
|
||||
dirtyPixels = new BitSet(imagePixels.length);
|
||||
Arrays.fill(imagePixels, WAITING.getRGB());
|
||||
Arrays.fill(pendingPixels, WAITING.getRGB());
|
||||
setBackground(PregenRenderer.BACKGROUND);
|
||||
}
|
||||
|
||||
void submit(int chunkX, int chunkZ, Color color) {
|
||||
if (disposed || !bounds.contains(chunkX, chunkZ)) {
|
||||
return;
|
||||
}
|
||||
int x = (int) (((long) chunkX - bounds.minX()) * image.getWidth() / bounds.width());
|
||||
int z = (int) (((long) chunkZ - bounds.minZ()) * image.getHeight() / bounds.height());
|
||||
int index = z * image.getWidth() + x;
|
||||
int rgb = color.getRGB();
|
||||
lock.lock();
|
||||
try {
|
||||
if (disposed || pendingPixels[index] == rgb) {
|
||||
return;
|
||||
}
|
||||
pendingPixels[index] = rgb;
|
||||
dirtyPixels.set(index);
|
||||
pendingChanges = true;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
boolean flush() {
|
||||
if (!pendingChanges || disposed) {
|
||||
return false;
|
||||
}
|
||||
lock.lock();
|
||||
try {
|
||||
for (int index = dirtyPixels.nextSetBit(0); index >= 0; index = dirtyPixels.nextSetBit(index + 1)) {
|
||||
imagePixels[index] = pendingPixels[index];
|
||||
}
|
||||
dirtyPixels.clear();
|
||||
pendingChanges = false;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void disposeMap() {
|
||||
lock.lock();
|
||||
try {
|
||||
disposed = true;
|
||||
dirtyPixels.clear();
|
||||
pendingChanges = false;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintComponent(Graphics graphics) {
|
||||
super.paintComponent(graphics);
|
||||
Graphics2D canvas = (Graphics2D) graphics.create();
|
||||
try {
|
||||
Rectangle area = fit(bounds, getWidth(), getHeight());
|
||||
canvas.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
|
||||
canvas.drawImage(image, area.x, area.y, area.width, area.height, null);
|
||||
canvas.setColor(PregenRenderer.BORDER);
|
||||
canvas.drawRect(area.x, area.y, area.width - 1, area.height - 1);
|
||||
} finally {
|
||||
canvas.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
static Rectangle fit(PregenRenderSnapshot.Bounds bounds, int width, int height) {
|
||||
int availableWidth = Math.max(1, width - 2);
|
||||
int availableHeight = Math.max(1, height - 2);
|
||||
double scale = Math.min((double) availableWidth / bounds.width(), (double) availableHeight / bounds.height());
|
||||
int mapWidth = Math.max(1, (int) Math.floor(bounds.width() * scale));
|
||||
int mapHeight = Math.max(1, (int) Math.floor(bounds.height() * scale));
|
||||
return new Rectangle((width - mapWidth) / 2, (height - mapHeight) / 2, mapWidth, mapHeight);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package art.arcane.iris.core.gui;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public record PregenRenderSnapshot(
|
||||
Bounds bounds,
|
||||
PregeneratorJob.PregenProgress progress,
|
||||
Phase phase,
|
||||
boolean cached,
|
||||
long usedMemoryBytes,
|
||||
double memoryUsage,
|
||||
long allocationBytesPerSecond,
|
||||
String failure
|
||||
) {
|
||||
public PregenRenderSnapshot {
|
||||
Objects.requireNonNull(bounds, "Map bounds");
|
||||
Objects.requireNonNull(progress, "Generation progress");
|
||||
Objects.requireNonNull(phase, "Generation phase");
|
||||
}
|
||||
|
||||
public enum Phase {
|
||||
INITIALIZING,
|
||||
GENERATING,
|
||||
PAUSED,
|
||||
SAVING,
|
||||
STOPPING,
|
||||
COMPLETED,
|
||||
ERROR
|
||||
}
|
||||
|
||||
public record Bounds(int minX, int minZ, int maxX, int maxZ) {
|
||||
public Bounds {
|
||||
if (maxX < minX || maxZ < minZ) {
|
||||
throw new IllegalArgumentException("Map bounds must contain at least one chunk");
|
||||
}
|
||||
}
|
||||
|
||||
public long width() {
|
||||
return (long) maxX - minX + 1;
|
||||
}
|
||||
|
||||
public long height() {
|
||||
return (long) maxZ - minZ + 1;
|
||||
}
|
||||
|
||||
public boolean contains(int x, int z) {
|
||||
return x >= minX && x <= maxX && z >= minZ && z <= maxZ;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,14 +18,6 @@
|
||||
|
||||
package art.arcane.iris.core.gui;
|
||||
|
||||
import art.arcane.volmlib.util.math.Position2;
|
||||
|
||||
public interface PregenRenderSource {
|
||||
Position2 min();
|
||||
|
||||
Position2 max();
|
||||
|
||||
String[] progress();
|
||||
|
||||
boolean paused();
|
||||
PregenRenderSnapshot renderSnapshot();
|
||||
}
|
||||
|
||||
@@ -18,92 +18,138 @@
|
||||
|
||||
package art.arcane.iris.core.gui;
|
||||
|
||||
import art.arcane.iris.core.IrisSettings;
|
||||
import art.arcane.iris.core.localization.DesktopUiMessages;
|
||||
import art.arcane.iris.core.localization.IrisLanguage;
|
||||
import art.arcane.iris.spi.IrisLogging;
|
||||
import art.arcane.iris.core.IrisSettings;
|
||||
import art.arcane.volmlib.util.math.M;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||
import art.arcane.volmlib.util.format.Form;
|
||||
import art.arcane.volmlib.util.localization.MessageArgument;
|
||||
import art.arcane.volmlib.util.localization.TextKey;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.AbstractButton;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JProgressBar;
|
||||
import javax.swing.KeyStroke;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.Timer;
|
||||
import javax.swing.plaf.basic.BasicButtonUI;
|
||||
import javax.swing.plaf.basic.BasicGraphicsUtils;
|
||||
import javax.swing.plaf.basic.BasicProgressBarUI;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Frame;
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.LayoutManager;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.FocusAdapter;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.Objects;
|
||||
|
||||
public final class PregenRenderer extends JPanel implements KeyListener {
|
||||
public final class PregenRenderer extends JPanel {
|
||||
private static final long serialVersionUID = 2094606939770332040L;
|
||||
static final Color BACKGROUND = new Color(12, 15, 22);
|
||||
static final Color BORDER = new Color(105, 119, 139);
|
||||
private static final Color SURFACE = new Color(17, 20, 29);
|
||||
private static final Color FIELD = new Color(29, 34, 47);
|
||||
private static final Color TEXT = new Color(230, 234, 242);
|
||||
private static final Color MUTED = new Color(163, 173, 191);
|
||||
private static final Color ACCENT = new Color(101, 194, 149);
|
||||
private static final Color ERROR = new Color(255, 139, 139);
|
||||
static final Color GENERATING = new Color(204, 168, 107);
|
||||
static final Color GENERATED = ACCENT;
|
||||
static final Color EXISTS = new Color(93, 133, 112);
|
||||
static final Color NETWORK = new Color(157, 138, 176);
|
||||
static final Color NETWORK_GENERATING = new Color(129, 112, 145);
|
||||
private static final Font BODY_FONT = new Font(Font.SANS_SERIF, Font.PLAIN, 13);
|
||||
private static final Font LABEL_FONT = new Font(Font.SANS_SERIF, Font.PLAIN, 11);
|
||||
private static final Font VALUE_FONT = new Font(Font.SANS_SERIF, Font.BOLD, 15);
|
||||
|
||||
private static final int MAX_PENDING_DRAWS = 16_384;
|
||||
private Long2ObjectLinkedOpenHashMap<Color> pending = new Long2ObjectLinkedOpenHashMap<>();
|
||||
private final ReentrantLock lock = new ReentrantLock();
|
||||
private final int res = 512;
|
||||
private final BufferedImage image = new BufferedImage(res, res, BufferedImage.TYPE_INT_RGB);
|
||||
private final Graphics2D imageGraphics = image.createGraphics();
|
||||
private final PregenRenderSource source;
|
||||
private final Runnable onPause;
|
||||
private final PregenMapPanel map;
|
||||
private final Timer repaintTimer;
|
||||
private final JLabel worldLabel = label("", new Font(Font.SANS_SERIF, Font.BOLD, 21), TEXT);
|
||||
private final JLabel phaseLabel = label("", BODY_FONT, MUTED);
|
||||
private final JLabel countLabel = label("", BODY_FONT, TEXT);
|
||||
private final JLabel percentLabel = label("", BODY_FONT, MUTED);
|
||||
private final JLabel currentValue = label("", VALUE_FONT, TEXT);
|
||||
private final JLabel overallValue = label("", VALUE_FONT, TEXT);
|
||||
private final JLabel thirtyValue = label("", VALUE_FONT, TEXT);
|
||||
private final JLabel sixtyValue = label("", VALUE_FONT, TEXT);
|
||||
private final JLabel etaValue = label("", VALUE_FONT, TEXT);
|
||||
private final JLabel elapsedValue = label("", VALUE_FONT, TEXT);
|
||||
private final JLabel memoryValue = label("", VALUE_FONT, TEXT);
|
||||
private final JLabel pressureValue = label("", VALUE_FONT, TEXT);
|
||||
private final JLabel methodLabel = label("", LABEL_FONT, MUTED);
|
||||
private final JLabel failureLabel = label("", LABEL_FONT, ERROR);
|
||||
private final JButton pauseButton = new JButton();
|
||||
private final JProgressBar progressBar = new JProgressBar(0, 10_000);
|
||||
private volatile boolean renderingEnabled;
|
||||
private boolean disposed;
|
||||
private volatile boolean disposed;
|
||||
private volatile JFrame frame;
|
||||
private PregenRenderSnapshot displayedSnapshot;
|
||||
|
||||
private PregenRenderer(PregenRenderSource source, Runnable onPause) {
|
||||
this.source = source;
|
||||
this.source = Objects.requireNonNull(source, "Generation view source");
|
||||
this.onPause = onPause;
|
||||
repaintTimer = new Timer(IrisSettings.get().getGui().isMaximumPregenGuiFPS() ? 4 : 250, event -> repaint());
|
||||
PregenRenderSnapshot initial = source.renderSnapshot();
|
||||
map = new PregenMapPanel(initial.bounds());
|
||||
setLayout(new BorderLayout(0, 18));
|
||||
setBackground(BACKGROUND);
|
||||
setBorder(BorderFactory.createEmptyBorder(20, 24, 18, 24));
|
||||
add(header(), BorderLayout.NORTH);
|
||||
add(mapArea(initial.bounds()), BorderLayout.CENTER);
|
||||
add(statusArea(), BorderLayout.SOUTH);
|
||||
installPauseControl();
|
||||
repaintTimer = new Timer(IrisSettings.get().getGui().isMaximumPregenGuiFPS() ? 4 : 250,
|
||||
event -> refresh());
|
||||
refresh();
|
||||
}
|
||||
|
||||
public static PregenRenderer open(String title, PregenRenderSource source, Runnable onPause) {
|
||||
if (!SwingUtilities.isEventDispatchThread()) {
|
||||
throw new IllegalStateException("The pregeneration window must open on the Swing event thread");
|
||||
}
|
||||
PregenRenderer renderer = new PregenRenderer(source, onPause);
|
||||
JFrame frame = new JFrame(title);
|
||||
GuiHost.prepareFrame(frame);
|
||||
renderer.frame = frame;
|
||||
renderer.renderingEnabled = true;
|
||||
frame.addKeyListener(renderer);
|
||||
frame.add(renderer);
|
||||
frame.setSize(1000, 1000);
|
||||
frame.setContentPane(renderer);
|
||||
frame.setSize(1040, 900);
|
||||
frame.setMinimumSize(new Dimension(760, 660));
|
||||
frame.addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosed(WindowEvent event) {
|
||||
renderer.disposeRenderer();
|
||||
}
|
||||
});
|
||||
frame.addWindowStateListener(event -> renderer.renderingEnabled = (event.getNewState() & Frame.ICONIFIED) == 0);
|
||||
frame.addWindowStateListener(event -> renderer.setRenderingEnabled((event.getNewState() & Frame.ICONIFIED) == 0));
|
||||
frame.setVisible(true);
|
||||
renderer.repaintTimer.start();
|
||||
return renderer;
|
||||
}
|
||||
|
||||
public void submit(int x, int z, Color color) {
|
||||
if (!renderingEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
long key = ((long) x << 32) ^ (z & 0xffffffffL);
|
||||
lock.lock();
|
||||
try {
|
||||
pending.putAndMoveToFirst(key, color);
|
||||
if (pending.size() > MAX_PENDING_DRAWS) {
|
||||
pending.removeLast();
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
map.submit(x, z, color);
|
||||
}
|
||||
|
||||
public boolean isVisibleFrame() {
|
||||
return renderingEnabled;
|
||||
return renderingEnabled && !disposed;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
@@ -119,6 +165,234 @@ public final class PregenRenderer extends JPanel implements KeyListener {
|
||||
}
|
||||
}
|
||||
|
||||
private JPanel header() {
|
||||
JPanel heading = panel(new BorderLayout(16, 0), BACKGROUND);
|
||||
JPanel identity = panel(new GridLayout(2, 1, 0, 4), BACKGROUND);
|
||||
identity.add(worldLabel);
|
||||
identity.add(phaseLabel);
|
||||
heading.add(identity, BorderLayout.CENTER);
|
||||
heading.add(pauseButton, BorderLayout.EAST);
|
||||
JPanel counts = panel(new BorderLayout(), BACKGROUND);
|
||||
counts.add(countLabel, BorderLayout.WEST);
|
||||
counts.add(percentLabel, BorderLayout.EAST);
|
||||
progressBar.setUI(new BasicProgressBarUI());
|
||||
progressBar.setForeground(ACCENT);
|
||||
progressBar.setBackground(FIELD);
|
||||
progressBar.setBorderPainted(false);
|
||||
progressBar.setPreferredSize(new Dimension(1, 6));
|
||||
progressBar.setFocusable(false);
|
||||
JPanel progress = panel(new BorderLayout(0, 9), BACKGROUND);
|
||||
progress.add(counts, BorderLayout.NORTH);
|
||||
progress.add(progressBar, BorderLayout.SOUTH);
|
||||
JPanel header = panel(new BorderLayout(0, 18), BACKGROUND);
|
||||
header.add(heading, BorderLayout.NORTH);
|
||||
header.add(progress, BorderLayout.SOUTH);
|
||||
return header;
|
||||
}
|
||||
|
||||
private JPanel mapArea(PregenRenderSnapshot.Bounds bounds) {
|
||||
JPanel area = panel(new BorderLayout(0, 8), BACKGROUND);
|
||||
map.getAccessibleContext().setAccessibleName(text(DesktopUiMessages.PREGEN_MAP));
|
||||
area.add(map, BorderLayout.CENTER);
|
||||
JLabel coordinates = label(text(DesktopUiMessages.PREGEN_BOUNDS,
|
||||
MessageArgument.trusted("minX", Form.f(bounds.minX())),
|
||||
MessageArgument.trusted("maxX", Form.f(bounds.maxX())),
|
||||
MessageArgument.trusted("minZ", Form.f(bounds.minZ())),
|
||||
MessageArgument.trusted("maxZ", Form.f(bounds.maxZ()))), LABEL_FONT, MUTED);
|
||||
area.add(coordinates, BorderLayout.SOUTH);
|
||||
return area;
|
||||
}
|
||||
|
||||
private JPanel statusArea() {
|
||||
JPanel metrics = panel(new GridLayout(2, 4, 24, 20), SURFACE);
|
||||
metrics.add(metric(DesktopUiMessages.PREGEN_CURRENT, currentValue));
|
||||
metrics.add(metric(DesktopUiMessages.PREGEN_OVERALL, overallValue));
|
||||
metrics.add(metric(DesktopUiMessages.PREGEN_THIRTY, thirtyValue));
|
||||
metrics.add(metric(DesktopUiMessages.PREGEN_SIXTY, sixtyValue));
|
||||
metrics.add(metric(DesktopUiMessages.PREGEN_ETA, etaValue));
|
||||
metrics.add(metric(DesktopUiMessages.PREGEN_ELAPSED, elapsedValue));
|
||||
metrics.add(metric(DesktopUiMessages.PREGEN_MEMORY_LABEL, memoryValue));
|
||||
metrics.add(metric(DesktopUiMessages.PREGEN_PRESSURE, pressureValue));
|
||||
JPanel method = panel(new BorderLayout(16, 0), SURFACE);
|
||||
method.add(methodLabel, BorderLayout.CENTER);
|
||||
method.add(failureLabel, BorderLayout.EAST);
|
||||
JPanel status = panel(new BorderLayout(0, 18), SURFACE);
|
||||
status.setBorder(BorderFactory.createEmptyBorder(18, 18, 16, 18));
|
||||
status.add(metrics, BorderLayout.CENTER);
|
||||
status.add(method, BorderLayout.SOUTH);
|
||||
JPanel footer = panel(new BorderLayout(0, 12), BACKGROUND);
|
||||
footer.add(legend(), BorderLayout.NORTH);
|
||||
footer.add(status, BorderLayout.CENTER);
|
||||
return footer;
|
||||
}
|
||||
|
||||
private JPanel legend() {
|
||||
JPanel legend = panel(new FlowLayout(FlowLayout.LEFT, 0, 0), BACKGROUND);
|
||||
legend.add(legendItem(DesktopUiMessages.PREGEN_WAITING, PregenMapPanel.WAITING));
|
||||
legend.add(legendItem(DesktopUiMessages.PREGEN_GENERATING, GENERATING));
|
||||
legend.add(legendItem(DesktopUiMessages.PREGEN_READY, GENERATED));
|
||||
legend.add(legendItem(DesktopUiMessages.PREGEN_EXISTING, EXISTS));
|
||||
legend.add(legendItem(DesktopUiMessages.PREGEN_NETWORK, NETWORK));
|
||||
legend.setToolTipText(text(DesktopUiMessages.PREGEN_TERRAIN_HINT));
|
||||
return legend;
|
||||
}
|
||||
|
||||
private JPanel legendItem(TextKey key, Color color) {
|
||||
JPanel item = panel(new FlowLayout(FlowLayout.LEFT, 6, 0), BACKGROUND);
|
||||
JPanel swatch = new JPanel();
|
||||
swatch.setBackground(color);
|
||||
swatch.setPreferredSize(new Dimension(10, 10));
|
||||
swatch.setBorder(BorderFactory.createLineBorder(BORDER));
|
||||
item.add(swatch);
|
||||
item.add(label(text(key), LABEL_FONT, MUTED));
|
||||
item.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 13));
|
||||
return item;
|
||||
}
|
||||
|
||||
private JPanel metric(TextKey title, JLabel value) {
|
||||
JPanel metric = panel(new BorderLayout(0, 5), SURFACE);
|
||||
metric.add(label(text(title), LABEL_FONT, MUTED), BorderLayout.NORTH);
|
||||
metric.add(value, BorderLayout.CENTER);
|
||||
return metric;
|
||||
}
|
||||
|
||||
private void installPauseControl() {
|
||||
pauseButton.setUI(new BasicButtonUI() {
|
||||
@Override
|
||||
protected void paintText(Graphics graphics, AbstractButton button, Rectangle bounds, String text) {
|
||||
if (button.isEnabled()) {
|
||||
super.paintText(graphics, button, bounds, text);
|
||||
return;
|
||||
}
|
||||
graphics.setColor(MUTED);
|
||||
BasicGraphicsUtils.drawStringUnderlineCharAt(graphics, text, button.getDisplayedMnemonicIndex(),
|
||||
bounds.x, bounds.y + graphics.getFontMetrics().getAscent());
|
||||
}
|
||||
});
|
||||
pauseButton.setBackground(FIELD);
|
||||
pauseButton.setForeground(TEXT);
|
||||
pauseButton.setFont(BODY_FONT);
|
||||
pauseButton.putClientProperty("html.disable", Boolean.TRUE);
|
||||
pauseButton.setFocusPainted(false);
|
||||
pauseButton.setPreferredSize(new Dimension(108, 46));
|
||||
setPauseBorder(false);
|
||||
pauseButton.addFocusListener(new FocusAdapter() {
|
||||
@Override
|
||||
public void focusGained(FocusEvent event) {
|
||||
setPauseBorder(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void focusLost(FocusEvent event) {
|
||||
setPauseBorder(false);
|
||||
}
|
||||
});
|
||||
pauseButton.addActionListener(event -> togglePause());
|
||||
getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_P, 0, true), "pause");
|
||||
getActionMap().put("pause", new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
togglePause();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setPauseBorder(boolean focused) {
|
||||
pauseButton.setBorder(BorderFactory.createCompoundBorder(
|
||||
BorderFactory.createLineBorder(focused ? ACCENT : BORDER, 2),
|
||||
BorderFactory.createEmptyBorder(8, 14, 8, 14)));
|
||||
}
|
||||
|
||||
private void togglePause() {
|
||||
if (onPause == null || !pauseButton.isEnabled()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
onPause.run();
|
||||
refresh();
|
||||
} catch (RuntimeException failure) {
|
||||
IrisLogging.reportError("Unable to change pregeneration pause state.", failure);
|
||||
failureLabel.setText(text(DesktopUiMessages.PREGEN_CONTROL_FAILED));
|
||||
}
|
||||
}
|
||||
|
||||
private void refresh() {
|
||||
if (disposed) {
|
||||
return;
|
||||
}
|
||||
PregenRenderSnapshot snapshot = source.renderSnapshot();
|
||||
if (!snapshot.equals(displayedSnapshot)) {
|
||||
updateStatus(snapshot);
|
||||
displayedSnapshot = snapshot;
|
||||
}
|
||||
if (map.flush()) {
|
||||
map.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateStatus(PregenRenderSnapshot snapshot) {
|
||||
PregeneratorJob.PregenProgress progress = snapshot.progress();
|
||||
boolean initializing = snapshot.phase() == PregenRenderSnapshot.Phase.INITIALIZING;
|
||||
boolean paused = snapshot.phase() == PregenRenderSnapshot.Phase.PAUSED;
|
||||
worldLabel.setText(progress.worldName() == null ? text(DesktopUiMessages.PREGEN_TITLE) : progress.worldName());
|
||||
phaseLabel.setText(text(switch (snapshot.phase()) {
|
||||
case INITIALIZING -> DesktopUiMessages.PREGEN_INITIALIZING;
|
||||
case GENERATING -> DesktopUiMessages.PREGEN_GENERATING;
|
||||
case PAUSED -> DesktopUiMessages.PREGEN_PAUSED;
|
||||
case SAVING -> DesktopUiMessages.PREGEN_SAVING;
|
||||
case STOPPING -> DesktopUiMessages.PREGEN_STOPPING;
|
||||
case COMPLETED -> DesktopUiMessages.PREGEN_COMPLETED;
|
||||
case ERROR -> DesktopUiMessages.PREGEN_ERROR;
|
||||
}));
|
||||
phaseLabel.setForeground(snapshot.phase() == PregenRenderSnapshot.Phase.ERROR ? ERROR : MUTED);
|
||||
countLabel.setText(text(DesktopUiMessages.PREGEN_PROGRESS,
|
||||
MessageArgument.trusted("generated", Form.f(progress.generated())),
|
||||
MessageArgument.trusted("total", Form.f(progress.totalChunks()))));
|
||||
percentLabel.setText(text(DesktopUiMessages.PREGEN_PERCENT,
|
||||
MessageArgument.trusted("percent", Form.pc(Math.max(0D, Math.min(1D, progress.percent() / 100D)), 1))));
|
||||
progressBar.setValue((int) Math.max(0D, Math.min(10_000D, progress.percent() * 100D)));
|
||||
pauseButton.setText(text(paused ? DesktopUiMessages.PREGEN_RESUME : DesktopUiMessages.PREGEN_PAUSE));
|
||||
pauseButton.setToolTipText(text(paused ? DesktopUiMessages.PREGEN_RESUME_HINT : DesktopUiMessages.PREGEN_PAUSE_HINT));
|
||||
pauseButton.setEnabled(onPause != null && switch (snapshot.phase()) {
|
||||
case GENERATING, PAUSED, SAVING -> true;
|
||||
default -> false;
|
||||
});
|
||||
currentValue.setText(initializing ? pending() : rate(progress.chunksPerSecond()));
|
||||
overallValue.setText(initializing ? pending() : rate(progress.overallChunksPerSecond()));
|
||||
thirtyValue.setText(initializing ? pending() : rate(progress.thirtySecondChunksPerSecond()));
|
||||
sixtyValue.setText(initializing ? pending() : rate(progress.sixtySecondChunksPerSecond()));
|
||||
etaValue.setText(initializing || paused || progress.eta() < 0
|
||||
|| (progress.eta() == 0 && progress.chunksRemaining() > 0)
|
||||
? pending() : Form.duration(progress.eta(), 2));
|
||||
elapsedValue.setText(initializing ? pending() : Form.duration(progress.elapsed(), 2));
|
||||
memoryValue.setText(snapshot.usedMemoryBytes() < 0 ? pending() : text(DesktopUiMessages.PREGEN_MEMORY_USAGE,
|
||||
MessageArgument.trusted("used", Form.memSize(snapshot.usedMemoryBytes(), 1)),
|
||||
MessageArgument.trusted("usage", Form.pc(snapshot.memoryUsage(), 0))));
|
||||
pressureValue.setText(text(DesktopUiMessages.PREGEN_PRESSURE_VALUE,
|
||||
MessageArgument.trusted("rate", Form.memSize(snapshot.allocationBytesPerSecond(), 0))));
|
||||
String method = progress.method() == null ? pending() : progress.method();
|
||||
if (snapshot.cached()) {
|
||||
method = text(DesktopUiMessages.PREGEN_CACHED, MessageArgument.untrusted("method", method));
|
||||
}
|
||||
methodLabel.setText(text(DesktopUiMessages.PREGEN_METHOD, MessageArgument.untrusted("method", method)));
|
||||
failureLabel.setText(progress.failed() > 0 ? text(DesktopUiMessages.PREGEN_FAILED,
|
||||
MessageArgument.trusted("count", Form.f(progress.failed()))) : "");
|
||||
failureLabel.setToolTipText(snapshot.failure());
|
||||
if (snapshot.failure() != null) {
|
||||
failureLabel.setText(text(DesktopUiMessages.PREGEN_ERROR_DETAILS));
|
||||
}
|
||||
}
|
||||
|
||||
private void setRenderingEnabled(boolean enabled) {
|
||||
renderingEnabled = enabled && !disposed;
|
||||
if (renderingEnabled) {
|
||||
refresh();
|
||||
repaintTimer.start();
|
||||
} else {
|
||||
repaintTimer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
private void disposeRenderer() {
|
||||
if (disposed) {
|
||||
return;
|
||||
@@ -127,79 +401,32 @@ public final class PregenRenderer extends JPanel implements KeyListener {
|
||||
renderingEnabled = false;
|
||||
frame = null;
|
||||
repaintTimer.stop();
|
||||
lock.lock();
|
||||
try {
|
||||
pending.clear();
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
imageGraphics.dispose();
|
||||
map.disposeMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics gx) {
|
||||
Graphics2D g = (Graphics2D) gx;
|
||||
Long2ObjectLinkedOpenHashMap<Color> batch;
|
||||
lock.lock();
|
||||
try {
|
||||
batch = pending;
|
||||
pending = new Long2ObjectLinkedOpenHashMap<>();
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
for (Long2ObjectMap.Entry<Color> entry : batch.long2ObjectEntrySet()) {
|
||||
try {
|
||||
long key = entry.getLongKey();
|
||||
draw((int) (key >> 32), (int) key, entry.getValue(), imageGraphics);
|
||||
} catch (Throwable e) {
|
||||
IrisLogging.reportError(e);
|
||||
}
|
||||
}
|
||||
|
||||
g.drawImage(image, 0, 0, getParent().getWidth(), getParent().getHeight(), (img, infoflags, x, y, width, height) -> true);
|
||||
g.setColor(Color.WHITE);
|
||||
g.setFont(new Font("Hevetica", Font.BOLD, 13));
|
||||
String[] prog = source.progress();
|
||||
int h = g.getFontMetrics().getHeight() + 5;
|
||||
int hh = 20;
|
||||
|
||||
if (source.paused()) {
|
||||
g.drawString(IrisLanguage.plain(DesktopUiMessages.PREGEN_PAUSED), 20, hh += h);
|
||||
g.drawString(IrisLanguage.plain(DesktopUiMessages.PREGEN_RESUME_HINT), 20, hh += h);
|
||||
} else {
|
||||
for (String i : prog) {
|
||||
g.drawString(i, 20, hh += h);
|
||||
}
|
||||
g.drawString(IrisLanguage.plain(DesktopUiMessages.PREGEN_PAUSE_HINT), 20, hh += h);
|
||||
}
|
||||
|
||||
private static JPanel panel(LayoutManager layout, Color background) {
|
||||
JPanel panel = new JPanel(layout);
|
||||
panel.setBackground(background);
|
||||
return panel;
|
||||
}
|
||||
|
||||
private void draw(int chunkX, int chunkZ, Color c, Graphics2D bg) {
|
||||
double pw = M.lerpInverse(source.min().getX(), source.max().getX(), chunkX);
|
||||
double ph = M.lerpInverse(source.min().getZ(), source.max().getZ(), chunkZ);
|
||||
double pwa = M.lerpInverse(source.min().getX(), source.max().getX(), chunkX + 1);
|
||||
double pha = M.lerpInverse(source.min().getZ(), source.max().getZ(), chunkZ + 1);
|
||||
int x = (int) M.lerp(0, res, pw);
|
||||
int z = (int) M.lerp(0, res, ph);
|
||||
int xa = (int) M.lerp(0, res, pwa);
|
||||
int za = (int) M.lerp(0, res, pha);
|
||||
bg.setColor(c);
|
||||
bg.fillRect(x, z, xa - x, za - z);
|
||||
private static JLabel label(String text, Font font, Color foreground) {
|
||||
JLabel label = new JLabel(text);
|
||||
label.putClientProperty("html.disable", Boolean.TRUE);
|
||||
label.setFont(font);
|
||||
label.setForeground(foreground);
|
||||
return label;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e) {
|
||||
private static String pending() {
|
||||
return text(DesktopUiMessages.PREGEN_METHOD_PENDING);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
private static String rate(double rate) {
|
||||
return text(DesktopUiMessages.PREGEN_RATE, MessageArgument.trusted("rate", Form.f(rate, 1)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e) {
|
||||
if (e.getKeyCode() == KeyEvent.VK_P && onPause != null) {
|
||||
onPause.run();
|
||||
}
|
||||
private static String text(TextKey key, MessageArgument... arguments) {
|
||||
return IrisLanguage.plain(key, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,11 +34,8 @@ import art.arcane.iris.core.pregenerator.PregenTask;
|
||||
import art.arcane.iris.core.pregenerator.PregeneratorMethod;
|
||||
import art.arcane.iris.engine.framework.Engine;
|
||||
import art.arcane.iris.engine.history.SavedBiomeUnavailableException;
|
||||
import art.arcane.volmlib.util.format.Form;
|
||||
import art.arcane.volmlib.util.format.MemoryMonitor;
|
||||
import art.arcane.volmlib.util.mantle.runtime.Mantle;
|
||||
import art.arcane.volmlib.util.localization.MessageArgument;
|
||||
import art.arcane.volmlib.util.math.Position2;
|
||||
import art.arcane.iris.util.common.scheduling.J;
|
||||
|
||||
import java.awt.Color;
|
||||
@@ -59,14 +56,6 @@ public class PregeneratorJob implements PregenListener, PregenRenderSource {
|
||||
// 60s permit drain + 120s flush + plate reclaim), or a routine drain trips the deadline
|
||||
// and aborts the engine shutdown sequence mid-teardown.
|
||||
private static final long WORLD_SHUTDOWN_TIMEOUT_MILLIS = 200_000L;
|
||||
private static final Color COLOR_EXISTS = parseColor("#4d7d5b");
|
||||
private static final Color COLOR_BLACK = parseColor("#4d7d5b");
|
||||
private static final Color COLOR_MANTLE = parseColor("#3c2773");
|
||||
private static final Color COLOR_GENERATING = parseColor("#66967f");
|
||||
private static final Color COLOR_NETWORK = parseColor("#a863c2");
|
||||
private static final Color COLOR_NETWORK_GENERATING = parseColor("#836b8c");
|
||||
private static final Color COLOR_GENERATED = parseColor("#65c295");
|
||||
private static final Color COLOR_CLEANED = parseColor("#34eb93");
|
||||
private static final AtomicReference<PregeneratorJob> instance = new AtomicReference<>();
|
||||
private final MemoryMonitor monitor;
|
||||
private final PregenTask task;
|
||||
@@ -75,14 +64,17 @@ public class PregeneratorJob implements PregenListener, PregenRenderSource {
|
||||
private final List<Consumer<Double>> onProgress = new CopyOnWriteArrayList<>();
|
||||
private final List<Runnable> whenDone = new CopyOnWriteArrayList<>();
|
||||
private final IrisPregenerator pregenerator;
|
||||
private final Position2 min;
|
||||
private final Position2 max;
|
||||
private final PregenRenderSnapshot.Bounds bounds;
|
||||
private final Engine engine;
|
||||
private final ExecutorService service;
|
||||
private final Thread worker;
|
||||
private final PregenPhaseTracker apiPhases = new PregenPhaseTracker();
|
||||
private PregenRenderer renderer;
|
||||
private String[] info;
|
||||
private volatile PregenRenderer renderer;
|
||||
private volatile PregenRenderSnapshot renderSnapshot;
|
||||
private volatile boolean closed;
|
||||
private volatile boolean finished;
|
||||
private volatile String failure;
|
||||
private boolean lastCached;
|
||||
private volatile double lastChunksPerSecond = 0D;
|
||||
private volatile double lastOverallChunksPerSecond = 0D;
|
||||
private volatile double lastThirtySecondChunksPerSecond = 0D;
|
||||
@@ -102,11 +94,13 @@ public class PregeneratorJob implements PregenListener, PregenRenderSource {
|
||||
monitor = new MemoryMonitor(50);
|
||||
saving = new AtomicBoolean(false);
|
||||
stopRequested = new AtomicBoolean(false);
|
||||
info = new String[]{IrisLanguage.plain(DesktopUiMessages.PREGEN_INITIALIZING)};
|
||||
this.task = task;
|
||||
this.pregenerator = new IrisPregenerator(task, method, this);
|
||||
max = new Position2(Integer.MIN_VALUE, Integer.MIN_VALUE);
|
||||
min = new Position2(Integer.MAX_VALUE, Integer.MAX_VALUE);
|
||||
int[] chunkBounds = task.chunkBounds();
|
||||
bounds = new PregenRenderSnapshot.Bounds(chunkBounds[0], chunkBounds[1], chunkBounds[2], chunkBounds[3]);
|
||||
lastTotalChunks = task.chunkCount();
|
||||
lastChunksRemaining = lastTotalChunks;
|
||||
publishView(PregenRenderSnapshot.Phase.INITIALIZING);
|
||||
service = new ThreadPoolExecutor(
|
||||
1,
|
||||
1,
|
||||
@@ -142,7 +136,7 @@ public class PregeneratorJob implements PregenListener, PregenRenderSource {
|
||||
// teardown with the new job's generation. Replacement goes through
|
||||
// shutdownAndWait first, matching the modded adapter's rejection contract.
|
||||
if (!instance.compareAndSet(null, this)) {
|
||||
monitor.close();
|
||||
close();
|
||||
service.shutdown();
|
||||
throw new IllegalStateException("An Iris pregeneration job is already running; stop it first.");
|
||||
}
|
||||
@@ -152,7 +146,7 @@ public class PregeneratorJob implements PregenListener, PregenRenderSource {
|
||||
// Un-publish: a worker that never started can never run onClose(), so nothing
|
||||
// else would ever clear this instance via the normal path.
|
||||
instance.compareAndSet(this, null);
|
||||
monitor.close();
|
||||
close();
|
||||
service.shutdown();
|
||||
throw startFailure;
|
||||
}
|
||||
@@ -170,23 +164,14 @@ public class PregeneratorJob implements PregenListener, PregenRenderSource {
|
||||
onClose();
|
||||
return;
|
||||
}
|
||||
computeBounds();
|
||||
pregenerator.start();
|
||||
} catch (Throwable failure) {
|
||||
this.failure = failure.toString();
|
||||
IrisLogging.reportError("Pregen startup failed.", failure);
|
||||
onClose();
|
||||
}
|
||||
}
|
||||
|
||||
private void computeBounds() {
|
||||
task.iterateAllChunks((xx, zz) -> {
|
||||
min.setX(Math.min(xx, min.getX()));
|
||||
min.setZ(Math.min(zz, min.getZ()));
|
||||
max.setX(Math.max(xx, max.getX()));
|
||||
max.setZ(Math.max(zz, max.getZ()));
|
||||
});
|
||||
}
|
||||
|
||||
public static boolean shutdownInstance() {
|
||||
PregeneratorJob inst = instance.get();
|
||||
if (inst == null) {
|
||||
@@ -245,15 +230,20 @@ public class PregeneratorJob implements PregenListener, PregenRenderSource {
|
||||
|
||||
public static boolean pauseResume() {
|
||||
PregeneratorJob inst = instance.get();
|
||||
if (inst == null) {
|
||||
return inst != null && inst.togglePause();
|
||||
}
|
||||
|
||||
synchronized boolean togglePause() {
|
||||
if (finished || stopRequested.get() || failure != null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isPaused()) {
|
||||
inst.pregenerator.resume();
|
||||
if (paused()) {
|
||||
pregenerator.resume();
|
||||
} else {
|
||||
inst.pregenerator.pause();
|
||||
pregenerator.pause();
|
||||
}
|
||||
publishView(paused() ? PregenRenderSnapshot.Phase.PAUSED : PregenRenderSnapshot.Phase.GENERATING);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -287,7 +277,7 @@ public class PregeneratorJob implements PregenListener, PregenRenderSource {
|
||||
return inst == null ? null : inst.snapshot();
|
||||
}
|
||||
|
||||
public PregenProgress snapshot() {
|
||||
public synchronized PregenProgress snapshot() {
|
||||
double percent = lastTotalChunks <= 0 ? 0D : ((double) lastGenerated / (double) lastTotalChunks) * 100D;
|
||||
return new PregenProgress(
|
||||
percent,
|
||||
@@ -330,18 +320,6 @@ public class PregeneratorJob implements PregenListener, PregenRenderSource {
|
||||
return worldIdentity.equals(engine.getWorld().identity());
|
||||
}
|
||||
|
||||
private static Color parseColor(String c) {
|
||||
String v = (c.startsWith("#") ? c : "#" + c).trim();
|
||||
try {
|
||||
return Color.decode(v);
|
||||
} catch (Throwable e) {
|
||||
IrisLogging.reportError(e);
|
||||
IrisLogging.error("Error Parsing 'color', (" + c + ")");
|
||||
}
|
||||
|
||||
return Color.RED;
|
||||
}
|
||||
|
||||
public Mantle getMantle() {
|
||||
return pregenerator.getMantle();
|
||||
}
|
||||
@@ -357,16 +335,17 @@ public class PregeneratorJob implements PregenListener, PregenRenderSource {
|
||||
}
|
||||
|
||||
public void drawRegion(int x, int z, Color color) {
|
||||
J.a(() -> task.iterateChunks(x, z, (xx, zz) -> {
|
||||
draw(xx, zz, color);
|
||||
J.sleep(3);
|
||||
}));
|
||||
PregenRenderer activeRenderer = renderer;
|
||||
if (activeRenderer == null || closed) {
|
||||
return;
|
||||
}
|
||||
task.iterateChunks(x, z, (chunkX, chunkZ) -> activeRenderer.submit(chunkX, chunkZ, color));
|
||||
}
|
||||
|
||||
public void draw(int x, int z, Color color) {
|
||||
try {
|
||||
PregenRenderer activeRenderer = renderer;
|
||||
if (activeRenderer != null && activeRenderer.isVisibleFrame()) {
|
||||
if (activeRenderer != null) {
|
||||
activeRenderer.submit(x, z, color);
|
||||
}
|
||||
} catch (Throwable error) {
|
||||
@@ -384,11 +363,13 @@ public class PregeneratorJob implements PregenListener, PregenRenderSource {
|
||||
if (!stopRequested.compareAndSet(false, true)) {
|
||||
return;
|
||||
}
|
||||
publishView(PregenRenderSnapshot.Phase.STOPPING);
|
||||
pregenerator.close();
|
||||
worker.interrupt();
|
||||
}
|
||||
|
||||
public void close() {
|
||||
closed = true;
|
||||
try {
|
||||
monitor.close();
|
||||
PregenRenderer activeRenderer = renderer;
|
||||
@@ -403,8 +384,15 @@ public class PregeneratorJob implements PregenListener, PregenRenderSource {
|
||||
|
||||
public void open() {
|
||||
EventQueue.invokeLater(() -> {
|
||||
if (closed) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
renderer = PregenRenderer.open(IrisLanguage.plain(DesktopUiMessages.PREGEN_TITLE), this, PregeneratorJob::pauseResume);
|
||||
PregenRenderer opened = PregenRenderer.open(IrisLanguage.plain(DesktopUiMessages.PREGEN_TITLE), this, this::togglePause);
|
||||
renderer = opened;
|
||||
if (closed) {
|
||||
opened.close();
|
||||
}
|
||||
} catch (Throwable error) {
|
||||
IrisLogging.reportError(error);
|
||||
IrisLogging.error("Error opening pregen gui");
|
||||
@@ -415,45 +403,21 @@ public class PregeneratorJob implements PregenListener, PregenRenderSource {
|
||||
@Override
|
||||
public void onTick(double chunksPerSecond, double chunksPerMinute, double regionsPerMinute, double percent, long generated, long totalChunks, long chunksRemaining, long eta, long elapsed, String method, boolean cached) {
|
||||
PregenRates rateSnapshot = pregenerator.getRates();
|
||||
lastChunksPerSecond = chunksPerSecond;
|
||||
lastOverallChunksPerSecond = rateSnapshot.overall();
|
||||
lastThirtySecondChunksPerSecond = rateSnapshot.thirtySecond();
|
||||
lastSixtySecondChunksPerSecond = rateSnapshot.sixtySecond();
|
||||
lastChunksRemaining = chunksRemaining;
|
||||
lastGenerated = generated;
|
||||
lastTotalChunks = totalChunks;
|
||||
lastEta = eta;
|
||||
lastElapsed = elapsed;
|
||||
lastMethod = method;
|
||||
|
||||
info = new String[]{
|
||||
IrisLanguage.plain(
|
||||
paused() ? DesktopUiMessages.PREGEN_PROGRESS_PAUSED
|
||||
: saving.getAndSet(false) ? DesktopUiMessages.PREGEN_PROGRESS_SAVING : DesktopUiMessages.PREGEN_PROGRESS_GENERATING,
|
||||
MessageArgument.trusted("generated", Form.f(generated)),
|
||||
MessageArgument.trusted("total", Form.f(totalChunks)),
|
||||
MessageArgument.trusted("percent", Form.pc(percent, 0))
|
||||
),
|
||||
IrisLanguage.plain(
|
||||
cached ? DesktopUiMessages.PREGEN_SPEED_CACHED : DesktopUiMessages.PREGEN_SPEED,
|
||||
MessageArgument.trusted("overall", Form.f(rateSnapshot.overall(), 1)),
|
||||
MessageArgument.trusted("tenSecond", Form.f(rateSnapshot.tenSecond(), 1)),
|
||||
MessageArgument.trusted("thirtySecond", Form.f(rateSnapshot.thirtySecond(), 1)),
|
||||
MessageArgument.trusted("sixtySecond", Form.f(rateSnapshot.sixtySecond(), 1))
|
||||
),
|
||||
IrisLanguage.plain(
|
||||
DesktopUiMessages.PREGEN_TIME,
|
||||
MessageArgument.trusted("remaining", Form.duration(eta, 2)),
|
||||
MessageArgument.trusted("elapsed", Form.duration(elapsed, 2))
|
||||
),
|
||||
IrisLanguage.plain(DesktopUiMessages.PREGEN_METHOD, MessageArgument.untrusted("method", String.valueOf(method))),
|
||||
IrisLanguage.plain(
|
||||
DesktopUiMessages.PREGEN_MEMORY,
|
||||
MessageArgument.trusted("used", Form.memSize(monitor.getUsedBytes(), 2)),
|
||||
MessageArgument.trusted("usage", Form.pc(monitor.getUsagePercent(), 0)),
|
||||
MessageArgument.trusted("pressure", Form.memSize(monitor.getPressure(), 0))
|
||||
)
|
||||
};
|
||||
synchronized (this) {
|
||||
lastChunksPerSecond = chunksPerSecond;
|
||||
lastOverallChunksPerSecond = rateSnapshot.overall();
|
||||
lastThirtySecondChunksPerSecond = rateSnapshot.thirtySecond();
|
||||
lastSixtySecondChunksPerSecond = rateSnapshot.sixtySecond();
|
||||
lastChunksRemaining = chunksRemaining;
|
||||
lastGenerated = generated;
|
||||
lastTotalChunks = totalChunks;
|
||||
lastEta = eta;
|
||||
lastElapsed = elapsed;
|
||||
lastMethod = method;
|
||||
lastCached = cached;
|
||||
publishView(paused() ? PregenRenderSnapshot.Phase.PAUSED
|
||||
: saving.getAndSet(false) ? PregenRenderSnapshot.Phase.SAVING : PregenRenderSnapshot.Phase.GENERATING);
|
||||
}
|
||||
|
||||
for (Consumer<Double> i : onProgress) {
|
||||
i.accept(percent);
|
||||
@@ -488,12 +452,12 @@ public class PregeneratorJob implements PregenListener, PregenRenderSource {
|
||||
|
||||
@Override
|
||||
public void onChunkGenerating(int x, int z) {
|
||||
draw(x, z, COLOR_GENERATING);
|
||||
draw(x, z, PregenRenderer.GENERATING);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChunkGenerated(int x, int z, boolean cached) {
|
||||
drawChunkPreview(x, z, COLOR_GENERATED);
|
||||
drawChunkPreview(x, z, PregenRenderer.GENERATED);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -528,7 +492,7 @@ public class PregeneratorJob implements PregenListener, PregenRenderSource {
|
||||
|
||||
@Override
|
||||
public void onNetworkStarted(int x, int z) {
|
||||
drawRegion(x, z, COLOR_NETWORK);
|
||||
drawRegion(x, z, PregenRenderer.NETWORK);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -543,18 +507,25 @@ public class PregeneratorJob implements PregenListener, PregenRenderSource {
|
||||
|
||||
@Override
|
||||
public void onNetworkGeneratedChunk(int x, int z) {
|
||||
draw(x, z, COLOR_NETWORK_GENERATING);
|
||||
draw(x, z, PregenRenderer.NETWORK_GENERATING);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNetworkDownloaded(int x, int z) {
|
||||
drawRegion(x, z, COLOR_NETWORK);
|
||||
drawRegion(x, z, PregenRenderer.NETWORK);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose() {
|
||||
finished = true;
|
||||
dispatchApiPhases(apiPhases.onClose(reachedTotal()));
|
||||
close();
|
||||
publishView(failure != null ? PregenRenderSnapshot.Phase.ERROR
|
||||
: reachedTotal() ? PregenRenderSnapshot.Phase.COMPLETED : PregenRenderSnapshot.Phase.STOPPING);
|
||||
if (failure == null) {
|
||||
close();
|
||||
} else {
|
||||
monitor.close();
|
||||
}
|
||||
instance.compareAndSet(this, null);
|
||||
whenDone.forEach(Runnable::run);
|
||||
service.shutdownNow();
|
||||
@@ -563,40 +534,47 @@ public class PregeneratorJob implements PregenListener, PregenRenderSource {
|
||||
@Override
|
||||
public void onSaving() {
|
||||
saving.set(true);
|
||||
publishView(PregenRenderSnapshot.Phase.SAVING);
|
||||
dispatchApiPhases(apiPhases.onSaving());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChunkExistsInRegionGen(int x, int z) {
|
||||
drawChunkPreview(x, z, COLOR_EXISTS);
|
||||
drawChunkPreview(x, z, PregenRenderer.EXISTS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Position2 max() {
|
||||
return max;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Position2 min() {
|
||||
return min;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean paused() {
|
||||
return pregenerator.paused();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] progress() {
|
||||
return info;
|
||||
public PregenRenderSnapshot renderSnapshot() {
|
||||
return renderSnapshot;
|
||||
}
|
||||
|
||||
private synchronized void publishView(PregenRenderSnapshot.Phase phase) {
|
||||
if (failure != null) {
|
||||
phase = PregenRenderSnapshot.Phase.ERROR;
|
||||
} else if (finished) {
|
||||
phase = reachedTotal() ? PregenRenderSnapshot.Phase.COMPLETED : PregenRenderSnapshot.Phase.STOPPING;
|
||||
} else if (stopRequested.get()) {
|
||||
phase = PregenRenderSnapshot.Phase.STOPPING;
|
||||
} else if (paused()) {
|
||||
phase = PregenRenderSnapshot.Phase.PAUSED;
|
||||
}
|
||||
renderSnapshot = new PregenRenderSnapshot(bounds, snapshot(), phase, lastCached,
|
||||
monitor.getUsedBytes(), monitor.getUsagePercent(), monitor.getPressure(), failure);
|
||||
}
|
||||
|
||||
private void drawChunkPreview(int x, int z, Color statusColor) {
|
||||
PregenRenderer activeRenderer = renderer;
|
||||
if (activeRenderer == null || !activeRenderer.isVisibleFrame() || service.isShutdown()) {
|
||||
if (activeRenderer == null) {
|
||||
return;
|
||||
}
|
||||
draw(x, z, statusColor);
|
||||
if (!activeRenderer.isVisibleFrame() || service.isShutdown()) {
|
||||
return;
|
||||
}
|
||||
if (engine != null) {
|
||||
service.execute(() -> renderChunkPreview(x, z));
|
||||
}
|
||||
|
||||
@@ -79,20 +79,44 @@ public final class DesktopUiMessages {
|
||||
public static final TextKey NOISE_CATEGORY_SIERPINSKI = TextKey.of("iris.desktop.noise.category.sierpinski", "Sierpinski");
|
||||
public static final TextKey NOISE_CATEGORY_UTILITY = TextKey.of("iris.desktop.noise.category.utility", "Utility");
|
||||
public static final TextKey NOISE_CATEGORY_OTHER = TextKey.of("iris.desktop.noise.category.other", "Other");
|
||||
public static final TextKey PREGEN_INITIALIZING = TextKey.of("iris.desktop.pregen.initializing", "Initializing...");
|
||||
public static final TextKey PREGEN_TITLE = TextKey.of("iris.desktop.pregen.title", "Pregen View");
|
||||
public static final TextKey PREGEN_INITIALIZING = TextKey.of("iris.desktop.pregen.initializing", "Preparing generation");
|
||||
public static final TextKey PREGEN_TITLE = TextKey.of("iris.desktop.pregen.title", "Pregeneration");
|
||||
public static final TextKey PREGEN_METHOD_PENDING = TextKey.of("iris.desktop.pregen.method_pending", "Pending");
|
||||
public static final TextKey PREGEN_PAUSED = TextKey.of("iris.desktop.pregen.paused", "PAUSED");
|
||||
public static final TextKey PREGEN_PAUSED = TextKey.of("iris.desktop.pregen.paused", "Paused");
|
||||
public static final TextKey PREGEN_RESUME_HINT = TextKey.of("iris.desktop.pregen.resume_hint", "Press P to resume");
|
||||
public static final TextKey PREGEN_PAUSE_HINT = TextKey.of("iris.desktop.pregen.pause_hint", "Press P to pause");
|
||||
public static final TextKey PREGEN_PROGRESS_PAUSED = TextKey.of("iris.desktop.pregen.progress_paused", "PAUSED {generated} of {total} ({percent} complete)");
|
||||
public static final TextKey PREGEN_PROGRESS_SAVING = TextKey.of("iris.desktop.pregen.progress_saving", "Saving... {generated} of {total} ({percent} complete)");
|
||||
public static final TextKey PREGEN_PROGRESS_GENERATING = TextKey.of("iris.desktop.pregen.progress_generating", "Generating {generated} of {total} ({percent} complete)");
|
||||
public static final TextKey PREGEN_SPEED = TextKey.of("iris.desktop.pregen.speed", "Speed: overall {overall}, 10s {tenSecond}, 30s {thirtySecond}, 60s {sixtySecond} chunks/s");
|
||||
public static final TextKey PREGEN_SPEED_CACHED = TextKey.of("iris.desktop.pregen.speed_cached", "Speed (cached): overall {overall}, 10s {tenSecond}, 30s {thirtySecond}, 60s {sixtySecond} chunks/s");
|
||||
public static final TextKey PREGEN_TIME = TextKey.of("iris.desktop.pregen.time", "{remaining} remaining ({elapsed} elapsed)");
|
||||
public static final TextKey PREGEN_METHOD = TextKey.of("iris.desktop.pregen.method", "Generation method: {method}");
|
||||
public static final TextKey PREGEN_MEMORY = TextKey.of("iris.desktop.pregen.memory", "Memory: {used} ({usage}) Pressure: {pressure}/s");
|
||||
public static final TextKey PREGEN_PAUSE = TextKey.of("iris.desktop.pregen.pause", "Pause");
|
||||
public static final TextKey PREGEN_RESUME = TextKey.of("iris.desktop.pregen.resume", "Resume");
|
||||
public static final TextKey PREGEN_GENERATING = TextKey.of("iris.desktop.pregen.generating", "Generating");
|
||||
public static final TextKey PREGEN_SAVING = TextKey.of("iris.desktop.pregen.saving", "Saving");
|
||||
public static final TextKey PREGEN_STOPPING = TextKey.of("iris.desktop.pregen.stopping", "Stopping");
|
||||
public static final TextKey PREGEN_COMPLETED = TextKey.of("iris.desktop.pregen.completed", "Complete");
|
||||
public static final TextKey PREGEN_ERROR = TextKey.of("iris.desktop.pregen.error", "Generation failed");
|
||||
public static final TextKey PREGEN_CONTROL_FAILED = TextKey.of("iris.desktop.pregen.control_failed", "Pause control failed · see server log");
|
||||
public static final TextKey PREGEN_ERROR_DETAILS = TextKey.of("iris.desktop.pregen.error_details", "See server log for details");
|
||||
public static final TextKey PREGEN_PROGRESS = TextKey.of("iris.desktop.pregen.progress", "{generated} / {total} chunks");
|
||||
public static final TextKey PREGEN_PERCENT = TextKey.of("iris.desktop.pregen.percent", "{percent} complete");
|
||||
public static final TextKey PREGEN_CURRENT = TextKey.of("iris.desktop.pregen.current", "Current · 10 s");
|
||||
public static final TextKey PREGEN_OVERALL = TextKey.of("iris.desktop.pregen.overall", "Overall");
|
||||
public static final TextKey PREGEN_THIRTY = TextKey.of("iris.desktop.pregen.thirty", "30 s average");
|
||||
public static final TextKey PREGEN_SIXTY = TextKey.of("iris.desktop.pregen.sixty", "60 s average");
|
||||
public static final TextKey PREGEN_RATE = TextKey.of("iris.desktop.pregen.rate", "{rate} chunks/s");
|
||||
public static final TextKey PREGEN_ETA = TextKey.of("iris.desktop.pregen.eta", "Remaining");
|
||||
public static final TextKey PREGEN_ELAPSED = TextKey.of("iris.desktop.pregen.elapsed", "Elapsed");
|
||||
public static final TextKey PREGEN_MEMORY_LABEL = TextKey.of("iris.desktop.pregen.memory_label", "Memory");
|
||||
public static final TextKey PREGEN_MEMORY_USAGE = TextKey.of("iris.desktop.pregen.memory_usage", "{used} · {usage}");
|
||||
public static final TextKey PREGEN_PRESSURE = TextKey.of("iris.desktop.pregen.pressure", "Allocation");
|
||||
public static final TextKey PREGEN_PRESSURE_VALUE = TextKey.of("iris.desktop.pregen.pressure_value", "{rate}/s");
|
||||
public static final TextKey PREGEN_METHOD = TextKey.of("iris.desktop.pregen.method", "Method: {method}");
|
||||
public static final TextKey PREGEN_CACHED = TextKey.of("iris.desktop.pregen.cached", "{method} · cached");
|
||||
public static final TextKey PREGEN_FAILED = TextKey.of("iris.desktop.pregen.failed", "{count} failed · see server log");
|
||||
public static final TextKey PREGEN_MAP = TextKey.of("iris.desktop.pregen.map", "Generation map");
|
||||
public static final TextKey PREGEN_BOUNDS = TextKey.of("iris.desktop.pregen.bounds", "Chunks X {minX} to {maxX} · Z {minZ} to {maxZ}");
|
||||
public static final TextKey PREGEN_WAITING = TextKey.of("iris.desktop.pregen.waiting", "Waiting");
|
||||
public static final TextKey PREGEN_READY = TextKey.of("iris.desktop.pregen.ready", "Ready");
|
||||
public static final TextKey PREGEN_EXISTING = TextKey.of("iris.desktop.pregen.existing", "Existing");
|
||||
public static final TextKey PREGEN_NETWORK = TextKey.of("iris.desktop.pregen.network", "Network");
|
||||
public static final TextKey PREGEN_TERRAIN_HINT = TextKey.of("iris.desktop.pregen.terrain_hint", "Finished chunks show terrain colors");
|
||||
public static final TextKey IMAGEMAP_TITLE = TextKey.of("iris.desktop.imagemap.title", "Image Map Studio");
|
||||
public static final TextKey IMAGEMAP_PRESET = TextKey.of("iris.desktop.imagemap.preset", "Preset:");
|
||||
public static final TextKey IMAGEMAP_LOAD = TextKey.of("iris.desktop.imagemap.load", "Load");
|
||||
@@ -179,10 +203,17 @@ public final class DesktopUiMessages {
|
||||
NOISE_CATEGORY_CELLULAR, NOISE_CATEGORY_IRIS, NOISE_CATEGORY_CLOVER, NOISE_CATEGORY_HEXAGON,
|
||||
NOISE_CATEGORY_VASCULAR, NOISE_CATEGORY_GLOBE, NOISE_CATEGORY_CUBIC, NOISE_CATEGORY_FRACTAL,
|
||||
NOISE_CATEGORY_STATIC, NOISE_CATEGORY_NOWHERE, NOISE_CATEGORY_SIERPINSKI,
|
||||
NOISE_CATEGORY_UTILITY, NOISE_CATEGORY_OTHER, PREGEN_INITIALIZING, PREGEN_TITLE,
|
||||
PREGEN_METHOD_PENDING, PREGEN_PAUSED, PREGEN_RESUME_HINT, PREGEN_PAUSE_HINT,
|
||||
PREGEN_PROGRESS_PAUSED, PREGEN_PROGRESS_SAVING, PREGEN_PROGRESS_GENERATING, PREGEN_SPEED,
|
||||
PREGEN_SPEED_CACHED, PREGEN_TIME, PREGEN_METHOD, PREGEN_MEMORY,
|
||||
NOISE_CATEGORY_UTILITY, NOISE_CATEGORY_OTHER,
|
||||
PREGEN_INITIALIZING, PREGEN_TITLE, PREGEN_METHOD_PENDING, PREGEN_PAUSED,
|
||||
PREGEN_RESUME_HINT, PREGEN_PAUSE_HINT, PREGEN_PAUSE, PREGEN_RESUME,
|
||||
PREGEN_GENERATING, PREGEN_SAVING, PREGEN_STOPPING, PREGEN_COMPLETED,
|
||||
PREGEN_ERROR, PREGEN_CONTROL_FAILED, PREGEN_ERROR_DETAILS, PREGEN_PROGRESS,
|
||||
PREGEN_PERCENT, PREGEN_CURRENT, PREGEN_OVERALL, PREGEN_THIRTY,
|
||||
PREGEN_SIXTY, PREGEN_RATE, PREGEN_ETA, PREGEN_ELAPSED,
|
||||
PREGEN_MEMORY_LABEL, PREGEN_MEMORY_USAGE, PREGEN_PRESSURE, PREGEN_PRESSURE_VALUE,
|
||||
PREGEN_METHOD, PREGEN_CACHED, PREGEN_FAILED, PREGEN_MAP,
|
||||
PREGEN_BOUNDS, PREGEN_WAITING, PREGEN_READY, PREGEN_EXISTING,
|
||||
PREGEN_NETWORK, PREGEN_TERRAIN_HINT,
|
||||
IMAGEMAP_TITLE, IMAGEMAP_PRESET, IMAGEMAP_LOAD, IMAGEMAP_IMPORT_PNG,
|
||||
IMAGEMAP_REPLACE_PNG, IMAGEMAP_PREVIEW, IMAGEMAP_EXPORT, IMAGEMAP_METADATA,
|
||||
IMAGEMAP_RESOURCE, IMAGEMAP_COORDINATES, IMAGEMAP_BINDING_KEY, IMAGEMAP_MAP_KEY,
|
||||
|
||||
@@ -215,6 +215,11 @@ public class PregenTask {
|
||||
return new int[]{bound.minX(), bound.minZ(), bound.maxX(), bound.maxZ()};
|
||||
}
|
||||
|
||||
public int[] chunkBounds() {
|
||||
Bound bound = bounds.chunk();
|
||||
return new int[]{bound.minX(), bound.minZ(), bound.maxX(), bound.maxZ()};
|
||||
}
|
||||
|
||||
public long chunkCount() {
|
||||
Bound bound = bounds.chunk();
|
||||
return (long) bound.sizeX() * bound.sizeZ();
|
||||
|
||||
@@ -992,6 +992,10 @@ public class IrisEngine implements Engine {
|
||||
}
|
||||
|
||||
public Optional<GenerationHistoryRuntimeRouter> getGenerationHistoryRuntimeRouter() {
|
||||
GenerationHistoryRuntimeRouter router = generationHistoryRuntimeRouter;
|
||||
if (router != null) {
|
||||
return Optional.of(router);
|
||||
}
|
||||
synchronized (generationHistoryRuntimeRouterLock) {
|
||||
return Optional.ofNullable(generationHistoryRuntimeRouter);
|
||||
}
|
||||
@@ -1001,7 +1005,10 @@ public class IrisEngine implements Engine {
|
||||
int blockX,
|
||||
int blockZ
|
||||
) throws IOException {
|
||||
GenerationHistoryRuntimeRouter router;
|
||||
GenerationHistoryRuntimeRouter router = generationHistoryRuntimeRouter;
|
||||
if (router != null) {
|
||||
return router.openCoordinateScope(blockX, blockZ);
|
||||
}
|
||||
synchronized (generationHistoryRuntimeRouterLock) {
|
||||
router = generationHistoryRuntimeRouter;
|
||||
if (router == null && generationHistoryRoutingRequired) {
|
||||
|
||||
@@ -1442,14 +1442,7 @@
|
||||
"iris.desktop.pregen.paused": "pausiert",
|
||||
"iris.desktop.pregen.resume_hint": "P drücken, um wieder aufzunehmen",
|
||||
"iris.desktop.pregen.pause_hint": "P drücken, um zu pausieren",
|
||||
"iris.desktop.pregen.progress_paused": "pausiert {generated} von {total} ({percent} abgeschlossen)",
|
||||
"iris.desktop.pregen.progress_saving": "Speichern... {generated} von {total} ({percent} abgeschlossen)",
|
||||
"iris.desktop.pregen.progress_generating": "{generated} von {total} werden generiert ({percent} abgeschlossen)",
|
||||
"iris.desktop.pregen.speed": "Geschwindigkeit: {overall} overall, {tenSecond} 10s, {thirtySecond} 30s, {sixtySecond} 60s chunks/s",
|
||||
"iris.desktop.pregen.speed_cached": "Geschwindigkeit: zwischengespeichert {overall} overall, {tenSecond} 10s, {thirtySecond} 30s, {sixtySecond} 60s chunks/s",
|
||||
"iris.desktop.pregen.time": "{remaining} verbleibend ({elapsed} abgelaufen)",
|
||||
"iris.desktop.pregen.method": "Erzeugungsmethode: {method}",
|
||||
"iris.desktop.pregen.memory": "Speicher: {used} ({usage}) Druck: {pressure}/s",
|
||||
"iris.modded.help.entry.command.what.here": "Inspect the Iris biome, region, cave biome, surface and chunk at your position",
|
||||
"iris.modded.help.entry.command.what.biome": "Inspect the Iris biome, configured derivative and registered native biome",
|
||||
"iris.modded.help.entry.command.what.region": "Inspect the Iris region at your current chunk",
|
||||
@@ -1570,6 +1563,37 @@
|
||||
"iris.modded.moddedpackcommands.compat_header": "Pack '{pack}': Inhalte in Minecraft {version} nicht verfügbar",
|
||||
"iris.modded.moddedpackcommands.compat_none": "Pack '{pack}' verwendet keine Inhalte, die in Minecraft {version} fehlen.",
|
||||
"iris.modded.moddedpackcommands.compat_remedy": "Aktualisiere den Server auf ein neueres Minecraft, um diese Inhalte wiederherzustellen, oder deklariere Ersatzwerte (Dimension blockFallbacks, Block backup).",
|
||||
"iris.modded.help.entry.command.compat_content": "Inhalte anzeigen, die in dieser Minecraft-Version nicht generiert werden können"
|
||||
"iris.modded.help.entry.command.compat_content": "Inhalte anzeigen, die in dieser Minecraft-Version nicht generiert werden können",
|
||||
"iris.desktop.pregen.pause": "Pausieren",
|
||||
"iris.desktop.pregen.resume": "Fortsetzen",
|
||||
"iris.desktop.pregen.generating": "Generierung",
|
||||
"iris.desktop.pregen.saving": "Speichern",
|
||||
"iris.desktop.pregen.stopping": "Wird beendet",
|
||||
"iris.desktop.pregen.completed": "Abgeschlossen",
|
||||
"iris.desktop.pregen.error": "Generierung fehlgeschlagen",
|
||||
"iris.desktop.pregen.control_failed": "Pause fehlgeschlagen · siehe Serverprotokoll",
|
||||
"iris.desktop.pregen.error_details": "Details im Serverprotokoll",
|
||||
"iris.desktop.pregen.progress": "{generated} / {total} Chunks",
|
||||
"iris.desktop.pregen.percent": "{percent} abgeschlossen",
|
||||
"iris.desktop.pregen.current": "Aktuell · 10 s",
|
||||
"iris.desktop.pregen.overall": "Gesamt",
|
||||
"iris.desktop.pregen.thirty": "30-s-Mittel",
|
||||
"iris.desktop.pregen.sixty": "60-s-Mittel",
|
||||
"iris.desktop.pregen.rate": "{rate} Chunks/s",
|
||||
"iris.desktop.pregen.eta": "Verbleibend",
|
||||
"iris.desktop.pregen.elapsed": "Verstrichen",
|
||||
"iris.desktop.pregen.memory_label": "Speicher",
|
||||
"iris.desktop.pregen.memory_usage": "{used} · {usage}",
|
||||
"iris.desktop.pregen.pressure": "Speicherzuweisung",
|
||||
"iris.desktop.pregen.pressure_value": "{rate}/s",
|
||||
"iris.desktop.pregen.cached": "{method} · zwischengespeichert",
|
||||
"iris.desktop.pregen.failed": "{count} fehlgeschlagen · siehe Serverprotokoll",
|
||||
"iris.desktop.pregen.map": "Generierungskarte",
|
||||
"iris.desktop.pregen.bounds": "Chunks X {minX} bis {maxX} · Z {minZ} bis {maxZ}",
|
||||
"iris.desktop.pregen.waiting": "Wartend",
|
||||
"iris.desktop.pregen.ready": "Bereit",
|
||||
"iris.desktop.pregen.existing": "Vorhanden",
|
||||
"iris.desktop.pregen.network": "Netzwerk",
|
||||
"iris.desktop.pregen.terrain_hint": "Fertige Chunks zeigen Geländefarben"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1442,14 +1442,7 @@
|
||||
"iris.desktop.pregen.paused": "PAUSADO",
|
||||
"iris.desktop.pregen.resume_hint": "Pulsa P para reanudar",
|
||||
"iris.desktop.pregen.pause_hint": "Pulsa P para pausar",
|
||||
"iris.desktop.pregen.progress_paused": "PAUSADO {generated} de {total} ({percent} completado)",
|
||||
"iris.desktop.pregen.progress_saving": "Guardando... {generated} de {total} ({percent} completado)",
|
||||
"iris.desktop.pregen.progress_generating": "Generando {generated} de {total} ({percent} completado)",
|
||||
"iris.desktop.pregen.speed": "Velocidad: {overall} overall, {tenSecond} 10s, {thirtySecond} 30s, {sixtySecond} 60s chunks/s",
|
||||
"iris.desktop.pregen.speed_cached": "Velocidad: en caché {overall} overall, {tenSecond} 10s, {thirtySecond} 30s, {sixtySecond} 60s chunks/s",
|
||||
"iris.desktop.pregen.time": "{remaining} restantes ({elapsed} transcurridos)",
|
||||
"iris.desktop.pregen.method": "Método de generación: {method}",
|
||||
"iris.desktop.pregen.memory": "Memoria: {used} ({usage}) Presión: {pressure}/s",
|
||||
"iris.modded.help.entry.command.what.here": "Inspect the Iris biome, region, cave biome, surface and chunk at your position",
|
||||
"iris.modded.help.entry.command.what.biome": "Inspect the Iris biome, configured derivative and registered native biome",
|
||||
"iris.modded.help.entry.command.what.region": "Inspect the Iris region at your current chunk",
|
||||
@@ -1570,6 +1563,37 @@
|
||||
"iris.modded.moddedpackcommands.compat_header": "Pack '{pack}': contenido no disponible en Minecraft {version}",
|
||||
"iris.modded.moddedpackcommands.compat_none": "El pack '{pack}' no usa contenido que falte en Minecraft {version}.",
|
||||
"iris.modded.moddedpackcommands.compat_remedy": "Actualiza el servidor a un Minecraft más reciente para recuperar este contenido, o declara alternativas (blockFallbacks de la dimensión, backup del bloque).",
|
||||
"iris.modded.help.entry.command.compat_content": "Muestra el contenido que no puede generarse en esta versión de Minecraft"
|
||||
"iris.modded.help.entry.command.compat_content": "Muestra el contenido que no puede generarse en esta versión de Minecraft",
|
||||
"iris.desktop.pregen.pause": "Pausar",
|
||||
"iris.desktop.pregen.resume": "Reanudar",
|
||||
"iris.desktop.pregen.generating": "Generando",
|
||||
"iris.desktop.pregen.saving": "Guardando",
|
||||
"iris.desktop.pregen.stopping": "Deteniendo",
|
||||
"iris.desktop.pregen.completed": "Completado",
|
||||
"iris.desktop.pregen.error": "Error de generación",
|
||||
"iris.desktop.pregen.control_failed": "Error al pausar · consulta el registro del servidor",
|
||||
"iris.desktop.pregen.error_details": "Detalles en el registro del servidor",
|
||||
"iris.desktop.pregen.progress": "{generated} / {total} chunks",
|
||||
"iris.desktop.pregen.percent": "{percent} completado",
|
||||
"iris.desktop.pregen.current": "Actual · 10 s",
|
||||
"iris.desktop.pregen.overall": "Global",
|
||||
"iris.desktop.pregen.thirty": "Media de 30 s",
|
||||
"iris.desktop.pregen.sixty": "Media de 60 s",
|
||||
"iris.desktop.pregen.rate": "{rate} chunks/s",
|
||||
"iris.desktop.pregen.eta": "Restante",
|
||||
"iris.desktop.pregen.elapsed": "Transcurrido",
|
||||
"iris.desktop.pregen.memory_label": "Memoria",
|
||||
"iris.desktop.pregen.memory_usage": "{used} · {usage}",
|
||||
"iris.desktop.pregen.pressure": "Asignación",
|
||||
"iris.desktop.pregen.pressure_value": "{rate}/s",
|
||||
"iris.desktop.pregen.cached": "{method} · en caché",
|
||||
"iris.desktop.pregen.failed": "{count} fallidos · consulta el registro del servidor",
|
||||
"iris.desktop.pregen.map": "Mapa de generación",
|
||||
"iris.desktop.pregen.bounds": "Chunks X de {minX} a {maxX} · Z de {minZ} a {maxZ}",
|
||||
"iris.desktop.pregen.waiting": "En espera",
|
||||
"iris.desktop.pregen.ready": "Listo",
|
||||
"iris.desktop.pregen.existing": "Existente",
|
||||
"iris.desktop.pregen.network": "Red",
|
||||
"iris.desktop.pregen.terrain_hint": "Los chunks terminados muestran los colores del terreno"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1442,14 +1442,7 @@
|
||||
"iris.desktop.pregen.paused": "keskeytetty",
|
||||
"iris.desktop.pregen.resume_hint": "Paina P jatkaaksesi",
|
||||
"iris.desktop.pregen.pause_hint": "Paina P taukoa varten",
|
||||
"iris.desktop.pregen.progress_paused": "keskeytetty {generated} / {total} ({percent} täydellinen)",
|
||||
"iris.desktop.pregen.progress_saving": "Tallennus... {generated} / {total} ({percent} täydellinen)",
|
||||
"iris.desktop.pregen.progress_generating": "Luodaan {generated} / {total} ({percent} täydellinen)",
|
||||
"iris.desktop.pregen.speed": "Nopeus: {overall} overall, {tenSecond} 10s, {thirtySecond} 30s, {sixtySecond} 60s chunks/s",
|
||||
"iris.desktop.pregen.speed_cached": "Nopeus: välimuisti {overall} overall, {tenSecond} 10s, {thirtySecond} 30s, {sixtySecond} 60s chunks/s",
|
||||
"iris.desktop.pregen.time": "{remaining} jäljellä ({elapsed} Kulunut)",
|
||||
"iris.desktop.pregen.method": "Generointimenetelmä: {method}",
|
||||
"iris.desktop.pregen.memory": "Muisti: {used} ({usage}) Paine: {pressure}/s",
|
||||
"iris.modded.help.entry.command.what.here": "Inspect the Iris biome, region, cave biome, surface and chunk at your position",
|
||||
"iris.modded.help.entry.command.what.biome": "Inspect the Iris biome, configured derivative and registered native biome",
|
||||
"iris.modded.help.entry.command.what.region": "Inspect the Iris region at your current chunk",
|
||||
@@ -1570,6 +1563,37 @@
|
||||
"iris.modded.moddedpackcommands.compat_header": "Paketti '{pack}': sisältö ei ole käytettävissä Minecraft {version} -versiossa",
|
||||
"iris.modded.moddedpackcommands.compat_none": "Paketti '{pack}' ei käytä sisältöä, joka puuttuisi Minecraft {version} -versiosta.",
|
||||
"iris.modded.moddedpackcommands.compat_remedy": "Päivitä palvelin uudempaan Minecraft-versioon palauttaaksesi tämän sisällön tai määritä varasisältö (ulottuvuuden blockFallbacks, lohkon backup).",
|
||||
"iris.modded.help.entry.command.compat_content": "Näytä sisältö, jota ei voi luoda tässä Minecraft-versiossa"
|
||||
"iris.modded.help.entry.command.compat_content": "Näytä sisältö, jota ei voi luoda tässä Minecraft-versiossa",
|
||||
"iris.desktop.pregen.pause": "Keskeytä",
|
||||
"iris.desktop.pregen.resume": "Jatka",
|
||||
"iris.desktop.pregen.generating": "Luodaan",
|
||||
"iris.desktop.pregen.saving": "Tallennetaan",
|
||||
"iris.desktop.pregen.stopping": "Pysäytetään",
|
||||
"iris.desktop.pregen.completed": "Valmis",
|
||||
"iris.desktop.pregen.error": "Luonti epäonnistui",
|
||||
"iris.desktop.pregen.control_failed": "Keskeytys epäonnistui · katso palvelinloki",
|
||||
"iris.desktop.pregen.error_details": "Lisätiedot palvelinlokissa",
|
||||
"iris.desktop.pregen.progress": "{generated} / {total} lohkoa",
|
||||
"iris.desktop.pregen.percent": "{percent} valmiina",
|
||||
"iris.desktop.pregen.current": "Nykyinen · 10 s",
|
||||
"iris.desktop.pregen.overall": "Kokonaiskeskiarvo",
|
||||
"iris.desktop.pregen.thirty": "30 s keskiarvo",
|
||||
"iris.desktop.pregen.sixty": "60 s keskiarvo",
|
||||
"iris.desktop.pregen.rate": "{rate} lohkoa/s",
|
||||
"iris.desktop.pregen.eta": "Jäljellä",
|
||||
"iris.desktop.pregen.elapsed": "Kulunut",
|
||||
"iris.desktop.pregen.memory_label": "Muisti",
|
||||
"iris.desktop.pregen.memory_usage": "{used} · {usage}",
|
||||
"iris.desktop.pregen.pressure": "Muistivaraus",
|
||||
"iris.desktop.pregen.pressure_value": "{rate}/s",
|
||||
"iris.desktop.pregen.cached": "{method} · välimuistissa",
|
||||
"iris.desktop.pregen.failed": "{count} epäonnistui · katso palvelinloki",
|
||||
"iris.desktop.pregen.map": "Luontikartta",
|
||||
"iris.desktop.pregen.bounds": "Lohkot X {minX}–{maxX} · Z {minZ}–{maxZ}",
|
||||
"iris.desktop.pregen.waiting": "Odottaa",
|
||||
"iris.desktop.pregen.ready": "Valmis",
|
||||
"iris.desktop.pregen.existing": "Olemassa",
|
||||
"iris.desktop.pregen.network": "Verkko",
|
||||
"iris.desktop.pregen.terrain_hint": "Valmiit lohkot näyttävät maaston värit"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1442,14 +1442,7 @@
|
||||
"iris.desktop.pregen.paused": "EN PAUSE",
|
||||
"iris.desktop.pregen.resume_hint": "Appuyez sur P pour reprendre",
|
||||
"iris.desktop.pregen.pause_hint": "Appuyez sur P pour mettre en pause",
|
||||
"iris.desktop.pregen.progress_paused": "EN PAUSE {generated} sur {total} ({percent} terminés)",
|
||||
"iris.desktop.pregen.progress_saving": "Enregistrement... {generated} sur {total} ({percent} terminés)",
|
||||
"iris.desktop.pregen.progress_generating": "Génération de {generated} sur {total} ({percent} terminés)",
|
||||
"iris.desktop.pregen.speed": "Vitesse : {overall} overall, {tenSecond} 10s, {thirtySecond} 30s, {sixtySecond} 60s chunks/s",
|
||||
"iris.desktop.pregen.speed_cached": "Vitesse : cache {overall} overall, {tenSecond} 10s, {thirtySecond} 30s, {sixtySecond} 60s chunks/s",
|
||||
"iris.desktop.pregen.time": "{remaining} restantes ({elapsed} écoulées)",
|
||||
"iris.desktop.pregen.method": "Méthode de génération : {method}",
|
||||
"iris.desktop.pregen.memory": "Mémoire : {used} ({usage}) Pression : {pressure}/s",
|
||||
"iris.modded.help.entry.command.what.here": "Inspecter le biome Iris, la région, le biome souterrain, la surface et le chunk à votre position",
|
||||
"iris.modded.help.entry.command.what.biome": "Inspect the Iris biome, configured derivative and registered native biome",
|
||||
"iris.modded.help.entry.command.what.region": "Inspect the Iris region at your current chunk",
|
||||
@@ -1570,6 +1563,37 @@
|
||||
"iris.modded.moddedpackcommands.compat_header": "Pack '{pack}' : contenu indisponible sur Minecraft {version}",
|
||||
"iris.modded.moddedpackcommands.compat_none": "Le pack '{pack}' n'utilise aucun contenu absent de Minecraft {version}.",
|
||||
"iris.modded.moddedpackcommands.compat_remedy": "Mettez le serveur à jour vers un Minecraft plus récent pour restaurer ce contenu, ou déclarez des replis (blockFallbacks de la dimension, backup du bloc).",
|
||||
"iris.modded.help.entry.command.compat_content": "Afficher le contenu qui ne peut pas être généré sur cette version de Minecraft"
|
||||
"iris.modded.help.entry.command.compat_content": "Afficher le contenu qui ne peut pas être généré sur cette version de Minecraft",
|
||||
"iris.desktop.pregen.pause": "Pause",
|
||||
"iris.desktop.pregen.resume": "Reprendre",
|
||||
"iris.desktop.pregen.generating": "Génération",
|
||||
"iris.desktop.pregen.saving": "Enregistrement",
|
||||
"iris.desktop.pregen.stopping": "Arrêt en cours",
|
||||
"iris.desktop.pregen.completed": "Terminé",
|
||||
"iris.desktop.pregen.error": "Échec de la génération",
|
||||
"iris.desktop.pregen.control_failed": "Échec de la pause · voir le journal serveur",
|
||||
"iris.desktop.pregen.error_details": "Détails dans le journal serveur",
|
||||
"iris.desktop.pregen.progress": "{generated} / {total} chunks",
|
||||
"iris.desktop.pregen.percent": "{percent} terminé",
|
||||
"iris.desktop.pregen.current": "Actuel · 10 s",
|
||||
"iris.desktop.pregen.overall": "Global",
|
||||
"iris.desktop.pregen.thirty": "Moyenne sur 30 s",
|
||||
"iris.desktop.pregen.sixty": "Moyenne sur 60 s",
|
||||
"iris.desktop.pregen.rate": "{rate} chunks/s",
|
||||
"iris.desktop.pregen.eta": "Restant",
|
||||
"iris.desktop.pregen.elapsed": "Écoulé",
|
||||
"iris.desktop.pregen.memory_label": "Mémoire",
|
||||
"iris.desktop.pregen.memory_usage": "{used} · {usage}",
|
||||
"iris.desktop.pregen.pressure": "Allocation",
|
||||
"iris.desktop.pregen.pressure_value": "{rate}/s",
|
||||
"iris.desktop.pregen.cached": "{method} · en cache",
|
||||
"iris.desktop.pregen.failed": "{count} échecs · voir le journal serveur",
|
||||
"iris.desktop.pregen.map": "Carte de génération",
|
||||
"iris.desktop.pregen.bounds": "Chunks X de {minX} à {maxX} · Z de {minZ} à {maxZ}",
|
||||
"iris.desktop.pregen.waiting": "En attente",
|
||||
"iris.desktop.pregen.ready": "Prêt",
|
||||
"iris.desktop.pregen.existing": "Existant",
|
||||
"iris.desktop.pregen.network": "Réseau",
|
||||
"iris.desktop.pregen.terrain_hint": "Les chunks terminés affichent les couleurs du terrain"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1442,14 +1442,7 @@
|
||||
"iris.desktop.pregen.paused": "מושהה",
|
||||
"iris.desktop.pregen.resume_hint": "לחץ על P לחדש",
|
||||
"iris.desktop.pregen.pause_hint": "הקש P כדי לעצור",
|
||||
"iris.desktop.pregen.progress_paused": "מושהה {generated} של {total} ({percent} שלם)",
|
||||
"iris.desktop.pregen.progress_saving": "חיסכון... {generated} של {total} ({percent} שלם)",
|
||||
"iris.desktop.pregen.progress_generating": "ייצור {generated} של {total} ({percent} שלם)",
|
||||
"iris.desktop.pregen.speed": "מהירות: {overall} overall, {tenSecond} 10s, {thirtySecond} 30s, {sixtySecond} 60s chunks/s",
|
||||
"iris.desktop.pregen.speed_cached": "מהירות: במטמון {overall} overall, {tenSecond} 10s, {thirtySecond} 30s, {sixtySecond} 60s chunks/s",
|
||||
"iris.desktop.pregen.time": "{remaining} הנותרים ({elapsed} מת)",
|
||||
"iris.desktop.pregen.method": "שיטת דור: {method}",
|
||||
"iris.desktop.pregen.memory": "זיכרון:{used} ({usage}לחץ:{pressure}/s",
|
||||
"iris.modded.help.entry.command.what.here": "Inspect the Iris biome, region, cave biome, surface and chunk at your position",
|
||||
"iris.modded.help.entry.command.what.biome": "Inspect the Iris biome, configured derivative and registered native biome",
|
||||
"iris.modded.help.entry.command.what.region": "Inspect the Iris region at your current chunk",
|
||||
@@ -1570,6 +1563,37 @@
|
||||
"iris.modded.moddedpackcommands.compat_header": "חבילה '{pack}': תוכן לא זמין ב-Minecraft {version}",
|
||||
"iris.modded.moddedpackcommands.compat_none": "החבילה '{pack}' אינה משתמשת בתוכן שחסר ב-Minecraft {version}.",
|
||||
"iris.modded.moddedpackcommands.compat_remedy": "עדכן את השרת ל-Minecraft חדש יותר כדי לשחזר את התוכן הזה, או הגדר חלופות (blockFallbacks של הממד, backup של הבלוק).",
|
||||
"iris.modded.help.entry.command.compat_content": "הצג תוכן שלא ניתן ליצור בגרסת Minecraft הזו"
|
||||
"iris.modded.help.entry.command.compat_content": "הצג תוכן שלא ניתן ליצור בגרסת Minecraft הזו",
|
||||
"iris.desktop.pregen.pause": "השהיה",
|
||||
"iris.desktop.pregen.resume": "המשך",
|
||||
"iris.desktop.pregen.generating": "יצירה",
|
||||
"iris.desktop.pregen.saving": "שמירה",
|
||||
"iris.desktop.pregen.stopping": "עצירה",
|
||||
"iris.desktop.pregen.completed": "הושלם",
|
||||
"iris.desktop.pregen.error": "היצירה נכשלה",
|
||||
"iris.desktop.pregen.control_failed": "ההשהיה נכשלה · פרטים ביומן השרת",
|
||||
"iris.desktop.pregen.error_details": "פרטים ביומן השרת",
|
||||
"iris.desktop.pregen.progress": "{generated} / {total} צ׳אנקים",
|
||||
"iris.desktop.pregen.percent": "{percent} הושלמו",
|
||||
"iris.desktop.pregen.current": "נוכחי · 10 שנ׳",
|
||||
"iris.desktop.pregen.overall": "כולל",
|
||||
"iris.desktop.pregen.thirty": "ממוצע 30 שנ׳",
|
||||
"iris.desktop.pregen.sixty": "ממוצע 60 שנ׳",
|
||||
"iris.desktop.pregen.rate": "{rate} צ׳אנקים/שנ׳",
|
||||
"iris.desktop.pregen.eta": "נותר",
|
||||
"iris.desktop.pregen.elapsed": "חלף",
|
||||
"iris.desktop.pregen.memory_label": "זיכרון",
|
||||
"iris.desktop.pregen.memory_usage": "{used} · {usage}",
|
||||
"iris.desktop.pregen.pressure": "הקצאה",
|
||||
"iris.desktop.pregen.pressure_value": "{rate}/s",
|
||||
"iris.desktop.pregen.cached": "{method} · מהמטמון",
|
||||
"iris.desktop.pregen.failed": "{count} נכשלו · פרטים ביומן השרת",
|
||||
"iris.desktop.pregen.map": "מפת יצירה",
|
||||
"iris.desktop.pregen.bounds": "צ׳אנקים X מ־{minX} עד {maxX} · Z מ־{minZ} עד {maxZ}",
|
||||
"iris.desktop.pregen.waiting": "בהמתנה",
|
||||
"iris.desktop.pregen.ready": "מוכן",
|
||||
"iris.desktop.pregen.existing": "קיים",
|
||||
"iris.desktop.pregen.network": "רשת",
|
||||
"iris.desktop.pregen.terrain_hint": "צ׳אנקים שהושלמו מציגים את צבעי השטח"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1442,14 +1442,7 @@
|
||||
"iris.desktop.pregen.paused": "in pausa",
|
||||
"iris.desktop.pregen.resume_hint": "Premere P per riprendere",
|
||||
"iris.desktop.pregen.pause_hint": "Premere P per mettere in pausa",
|
||||
"iris.desktop.pregen.progress_paused": "in pausa {generated} di {total} ({percent} completo)",
|
||||
"iris.desktop.pregen.progress_saving": "Salvataggio... {generated} di {total} ({percent} completato)",
|
||||
"iris.desktop.pregen.progress_generating": "Generazione {generated} di {total} ({percent} completo)",
|
||||
"iris.desktop.pregen.speed": "Velocità: {overall} overall, {tenSecond} 10s, {thirtySecond} 30s, {sixtySecond} 60s chunks/s",
|
||||
"iris.desktop.pregen.speed_cached": "Velocità: cache {overall} overall, {tenSecond} 10s, {thirtySecond} 30s, {sixtySecond} 60s chunks/s",
|
||||
"iris.desktop.pregen.time": "{remaining} rimanenti ({elapsed} trascorso)",
|
||||
"iris.desktop.pregen.method": "Metodo di generazione: {method}",
|
||||
"iris.desktop.pregen.memory": "Memoria: {used} ({usage}) Pressione: {pressure}/s",
|
||||
"iris.modded.help.entry.command.what.here": "Inspect the Iris biome, region, cave biome, surface and chunk at your position",
|
||||
"iris.modded.help.entry.command.what.biome": "Inspect the Iris biome, configured derivative and registered native biome",
|
||||
"iris.modded.help.entry.command.what.region": "Inspect the Iris region at your current chunk",
|
||||
@@ -1570,6 +1563,37 @@
|
||||
"iris.modded.moddedpackcommands.compat_header": "Pack '{pack}': contenuti non disponibili su Minecraft {version}",
|
||||
"iris.modded.moddedpackcommands.compat_none": "Il pack '{pack}' non usa contenuti assenti da Minecraft {version}.",
|
||||
"iris.modded.moddedpackcommands.compat_remedy": "Aggiorna il server a un Minecraft più recente per ripristinare questi contenuti, oppure dichiara delle alternative (blockFallbacks della dimensione, backup del blocco).",
|
||||
"iris.modded.help.entry.command.compat_content": "Mostra i contenuti che non possono essere generati su questa versione di Minecraft"
|
||||
"iris.modded.help.entry.command.compat_content": "Mostra i contenuti che non possono essere generati su questa versione di Minecraft",
|
||||
"iris.desktop.pregen.pause": "Pausa",
|
||||
"iris.desktop.pregen.resume": "Riprendi",
|
||||
"iris.desktop.pregen.generating": "Generazione",
|
||||
"iris.desktop.pregen.saving": "Salvataggio",
|
||||
"iris.desktop.pregen.stopping": "Arresto in corso",
|
||||
"iris.desktop.pregen.completed": "Completato",
|
||||
"iris.desktop.pregen.error": "Generazione fallita",
|
||||
"iris.desktop.pregen.control_failed": "Pausa fallita · consulta il log del server",
|
||||
"iris.desktop.pregen.error_details": "Dettagli nel log del server",
|
||||
"iris.desktop.pregen.progress": "{generated} / {total} chunk",
|
||||
"iris.desktop.pregen.percent": "{percent} completato",
|
||||
"iris.desktop.pregen.current": "Attuale · 10 s",
|
||||
"iris.desktop.pregen.overall": "Complessivo",
|
||||
"iris.desktop.pregen.thirty": "Media su 30 s",
|
||||
"iris.desktop.pregen.sixty": "Media su 60 s",
|
||||
"iris.desktop.pregen.rate": "{rate} chunk/s",
|
||||
"iris.desktop.pregen.eta": "Rimanente",
|
||||
"iris.desktop.pregen.elapsed": "Trascorso",
|
||||
"iris.desktop.pregen.memory_label": "Memoria",
|
||||
"iris.desktop.pregen.memory_usage": "{used} · {usage}",
|
||||
"iris.desktop.pregen.pressure": "Allocazione",
|
||||
"iris.desktop.pregen.pressure_value": "{rate}/s",
|
||||
"iris.desktop.pregen.cached": "{method} · in cache",
|
||||
"iris.desktop.pregen.failed": "{count} falliti · consulta il log del server",
|
||||
"iris.desktop.pregen.map": "Mappa di generazione",
|
||||
"iris.desktop.pregen.bounds": "Chunk X da {minX} a {maxX} · Z da {minZ} a {maxZ}",
|
||||
"iris.desktop.pregen.waiting": "In attesa",
|
||||
"iris.desktop.pregen.ready": "Pronto",
|
||||
"iris.desktop.pregen.existing": "Esistente",
|
||||
"iris.desktop.pregen.network": "Rete",
|
||||
"iris.desktop.pregen.terrain_hint": "I chunk completati mostrano i colori del terreno"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1442,14 +1442,7 @@
|
||||
"iris.desktop.pregen.paused": "一時停止中",
|
||||
"iris.desktop.pregen.resume_hint": "P を押して再開",
|
||||
"iris.desktop.pregen.pause_hint": "P を押して一時停止",
|
||||
"iris.desktop.pregen.progress_paused": "一時停止中 {generated}/{total}({percent} 完了)",
|
||||
"iris.desktop.pregen.progress_saving": "保存中... {generated}/{total}({percent} 完了)",
|
||||
"iris.desktop.pregen.progress_generating": "生成中 {generated}/{total}({percent} 完了)",
|
||||
"iris.desktop.pregen.speed": "速度: {overall} overall, {tenSecond} 10s, {thirtySecond} 30s, {sixtySecond} 60s chunks/s",
|
||||
"iris.desktop.pregen.speed_cached": "速度: キャッシュ {overall} overall, {tenSecond} 10s, {thirtySecond} 30s, {sixtySecond} 60s chunks/s",
|
||||
"iris.desktop.pregen.time": "残り {remaining}(経過 {elapsed})",
|
||||
"iris.desktop.pregen.method": "生成方法: {method}",
|
||||
"iris.desktop.pregen.memory": "メモリ: {used}({usage})負荷: {pressure}/s",
|
||||
"iris.modded.help.entry.command.what.here": "Inspect the Iris biome, region, cave biome, surface and chunk at your position",
|
||||
"iris.modded.help.entry.command.what.biome": "Inspect the Iris biome, configured derivative and registered native biome",
|
||||
"iris.modded.help.entry.command.what.region": "Inspect the Iris region at your current chunk",
|
||||
@@ -1570,6 +1563,37 @@
|
||||
"iris.modded.moddedpackcommands.compat_header": "パック '{pack}': Minecraft {version} では利用できない内容があります",
|
||||
"iris.modded.moddedpackcommands.compat_none": "パック '{pack}' に Minecraft {version} で欠けている内容はありません。",
|
||||
"iris.modded.moddedpackcommands.compat_remedy": "この内容を復元するにはサーバーを新しい Minecraft に更新するか、代替を宣言してください (ディメンションの blockFallbacks、ブロックの backup)。",
|
||||
"iris.modded.help.entry.command.compat_content": "この Minecraft バージョンでは生成できない内容を表示します"
|
||||
"iris.modded.help.entry.command.compat_content": "この Minecraft バージョンでは生成できない内容を表示します",
|
||||
"iris.desktop.pregen.pause": "一時停止",
|
||||
"iris.desktop.pregen.resume": "再開",
|
||||
"iris.desktop.pregen.generating": "生成中",
|
||||
"iris.desktop.pregen.saving": "保存中",
|
||||
"iris.desktop.pregen.stopping": "停止中",
|
||||
"iris.desktop.pregen.completed": "完了",
|
||||
"iris.desktop.pregen.error": "生成に失敗",
|
||||
"iris.desktop.pregen.control_failed": "一時停止に失敗 · サーバーログを確認",
|
||||
"iris.desktop.pregen.error_details": "詳細はサーバーログを確認",
|
||||
"iris.desktop.pregen.progress": "{generated} / {total} チャンク",
|
||||
"iris.desktop.pregen.percent": "{percent} 完了",
|
||||
"iris.desktop.pregen.current": "現在 · 10秒",
|
||||
"iris.desktop.pregen.overall": "全体",
|
||||
"iris.desktop.pregen.thirty": "30秒平均",
|
||||
"iris.desktop.pregen.sixty": "60秒平均",
|
||||
"iris.desktop.pregen.rate": "{rate} チャンク/秒",
|
||||
"iris.desktop.pregen.eta": "残り",
|
||||
"iris.desktop.pregen.elapsed": "経過",
|
||||
"iris.desktop.pregen.memory_label": "メモリ",
|
||||
"iris.desktop.pregen.memory_usage": "{used} · {usage}",
|
||||
"iris.desktop.pregen.pressure": "メモリ割り当て",
|
||||
"iris.desktop.pregen.pressure_value": "{rate}/s",
|
||||
"iris.desktop.pregen.cached": "{method} · キャッシュ済み",
|
||||
"iris.desktop.pregen.failed": "{count} 件失敗 · サーバーログを確認",
|
||||
"iris.desktop.pregen.map": "生成マップ",
|
||||
"iris.desktop.pregen.bounds": "チャンク X {minX} ~ {maxX} · Z {minZ} ~ {maxZ}",
|
||||
"iris.desktop.pregen.waiting": "待機中",
|
||||
"iris.desktop.pregen.ready": "準備完了",
|
||||
"iris.desktop.pregen.existing": "既存",
|
||||
"iris.desktop.pregen.network": "ネットワーク",
|
||||
"iris.desktop.pregen.terrain_hint": "完了したチャンクは地形の色で表示されます"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1442,14 +1442,7 @@
|
||||
"iris.desktop.pregen.paused": "일시 중지",
|
||||
"iris.desktop.pregen.resume_hint": "재개하려면 P를 누르세요",
|
||||
"iris.desktop.pregen.pause_hint": "일시 중지하려면 P를 누르세요",
|
||||
"iris.desktop.pregen.progress_paused": "일시 중지 {generated}/{total} ({percent} 완료)",
|
||||
"iris.desktop.pregen.progress_saving": "저장 중... {generated}/{total} ({percent} 완료)",
|
||||
"iris.desktop.pregen.progress_generating": "전체 {total} 중 {generated} 생성 중 ({percent} 완료)",
|
||||
"iris.desktop.pregen.speed": "속도: {overall} overall, {tenSecond} 10s, {thirtySecond} 30s, {sixtySecond} 60s chunks/s",
|
||||
"iris.desktop.pregen.speed_cached": "속도: 캐시 {overall} overall, {tenSecond} 10s, {thirtySecond} 30s, {sixtySecond} 60s chunks/s",
|
||||
"iris.desktop.pregen.time": "{remaining} 나머지 ({elapsed} 탈출)",
|
||||
"iris.desktop.pregen.method": "생성 방법: {method}",
|
||||
"iris.desktop.pregen.memory": "기억: {used} ({usage}) 압력: {pressure}/s",
|
||||
"iris.modded.help.entry.command.what.here": "Inspect the Iris biome, region, cave biome, surface and chunk at your position",
|
||||
"iris.modded.help.entry.command.what.biome": "Inspect the Iris biome, configured derivative and registered native biome",
|
||||
"iris.modded.help.entry.command.what.region": "Inspect the Iris region at your current chunk",
|
||||
@@ -1570,6 +1563,37 @@
|
||||
"iris.modded.moddedpackcommands.compat_header": "팩 '{pack}': Minecraft {version} 에서 사용할 수 없는 콘텐츠",
|
||||
"iris.modded.moddedpackcommands.compat_none": "팩 '{pack}' 은 Minecraft {version} 에 없는 콘텐츠를 사용하지 않습니다.",
|
||||
"iris.modded.moddedpackcommands.compat_remedy": "이 콘텐츠를 복원하려면 서버를 최신 Minecraft 로 업데이트하거나 대체를 선언하세요 (차원의 blockFallbacks, 블록의 backup).",
|
||||
"iris.modded.help.entry.command.compat_content": "이 Minecraft 버전에서 생성할 수 없는 콘텐츠를 표시합니다"
|
||||
"iris.modded.help.entry.command.compat_content": "이 Minecraft 버전에서 생성할 수 없는 콘텐츠를 표시합니다",
|
||||
"iris.desktop.pregen.pause": "일시 중지",
|
||||
"iris.desktop.pregen.resume": "계속",
|
||||
"iris.desktop.pregen.generating": "생성 중",
|
||||
"iris.desktop.pregen.saving": "저장 중",
|
||||
"iris.desktop.pregen.stopping": "중지 중",
|
||||
"iris.desktop.pregen.completed": "완료",
|
||||
"iris.desktop.pregen.error": "생성 실패",
|
||||
"iris.desktop.pregen.control_failed": "일시 중지 실패 · 서버 로그 확인",
|
||||
"iris.desktop.pregen.error_details": "자세한 내용은 서버 로그 확인",
|
||||
"iris.desktop.pregen.progress": "{generated} / {total} 청크",
|
||||
"iris.desktop.pregen.percent": "{percent} 완료",
|
||||
"iris.desktop.pregen.current": "현재 · 10초",
|
||||
"iris.desktop.pregen.overall": "전체",
|
||||
"iris.desktop.pregen.thirty": "30초 평균",
|
||||
"iris.desktop.pregen.sixty": "60초 평균",
|
||||
"iris.desktop.pregen.rate": "{rate} 청크/초",
|
||||
"iris.desktop.pregen.eta": "남은 시간",
|
||||
"iris.desktop.pregen.elapsed": "경과 시간",
|
||||
"iris.desktop.pregen.memory_label": "메모리",
|
||||
"iris.desktop.pregen.memory_usage": "{used} · {usage}",
|
||||
"iris.desktop.pregen.pressure": "메모리 할당",
|
||||
"iris.desktop.pregen.pressure_value": "{rate}/s",
|
||||
"iris.desktop.pregen.cached": "{method} · 캐시됨",
|
||||
"iris.desktop.pregen.failed": "{count}개 실패 · 서버 로그 확인",
|
||||
"iris.desktop.pregen.map": "생성 지도",
|
||||
"iris.desktop.pregen.bounds": "청크 X {minX} ~ {maxX} · Z {minZ} ~ {maxZ}",
|
||||
"iris.desktop.pregen.waiting": "대기 중",
|
||||
"iris.desktop.pregen.ready": "준비됨",
|
||||
"iris.desktop.pregen.existing": "기존",
|
||||
"iris.desktop.pregen.network": "네트워크",
|
||||
"iris.desktop.pregen.terrain_hint": "완료된 청크는 지형 색상으로 표시됩니다"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1442,14 +1442,7 @@
|
||||
"iris.desktop.pregen.paused": "pristabdyta",
|
||||
"iris.desktop.pregen.resume_hint": "Paspauskite P norėdami atnaujinti",
|
||||
"iris.desktop.pregen.pause_hint": "Paspauskite P pristabdyti",
|
||||
"iris.desktop.pregen.progress_paused": "pristabdyta {generated} iš {total} ({percent} užbaigti)",
|
||||
"iris.desktop.pregen.progress_saving": "Taupoma... {generated} iš {total} ({percent} užbaigti)",
|
||||
"iris.desktop.pregen.progress_generating": "Generuojama {generated} iš {total} ({percent} užbaigti)",
|
||||
"iris.desktop.pregen.speed": "Greitis: {overall} overall, {tenSecond} 10s, {thirtySecond} 30s, {sixtySecond} 60s chunks/s",
|
||||
"iris.desktop.pregen.speed_cached": "Greitis: cached {overall} overall, {tenSecond} 10s, {thirtySecond} 30s, {sixtySecond} 60s chunks/s",
|
||||
"iris.desktop.pregen.time": "{remaining} likę ({elapsed} praėjo)",
|
||||
"iris.desktop.pregen.method": "Gamybos būdas: {method}",
|
||||
"iris.desktop.pregen.memory": "Atmintis: {used} ({usage}) Slėgis: {pressure}/s",
|
||||
"iris.modded.help.entry.command.what.here": "Inspect the Iris biome, region, cave biome, surface and chunk at your position",
|
||||
"iris.modded.help.entry.command.what.biome": "Inspect the Iris biome, configured derivative and registered native biome",
|
||||
"iris.modded.help.entry.command.what.region": "Inspect the Iris region at your current chunk",
|
||||
@@ -1570,6 +1563,37 @@
|
||||
"iris.modded.moddedpackcommands.compat_header": "Paketas '{pack}': turinys nepasiekiamas Minecraft {version}",
|
||||
"iris.modded.moddedpackcommands.compat_none": "Paketas '{pack}' nenaudoja turinio, kurio trūksta Minecraft {version}.",
|
||||
"iris.modded.moddedpackcommands.compat_remedy": "Atnaujinkite serverį į naujesnį Minecraft, kad atkurtumėte šį turinį, arba paskelbkite atsargas (dimensijos blockFallbacks, bloko backup).",
|
||||
"iris.modded.help.entry.command.compat_content": "Rodyti turinį, kurio negalima sugeneruoti šioje Minecraft versijoje"
|
||||
"iris.modded.help.entry.command.compat_content": "Rodyti turinį, kurio negalima sugeneruoti šioje Minecraft versijoje",
|
||||
"iris.desktop.pregen.pause": "Pristabdyti",
|
||||
"iris.desktop.pregen.resume": "Tęsti",
|
||||
"iris.desktop.pregen.generating": "Generuojama",
|
||||
"iris.desktop.pregen.saving": "Išsaugoma",
|
||||
"iris.desktop.pregen.stopping": "Stabdoma",
|
||||
"iris.desktop.pregen.completed": "Baigta",
|
||||
"iris.desktop.pregen.error": "Generavimas nepavyko",
|
||||
"iris.desktop.pregen.control_failed": "Pristabdyti nepavyko · žr. serverio žurnalą",
|
||||
"iris.desktop.pregen.error_details": "Išsamiau serverio žurnale",
|
||||
"iris.desktop.pregen.progress": "{generated} / {total} sričių",
|
||||
"iris.desktop.pregen.percent": "Baigta {percent}",
|
||||
"iris.desktop.pregen.current": "Dabartinis · 10 s",
|
||||
"iris.desktop.pregen.overall": "Bendras",
|
||||
"iris.desktop.pregen.thirty": "30 s vidurkis",
|
||||
"iris.desktop.pregen.sixty": "60 s vidurkis",
|
||||
"iris.desktop.pregen.rate": "{rate} sričių/s",
|
||||
"iris.desktop.pregen.eta": "Liko",
|
||||
"iris.desktop.pregen.elapsed": "Praėjo",
|
||||
"iris.desktop.pregen.memory_label": "Atmintis",
|
||||
"iris.desktop.pregen.memory_usage": "{used} · {usage}",
|
||||
"iris.desktop.pregen.pressure": "Atminties skyrimas",
|
||||
"iris.desktop.pregen.pressure_value": "{rate}/s",
|
||||
"iris.desktop.pregen.cached": "{method} · iš podėlio",
|
||||
"iris.desktop.pregen.failed": "{count} klaidų · žr. serverio žurnalą",
|
||||
"iris.desktop.pregen.map": "Generavimo žemėlapis",
|
||||
"iris.desktop.pregen.bounds": "Sritys X nuo {minX} iki {maxX} · Z nuo {minZ} iki {maxZ}",
|
||||
"iris.desktop.pregen.waiting": "Laukiama",
|
||||
"iris.desktop.pregen.ready": "Paruošta",
|
||||
"iris.desktop.pregen.existing": "Esamos",
|
||||
"iris.desktop.pregen.network": "Tinklas",
|
||||
"iris.desktop.pregen.terrain_hint": "Baigtos sritys rodo reljefo spalvas"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1442,14 +1442,7 @@
|
||||
"iris.desktop.pregen.paused": "gepauzeerd",
|
||||
"iris.desktop.pregen.resume_hint": "Druk op P om te hervatten",
|
||||
"iris.desktop.pregen.pause_hint": "Druk op P om te pauzeren",
|
||||
"iris.desktop.pregen.progress_paused": "gepauzeerd {generated} van {total} ({percent} volledig)",
|
||||
"iris.desktop.pregen.progress_saving": "Opslaan... {generated} van {total} ({percent} volledig)",
|
||||
"iris.desktop.pregen.progress_generating": "Genereren {generated} van {total} ({percent} volledig)",
|
||||
"iris.desktop.pregen.speed": "Snelheid: {overall} overall, {tenSecond} 10s, {thirtySecond} 30s, {sixtySecond} 60s chunks/s",
|
||||
"iris.desktop.pregen.speed_cached": "Snelheid: gecached {overall} overall, {tenSecond} 10s, {thirtySecond} 30s, {sixtySecond} 60s chunks/s",
|
||||
"iris.desktop.pregen.time": "{remaining} resterende ({elapsed} verlopen)",
|
||||
"iris.desktop.pregen.method": "Generatiemethode: {method}",
|
||||
"iris.desktop.pregen.memory": "Geheugen: {used} ({usage}) Druk {pressure}/s",
|
||||
"iris.modded.help.entry.command.what.here": "Inspect the Iris biome, region, cave biome, surface and chunk at your position",
|
||||
"iris.modded.help.entry.command.what.biome": "Inspect the Iris biome, configured derivative and registered native biome",
|
||||
"iris.modded.help.entry.command.what.region": "Inspect the Iris region at your current chunk",
|
||||
@@ -1570,6 +1563,37 @@
|
||||
"iris.modded.moddedpackcommands.compat_header": "Pack '{pack}': inhoud niet beschikbaar op Minecraft {version}",
|
||||
"iris.modded.moddedpackcommands.compat_none": "Pack '{pack}' gebruikt geen inhoud die ontbreekt in Minecraft {version}.",
|
||||
"iris.modded.moddedpackcommands.compat_remedy": "Werk de server bij naar een nieuwere Minecraft om deze inhoud te herstellen, of declareer terugvallen (blockFallbacks van de dimensie, backup van het blok).",
|
||||
"iris.modded.help.entry.command.compat_content": "Toon inhoud die niet kan worden gegenereerd op deze Minecraft-versie"
|
||||
"iris.modded.help.entry.command.compat_content": "Toon inhoud die niet kan worden gegenereerd op deze Minecraft-versie",
|
||||
"iris.desktop.pregen.pause": "Pauzeren",
|
||||
"iris.desktop.pregen.resume": "Hervatten",
|
||||
"iris.desktop.pregen.generating": "Genereren",
|
||||
"iris.desktop.pregen.saving": "Opslaan",
|
||||
"iris.desktop.pregen.stopping": "Stoppen",
|
||||
"iris.desktop.pregen.completed": "Voltooid",
|
||||
"iris.desktop.pregen.error": "Generatie mislukt",
|
||||
"iris.desktop.pregen.control_failed": "Pauzeren mislukt · zie serverlog",
|
||||
"iris.desktop.pregen.error_details": "Details in serverlog",
|
||||
"iris.desktop.pregen.progress": "{generated} / {total} chunks",
|
||||
"iris.desktop.pregen.percent": "{percent} voltooid",
|
||||
"iris.desktop.pregen.current": "Huidig · 10 s",
|
||||
"iris.desktop.pregen.overall": "Totaal",
|
||||
"iris.desktop.pregen.thirty": "Gemiddelde 30 s",
|
||||
"iris.desktop.pregen.sixty": "Gemiddelde 60 s",
|
||||
"iris.desktop.pregen.rate": "{rate} chunks/s",
|
||||
"iris.desktop.pregen.eta": "Resterend",
|
||||
"iris.desktop.pregen.elapsed": "Verstreken",
|
||||
"iris.desktop.pregen.memory_label": "Geheugen",
|
||||
"iris.desktop.pregen.memory_usage": "{used} · {usage}",
|
||||
"iris.desktop.pregen.pressure": "Toewijzing",
|
||||
"iris.desktop.pregen.pressure_value": "{rate}/s",
|
||||
"iris.desktop.pregen.cached": "{method} · gecachet",
|
||||
"iris.desktop.pregen.failed": "{count} mislukt · zie serverlog",
|
||||
"iris.desktop.pregen.map": "Generatiekaart",
|
||||
"iris.desktop.pregen.bounds": "Chunks X {minX} tot {maxX} · Z {minZ} tot {maxZ}",
|
||||
"iris.desktop.pregen.waiting": "Wachtend",
|
||||
"iris.desktop.pregen.ready": "Gereed",
|
||||
"iris.desktop.pregen.existing": "Bestaand",
|
||||
"iris.desktop.pregen.network": "Netwerk",
|
||||
"iris.desktop.pregen.terrain_hint": "Voltooide chunks tonen terreinkleuren"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1442,14 +1442,7 @@
|
||||
"iris.desktop.pregen.paused": "wstrzymano",
|
||||
"iris.desktop.pregen.resume_hint": "Naciśnij P, aby wznowić",
|
||||
"iris.desktop.pregen.pause_hint": "Naciśnij P, aby zatrzymać",
|
||||
"iris.desktop.pregen.progress_paused": "wstrzymano {generated} z {total} ({percent} całkowita)",
|
||||
"iris.desktop.pregen.progress_saving": "Zapisywanie... {generated} z {total} ({percent} całkowita)",
|
||||
"iris.desktop.pregen.progress_generating": "Generowanie {generated} z {total} ({percent} całkowita)",
|
||||
"iris.desktop.pregen.speed": "Prędkość: {overall} overall, {tenSecond} 10s, {thirtySecond} 30s, {sixtySecond} 60s chunks/s",
|
||||
"iris.desktop.pregen.speed_cached": "Prędkość: buforowana {overall} overall, {tenSecond} 10s, {thirtySecond} 30s, {sixtySecond} 60s chunks/s",
|
||||
"iris.desktop.pregen.time": "{remaining} pozostałe ({elapsed} elapsed)",
|
||||
"iris.desktop.pregen.method": "Metoda wytwarzania: {method}",
|
||||
"iris.desktop.pregen.memory": "Pamięć: {used} ({usage}) Ciśnienie: {pressure}/s",
|
||||
"iris.modded.help.entry.command.what.here": "Inspect the Iris biome, region, cave biome, surface and chunk at your position",
|
||||
"iris.modded.help.entry.command.what.biome": "Inspect the Iris biome, configured derivative and registered native biome",
|
||||
"iris.modded.help.entry.command.what.region": "Inspect the Iris region at your current chunk",
|
||||
@@ -1570,6 +1563,37 @@
|
||||
"iris.modded.moddedpackcommands.compat_header": "Paczka '{pack}': zawartość niedostępna w Minecraft {version}",
|
||||
"iris.modded.moddedpackcommands.compat_none": "Paczka '{pack}' nie używa zawartości brakującej w Minecraft {version}.",
|
||||
"iris.modded.moddedpackcommands.compat_remedy": "Zaktualizuj serwer do nowszego Minecraft, aby przywrócić tę zawartość, albo zadeklaruj zamienniki (blockFallbacks wymiaru, backup bloku).",
|
||||
"iris.modded.help.entry.command.compat_content": "Pokaż zawartość, której nie można wygenerować w tej wersji Minecraft"
|
||||
"iris.modded.help.entry.command.compat_content": "Pokaż zawartość, której nie można wygenerować w tej wersji Minecraft",
|
||||
"iris.desktop.pregen.pause": "Wstrzymaj",
|
||||
"iris.desktop.pregen.resume": "Wznów",
|
||||
"iris.desktop.pregen.generating": "Generowanie",
|
||||
"iris.desktop.pregen.saving": "Zapisywanie",
|
||||
"iris.desktop.pregen.stopping": "Zatrzymywanie",
|
||||
"iris.desktop.pregen.completed": "Ukończono",
|
||||
"iris.desktop.pregen.error": "Generowanie nie powiodło się",
|
||||
"iris.desktop.pregen.control_failed": "Błąd wstrzymania · zobacz log serwera",
|
||||
"iris.desktop.pregen.error_details": "Szczegóły w logu serwera",
|
||||
"iris.desktop.pregen.progress": "{generated} / {total} chunków",
|
||||
"iris.desktop.pregen.percent": "Ukończono {percent}",
|
||||
"iris.desktop.pregen.current": "Bieżąca · 10 s",
|
||||
"iris.desktop.pregen.overall": "Ogółem",
|
||||
"iris.desktop.pregen.thirty": "Średnia z 30 s",
|
||||
"iris.desktop.pregen.sixty": "Średnia z 60 s",
|
||||
"iris.desktop.pregen.rate": "{rate} chunków/s",
|
||||
"iris.desktop.pregen.eta": "Pozostało",
|
||||
"iris.desktop.pregen.elapsed": "Upłynęło",
|
||||
"iris.desktop.pregen.memory_label": "Pamięć",
|
||||
"iris.desktop.pregen.memory_usage": "{used} · {usage}",
|
||||
"iris.desktop.pregen.pressure": "Alokacja",
|
||||
"iris.desktop.pregen.pressure_value": "{rate}/s",
|
||||
"iris.desktop.pregen.cached": "{method} · w pamięci podręcznej",
|
||||
"iris.desktop.pregen.failed": "{count} błędów · zobacz log serwera",
|
||||
"iris.desktop.pregen.map": "Mapa generowania",
|
||||
"iris.desktop.pregen.bounds": "Chunki X od {minX} do {maxX} · Z od {minZ} do {maxZ}",
|
||||
"iris.desktop.pregen.waiting": "Oczekuje",
|
||||
"iris.desktop.pregen.ready": "Gotowe",
|
||||
"iris.desktop.pregen.existing": "Istniejące",
|
||||
"iris.desktop.pregen.network": "Sieć",
|
||||
"iris.desktop.pregen.terrain_hint": "Gotowe chunki pokazują kolory terenu"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1442,14 +1442,7 @@
|
||||
"iris.desktop.pregen.paused": "pausado",
|
||||
"iris.desktop.pregen.resume_hint": "Pressione P para retomar",
|
||||
"iris.desktop.pregen.pause_hint": "Pressione P para pausar",
|
||||
"iris.desktop.pregen.progress_paused": "pausado {generated} de {total} ({percent} completo)",
|
||||
"iris.desktop.pregen.progress_saving": "Salvando... {generated} de {total} ({percent} completo)",
|
||||
"iris.desktop.pregen.progress_generating": "Gerando {generated} de {total} ({percent} completo)",
|
||||
"iris.desktop.pregen.speed": "Velocidade: {overall} overall, {tenSecond} 10s, {thirtySecond} 30s, {sixtySecond} 60s chunks/s",
|
||||
"iris.desktop.pregen.speed_cached": "Velocidade: em cache {overall} overall, {tenSecond} 10s, {thirtySecond} 30s, {sixtySecond} 60s chunks/s",
|
||||
"iris.desktop.pregen.time": "{remaining} restantes ({elapsed} transcorrido)",
|
||||
"iris.desktop.pregen.method": "Método de geração: {method}",
|
||||
"iris.desktop.pregen.memory": "Memória: {used} ({usage}) Pressão: {pressure}/s",
|
||||
"iris.modded.help.entry.command.what.here": "Inspect the Iris biome, region, cave biome, surface and chunk at your position",
|
||||
"iris.modded.help.entry.command.what.biome": "Inspect the Iris biome, configured derivative and registered native biome",
|
||||
"iris.modded.help.entry.command.what.region": "Inspect the Iris region at your current chunk",
|
||||
@@ -1570,6 +1563,37 @@
|
||||
"iris.modded.moddedpackcommands.compat_header": "Pack '{pack}': conteúdo indisponível no Minecraft {version}",
|
||||
"iris.modded.moddedpackcommands.compat_none": "O pack '{pack}' não usa conteúdo em falta no Minecraft {version}.",
|
||||
"iris.modded.moddedpackcommands.compat_remedy": "Atualize o servidor para um Minecraft mais recente para restaurar este conteúdo, ou declare alternativas (blockFallbacks da dimensão, backup do bloco).",
|
||||
"iris.modded.help.entry.command.compat_content": "Mostrar o conteúdo que não pode ser gerado nesta versão do Minecraft"
|
||||
"iris.modded.help.entry.command.compat_content": "Mostrar o conteúdo que não pode ser gerado nesta versão do Minecraft",
|
||||
"iris.desktop.pregen.pause": "Pausar",
|
||||
"iris.desktop.pregen.resume": "Retomar",
|
||||
"iris.desktop.pregen.generating": "A gerar",
|
||||
"iris.desktop.pregen.saving": "A guardar",
|
||||
"iris.desktop.pregen.stopping": "A parar",
|
||||
"iris.desktop.pregen.completed": "Concluído",
|
||||
"iris.desktop.pregen.error": "Falha na geração",
|
||||
"iris.desktop.pregen.control_failed": "Falha ao pausar · consultar registo do servidor",
|
||||
"iris.desktop.pregen.error_details": "Detalhes no registo do servidor",
|
||||
"iris.desktop.pregen.progress": "{generated} / {total} chunks",
|
||||
"iris.desktop.pregen.percent": "{percent} concluído",
|
||||
"iris.desktop.pregen.current": "Atual · 10 s",
|
||||
"iris.desktop.pregen.overall": "Global",
|
||||
"iris.desktop.pregen.thirty": "Média de 30 s",
|
||||
"iris.desktop.pregen.sixty": "Média de 60 s",
|
||||
"iris.desktop.pregen.rate": "{rate} chunks/s",
|
||||
"iris.desktop.pregen.eta": "Restante",
|
||||
"iris.desktop.pregen.elapsed": "Decorrido",
|
||||
"iris.desktop.pregen.memory_label": "Memória",
|
||||
"iris.desktop.pregen.memory_usage": "{used} · {usage}",
|
||||
"iris.desktop.pregen.pressure": "Alocação",
|
||||
"iris.desktop.pregen.pressure_value": "{rate}/s",
|
||||
"iris.desktop.pregen.cached": "{method} · em cache",
|
||||
"iris.desktop.pregen.failed": "{count} falhas · consultar registo do servidor",
|
||||
"iris.desktop.pregen.map": "Mapa de geração",
|
||||
"iris.desktop.pregen.bounds": "Chunks X de {minX} a {maxX} · Z de {minZ} a {maxZ}",
|
||||
"iris.desktop.pregen.waiting": "Em espera",
|
||||
"iris.desktop.pregen.ready": "Pronto",
|
||||
"iris.desktop.pregen.existing": "Existente",
|
||||
"iris.desktop.pregen.network": "Rede",
|
||||
"iris.desktop.pregen.terrain_hint": "Os chunks concluídos mostram as cores do terreno"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1442,14 +1442,7 @@
|
||||
"iris.desktop.pregen.paused": "приостановлено",
|
||||
"iris.desktop.pregen.resume_hint": "Нажмите P, чтобы возобновить",
|
||||
"iris.desktop.pregen.pause_hint": "Нажмите P, чтобы остановиться",
|
||||
"iris.desktop.pregen.progress_paused": "приостановлено {generated} из {total} ({percent} полный)",
|
||||
"iris.desktop.pregen.progress_saving": "экономить... {generated} из {total} ({percent} полный)",
|
||||
"iris.desktop.pregen.progress_generating": "генерировать {generated} из {total} ({percent} полный)",
|
||||
"iris.desktop.pregen.speed": "Скорость: {overall} overall, {tenSecond} 10s, {thirtySecond} 30s, {sixtySecond} 60s chunks/s",
|
||||
"iris.desktop.pregen.speed_cached": "Скорость: кэшировано {overall} overall, {tenSecond} 10s, {thirtySecond} 30s, {sixtySecond} 60s chunks/s",
|
||||
"iris.desktop.pregen.time": "{remaining} оставшееся ({elapsed} истекший)",
|
||||
"iris.desktop.pregen.method": "Метод генерации: {method}",
|
||||
"iris.desktop.pregen.memory": "Память: {used} ({usage}) Давление: {pressure}/s",
|
||||
"iris.modded.help.entry.command.what.here": "Inspect the Iris biome, region, cave biome, surface and chunk at your position",
|
||||
"iris.modded.help.entry.command.what.biome": "Inspect the Iris biome, configured derivative and registered native biome",
|
||||
"iris.modded.help.entry.command.what.region": "Inspect the Iris region at your current chunk",
|
||||
@@ -1570,6 +1563,37 @@
|
||||
"iris.modded.moddedpackcommands.compat_header": "Пак '{pack}': содержимое недоступно в Minecraft {version}",
|
||||
"iris.modded.moddedpackcommands.compat_none": "Пак '{pack}' не использует содержимое, которого нет в Minecraft {version}.",
|
||||
"iris.modded.moddedpackcommands.compat_remedy": "Обновите сервер до более новой версии Minecraft, чтобы вернуть это содержимое, или объявите замены (blockFallbacks измерения, backup блока).",
|
||||
"iris.modded.help.entry.command.compat_content": "Показать содержимое, которое нельзя сгенерировать в этой версии Minecraft"
|
||||
"iris.modded.help.entry.command.compat_content": "Показать содержимое, которое нельзя сгенерировать в этой версии Minecraft",
|
||||
"iris.desktop.pregen.pause": "Пауза",
|
||||
"iris.desktop.pregen.resume": "Продолжить",
|
||||
"iris.desktop.pregen.generating": "Генерация",
|
||||
"iris.desktop.pregen.saving": "Сохранение",
|
||||
"iris.desktop.pregen.stopping": "Остановка",
|
||||
"iris.desktop.pregen.completed": "Завершено",
|
||||
"iris.desktop.pregen.error": "Ошибка генерации",
|
||||
"iris.desktop.pregen.control_failed": "Ошибка паузы · см. журнал сервера",
|
||||
"iris.desktop.pregen.error_details": "Подробности в журнале сервера",
|
||||
"iris.desktop.pregen.progress": "{generated} / {total} чанков",
|
||||
"iris.desktop.pregen.percent": "Завершено {percent}",
|
||||
"iris.desktop.pregen.current": "Текущая · 10 с",
|
||||
"iris.desktop.pregen.overall": "Общая",
|
||||
"iris.desktop.pregen.thirty": "Средняя за 30 с",
|
||||
"iris.desktop.pregen.sixty": "Средняя за 60 с",
|
||||
"iris.desktop.pregen.rate": "{rate} чанков/с",
|
||||
"iris.desktop.pregen.eta": "Осталось",
|
||||
"iris.desktop.pregen.elapsed": "Прошло",
|
||||
"iris.desktop.pregen.memory_label": "Память",
|
||||
"iris.desktop.pregen.memory_usage": "{used} · {usage}",
|
||||
"iris.desktop.pregen.pressure": "Выделение памяти",
|
||||
"iris.desktop.pregen.pressure_value": "{rate}/s",
|
||||
"iris.desktop.pregen.cached": "{method} · из кеша",
|
||||
"iris.desktop.pregen.failed": "Ошибок: {count} · см. журнал сервера",
|
||||
"iris.desktop.pregen.map": "Карта генерации",
|
||||
"iris.desktop.pregen.bounds": "Чанки X от {minX} до {maxX} · Z от {minZ} до {maxZ}",
|
||||
"iris.desktop.pregen.waiting": "Ожидание",
|
||||
"iris.desktop.pregen.ready": "Готово",
|
||||
"iris.desktop.pregen.existing": "Существующие",
|
||||
"iris.desktop.pregen.network": "Сеть",
|
||||
"iris.desktop.pregen.terrain_hint": "Готовые чанки отображают цвета ландшафта"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1442,14 +1442,7 @@
|
||||
"iris.desktop.pregen.paused": "duraklatıldı",
|
||||
"iris.desktop.pregen.resume_hint": "Devam etmek için P'ye basın",
|
||||
"iris.desktop.pregen.pause_hint": "Duraklatmak için P'ye basın",
|
||||
"iris.desktop.pregen.progress_paused": "duraklatıldı {generated} Of {total} ({percent} Tamam)",
|
||||
"iris.desktop.pregen.progress_saving": "Tasarruf kurtarmak... {generated} Of {total} ({percent} Tamam)",
|
||||
"iris.desktop.pregen.progress_generating": "Genating {generated} Of {total} ({percent} Tamam)",
|
||||
"iris.desktop.pregen.speed": "Hız: {overall} overall, {tenSecond} 10s, {thirtySecond} 30s, {sixtySecond} 60s chunks/s",
|
||||
"iris.desktop.pregen.speed_cached": "Hız: Önbelli {overall} overall, {tenSecond} 10s, {thirtySecond} 30s, {sixtySecond} 60s chunks/s",
|
||||
"iris.desktop.pregen.time": "{remaining} kalan ({elapsed} elapd)",
|
||||
"iris.desktop.pregen.method": "Nesil yöntemi: {method}",
|
||||
"iris.desktop.pregen.memory": "bellek: {used} ({usage}Baskı:) {pressure}/s",
|
||||
"iris.modded.help.entry.command.what.here": "Inspect the Iris biome, region, cave biome, surface and chunk at your position",
|
||||
"iris.modded.help.entry.command.what.biome": "Inspect the Iris biome, configured derivative and registered native biome",
|
||||
"iris.modded.help.entry.command.what.region": "Inspect the Iris region at your current chunk",
|
||||
@@ -1570,6 +1563,37 @@
|
||||
"iris.modded.moddedpackcommands.compat_header": "Paket '{pack}': içerik Minecraft {version} sürümünde yok",
|
||||
"iris.modded.moddedpackcommands.compat_none": "Paket '{pack}' Minecraft {version} sürümünde eksik olan içerik kullanmıyor.",
|
||||
"iris.modded.moddedpackcommands.compat_remedy": "Bu içeriği geri kazanmak için sunucuyu daha yeni bir Minecraft sürümüne güncelleyin veya yedekler tanımlayın (boyutun blockFallbacks, bloğun backup).",
|
||||
"iris.modded.help.entry.command.compat_content": "Bu Minecraft sürümünde üretilemeyen içeriği göster"
|
||||
"iris.modded.help.entry.command.compat_content": "Bu Minecraft sürümünde üretilemeyen içeriği göster",
|
||||
"iris.desktop.pregen.pause": "Duraklat",
|
||||
"iris.desktop.pregen.resume": "Devam et",
|
||||
"iris.desktop.pregen.generating": "Oluşturuluyor",
|
||||
"iris.desktop.pregen.saving": "Kaydediliyor",
|
||||
"iris.desktop.pregen.stopping": "Durduruluyor",
|
||||
"iris.desktop.pregen.completed": "Tamamlandı",
|
||||
"iris.desktop.pregen.error": "Oluşturma başarısız",
|
||||
"iris.desktop.pregen.control_failed": "Duraklatma başarısız · sunucu günlüğüne bakın",
|
||||
"iris.desktop.pregen.error_details": "Ayrıntılar için sunucu günlüğüne bakın",
|
||||
"iris.desktop.pregen.progress": "{generated} / {total} chunk",
|
||||
"iris.desktop.pregen.percent": "{percent} tamamlandı",
|
||||
"iris.desktop.pregen.current": "Güncel · 10 sn",
|
||||
"iris.desktop.pregen.overall": "Genel",
|
||||
"iris.desktop.pregen.thirty": "30 sn ortalama",
|
||||
"iris.desktop.pregen.sixty": "60 sn ortalama",
|
||||
"iris.desktop.pregen.rate": "{rate} chunk/sn",
|
||||
"iris.desktop.pregen.eta": "Kalan",
|
||||
"iris.desktop.pregen.elapsed": "Geçen",
|
||||
"iris.desktop.pregen.memory_label": "Bellek",
|
||||
"iris.desktop.pregen.memory_usage": "{used} · {usage}",
|
||||
"iris.desktop.pregen.pressure": "Bellek ayırma",
|
||||
"iris.desktop.pregen.pressure_value": "{rate}/s",
|
||||
"iris.desktop.pregen.cached": "{method} · önbellekten",
|
||||
"iris.desktop.pregen.failed": "{count} başarısız · sunucu günlüğüne bakın",
|
||||
"iris.desktop.pregen.map": "Oluşturma haritası",
|
||||
"iris.desktop.pregen.bounds": "Chunk X {minX} – {maxX} · Z {minZ} – {maxZ}",
|
||||
"iris.desktop.pregen.waiting": "Bekliyor",
|
||||
"iris.desktop.pregen.ready": "Hazır",
|
||||
"iris.desktop.pregen.existing": "Mevcut",
|
||||
"iris.desktop.pregen.network": "Ağ",
|
||||
"iris.desktop.pregen.terrain_hint": "Tamamlanan chunklar arazi renklerini gösterir"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1442,14 +1442,7 @@
|
||||
"iris.desktop.pregen.paused": "đã tạm dừng",
|
||||
"iris.desktop.pregen.resume_hint": "Nhấn P để tiếp tục",
|
||||
"iris.desktop.pregen.pause_hint": "Nhấn nút P để tạm dừng",
|
||||
"iris.desktop.pregen.progress_paused": "đã tạm dừng {generated} Kho {total} ({percent} Hoàn tất)",
|
||||
"iris.desktop.pregen.progress_saving": "Đang lưu... {generated} Kho {total} ({percent} Hoàn tất)",
|
||||
"iris.desktop.pregen.progress_generating": "Đang tạo ra {generated} Kho {total} ({percent} Hoàn tất)",
|
||||
"iris.desktop.pregen.speed": "Tốc độ: {overall} overall, {tenSecond} 10s, {thirtySecond} 30s, {sixtySecond} 60s chunks/s",
|
||||
"iris.desktop.pregen.speed_cached": "Tốc độ: đã lưu tạm {overall} overall, {tenSecond} 10s, {thirtySecond} 30s, {sixtySecond} 60s chunks/s",
|
||||
"iris.desktop.pregen.time": "{remaining} còn lại ({elapsed} Mở rộng)",
|
||||
"iris.desktop.pregen.method": "Phương pháp thế hệ: {method}",
|
||||
"iris.desktop.pregen.memory": "Bộ nhớ: {used} ({usage}) Áp lực: {pressure}/s",
|
||||
"iris.modded.help.entry.command.what.here": "Inspect the Iris biome, region, cave biome, surface and chunk at your position",
|
||||
"iris.modded.help.entry.command.what.biome": "Inspect the Iris biome, configured derivative and registered native biome",
|
||||
"iris.modded.help.entry.command.what.region": "Inspect the Iris region at your current chunk",
|
||||
@@ -1570,6 +1563,37 @@
|
||||
"iris.modded.moddedpackcommands.compat_header": "Gói '{pack}': nội dung không có trên Minecraft {version}",
|
||||
"iris.modded.moddedpackcommands.compat_none": "Gói '{pack}' không dùng nội dung nào thiếu trên Minecraft {version}.",
|
||||
"iris.modded.moddedpackcommands.compat_remedy": "Cập nhật máy chủ lên Minecraft mới hơn để khôi phục nội dung này, hoặc khai báo phương án dự phòng (blockFallbacks của chiều, backup của khối).",
|
||||
"iris.modded.help.entry.command.compat_content": "Hiển thị nội dung không thể tạo trên phiên bản Minecraft này"
|
||||
"iris.modded.help.entry.command.compat_content": "Hiển thị nội dung không thể tạo trên phiên bản Minecraft này",
|
||||
"iris.desktop.pregen.pause": "Tạm dừng",
|
||||
"iris.desktop.pregen.resume": "Tiếp tục",
|
||||
"iris.desktop.pregen.generating": "Đang tạo",
|
||||
"iris.desktop.pregen.saving": "Đang lưu",
|
||||
"iris.desktop.pregen.stopping": "Đang dừng",
|
||||
"iris.desktop.pregen.completed": "Hoàn tất",
|
||||
"iris.desktop.pregen.error": "Tạo thất bại",
|
||||
"iris.desktop.pregen.control_failed": "Tạm dừng thất bại · xem nhật ký máy chủ",
|
||||
"iris.desktop.pregen.error_details": "Xem chi tiết trong nhật ký máy chủ",
|
||||
"iris.desktop.pregen.progress": "{generated} / {total} chunk",
|
||||
"iris.desktop.pregen.percent": "Hoàn tất {percent}",
|
||||
"iris.desktop.pregen.current": "Hiện tại · 10 giây",
|
||||
"iris.desktop.pregen.overall": "Tổng thể",
|
||||
"iris.desktop.pregen.thirty": "Trung bình 30 giây",
|
||||
"iris.desktop.pregen.sixty": "Trung bình 60 giây",
|
||||
"iris.desktop.pregen.rate": "{rate} chunk/giây",
|
||||
"iris.desktop.pregen.eta": "Còn lại",
|
||||
"iris.desktop.pregen.elapsed": "Đã qua",
|
||||
"iris.desktop.pregen.memory_label": "Bộ nhớ",
|
||||
"iris.desktop.pregen.memory_usage": "{used} · {usage}",
|
||||
"iris.desktop.pregen.pressure": "Cấp phát",
|
||||
"iris.desktop.pregen.pressure_value": "{rate}/s",
|
||||
"iris.desktop.pregen.cached": "{method} · đã lưu đệm",
|
||||
"iris.desktop.pregen.failed": "{count} thất bại · xem nhật ký máy chủ",
|
||||
"iris.desktop.pregen.map": "Bản đồ tạo địa hình",
|
||||
"iris.desktop.pregen.bounds": "Chunk X từ {minX} đến {maxX} · Z từ {minZ} đến {maxZ}",
|
||||
"iris.desktop.pregen.waiting": "Đang chờ",
|
||||
"iris.desktop.pregen.ready": "Sẵn sàng",
|
||||
"iris.desktop.pregen.existing": "Có sẵn",
|
||||
"iris.desktop.pregen.network": "Mạng",
|
||||
"iris.desktop.pregen.terrain_hint": "Chunk hoàn tất hiển thị màu địa hình"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1442,14 +1442,7 @@
|
||||
"iris.desktop.pregen.paused": "已暂停",
|
||||
"iris.desktop.pregen.resume_hint": "按 P 键恢复",
|
||||
"iris.desktop.pregen.pause_hint": "按 P 暂停",
|
||||
"iris.desktop.pregen.progress_paused": "已暂停 {generated} 页:1 {total} ({percent} 完成) 数据",
|
||||
"iris.desktop.pregen.progress_saving": "保存... {generated} 页:1 {total} ({percent} 完成) 数据",
|
||||
"iris.desktop.pregen.progress_generating": "正在生成 {generated} 页:1 {total} ({percent} 完成) 数据",
|
||||
"iris.desktop.pregen.speed": "速度 : {overall} overall, {tenSecond} 10s, {thirtySecond} 30s, {sixtySecond} 60s chunks/s",
|
||||
"iris.desktop.pregen.speed_cached": "速度:已缓存 {overall} overall, {tenSecond} 10s, {thirtySecond} 30s, {sixtySecond} 60s chunks/s",
|
||||
"iris.desktop.pregen.time": "{remaining} 剩余({elapsed} 已过期)",
|
||||
"iris.desktop.pregen.method": "生成方法 : {method}",
|
||||
"iris.desktop.pregen.memory": "内存 : {used} ({usage})压力: {pressure}/s",
|
||||
"iris.modded.help.entry.command.what.here": "Inspect the Iris biome, region, cave biome, surface and chunk at your position",
|
||||
"iris.modded.help.entry.command.what.biome": "Inspect the Iris biome, configured derivative and registered native biome",
|
||||
"iris.modded.help.entry.command.what.region": "Inspect the Iris region at your current chunk",
|
||||
@@ -1570,6 +1563,37 @@
|
||||
"iris.modded.moddedpackcommands.compat_header": "资源包 '{pack}': 内容在 Minecraft {version} 中不可用",
|
||||
"iris.modded.moddedpackcommands.compat_none": "资源包 '{pack}' 未使用 Minecraft {version} 中缺失的内容。",
|
||||
"iris.modded.moddedpackcommands.compat_remedy": "将服务器升级到更新的 Minecraft 以恢复这些内容,或声明回退 (维度的 blockFallbacks、方块的 backup)。",
|
||||
"iris.modded.help.entry.command.compat_content": "显示在当前 Minecraft 版本中无法生成的内容"
|
||||
"iris.modded.help.entry.command.compat_content": "显示在当前 Minecraft 版本中无法生成的内容",
|
||||
"iris.desktop.pregen.pause": "暂停",
|
||||
"iris.desktop.pregen.resume": "继续",
|
||||
"iris.desktop.pregen.generating": "生成中",
|
||||
"iris.desktop.pregen.saving": "保存中",
|
||||
"iris.desktop.pregen.stopping": "停止中",
|
||||
"iris.desktop.pregen.completed": "已完成",
|
||||
"iris.desktop.pregen.error": "生成失败",
|
||||
"iris.desktop.pregen.control_failed": "暂停失败 · 请查看服务器日志",
|
||||
"iris.desktop.pregen.error_details": "详情请查看服务器日志",
|
||||
"iris.desktop.pregen.progress": "{generated} / {total} 区块",
|
||||
"iris.desktop.pregen.percent": "已完成 {percent}",
|
||||
"iris.desktop.pregen.current": "当前 · 10秒",
|
||||
"iris.desktop.pregen.overall": "总体",
|
||||
"iris.desktop.pregen.thirty": "30秒平均",
|
||||
"iris.desktop.pregen.sixty": "60秒平均",
|
||||
"iris.desktop.pregen.rate": "{rate} 区块/秒",
|
||||
"iris.desktop.pregen.eta": "剩余时间",
|
||||
"iris.desktop.pregen.elapsed": "已用时间",
|
||||
"iris.desktop.pregen.memory_label": "内存",
|
||||
"iris.desktop.pregen.memory_usage": "{used} · {usage}",
|
||||
"iris.desktop.pregen.pressure": "内存分配",
|
||||
"iris.desktop.pregen.pressure_value": "{rate}/s",
|
||||
"iris.desktop.pregen.cached": "{method} · 已缓存",
|
||||
"iris.desktop.pregen.failed": "{count} 个失败 · 请查看服务器日志",
|
||||
"iris.desktop.pregen.map": "生成地图",
|
||||
"iris.desktop.pregen.bounds": "区块 X {minX} 至 {maxX} · Z {minZ} 至 {maxZ}",
|
||||
"iris.desktop.pregen.waiting": "等待中",
|
||||
"iris.desktop.pregen.ready": "就绪",
|
||||
"iris.desktop.pregen.existing": "已有",
|
||||
"iris.desktop.pregen.network": "网络",
|
||||
"iris.desktop.pregen.terrain_hint": "已完成的区块显示地形颜色"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1442,14 +1442,7 @@
|
||||
"iris.desktop.pregen.paused": "已暫停",
|
||||
"iris.desktop.pregen.resume_hint": "按 P 鍵恢復",
|
||||
"iris.desktop.pregen.pause_hint": "按 P 暫停",
|
||||
"iris.desktop.pregen.progress_paused": "已暫停 {generated} 頁:1 {total} ({percent} 完成) 資料",
|
||||
"iris.desktop.pregen.progress_saving": "儲存... {generated} 頁:1 {total} ({percent} 完成) 資料",
|
||||
"iris.desktop.pregen.progress_generating": "正在生成 {generated} 頁:1 {total} ({percent} 完成) 資料",
|
||||
"iris.desktop.pregen.speed": "速度 : {overall} overall, {tenSecond} 10s, {thirtySecond} 30s, {sixtySecond} 60s chunks/s",
|
||||
"iris.desktop.pregen.speed_cached": "速度:已快取 {overall} overall, {tenSecond} 10s, {thirtySecond} 30s, {sixtySecond} 60s chunks/s",
|
||||
"iris.desktop.pregen.time": "{remaining} 剩餘({elapsed} 已過期)",
|
||||
"iris.desktop.pregen.method": "生成方法 : {method}",
|
||||
"iris.desktop.pregen.memory": "記憶體 : {used} ({usage})壓力: {pressure}/s",
|
||||
"iris.modded.help.entry.command.what.here": "Inspect the Iris biome, region, cave biome, surface and chunk at your position",
|
||||
"iris.modded.help.entry.command.what.biome": "Inspect the Iris biome, configured derivative and registered native biome",
|
||||
"iris.modded.help.entry.command.what.region": "Inspect the Iris region at your current chunk",
|
||||
@@ -1570,6 +1563,37 @@
|
||||
"iris.modded.moddedpackcommands.compat_header": "資源包 '{pack}': 內容在 Minecraft {version} 中無法使用",
|
||||
"iris.modded.moddedpackcommands.compat_none": "資源包 '{pack}' 未使用 Minecraft {version} 中缺少的內容。",
|
||||
"iris.modded.moddedpackcommands.compat_remedy": "將伺服器升級到較新的 Minecraft 以還原這些內容,或宣告備援 (維度的 blockFallbacks、方塊的 backup)。",
|
||||
"iris.modded.help.entry.command.compat_content": "顯示在目前 Minecraft 版本中無法生成的內容"
|
||||
"iris.modded.help.entry.command.compat_content": "顯示在目前 Minecraft 版本中無法生成的內容",
|
||||
"iris.desktop.pregen.pause": "暫停",
|
||||
"iris.desktop.pregen.resume": "繼續",
|
||||
"iris.desktop.pregen.generating": "生成中",
|
||||
"iris.desktop.pregen.saving": "儲存中",
|
||||
"iris.desktop.pregen.stopping": "停止中",
|
||||
"iris.desktop.pregen.completed": "已完成",
|
||||
"iris.desktop.pregen.error": "生成失敗",
|
||||
"iris.desktop.pregen.control_failed": "暫停失敗 · 請查看伺服器日誌",
|
||||
"iris.desktop.pregen.error_details": "詳情請查看伺服器日誌",
|
||||
"iris.desktop.pregen.progress": "{generated} / {total} 區塊",
|
||||
"iris.desktop.pregen.percent": "已完成 {percent}",
|
||||
"iris.desktop.pregen.current": "目前 · 10秒",
|
||||
"iris.desktop.pregen.overall": "整體",
|
||||
"iris.desktop.pregen.thirty": "30秒平均",
|
||||
"iris.desktop.pregen.sixty": "60秒平均",
|
||||
"iris.desktop.pregen.rate": "{rate} 區塊/秒",
|
||||
"iris.desktop.pregen.eta": "剩餘時間",
|
||||
"iris.desktop.pregen.elapsed": "已用時間",
|
||||
"iris.desktop.pregen.memory_label": "記憶體",
|
||||
"iris.desktop.pregen.memory_usage": "{used} · {usage}",
|
||||
"iris.desktop.pregen.pressure": "記憶體配置",
|
||||
"iris.desktop.pregen.pressure_value": "{rate}/s",
|
||||
"iris.desktop.pregen.cached": "{method} · 已快取",
|
||||
"iris.desktop.pregen.failed": "{count} 個失敗 · 請查看伺服器日誌",
|
||||
"iris.desktop.pregen.map": "生成地圖",
|
||||
"iris.desktop.pregen.bounds": "區塊 X {minX} 至 {maxX} · Z {minZ} 至 {maxZ}",
|
||||
"iris.desktop.pregen.waiting": "等待中",
|
||||
"iris.desktop.pregen.ready": "就緒",
|
||||
"iris.desktop.pregen.existing": "既有",
|
||||
"iris.desktop.pregen.network": "網路",
|
||||
"iris.desktop.pregen.terrain_hint": "已完成的區塊顯示地形顏色"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
package art.arcane.iris.core.gui;
|
||||
|
||||
import art.arcane.iris.core.pregenerator.PregenTask;
|
||||
import art.arcane.volmlib.util.math.Position2;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.swing.SwingUtilities;
|
||||
import java.awt.Color;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class PregenMapPanelTest {
|
||||
@Test
|
||||
public void singleChunkAndInclusiveFinalEdgesReceivePixels() throws Exception {
|
||||
PregenMapPanel single = panel(new PregenRenderSnapshot.Bounds(5, -9, 5, -9));
|
||||
single.submit(5, -9, Color.GREEN);
|
||||
flush(single);
|
||||
assertEquals(Color.GREEN.getRGB(), image(single).getRGB(0, 0));
|
||||
|
||||
PregenMapPanel rectangle = panel(new PregenRenderSnapshot.Bounds(-2, -3, 1, -1));
|
||||
rectangle.submit(1, -1, Color.RED);
|
||||
rectangle.submit(-2, -3, Color.BLUE);
|
||||
flush(rectangle);
|
||||
assertEquals(Color.RED.getRGB(), image(rectangle).getRGB(3, 2));
|
||||
assertEquals(Color.BLUE.getRGB(), image(rectangle).getRGB(0, 0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void largeMapsStayBoundedAndEverySubmittedChunkCanReachAPixel() throws Exception {
|
||||
PregenMapPanel panel = panel(new PregenRenderSnapshot.Bounds(Integer.MIN_VALUE, -10, Integer.MAX_VALUE, 10));
|
||||
panel.submit(Integer.MAX_VALUE, 10, Color.GREEN);
|
||||
panel.submit(0, 0, Color.RED);
|
||||
flush(panel);
|
||||
|
||||
assertEquals(1024, image(panel).getWidth());
|
||||
assertEquals(21, image(panel).getHeight());
|
||||
assertEquals(Color.GREEN.getRGB(), image(panel).getRGB(1023, 20));
|
||||
assertEquals(Color.RED.getRGB(), image(panel).getRGB(512, 10));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void duplicateAndOutOfBoundsSubmissionsDoNotRequestAnotherFrame() throws Exception {
|
||||
PregenMapPanel panel = panel(new PregenRenderSnapshot.Bounds(0, 0, 1, 1));
|
||||
panel.submit(2, 0, Color.GREEN);
|
||||
SwingUtilities.invokeAndWait(() -> assertFalse(panel.flush()));
|
||||
panel.submit(0, 0, Color.GREEN);
|
||||
SwingUtilities.invokeAndWait(() -> assertTrue(panel.flush()));
|
||||
panel.submit(0, 0, Color.GREEN);
|
||||
SwingUtilities.invokeAndWait(() -> assertFalse(panel.flush()));
|
||||
SwingUtilities.invokeAndWait(panel::disposeMap);
|
||||
panel.submit(0, 0, Color.RED);
|
||||
SwingUtilities.invokeAndWait(() -> assertFalse(panel.flush()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pixelUpdatesRetainTheirLatestValueUntilTheViewFlushes() throws Exception {
|
||||
PregenMapPanel panel = panel(new PregenRenderSnapshot.Bounds(0, 0, 10_000, 0));
|
||||
for (int index = 0; index < 100_000; index++) {
|
||||
panel.submit(index % 10_001, 0, Color.RED);
|
||||
}
|
||||
panel.submit(10_000, 0, Color.GREEN);
|
||||
flush(panel);
|
||||
assertEquals(Color.GREEN.getRGB(), image(panel).getRGB(1023, 0));
|
||||
assertEquals(1024, image(panel).getWidth());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mapFitPreservesRectangularChunkAspect() {
|
||||
Rectangle wide = PregenMapPanel.fit(new PregenRenderSnapshot.Bounds(0, 0, 3, 1), 802, 602);
|
||||
assertEquals(new Rectangle(1, 101, 800, 400), wide);
|
||||
Rectangle tall = PregenMapPanel.fit(new PregenRenderSnapshot.Bounds(0, 0, 1, 3), 802, 602);
|
||||
assertEquals(new Rectangle(251, 1, 300, 600), tall);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void arithmeticTaskBoundsMatchActualRectangularTraversal() {
|
||||
PregenTask task = PregenTask.builder().center(new Position2(-17, 35)).radiusX(9).radiusZ(37).build();
|
||||
int[] actual = {Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE};
|
||||
task.iterateAllChunks((x, z) -> {
|
||||
actual[0] = Math.min(actual[0], x);
|
||||
actual[1] = Math.min(actual[1], z);
|
||||
actual[2] = Math.max(actual[2], x);
|
||||
actual[3] = Math.max(actual[3], z);
|
||||
});
|
||||
assertArrayEquals(actual, task.chunkBounds());
|
||||
}
|
||||
|
||||
private static PregenMapPanel panel(PregenRenderSnapshot.Bounds bounds) throws Exception {
|
||||
PregenMapPanel[] result = new PregenMapPanel[1];
|
||||
SwingUtilities.invokeAndWait(() -> result[0] = new PregenMapPanel(bounds));
|
||||
return result[0];
|
||||
}
|
||||
|
||||
private static void flush(PregenMapPanel panel) throws Exception {
|
||||
SwingUtilities.invokeAndWait(panel::flush);
|
||||
}
|
||||
|
||||
private static BufferedImage image(PregenMapPanel panel) throws Exception {
|
||||
Field field = PregenMapPanel.class.getDeclaredField("image");
|
||||
field.setAccessible(true);
|
||||
return (BufferedImage) field.get(panel);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
package art.arcane.iris.core.gui;
|
||||
|
||||
import art.arcane.iris.core.pregenerator.IrisPregenerator;
|
||||
import art.arcane.iris.core.pregenerator.PregenPhaseTracker;
|
||||
import art.arcane.iris.core.pregenerator.PregenRates;
|
||||
import art.arcane.volmlib.util.format.MemoryMonitor;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.CALLS_REAL_METHODS;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.mockito.Mockito.verifyNoInteractions;
|
||||
|
||||
public class PregeneratorJobRenderSnapshotTest {
|
||||
@Test
|
||||
public void viewSnapshotPublishesAllRatesMemoryAndFailedCountsTogether() throws Exception {
|
||||
Fixture fixture = new Fixture();
|
||||
when(fixture.pregenerator.getFailedChunks()).thenReturn(2L);
|
||||
|
||||
fixture.tick();
|
||||
|
||||
PregenRenderSnapshot view = fixture.job.renderSnapshot();
|
||||
assertEquals(PregenRenderSnapshot.Phase.GENERATING, view.phase());
|
||||
assertEquals(12D, view.progress().chunksPerSecond(), 0D);
|
||||
assertEquals(7D, view.progress().overallChunksPerSecond(), 0D);
|
||||
assertEquals(18D, view.progress().thirtySecondChunksPerSecond(), 0D);
|
||||
assertEquals(24D, view.progress().sixtySecondChunksPerSecond(), 0D);
|
||||
assertEquals(2L, view.progress().failed());
|
||||
assertEquals(1234L, view.usedMemoryBytes());
|
||||
assertEquals(0.25D, view.memoryUsage(), 0D);
|
||||
assertEquals(256L, view.allocationBytesPerSecond());
|
||||
assertTrue(view.cached());
|
||||
assertSame(view, fixture.job.renderSnapshot());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void stoppingAndFinishedPhasesCannotBeOverwrittenByTickOrSave() throws Exception {
|
||||
Fixture fixture = new Fixture();
|
||||
fixture.stopping.set(true);
|
||||
fixture.tick();
|
||||
assertEquals(PregenRenderSnapshot.Phase.STOPPING, fixture.job.renderSnapshot().phase());
|
||||
fixture.job.onSaving();
|
||||
assertEquals(PregenRenderSnapshot.Phase.STOPPING, fixture.job.renderSnapshot().phase());
|
||||
fixture.stopping.set(false);
|
||||
fixture.set("finished", true);
|
||||
fixture.tick();
|
||||
assertEquals(PregenRenderSnapshot.Phase.STOPPING, fixture.job.renderSnapshot().phase());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pausedAndErrorStateKeepTheirPrecedence() throws Exception {
|
||||
Fixture fixture = new Fixture();
|
||||
when(fixture.pregenerator.paused()).thenReturn(true);
|
||||
fixture.job.onSaving();
|
||||
assertEquals(PregenRenderSnapshot.Phase.PAUSED, fixture.job.renderSnapshot().phase());
|
||||
assertTrue(fixture.job.renderSnapshot().progress().paused());
|
||||
fixture.set("failure", "Preparation failed");
|
||||
fixture.tick();
|
||||
assertEquals(PregenRenderSnapshot.Phase.ERROR, fixture.job.renderSnapshot().phase());
|
||||
assertEquals("Preparation failed", fixture.job.renderSnapshot().failure());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void finishedWindowCannotPauseItsReplacementJob() throws Exception {
|
||||
Fixture previous = new Fixture();
|
||||
Fixture replacement = new Fixture();
|
||||
Runnable queuedPause = previous.job::togglePause;
|
||||
previous.set("finished", true);
|
||||
Field field = PregeneratorJob.class.getDeclaredField("instance");
|
||||
field.setAccessible(true);
|
||||
@SuppressWarnings("unchecked")
|
||||
AtomicReference<PregeneratorJob> instance = (AtomicReference<PregeneratorJob>) field.get(null);
|
||||
PregeneratorJob original = instance.getAndSet(replacement.job);
|
||||
try {
|
||||
queuedPause.run();
|
||||
verifyNoInteractions(previous.pregenerator, replacement.pregenerator);
|
||||
} finally {
|
||||
instance.set(original);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class Fixture {
|
||||
private final PregeneratorJob job = mock(PregeneratorJob.class, CALLS_REAL_METHODS);
|
||||
private final IrisPregenerator pregenerator = mock(IrisPregenerator.class);
|
||||
private final AtomicBoolean stopping = new AtomicBoolean();
|
||||
|
||||
private Fixture() throws Exception {
|
||||
MemoryMonitor monitor = mock(MemoryMonitor.class);
|
||||
when(monitor.getUsedBytes()).thenReturn(1234L);
|
||||
when(monitor.getUsagePercent()).thenReturn(0.25D);
|
||||
when(monitor.getPressure()).thenReturn(256L);
|
||||
when(pregenerator.getRates()).thenReturn(new PregenRates(7D, 12D, 18D, 24D));
|
||||
set("bounds", new PregenRenderSnapshot.Bounds(-5, 2, 8, 12));
|
||||
set("pregenerator", pregenerator);
|
||||
set("monitor", monitor);
|
||||
set("stopRequested", stopping);
|
||||
set("saving", new AtomicBoolean());
|
||||
set("onProgress", List.of());
|
||||
set("apiPhases", new PregenPhaseTracker());
|
||||
}
|
||||
|
||||
private void tick() {
|
||||
job.onTick(12D, 720D, 1D, 0.5D, 5L, 10L, 3L, 1000L, 2500L, "Async", true);
|
||||
}
|
||||
|
||||
private void set(String name, Object value) throws Exception {
|
||||
Field field = PregeneratorJob.class.getDeclaredField(name);
|
||||
field.setAccessible(true);
|
||||
field.set(job, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -45,7 +45,10 @@ import java.util.IdentityHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.FutureTask;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
@@ -554,6 +557,109 @@ public class IrisEngineGenerationRuntimeScopeTest {
|
||||
assertThrows(IllegalStateException.class, () -> engine.getHeight(0, 0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void publishedRouterLookupDoesNotWaitForTheAttachmentMonitor() throws Exception {
|
||||
RuntimeFixture active = runtime(1, 1D, 1D, 1D);
|
||||
IrisEngine engine = engine(active.runtime, mock(EngineEffects.class), mock(EngineWorldManager.class));
|
||||
GenerationHistoryRuntimeRouter router = historyRouter(engine);
|
||||
engine.attachGenerationHistoryRuntimeRouter(router);
|
||||
FutureTask<Optional<GenerationHistoryRuntimeRouter>> read = new FutureTask<>(engine::getGenerationHistoryRuntimeRouter);
|
||||
Thread reader = new Thread(read, "History router lookup");
|
||||
|
||||
try {
|
||||
synchronized (engine.generationHistoryRuntimeRouterLock) {
|
||||
reader.start();
|
||||
assertSame(router, read.get(5, TimeUnit.SECONDS).orElseThrow());
|
||||
}
|
||||
} finally {
|
||||
reader.join(5_000L);
|
||||
assertTrue("Router lookup did not finish", !reader.isAlive());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void publishedCoordinateReadDoesNotWaitForTheAttachmentMonitor() throws Exception {
|
||||
RuntimeFixture active = runtime(1, 1D, 1D, 1D);
|
||||
IrisEngine engine = engine(active.runtime, mock(EngineEffects.class), mock(EngineWorldManager.class));
|
||||
GenerationHistoryRuntimeRouter router = historyRouter(engine);
|
||||
engine.attachGenerationHistoryRuntimeRouter(router);
|
||||
GenerationHistoryRuntimeRouter.CoordinateScope scope = mock(GenerationHistoryRuntimeRouter.CoordinateScope.class);
|
||||
when(router.openCoordinateScope(-17, 32)).thenReturn(scope);
|
||||
FutureTask<GenerationHistoryRuntimeRouter.CoordinateScope> read =
|
||||
new FutureTask<>(() -> engine.openGenerationHistoryCoordinateScope(-17, 32));
|
||||
Thread reader = new Thread(read, "History coordinate read");
|
||||
|
||||
try {
|
||||
synchronized (engine.generationHistoryRuntimeRouterLock) {
|
||||
reader.start();
|
||||
assertSame(scope, read.get(5, TimeUnit.SECONDS));
|
||||
}
|
||||
} finally {
|
||||
reader.join(5_000L);
|
||||
assertTrue("Coordinate read did not finish", !reader.isAlive());
|
||||
}
|
||||
verify(router).openCoordinateScope(-17, 32);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void missingRouterReadWaitsForAttachmentPublication() throws Exception {
|
||||
RuntimeFixture active = runtime(1, 1D, 1D, 1D);
|
||||
IrisEngine engine = engine(active.runtime, mock(EngineEffects.class), mock(EngineWorldManager.class));
|
||||
GenerationHistoryRuntimeRouter router = historyRouter(engine);
|
||||
GenerationHistoryRuntimeRouter.CoordinateScope scope = mock(GenerationHistoryRuntimeRouter.CoordinateScope.class);
|
||||
when(router.openCoordinateScope(-17, 32)).thenReturn(scope);
|
||||
CountDownLatch started = new CountDownLatch(1);
|
||||
FutureTask<GenerationHistoryRuntimeRouter.CoordinateScope> read = new FutureTask<>(() -> {
|
||||
started.countDown();
|
||||
return engine.openGenerationHistoryCoordinateScope(-17, 32);
|
||||
});
|
||||
Thread reader = new Thread(read, "Pending history attachment");
|
||||
|
||||
try {
|
||||
synchronized (engine.generationHistoryRuntimeRouterLock) {
|
||||
reader.start();
|
||||
assertTrue(started.await(5, TimeUnit.SECONDS));
|
||||
awaitBlocked(reader);
|
||||
engine.attachGenerationHistoryRuntimeRouter(router);
|
||||
}
|
||||
assertSame(scope, read.get(5, TimeUnit.SECONDS));
|
||||
} finally {
|
||||
reader.join(5_000L);
|
||||
assertTrue("Pending router read did not finish", !reader.isAlive());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void detachedRouterReadRemainsFailClosedAcrossThreads() throws Exception {
|
||||
RuntimeFixture active = runtime(1, 1D, 1D, 1D);
|
||||
IrisEngine engine = engine(active.runtime, mock(EngineEffects.class), mock(EngineWorldManager.class));
|
||||
GenerationHistoryRuntimeRouter router = historyRouter(engine);
|
||||
engine.attachGenerationHistoryRuntimeRouter(router);
|
||||
CountDownLatch started = new CountDownLatch(1);
|
||||
FutureTask<GenerationHistoryRuntimeRouter.CoordinateScope> read = new FutureTask<>(() -> {
|
||||
started.countDown();
|
||||
return engine.openGenerationHistoryCoordinateScope(-17, 32);
|
||||
});
|
||||
Thread reader = new Thread(read, "Detached history read");
|
||||
|
||||
try {
|
||||
synchronized (engine.generationHistoryRuntimeRouterLock) {
|
||||
engine.detachGenerationHistoryRuntimeRouter(router);
|
||||
reader.start();
|
||||
assertTrue(started.await(5, TimeUnit.SECONDS));
|
||||
awaitBlocked(reader);
|
||||
}
|
||||
ExecutionException failure = assertThrows(ExecutionException.class, () -> read.get(5, TimeUnit.SECONDS));
|
||||
assertTrue(failure.getCause() instanceof IllegalStateException);
|
||||
assertEquals("Iris generation-history runtime router is detached.", failure.getCause().getMessage());
|
||||
assertTrue(engine.getGenerationHistoryRuntimeRouter().isEmpty());
|
||||
} finally {
|
||||
reader.join(5_000L);
|
||||
assertTrue("Detached router read did not finish", !reader.isAlive());
|
||||
}
|
||||
verify(router, never()).openCoordinateScope(anyInt(), anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void transferredMantleIsNotClosedWithTheRetiredRuntime() throws Exception {
|
||||
RuntimeFixture active = runtime(1, 1D, 1D, 1D);
|
||||
@@ -717,6 +823,14 @@ public class IrisEngineGenerationRuntimeScopeTest {
|
||||
return router;
|
||||
}
|
||||
|
||||
private static void awaitBlocked(Thread thread) throws InterruptedException {
|
||||
long deadline = System.nanoTime() + TimeUnit.SECONDS.toNanos(5L);
|
||||
while (thread.getState() != Thread.State.BLOCKED && thread.isAlive() && System.nanoTime() < deadline) {
|
||||
Thread.sleep(1L);
|
||||
}
|
||||
assertEquals(Thread.State.BLOCKED, thread.getState());
|
||||
}
|
||||
|
||||
private static IrisEngine engine(
|
||||
GenerationRuntime generationRuntime,
|
||||
EngineEffects effects,
|
||||
|
||||
Reference in New Issue
Block a user