tcr/java/src/game/gui/world/GuiCreate.java

321 lines
11 KiB
Java
Raw Normal View History

2025-03-11 00:23:54 +01:00
package game.gui.world;
import java.io.File;
2025-03-18 10:24:05 +01:00
2025-03-11 00:23:54 +01:00
import game.color.TextColor;
import game.dimension.DimType;
import game.dimension.Dimension;
import game.dimension.Space;
2025-03-17 18:21:41 +01:00
import game.gui.Gui;
import game.gui.element.ActButton;
2025-03-18 10:24:05 +01:00
import game.gui.element.ActButton.Mode;
2025-03-17 18:21:41 +01:00
import game.gui.element.Label;
import game.gui.element.Textbox;
import game.gui.element.Textbox.Action;
import game.gui.element.TransparentBox;
import game.init.Config;
2025-03-11 00:23:54 +01:00
import game.init.UniverseRegistry;
2025-03-17 18:21:41 +01:00
import game.log.Log;
import game.nbt.NBTLoader;
import game.nbt.NBTTagCompound;
2025-03-11 00:23:54 +01:00
import game.network.NetHandlerPlayServer;
import game.rng.Random;
2025-03-17 18:21:41 +01:00
import game.util.Util;
2025-03-11 00:23:54 +01:00
import game.world.Region;
2025-03-17 18:21:41 +01:00
import game.world.World;
2025-03-11 00:23:54 +01:00
2025-03-17 18:21:41 +01:00
public class GuiCreate extends Gui implements ActButton.Callback, Textbox.Callback
2025-03-11 00:23:54 +01:00
{
2025-03-17 18:21:41 +01:00
public static final GuiCreate INSTANCE = new GuiCreate();
2025-03-11 00:23:54 +01:00
private static final String MBASE32_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ!?-_<3";
private static final String MBASE64A_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-!";
private static final String MBASE64B_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz<_";
2025-03-17 18:21:41 +01:00
private Textbox worldNameField;
private Textbox worldSeedField;
private Textbox worldUserField;
private ActButton dimButton;
private ActButton createButton;
private Label actionLabel;
private Label nameLabel;
private Label userLabel;
private Label seed;
private Label decoded;
private TransparentBox descLines;
2025-03-11 00:23:54 +01:00
private boolean alreadyGenerated;
private boolean fileExists;
private int dimension;
private static long getSeed(String str) {
if(str == null || str.isEmpty())
return (new Random()).longv();
try {
return Long.parseLong(str);
}
catch(NumberFormatException e) {
}
long seed = 0L;
if(str.length() <= 9) {
for(int z = 0; z < str.length(); z++) {
seed <<= 7;
char c = str.charAt(z);
if(c >= 0x80) {
seed = -1L;
break;
}
seed |= (long)c;
}
}
else if(str.length() == 10) {
String ch = str.indexOf('<') != -1 || str.indexOf('_') != -1 ? MBASE64B_CHARS : MBASE64A_CHARS;
for(int z = 0; z < str.length(); z++) {
seed <<= 6;
int idx = ch.indexOf(str.charAt(z));
if(idx == -1) {
seed = -1L;
break;
}
seed |= (long)idx;
}
if(seed != -1L)
seed |= ch == MBASE64B_CHARS ? 0xb000000000000000L : 0xa000000000000000L;
}
else if(str.length() <= 12) {
for(int z = 0; z < str.length(); z++) {
seed <<= 5;
int idx = MBASE32_CHARS.indexOf(Character.toUpperCase(str.charAt(z)));
if(idx == -1) {
seed = -1L;
break;
}
seed |= (long)idx;
}
if(seed != -1L)
seed |= str.length() == 12 ? 0x9000000000000000L : 0x8000000000000000L;
}
else {
seed = -1L;
}
if(seed == -1L) {
seed = 0L;
for(int z = 0; z < str.length(); z++) {
seed <<= 7;
seed |= (long)((char)(str.charAt(z) & 0x7f));
}
seed = (seed ^ (((long)str.hashCode()) | (~((long)str.hashCode()) << 32))) | 0xc000000000000000L;
}
return seed;
}
private static String decodeSeed(long seed, String def) {
if(seed == 0L)
return (def == null ? ("" + seed) : def);
if((seed & 0x8000000000000000L) == 0L) {
String str = "";
long value = seed;
while(value != 0L) {
char c = (char)(value & 0x7fL);
if(c < 32 || c > 126)
return (def == null ? ("" + seed) : def);
str = c + str;
value >>= 7;
}
try {
Long.parseLong(str);
}
catch(NumberFormatException e) {
return str;
}
return (def == null ? ("" + seed) : def);
}
String chset;
int len;
int shift;
long mask;
long type = (seed >> 60) & 0xf;
switch((int)type) {
case 0x8:
chset = MBASE32_CHARS;
len = 11;
shift = 5;
mask = 0x1fL;
break;
case 0x9:
chset = MBASE32_CHARS;
len = 12;
shift = 5;
mask = 0x1fL;
break;
case 0xa:
chset = MBASE64A_CHARS;
len = 10;
shift = 6;
mask = 0x3fL;
break;
case 0xb:
chset = MBASE64B_CHARS;
len = 10;
shift = 6;
mask = 0x3fL;
break;
default:
return (def == null ? ("" + seed) : def);
}
String str = "";
for(int z = 0; z < len; z++) {
str = chset.charAt((int)(seed & mask)) + str;
seed >>= shift;
}
try {
Long.parseLong(str);
}
catch(NumberFormatException e) {
return str;
}
return (def == null ? ("" + seed) : def);
}
2025-03-17 18:21:41 +01:00
private GuiCreate()
2025-03-11 00:23:54 +01:00
{
}
public void updateScreen()
{
String text = this.worldSeedField.getText();
if(text.isEmpty()) {
2025-03-17 18:21:41 +01:00
this.seed.setText("Startwert [Zufällig]");
this.decoded.setText("Dekodiert: -");
2025-03-11 00:23:54 +01:00
}
else {
2025-03-17 18:21:41 +01:00
this.seed.setText("Startwert [" + getSeed(text) + "]");
2025-03-11 00:23:54 +01:00
try {
2025-03-17 18:21:41 +01:00
this.decoded.setText("Dekodiert: " + decodeSeed(Long.parseLong(text), "-"));
2025-03-11 00:23:54 +01:00
}
catch(NumberFormatException e) {
2025-03-17 18:21:41 +01:00
this.decoded.setText("Dekodiert: " + decodeSeed(getSeed(text), "-"));
2025-03-11 00:23:54 +01:00
}
}
this.fileExists = false;
text = this.worldNameField.getText().trim();
2025-03-17 18:21:41 +01:00
this.createButton.enabled = !text.isEmpty() && !this.worldUserField.getText().isEmpty();
2025-03-11 00:23:54 +01:00
if(this.fileExists = (!text.isEmpty() && new File(Region.SAVE_DIR, text).exists()))
2025-03-17 18:21:41 +01:00
this.createButton.enabled = false;
this.actionLabel.setText(this.getFolderDesc());
this.userLabel.setText(this.getUserDesc());
2025-03-11 00:23:54 +01:00
}
2025-03-17 18:21:41 +01:00
public void init(int width, int height)
2025-03-11 00:23:54 +01:00
{
2025-03-17 18:21:41 +01:00
UniverseRegistry.clear();
this.alreadyGenerated = false;
this.dimension = Integer.MAX_VALUE;
this.createButton = this.add(new ActButton(width / 2 - 155, height - 28, 150, 20, (ActButton.Callback)this, "Neue Welt erstellen"));
this.add(new ActButton(width / 2 + 5, height - 28, 150, 20, (Gui)GuiWorlds.INSTANCE, "Abbrechen"));
this.dimButton = this.add(new ActButton(width / 2 - 155, 220, 310, 20, (ActButton.Callback)this, ""));
this.worldNameField = this.add(new Textbox(width / 2 - 100, 60, 200, 20, 256, true, this, GuiWorlds.VALID_FILE, ""));
this.worldNameField.setSelected();
this.worldSeedField = this.add(new Textbox(width / 2 - 100, 136, 200, 20, 256, true, this, ""));
this.worldUserField = this.add(new Textbox(width / 2 - 100, 98, 200, 20, NetHandlerPlayServer.MAX_USER_LENGTH, true, this, NetHandlerPlayServer.VALID_USER, ""));
this.createButton.enabled = false;
this.actionLabel = this.add(new Label(width / 2 - 100, 49, 200, 20, this.getFolderDesc(), true));
this.userLabel = this.add(new Label(width / 2 - 100, 87, 200, 20, this.getUserDesc(), true));
this.seed = this.add(new Label(width / 2 - 100, 125, 200, 20, "", true));
this.decoded = this.add(new Label(width / 2 - 100, 160, 200, 20, "", true));
this.descLines = this.add(new TransparentBox(width / 2 - 153, 242, 306, 160, ""));
2025-03-11 00:23:54 +01:00
this.setDimButton();
}
2025-03-17 18:21:41 +01:00
public String getTitle() {
return "Neue Welt erstellen";
}
2025-03-11 00:23:54 +01:00
private void setDimButton() {
Dimension dim = this.dimension == Integer.MAX_VALUE ? Space.INSTANCE : UniverseRegistry.getBaseDimensions().get(this.dimension);
2025-03-17 18:21:41 +01:00
this.dimButton.setText((dim == Space.INSTANCE ? "" :
2025-03-11 00:23:54 +01:00
((dim.getDimensionId() >= UniverseRegistry.MORE_DIM_ID ?
"Vorlage" : (dim.getType() == DimType.PLANET ? "Heimplanet" : "Dimension")) + ": ")) +
(dim.getDimensionId() >= UniverseRegistry.MORE_DIM_ID ? dim.getCustomName() :
2025-03-17 18:21:41 +01:00
dim.getFormattedName(false)));
2025-03-20 11:32:45 +01:00
String name = dim.getFormattedName(true);
int index = name.indexOf(" / ");
this.descLines.setText(index >= 0 ? Util.buildLines(name.substring(index + " / ".length()).split(" / ")) : "");
2025-03-11 00:23:54 +01:00
}
2025-03-17 18:21:41 +01:00
public void use(ActButton button, Mode mode)
2025-03-11 00:23:54 +01:00
{
2025-03-17 18:21:41 +01:00
if (button == this.createButton)
2025-03-11 00:23:54 +01:00
{
2025-03-17 18:21:41 +01:00
// this.gm.displayGuiScreen(null);
if(this.alreadyGenerated)
return;
this.alreadyGenerated = true;
Config.clear();
UniverseRegistry.clear();
Dimension dim = this.dimension == Integer.MAX_VALUE ? Space.INSTANCE :
UniverseRegistry.getBaseDimensions().get(this.dimension);
dim.setSeed(getSeed(this.worldSeedField.getText()));
File dir = new File(Region.SAVE_DIR, this.worldNameField.getText().trim());
Dimension[] dims = UniverseRegistry.registerPreset(dim);
Config.set("spawnDim", "" + dims[0].getDimensionId(), null);
Region.saveWorldInfo(dir, World.START_TIME, this.worldUserField.getText());
for(Dimension sdim : dims) {
NBTTagCompound data = new NBTTagCompound();
data.setTag("Generator", sdim.toNbt(true));
File chunkDir = new File(new File(dir, "chunk"), sdim.getDimensionName());
chunkDir.mkdirs();
File file = new File(chunkDir, "data.nbt");
try {
NBTLoader.writeGZip(data, file);
}
catch(Exception e) {
Log.IO.error(e, "Konnte Weltdaten nicht speichern");
}
2025-03-11 00:23:54 +01:00
}
2025-03-17 18:21:41 +01:00
this.gm.startServer(dir, this.worldUserField.getText());
}
else if (button == this.dimButton)
{
if(mode == Mode.TERTIARY) {
this.dimension = Integer.MAX_VALUE;
}
else if(this.dimension == Integer.MAX_VALUE) {
this.dimension = mode == Mode.SECONDARY ? UniverseRegistry.getBaseDimensions().size() - 1 : 0;
}
else {
if(mode == Mode.SECONDARY) {
if(--this.dimension < 0)
this.dimension = Integer.MAX_VALUE;
2025-03-11 00:23:54 +01:00
}
else {
2025-03-17 18:21:41 +01:00
if(++this.dimension >= UniverseRegistry.getBaseDimensions().size())
this.dimension = Integer.MAX_VALUE;
2025-03-11 00:23:54 +01:00
}
2025-03-17 18:21:41 +01:00
}
this.setDimButton();
2025-03-11 00:23:54 +01:00
}
}
2025-03-17 18:21:41 +01:00
public void use(Textbox elem, Action action) {
if(action == Action.SEND)
this.use(this.createButton, Mode.PRIMARY);
}
private String getFolderDesc() {
// FontRenderer.drawStringWithShadow("Startwert [" + this.seed + "]", this.width / 2 - 100, 125, -6250336);
// FontRenderer.drawStringWithShadow("Dekodiert: " + this.decoded, this.width / 2 - 100, 160, -6250336);
// FontRenderer.drawStringWithShadow(, this.width / 2 - 100, 49, -6250336);
// FontRenderer.drawStringWithShadow((this.worldUserField.getText().isEmpty() ? TextColor.DARK_RED : "") + "Spielername", this.width / 2 - 100, 87, -6250336);
//
// for(int z = 1; z < this.descLines.length; z++) {
// FontRenderer.drawStringWithShadow(this.descLines[z], this.width / 2 - 153, 242 + (z - 1) * (FontRenderer.FONT_HEIGHT + 1), -6250336);
// }
return (this.worldNameField.getText().trim().isEmpty() || this.fileExists ? TextColor.DRED : "")
+ "Ordner der Welt" + (this.fileExists ? " - Existiert bereits" : "");
2025-03-11 00:23:54 +01:00
}
2025-03-17 18:21:41 +01:00
private String getUserDesc() {
return (this.worldUserField.getText().isEmpty() ? TextColor.DRED : "") + "Spielername";
}
2025-03-11 00:23:54 +01:00
}