Added multiplayer and skins

This commit is contained in:
LAX1DUDE 2022-06-05 00:03:04 -07:00
parent 2d1b1686b5
commit 2640c2b045
75 changed files with 2542 additions and 10384 deletions

10
bukkit/readme.txt Normal file
View File

@ -0,0 +1,10 @@
To compile:
1. Link "src/main/java" as a source folder
2. Link "src/main/resources" as a source folder
3. Add "server/craftbukkit-bin.jar" to the build path as a dependency
4. Add "server/java_websocket.jar" to the build path as a dependency
5. Set "watchdog.WatchDog" as the main class
6. Export the project as a runnable jar file
You cannot run the project from within the IDE, you must export it every time as a runnable jar file for both testing and production.

View File

@ -0,0 +1,119 @@
package net.lax1dude.eaglercraft.beta.server;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import org.bukkit.util.config.Configuration;
public class EaglercraftConfig {
private Configuration yamlFile = null;
private boolean enablePasswordLoginValue = true;
private boolean requirePasswordLoginValue = true;
private boolean allowSelfRegistrationValue = false;
private boolean allowSelfRegistrationWithoutExpireValue = false;
private boolean allowSelfChangePasswordValue = true;
private boolean allowSelfRenewPasswordValue = true;
private boolean allowSelfRenewPasswordWithTimeValue = false;
private boolean allowSelfDeletePasswordValue = false;
private int defaultPasswordExpireTimeValue = 7 * 24 * 60 * 60;
private int maximumPasswordExpireTimeValue = 21 * 24 * 60 * 60;
private boolean allowPasswordsWithoutExpireValue = true;
private static final File configFile = new File("eagler.yml");
public boolean enablePasswordLogin() {
return enablePasswordLoginValue;
}
public boolean requirePasswordLogin() {
return requirePasswordLoginValue;
}
public boolean allowSelfRegistration() {
return allowSelfRegistrationValue;
}
public boolean allowSelfRegistrationWithoutExpire() {
return allowSelfRegistrationWithoutExpireValue;
}
public boolean allowSelfChangePassword() {
return allowSelfChangePasswordValue;
}
public boolean allowSelfRenewPassword() {
return allowSelfRenewPasswordValue;
}
public boolean allowSelfRenewPasswordWithTime() {
return allowSelfRenewPasswordWithTimeValue;
}
public boolean allowSelfDeletePassword() {
return allowSelfDeletePasswordValue;
}
public int defaultPasswordExpireTime() {
return defaultPasswordExpireTimeValue;
}
public int maximumPasswordExpireTime() {
return maximumPasswordExpireTimeValue;
}
public boolean allowPasswordsWithoutExpire() {
return allowPasswordsWithoutExpireValue;
}
public void reload() {
if(yamlFile == null) {
if(!configFile.exists()) {
InputStream is = EaglercraftConfig.class.getResourceAsStream("/default_eagler_config.yml");
if(is == null) {
System.err.println("The file '/default_eagler_config.yml' could not be located in this jar!");
return;
}
try(FileOutputStream os = new FileOutputStream(configFile)) {
byte[] buffer = new byte[1024];
int i;
while((i = is.read(buffer)) > 0) {
os.write(buffer, 0, i);
}
os.close();
}catch(IOException ex) {
System.err.println("The default config fould not be written! (writing '" + configFile.getName() + "')");
ex.printStackTrace();
}
try {
is.close();
} catch (IOException e) {
}
}
yamlFile = new Configuration(configFile);
yamlFile.load();
enablePasswordLoginValue = yamlFile.getBoolean("enable_password_logins", true);
}else {
yamlFile.load();
}
if(enablePasswordLoginValue != yamlFile.getBoolean("enable_password_logins", true)) {
System.err.println("Please restart the server when you change the 'enable_password_logins' option ");
}
requirePasswordLoginValue = yamlFile.getBoolean("only_allow_registered_users_to_login", true);
allowPasswordsWithoutExpireValue = yamlFile.getBoolean("allow_passwords_without_expiration", true);
allowSelfRegistrationValue = yamlFile.getBoolean("allow_self_registration", false);
allowSelfRegistrationWithoutExpireValue = yamlFile.getBoolean("allow_self_registration_without_expiration", false);
allowSelfChangePasswordValue = yamlFile.getBoolean("allow_self_change_password", true);
allowSelfRenewPasswordValue = yamlFile.getBoolean("allow_self_renew_password", true);
allowSelfRenewPasswordWithTimeValue = yamlFile.getBoolean("allow_self_change_password_expiration", false);
allowSelfDeletePasswordValue = yamlFile.getBoolean("allow_self_delete_password", false);
defaultPasswordExpireTimeValue = yamlFile.getInt("default_password_expire_time_seconds", 604800); // 1 week
maximumPasswordExpireTimeValue = yamlFile.getInt("maximum_password_expire_time_seconds", 1814400); // 1 week
}
}

View File

