initial commit

This commit is contained in:
Sen 2025-03-11 00:23:54 +01:00 committed by Sen
parent 3c9ee26b06
commit 22186c33b9
1458 changed files with 282792 additions and 0 deletions

View file

@ -0,0 +1,633 @@
package game.gui.world;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.Set;
import game.ActButton;
import game.CharValidator;
import game.ActButton.Mode;
import game.Drawing;
import game.FileCallback;
import game.FileUtils;
import game.GuiMenu;
import game.Log;
import game.WCF;
import game.collect.Sets;
import game.color.TextColor;
import game.dimension.Dimension;
import game.gui.GuiConfirm;
import game.gui.GuiList;
import game.gui.ListEntry;
import game.gui.world.GuiEdit.Callback;
import game.init.Config;
import game.init.UniverseRegistry;
import game.nbt.NBTLoader;
import game.nbt.NBTTagCompound;
import game.world.Converter;
import game.world.Converter.SaveVersion;
import game.world.Region;
import game.world.World;
import game.world.Region.FolderInfo;
public class GuiWorlds extends GuiList<GuiWorlds.SaveInfo> implements ActButton.Callback
{
protected class SaveInfo implements Comparable<SaveInfo>, ListEntry {
private final String file;
private final String name;
private final long seed;
private final FolderInfo info;
public SaveInfo(String file, String name, long seed, FolderInfo info) {
this.file = file;
this.name = name;
this.seed = seed;
this.info = info;
}
public String getFile() {
return this.file;
}
public String getName() {
return this.name == null ? "<?>" : this.name;
}
public String getUser() {
return this.info.user == null ? "<?>" : this.info.user;
}
public String getUsername() {
return this.info.user;
}
public boolean mustConvert() {
return this.info.legacy != null;
}
public String getVersion() {
return this.info.legacy == null ? (this.info.version == null ? "<Unbekannt>" : this.info.version) : this.info.legacy.toString();
}
public boolean isIncompatible() {
return this.info.legacy == SaveVersion.RELEASE_1_13;
}
public long getLastPlayed() {
return this.info.lastPlayed;
}
public long getSeed() {
return this.seed;
}
public int compareTo(SaveInfo comp) {
return this.info.lastPlayed < comp.info.lastPlayed ? 1 : (this.info.lastPlayed > comp.info.lastPlayed ? -1 : this.file.compareTo(comp.file));
}
public void select(boolean isDoubleClick, int mouseX, int mouseY)
{
boolean use = !this.isIncompatible();
boolean cur = use && !this.mustConvert();
GuiWorlds.this.selectButton.setText(!use || !cur ? "Konvertieren" : "Welt spielen");
GuiWorlds.this.selectButton.enabled = use;
GuiWorlds.this.deleteButton.enabled = true;
GuiWorlds.this.pruneButton.enabled = cur;
GuiWorlds.this.copyButton.enabled = use;
GuiWorlds.this.moveButton.enabled = use;
GuiWorlds.this.seedButton.enabled = cur;
GuiWorlds.this.userButton.enabled = cur;
GuiWorlds.this.dupeButton.enabled = cur;
if (isDoubleClick && use)
{
GuiWorlds.this.playWorld(null);
}
}
public void draw(int x, int y, int mouseXIn, int mouseYIn, boolean hover)
{
Drawing.drawText((this.isIncompatible() ? TextColor.DRED : "") + this.getFile() + (this.mustConvert() ? "" :
(TextColor.GRAY + " - " + TextColor.RESET + this.getUser())), x + 2, y, 0xffffffff);
Drawing.drawText((this.mustConvert() ? (this.isIncompatible() ? TextColor.CRIMSON : "") + this.getVersion() : this.getName())
, x + 2, y + 18, 0xff808080);
Drawing.drawText(this.mustConvert() ? (this.isIncompatible() ? TextColor.CRIMSON + "Kann nicht konvertiert werden!" :
"Muss konvertiert werden!") : ( // "Kreativmodus: " + (info.isNoCreative() ? "Aus" : "An") +
"Zuletzt gespielt: " + DATE_FORMAT.format(new Date(this.getLastPlayed()))) + " " + TextColor.LGRAY + this.getVersion(), x + 2, y + 18 + 16, 0xff808080);
}
}
public static final GuiWorlds INSTANCE = new GuiWorlds();
public static final Set<Character> DISALLOWED_CHARS = Sets.newHashSet('/', '\n', '\r', '\t', '\u0000', '\f', '`', '?', '*', '\\',
'<', '>', '|', '\"', ':');
public static final CharValidator VALID_FILE = new CharValidator() {
public boolean valid(char ch) {
return !DISALLOWED_CHARS.contains(ch);
}
};
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss");
private boolean starting;
private int warningTimer;
private String warningMessage;
private ActButton deleteButton;
private ActButton pruneButton;
private ActButton selectButton;
private ActButton copyButton;
private ActButton moveButton;
private ActButton seedButton;
private ActButton userButton;
private ActButton dupeButton;
private ActButton createButton;
private GuiWorlds()
{
}
public void init(int width, int height)
{
this.starting = false;
this.setDimensions(width, height, 48, height - 64);
boolean create = true;
this.elements.clear();
try
{
Region.SAVE_DIR.mkdirs();
if(!Region.SAVE_DIR.exists() || !Region.SAVE_DIR.isDirectory())
throw new RuntimeException("Kann den Speicherordner für Welten nicht lesen oder öffnen!");
// java.util.List<SaveInfo> list = Lists.<SaveInfo>newArrayList();
File[] files = Region.SAVE_DIR.listFiles();
if(files == null)
throw new RuntimeException("Kann den Speicherordner für Welten nicht lesen oder öffnen!");
for(File file : files) {
if(!file.isDirectory())
continue;
FolderInfo info = Region.loadWorldInfo(file);
if(info == null)
info = Converter.convertMapFormat(file, null);
if(info == null) {
this.elements.add(new SaveInfo(file.getName(), null,
0L, new FolderInfo(World.START_TIME, null, file.lastModified(), null, null)));
continue;
}
Dimension dim = info.legacy != null ? null : UniverseRegistry.getDimension(Config.spawnDim);
if(dim != null) {
File dat = new File(new File(new File(new File(Region.SAVE_DIR, file.getName()), "chunk"),
dim.getDimensionName()), "data.nbt");
try {
dim.fromNbt(NBTLoader.readGZip(dat).getCompoundTag("Generator"));
}
catch(Exception e) {
}
}
this.elements.add(new SaveInfo(file.getName(), dim == null ? null : TextColor.stripCodes(dim.getFormattedName(true)),
dim == null ? 0L : dim.getSeed(), info));
}
// this.saveList = list;
Collections.sort(this.elements);
}
catch (Exception e)
{
Log.IO.error("Konnte Weltliste nicht laden", e);
this.elements.clear();
create = false;
this.warningTimer = 120;
this.warningMessage = "Welten-Ordner nicht lesbar!";
}
this.add(this.selectButton = new ActButton(width / 2 - 153 - 39, height - 52, 72, 20, (ActButton.Callback)this, "Welt spielen"));
this.add(this.createButton = new ActButton(width / 2 + 81 + 72 + 6 - 39, height - 52, 72, 20, (ActButton.Callback)this,
(create ? "" : "" + TextColor.DRED) + (create ? "Neue Welt ..." : "Fehler!")));
this.add(this.deleteButton = new ActButton(width / 2 - 75 - 39, height - 28, 72, 20, (ActButton.Callback)this, "Löschen"));
this.add(this.pruneButton = new ActButton(width / 2 + 3 - 39, height - 28, 72, 20, (ActButton.Callback)this, "Leeren"));
this.add(this.copyButton = new ActButton(width / 2 - 153 - 39, height - 28, 72, 20, (ActButton.Callback)this, "Kopieren"));
this.add(this.moveButton = new ActButton(width / 2 + 81 - 39, height - 28, 72, 20, (ActButton.Callback)this, "Verschieben"));
this.add(this.seedButton = new ActButton(width / 2 + 3 - 39, height - 52, 72, 20, (ActButton.Callback)this, "Startwert"));
this.add(this.userButton = new ActButton(width / 2 - 75 - 39, height - 52, 72, 20, (ActButton.Callback)this, "Spieler"));
this.add(this.dupeButton = new ActButton(width / 2 + 81 - 39, height - 52, 72, 20, (ActButton.Callback)this, "Duplizieren"));
this.add(new ActButton(width / 2 + 81 + 72 + 6 - 39, height - 28, 72, 20, GuiMenu.INSTANCE, "Abbrechen"));
this.add(new ActButton(20, 20, 200, 24, new ActButton.Callback() {
public void use(ActButton elem, ActButton.Mode action) {
if(GuiWorlds.this.gm.theWorld != null)
return;
GuiWorlds.this.gm.showDirDialog("Welt öffnen", "saves", new FileCallback() {
public void selected(File file) {
if(GuiWorlds.this.gm.theWorld == null && GuiWorlds.this.gm.open instanceof GuiWorlds)
GuiWorlds.this.gm.startServer(file, "sen");
}
});
}
}, "Welt laden"));
this.selectButton.enabled = false;
this.deleteButton.enabled = false;
this.pruneButton.enabled = false;
this.copyButton.enabled = false;
this.moveButton.enabled = false;
this.seedButton.enabled = false;
this.userButton.enabled = false;
this.dupeButton.enabled = false;
this.createButton.enabled = create;
}
public String getTitle() {
return "Welt auswählen";
}
public int getListWidth()
{
return 660;
}
public int getSlotHeight()
{
return 56;
}
public void updateScreen() {
super.updateScreen();
// this.userField.updateCursorCounter();
if(this.warningTimer > 0) {
if(--this.warningTimer == 0) {
this.warningMessage = null;
}
}
}
// /**
// * Handles mouse input.
// */
// public void handleMouseInput() throws IOException
// {
// super.handleMouseInput();
// this.availableWorlds.handleMouseInput();
// }
// private void loadLevelList() {
//
// }
private String getSaveAt()
{
return this.getSelected().getFile();
}
// protected String getNameAt(int index)
// {
// String s = ((SaveInfo)this.saveList.get(index)).getName();
//
// if (s == null || s.isEmpty())
// {
// s = I18n.format("selectWorld.world") + " " + (index + 1);
// }
//
// return s;
// }
// public void addWorldSelectionButtons(boolean create)
// {
//// this.userField = new TextField(this.width / 2 + 4 + 2, 26, 146, 16);
//// this.userField.setMaxStringLength(16);
//// this.userField.setText(this.gm.localUser);
//// this.userField.setValidator(new Predicate<String>()
//// {
//// public boolean apply(String name)
//// {
//// return StringValidator.isValidUser(name);
//// }
//// });
// }
public void use(ActButton button, Mode mode)
{
// if (button.enabled)
// {
if (button == this.deleteButton)
{
String s = this.getSaveAt();
if (s != null)
{
GuiConfirm guiyesno = makeYesNo(this, s, false);
this.gm.displayGuiScreen(guiyesno);
}
}
else if (button == this.pruneButton)
{
String s = this.getSaveAt();
if (s != null)
{
GuiConfirm guiyesno = makeYesNo(this, s, true);
this.gm.displayGuiScreen(guiyesno);
}
}
else if (button == this.selectButton)
{
// if(isShiftKeyDown())
//
// else
this.playWorld(null);
}
else if (button == this.createButton)
{
if(GuiWorlds.this.gm.theWorld == null) {
if(this.gm.shift()) {
// this.gm.displayGuiScreen(null);
this.gm.startServer(null, "debug");
}
else {
// this.gm.displayGuiScreen(new GuiCreate(this)); //TODO: create
}
}
}
else if (button == this.userButton)
{
this.gm.displayGuiScreen(new GuiEdit(this.getSelected().getUsername(), true,
"Spieler für '" + this.getSaveAt() + "' ändern", "Ändern", "Spielername", new Callback() {
public void confirm(String name) {
if(name != null)
GuiWorlds.this.changeUser(name);
GuiWorlds.this.gm.displayGuiScreen(GuiWorlds.this);
}
}));
}
// else if (button.id == 0)
// {
// this.gm.displayGuiScreen(this.parentScreen);
// }
else if (button == this.dupeButton)
{
}
else if (button == this.copyButton)
{
this.gm.displayGuiScreen(new GuiEdit("", false,
"Welt '" + this.getSaveAt() + "' kopieren", "Kopieren", "Ordner der Welt", new Callback() {
public void confirm(String name) {
if(name != null)
GuiWorlds.this.copyWorld(name);
GuiWorlds.this.gm.displayGuiScreen(GuiWorlds.this);
}
}));
}
else if (button == this.moveButton)
{
this.gm.displayGuiScreen(new GuiEdit(this.getSaveAt(), false,
"Welt '" + this.getSaveAt() + "' verschieben", "Verschieben", "Ordner der Welt", new Callback() {
public void confirm(String name) {
if(name != null)
GuiWorlds.this.moveWorld(name);
GuiWorlds.this.gm.displayGuiScreen(GuiWorlds.this);
}
}));
}
else if (button == this.seedButton)
{
WCF.setClipboard("" + this.getSelected().getSeed());
this.warningTimer = 40;
this.warningMessage = TextColor.DGREEN + "Startwert wurde in die Zwischenablage kopiert";
}
// else
// {
// this.availableWorlds.actionPerformed(button);
// }
// }
}
private void copyWorld(String name) {
File oldDir = new File(Region.SAVE_DIR, this.getSaveAt());
// String name = this.getSaveAt(this.selectedIndex);
// while(new File(Region.SAVE_DIR, name).exists()) {
// name = name + "-";
// }
File newDir = new File(Region.SAVE_DIR, name);
Log.IO.info("Kopiere Welt " + oldDir + " nach " + newDir);
if(!copyFiles(oldDir, newDir, oldDir.listFiles())) {
this.warningTimer = 120;
this.warningMessage = "Fehler beim Kopieren der Welt, diese könnte unvollständig sein!";
}
// try
// {
// this.loadLevelList();
// }
// catch (Exception anvilconverterexception)
// {
// Log.error((String)"Konnte Weltliste nicht laden", (Throwable)anvilconverterexception);
// }
this.gm.displayGuiScreen(this);
}
private void moveWorld(String dest) {
File oldDir = new File(Region.SAVE_DIR, this.getSaveAt());
File newDir = new File(Region.SAVE_DIR, dest);
Log.IO.info("Kopiere Welt " + oldDir + " nach " + newDir);
if(!copyFiles(oldDir, newDir, oldDir.listFiles())) {
this.warningTimer = 120;
this.warningMessage = "Fehler beim Kopieren der Welt, diese könnte unvollständig sein!";
return;
}
if(!this.deleteWorld(false)) {
this.warningTimer = 120;
this.warningMessage = "Fehler beim Löschen der Welt!";
}
this.gm.displayGuiScreen(this);
}
private void changeUser(String user) {
File file = new File(new File(Region.SAVE_DIR, this.getSaveAt()), "level.nbt");
if(file.exists()) {
try {
NBTTagCompound tag = NBTLoader.readGZip(file);
tag.setString("Owner", user);
NBTLoader.writeGZip(tag, file);
}
catch(Exception e) {
Log.IO.error("Fehler beim Verarbeiten von " + file, e);
}
}
// this.gm.displayGuiScreen(this);
}
private void playWorld(String user)
{
if(GuiWorlds.this.gm.theWorld != null)
return;
// this.gm.displayGuiScreen(null);
if (!this.starting)
{
this.starting = true;
// int index = this.selectedIndex;
if(user == null)
user = this.getSelected().getUsername();
String dir = this.getSaveAt();
File folder = new File(Region.SAVE_DIR, dir);
if(folder.isDirectory()) {
if(user == null) {
this.gm.displayGuiScreen(new GuiEdit("", true,
"Spieler für '" + dir + "' festlegen", "Festlegen", "Spielername", new Callback() {
public void confirm(String name) {
if(name != null)
GuiWorlds.this.playWorld(name);
else
GuiWorlds.this.gm.displayGuiScreen(GuiWorlds.this);
}
}));
this.starting = false;
}
else {
if(this.getSelected().mustConvert()) {
this.gm.convert(folder, user);
this.gm.displayGuiScreen(this);
this.starting = false;
}
else {
this.gm.startServer(folder, user);
}
}
}
}
}
// public void confirmClicked(boolean result)
// {
// if (this.confirmingDelete >= 0 || this.confirmingPrune >= 0)
// {
// boolean prune = this.confirmingPrune >= 0;
// int id = prune ? this.confirmingPrune : this.confirmingDelete;
// this.confirmingDelete = -1;
// this.confirmingPrune = -1;
//
// if (result)
// {
//// Region.clearCache(true);
// if(!this.deleteWorld(prune)) {
// this.warningTimer = 120;
// this.warningMessage = "Fehler beim " + (prune ? "Leeren" : "Löschen") + " der Welt!";
// }
//
//// try
//// {
//// this.loadLevelList();
//// }
//// catch (Exception anvilconverterexception)
//// {
//// Log.error((String)"Konnte Weltliste nicht laden", (Throwable)anvilconverterexception);
//// }
// }
//
// this.gm.displayGuiScreen(this);
// }
// }
private boolean deleteWorld(final boolean pruneOnly)
{
File worldDir = new File(Region.SAVE_DIR, this.getSaveAt());
if (!worldDir.exists())
{
return true;
}
Log.IO.info((pruneOnly ? "Leere" : "Lösche") + " Welt " + worldDir);
boolean flag = false;
for (int i = 1; i <= 5; ++i)
{
Log.IO.info("Versuch " + i + "...");
if (FileUtils.deleteFiles(worldDir.listFiles(new FileFilter() {
public boolean accept(File file) {
return !pruneOnly || (file.isDirectory() ? file.getName().equals("chunk") : file.getName().equals("signs.nbt"));
}
})))
{
flag = true;
break;
}
Log.IO.warn("Konnte Inhalt nicht löschen.");
if (i < 5)
{
try
{
Thread.sleep(500L);
}
catch (InterruptedException e)
{
;
}
}
}
return pruneOnly ? flag : worldDir.delete();
}
private static boolean copyFiles(File source, File dest, File[] files)
{
dest.mkdirs();
if(files == null || !dest.isDirectory()) {
Log.IO.warn("Konnte Ordner " + source + " nicht nach " + dest + " kopieren");
return false;
}
boolean flag = true;
for (int i = 0; i < files.length; ++i)
{
File file = files[i];
File nfile = new File(dest, file.getName());
Log.IO.info("Kopiere " + file + " nach " + nfile);
if (file.isDirectory())
{
flag &= copyFiles(file, nfile, file.listFiles());
continue;
}
try {
Files.copy(file.toPath(), nfile.toPath(), StandardCopyOption.REPLACE_EXISTING);
// Files.copy(file, nfile);
}
catch(IOException e) {
Log.IO.error("Konnte Datei " + file + " nicht nach " + nfile + " kopieren", e);
flag = false;
}
}
return flag;
}
public void drawOverlays()
{
super.drawOverlays();
if(this.warningMessage != null) {
drawRect(this.gm.fb_x / 2 - 191, this.gm.fb_y - 82, this.gm.fb_x / 2 + 191, this.gm.fb_y - 66, 0xff808080);
drawRect(this.gm.fb_x / 2 - 190, this.gm.fb_y - 81, this.gm.fb_x / 2 + 190, this.gm.fb_y - 67, 0xff000000);
Drawing.drawText(this.warningMessage, this.gm.fb_x / 2, this.gm.fb_y - 78, 0xffff0000);
}
}
public static GuiConfirm makeYesNo(GuiWorlds selectWorld, String name, boolean prune)
{
String s = prune ? "Willst du diese Welt wirklich leeren?" : "Bist du sicher, dass du diese Welt löschen möchtest?";
String s1 = "\'" + name + "\' " + (prune ? "wird alle Daten außer dem Spieler und Einstellungen verlieren!"
: "wird für immer verloren sein! (Eine lange Zeit!)");
String s2 = prune ? "Leeren" : "Löschen";
String s3 = "Abbrechen";
GuiConfirm guiyesno = new GuiConfirm(new GuiConfirm.Callback() {
@Override
public void confirm(boolean confirmed) {
if(confirmed && !selectWorld.deleteWorld(prune)) {
selectWorld.warningTimer = 120;
selectWorld.warningMessage = "Fehler beim " + (prune ? "Leeren" : "Löschen") + " der Welt!";
}
selectWorld.gm.displayGuiScreen(selectWorld);
}
}, s, s1, s2, s3);
return guiyesno;
}
}