Minecraft Wiki
Advertisement

Random Code

I hereby release all of my rights to the code contained within this section.

Finding .minecraft (Java)

static final File getMinecraftWorkingDir() {
	String home = System.getProperty("user.home", ".");
	String os = System.getProperty("os.name").toLowerCase();
	if (os.contains("solaris") || os.contains("sunos")
	    || os.contains("linux") || os.contains("unix"))
		return new File(home, ".minecraft/");
	else if (os.contains("win")) {
		String appdata = System.getenv("APPDATA");
		return new File(appdata != null ? appdata : home, ".minecraft/");
	} else if (os.contains("mac"))
		return new File(home, "Library/Application Support/minecraft/");
	return new File(home, "minecraft/");
}

Reading lastlog File (Java)

Cipher.getInstance is expensive, so here it is only called once and the result is stored as a static final.

To get the default lastlogin file, use: new File(getMinecraftWorkingDir(), "lastlogin");

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
public static class UserData {
	public String username;
	public String password;
	
	public UserData(final String username, final String password) {
		this.username = username;
		this.password = password;
	}
}

private static final SecretKey        key       = getKey();
private static final PBEParameterSpec paramspec = getParamSpec();
private static final Cipher           cipher    = getCipher();

private static final Cipher getCipher() {
	try {
		return Cipher.getInstance("PBEWithMD5AndDES");
	} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {}
	return null;
}

private static final SecretKey getKey() {
	try {
		return SecretKeyFactory.getInstance("PBEWithMD5AndDES")
		    .generateSecret(new PBEKeySpec("passwordfile".toCharArray()));
	} catch (InvalidKeySpecException | NoSuchAlgorithmException e) {}
	return null;
}

private static final PBEParameterSpec getParamSpec() {
	return new PBEParameterSpec(new byte[] { 0x0C, (byte) 0x9D, 0x4A,
	    (byte) 0xE4, 0x1E, (byte) 0x83, 0x15, (byte) 0xFC }, 5);
}

private static synchronized boolean initCipher(final int mode) {
	try {
		cipher.init(mode, key, paramspec);
		return true;
	} catch (InvalidKeyException | InvalidAlgorithmParameterException
	    | NullPointerException e) {}
	return false;
}

public static void main(final String[] args) throws IOException {
	UserData data = load(new File(Minecraft.DEFAULT_WORKDIR, "lastlogin"));
	System.out.println(data.username);
	System.out.println(data.password);
	
}

public static synchronized UserData load(final File file)
    throws IOException {
	@SuppressWarnings("resource")
	final DataInputStream dis = new DataInputStream(
	    initCipher(Cipher.DECRYPT_MODE)
	        ? new CipherInputStream(new FileInputStream(file), cipher)
	        : new FileInputStream(file));
	final UserData data = new UserData(dis.readUTF(), dis.readUTF());
	dis.close();
	return data;
}

public static synchronized void save(final File file,
    final UserData data) throws IOException {
	final DataOutputStream dos = new DataOutputStream(
	    initCipher(Cipher.ENCRYPT_MODE)
	        ? new CipherOutputStream(new FileOutputStream(file), cipher)
	        : new FileOutputStream(file));
	dos.writeUTF(data.username);
	dos.writeUTF(data.password);
	dos.close();
}
Advertisement