@ -2,21 +2,34 @@ package net.lax1dude.eaglercraft.beta.server;
import java.io.File;
import java.io.IOException;
import java.util.regex.Pattern;
import org.bukkit.Server;
import org.bukkit.command.Command;
import org.bukkit.command.CommandMap;
import org.bukkit.command.CommandSender;
import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.event.Event.Priority;
import org.bukkit.event.Event.Type;
import org.bukkit.event.Event;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerEvent;
import org.bukkit.event.player.PlayerListener;
import org.bukkit.plugin.EventExecutor;
import org.bukkit.plugin.InvalidDescriptionException;
import org.bukkit.plugin.InvalidPluginException;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.PluginLoader;
import org.bukkit.plugin.PluginManager;
import org.bukkit.util.config.Configuration;
import net.lax1dude.eaglercraft.beta.server.PasswordManager.PasswordEntry;
import net.lax1dude.eaglercraft.beta.server.commands.*;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.PacketRegister;
public class EaglercraftServer {
public class EaglercraftServer extends PlayerListener {
private static final File dataFolder = new File(".");
private static CraftServer server = null;
@ -24,11 +37,33 @@ public class EaglercraftServer {
private static PluginManager pluginManager = null;
private static boolean passwordDBWorking = false;
private static EaglercraftServer instance = null;
public static final EaglercraftConfig config = new EaglercraftConfig();
private static final Plugin dummyPlugin = new Plugin() {
@Override public File getDataFolder() { return dataFolder; }
@Override public PluginDescriptionFile getDescription() { return new PluginDescriptionFile("EaglercraftServer", "0.0.0", ""); }
@Override public Configuration getConfiguration() { return null; }
@Override public PluginLoader getPluginLoader() { return null; }
@Override public PluginLoader getPluginLoader() { return new PluginLoader() {
@Override public Plugin loadPlugin(File var1) throws InvalidPluginException, InvalidDescriptionException {
return dummyPlugin;
}
@Override public Pattern[] getPluginFileFilters() {
return new Pattern[0];
}
@Override public EventExecutor createExecutor(Type var1, Listener var2) {
if(var1 == Type.PLAYER_JOIN) {
return new EventExecutor() { @Override public void execute(Listener var1, Event var2) {
((PlayerListener)var1).onPlayerJoin((PlayerEvent)var2);
}};
}else {
return null;
}
}
@Override public void enablePlugin(Plugin var1) { }
@Override public void disablePlugin(Plugin var1) { }
}; }
@Override public Server getServer() { return server; }
@Override public boolean isEnabled() { return true; }
@Override public void onDisable() { }
@ -38,27 +73,42 @@ public class EaglercraftServer {
return false;
}
};
static {
PacketRegister.register(69, Packet69EaglercraftData.class);
}
public static void installHooks(CraftServer craftServer, CommandMap commandMap) {
server = craftServer;
commands = commandMap;
pluginManager = craftServer.getPluginManager();
instance = new EaglercraftServer();
try {
PasswordManager.loadPasswordDB();
passwordDBWorking = true;
} catch (IOException e) {
PasswordManager.log.severe("ERROR: could not create or load password database!");
PasswordManager.log.severe("Eaglercraft will not function correctly, unless you disable password login");
e.printStackTrace();
passwordDBWorking = false;
PasswordManager.log.info("Loading Eaglercraft Bukkit...");
config.reload();
if(config.enablePasswordLogin()) {
try {
PasswordManager.loadPasswordDB();
passwordDBWorking = true;
} catch (IOException e) {
PasswordManager.log.severe("ERROR: could not create or load password database!");
PasswordManager.log.severe("Eaglercraft will not function correctly, unless you disable password login");
e.printStackTrace();
passwordDBWorking = false;
}
}
pluginManager.registerEvent(Type.PLAYER_JOIN, instance, Priority.Normal, dummyPlugin);
registerCommand(new CommandSetPassword());
registerCommand(new CommandChangePassword());
registerCommand(new CommandClearPassword());
registerCommand(new CommandListPasswords());
registerCommand(new CommandPasswordExpires());
registerCommand(new CommandRenewPassword());
registerCommand(new CommandRegister());
}
@ -68,6 +118,30 @@ public class EaglercraftServer {
private static void registerCommand(Command command) {
commands.register(command.getName(), "eagler", command);
for(String s : command.getAliases()) {
commands.register(s, "eagler", command);
}
}
@Override
public void onPlayerJoin(PlayerEvent event) {
if(config.enablePasswordLogin()) {
PasswordEntry et = PasswordManager.load(event.getPlayer().getName());
if(et != null && et.secondsRemaining() != Integer.MAX_VALUE) {
event.getPlayer().sendMessage("Your password will expire after " + CommandListPasswords.expiresAfter(et.secondsRemaining()));
if(config.allowSelfRenewPassword()) {
event.getPlayer().sendMessage("Use /renew-password to extend");
}
}
}
}
public static CraftServer getMinecraftServer() {
return server;
}
public static PluginManager getPluginManager() {
return pluginManager;
}
}

View File

@ -0,0 +1,56 @@
package net.lax1dude.eaglercraft.beta.server;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import net.minecraft.server.EntityPlayer;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.NetServerHandler;
import net.minecraft.server.NetworkManager;
import net.minecraft.server.Packet255KickDisconnect;
public class NetEaglerServerHandler extends NetServerHandler {
public final byte[] skinData;
private final MinecraftServer server;
public NetEaglerServerHandler(MinecraftServer minecraftserver, NetworkManager networkmanager, EntityPlayer entityplayer, byte[] skinData) {
super(minecraftserver, networkmanager, entityplayer);
this.server = minecraftserver;
this.skinData = skinData;
}
public void a(Packet69EaglercraftData pkt) {
if(pkt.type.equals("EAG|RequestPlayerSkin")) {
DataInputStream dis = new DataInputStream(new ByteArrayInputStream(pkt.data));
try {
int cookie = dis.readUnsignedShort();
String un = dis.readUTF();
if(dis.available() > 0) {
throw new IOException("Packet has " + dis.available() + " extra bytes!");
}
EntityPlayer ep = server.f.i(un);
if(ep != null) {
if(ep.a instanceof NetEaglerServerHandler) {
byte[] pk = ((NetEaglerServerHandler)ep.a).skinData;
if(pk != null) {
byte[] ret = new byte[pk.length + 2];
ret[0] = (byte)((cookie >> 8) & 0xFF);
ret[1] = (byte)(cookie & 0xFF);
System.arraycopy(pk, 0, ret, 2, pk.length);
this.b.a(new Packet69EaglercraftData("EAG|PlayerSkin", ret));
}else {
this.b.a(new Packet69EaglercraftData("EAG|PlayerSkin", new byte[] { (byte)((cookie >> 8) & 0xFF), (byte)(cookie & 0xFF), (byte)0, (byte)0 }));
}
}
}
}catch(IOException ex) {
this.b.a(new Packet255KickDisconnect("Invalid Skin Request"));
this.b.c();
this.c = true;
}
}
}
}

View File

@ -0,0 +1,58 @@
package net.lax1dude.eaglercraft.beta.server;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import net.minecraft.server.NetHandler;
import net.minecraft.server.Packet;
public class Packet69EaglercraftData extends Packet {
public String type;
public byte[] data;
public Packet69EaglercraftData() {
}
public Packet69EaglercraftData(String type, byte[] data) {
if(data.length > 65535) {
throw new IllegalArgumentException("Packet69EaglercraftData may at most carry a 65535 byte payload");
}
this.type = type;
this.data = data;
}
@Override
public void a(DataInputStream datainputstream) {
try {
type = datainputstream.readUTF();
data = new byte[datainputstream.readUnsignedShort()];
datainputstream.read(data);
}catch(IOException ex) {
throw new RuntimeException("IOException was thrown while reading Packet69EaglercraftData!", ex);
}
}
@Override
public void a(DataOutputStream var1) {
try {
var1.writeUTF(type);
var1.writeShort(data.length);
var1.write(data);
}catch(IOException ex) {
throw new RuntimeException("IOException was thrown while writing Packet69EaglercraftData!", ex);
}
}
@Override
public void a(NetHandler var1) {
var1.a(this);
}
@Override
public int a() {
return 2 + type.length() + 2 + data.length;
}
}

View File

@ -169,7 +169,7 @@ public class PasswordManager {
continue;
}
synchronized(passwordEntries) {
if(pse.secondsRemaining() > 0) {
if(pse.secondsRemaining() > 0 && !(!EaglercraftServer.config.allowPasswordsWithoutExpire() && pse.expiresAfter == -1)) {
passwordEntries.put(pse.username, pse);
}else {
mustRewrite = true;
@ -410,6 +410,10 @@ public class PasswordManager {
public static void create(String username, String password, int expiresAfter) {
discardExpiredPasswords();
if(expiresAfter < -1) {
expiresAfter = -1;
}
byte[] salt = new byte[9];
synchronized(rand) {
rand.nextBytes(salt);
@ -444,12 +448,43 @@ public class PasswordManager {
}
}
public static int changeExpires(String username, int expiresAfter) {
PasswordEntry et;
synchronized(passwordEntries) {
et = passwordEntries.get(username.toLowerCase());
}
if(et != null) {
if(expiresAfter == -1) {
expiresAfter = et.expiresAfter;
}
synchronized(passwordEntries) {
passwordEntries.put(et.username, new PasswordEntry(et.username, et.salt, et.password, System.currentTimeMillis(), expiresAfter == -2 ? -1 : expiresAfter));
}
}
if(discardExpiredPasswords() || et != null) {
try {
syncDatabase();
}catch(SyncException e) {
Throwable t = e.getCause();
System.err.println("Could not write passwords to disk!");
if(t != null) {
t.printStackTrace();
}else {
e.printStackTrace();
}
}
}
return et == null ? -1 : (expiresAfter == -1 ? -2 : expiresAfter);
}
private static boolean discardExpiredPasswords() {
boolean flag = false;
boolean removePasswordsWithoutExpire = !EaglercraftServer.config.allowPasswordsWithoutExpire();
synchronized(passwordEntries) {
Iterator<PasswordEntry> itr = passwordEntries.values().iterator();
while(itr.hasNext()) {
if(itr.next().secondsRemaining() <= 0) {
PasswordEntry et = itr.next();
if(et.secondsRemaining() <= 0 || (removePasswordsWithoutExpire && et.expiresAfter == -1)) {
flag = true;
itr.remove();
}

View File

@ -24,6 +24,10 @@ public class CommandChangePassword extends EaglerCommand {
@Override
protected void execute(CommandSender sender, String[] args) {
if(!EaglercraftServer.config.enablePasswordLogin()) {
sender.sendMessage(ChatColor.RED + "Error: password login is disabled");
return;
}
if(sender instanceof Player) {
if(!EaglercraftServer.hasPasswordDB()) {
sender.sendMessage(ChatColor.RED + "Error: the password database is not initialized, it probably won't save your changes");
@ -31,8 +35,14 @@ public class CommandChangePassword extends EaglerCommand {
if(args.length != 1) {
throw new IncorrectUsageException("this command only takes 1 argument!");
}
if(args[0].length() < 3) {
throw new IncorrectUsageException("A password must be at least 3 characters!");
}
if(((CraftPlayer)sender).getHandle().a.b instanceof EaglercraftWebsocketNetworkManager) {
if(!EaglercraftServer.config.allowSelfChangePassword()) {
sender.sendMessage(ChatColor.RED + "Error: you are not allowed to change your password");
return;
}
PasswordEntry et = PasswordManager.load(((Player)sender).getName());
if(et != null) {
PasswordManager.create(et.username, args[0], et.expiresAfter);

View File

@ -15,7 +15,7 @@ public class CommandClearPassword extends EaglerCommand {
public CommandClearPassword() {
super("clear-password");
setAliases(Arrays.asList("clear-pass"));
setAliases(Arrays.asList("clear-pass", "remove-password", "remove-pass", "delete-password", "delete-pass"));
setNeedsOp(false);
setTooltip("Removes a password from a username, or your own username, for Eaglercraft connections");
setUsage("/clear-password [username]");
@ -23,15 +23,28 @@ public class CommandClearPassword extends EaglerCommand {
@Override
protected void execute(CommandSender sender, String[] args) {
if(!EaglercraftServer.config.enablePasswordLogin()) {
sender.sendMessage(ChatColor.RED + "Error: password login is disabled");
return;
}
if(!EaglercraftServer.hasPasswordDB()) {
sender.sendMessage(ChatColor.RED + "Error: the password database is not initialized, it probably won't save your changes");
}
if(sender instanceof CraftPlayer && ((CraftPlayer)sender).getHandle().a.b instanceof EaglercraftWebsocketNetworkManager && (args.length == 0 || (args.length == 1 && args[0].equalsIgnoreCase(((Player)sender).getName())))) {
if(PasswordManager.delete(((Player)sender).getName())) {
sender.sendMessage("Your password was removed.");
if(EaglercraftServer.config.allowSelfDeletePassword() || EaglercraftServer.config.allowSelfRegistration()) {
if(PasswordManager.delete(((Player)sender).getName())) {
if(EaglercraftServer.config.requirePasswordLogin()) {
((Player)sender).kickPlayer("Your password was removed.");
}else {
sender.sendMessage("Your password was removed.");
}
}else {
sender.sendMessage(ChatColor.RED + "You do not have a password on this account!");
}
}else {
sender.sendMessage(ChatColor.RED + "You do not have a password on this account!");
sender.sendMessage(ChatColor.RED + "You cannot remove the password from your username.");
}
return;
}else if(args.length != 1) {
throw new IncorrectUsageException("this command only takes 1 argument!");
}

View File

@ -22,6 +22,10 @@ public class CommandListPasswords extends EaglerCommand {
@Override
protected void execute(CommandSender sender, String[] args) {
if(!EaglercraftServer.config.enablePasswordLogin()) {
sender.sendMessage(ChatColor.RED + "Error: password login is disabled");
return;
}
if(args.length != 0) {
throw new IncorrectUsageException("This command does not take any arguments");
}
@ -36,24 +40,27 @@ public class CommandListPasswords extends EaglerCommand {
int characterWidth = (sender instanceof Player) ? 60 : 40;
String row = "";
for(PasswordEntry s : cc) {
String rowAdd = s.username + (s.expiresAfter <= 0 ? " (*)" : " (" + expiresAfter(s.expiresAfter) + ")");
String rowAdd = s.username + (s.expiresAfter <= 0 ? " (*)" : " (" + expiresAfter(s.secondsRemaining()) + ")");
if(row.length() + rowAdd.length() + 2 > characterWidth) {
sender.sendMessage(" " + row);
sender.sendMessage(" " + row);
row = "";
}
if(row.length() > 0) {
row = ", " + rowAdd;
row = row + ", " + rowAdd;
}else {
row = rowAdd;
}
}
if(row.length() > 0) {
sender.sendMessage(" " + row);
sender.sendMessage(" " + row);
}
}
}
public static String expiresAfter(int remaining) {
if(remaining < 0) {
return "never";
}
if(remaining < 60) {
return remaining + "s";
}else if(remaining < 60 * 60) {

View File

@ -24,6 +24,10 @@ public class CommandPasswordExpires extends EaglerCommand {
@Override
protected void execute(CommandSender sender, String[] args) {
if(!EaglercraftServer.config.enablePasswordLogin()) {
sender.sendMessage(ChatColor.RED + "Error: password login is disabled");
return;
}
if(!EaglercraftServer.hasPasswordDB()) {
sender.sendMessage(ChatColor.RED + "Error: the password database is not initialized, it probably won't save your changes");
}

View File

@ -0,0 +1,70 @@
package net.lax1dude.eaglercraft.beta.server.commands;
import java.util.Arrays;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.craftbukkit.entity.CraftPlayer;
import org.bukkit.entity.Player;
import net.lax1dude.eaglercraft.beta.server.EaglercraftServer;
import net.lax1dude.eaglercraft.beta.server.PasswordManager;
import net.minecraft.server.EaglercraftWebsocketNetworkManager;
public class CommandRegister extends EaglerCommand {
public CommandRegister() {
super("register-password");
setAliases(Arrays.asList("register-pass", "password-register", "pass-register", "eagler-register", "eag-register"));
setNeedsOp(false);
setTooltip("Register a password for your username");
setUsage("/register-password <password> [expires after][s|m|h|d|w]");
}
@Override
protected void execute(CommandSender sender, String[] args) {
if(!EaglercraftServer.config.enablePasswordLogin()) {
sender.sendMessage(ChatColor.RED + "Error: password login is disabled");
return;
}
if(!EaglercraftServer.hasPasswordDB()) {
sender.sendMessage(ChatColor.RED + "Error: the password database is not initialized, it probably won't save your changes");
}
if(sender instanceof Player && ((CraftPlayer)sender).getHandle().a.b instanceof EaglercraftWebsocketNetworkManager) {
if(!EaglercraftServer.config.allowSelfRegistration()) {
sender.sendMessage(ChatColor.RED + "Error: password registration is disabled");
return;
}
if(PasswordManager.load(((Player)sender).getName()) != null) {
sender.sendMessage(ChatColor.RED + "Error: you are already registered on this server, use /change-password to edit it");
}else {
if(args.length != 1 && args.length != 2) {
throw new IncorrectUsageException("this command takes 1 or 2 arguments!");
}
if(args[0].length() < 3) {
throw new IncorrectUsageException("A password must be at least 3 characters!");
}
int expires = EaglercraftServer.config.defaultPasswordExpireTime();
if(args.length == 2) {
expires = CommandRenewPassword.tryParseTime(args[1]);
if(expires == -1) {
throw new IncorrectUsageException("Expires time is invalid!");
}
}
if(expires == -2 && !(EaglercraftServer.config.allowSelfRegistrationWithoutExpire() || !EaglercraftServer.config.allowPasswordsWithoutExpire())) {
sender.sendMessage(ChatColor.RED + "Error: you cannot register a password");
return;
}
if(expires > EaglercraftServer.config.maximumPasswordExpireTime()) {
sender.sendMessage(ChatColor.RED + "Error: the maximum time before your password expires can be at most " + CommandListPasswords.expiresAfter(expires));
return;
}
PasswordManager.create(((Player)sender).getName(), args[0], expires == -2 ? -1 : expires);
sender.sendMessage("Your password was registered." + (expires == -2 ? "" : " It will expire in " + CommandListPasswords.expiresAfter(expires)));
}
}else {
sender.sendMessage(ChatColor.RED + "Error: only players connected via websocket can use this command");
}
}
}

View File

@ -9,6 +9,7 @@ import org.bukkit.entity.Player;
import net.lax1dude.eaglercraft.beta.server.EaglercraftServer;
import net.lax1dude.eaglercraft.beta.server.PasswordManager;
import net.lax1dude.eaglercraft.beta.server.PasswordManager.PasswordEntry;
import net.minecraft.server.EaglercraftWebsocketNetworkManager;
public class CommandRenewPassword extends EaglerCommand {
@ -23,31 +24,166 @@ public class CommandRenewPassword extends EaglerCommand {
@Override
protected void execute(CommandSender sender, String[] args) {
if(!EaglercraftServer.config.enablePasswordLogin()) {
sender.sendMessage(ChatColor.RED + "Error: password login is disabled");
return;
}
// Tomorrow: program this command
boolean isPlayer = sender instanceof Player;
boolean isWsPlayer = isPlayer && ((CraftPlayer)sender).getHandle().a.b instanceof EaglercraftWebsocketNetworkManager;
boolean isSelfPlayer = isPlayer && args.length >= 1 && args[0].equalsIgnoreCase(((Player)sender).getName());
int is1stTime = args.length >= 1 ? tryParseTime(args[0]) : -1;
int is2stTime = args.length >= 2 ? tryParseTime(args[1]) : -1;
int mpe = EaglercraftServer.config.maximumPasswordExpireTime();
if(is1stTime > mpe || is2stTime > mpe) {
sender.sendMessage(ChatColor.RED + "Error: the maximum time before a password expires can be at most " + CommandListPasswords.expiresAfter(mpe));
return;
}
if(!EaglercraftServer.config.allowPasswordsWithoutExpire() && (is1stTime == -2 || is2stTime == -2)) {
sender.sendMessage(ChatColor.RED + "Error: passwords that do not expire are not enabled on this server!");
return;
}
if(!EaglercraftServer.hasPasswordDB()) {
sender.sendMessage(ChatColor.RED + "Error: the password database is not initialized, it probably won't save your changes");
}
if(sender instanceof CraftPlayer && ((CraftPlayer)sender).getHandle().a.b instanceof EaglercraftWebsocketNetworkManager && (args.length == 0 || (args.length == 1 && args[0].equalsIgnoreCase(((Player)sender).getName())))) {
if(PasswordManager.delete(((Player)sender).getName())) {
sender.sendMessage("Your password was removed.");
if(args.length == 0 || (args.length == 1 && isSelfPlayer)) {
if(isPlayer && (isWsPlayer || sender.isOp())) {
if(!sender.isOp() && !EaglercraftServer.config.allowSelfRenewPassword()) {
sender.sendMessage(ChatColor.RED + "Error: you cannot renew your password on this server");
return;
}
int n = PasswordManager.changeExpires(((Player)sender).getName(), -1);
if(n > 0) {
sender.sendMessage("Your password will expire in " + CommandListPasswords.expiresAfter(n) + ".");
}else {
if(n == -2) {
sender.sendMessage("Your password is not going to expire.");
}else {
sender.sendMessage(ChatColor.RED + "Error: you do not have a password to renew");
}
}
}else {
sender.sendMessage(ChatColor.RED + "You do not have a password on this account!");
sender.sendMessage(ChatColor.RED + "Error: you need to be logged in via websocket to use this command");
}
}else if(args.length != 1) {
throw new IncorrectUsageException("this command only takes 1 argument!");
}
if(sender.isOp()) {
if(PasswordManager.delete(args[0])) {
sender.sendMessage("Password for '" + args[0] + "' was removed");
}else if(args.length == 1 && is1stTime != -1) {
if(isPlayer && (isWsPlayer || sender.isOp())) {
if(!sender.isOp() && !EaglercraftServer.config.allowSelfRenewPassword()) {
sender.sendMessage(ChatColor.RED + "Error: you cannot renew your password on this server");
return;
}
System.out.println(EaglercraftServer.config.allowSelfRenewPasswordWithTime());
if(!sender.isOp() && !EaglercraftServer.config.allowSelfRenewPasswordWithTime()) {
sender.sendMessage(ChatColor.RED + "Error: you cannot manually set the time until your password expires on this server");
return;
}
PasswordEntry pe = PasswordManager.load(((Player)sender).getName());
if(pe.expiresAfter == -1) {
sender.sendMessage("Your password is not going to expire.");
}else {
if(!sender.isOp() && is1stTime == -2) {
sender.sendMessage(ChatColor.RED + "Error: you cannot renew your password not to expire");
return;
}else {
int n = PasswordManager.changeExpires(((Player)sender).getName(), is1stTime);
if(n > 0) {
sender.sendMessage("Your password will expire in " + CommandListPasswords.expiresAfter(n) + ".");
}else {
if(n == -2) {
sender.sendMessage("Your password is not going to expire.");
}else {
sender.sendMessage(ChatColor.RED + "Error: you do not have a password to renew");
}
}
}
}
}else {
sender.sendMessage(ChatColor.RED + "The user '" + args[0] + "' does not have a password!");
sender.sendMessage(ChatColor.RED + "Error: you need to be logged in via websocket to use this command");
}
}else if(args.length == 2 && isSelfPlayer && is2stTime != -1) {
if(isPlayer && (isWsPlayer || sender.isOp())) {
if(!sender.isOp() && !EaglercraftServer.config.allowSelfRenewPassword()) {
sender.sendMessage(ChatColor.RED + "Error: you cannot renew your password on this server");
return;
}
if(!sender.isOp() && !EaglercraftServer.config.allowSelfRenewPasswordWithTime()) {
sender.sendMessage(ChatColor.RED + "Error: you cannot manually set the time until your password expires on this server");
return;
}
PasswordEntry pe = PasswordManager.load(((Player)sender).getName());
if(pe.expiresAfter == -1) {
sender.sendMessage("Your password is not going to expire.");
}else {
if(!sender.isOp() && is2stTime == -2) {
sender.sendMessage(ChatColor.RED + "Error: you cannot renew your password not to expire");
return;
}else {
int n = PasswordManager.changeExpires(((Player)sender).getName(), is2stTime);
if(n > 0) {
sender.sendMessage("Your password will expire in " + CommandListPasswords.expiresAfter(n) + ".");
}else {
if(n == -2) {
sender.sendMessage("Your password is not going to expire.");
}else {
sender.sendMessage(ChatColor.RED + "Error: you do not have a password to renew");
}
}
}
}
}else {
sender.sendMessage(ChatColor.RED + "Error: you need to be logged in via websocket to use this command");
}
}else if(args.length == 2 && is2stTime != -1) {
if(sender.isOp()) {
int n = PasswordManager.changeExpires(args[0], is2stTime);
if(n > 0) {
sender.sendMessage("The password for '" + args[0] + "' will expire in " + CommandListPasswords.expiresAfter(n) + ".");
}else {
if(n == -2) {
sender.sendMessage("The password for '" + args[0] + "' will not expire.");
}else {
sender.sendMessage(ChatColor.RED + "Error: this player '" + args[0] + "' does not have a password to renew");
}
}
}else {
sender.sendMessage(ChatColor.RED + "Error: you need /op to use this command!");
}
}else {
sender.sendMessage(ChatColor.RED + "Error: you need /op to use this command!");
throw new IncorrectUsageException("Illegal argument combination");
}
}
public static int tryParseTime(String str) {
int expires = -1;
if(str.length() >= 2) {
if(str.equalsIgnoreCase("never") || str.equalsIgnoreCase("infinite") || str.equalsIgnoreCase("infinity")) {
return -2;
}
int mul = 60 * 60 * 24;
String exp = str.toLowerCase();
if(exp.endsWith("s")) {
mul = 1;
exp = exp.substring(0, exp.length() - 1);
}else if(exp.endsWith("m")) {
mul = 60;
exp = exp.substring(0, exp.length() - 1);
}else if(exp.endsWith("h")) {
mul = 60 * 60;
exp = exp.substring(0, exp.length() - 1);
}else if(exp.endsWith("d")) {
exp = exp.substring(0, exp.length() - 1);
}else if(exp.endsWith("w")) {
mul = 60 * 60 * 24 * 7;
exp = exp.substring(0, exp.length() - 1);
}
try {
expires = Integer.parseInt(exp) * mul;
}catch(NumberFormatException ex) {
}
}
return expires < 0 ? -1 : expires;
}
}

View File

@ -19,6 +19,10 @@ public class CommandSetPassword extends EaglerCommand {
@Override
protected void execute(CommandSender sender, String[] args) {
if(!EaglercraftServer.config.enablePasswordLogin()) {
sender.sendMessage(ChatColor.RED + "Error: password login is disabled");
return;
}
if(!EaglercraftServer.hasPasswordDB()) {
sender.sendMessage(ChatColor.RED + "Error: the password database is not initialized, it probably won't save your changes");
}
@ -28,34 +32,27 @@ public class CommandSetPassword extends EaglerCommand {
if(args[0].length() > 16) {
throw new IncorrectUsageException("the maximum length for a username is 16 characters!");
}
int expires = -1;
if(args[1].length() < 3) {
throw new IncorrectUsageException("A password must be at least 3 characters!");
}
int expires = EaglercraftServer.config.defaultPasswordExpireTime();
if(args.length == 3) {
int mul = 60 * 60 * 24;
String exp = args[2].toLowerCase();
if(exp.endsWith("s")) {
mul = 1;
exp = exp.substring(0, exp.length() - 1);
}else if(exp.endsWith("m")) {
mul = 60;
exp = exp.substring(0, exp.length() - 1);
}else if(exp.endsWith("h")) {
mul = 60 * 60;
exp = exp.substring(0, exp.length() - 1);
}else if(exp.endsWith("d")) {
exp = exp.substring(0, exp.length() - 1);
}else if(exp.endsWith("w")) {
mul = 60 * 60 * 24 * 7;
exp = exp.substring(0, exp.length() - 1);
expires = CommandRenewPassword.tryParseTime(args[2]);
if(expires == -1) {
throw new IncorrectUsageException("Expires time is invalid!");
}
try {
expires = Integer.parseInt(exp) * mul;
}catch(NumberFormatException ex) {
throw new IncorrectUsageException("The number '" + exp + "' is invalid!");
}
if(expires < 1) {
throw new IncorrectUsageException("Expires time must be positive!");
if(expires == -2) {
expires = -1;
}
}
if(expires > EaglercraftServer.config.maximumPasswordExpireTime()) {
sender.sendMessage(ChatColor.RED + "Error: the maximum time before a password expires can be at most " + CommandListPasswords.expiresAfter(EaglercraftServer.config.maximumPasswordExpireTime()));
return;
}
if(expires == -1 && !EaglercraftServer.config.allowPasswordsWithoutExpire()) {
sender.sendMessage(ChatColor.RED + "Error: passwords that do not expire are disabled!");
return;
}
PasswordManager.create(args[0], args[1], expires);
sender.sendMessage("Password for '" + args[0] + "' was changed");
}

View File

@ -9,7 +9,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class EaglercraftVanillaNetworkManager implements NetworkManager {
public class EaglercraftVanillaNetworkManager extends NetworkManager {
public static final Object a = new Object();
public static int b;
public static int c;

View File

@ -29,7 +29,10 @@ public class EaglercraftWebsocketListenerThread extends WebSocketServer {
@Override
public void onClose(WebSocket arg0, int arg1, String arg2, boolean arg3) {
// rip
EaglercraftWebsocketNetworkManager mgr = arg0.getAttachment();
if(mgr != null && !mgr.disconnected) {
mgr.a("disconnect.close");
}
}
@Override

View File

@ -11,31 +11,23 @@ import java.util.List;
import org.java_websocket.WebSocket;
import net.minecraft.server.NetHandler;
import net.minecraft.server.NetServerHandler;
import net.minecraft.server.Packet;
public class EaglercraftWebsocketNetworkManager implements NetworkManager {
public class EaglercraftWebsocketNetworkManager extends NetworkManager {
public static final int PACKET_LIMIT = 300;
public static final int PACKET_PER_SECOND_QUOTA = 1000 / 35;
public static final int PACKET_MAX_SIZE = 1536;
public static final int PACKET_MAX_SIZE = 9600;
final WebSocket websocket;
NetHandler netHandler;
// Next step: add cooldown to implement 'delayedPackets'
private volatile int packetCounter = 0;
private long packetDecrement;
private int timeoutCounter = 0;
private final List<Packet> delayedPackets = new LinkedList();
private final List<Packet> readPackets = new LinkedList();
protected final List<Packet> writePackets = new LinkedList();
private boolean delay = false;
private int delayTimer = 0;
public boolean disconnected = false;
private final Thread writeThread;
protected final Object writeThreadLock = new Object();
@ -108,6 +100,10 @@ public class EaglercraftWebsocketNetworkManager implements NetworkManager {
manager.websocket.send(ByteBuffer.wrap(pktBytes));
}
}
if(manager.disconnected) {
manager.websocket.close();
break main_loop;
}
}catch(Throwable t) {
t.printStackTrace();
manager.a("disconnect.closed", "Packet write fault");
@ -131,18 +127,11 @@ public class EaglercraftWebsocketNetworkManager implements NetworkManager {
*/
@Override
public void a(Packet var1) {
if (var1.k) {
synchronized(delayedPackets) {
delayedPackets.add(var1);
}
}else {
delay = true;
synchronized(writePackets) {
writePackets.add(var1);
}
synchronized(writeThreadLock) {
writeThreadLock.notify();
}
synchronized(writePackets) {
writePackets.add(var1);
}
synchronized(writeThreadLock) {
writeThreadLock.notify();
}
}
@ -151,10 +140,8 @@ public class EaglercraftWebsocketNetworkManager implements NetworkManager {
*/
@Override
public void a(String var1, Object... var2) {
if(!websocket.isClosed()) {
netHandler.a(var1, var2);
websocket.close();
}
netHandler.a(var1, var2);
disconnected = true;
}
/**
@ -175,7 +162,7 @@ public class EaglercraftWebsocketNetworkManager implements NetworkManager {
}
long t = System.currentTimeMillis();
int decr = (int) ((packetDecrement - t) / PACKET_PER_SECOND_QUOTA);
int decr = (int) ((t - packetDecrement) / PACKET_PER_SECOND_QUOTA);
packetCounter -= decr;
packetDecrement += decr * PACKET_PER_SECOND_QUOTA;
@ -205,20 +192,6 @@ public class EaglercraftWebsocketNetworkManager implements NetworkManager {
p.a(netHandler);
}
}
synchronized(delayedPackets) {
if(!delayedPackets.isEmpty() && (!delay || --delayTimer <= 0)) {
synchronized(writePackets) {
writePackets.add(delayedPackets.remove(0));
}
synchronized(writeThreadLock) {
writeThreadLock.notify();
}
delayTimer = 50;
}
}
delay = false;
}
/**
@ -242,9 +215,7 @@ public class EaglercraftWebsocketNetworkManager implements NetworkManager {
*/
@Override
public int d() {
synchronized(delayedPackets) {
return delayedPackets.size();
}
return 0;
}
@Override

View File

@ -0,0 +1,192 @@
package net.minecraft.server;
import net.lax1dude.eaglercraft.beta.server.Packet69EaglercraftData;
public class NetHandler {
public void a(Packet51MapChunk var1) {
}
public void a(Packet var1) {
}
public void a(String var1, Object[] var2) {
}
public void a(Packet255KickDisconnect var1) {
this.a((Packet) var1);
}
public void a(Packet1Login var1) {
this.a((Packet) var1);
}
public void a(Packet10Flying var1) {
this.a((Packet) var1);
}
public void a(Packet52MultiBlockChange var1) {
this.a((Packet) var1);
}
public void a(Packet14BlockDig var1) {
this.a((Packet) var1);
}
public void a(Packet53BlockChange var1) {
this.a((Packet) var1);
}
public void a(Packet50PreChunk var1) {
this.a((Packet) var1);
}
public void a(Packet20NamedEntitySpawn var1) {
this.a((Packet) var1);
}
public void a(Packet30Entity var1) {
this.a((Packet) var1);
}
public void a(Packet34EntityTeleport var1) {
this.a((Packet) var1);
}
public void a(Packet15Place var1) {
this.a((Packet) var1);
}
public void a(Packet16BlockItemSwitch var1) {
this.a((Packet) var1);
}
public void a(Packet29DestroyEntity var1) {
this.a((Packet) var1);
}
public void a(Packet21PickupSpawn var1) {
this.a((Packet) var1);
}
public void a(Packet22Collect var1) {
this.a((Packet) var1);
}
public void a(Packet3Chat var1) {
this.a((Packet) var1);
}
public void a(Packet23VehicleSpawn var1) {
this.a((Packet) var1);
}
public void a(Packet18ArmAnimation var1) {
this.a((Packet) var1);
}
public void a(Packet19EntityAction var1) {
this.a((Packet) var1);
}
public void a(Packet2Handshake var1) {
this.a((Packet) var1);
}
public void a(Packet24MobSpawn var1) {
this.a((Packet) var1);
}
public void a(Packet4UpdateTime var1) {
this.a((Packet) var1);
}
public void a(Packet6SpawnPosition var1) {
this.a((Packet) var1);
}
public void a(Packet28EntityVelocity var1) {
this.a((Packet) var1);
}
public void a(Packet40EntityMetadata var1) {
this.a((Packet) var1);
}
public void a(Packet39AttachEntity var1) {
this.a((Packet) var1);
}
public void a(Packet7UseEntity var1) {
this.a((Packet) var1);
}
public void a(Packet38EntityStatus var1) {
this.a((Packet) var1);
}
public void a(Packet8UpdateHealth var1) {
this.a((Packet) var1);
}
public void a(Packet9Respawn var1) {
this.a((Packet) var1);
}
public void a(Packet60Explosion var1) {
this.a((Packet) var1);
}
public void a(Packet100OpenWindow var1) {
this.a((Packet) var1);
}
public void a(Packet101CloseWindow var1) {
this.a((Packet) var1);
}
public void a(Packet102WindowClick var1) {
this.a((Packet) var1);
}
public void a(Packet103SetSlot var1) {
this.a((Packet) var1);
}
public void a(Packet104WindowItems var1) {
this.a((Packet) var1);
}
public void a(Packet130UpdateSign var1) {
this.a((Packet) var1);
}
public void a(Packet105CraftProgressBar var1) {
this.a((Packet) var1);
}
public void a(Packet5EntityEquipment var1) {
this.a((Packet) var1);
}
public void a(Packet106Transaction var1) {
this.a((Packet) var1);
}
public void a(Packet25EntityPainting var1) {
this.a((Packet) var1);
}
public void a(Packet54PlayNoteBlock var1) {
this.a((Packet) var1);
}
public void a(Packet69EaglercraftData var1) {
this.a((Packet) var1);
}
public void a(Packet17 var1) {
}
public void a(Packet27 var1) {
}
}

View File

@ -9,6 +9,9 @@ import java.util.logging.Logger;
import org.java_websocket.WebSocket;
import net.lax1dude.eaglercraft.beta.server.Base64;
import net.lax1dude.eaglercraft.beta.server.EaglercraftServer;
import net.lax1dude.eaglercraft.beta.server.NetEaglerServerHandler;
import net.lax1dude.eaglercraft.beta.server.Packet69EaglercraftData;
import net.lax1dude.eaglercraft.beta.server.PasswordManager;
import net.lax1dude.eaglercraft.beta.server.PasswordManager.PasswordEntry;
import net.lax1dude.eaglercraft.beta.server.SHA1Digest;
@ -27,6 +30,7 @@ public class NetLoginHandler extends NetHandler {
private String wsUsername = null;
private PasswordEntry passEntry = null;
private byte[] sentSalt = null;
private byte[] skinData = null;
private boolean isWebsocket() {
return b instanceof EaglercraftWebsocketNetworkManager;
@ -76,19 +80,34 @@ public class NetLoginHandler extends NetHandler {
public void a(Packet2Handshake packet2handshake) {
if(isWebsocket()) {
wsUsername = packet2handshake.a;
passEntry = PasswordManager.load(wsUsername);
if(passEntry == null) {
this.a("You're not registered on this server!");
if(!validateUsername(wsUsername)) {
this.a("Invalid username!");
return;
}
sentSalt = new byte[9];
synchronized(PasswordManager.rand) {
PasswordManager.rand.nextBytes(sentSalt);
if(EaglercraftServer.config.enablePasswordLogin()) {
passEntry = PasswordManager.load(wsUsername);
if(passEntry == null) {
if(EaglercraftServer.config.requirePasswordLogin()) {
this.a("You're not registered on this server!");
return;
}else {
sentSalt = new byte[0];
this.b.a(new Packet2Handshake("NULL"));
}
}else {
sentSalt = new byte[9];
synchronized(PasswordManager.rand) {
PasswordManager.rand.nextBytes(sentSalt);
}
byte[] sendHash = new byte[18];
System.arraycopy(passEntry.salt, 0, sendHash, 0, 9);
System.arraycopy(sentSalt, 0, sendHash, 9, 9);
this.b.a(new Packet2Handshake(Base64.encodeBase64String(sendHash)));
}
}else {
sentSalt = new byte[0];
this.b.a(new Packet2Handshake("NULL"));
}
byte[] sendHash = new byte[18];
System.arraycopy(passEntry.salt, 0, sendHash, 0, 9);
System.arraycopy(sentSalt, 0, sendHash, 9, 9);
this.b.a(new Packet2Handshake(Base64.encodeBase64String(sendHash)));
}else {
if (this.e.l) {
this.i = Long.toHexString(d.nextLong());
@ -99,6 +118,16 @@ public class NetLoginHandler extends NetHandler {
}
}
public static boolean validateUsername(String wsUsername2) {
if (wsUsername2.length() < 3 || wsUsername2.length() > 16) {
return false;
}else if(!wsUsername2.equals(wsUsername2.replaceAll("[^A-Za-z0-9\\-_]", "_").trim())) {
return false;
}else {
return true;
}
}
public void a(Packet1Login packet1login) {
if (packet1login.a != 9) {
if (packet1login.a > 9) {
@ -109,27 +138,39 @@ public class NetLoginHandler extends NetHandler {
return;
}else {
if(isWebsocket()) {
if(wsUsername == null || !wsUsername.equals(packet1login.b)) {
if(wsUsername == null || sentSalt == null || !wsUsername.equals(packet1login.b)) {
this.a("Invalid login!");
}else {
this.g = packet1login.b;
SHA1Digest dg = new SHA1Digest();
dg.update(PasswordManager.eaglerSalt, 0, PasswordManager.eaglerSalt.length);
dg.update(sentSalt, 0, 9);
dg.update(passEntry.password, 0, passEntry.password.length);
byte[] o = new byte[20];
dg.doFinal(o, 0);
byte[] hsh = Base64.decodeBase64(packet1login.c.replace('-', '+').replace('_', '/'));
if(Arrays.equals(o, hsh)) {
packet1login.c = "-";
this.h = packet1login;
this.hf = f;
if(packet1login.c.equalsIgnoreCase("NULL")) {
if(sentSalt.length == 0) {
this.h = packet1login;
}else {
this.a(EaglercraftServer.config.requirePasswordLogin() ? "A password is required to join this server!" : "This username requires a password to join!");
}
}else {
this.a("Wrong password!");
SHA1Digest dg = new SHA1Digest();
dg.update(PasswordManager.eaglerSalt, 0, PasswordManager.eaglerSalt.length);
dg.update(sentSalt, 0, 9);
dg.update(passEntry.password, 0, passEntry.password.length);
byte[] o = new byte[20];
dg.doFinal(o, 0);
byte[] hsh = Base64.decodeBase64(packet1login.c.replace('-', '+').replace('_', '/'));
if(Arrays.equals(o, hsh)) {
packet1login.c = "-";
this.h = packet1login;
this.hf = f;
}else {
this.a("Wrong password!");
}
}
}
}else {
if(!validateUsername(packet1login.b)) {
this.a("Invalid username!");
return;
}
this.g = packet1login.b;
if (!this.e.l) {
this.b(packet1login);
@ -139,12 +180,45 @@ public class NetLoginHandler extends NetHandler {
}
}
}
public static final int SKIN_DATA_SIZE = 64*32*4;
public void a(Packet69EaglercraftData pkt) {
if(isWebsocket()) {
if(pkt.type.equals("EAG|MySkin")) {
String inv = "Invalid skin";
if(pkt.data.length < 2) {
this.a(inv);
}else {
int type = (int)pkt.data[0] & 0xFF;
if(type == 0) {
if(pkt.data.length == 2) {
skinData = pkt.data;
}else {
this.a(inv);
}
}else if(type == 1) {
if(pkt.data.length == SKIN_DATA_SIZE + 1) {
skinData = pkt.data;
}else {
this.a(inv);
}
}else {
this.a(inv);
}
}
}
}else {
a((Packet)pkt);
}
}
public void b(Packet1Login packet1login) {
EntityPlayer entityplayer = this.e.f.a(this, packet1login.b, packet1login.c);
if (entityplayer != null) {
a.info(this.b() + " logged in with entity id " + entityplayer.id);
NetServerHandler netserverhandler = new NetServerHandler(this.e, this.b, entityplayer);
NetServerHandler netserverhandler = isWebsocket() ? new NetEaglerServerHandler(this.e, this.b, entityplayer, skinData) :
new NetServerHandler(this.e, this.b, entityplayer);
ChunkCoordinates chunkcoordinates = entityplayer.world.l();
netserverhandler.b(
new Packet1Login("", "", entityplayer.id, entityplayer.world.j(), (byte) entityplayer.world.m.g));
@ -162,7 +236,7 @@ public class NetLoginHandler extends NetHandler {
}
public void a(String s, Object[] aobject) {
a.info(this.b() + " lost connection");
a.info(this.b() + " was kicked while logging in: " + s);
this.c = true;
}

View File

@ -2,45 +2,45 @@ package net.minecraft.server;
import java.net.SocketAddress;
public interface NetworkManager {
public abstract class NetworkManager {
/**
* Set the NetHandler
*/
void a(NetHandler var1);
abstract void a(NetHandler var1);
/**
* addToSendQueue
*/
void a(Packet var1);
public abstract void a(Packet var1);
/**
* disconnect
*/
void a(String var1, Object... var2);
abstract void a(String var1, Object... var2);
/**
* processReadPackets
*/
void a();
abstract void a();
/**
* gets the remote address
*/
SocketAddress b();
abstract SocketAddress b();
/**
* shuts connection down
*/
void c();
public abstract void c();
/**
* gets a number of delayed packets
*/
int d();
abstract int d();
/**
* gets if the connection is closed
*/
boolean isDead();
abstract boolean isDead();
}

View File

@ -0,0 +1,9 @@
package net.minecraft.server;
public class PacketRegister {
public static void register(int id, Class<? extends Packet> pkt) {
Packet.a(id, pkt);
}
}

View File

@ -0,0 +1,184 @@
package net.minecraft.server;
import java.util.ArrayList;
import java.util.List;
class PlayerInstance {
private List b;
private int c;
private int d;
private ChunkCoordIntPair e;
private short[] f;
private int g;
private int h;
private int i;
private int j;
private int k;
private int l;
private int m;
final PlayerManager a;
public PlayerInstance(PlayerManager playermanager, int i, int j) {
this.a = playermanager;
this.b = new ArrayList();
this.f = new short[10];
this.g = 0;
this.c = i;
this.d = j;
this.e = new ChunkCoordIntPair(i, j);
playermanager.world.u.d(i, j);
}
public void a(EntityPlayer entityplayer) {
if (this.b.contains(entityplayer)) {
//throw new IllegalStateException(
// "Failed to add player. " + entityplayer + " already is in chunk " + this.c + ", " + this.d);
} else {
entityplayer.g.add(this.e);
entityplayer.a.b(new Packet50PreChunk(this.e.a, this.e.b, true));
this.b.add(entityplayer);
entityplayer.f.add(this.e);
}
}
public void b(EntityPlayer entityplayer) {
if (!this.b.contains(entityplayer)) {
//(new IllegalStateException(
// "Failed to remove player. " + entityplayer + " isn't in chunk " + this.c + ", " + this.d))
// .printStackTrace();
} else {
this.b.remove(entityplayer);
if (this.b.size() == 0) {
long i = (long) this.c + 2147483647L | (long) this.d + 2147483647L << 32;
PlayerManager.b(this.a).b(i);
if (this.g > 0) {
PlayerManager.c(this.a).remove(this);
}
((WorldServer) entityplayer.world).u.c(this.c, this.d);
}
entityplayer.f.remove(this.e);
if (entityplayer.g.contains(this.e)) {
entityplayer.a.b(new Packet50PreChunk(this.c, this.d, false));
}
}
}
public void a(int i, int j, int k) {
if (this.g == 0) {
PlayerManager.c(this.a).add(this);
this.h = this.i = i;
this.j = this.k = j;
this.l = this.m = k;
}
if (this.h > i) {
this.h = i;
}
if (this.i < i) {
this.i = i;
}
if (this.j > j) {
this.j = j;
}
if (this.k < j) {
this.k = j;
}
if (this.l > k) {
this.l = k;
}
if (this.m < k) {
this.m = k;
}
if (this.g < 10) {
short short1 = (short) (i << 12 | k << 8 | j);
for (int l = 0; l < this.g; ++l) {
if (this.f[l] == short1) {
return;
}
}
this.f[this.g++] = short1;
}
}
public void a(Packet packet) {
for (int i = 0; i < this.b.size(); ++i) {
EntityPlayer entityplayer = (EntityPlayer) this.b.get(i);
if (entityplayer.g.contains(this.e)) {
entityplayer.a.b(packet);
}
}
}
public void a() {
if (this.g != 0) {
int i;
int j;
int k;
if (this.g == 1) {
i = this.c * 16 + this.h;
j = this.j;
k = this.d * 16 + this.l;
this.a((Packet) (new Packet53BlockChange(i, j, k, this.a.world)));
if (Block.p[this.a.world.getTypeId(i, j, k)]) {
this.a(this.a.world.getTileEntity(i, j, k));
}
} else {
int l;
if (this.g == 10) {
this.j = this.j / 2 * 2;
this.k = (this.k / 2 + 1) * 2;
i = this.h + this.c * 16;
j = this.j;
k = this.l + this.d * 16;
l = this.i - this.h + 1;
int i1 = this.k - this.j + 2;
int j1 = this.m - this.l + 1;
this.a((Packet) (new Packet51MapChunk(i, j, k, l, i1, j1, this.a.world)));
List list = this.a.world.d(i, j, k, i + l, j + i1, k + j1);
for (int k1 = 0; k1 < list.size(); ++k1) {
this.a((TileEntity) list.get(k1));
}
} else {
this.a((Packet) (new Packet52MultiBlockChange(this.c, this.d, this.f, this.g, this.a.world)));
for (i = 0; i < this.g; ++i) {
j = this.c * 16 + (this.g >> 12 & 15);
k = this.g & 255;
l = this.d * 16 + (this.g >> 8 & 15);
if (Block.p[this.a.world.getTypeId(j, k, l)]) {
System.out.println("Sending!");
this.a(this.a.world.getTileEntity(j, k, l));
}
}
}
}
this.g = 0;
}
}
private void a(TileEntity tileentity) {
if (tileentity != null) {
Packet packet = tileentity.e();
if (packet != null) {
this.a(packet);
}
}
}
}

View File

@ -0,0 +1,128 @@
package net.minecraft.server;
public class PlayerList {
private transient PlayerListEntry[] a = new PlayerListEntry[16];
private transient int b;
private int c = 12;
private final float d = 0.75F;
private transient volatile int e;
private static int e(long var0) {
return a((int) (var0 ^ var0 >>> 32));
}
private static int a(int var0) {
var0 ^= var0 >>> 20 ^ var0 >>> 12;
return var0 ^ var0 >>> 7 ^ var0 >>> 4;
}
private static int a(int var0, int var1) {
return var0 & var1 - 1;
}
public Object a(long var1) {
int var3 = e(var1);
for (PlayerListEntry var4 = this.a[a(var3, this.a.length)]; var4 != null; var4 = var4.c) {
if (var4.a == var1) {
return var4.b;
}
}
return null;
}
public void a(long var1, Object var3) {
int var4 = e(var1);
int var5 = a(var4, this.a.length);
for (PlayerListEntry var6 = this.a[var5]; var6 != null; var6 = var6.c) {
if (var6.a == var1) {
var6.b = var3;
}
}
++this.e;
this.a(var4, var1, var3, var5);
}
private void b(int var1) {
PlayerListEntry[] var2 = this.a;
int var3 = var2.length;
if (var3 == 1073741824) {
this.c = Integer.MAX_VALUE;
} else {
PlayerListEntry[] var4 = new PlayerListEntry[var1];
this.a(var4);
this.a = var4;
this.c = (int) ((float) var1 * this.d);
}
}
private void a(PlayerListEntry[] var1) {
PlayerListEntry[] var2 = this.a;
int var3 = var1.length;
for (int var4 = 0; var4 < var2.length; ++var4) {
PlayerListEntry var5 = var2[var4];
if (var5 != null) {
var2[var4] = null;
PlayerListEntry var6;
do {
var6 = var5.c;
int var7 = a(var5.d, var3);
var5.c = var1[var7];
var1[var7] = var5;
var5 = var6;
} while (var6 != null);
}
}
}
public Object b(long var1) {
PlayerListEntry var3 = this.c(var1);
return var3 == null ? null : var3.b;
}
final PlayerListEntry c(long var1) {
int var3 = e(var1);
int var4 = a(var3, this.a.length);
PlayerListEntry var5 = this.a[var4];
PlayerListEntry var6;
PlayerListEntry var7;
for (var6 = var5; var6 != null; var6 = var7) {
var7 = var6.c;
if (var6.a == var1) {
++this.e;
--this.b;
if (var5 == var6) {
this.a[var4] = var7;
} else {
var5.c = var7;
}
return var6;
}
var5 = var6;
}
return var6;
}
private void a(int var1, long var2, Object var4, int var5) {
PlayerListEntry var6 = this.a[var5];
this.a[var5] = new PlayerListEntry(var1, var2, var4, var6);
if (this.b++ >= this.c) {
this.b(2 * this.a.length);
}
}
public PlayerListEntry[] getMap() {
return a;
}
}

View File

@ -0,0 +1,181 @@
package net.minecraft.server;
import java.util.ArrayList;
import java.util.List;
public class PlayerManager {
private List a = new ArrayList();
private PlayerList b = new PlayerList();
private List c = new ArrayList();
private MinecraftServer d;
private final int[][] e = new int[][]{{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
public WorldServer world;
public PlayerManager(MinecraftServer minecraftserver, WorldServer world) {
this.d = minecraftserver;
this.world = world;
}
public void a() {
for (int i = 0; i < this.c.size(); ++i) {
((PlayerInstance) this.c.get(i)).a();
}
this.c.clear();
}
private PlayerInstance a(int i, int j, boolean flag) {
long k = (long) i + 2147483647L | (long) j + 2147483647L << 32;
PlayerInstance playerinstance = (PlayerInstance) this.b.a(k);
if (playerinstance == null && flag) {
playerinstance = new PlayerInstance(this, i, j);
this.b.a(k, playerinstance);
}
return playerinstance;
}
public void a(int i, int j, int k) {
int l = i >> 4;
int i1 = k >> 4;
PlayerInstance playerinstance = this.a(l, i1, false);
if (playerinstance != null) {
playerinstance.a(i & 15, j, k & 15);
}
}
public void a(EntityPlayer entityplayer) {
int i = (int) entityplayer.locX >> 4;
int j = (int) entityplayer.locZ >> 4;
entityplayer.d = entityplayer.locX;
entityplayer.e = entityplayer.locZ;
int k = 0;
byte b0 = 10;
int l = 0;
int i1 = 0;
this.a(i, j, true).a(entityplayer);
int j1;
for (j1 = 1; j1 <= b0 * 2; ++j1) {
for (int k1 = 0; k1 < 2; ++k1) {
int[] aint = this.e[k++ % 4];
for (int l1 = 0; l1 < j1; ++l1) {
l += aint[0];
i1 += aint[1];
this.a(i + l, j + i1, true).a(entityplayer);
}
}
}
k %= 4;
for (j1 = 0; j1 < b0 * 2; ++j1) {
l += this.e[k][0];
i1 += this.e[k][1];
this.a(i + l, j + i1, true).a(entityplayer);
}
this.a.add(entityplayer);
}
public void b(EntityPlayer entityplayer) {
/*
int i = (int) entityplayer.d >> 4;
int j = (int) entityplayer.e >> 4;
for (int k = i - 10; k <= i + 10; ++k) {
for (int l = j - 10; l <= j + 10; ++l) {
PlayerInstance playerinstance = this.a(k, l, false);
if (playerinstance != null) {
playerinstance.b(entityplayer);
}
}
}
*/
// rewritten to remove player from all loaded chunks
PlayerListEntry[] et = this.b.getMap();
for(int i = 0; i < et.length; ++i) {
for(PlayerListEntry etr = et[i]; etr != null; etr = etr.c) {
if(etr.b != null) {
((PlayerInstance)etr.b).b(entityplayer);
}
}
}
this.a.remove(entityplayer);
}
private boolean a(int i, int j, int k, int l) {
int i1 = i - k;
int j1 = j - l;
return i1 >= -10 && i1 <= 10 ? j1 >= -10 && j1 <= 10 : false;
}
public void c(EntityPlayer entityplayer) {
int i = (int) entityplayer.locX >> 4;
int j = (int) entityplayer.locZ >> 4;
double d0 = entityplayer.d - entityplayer.locX;
double d1 = entityplayer.e - entityplayer.locZ;
double d2 = d0 * d0 + d1 * d1;
if (d2 >= 64.0D) {
int k = (int) entityplayer.d >> 4;
int l = (int) entityplayer.e >> 4;
int i1 = i - k;
int j1 = j - l;
if (!this.a(i, j, k, l)) {
this.a(i, j, true).a(entityplayer);
}
if (!this.a(i - i1, j - j1, i, j)) {
PlayerInstance playerinstance = this.a(i - i1, j - j1, false);
if (playerinstance != null) {
playerinstance.b(entityplayer);
}
}
if (i1 != 0 || j1 != 0) {
for (int k1 = i - 10; k1 <= i + 10; ++k1) {
for (int l1 = j - 10; l1 <= j + 10; ++l1) {
if (k1 != i || l1 != j) {
if (!this.a(k1, l1, k, l)) {
this.a(k1, l1, true).a(entityplayer);
}
if (!this.a(k1 - i1, l1 - j1, i, j)) {
PlayerInstance playerinstance = this.a(k1 - i1, l1 - j1, false);
if (playerinstance != null) {
playerinstance.b(entityplayer);
}
}
}
}
}
entityplayer.d = entityplayer.locX;
entityplayer.e = entityplayer.locZ;
}
}
}
public int b() {
return 144;
}
static MinecraftServer a(PlayerManager playermanager) {
return playermanager.d;
}
static PlayerList b(PlayerManager playermanager) {
return playermanager.b;
}
static List c(PlayerManager playermanager) {
return playermanager.c;
}
}

View File

@ -0,0 +1,11 @@
enable_password_logins: true
only_allow_registered_users_to_login: true
allow_passwords_without_expiration: true
allow_self_registration: false
allow_self_registration_without_expiration: false
allow_self_change_password: true
allow_self_renew_password: true
allow_self_change_password_expiration: false
allow_self_delete_password: false
default_password_expire_time_seconds: 604800
maximum_password_expire_time_seconds: 1814400

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -15,6 +15,12 @@ menu.quit=Quit Game
menu.editProfile=Edit Profile
menu.exitChat=Exit Chat
profile.title=Edit Profile
profile.screenname=Screenname
profile.playerSkin=Player Skin
profile.addSkin=Add Skin
profile.clearSkin=Clear List
selectWorld.title=Select World
selectWorld.empty=empty
selectWorld.world=World

Binary file not shown.

After

Width:  |  Height:  |  Size: 511 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 950 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -29,7 +29,7 @@ public class SaveFormatOld implements ISaveFormat {
return "Old Format";
}
public List getWorldList() {
public List getWorldList(IProgressUpdate progress) {
ArrayList arraylist = new ArrayList();
for (int i = 0; i < 5; i++) {
String s = (new StringBuilder()).append("World").append(i + 1).toString();

View File

@ -4,7 +4,7 @@ public class ConfigConstants {
public static boolean profanity = false;
public static final String version = "22w21a-SNAPSHOT";
public static final String version = "22w22a";
public static final String mainMenuString = "eaglercraft beta-" + version;
public static final String forkMe = "https://github.com/LAX1DUDE/eaglercraft";

View File

@ -0,0 +1,389 @@
package net.lax1dude.eaglercraft;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import net.minecraft.client.Minecraft;
import net.minecraft.src.NBTTagCompound;
import net.minecraft.src.RenderEngine;
public class EaglerProfile {
public static class EaglerProfileSkin {
public String name;
public byte[] data;
public boolean slim;
public int glTex;
public EaglerProfileSkin(String name, byte[] data, boolean slim, int glTex) {
this.name = name;
this.data = data;
this.slim = slim;
this.glTex = glTex;
}
}
public static String username;
public static int presetSkinId;
public static int customSkinId;
public static String myChannel;
public static final int SKIN_DATA_SIZE = 64*32*4;
public static ArrayList<EaglerProfileSkin> skins = new ArrayList();
public static final EaglercraftRandom rand;
public static byte[] getSelfSkinPacket() {
if(presetSkinId == -1) {
byte[] d = skins.get(customSkinId).data;
byte[] d2 = new byte[1 + d.length];
d2[0] = (byte) 1;
System.arraycopy(d, 0, d2, 1, d.length);
return d2;
}else {
return new byte[] { (byte)0, (byte)presetSkinId };
}
}
public static String[] concatArrays(String[] a, String[] b) {
String[] r = new String[a.length + b.length];
System.arraycopy(a, 0, r, 0, a.length);
System.arraycopy(b, 0, r, a.length, b.length);
return r;
}
public static int addSkin(String name, byte[] data, boolean slim) {
int i = -1;
for(int j = 0, l = skins.size(); j < l; ++j) {
if(skins.get(j).name.equalsIgnoreCase(name)) {
i = j;
break;
}
}
if(data.length != SKIN_DATA_SIZE) {
return -1;
}
int im = Minecraft.getMinecraft().renderEngine.allocateAndSetupTexture(data, 64, 32);
if(i == -1) {
i = skins.size();
skins.add(new EaglerProfileSkin(name, data, slim, im));
}else {
skins.get(i).glTex = im;
skins.get(i).data = data;
skins.get(i).slim = slim;
}
return i;
}
private static class CachedSkin {
protected final String username;
protected UserSkin skin;
protected long age;
protected CachedSkin(String username, UserSkin skin) {
this.username = username;
this.skin = skin;
this.age = System.currentTimeMillis();
}
}
public static enum EnumSkinType {
PRESET, CUSTOM_LEGACY
}
public static interface UserSkin {
abstract EnumSkinType getSkinType();
abstract int getSkin();
abstract int getTexture();
abstract void free();
}
private static class UserPresetSkin implements UserSkin {
protected final int skinType;
protected UserPresetSkin(int skin) {
this.skinType = skin;
}
@Override
public EnumSkinType getSkinType() {
return EnumSkinType.PRESET;
}
@Override
public int getSkin() {
return skinType;
}
@Override
public int getTexture() {
return (skinType >= defaultOptionsTextures.length || skinType < 0) ? -1 : defaultOptionsTextures[skinType].getTexturePointer();
}
@Override
public void free() {
}
}
private static class UserCustomSkin implements UserSkin {
protected final byte[] data;
protected int glTexture;
protected UserCustomSkin(byte[] data) {
this.data = data;
this.glTexture = -1;
}
@Override
public EnumSkinType getSkinType() {
return EnumSkinType.CUSTOM_LEGACY;
}
@Override
public int getSkin() {
return -1;
}
@Override
public int getTexture() {
RenderEngine r = Minecraft.getMinecraft().renderEngine;
if(glTexture == -1) {
glTexture = r.allocateAndSetupTexture(data, 64, 32);
}
return glTexture;
}
@Override
public void free() {
RenderEngine r = Minecraft.getMinecraft().renderEngine;
r.deleteTexture(glTexture);
glTexture = -1;
}
}
private static class WaitingSkin {
protected final int cookie;
protected final String username;
protected final long requestStartTime;
protected WaitingSkin(int cookie, String username) {
this.cookie = cookie;
this.username = username;
this.requestStartTime = System.currentTimeMillis();
}
}
private static final Map<Integer,WaitingSkin> multiplayerWaitingSkinCache = new HashMap();
private static final Map<String,CachedSkin> multiplayerSkinCache = new HashMap();
private static final long maxSkinAge = 1000l * 60l * 5l;
private static final UserSkin defaultSkin = new UserPresetSkin(0);
private static int skinRequestId = 0;
public static int beginSkinRequest(String un) {
int ret = skinRequestId++;
if(skinRequestId >= 65536) {
skinRequestId = 0;
}
multiplayerWaitingSkinCache.put(ret, new WaitingSkin(ret, un));
return ret;
}
public static boolean skinRequestPending(String un) {
return multiplayerWaitingSkinCache.containsKey(un);
}
public static UserSkin getUserSkin(String un) {
CachedSkin cs = multiplayerSkinCache.get(un);
if(cs == null) {
return null;
}else {
cs.age = System.currentTimeMillis();
return cs.skin;
}
}
public static void processSkinResponse(byte[] dat) {
if(dat.length >= 3) {
int cookie = (((int)dat[0] & 0xFF) << 8) | ((int)dat[1] & 0xFF);
WaitingSkin st = multiplayerWaitingSkinCache.remove(cookie);
if(st != null) {
int t = (int)dat[2] & 0xFF;
if(t == 0) {
if(dat.length == 4) {
multiplayerSkinCache.put(st.username, new CachedSkin(st.username, new UserPresetSkin((int)dat[3] & 0xFF)));
}else {
System.out.println("Recieved a PRESET skin of the wrong size (" + (dat.length - 3) + ") for player " + st + ".");
}
}else if(t == 1) {
if(dat.length == 3 + SKIN_DATA_SIZE) {
byte[] datt = new byte[SKIN_DATA_SIZE];
System.arraycopy(dat, 3, datt, 0, SKIN_DATA_SIZE);
multiplayerSkinCache.put(st.username, new CachedSkin(st.username, new UserCustomSkin(datt)));
}else {
System.out.println("Recieved a CUSTOM_LEGACY skin of the wrong size (" + (dat.length - 3) + ") for player " + st + ".");
}
}else {
System.out.println("Unsupported skin type '" + t + "' was recieved from server for player " + st + ".");
}
}
}
}
public static void freeSkins() {
long millis = System.currentTimeMillis();
Iterator<CachedSkin> skns = multiplayerSkinCache.values().iterator();
while(skns.hasNext()) {
CachedSkin cs = skns.next();
if(millis - cs.age > maxSkinAge) {
cs.skin.free();
skns.remove();
}
}
Iterator<WaitingSkin> skns2 = multiplayerWaitingSkinCache.values().iterator();
while(skns2.hasNext()) {
WaitingSkin cs = skns2.next();
if(millis - cs.requestStartTime > 10000l) {
skns2.remove();
}
}
}
public static void freeUserSkin(String un) {
CachedSkin cs = multiplayerSkinCache.remove(un);
if(cs != null) {
cs.skin.free();
}
}
public static void freeAllSkins() {
Iterator<CachedSkin> skns = multiplayerSkinCache.values().iterator();
while(skns.hasNext()) {
skns.next().skin.free();
}
multiplayerWaitingSkinCache.clear();
multiplayerSkinCache.clear();
}
static {
String[] usernameDefaultWords = ConfigConstants.profanity ? new String[] {
"Eagler",
"Eagler",
"Bitch",
"Cock",
"Milf",
"Milf",
"Yeer",
"Groon",
"Eag",
"Deevis",
"Chode",
"Deev",
"Deev",
"Fucker",
"Fucking",
"Dumpster",
"Dumpster",
"Cum",
"Chad",
"Egg",
"Fudgler",
"Fudgli",
"Yee",
"Yee",
"Yee",
"Yeet",
"Flumpter",
"Darvy",
"Darver",
"Darver",
"Fuck",
"Fuck",
"Frick",
"Eagler",
"Vigg",
"Vigg",
"Cunt",
"Darvig"
} : new String[] {
"Yeeish",
"Yeeish",
"Yee",
"Yee",
"Yeer",
"Yeeler",
"Eagler",
"Eagl",
"Darver",
"Darvler",
"Vool",
"Vigg",
"Vigg",
"Deev",
"Yigg",
"Yeeg"
};
rand = new EaglercraftRandom();
do {
username = usernameDefaultWords[rand.nextInt(usernameDefaultWords.length)] + usernameDefaultWords[rand.nextInt(usernameDefaultWords.length)] + (10 + rand.nextInt(90));
}while(username.length() > 16);
presetSkinId = rand.nextInt(GuiScreenEditProfile.defaultOptions.length);
myChannel = username + "_" + (100 + rand.nextInt(900));
customSkinId = -1;
}
public static void loadFromStorage() {
if(!LocalStorageManager.profileSettingsStorage.hasNoTags()) {
presetSkinId = LocalStorageManager.profileSettingsStorage.getInteger("ps");
customSkinId = LocalStorageManager.profileSettingsStorage.getInteger("cs");
username = LocalStorageManager.profileSettingsStorage.getString("name");
myChannel = username + "_" + (100 + rand.nextInt(900));
NBTTagCompound n = LocalStorageManager.profileSettingsStorage.getCompoundTag("skins");
for(Object s : NBTTagCompound.getTagMap(n).keySet()) {
String s2 = (String)s;
addSkin(s2, n.getByteArray(s2), false);
}
}
}
public static final TextureLocation[] defaultOptionsTextures = new TextureLocation[] {
new TextureLocation("/skins/01.default_steve.png"),
new TextureLocation("/skins/02.tennis_steve.png"),
new TextureLocation("/skins/03.tuxedo_steve.png"),
new TextureLocation("/skins/04.athlete_steve.png"),
new TextureLocation("/skins/05.cyclist_steve.png"),
new TextureLocation("/skins/06.boxer_steve.png"),
new TextureLocation("/skins/07.prisoner_steve.png"),
new TextureLocation("/skins/08.scottish_steve.png"),
new TextureLocation("/skins/09.dev_steve.png"),
new TextureLocation("/skins/10.herobrine.png"),
new TextureLocation("/skins/11.slime.png"),
new TextureLocation("/skins/12.trump.png"),
new TextureLocation("/skins/13.notch.png"),
new TextureLocation("/skins/14.creeper.png"),
new TextureLocation("/skins/15.zombie.png"),
new TextureLocation("/skins/16.pig.png"),
new TextureLocation("/skins/17.squid.png"),
new TextureLocation("/skins/18.mooshroom.png")
};
}

View File

@ -0,0 +1,401 @@
package net.lax1dude.eaglercraft;
import net.lax1dude.eaglercraft.EaglerProfile.EaglerProfileSkin;
import net.minecraft.client.Minecraft;
import net.minecraft.src.GuiButton;
import net.minecraft.src.GuiScreen;
import net.minecraft.src.GuiTextField;
import net.minecraft.src.ModelBiped;
import net.minecraft.src.NBTTagCompound;
import net.minecraft.src.RenderHelper;
import net.minecraft.src.Session;
import net.minecraft.src.StringTranslate;
public class GuiScreenEditProfile extends GuiScreen {
private GuiScreen parent;
private GuiTextField username;
private boolean dropDownOpen = false;
private String[] dropDownOptions;
private int slotsVisible = 0;
private int selectedSlot = 0;
private int scrollPos = -1;
private int skinsHeight = 0;
private boolean dragging = false;
private int mousex = 0;
private int mousey = 0;
private static final TextureLocation gui = new TextureLocation("/gui/gui.png");
public static final String[] defaultOptions = new String[] {
"Default Steve",
"Tennis Steve",
"Tuxedo Steve",
"Athlete Steve",
"Cyclist Steve",
"Boxer Steve",
"Prisoner Steve",
"Scottish Steve",
"Developer Steve",
"Herobrine",
"Slime",
"Trump",
"Notch",
"Creeper",
"Zombie",
"Pig",
"Squid",
"Mooshroom"
};
public static final TextureLocation[] defaultOptionsTextures = new TextureLocation[] {
new TextureLocation("/skins/01.default_steve.png"),
new TextureLocation("/skins/02.tennis_steve.png"),
new TextureLocation("/skins/03.tuxedo_steve.png"),
new TextureLocation("/skins/04.athlete_steve.png"),
new TextureLocation("/skins/05.cyclist_steve.png"),
new TextureLocation("/skins/06.boxer_steve.png"),
new TextureLocation("/skins/07.prisoner_steve.png"),
new TextureLocation("/skins/08.scottish_steve.png"),
new TextureLocation("/skins/09.dev_steve.png"),
new TextureLocation("/skins/10.herobrine.png"),
new TextureLocation("/skins/11.slime.png"),
new TextureLocation("/skins/12.trump.png"),
new TextureLocation("/skins/13.notch.png"),
new TextureLocation("/skins/14.creeper.png"),
new TextureLocation("/skins/15.zombie.png"),
new TextureLocation("/skins/16.pig.png"),
new TextureLocation("/skins/17.squid.png"),
new TextureLocation("/skins/18.mooshroom.png")
};
protected String screenTitle = "Edit Profile";
public GuiScreenEditProfile(GuiScreen parent) {
this.parent = parent;
reconcatDD();
}
private void reconcatDD() {
String[] n = new String[EaglerProfile.skins.size()];
for(int i = 0; i < n.length; ++i) {
n[i] = EaglerProfile.skins.get(i).name;
}
this.dropDownOptions = EaglerProfile.concatArrays(n, defaultOptions);
}
private GuiButton button0, button1, button2, button10, button11, button12;
public void initGui() {
super.initGui();
EaglerAdapter.enableRepeatEvents(true);
StringTranslate var1 = StringTranslate.getInstance();
this.screenTitle = var1.translateKey("profile.title");
this.username = new GuiTextField(this.fontRenderer, this.width / 2 - 20 + 1, this.height / 6 + 24 + 1, 138, 20, EaglerProfile.username);
this.username.field_22081_b = true;
selectedSlot = EaglerProfile.presetSkinId == -1 ? EaglerProfile.customSkinId : (EaglerProfile.presetSkinId + EaglerProfile.skins.size());
//this.buttonList.add(new GuiButton(0, this.width / 2 - 100, 140, "eeeee"));
this.controlList.add(button0 = new GuiButton(200, this.width / 2 - 100, this.height / 6 + 168, var1.translateKey("gui.done")));
this.controlList.add(button1 = new GuiButton(2, this.width / 2 - 21, this.height / 6 + 110, 71, 20, var1.translateKey("profile.addSkin")));
this.controlList.add(button2 = new GuiButton(3, this.width / 2 - 21 + 71, this.height / 6 + 110, 72, 20, var1.translateKey("profile.clearSkin")));
//this.buttonList.add(new GuiButton(200, this.width / 2, this.height / 6 + 72, 150, 20, var1.translateKey("gui.done")));
}
private static ModelBiped playerModel = null;
public void drawScreen(int mx, int my, float par3) {
StringTranslate var1 = StringTranslate.getInstance();
this.drawDefaultBackground();
this.drawCenteredString(this.fontRenderer, this.screenTitle, this.width / 2, 15, 16777215);
this.drawString(this.fontRenderer, var1.translateKey("profile.screenname"), this.width / 2 - 20, this.height / 6 + 8, 10526880);
this.drawString(this.fontRenderer, var1.translateKey("profile.playerSkin"), this.width / 2 - 20, this.height / 6 + 66, 10526880);
mousex = mx;
mousey = my;
int skinX = this.width / 2 - 120;
int skinY = this.height / 6 + 8;
int skinWidth = 80;
int skinHeight = 130;
drawRect(skinX, skinY, skinX + skinWidth, skinY + skinHeight, -6250336);
drawRect(skinX + 1, skinY + 1, skinX + skinWidth - 1, skinY + skinHeight - 1, 0xff000015);
this.username.drawTextBox();
if(dropDownOpen) {
super.drawScreen(0, 0, par3);
}else {
super.drawScreen(mx, my, par3);
}
skinX = this.width / 2 - 20;
skinY = this.height / 6 + 82;
skinWidth = 140;
skinHeight = 22;
drawRect(skinX, skinY, skinX + skinWidth, skinY + skinHeight, -6250336);
drawRect(skinX + 1, skinY + 1, skinX + skinWidth - 21, skinY + skinHeight - 1, -16777216);
drawRect(skinX + skinWidth - 20, skinY + 1, skinX + skinWidth - 1, skinY + skinHeight - 1, -16777216);
EaglerAdapter.glColor4f(1f, 1f, 1f, 1f);
gui.bindTexture();
drawTexturedModalRect(skinX + skinWidth - 18, skinY + 3, 0, 240, 16, 16);
this.fontRenderer.drawStringWithShadow(dropDownOptions[selectedSlot], skinX + 5, skinY + 7, 14737632);
skinX = this.width / 2 - 20;
skinY = this.height / 6 + 103;
skinWidth = 140;
skinHeight = (this.height - skinY - 10);
slotsVisible = (skinHeight / 10);
if(slotsVisible > dropDownOptions.length) slotsVisible = dropDownOptions.length;
skinHeight = slotsVisible * 10 + 7;
skinsHeight = skinHeight;
if(scrollPos == -1) {
scrollPos = selectedSlot - 2;
}
if(scrollPos > (dropDownOptions.length - slotsVisible)) {
scrollPos = (dropDownOptions.length - slotsVisible);
}
if(scrollPos < 0) {
scrollPos = 0;
}
if(dropDownOpen) {
drawRect(skinX, skinY, skinX + skinWidth, skinY + skinHeight, -6250336);
drawRect(skinX + 1, skinY + 1, skinX + skinWidth - 1, skinY + skinHeight - 1, -16777216);
for(int i = 0; i < slotsVisible; i++) {
if(i + scrollPos < dropDownOptions.length) {
if(selectedSlot == i + scrollPos) {
drawRect(skinX + 1, skinY + i*10 + 4, skinX + skinWidth - 1, skinY + i*10 + 14, 0x77ffffff);
}else if(mx >= skinX && mx < (skinX + skinWidth - 10) && my >= (skinY + i*10 + 5) && my < (skinY + i*10 + 15)) {
drawRect(skinX + 1, skinY + i*10 + 4, skinX + skinWidth - 1, skinY + i*10 + 14, 0x55ffffff);
}
this.fontRenderer.drawStringWithShadow(dropDownOptions[i + scrollPos], skinX + 5, skinY + 5 + i*10, 14737632);
}
}
int scrollerSize = skinHeight * slotsVisible / dropDownOptions.length;
int scrollerPos = skinHeight * scrollPos / dropDownOptions.length;
drawRect(skinX + skinWidth - 4, skinY + scrollerPos + 1, skinX + skinWidth - 1, skinY + scrollerPos + scrollerSize, 0xff888888);
}
int xx = this.width / 2 - 80;
int yy = this.height / 6 + 130;
skinX = this.width / 2 - 120;
skinY = this.height / 6 + 8;
skinWidth = 80;
skinHeight = 130;
int id = selectedSlot - EaglerProfile.skins.size();
if(id < 0) {
Minecraft.getMinecraft().renderEngine.bindTexture(EaglerProfile.skins.get(selectedSlot).glTex);
}else {
defaultOptionsTextures[id].bindTexture();
}
EaglerAdapter.glEnable(EaglerAdapter.GL_TEXTURE_2D);
EaglerAdapter.glDisable(EaglerAdapter.GL_BLEND);
EaglerAdapter.glDisable(EaglerAdapter.GL_CULL_FACE);
EaglerAdapter.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
EaglerAdapter.glPushMatrix();
EaglerAdapter.glTranslatef((float) xx, (float) (yy - 80), 100.0F);
EaglerAdapter.glScalef(50.0f, 50.0f, 50.0f);
EaglerAdapter.glRotatef(180.0f, 1.0f, 0.0f, 0.0f);
RenderHelper.enableStandardItemLighting();
EaglerAdapter.glScalef(1.0F, -1.0F, 1.0F);
EaglerAdapter.glTranslatef(0.0F, 1.0F, 0.0F);
EaglerAdapter.glRotatef(((yy - my) * -0.06f), 1.0f, 0.0f, 0.0f);
EaglerAdapter.glRotatef(((xx - mx) * 0.06f), 0.0f, 1.0f, 0.0f);
EaglerAdapter.glTranslatef(0.0F, -1.0F, 0.0F);
if(playerModel == null) {
playerModel = new ModelBiped(0.0f);
playerModel.blockTransparentSkins = true;
}
playerModel.render(0.0f, 0.0f, (float)(System.currentTimeMillis() % 100000) / 50f, ((xx - mx) * 0.06f), ((yy - my) * -0.1f), 0.0625F);
EaglerAdapter.glPopMatrix();
EaglerAdapter.glEnable(EaglerAdapter.GL_BLEND);
EaglerAdapter.glEnable(EaglerAdapter.GL_CULL_FACE);
}
public void handleMouseInput() {
super.handleMouseInput();
if(dropDownOpen) {
int var1 = EaglerAdapter.mouseGetEventDWheel();
if(var1 < 0) {
scrollPos += 3;
}
if(var1 > 0) {
scrollPos -= 3;
}
if(scrollPos < 0) {
scrollPos = 0;
}
if(scrollPos > defaultOptions.length + EaglerProfile.skins.size()) {
scrollPos = defaultOptions.length + EaglerProfile.skins.size();
}
}
}
private void save() {
EaglerProfile.username = this.username.getTextBoxText().length() == 0 ? "null" : this.username.getTextBoxText();
mc.session = new Session(EaglerProfile.username, "-");
EaglerProfile.presetSkinId = selectedSlot - EaglerProfile.skins.size();
if(EaglerProfile.presetSkinId < 0) {
EaglerProfile.presetSkinId = -1;
EaglerProfile.customSkinId = selectedSlot;
}else {
EaglerProfile.customSkinId = -1;
}
LocalStorageManager.profileSettingsStorage.setInteger("ps", EaglerProfile.presetSkinId);
LocalStorageManager.profileSettingsStorage.setInteger("cs", EaglerProfile.customSkinId);
LocalStorageManager.profileSettingsStorage.setString("name", EaglerProfile.username);
NBTTagCompound skins = new NBTTagCompound();
for(int i = 0, l = EaglerProfile.skins.size(); i < l; i++) {
skins.setByteArray(EaglerProfile.skins.get(i).name, EaglerProfile.skins.get(i).data);
}
LocalStorageManager.profileSettingsStorage.setCompoundTag("skins", skins);
LocalStorageManager.saveStorageP();
}
protected void actionPerformed(GuiButton par1GuiButton) {
if(!dropDownOpen) {
if(par1GuiButton.id == 200) {
save();
this.mc.displayGuiScreen((GuiScreen) parent);
}else if(par1GuiButton.id == 2) {
EaglerAdapter.openFileChooser("png", "image/png");
}else if(par1GuiButton.id == 3) {
for(EaglerProfileSkin i : EaglerProfile.skins) {
this.mc.renderEngine.deleteTexture(i.glTex);
}
EaglerProfile.skins.clear();
this.dropDownOptions = defaultOptions;
this.selectedSlot = 0;
save();
}
}
}
public void updateScreen() {
this.username.onUpdate();
if(dropDownOpen) {
if(EaglerAdapter.mouseIsButtonDown(0)) {
int skinX = this.width / 2 - 20;
int skinY = this.height / 6 + 103;
int skinWidth = 140;
if(mousex >= (skinX + skinWidth - 10) && mousex < (skinX + skinWidth) && mousey >= skinY && mousey < (skinY + skinsHeight)) {
dragging = true;
}
if(dragging) {
int scrollerSize = skinsHeight * slotsVisible / dropDownOptions.length;
scrollPos = (mousey - skinY - (scrollerSize / 2)) * dropDownOptions.length / skinsHeight;
}
}else {
dragging = false;
}
}else {
dragging = false;
}
byte[] b;
if((b = EaglerAdapter.getFileChooserResult()) != null && b.length > 0) {
EaglerImage img = EaglerAdapter.loadPNG(b);
if(!((img.w == 64 && img.h == 32) || (img.w == 64 && img.h == 64) || (img.w == 128 && img.h == 64) || (img.w == 128 && img.h == 128))) return;
byte[] rawSkin = new byte[img.data.length * 4];
for(int i = 0; i < img.data.length; i++) {
int i2 = i * 4; int i3 = img.data[i];
rawSkin[i2] = (byte)(i3 >> 16);
rawSkin[i2 + 1] = (byte)(i3 >> 8);
rawSkin[i2 + 2] = (byte)(i3);
rawSkin[i2 + 3] = (byte)(i3 >> 24);
}
String name = EaglerAdapter.getFileChooserResultName();
if(name.length() > 32) {
name = name.substring(0, 32);
}
int k;
if((k = EaglerProfile.addSkin(name, rawSkin, false)) != -1) {
selectedSlot = k;
reconcatDD();
save();
}
}
}
public void onGuiClosed() {
EaglerAdapter.enableRepeatEvents(false);
}
protected void keyTyped(char par1, int par2) {
this.username.handleKeyboardInput(par1, par2);
String text = username.getTextBoxText();
if(text.length() > 16) text = text.substring(0, 16);
text = text.replaceAll("[^A-Za-z0-9\\-_]", "_");
this.username.setTextBoxText(text);
if(par2 == 200 && selectedSlot > 0) {
--selectedSlot;
scrollPos = selectedSlot - 2;
}
if(par2 == 208 && selectedSlot < (dropDownOptions.length - 1)) {
++selectedSlot;
scrollPos = selectedSlot - 2;
}
}
protected void mouseClicked(int par1, int par2, int par3) {
super.mouseClicked(par1, par2, par3);
this.username.handleMouseInput(par1, par2, par3);
if (par3 == 0) {
int skinX = this.width / 2 + 140 - 40;
int skinY = this.height / 6 + 82;
if(par1 >= skinX && par1 < (skinX + 20) && par2 >= skinY && par2 < (skinY + 22)) {
dropDownOpen = !dropDownOpen;
}
skinX = this.width / 2 - 20;
skinY = this.height / 6 + 82;
int skinWidth = 140;
int skinHeight = skinsHeight;
if(!(par1 >= skinX && par1 < (skinX + skinWidth) && par2 >= skinY && par2 < (skinY + skinHeight + 22))) {
dropDownOpen = false;
dragging = false;
}
skinY += 21;
if(dropDownOpen && !dragging) {
for(int i = 0; i < slotsVisible; i++) {
if(i + scrollPos < dropDownOptions.length) {
if(selectedSlot != i + scrollPos) {
if(par1 >= skinX && par1 < (skinX + skinWidth - 10) && par2 >= (skinY + i*10 + 5) && par2 < (skinY + i*10 + 15) && selectedSlot != i + scrollPos) {
selectedSlot = i + scrollPos;
dropDownOpen = false;
dragging = false;
}
}
}
}
}
}
}
}

View File

@ -22,7 +22,7 @@ public class TextureLocation {
}
}
public void bindTexture() {
public int getTexturePointer() {
RenderEngine r = Minecraft.getMinecraft().renderEngine;
if (glObject == -1) {
glObject = r.getTexture(path);
@ -30,7 +30,15 @@ public class TextureLocation {
System.err.println("could not load: " + path);
}
}
r.bindTexture(glObject);
return glObject;
}
public void bindTexture() {
RenderEngine r = Minecraft.getMinecraft().renderEngine;
int i = getTexturePointer();
if(i != -1) {
r.bindTexture(i);
}
}
private static final ArrayList<TextureLocation> locations = new ArrayList();

View File

@ -140,4 +140,8 @@ public class WebsocketNetworkManager {
return this.serverURI;
}
public boolean isSocketOpen() {
return EaglerAdapter.connectionOpen();
}
}

View File

@ -39,7 +39,8 @@ public class EaglercraftSaveManager implements ISaveFormat {
}
@Override
public List getWorldList() {
public List getWorldList(IProgressUpdate progress) {
progress.displayLoadingString("Loading Worlds...", "just wait a moment");
ArrayList<SaveFormatComparator> lst = new ArrayList<>();
EaglerAdapter.listFilesAndDirectories(directory).forEach(new Consumer<FileEntry>() {
@Override

View File

@ -5,7 +5,9 @@
package net.minecraft.client;
import net.lax1dude.eaglercraft.EaglerAdapter;
import net.lax1dude.eaglercraft.EaglerProfile;
import net.lax1dude.eaglercraft.GuiMultiplayer;
import net.lax1dude.eaglercraft.GuiScreenEditProfile;
import net.lax1dude.eaglercraft.TextureLocation;
import net.lax1dude.eaglercraft.adapter.Tessellator;
import net.lax1dude.eaglercraft.beta.EaglercraftSaveManager;
@ -91,15 +93,18 @@ public abstract class Minecraft implements Runnable {
EaglerAdapter.glViewport(0, 0, displayWidth, displayHeight);
effectRenderer = new EffectRenderer(theWorld, renderEngine);
checkGLError("Post startup");
EaglerProfile.loadFromStorage();
session = new Session(EaglerProfile.username, "-");
while(EaglerAdapter.keysNext());
while(EaglerAdapter.mouseNext());
ingameGUI = new GuiIngame(this);
String srv = EaglerAdapter.getServerToJoinOnLaunch();
if (srv != null && srv.length() > 0) {
displayGuiScreen(new GuiMultiplayer(new GuiMainMenu(), srv));
displayGuiScreen(new GuiScreenEditProfile(new GuiMultiplayer(new GuiMainMenu(), srv)));
} else {
displayGuiScreen(new GuiMainMenu());
displayGuiScreen(new GuiScreenEditProfile(new GuiMainMenu()));
}
}
@ -551,8 +556,18 @@ public abstract class Minecraft implements Runnable {
playerController.updateController();
if(++holdStillTimer == 150) {
if (thePlayer != null) {
ingameGUI.addChatMessage("Note, the game can lag when chunks are generated");
ingameGUI.addChatMessage("hold still for a few moments and the lag will stop");
if(isMultiplayerWorld()) {
//ingameGUI.addChatMessage("Known Multiplayer Bugs:");
//ingameGUI.addChatMessage(" - chunks may not show until you move around");
//ingameGUI.addChatMessage(" - block crack animation is fucked up");
}else {
ingameGUI.addChatMessage("Note, the game can lag when chunks are generated");
ingameGUI.addChatMessage("hold still for a few moments and the lag will stop");
}
}
}else if(holdStillTimer == 10) {
if(isMultiplayerWorld()) {
renderGlobal.loadRenderers(); // dammit
}
}
}
@ -705,6 +720,7 @@ public abstract class Minecraft implements Runnable {
theWorld.difficultySetting = 3;
}
if (!isWorldLoaded) {
EaglerProfile.freeSkins();
entityRenderer.updateRenderer();
}
if (!isWorldLoaded) {
@ -749,7 +765,6 @@ public abstract class Minecraft implements Runnable {
}
public void startWorld(String s, String s1, long l) {
holdStillTimer = 0;
changeWorld1(null);
System.gc();
if (field_22008_V.worldNeedsConvert_maybe(s)) {
@ -802,6 +817,7 @@ public abstract class Minecraft implements Runnable {
}
public void changeWorld2(World world, String s) {
holdStillTimer = 0;
changeWorld(world, s, null);
}
@ -859,6 +875,7 @@ public abstract class Minecraft implements Runnable {
field_22009_h = thePlayer;
mouseHelper.grabMouse();
} else {
EaglerProfile.freeAllSkins();
ungrabMouseCursor();
thePlayer = null;
}

View File

@ -16,6 +16,7 @@ public class EntityOtherPlayerMP extends EntityPlayer {
skinUrl = (new StringBuilder()).append("http://s3.amazonaws.com/MinecraftSkins/").append(s).append(".png")
.toString();
}
skinUrl = "MPSkin" + s;
noClip = true;
field_22062_y = 0.25F;
renderDistanceWeight = 10D;

View File

@ -28,6 +28,7 @@ public abstract class EntityPlayer extends EntityLiving {
field_9351_C = "humanoid";
field_9353_B = 180F;
fireResistance = 20;
skinUrl = "SPSkin";
//texture = "/mob/char.png";
}

View File

@ -18,10 +18,6 @@ public class EntityPlayerSP extends EntityPlayer {
field_21902_bL = new MouseFilter();
mc = minecraft;
dimension = i;
if (session != null && session.username != null && session.username.length() > 0) {
skinUrl = (new StringBuilder()).append("http://s3.amazonaws.com/MinecraftSkins/").append(session.username)
.append(".png").toString();
}
username = session.username;
}

View File

@ -349,7 +349,9 @@ public class EntityRenderer {
f3 = field_22235_l.func_22386_a(f3, 0.05F * f2);
f4 = field_22234_m.func_22386_a(f4, 0.05F * f2);
}
mc.thePlayer.func_346_d(f3, f4 * (float) l);
if(mc.thePlayer != null) {
mc.thePlayer.func_346_d(f3, f4 * (float) l);
}
}
if (mc.field_6307_v) {
return;

View File

@ -4,6 +4,7 @@ package net.minecraft.src;
import java.io.IOException;
import net.lax1dude.eaglercraft.EaglerAdapter;
import net.lax1dude.eaglercraft.EaglerProfile;
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3) braces deadcode
@ -61,6 +62,7 @@ public class GuiConnecting extends GuiScreen {
this.clientHandler = new NetClientHandler(mc, uri, 0);
this.clientHandler.addToSendQueue(new Packet2Handshake(mc.session.username));
this.clientHandler.addToSendQueue(new Packet69EaglercraftData("EAG|MySkin", EaglerProfile.getSelfSkinPacket()));
} catch (IOException e) {
try {
this.clientHandler.disconnect();

View File

@ -9,6 +9,7 @@ import net.lax1dude.eaglercraft.ConfigConstants;
import net.lax1dude.eaglercraft.EaglerAdapter;
import net.lax1dude.eaglercraft.EaglercraftRandom;
import net.lax1dude.eaglercraft.GuiMultiplayer;
import net.lax1dude.eaglercraft.GuiScreenEditProfile;
import net.lax1dude.eaglercraft.TextureLocation;
import net.lax1dude.eaglercraft.adapter.Tessellator;
import net.lax1dude.eaglercraft.beta.GuiNoMultiplayer;
@ -72,8 +73,8 @@ public class GuiMainMenu extends GuiScreen {
// mc.displayGuiScreen(new GuiTexturePacks(this));
//}
if (guibutton.id == 4) {
mc.displayGuiScreen(new GuiNoMultiplayer(this));
//mc.displayGuiScreen(new GuiMultiplayer(this));
//mc.displayGuiScreen(new GuiNoMultiplayer(this));
mc.displayGuiScreen(new GuiScreenEditProfile(this));
}
}
@ -98,6 +99,7 @@ public class GuiMainMenu extends GuiScreen {
drawString(fontRenderer, s, width - fontRenderer.getStringWidth(s) - 2, height - 10, 0xffffff);
drawString(fontRenderer, ConfigConstants.mainMenuString, 2, height - 10, 0xffffff);
/*
EaglerAdapter.glPushMatrix();
float ff = 0.75f;
EaglerAdapter.glScalef(ff, ff, ff);
@ -107,6 +109,7 @@ public class GuiMainMenu extends GuiScreen {
drawString(fontRenderer, str, (int)(((width / ff) - w) / 2), (int)((height / 4 + 102) / ff), 0xffeeee);
EaglerAdapter.glPopMatrix();
*/
super.drawScreen(i, j, f);
}

View File

@ -35,7 +35,7 @@ public class GuiSelectWorld extends GuiScreen {
private void func_22084_k() {
ISaveFormat isaveformat = mc.func_22004_c();
field_22100_m = isaveformat.getWorldList();
field_22100_m = isaveformat.getWorldList(mc.loadingScreen);
Collections.sort(field_22100_m);
field_22101_l = -1;
}

View File

@ -12,7 +12,7 @@ public interface ISaveFormat {
public abstract ISaveHandler loadWorldHandler(String s, boolean flag);
public abstract List getWorldList();
public abstract List getWorldList(IProgressUpdate progress);
public abstract void flushCache();

View File

@ -2,6 +2,7 @@ package net.minecraft.src;
// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
import net.lax1dude.eaglercraft.EaglerAdapter;
import net.lax1dude.eaglercraft.EaglerProfile;
import net.lax1dude.eaglercraft.TextureLocation;
import net.lax1dude.eaglercraft.adapter.Tessellator;
@ -185,8 +186,13 @@ public class ItemRenderer {
f10 = MathHelper.sin(MathHelper.sqrt_float(f6) * 3.141593F);
EaglerAdapter.glRotatef(f10 * 70F, 0.0F, 1.0F, 0.0F);
EaglerAdapter.glRotatef(-f8 * 20F, 0.0F, 0.0F, 1.0F);
EaglerAdapter.glBindTexture(3553 /* GL_TEXTURE_2D */, mc.renderEngine
.getTextureForDownloadableImage(mc.thePlayer.skinUrl, mc.thePlayer.getEntityTexture()));
// EaglerAdapter.glBindTexture(3553 /* GL_TEXTURE_2D */, mc.renderEngine
// .getTextureForDownloadableImage(mc.thePlayer.skinUrl, mc.thePlayer.getEntityTexture()));
if(EaglerProfile.presetSkinId < 0) {
mc.renderEngine.bindTexture(EaglerProfile.skins.get(EaglerProfile.customSkinId).glTex);
}else {
EaglerProfile.defaultOptionsTextures[EaglerProfile.presetSkinId].bindTexture();
}
EaglerAdapter.glTranslatef(-1F, 3.6F, 3.5F);
EaglerAdapter.glRotatef(120F, 0.0F, 0.0F, 1.0F);
EaglerAdapter.glRotatef(200F, 1.0F, 0.0F, 0.0F);

View File

@ -1,4 +1,7 @@
package net.minecraft.src;
import net.lax1dude.eaglercraft.EaglerAdapter;
// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
@ -50,7 +53,17 @@ public class ModelBiped extends ModelBase {
public void render(float f, float f1, float f2, float f3, float f4, float f5) {
setRotationAngles(f, f1, f2, f3, f4, f5);
bipedHead.render(f5);
if(blockTransparentSkins) {
EaglerAdapter.glDisable(EaglerAdapter.GL_ALPHA_TEST);
}
bipedBody.render(f5);
if(blockTransparentSkins) {
EaglerAdapter.glEnable(EaglerAdapter.GL_ALPHA_TEST);
}
bipedRightArm.render(f5);
bipedLeftArm.render(f5);
bipedRightLeg.render(f5);
@ -156,4 +169,6 @@ public class ModelBiped extends ModelBase {
public boolean field_1279_h;
public boolean field_1278_i;
public boolean isSneak;
public boolean blockTransparentSkins = false;
}

View File

@ -175,4 +175,12 @@ public class NBTTagCompound extends NBTBase {
}
private Map tagMap;
public NBTBase getTag(String s) {
return (NBTBase) tagMap.get(s);
}
public static Map<String,NBTBase> getTagMap(NBTTagCompound nb) {
return nb.tagMap;
}
}

View File

@ -6,6 +6,7 @@ package net.minecraft.src;
import java.io.*;
import net.lax1dude.eaglercraft.EaglerProfile;
import net.lax1dude.eaglercraft.EaglercraftRandom;
import net.lax1dude.eaglercraft.GuiMultiplayer;
import net.lax1dude.eaglercraft.WebsocketNetworkManager;
@ -23,9 +24,14 @@ public class NetClientHandler extends NetHandler {
public void processReadPackets() {
if (disconnected) {
if(mc.theWorld != null) {
mc.changeWorld1(null);
mc.displayGuiScreen(new GuiConnectFailed("disconnect.disconnected", "disconnect.endOfStream", new Object[0]));
}
return;
} else {
netManager.processReadPackets();
disconnected = !netManager.isSocketOpen();
return;
}
}
@ -336,14 +342,19 @@ public class NetClientHandler extends NetHandler {
}
public void handleHandshake(Packet2Handshake packet2handshake) {
if(packet2handshake.username.length() < 26 || mc.gameSettings.lastPasswordLength <= 0) {
if(packet2handshake.username.length() < 24 || mc.gameSettings.lastPasswordLength <= 0) {
addToSendQueue(new Packet1Login(mc.session.username, "NULL", 9));
}else {
String hsh = GuiMultiplayer.makeLoginHash(mc.gameSettings.lastPasswordHash, packet2handshake.username);
String hsh = (mc.gameSettings.lastPasswordHash == null || mc.gameSettings.lastPasswordHash.length() == 0 || mc.gameSettings.lastPasswordHash.equalsIgnoreCase("null")) ?
null : GuiMultiplayer.makeLoginHash(mc.gameSettings.lastPasswordHash, packet2handshake.username);
if(hsh != null) {
addToSendQueue(new Packet1Login(mc.session.username, hsh, 9));
}else {
addToSendQueue(new Packet1Login(mc.session.username, "NULL", 9));
disconnected = true;
netManager.networkShutdown("disconnect.closed", new Object[0]);
mc.changeWorld1(null);
mc.displayGuiScreen(new GuiConnectFailed("disconnect.disconnected", "disconnect.genericReason",
new Object[] { "A password is required to join this server!" }));
}
}
}
@ -522,6 +533,12 @@ public class NetClientHandler extends NetHandler {
packet54.pitch);
}
public void handleEaglercraftData(Packet69EaglercraftData packet) {
if(packet.type.equals("EAG|PlayerSkin")) {
EaglerProfile.processSkinResponse(packet.data);
}
}
private boolean disconnected;
private WebsocketNetworkManager netManager;
public String field_1209_a;

View File

@ -191,4 +191,8 @@ public class NetHandler {
public void func_22185_a(Packet27 packet27) {
}
public void handleEaglercraftData(Packet69EaglercraftData packet) {
registerPacket(packet);
}
}

View File

@ -151,6 +151,7 @@ public abstract class Packet {
addIdClassMapping(53, Packet53BlockChange.class);
addIdClassMapping(54, Packet54.class);
addIdClassMapping(60, Packet60.class);
addIdClassMapping(69, Packet69EaglercraftData.class);
addIdClassMapping(100, Packet100.class);
addIdClassMapping(101, Packet101.class);
addIdClassMapping(102, Packet102.class);

View File

@ -0,0 +1,47 @@
package net.minecraft.src;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public class Packet69EaglercraftData extends Packet {
public String type;
public byte[] data;
public Packet69EaglercraftData() {
}
public Packet69EaglercraftData(String type, byte[] data) {
if(data.length > 65535) {
throw new IllegalArgumentException("Packet69EaglercraftData may at most carry a 65535 byte payload");
}
this.type = type;
this.data = data;
}
@Override
public void readPacketData(DataInputStream datainputstream) throws IOException {
type = datainputstream.readUTF();
data = new byte[datainputstream.readUnsignedShort()];
datainputstream.read(data);
}
@Override
public void writePacketData(DataOutputStream dataoutputstream) throws IOException {
dataoutputstream.writeUTF(type);
dataoutputstream.writeShort(data.length);
dataoutputstream.write(data);
}
@Override
public void processPacket(NetHandler nethandler) {
nethandler.handleEaglercraftData(this);
}
@Override
public int getPacketSize() {
return 2 + type.length() + 2 + data.length;
}
}

View File

@ -78,9 +78,24 @@ public class RenderEngine {
textureNameToImageMap.put(Integer.valueOf(i), bufferedimage);
return i;
}
public int allocateAndSetupTexture(byte[] data, int w, int h) {
int i = EaglerAdapter.glGenTextures();
bindTexture(i);
EaglerAdapter.glTexParameteri(3553 /* GL_TEXTURE_2D */, 10241 /* GL_TEXTURE_MIN_FILTER */, 9729 /* GL_LINEAR */);
EaglerAdapter.glTexParameteri(3553 /* GL_TEXTURE_2D */, 10240 /* GL_TEXTURE_MAG_FILTER */, 9728 /* GL_NEAREST */);
EaglerAdapter.glTexParameteri(3553 /* GL_TEXTURE_2D */, 10242 /* GL_TEXTURE_WRAP_S */, 10497 /* GL_REPEAT */);
EaglerAdapter.glTexParameteri(3553 /* GL_TEXTURE_2D */, 10243 /* GL_TEXTURE_WRAP_T */, 10497 /* GL_REPEAT */);
imageDataB1.clear();
imageDataB1.put(data);
imageDataB1.position(0).limit(data.length);
EaglerAdapter.glTexImage2D(3553 /* GL_TEXTURE_2D */, 0, 6408 /* GL_RGBA */, w, h, 0, 6408 /* GL_RGBA */,
5121 /* GL_UNSIGNED_BYTE */, imageDataB1);
return i;
}
public void setupTexture(EaglerImage bufferedimage, int i) {
EaglerAdapter.glBindTexture(3553 /* GL_TEXTURE_2D */, i);
bindTexture(i);
if (useMipmaps) {
EaglerAdapter.glTexParameteri(3553 /* GL_TEXTURE_2D */, 10241 /* GL_TEXTURE_MIN_FILTER */, EaglerAdapter.GL_NEAREST_MIPMAP_LINEAR);
EaglerAdapter.glTexParameteri(3553 /* GL_TEXTURE_2D */, 10240 /* GL_TEXTURE_MAG_FILTER */, EaglerAdapter.GL_NEAREST /* GL_LINEAR */);
@ -343,11 +358,11 @@ public class RenderEngine {
TextureFX texturefx = (TextureFX) textureList.get(i);
texturefx.anaglyphEnabled = options.anaglyph;
texturefx.onTick();
texturefx.bindImage(this);
int tileSize = 16 * 16 * 4;
imageDataB1.clear();
imageDataB1.put(texturefx.imageData);
imageDataB1.position(0).limit(tileSize);
texturefx.bindImage(this);
EaglerAdapter.glTexSubImage2D(3553 /* GL_TEXTURE_2D */, 0, (texturefx.iconIndex % 16) * 16, (texturefx.iconIndex / 16) * 16, 16, 16,
6408 /* GL_RGBA */, 5121 /* GL_UNSIGNED_BYTE */, imageDataB1);
}

View File

@ -25,6 +25,7 @@ public class RenderFallingSand extends Render {
Block block = Block.blocksList[entityfallingsand.blockID];
World world = entityfallingsand.func_465_i();
EaglerAdapter.glDisable(2896 /* GL_LIGHTING */);
EaglerAdapter.glColor4f(1f, 1f, 1f, 1f);
field_197_d.renderBlockFallingSand(block, world, MathHelper.floor_double(entityfallingsand.posX),
MathHelper.floor_double(entityfallingsand.posY), MathHelper.floor_double(entityfallingsand.posZ));
EaglerAdapter.glEnable(2896 /* GL_LIGHTING */);

View File

@ -835,33 +835,28 @@ public class RenderGlobal implements IWorldAccess {
}
public boolean updateRenderers(EntityLiving entityliving, boolean flag) {
boolean flag1 = false;
if (flag1) {
Collections.sort(worldRenderersToUpdate, new RenderSorter(entityliving));
int i = worldRenderersToUpdate.size() - 1;
int j = worldRenderersToUpdate.size();
for (int k = 0; k < j; k++) {
WorldRenderer worldrenderer = (WorldRenderer) worldRenderersToUpdate.get(i - k);
if (!flag) {
if (worldrenderer.distanceToEntity(entityliving) > 1024F) {
if (worldrenderer.isInFrustum) {
if (k >= 3) {
return false;
}
} else if (k >= 1) {
return false;
}
//boolean flag1 = false;
//if (flag1) {
int t = worldRenderersToUpdate.size();
if(t > 0) {
Collections.sort(worldRenderersToUpdate, new RenderSorter(entityliving));
boolean b = false;
for(int i = t - 1; i >= 0; --i) {
WorldRenderer worldrenderer = (WorldRenderer) worldRenderersToUpdate.get(i);
if(worldrenderer.isInFrustum || worldrenderer.distanceToEntity(entityliving) < 1024F) {
b = true;
worldrenderer.updateRenderer();
worldRenderersToUpdate.remove(i);
break;
}
} else if (!worldrenderer.isInFrustum) {
continue;
}
worldrenderer.updateRenderer();
worldRenderersToUpdate.remove(worldrenderer);
worldrenderer.needsUpdate = false;
if(!b) {
((WorldRenderer)worldRenderersToUpdate.remove(t - 1)).updateRenderer();
}
}
return worldRenderersToUpdate.size() == 0;
}
//}
/*
RenderSorter rendersorter = new RenderSorter(entityliving);
WorldRenderer aworldrenderer[] = new WorldRenderer[3];
ArrayList arraylist = null;
@ -941,6 +936,7 @@ public class RenderGlobal implements IWorldAccess {
worldRenderersToUpdate.remove(j2);
}
return l == i1 + l1;
*/
}
private static final TextureLocation terrainTexture = new TextureLocation("/terrain.png");

View File

@ -1,7 +1,14 @@
package net.minecraft.src;
// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import net.lax1dude.eaglercraft.EaglerAdapter;
import net.lax1dude.eaglercraft.EaglerProfile;
import net.lax1dude.eaglercraft.EaglerProfile.EnumSkinType;
import net.lax1dude.eaglercraft.EaglerProfile.UserSkin;
import net.lax1dude.eaglercraft.TextureLocation;
import net.lax1dude.eaglercraft.adapter.Tessellator;
@ -25,6 +32,7 @@ public class RenderPlayer extends RenderLiving {
public RenderPlayer() {
super(new ModelBiped(0.0F), 0.5F);
modelBipedMain = (ModelBiped) mainModel;
modelBipedMain.blockTransparentSkins = true;
modelArmorChestplate = new ModelBiped(1.0F);
modelArmor = new ModelBiped(0.5F);
}
@ -298,7 +306,47 @@ public class RenderPlayer extends RenderLiving {
@Override
protected boolean loadDownloadableImageTexture(String s, String s1) {
defaultPlayerSkin.bindTexture();
RenderEngine re = Minecraft.getMinecraft().renderEngine;
if(s == null) {
defaultPlayerSkin.bindTexture();
}else if(s.equals("SPSkin")) {
if(EaglerProfile.presetSkinId < 0) {
re.bindTexture(EaglerProfile.skins.get(EaglerProfile.customSkinId).glTex);
}else {
EaglerProfile.defaultOptionsTextures[EaglerProfile.presetSkinId].bindTexture();
}
}else if(s.startsWith("MPSkin")) {
String un = s.substring(6);
UserSkin us = EaglerProfile.getUserSkin(un);
if(us == null) {
if(!EaglerProfile.skinRequestPending(un)) {
World w = Minecraft.getMinecraft().theWorld;
if(w != null && (w instanceof WorldClient)) {
try {
ByteArrayOutputStream bao = new ByteArrayOutputStream();
DataOutputStream dao = new DataOutputStream(bao);
dao.writeShort(EaglerProfile.beginSkinRequest(un));
dao.writeUTF(un);
((WorldClient)w).sendPacket(new Packet69EaglercraftData("EAG|RequestPlayerSkin", bao.toByteArray()));
}catch(IOException exx) {
// ?
}
}
}
defaultPlayerSkin.bindTexture();
}else {
EnumSkinType st = us.getSkinType();
if(st == EnumSkinType.PRESET) {
EaglerProfile.defaultOptionsTextures[us.getSkin()].bindTexture();
}else if(st == EnumSkinType.CUSTOM_LEGACY){
re.bindTexture(us.getTexture());
}else {
defaultPlayerSkin.bindTexture();
}
}
}else {
defaultPlayerSkin.bindTexture();
}
return true;
}

View File

@ -6,6 +6,8 @@ package net.minecraft.src;
import java.util.*;
import net.lax1dude.eaglercraft.EaglerProfile;
public class WorldClient extends World {
public WorldClient(NetClientHandler netclienthandler, long l, int i) {
@ -102,6 +104,9 @@ public class WorldClient extends World {
}
public void setEntityDead(Entity entity) {
if(entity instanceof EntityOtherPlayerMP) {
EaglerProfile.freeUserSkin(((EntityOtherPlayerMP)entity).username);
}
super.setEntityDead(entity);
field_20914_E.remove(entity);
}
@ -192,6 +197,10 @@ public class WorldClient extends World {
public void sendQuittingDisconnectingPacket() {
sendQueue.addToSendQueue(new Packet255KickDisconnect("Quitting"));
}
public void sendPacket(Packet p) {
sendQueue.addToSendQueue(p);
}
private LinkedList field_1057_z;
private NetClientHandler sendQueue;

View File

@ -36,13 +36,20 @@ public class Client {
registerErrorHandler();
String[] e = getOpts();
try {
EaglerAdapterImpl2.initializeContext(rootElement = Window.current().getDocument().getElementById(e[0]), e[1]);
}catch(AbortedLaunchException ex) {
try {
EaglerAdapterImpl2.initializeContext(rootElement = Window.current().getDocument().getElementById(e[0]), e[1]);
}catch(AbortedLaunchException ex) {
return;
}
}catch(Throwable ex2) {
StringWriter s = new StringWriter();
ex2.printStackTrace(new PrintWriter(s));
showCrashScreen(s.toString());
return;
}
LocalStorageManager.loadStorage();
if(e.length > 2) {
EaglerAdapterImpl2.setServerToJoinOnLaunch(e[3]);
EaglerAdapterImpl2.setServerToJoinOnLaunch(e[2]);
}
run0();
}